diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-00cecdb4dc8514ec7e775622bc723648.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-00cecdb4dc8514ec7e775622bc723648.json new file mode 100644 index 0000000..0f7db0d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-00cecdb4dc8514ec7e775622bc723648.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Loading\u2026":["Cargando..."]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/base\/components\/loading-mask\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-01739590876f3ab645ec3678e42bbc29.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-01739590876f3ab645ec3678e42bbc29.json new file mode 100644 index 0000000..a9bd00b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-01739590876f3ab645ec3678e42bbc29.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Link to":["Enlace a"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/editor-components\/page-selector\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-01b768ae1db405a69d13758eda43a58b.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-01b768ae1db405a69d13758eda43a58b.json new file mode 100644 index 0000000..1499138 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-01b768ae1db405a69d13758eda43a58b.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"This product is currently out of stock and cannot be purchased.":["Este producto actualmente no tiene existencias y no puede comprarse."],"View Product":["Ver producto"],"Select an option":["Selecciona una opci\u00f3n"],"Please select a value.":["Por favor, selecciona un valor."],"Something went wrong. Please contact us to get assistance.":["Algo ha salido mal. Por favor, cont\u00e1ctanos para obtener ayuda."],"%d in cart":["%d en el carrito","%d en el carrito"],"Done":["Hecho"],"Sorry, this product cannot be purchased.":["Lo sentimos, este producto no se puede comprar."],"Add to cart":["A\u00f1adir al carrito"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/atomic-block-components\/add-to-cart-frontend.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-02acd74879196411261af7576fdb4b93.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-02acd74879196411261af7576fdb4b93.json new file mode 100644 index 0000000..3778d1d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-02acd74879196411261af7576fdb4b93.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"The last inner block will follow other content.":["El \u00faltimo bloque interior seguir\u00e1 al resto del contenido."],"The last inner block will be aligned vertically.":["El \u00faltimo bloque interior se alinear\u00e1 verticalmente"],"Align Last Block":["Alinear \u00faltimo bloque"],"Product Tags":["Etiquetas del producto"],"This block displays products from selected tags. In order to preview this you'll first need to create a product and assign it some tags.":["Este bloque muestra productos de las etiquetas seleccionadas. Para previsualizarlo primero tienes que crear un producto y asignarle alguna etiqueta."],"This block displays products from selected tags. Select at least one tag to display its products.":["Este bloque muestra productos de las etiquetas seleccionadas. Selecciona al menos una etiqueta para mostrar sus productos."],"Done":["Hecho"],"Showing Products by Tag block preview.":["Mostrando la vista previa del bloque de productos por etiqueta."],"Products by Tag":["Productos por etiqueta"],"Order By":["Ordenar por"],"Layout":["Estructura"],"Rows":["Filas"],"Add to Cart button is hidden.":["El bot\u00f3n de a\u00f1adir al carrito est\u00e1 oculto."],"Columns":["Columnas"],"Add to Cart button is visible.":["El bot\u00f3n de a\u00f1adir al carrito es visible."],"Add to Cart button":["Bot\u00f3n de a\u00f1adir al carrito"],"Display a grid of products from your selected tags.":["Muestra una cuadr\u00edcula de productos de las etiquetas que selecciones."],"Display a grid of products with selected tags.":["Muestra una cuadr\u00edcula de productos con las etiquetas seleccionadas."],"Menu Order":["Orden del men\u00fa"],"Title - alphabetical":["T\u00edtulo - alfab\u00e9tico"],"Sales - most first":["Ventas - primero los m\u00e1s vendidos"],"Rating - highest first":["Valoraci\u00f3n - primero los mejores"],"Price - high to low":["Precio - de mayor a menor"],"Price - low to high":["Precio - de menor a mayor"],"Newness - newest first":["Novedad - primero los m\u00e1s nuevos"],"Order products by":["Ordenar productos por"],"All selected tags":["Todas las etiquetas seleccionadas"],"Any selected tags":["Cualquier etiqueta seleccionada"],"Pick at least two tags to use this setting.":["Elige al menos dos etiquetas para usar este ajuste."],"Display products matching":["Mostrar productos que coincidan"],"Tag search results updated.":["Resultados de b\u00fasqueda de etiqueta actualizados."],"%d tag selected":["%d etiqueta seleccionada","%d etiquetas seleccionadas"],"Search for product tags":["Buscar por etiquetas de productos"],"Your store doesn't have any product tags.":["Tu tienda no tiene ninguna etiqueta de producto."],"Clear all product tags":["Vaciar todas las etiquetas de producto"],"Product rating is hidden.":["La valoraci\u00f3n del producto est\u00e1 oculta."],"Product rating is visible.":["La valoraci\u00f3n del producto es visible."],"Product rating":["Valoraci\u00f3n del producto"],"Product price is hidden.":["El precio del producto est\u00e1 oculto."],"Product price is visible.":["El precio del producto es visible."],"Product price":["Precio del producto"],"Product title is hidden.":["El t\u00edtulo del producto est\u00e1 oculto."],"Product title is visible.":["El t\u00edtulo del producto es visible."],"Product title":["T\u00edtulo del producto"],"%1$d product tagged as %2$s":["%1$d producto etiquetado como %2$s","%1$d productos etiquetados como %2$s"],"Content":["Contenido"],"Cancel":["Cancelar"],"Product Tag":["Etiquetas de producto"],"WooCommerce":["WooCommerce"],"Edit":["Editar"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/product-tag.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0436417c01a5fcf6da938f5082798846.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0436417c01a5fcf6da938f5082798846.json new file mode 100644 index 0000000..409e402 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0436417c01a5fcf6da938f5082798846.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Choose which leaderboards to display and other settings":["Elige qu\u00e9 favoritos mostrar y otros ajustes"],"Leaderboards":["Favoritos"],"Rows Per Table":["Filas por tabla"],"No data recorded for the selected time period.":["No hay datos almacenados del periodo de tiempo seleccionado."],"View Orders":["Ver pedidos"],"No results could be found for this date range.":["No se han encontrado resultados en este rango de fechas."],"Reload":["Recargar"],"There was an error getting your stats. Please try again.":["Hubo un error al recuperar tus estad\u00edsticas. Por favor, int\u00e9ntalo de nuevo."]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/chunks\/leaderboards.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-056e3f14efed538fde21950202add8dc.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-056e3f14efed538fde21950202add8dc.json new file mode 100644 index 0000000..d1ae5b6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-056e3f14efed538fde21950202add8dc.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Visually highlight a product or variation and encourage prompt action.":["Destaca visualmente un producto o una variaci\u00f3n y anima a realizar una acci\u00f3n."],"Shop now":["Comprar ahora"],"Featured Product":["Producto destacado"],"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/featured-product\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0657952e8fe472b7a7f031ef6c2f1e6a.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0657952e8fe472b7a7f031ef6c2f1e6a.json new file mode 100644 index 0000000..e554df5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0657952e8fe472b7a7f031ef6c2f1e6a.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Choose a product to display its add to cart button.":["Elige un producto para mostrar su bot\u00f3n de a\u00f1adir al carrito."]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/button\/edit.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-09444bf964f9242a7dc345c5da29c237.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-09444bf964f9242a7dc345c5da29c237.json new file mode 100644 index 0000000..ccbf8ed --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-09444bf964f9242a7dc345c5da29c237.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Add a note to your order":["A\u00f1ade una nota a tu pedido"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/cart-checkout\/checkout\/form\/order-notes\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-09b8a04693848711e3459fcc6f5f2a94.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-09b8a04693848711e3459fcc6f5f2a94.json new file mode 100644 index 0000000..997c668 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-09b8a04693848711e3459fcc6f5f2a94.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Display the main product image":["Mostrar la imagen principal del producto"],"Product Image":["Imagen del producto"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/image\/constants.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-09c5919a18291dd26d6f52f9d1563a8e.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-09c5919a18291dd26d6f52f9d1563a8e.json new file mode 100644 index 0000000..a22cfd5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-09c5919a18291dd26d6f52f9d1563a8e.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Fly your WordPress banner with this beauty! Deck out your office space or add it to your kids walls. This banner will spruce up any space it\u2019s hung!":["\u00a1Despliega tu estandarte de WordPress con esta belleza! Decora tu oficina o a\u00f1\u00e1dela a las paredes de tus hijos. \u00a1Esta banderola aderezar\u00e1 cualquier espacio en el que se cuelgue!"],"Add to cart":["A\u00f1adir al carrito"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/previews\/products.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0a3b65850c50f16de824a40fa5ff0f0f.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0a3b65850c50f16de824a40fa5ff0f0f.json new file mode 100644 index 0000000..446659f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0a3b65850c50f16de824a40fa5ff0f0f.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Filter by Product Category":["Filtrar por categor\u00eda de producto"],"Layout":["Estructura"],"Content":["Contenido"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/product-new\/block.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0cf7579f6fbc3a394bde81590518d79e.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0cf7579f6fbc3a394bde81590518d79e.json new file mode 100644 index 0000000..50f7ee6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0cf7579f6fbc3a394bde81590518d79e.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"The following error was returned":["Se devolvi\u00f3 el siguiente error"],"This product is awesome, I love it!":["Este producto es asombroso, \u00a1me encanta!"],"Bob":["Roberto"],"July 12, 2019":["12 de julio de 2019"],"I bought this product last week and I'm very happy with it.":["Compr\u00e9 este producto la semana pasada y estoy muy feliz con \u00e9l."],"Alice":["Alicia"],"WordPress Pennant":["Bander\u00edn de WordPress"],"July 15, 2019":["15 de julio de 2019"],"This block shows a list of all product reviews. Your store does not have any reviews yet, but they will show up here when it does.":["Este bloque muestra una lista de todas las valoraciones de productos. Tu tienda todav\u00eda no tiene valoraciones, pero se mostrar\u00e1n aqu\u00ed cuando las tenga."],"Load more reviews":["Cargar m\u00e1s valoraciones"],"Sorry, an error occurred":["Lo siento, ha ocurrido un error"],"The following error was returned from the API":["El siguiente error ha sido devuelto desde la API"],"An unknown error occurred which prevented the block from being updated.":["Ha ocurrido un error desconocido que ha impedido que el bloque haya sido actualizado."],"All Reviews":["Todas las valoraciones"],"Retry":["Volver a intentar"],"Show a list of all product reviews.":["Muestra una lista de todas las valoraciones de productos."],"Starting Number of Reviews":["N\u00famero inicial de valoraciones"],"Load More Reviews":["Cargar m\u00e1s valoraciones"],"Reviewer name":["Nombre de quien valora"],"Review date":["Fecha de la valoraci\u00f3n"],"Review content":["Contenido de la valoraci\u00f3n"],"Review image":["Imagen de la valoraci\u00f3n"],"Reviewer photo":["Foto de quien valora"],"Order Product Reviews by":["Ordenar las valoraciones de los productos por"],"The content for this block is hidden due to block settings.":["El contenido de este bloque est\u00e1 oculto debido a los ajustes del bloque."],"Most recent":["Las m\u00e1s recientes"],"Verified buyer":["Comprador verificado"],"Read full review":["Leer la valoraci\u00f3n completa"],"Hide full review":["Ocultar la valoraci\u00f3n completa"],"Read less":["Leer menos"],"Load more":["Cargar m\u00e1s"],"Highest rating":["La mayor valoraci\u00f3n"],"Lowest rating":["La menor valoraci\u00f3n"],"Order reviews by":["Ordenar las valoraciones por"],"Product rating is disabled in your store settings<\/a>.":["La valoraci\u00f3n de productos est\u00e1 desactivada en tus ajustes de la tienda<\/a>."],"Reviewer photo is disabled in your site settings<\/a>.":["La foto de quien valora est\u00e1 desactivada en tus ajustes del sitio<\/a>."],"List Settings":["Ajustes de la lista"],"Product rating":["Valoraci\u00f3n del producto"],"Rated %f out of 5":["Valorado con %f de 5"],"Content":["Contenido"],"Image":["Imagen"],"Product name":["Nombre del producto"],"WooCommerce":["WooCommerce"],"Order by":["Ordenar por"],"Edit":["Editar"],"Product":["Producto"],"Read more":["Leer m\u00e1s"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/all-reviews.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0db65848d165e94c1b721836932fa2b2.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0db65848d165e94c1b721836932fa2b2.json new file mode 100644 index 0000000..6666527 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0db65848d165e94c1b721836932fa2b2.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"This product is currently out of stock and cannot be purchased.":["Este producto actualmente no tiene existencias y no puede comprarse."]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/add-to-cart\/product-types\/simple.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0dc089127d6d4abad378c797b27b1007.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0dc089127d6d4abad378c797b27b1007.json new file mode 100644 index 0000000..7a808c3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0dc089127d6d4abad378c797b27b1007.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Text color":["Color de texto"],"Color settings":["Ajustes de color"],"Choose a product to display its title.":["Elige un producto para mostrar su t\u00edtulo."],"Links the image to the single product listing.":["Enlaza la imagen al listado de un producto."],"Link to Product Page":["Enlace a la p\u00e1gina del producto"],"Content":["Contenido"],"Text settings":["Ajustes de texto"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/title\/edit.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0e3dcd4f3ff5aa786acbbd18de58d420.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0e3dcd4f3ff5aa786acbbd18de58d420.json new file mode 100644 index 0000000..2b94e4c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-0e3dcd4f3ff5aa786acbbd18de58d420.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"%1$s, has %2$d product":["%1$s, tiene %2$d producto","%1$s, tiene %2$d productos"],"%1$s, has %2$d review":["%1$s, tiene %2$d valoraci\u00f3n","%1$s, tiene %2$d valoraciones"],"The last inner block will follow other content.":["El \u00faltimo bloque interior seguir\u00e1 al resto del contenido."],"The last inner block will be aligned vertically.":["El \u00faltimo bloque interior se alinear\u00e1 verticalmente"],"Align Last Block":["Alinear \u00faltimo bloque"],"%d Product":["%d producto","%d productos"],"The following error was returned":["Se devolvi\u00f3 el siguiente error"],"%d Review":["%d valoraci\u00f3n","%d valoraciones"],"The following error was returned from the API":["El siguiente error ha sido devuelto desde la API"],"An unknown error occurred which prevented the block from being updated.":["Ha ocurrido un error desconocido que ha impedido que el bloque haya sido actualizado."],"Display a grid of your newest products.":["Muestra una cuadr\u00edcula de productos m\u00e1s recientes."],"Newest Products":["Productos m\u00e1s recientes"],"Filter by Product Category":["Filtrar por categor\u00eda de producto"],"All selected categories":["Todas las categor\u00edas seleccionadas"],"Any selected categories":["Cualquier categor\u00eda seleccionada"],"Pick at least two categories to use this setting.":["Elige al menos dos categor\u00edas para usar este ajuste."],"Category search results updated.":["Resultados de b\u00fasqueda de categor\u00eda actualizados."],"%d category selected":["%d categor\u00eda seleccionada","%d categor\u00edas seleccionadas"],"Search for product categories":["Buscar por categor\u00edas de producto"],"Your store doesn't have any product categories.":["Tu tienda no tiene ninguna categor\u00eda de producto."],"Clear all product categories":["Vaciar todas las categor\u00edas de producto"],"Layout":["Estructura"],"Rows":["Filas"],"Add to Cart button is hidden.":["El bot\u00f3n de a\u00f1adir al carrito est\u00e1 oculto."],"Columns":["Columnas"],"Add to Cart button is visible.":["El bot\u00f3n de a\u00f1adir al carrito es visible."],"Add to Cart button":["Bot\u00f3n de a\u00f1adir al carrito"],"Display products matching":["Mostrar productos que coincidan"],"Product rating is hidden.":["La valoraci\u00f3n del producto est\u00e1 oculta."],"Product rating is visible.":["La valoraci\u00f3n del producto es visible."],"Product rating":["Valoraci\u00f3n del producto"],"Product price is hidden.":["El precio del producto est\u00e1 oculto."],"Product price is visible.":["El precio del producto es visible."],"Product price":["Precio del producto"],"Product title is hidden.":["El t\u00edtulo del producto est\u00e1 oculto."],"Product title is visible.":["El t\u00edtulo del producto es visible."],"Product title":["T\u00edtulo del producto"],"Content":["Contenido"],"Product Categories":["Categor\u00edas de producto"],"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/product-new.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-11eaf0a60d602f142e96c14c44445c1c.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-11eaf0a60d602f142e96c14c44445c1c.json new file mode 100644 index 0000000..34c766f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-11eaf0a60d602f142e96c14c44445c1c.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Return to Cart":["Volver al carrito"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/base\/components\/cart-checkout\/return-to-cart-button\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-124cfb7a5d89d9c89c181e1d53e04227.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-124cfb7a5d89d9c89c181e1d53e04227.json new file mode 100644 index 0000000..ec538fb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-124cfb7a5d89d9c89c181e1d53e04227.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"This block displays products from selected tags. In order to preview this you'll first need to create a product and assign it some tags.":["Este bloque muestra productos de las etiquetas seleccionadas. Para previsualizarlo primero tienes que crear un producto y asignarle alguna etiqueta."],"This block displays products from selected tags. Select at least one tag to display its products.":["Este bloque muestra productos de las etiquetas seleccionadas. Selecciona al menos una etiqueta para mostrar sus productos."],"Done":["Hecho"],"Showing Products by Tag block preview.":["Mostrando la vista previa del bloque de productos por etiqueta."],"Products by Tag":["Productos por etiqueta"],"Order By":["Ordenar por"],"Layout":["Estructura"],"Display a grid of products from your selected tags.":["Muestra una cuadr\u00edcula de productos de las etiquetas que selecciones."],"Content":["Contenido"],"Cancel":["Cancelar"],"Product Tag":["Etiquetas de producto"],"Edit":["Editar"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/product-tag\/block.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-12698f76de1361156158b68e7449b0a9.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-12698f76de1361156158b68e7449b0a9.json new file mode 100644 index 0000000..74abb88 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-12698f76de1361156158b68e7449b0a9.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Add %s section":["A\u00f1adir secci\u00f3n %s"],"Dashboard Sections":["Secciones del escritorio"],"Add more sections":["A\u00f1adir m\u00e1s secciones"],"Remove section":["Quitar secci\u00f3n"],"Remove block":["Quitar bloque"],"Move Down":["Bajar"],"Performance":["Rendimiento"],"Section Title":["T\u00edtulo de la secci\u00f3n"],"Leaderboards":["Favoritos"],"Charts":["Gr\u00e1ficos"],"Move up":["Subir"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/chunks\/customizable-dashboard.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-154eb5541053115f9cf2cc279decf649.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-154eb5541053115f9cf2cc279decf649.json new file mode 100644 index 0000000..acd0b0b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-154eb5541053115f9cf2cc279decf649.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"This block lists reviews for products from selected categories. The selected categories do not have any reviews yet, but they will show up here when they do.":["Este bloque lista las valoraciones de los productos de las categor\u00edas seleccionadas. Las categor\u00edas seleccionadas todav\u00eda no tienen valoraciones, pero se mostrar\u00e1n aqu\u00ed cuando las tengan."],"Reviews by Category":["Valoraciones por categor\u00eda"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/reviews\/reviews-by-category\/no-reviews-placeholder.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-15ffb2e3ba27c86287dde1e4045e79cc.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-15ffb2e3ba27c86287dde1e4045e79cc.json new file mode 100644 index 0000000..873ad6f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-15ffb2e3ba27c86287dde1e4045e79cc.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Choose which analytics to display and the section name":["Elige qu\u00e9 an\u00e1lisis mostrar y el nombre de la secci\u00f3n"],"Display Stats:":["Mostrar estad\u00edsticas:"],"Store Performance":["Rendimiento de la tienda"],"Previous Year:":["A\u00f1o anterior:"],"Previous Period:":["Periodo anterior:"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/chunks\/store-performance.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1605a532b87cc989e30f0c39532c5845.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1605a532b87cc989e30f0c39532c5845.json new file mode 100644 index 0000000..be1cac4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1605a532b87cc989e30f0c39532c5845.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Sorry, this product cannot be purchased.":["Lo sentimos, este producto no se puede comprar."]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/add-to-cart\/shared\/product-unavailable.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-16268754aba0e39aeb4f24c835d52820.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-16268754aba0e39aeb4f24c835d52820.json new file mode 100644 index 0000000..6297971 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-16268754aba0e39aeb4f24c835d52820.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Display a single product.":["Mostrar un producto individual."],"Single Product":["Producto individual"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/single-product\/constants.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1869430a90f07a7364b4c043829f725f.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1869430a90f07a7364b4c043829f725f.json new file mode 100644 index 0000000..34119c4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1869430a90f07a7364b4c043829f725f.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Categories:":["Categor\u00edas:"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/atomic-block-components\/category-list-frontend.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-18a31075fa5f4596edaf76ec78921ff4.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-18a31075fa5f4596edaf76ec78921ff4.json new file mode 100644 index 0000000..5571ce9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-18a31075fa5f4596edaf76ec78921ff4.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"%1$s, has %2$d review":["%1$s, tiene %2$d valoraci\u00f3n","%1$s, tiene %2$d valoraciones"],"Showing Reviews by Product block preview.":["Mostrando la vista previa del bloque de valoraciones por producto."],"Show reviews of your product to build trust":["Muestra las valoraciones de tus productos para crear confianza"],"%d Review":["%d valoraci\u00f3n","%d valoraciones"],"Reviews by Product":["Valoraciones por producto"],"List Settings":["Ajustes de la lista"],"Done":["Hecho"],"Content":["Contenido"],"Product":["Producto"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/reviews\/reviews-by-product\/edit.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-19f16f4fc69aa97ecde5d39d523dfd8b.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-19f16f4fc69aa97ecde5d39d523dfd8b.json new file mode 100644 index 0000000..ee12887 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-19f16f4fc69aa97ecde5d39d523dfd8b.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"CVV\/CVC":["CVV\/CVC"],"Expiry Date":["Fecha de caducidad"],"Card Number":["N\u00famero de la tarjeta"],"Credit Card Information":["Informaci\u00f3n de la tarjeta de cr\u00e9dito"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/payment-method-extensions\/payment-methods\/stripe\/credit-card\/elements.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-19f52ef80d162b0ab094ab96c60a76e8.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-19f52ef80d162b0ab094ab96c60a76e8.json new file mode 100644 index 0000000..d5db413 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-19f52ef80d162b0ab094ab96c60a76e8.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"%d in cart":["%d en el carrito","%d en el carrito"],"Add to cart":["A\u00f1adir al carrito"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/atomic-block-components\/button.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1a349548a3d38de6f8013f63a02ddf4b.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1a349548a3d38de6f8013f63a02ddf4b.json new file mode 100644 index 0000000..5f88dff --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1a349548a3d38de6f8013f63a02ddf4b.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Remove coupon \"%s\"":["Eliminar cup\u00f3n \u00ab%s\u00bb"],"Removing coupon\u2026":["Eliminando cup\u00f3n\u2026"],"Coupon: %s":["Cup\u00f3n: %s"],"Discount":["Descuento"],"Coupons":["Cupones"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/base\/components\/cart-checkout\/totals\/totals-discount-item\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1ab3c5ff6a861a0bbc5e57811248de9b.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1ab3c5ff6a861a0bbc5e57811248de9b.json new file mode 100644 index 0000000..782ca16 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1ab3c5ff6a861a0bbc5e57811248de9b.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Apply price filter":["Aplicar el filtro de precios"],"Apply filter":["Aplicar filtro"],"Filter products by maximum price":["Filtrar productos por mayor precio"],"Filter products by minimum price":["Filtrar productos por el menor precio"],"Oops!":["\u00a1Vaya!"],"There was an error loading the content.":["Ha habido un error al cargar este contenido."],"Error:":["Error:"],"Go":["Ir"],"Price":["Precio"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/price-filter-frontend.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1b3f299878731ed7e1fc34722ef3c267.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1b3f299878731ed7e1fc34722ef3c267.json new file mode 100644 index 0000000..25005f7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1b3f299878731ed7e1fc34722ef3c267.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"example product in Cart Block\u0004Beanie":["Gorro"],"example product in Cart Block\u0004Beanie with Logo":["Gorra con logotipo"],"Free shipping":["Env\u00edo gratuito"],"Shipping":["Env\u00edo"],"Local pickup":["Recogida local"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/previews\/shipping-rates.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1b59d077cd5a766feef182aa33bfdeb6.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1b59d077cd5a766feef182aa33bfdeb6.json new file mode 100644 index 0000000..72327bb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1b59d077cd5a766feef182aa33bfdeb6.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Filter button":["Bot\u00f3n de filtrado"],"Editable":["Editable"],"Price Range":["Rango de precios"],"Products with prices are needed for filtering by price. You haven't created any products yet.":["Para filtrar por precio, se necesitan productos con precio. Todav\u00eda no has creado ning\u00fan producto."],"Products will update when the slider is moved.":["Los productos se actualizar\u00e1n cuando se mueva el carrusel."],"Products will only update when the button is pressed.":["Los productos solo se actualizar\u00e1n cuando se presione el bot\u00f3n."],"Block Settings":["Ajustes del bloque"],"Heading Level":["Nivel del encabezado"],"Filter Products by Price":["Filtrar productos por precio"],"Display a slider to filter products in your store by price.":["Muestra un control deslizante para filtrar productos de tu tienda por precio."],"Text":["Texto"],"Add new product":["A\u00f1adir nuevo producto"],"Learn more":["Aprende m\u00e1s"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/price-filter\/edit.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1b8267223028487f1ab7e31c03738ca0.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1b8267223028487f1ab7e31c03738ca0.json new file mode 100644 index 0000000..925ba33 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1b8267223028487f1ab7e31c03738ca0.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/shared\/config.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1cad345524084a630039a2d2c327cd23.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1cad345524084a630039a2d2c327cd23.json new file mode 100644 index 0000000..9e3cc5f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1cad345524084a630039a2d2c327cd23.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Secret Key":["Clave secreta"],"Publishable Key":["Clave publicable"],"Please enter a secret key in the same mode as the publishable key.":["Por favor, introduce una clave secreta del mismo modo que la clave publicable."],"Please enter a valid secret key (starting with \"sk_\" or \"rk_\").":["Por favor, introduce una clave secreta v\u00e1lida (que empiece con \u00absk_\u00bb o \u00abrk_\u00bb)."],"Please enter a valid publishable key (starting with \"pk_\").":["Por favor, introduce una clave publicable v\u00e1lida (que empiece con \u00abpk_\u00bb)."],"Your API details can be obtained from your {{link}}PayPal account{{\/link}}":["Los detalles de tu API los puedes obtener en tu {{link}}cuenta de PayPal{{\/link}}"],"Connect your eWAY account":["Conecta tu cuenta de eWAY"],"Customer Password":["Contrase\u00f1a de cliente"],"Customer API Key":["Clave de cliente de la API"],"eWAY connected successfully":["eWAY conectado correctamente"],"Please enter your customer password":["Por favor,\u00a0introduce tu contrase\u00f1a de cliente"],"Please enter your customer API key ":["Por favor, introduce tu clave de cliente de la API"],"Create account":["Crear cuenta"],"eWAY":["eWAY"],"A PayPal account is required to process payments. Connect your store to your PayPal account.":["Para procesar los pagos, es necesaria una cuenta de PayPal. Conecta tu tienda con tu cuenta de PayPal."],"You will be redirected to the PayPal website to create the connection.":["Ser\u00e1s redirigido a la web de PayPal para crear la conexi\u00f3n."],"By clicking \"Set up,\" you agree to the {{link}}Terms of Service{{\/link}}":["Al hacer clic en \u00abConfiguraci\u00f3n\u00bb, est\u00e1 de acuerdo con los {{link}}t\u00e9rminos de servicio{{\/link}}"],"Setting up a store for a client? {{link}}Start here{{\/link}}":["\u00bfConfigurando una tienda para un cliente? {{link}}Empieza aqu\u00ed{{\/link}}"],"Accept credit card payments the easy way! No setup fees. No monthly fees. Just 2.9% + $0.30 per transaction on U.S. issued cards. ":["\u00a1Acepta pagos con tarjeta de cr\u00e9dito de forma f\u00e1cil! Sin cuotas de configuraci\u00f3n. Sin cuotas mensuales. Solo el 2,9 % m\u00e1s 0,30 $ por transacci\u00f3n en tarjetas emitidas en los EE.UU."],"Connect your Klarna account":["Conecta tu cuenta de Klarna"]," Selling CBD products is only supported by Square.":[" La venta de productos de CBD solo est\u00e1 soportada por Square."],"Passphrase":["Frase de contrase\u00f1a"],"Take payments via bank transfer.":["Acepta pagos mediante transferencia bancaria."],"Take payments in cash upon delivery.":["Acepta pagos en efectivo en el momento de la entrega."],"Selecting this extension will configure your store to use South African rands as the selected currency.":["Al seleccionar esta extensi\u00f3n, tu tienda se configurar\u00e1 para usar rands sudafricanos como moneda seleccionada."],"Merchant Key":["Clave de vendedor"],"Merchant ID":["ID de vendedor"],"PayFast connected successfully":["PayFast conectado correctamente."],"Please enter your passphrase":["Por favor, introduce tu contrase\u00f1a"],"Please enter your merchant ID":["Por favor, introduce tu ID de vendedor"],"Connect your PayFast account":["Conecta tu cuenta de PayFast"],"PayFast":["PayFast"],"Connect your PayPal account":["Conecta tu cuenta de PayPal"],"There was an error connecting to WooCommerce Payments. Please try again or connect later in store settings.":["Ha habido un error al conectar con WooCommerce Payments. Por favor, int\u00e9ntalo de nuevo o con\u00e9ctalo m\u00e1s tarde en los ajustes de la tienda."],"WooCommerce Payments connected successfully.":["WooCommerce Payments conectado correctamente."],"Connect your Square account":["Conecta tu cuenta de Square"],"A Square account is required to process payments. You will be redirected to the Square website to create the connection.":["Se necesita una cuenta de Square para procesar los pagos. Ser\u00e1s redirigido a la web de Square para crear la conexi\u00f3n."],"Connect your store to your Stripe account. Don\u2019t have a Stripe account? Create one.":["Conecta tu tienda a tu cuenta de Stripe. \u00bfNo tienes una cuenta de Stripe? Crea una."],"A Stripe account is required to process payments.":["Se necesita una cuenta de Stripe para procesar los pagos."],"Connect your Stripe account":["Conecta tu cuenta de Stripe"],"Your API details can be obtained from your {{docsLink}}Stripe account{{\/docsLink}}. Don\u2019t have a Stripe account? {{registerLink}}Create one.{{\/registerLink}}":["Los detalles de la API pueden obtenerse desde tu {{docsLink}}cuenta de Stripe{{\/docsLink}}. \u00bfNo tienes una cuenta en Stripe? {{registerLink}}Crea una.{{\/registerLink}}"],"Please enter an account number or IBAN":["Por favor, introduce un n\u00famero de cuenta o IBAN"],"WooCommerce Payments":["WooCommerce Payments"],"These details are required to receive payments via bank transfer":["Estos detalles son obligatorios para recibir pagos mediante transferencia bancaria"],"Add your bank details":["A\u00f1ade los detalles de tu banco"],"Direct bank transfer details added successfully":["Detalles para transferencia bancaria directa a\u00f1adidos correctamente"],"There was a problem saving your payment settings":["Ha habido un problema al guardar tus ajustes de pago"],"Securely accept credit and debit cards with one low rate, no surprise fees (custom rates available). Sell online and in store and track sales and inventory in one place.":["Acepta de forma segura tarjetas de cr\u00e9dito y d\u00e9bito con una baja tarifa, sin cuotas sorpresa (disponibles tarifas personalizadas). Vende online y en tienda f\u00edsica y sigue las ventas y el inventario en un solo lugar."],"Accept debit and credit cards in 135+ currencies, methods such as Alipay, and one-touch checkout with Apple Pay.":["Acepta tarjetas de d\u00e9bito y cr\u00e9dito en m\u00e1s de 135 monedas, m\u00e9todos como Alipay y pago con un solo toque con Apple Pay."],"PayPal Checkout":["Pago con PayPal"],"Choose the payment that you want, pay now, pay later or slice it. No credit card numbers, no passwords, no worries.":["Elige el pago que quieras, pagar ahora, pagar m\u00e1s tarde o div\u00eddelo. Sin n\u00fameros de tarjeta, sin contrase\u00f1as, sin preocupaciones."],"Credit cards - powered by Stripe":["Tarjetas de cr\u00e9dito - gestionado por Stripe"],"Stripe connected successfully.":["Stripe conectado correctamente."],"There was an error connecting to Square. Please try again or skip to connect later in store settings.":["Ocurri\u00f3 un error al conectar con Square. Por favor, int\u00e9ntalo de nuevo o s\u00e1ltate este paso para conectarte m\u00e1s tarde en los ajustes de la tienda."],"Square connected successfully.":["Square conectado correctamente."],"Please enter your API password":["Por favor, introduce tu contrase\u00f1a de la API"],"Please enter your API username":["Por favor, introduce tu nombre de usuario de la API"],"There was a problem saving your payment settings.":["Ocurri\u00f3 un problema al guardar tus ajustes de pagos."],"Klarna can be configured under your {{link}}store settings{{\/link}}. Figure out {{helpLink}}what you need{{\/helpLink}}.":["Klarna se puede configurar en tus {{link}}ajustes de la tienda{{\/link}}. Descubre {{helpLink}}qu\u00e9 necesitas{{\/helpLink}}."],"PayPal connected successfully.":["PayPal conectado correctamente."],"Your API details can be obtained from your {{link}}PayFast account{{\/link}}":["Tus detalles de la API los puedes obtener en tu {{link}}cuenta de PayFast{{\/link}}"],"Please enter your merchant key":["Por favor, introduce tu clave de vendedor"],"Your API details can be obtained from your {{link}}eWAY account{{\/link}}":["Los detalles de tu API los puedes obtener en tu {{link}}cuenta de PayPal{{\/link}}"],"Proceed":["Ejecutar"],"The PayFast extension for WooCommerce enables you to accept payments by Credit Card and EFT via one of South Africa\u2019s most popular payment gateways. No setup fees or monthly subscription costs.":["La extensi\u00f3n PayFast para WooCommerce te permite aceptar pagos mediante tarjeta de cr\u00e9dito y EFT gracias a una de las pasarelas de pago m\u00e1s populares de Sud\u00e1frica. No hay cuotas de activaci\u00f3n ni costes de suscripci\u00f3n."],"The eWAY extension for WooCommerce allows you to take credit card payments directly on your store without redirecting your customers to a third party site to make payment.":["La extensi\u00f3n eWAY para WooCommerce te permite recibir pagos directamente por tarjeta de cr\u00e9dito en tu tienda sin redirigir a tus clientes a otro sitio para hacer el pago."],"Square":["Cuadrado"],"Klarna Payments":["Pagos Klarna"],"Klarna Checkout":["Pago con Klarna"],"Please enter a valid email address":["Por favor, introduce una direcci\u00f3n de correo electr\u00f3nico v\u00e1lida"],"Create a PayPal account for me":["Crear una cuenta PayPal para mi"],"Connect":["Conectar"],"Safe and secure payments using credit cards or your customer's PayPal account.":["Pagos seguros y protegidos usando tarjetas de cr\u00e9dito o la cuenta PayPal de tu cliente."],"Email address":["Direcci\u00f3n de correo electr\u00f3nico"],"IBAN":["IBAN"],"BIC \/ Swift":["BIC \/ Swift"],"Bank name":["Nombre del banco"],"Account number":["N\u00famero de cuenta"],"Account name":["Nombre de la cuenta"],"Direct bank transfer":["Transferencia bancaria directa"],"Sort code":["C\u00f3digo de clasificaci\u00f3n"],"API Username":["Nombre de usuario de la API"],"API Password":["Contrase\u00f1a de la API"],"Save":["Guardar"],"Cash on delivery":["Contra reembolso"],"Continue":["Seguir"],"Settings":["Ajustes"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/chunks\/9.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1e6e582c38fd3046aa3c225009d2a90c.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1e6e582c38fd3046aa3c225009d2a90c.json new file mode 100644 index 0000000..2746f9d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1e6e582c38fd3046aa3c225009d2a90c.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Product on sale":["Producto en oferta"],"Sale":["Oferta"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/sale-badge\/block.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1ea5d0886ad91cfcb79dbb02979efdc3.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1ea5d0886ad91cfcb79dbb02979efdc3.json new file mode 100644 index 0000000..337154a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1ea5d0886ad91cfcb79dbb02979efdc3.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"No posts yet":["Todav\u00eda no hay entradas"],"Oops, our posts aren't loading right now":["Vaya, nuestras entradas no se est\u00e1n cargando justo ahora"],"Read {{link}}the WooCommerce blog{{\/link}} for more tips on marketing your store":["Lee el {{link}}blog de WooCommerce{{\/link}} para m\u00e1s trucos sobre c\u00f3mo hacer marketing en tu tienda"],"Recommended coupon extensions":["Extensiones de cup\u00f3n recomendadas"],"Take your coupon marketing to the next level with our recommended coupon extensions.":["Lleva tu marketing de cupones al siguiente nivel con nuestras extensiones de cupones recomendadas."],"Learn the ins and outs of successful coupon marketing from the experts at WooCommerce.":["Aprende los entresijos del marketing exitoso de cupones de los expertos de WooCommerce."],"The extension has been successfully activated.":["La extensi\u00f3n se ha activado correctamente."],"WooCommerce knowledge base":["Base de conocimientos de WooCommerce"],"There was an error loading recommended extensions.":["Ha habido un error al cargar las extensiones recomendadas."],"There was an error loading installed extensions.":["Ha habido un error al cargar las extensiones instaladas."],"There was an error trying to activate the extension.":["Ha habido un error al intentar activar la extensi\u00f3n."],"Learn the ins and outs of successful marketing from the experts at WooCommerce.":["Aprende los entresijos de un marketing de \u00e9xito de los expertos de WooCommerce."],"Great marketing requires the right tools. Take your marketing to the next level with our recommended marketing extensions.":["Un gran marketing necesita las herramientas adecuadas. Lleva tu marketing al siguiente nivel con nuestras extensiones de marketing recomendadas."],"Recommended extensions":["Extensiones recomendadas"],"Comma":["Coma"],"Backtick":["Acento grave"],"Mutable settings should be mutated via data store.":["Los ajustes modificables deben modificarse a trav\u00e9s del almacenamiento de datos."],"Mutable settings should be accessed via data store.":["Los ajustes modificables deber\u00edan ser accesibles a trav\u00e9s del almacenamiento de datos."],"Period":["Per\u00edodo"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/wp-admin-scripts\/marketing-coupons.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1fce6066a1f86a34fccc35420cf1071e.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1fce6066a1f86a34fccc35420cf1071e.json new file mode 100644 index 0000000..030a39f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1fce6066a1f86a34fccc35420cf1071e.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Sorry, an error occurred":["Lo siento, ha ocurrido un error"],"Retry":["Volver a intentar"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/editor-components\/error-placeholder\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1fd108afcd6b1150ccd257c03371fcf4.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1fd108afcd6b1150ccd257c03371fcf4.json new file mode 100644 index 0000000..8af560b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1fd108afcd6b1150ccd257c03371fcf4.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Display a grid of products currently on sale.":["Muestra una cuadr\u00edcula de productos actualmente rebajados."],"On Sale Products":["Productos en oferta"],"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/product-on-sale\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1ff2b9879bf907d438b0a402676a8c76.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1ff2b9879bf907d438b0a402676a8c76.json new file mode 100644 index 0000000..84cd4f3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-1ff2b9879bf907d438b0a402676a8c76.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Log in.":["Acceder."],"Already have an account? ":["\u00bfYa tienes una cuenta? "]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/cart-checkout\/checkout\/form\/login-prompt.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-202a71ed52f50963a82272da6ac2c610.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-202a71ed52f50963a82272da6ac2c610.json new file mode 100644 index 0000000..c61dd15 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-202a71ed52f50963a82272da6ac2c610.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"categories\u0004Excludes":["Excluye"],"categories\u0004Includes":["Incluye"],"Select categories":["Seleccionar categor\u00edas"],"{{title}}Category{{\/title}} {{rule \/}} {{filter \/}}":["{{title}}Categor\u00eda{{\/title}} {{rule \/}} {{filter \/}}"],"Remove categories filter":["Eliminar el filtro de categor\u00edas"],"A sentence describing filters for Variations. See screen shot for context: https:\/\/cloudup.com\/cSsUY9VeCVJ\u0004Variations Match {{select \/}} Filters":["Variaciones que coinciden con los filtros {{select \/}}"],"Select a category filter match":["Selecciona una coincidencia de filtro de categor\u00eda"],"product attribute\u0004Is Not":["No es"],"product attribute\u0004Is":["Es"],"Select attributes":["Seleccionar atributos"],"Select a product attribute filter match":["Selecciona una coincidencia de filtro de atributo de producto"],"Remove attribute filter":["Quitar el filtro de atributos"],"Search attributes":["Buscar atributos"],"Type to search for a variation":["Escribe para buscar una variaci\u00f3n"],"Single Variation":["Variaci\u00f3n simple"],"Check at least two variations below to compare":["Selecciona a menos dos variaciones de las siguientes para compararlas"],"Indication of a low quantity\u0004Low":["Baja"],"Search by variation name or SKU":["Buscar por nombre de variaci\u00f3n o SKU"],"variation sold":["variaci\u00f3n vendida","variaciones vendidas"],"%d variations":["%d variaciones"],"All Variations":["Todas las variaciones"],"Compare Variations":["Comparar variaciones"],"Search for variations to compare":["Busca variaciones para compararlas"],"net sales":["ventas netas"],"products\u0004Excludes":["Excluido"],"products\u0004Includes":["Incluido"],"Select products":["Seleccionar productos"],"Remove products filter":["Quitar filtro de productos"],"{{title}}Product{{\/title}} {{rule \/}} {{filter \/}}":["{{title}}Producto{{\/title}} {{rule \/}} {{filter \/}}"],"Select a product filter match":["Elige una coincidencia de filtro de producto"],"Advanced Filters":["Filtros avanzados"],"item sold":["art\u00edculo vendido","art\u00edculos vendidos"],"Comparison":["Comparaci\u00f3n"],"Previous Year:":["A\u00f1o anterior:"],"No data for the selected date range":["No hay datos en el rango de fechas solicitado"],"No data for the current search":["No hay datos para la b\u00fasqueda actual"],"{{title}}Attribute{{\/title}} {{rule \/}} {{filter \/}}":["{{title}}Atributo{{\/title}} {{rule \/}} {{filter \/}}"],"Product \/ Variation Title":["Producto \/ T\u00edtulo de la variaci\u00f3n"],"Net Sales":["Ventas netas"],"Items Sold":["Art\u00edculos vendidos"],"Compare":["Comparar"],"Previous Period:":["Periodo anterior:"],"TAX":["IMPUESTO"],"Search categories":["Buscar categor\u00edas"],"Attribute":["Atributo"],"Search products":["Buscar productos"],"Show":["Mostrar"],"orders":["pedidos","pedidos"],"Products":["Productos"],"Variations":["Variaciones"],"SKU":["SKU"],"Categories":["Categor\u00edas"],"Status":["Estado"],"Orders":["Pedidos"],"Stock":["Inventario"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/chunks\/analytics-report-variations.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-206459d169f12b652a1dabe78a376826.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-206459d169f12b652a1dabe78a376826.json new file mode 100644 index 0000000..b48e61c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-206459d169f12b652a1dabe78a376826.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Display a grid of products from your selected categories.":["Muestra una cuadr\u00edcula de productos de las categor\u00edas que elijas"],"Products by Category":["Productos por categor\u00eda"],"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/product-category\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-20e7fc3ea96346f2d1f05ca5e7847392.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-20e7fc3ea96346f2d1f05ca5e7847392.json new file mode 100644 index 0000000..6b45c3a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-20e7fc3ea96346f2d1f05ca5e7847392.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"The last inner block will follow other content.":["El \u00faltimo bloque interior seguir\u00e1 al resto del contenido."],"The last inner block will be aligned vertically.":["El \u00faltimo bloque interior se alinear\u00e1 verticalmente"],"Align Last Block":["Alinear \u00faltimo bloque"],"Rows":["Filas"],"Columns":["Columnas"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/editor-components\/grid-layout-control\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-21fee52f2b4be704278bd81018c89b15.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-21fee52f2b4be704278bd81018c89b15.json new file mode 100644 index 0000000..a67c28c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-21fee52f2b4be704278bd81018c89b15.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"\u2026":["\u2026"],"Navigate to another page":["Navegar a otra p\u00e1gina"],"Next page":["P\u00e1gina siguiente"],"Previous page":["P\u00e1gina anterior"],"Page %d":["P\u00e1gina %d"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/base\/components\/pagination\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-23a5d7b5185c7352a40e30649d5daad8.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-23a5d7b5185c7352a40e30649d5daad8.json new file mode 100644 index 0000000..8f98125 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-23a5d7b5185c7352a40e30649d5daad8.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Creative Mail for WooCommerce":["Creative Mail para WooCommerce"],"WooCommerce Shipping & Tax":["WooCommerce Shipping & Tax"],"Google Ads":["Google Ads"],"WooCommerce PayPal":["WooCommerce PayPal"],"WooCommerce Payments":["WooCommerce Payments"],"WooCommerce PayFast":["WooCommerce PayFast"],"WooCommerce Stripe":["WooCommerce Stripe"],"WooCommerce ShipStation Gateway":["WooCommerce ShipStation Gateway"],"There was a problem updating your settings.":["Ha habido un problema al actualizar tus ajustes."],"MM\/DD\/YYYY":["DD\/MM\/YYYY"],"Facebook for WooCommerce":["Facebook for WooCommerce"],"Mailchimp for WooCommerce":["Mailchimp for WooCommerce"],"Klarna Payments for WooCommerce":["Klarna Payments for WooCommerce"],"Klarna Checkout for WooCommerce":["Klarna Checkout for WooCommerce"],"Jetpack":["Jetpack"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/data\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-25681209877dbbf4b351e01720af480c.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-25681209877dbbf4b351e01720af480c.json new file mode 100644 index 0000000..592836c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-25681209877dbbf4b351e01720af480c.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Orange":["Naranja"],"Lightweight baseball cap":["Gorra de beisbol ligera"],"Cap":["Gorra"],"Yellow":["Amarillo"],"Warm hat for winter":["Sombrero caliente de invierno"],"Beanie":["Gorro"],"Color":["Color"],"Small":["Peque\u00f1o"],"Size":["Tama\u00f1o"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/previews\/cart.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-266b21f550f6c336217746f77332e8d9.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-266b21f550f6c336217746f77332e8d9.json new file mode 100644 index 0000000..65d4e83 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-266b21f550f6c336217746f77332e8d9.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Category images are hidden.":["Las im\u00e1genes de las categor\u00edas est\u00e1n ocultas."],"Category images are visible.":["Las im\u00e1genes de las categor\u00edas son visibles."],"Show category images":["Mostrar im\u00e1genes de categor\u00edas"],"Display style":["Estilo de visualizaci\u00f3n"],"List Settings":["Ajustes de la lista"],"Empty categories are hidden.":["Las categor\u00edas vac\u00edas est\u00e1n ocultas."],"Empty categories are visible.":["Las categor\u00edas vac\u00edas son visibles."],"Show empty categories":["Mostrar categor\u00edas vac\u00edas"],"Hierarchy is hidden.":["La jerarqu\u00eda est\u00e1 oculta."],"Hierarchy is visible.":["La jerarqu\u00eda es visible."],"Product count is hidden.":["La cantidad de productos est\u00e1 oculta."],"Product count is visible.":["La cantidad de productos es visible."],"Show product count":["Mostrar cantidad de productos"],"Product Categories List":["Lista de categor\u00edas de productos"],"This block shows product categories for your store. To use it, you'll first need to create a product and assign it to a category.":["Este bloque muestra las categor\u00edas de productos de tu tienda. Para usarlo primero tienes que crear un producto y asignarlo a una categor\u00eda."],"List":["Lista"],"Dropdown":["Lista desplegable"],"Show hierarchy":["Mostrar jerarqu\u00eda"],"Content":["Contenido"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/product-categories\/block.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-272ce40a99e1a33c3ee6c9cbce70cc33.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-272ce40a99e1a33c3ee6c9cbce70cc33.json new file mode 100644 index 0000000..0aac111 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-272ce40a99e1a33c3ee6c9cbce70cc33.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Product Stock Indicator":["Indicador del inventario del producto"],"Display product stock status.":["Mostrar el estado del inventario del producto."]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/stock-indicator\/constants.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2744127682072dcdf2583cd6dc64ce99.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2744127682072dcdf2583cd6dc64ce99.json new file mode 100644 index 0000000..a0940f6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2744127682072dcdf2583cd6dc64ce99.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Display a list of categories belonging to a product.":["Muestra una lista de categor\u00edas pertenecientes a un producto."],"Product Category List":["Lista de categor\u00edas del producto"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/category-list\/constants.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-275818e8b4218da8c54856bdf290d8f6.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-275818e8b4218da8c54856bdf290d8f6.json new file mode 100644 index 0000000..963b2ff --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-275818e8b4218da8c54856bdf290d8f6.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Comma":["Coma"],"Backtick":["Acento grave"],"%s stock could not be updated.":["El inventario de %s no se pudo actualizar."],"%s stock updated.":["Inventario de %s actualizado."],"No products with low stock":["No hay productos con pocas existencias."],"There was an error getting your low stock products. Please try again.":["Hubo un error al recuperar tus productos con pocas existencias. Por favor, int\u00e9ntalo de nuevo."],"You currently have no products running low on stock.":["Actualmente no tienes ning\u00fan producto con pocas existencias."],"Your stock is in good shape.":["Tus existencias est\u00e1n en buena forma."],"Update stock":["Actualizar inventario"],"%d in stock":["Hay %d existencias"],"in stock":["con existencias"],"Reload":["Recargar"],"Save":["Guardar"],"Period":["Per\u00edodo"],"Cancel":["Cancelar"],"Stock":["Inventario"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/chunks\/activity-panels-stock.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-27c3c96efb4bdb0e7c38db93c5b151be.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-27c3c96efb4bdb0e7c38db93c5b151be.json new file mode 100644 index 0000000..257818a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-27c3c96efb4bdb0e7c38db93c5b151be.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Tags:":["Etiquetas:"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/atomic-block-components\/tag-list-frontend.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-28373221fc2f980b198a22af0e736c42.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-28373221fc2f980b198a22af0e736c42.json new file mode 100644 index 0000000..1e78fac --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-28373221fc2f980b198a22af0e736c42.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Product on sale":["Producto en oferta"],"Sale":["Oferta"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/atomic-block-components\/sale-badge-frontend.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-287f246e61a201cec5ac1e37a10190bc.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-287f246e61a201cec5ac1e37a10190bc.json new file mode 100644 index 0000000..e952a9b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-287f246e61a201cec5ac1e37a10190bc.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Display a checkout form so your customers can submit orders.":["Muestra un formulario de pago para que tus clientes puedan hacer pedidos."],"Checkout":["Finalizar compra"],"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/cart-checkout\/checkout\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a130218c40b2b37eedb3857f22c90a1.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a130218c40b2b37eedb3857f22c90a1.json new file mode 100644 index 0000000..f438ca5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a130218c40b2b37eedb3857f22c90a1.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"g:ia":["G:i"],"F j, Y":["j F, Y"],"{{attribute \/}} {{equals \/}} {{value \/}}":["{{attribute \/}} {{equals \/}} {{value \/}}"],"Abort":["Abortar"],"Press the down arrow key to interact with the calendar and select a date.":["Pulsa la tecla de flecha abajo para interactuar con el calendario y seleccionar una fecha."],"Comma":["Coma"],"Backtick":["Acento grave"],"Add an image":["A\u00f1ade una imagen"],"Select or upload image":["Selecciona o sube una imagen"],"Continue without installing":["Continuar sin instalar"],"Install & enable":["Instalar y activar"],"No data to display":["No hay datos para mostrar"],"Attribute value":["Valor del atributo."],"Retry":["Volver a intentar"],"+%d more":["+%d m\u00e1s"],"Columns:":["Columnas:"],"Sort by %s in descending order":["Ordenar por %s en orden descendente"],"Sort by %s in ascending order":["Ordenar por %s en orden ascendente"],"(scroll to see more)":["(scroll para ver m\u00e1s)"],"Previous Period:":["Periodo anterior:"],"%d%%":["%d%%"],"No change from %s":["Ning\u00fan cambio desde %s"],"Down %d%% from %s":["Abajo %d%% desde %s"],"Up %d%% from %s":["Arriba %d%% desde %s"],"Performance Indicators":["Indicadores de rendimiento"],"Search results updated.":["Resultados de b\u00fasqueda actualizados."],"%d item selected":["%d art\u00edculo seleccionado","%d art\u00edculos seleccionados"],"Search for items":["Buscar art\u00edculos"],"Results":["Resultados"],"Filters":["Filtros"],"%1$s out of %2$s stars.":["%1$s de %2$s estrellas."],"Go to page":["Ir a la p\u00e1gina"],"Next Page":["P\u00e1gina siguiente"],"Previous Page":["P\u00e1gina anterior"],"Page %d of %d":["P\u00e1gina %d de %d"],"Date Range":["Rango de fechas"],"select a date range":["selecciona un rango de fechas"],"Start Date":["Fecha de inicio"],"%s is not selectable.":["%s no se puede seleccionar."],"Go to the first or last day of a week.":["Ir al primer o \u00faltimo d\u00eda de una semana."],"Switch months.":["Cambiar de mes."],"Question mark":["Signo de interrogaci\u00f3n"],"Clear Dates":["Vaciar fechas"],"Clear Date":["Vaciar fecha"],"Interact with the calendar and select start and end dates.":["Interact\u00faa con el calendario y selecciona las fechas de inicio y fin."],"Calendar":["Calendario"],"compare to":["comparar con"],"Total %d":["Total %d"],"Bar chart":["Gr\u00e1fico de barras"],"Line chart":["Gr\u00e1fico de l\u00edneas"],"By year":["Por a\u00f1o"],"By quarter":["Por trimestre"],"By month":["Por mes"],"By week":["Por semana"],"By day":["Por d\u00eda"],"By hour":["Por hora"],"Clear all filters":["Vaciar todos los filtros"],"Add a Filter":["A\u00f1ade un filtro"],"select a date":["selecciona una fecha"],"Choose a date":["Elige una fecha"],"%(field)s range end":["%(field)s fin del rango"],"%(field)s range start":["%(field)s inicio del rango"],"minimum value input\u0004%(field)s minimum amount":["%(field)s cantidad m\u00ednima"],"maximum value input\u0004%(field)s maximum amount":["%(field)s cantidad m\u00e1xima"],"Numerical range inputs arranged on a single line\u0004{{rangeStart \/}}{{span}} and {{\/span}}{{rangeEnd \/}}":["{{rangeStart \/}}{{span}} y {{\/span}}{{rangeEnd \/}}"],"Clear all":["Vaciar todo"],"%1$s (%2$s of %3$s)":["%1$s (%2$s de %3$s)"],"Remove %s":["Quitar %s"],"TAX":["IMPUESTO"],"Return to the date input field.":["Volver al campo de introducci\u00f3n de fecha."],"Date range inputs arranged on a single line\u0004{{after \/}}{{span}} and {{\/span}}{{before \/}}":["{{after \/}}{{span}} y {{\/span}}{{before \/}}"],"Choose which values to display":["Elije qu\u00e9 valores mostrar"],"List of data points available for filtering. Use arrow keys to cycle through the list. Click a data point for a detailed report.":["Lista de puntos de datos disponibles para el filtrado. Utiliza las teclas de flecha para desplazarte por la lista. Haz clic en un punto de datos para obtener un informe detallado."],"Move backward for selected items":["Retrocede a los art\u00edculos seleccionados"],"All taxes with codes that include {{query \/}}":["Todos los impuestos con c\u00f3digos que incluyan {{query \/}}"],"All products with titles that include {{query \/}}":["Todos los productos con t\u00edtulos que incluyan {{query \/}}"],"All customers with names that include {{query \/}}":["Todos los clientes con nombres que incluyan {{query \/}}"],"All coupons with codes that include {{query \/}}":["Todos los cupones con c\u00f3digos que incluyan {{query \/}}"],"All categories with titles that include {{query \/}}":["Todas las categor\u00edas con t\u00edtulos que incluyan {{query \/}}"],"No results.":["Ning\u00fan resultado."],"%d result found, use up and down arrow keys to navigate.":["%d resultado encontrado, usa las teclas de flecha arriba y abajo para navegar.","%d resultados encontrados, usa las teclas de flecha arriba y abajo para navegar."],"No results for %s":["No hay resultados para %s"],"No items found.":["No se encontraron art\u00edculos."],"Clear all selected items":["Vaciar todos los art\u00edculos seleccionados"],"filter report to show:":["filtro del informe a mostrar:"],"select a preset period":["selecciona un periodo de preajuste"],"vs.":["frente al"],"Presets":["Preajustes"],"Select date range and comparison":["Selecciona un rango de fechas a comparar"],"Choose to apply any or all filters":["Elige si aplicar alguno o todos los filtros"],"MM\/DD\/YYYY":["DD\/MM\/YYYY"],"MMM D, YYYY":["D MMM, YYYY"],"Your requested data is loading":["Los datos que has solicitado se est\u00e1n cargando"],"You may select up to %d items.":["Puedes seleccionar hasta %d art\u00edculos."],"Selected. %s":["Seleccionada. %s"],"Select %s as an end date.":["Seleccionar %s como fecha de fin."],"Select %s as a start date.":["Seleccionar %s como fecha de inicio."],"Move backward (up) and forward (down) by one week.":["Mu\u00e9vete atr\u00e1s (arriba) y adelante (abajo) de semana en semana."],"Move backward (left) and forward (right) by one day.":["Mu\u00e9vete atr\u00e1s (izquierda) y adelante (derecha) de d\u00eda en d\u00eda."],"Select the date in focus.":["Selecciona la fecha en cuesti\u00f3n."],"Escape key":["Tecla Escape"],"Home and end keys":["Teclas Inicio y Fin"],"page up and page down keys":["teclas de p\u00e1gina arriba y p\u00e1gina abajo"],"up and down arrow keys":["teclas de flechas arriba y abajo"],"Right and left arrow keys":["Teclas de flechas izquierda y derecha"],"Enter key":["Tecla Intro"],"Move forward to switch to the next month.":["Mover hacia delante para cambiar al mes siguiente."],"Move backward to switch to the previous month.":["Mover hacia atr\u00e1s para cambiar al mes anterior."],"Date input describing a selected date range's end date in format %s":["Anotaci\u00f3n de fecha que describe la fecha final de un rango de fechas seleccionado en formato %s"],"End Date":["Fecha de fin"],"Date input describing a selected date range's start date in format %s":["Anotaci\u00f3n de fecha que describe la fecha de inicio de un rango de fechas seleccionado en formato %s"],"Date input describing a selected date in format %s":["Anotaci\u00f3n de fecha que describe una fecha seleccionada en formato %s"],"Rows per page":["Filas por p\u00e1gina"],"Attribute name":["Nombre del atributo"],"Select":["Seleccionar"],"Filter":["Filtrar"],"to":["hasta"],"Custom":["Personalizado"],"Notifications":["Avisos"],"Close":["Cerrar"],"Period":["Per\u00edodo"],"Reset":["Restablecer"],"Any":["Cualquiera"],"All":["Todos"],"Remove image":["Quitar imagen"],"N\/A":["N\/D"],"No thanks":["No, gracias"],"Continue":["Seguir"],"Update":["Actualizar"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/components\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a131eb5bf930c716935378d6cbb25d2.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a131eb5bf930c716935378d6cbb25d2.json new file mode 100644 index 0000000..2f66ff4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a131eb5bf930c716935378d6cbb25d2.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Direct bank transfer":["Transferencia bancaria directa"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/wc-payment-method-bacs.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a4f5667ed4e81d44f6ccfb84523b904.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a4f5667ed4e81d44f6ccfb84523b904.json new file mode 100644 index 0000000..8387751 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a4f5667ed4e81d44f6ccfb84523b904.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"This block lists reviews for a selected product. %s doesn't have any reviews yet, but they will show up here when it does.":["Este bloque lista las valoraciones de un producto seleccionado. %s todav\u00eda no tiene valoraciones, pero se mostrar\u00e1n aqu\u00ed cuando las tenga."],"Reviews by Product":["Valoraciones por producto"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/reviews\/reviews-by-product\/no-reviews-placeholder.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a7eca80ba12897c21ffaa74974c8fef.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a7eca80ba12897c21ffaa74974c8fef.json new file mode 100644 index 0000000..f569b67 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2a7eca80ba12897c21ffaa74974c8fef.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"All Reviews":["Todas las valoraciones"],"Show a list of all product reviews.":["Muestra una lista de todas las valoraciones de productos."],"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/reviews\/all-reviews\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2af5e068de293517b1bb2cfc58cf9989.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2af5e068de293517b1bb2cfc58cf9989.json new file mode 100644 index 0000000..a9a8827 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2af5e068de293517b1bb2cfc58cf9989.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Tags:":["Etiquetas:"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/tag-list\/block.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2cd54bc9eeab906cf0f6abb2399e9fb7.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2cd54bc9eeab906cf0f6abb2399e9fb7.json new file mode 100644 index 0000000..2345fc3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2cd54bc9eeab906cf0f6abb2399e9fb7.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Mutable settings should be mutated via data store.":["Los ajustes modificables deben modificarse a trav\u00e9s del almacenamiento de datos."],"Mutable settings should be accessed via data store.":["Los ajustes modificables deber\u00edan ser accesibles a trav\u00e9s del almacenamiento de datos."],"Continue setup.":["Continuar con la configuraci\u00f3n."],"You've added your first tax rate!":["\u00a1Has a\u00f1adido tu primera tasa de impuestos!"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/wp-admin-scripts\/onboarding-tax-notice.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2d000e7ced69fed51ef7de882445014e.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2d000e7ced69fed51ef7de882445014e.json new file mode 100644 index 0000000..f573e08 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2d000e7ced69fed51ef7de882445014e.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"SKU:":["SKU:"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/sku\/block.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2e2892cb61344eb4fdac4c1e37619262.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2e2892cb61344eb4fdac4c1e37619262.json new file mode 100644 index 0000000..c52765a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2e2892cb61344eb4fdac4c1e37619262.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Check at least two categories below to compare":["Selecciona al menos dos categor\u00edas de las siguientes para compararlas"],"Search by category name":["Buscar por nombre de categor\u00eda"],"category":["categor\u00eda","categor\u00edas"],"%d categories":["%d categor\u00edas"],"%d products":["%d productos"],"Compare Categories":["Comparar categor\u00edas"],"Search for categories to compare":["Busca categor\u00edas para compararlas"],"Single Category":["Categor\u00eda \u00fanica"],"Type to search for a category":["Teclea para buscar una categor\u00eda"],"All Categories":["Todas las categor\u00edas"],"net sales":["ventas netas"],"order":["pedido","pedidos"],"item sold":["art\u00edculo vendido","art\u00edculos vendidos"],"Comparison":["Comparaci\u00f3n"],"Net Sales":["Ventas netas"],"Items Sold":["Art\u00edculos vendidos"],"Compare":["Comparar"],"Category":["Categor\u00eda"],"Show":["Mostrar"],"Products":["Productos"],"Categories":["Categor\u00edas"],"Orders":["Pedidos"]}},"comment":{"reference":"packages\/woocommerce-admin\/dist\/chunks\/analytics-report-categories.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2e5b773a600e6595bad14136c2d73f08.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2e5b773a600e6595bad14136c2d73f08.json new file mode 100644 index 0000000..06271bd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2e5b773a600e6595bad14136c2d73f08.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Show the currently active product filters. Works in combination with the All Products and filters blocks.":["Muestra el filtro de productos actualmente activos. Funciona en combinaci\u00f3n con los bloques de todos los productos y de filtrado."],"Active Product Filters":["Filtros de productos activos"],"Active filters":["Filtros activos"],"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/active-filters\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2e8ff1f945781cdab678c7cf64caff6f.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2e8ff1f945781cdab678c7cf64caff6f.json new file mode 100644 index 0000000..f161650 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2e8ff1f945781cdab678c7cf64caff6f.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"SKU:":["SKU:"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/atomic-block-components\/sku.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2ea015f5a250d849138bc331f2668c60.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2ea015f5a250d849138bc331f2668c60.json new file mode 100644 index 0000000..a48c244 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2ea015f5a250d849138bc331f2668c60.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Product on sale":["Producto en oferta"],"Sale":["Oferta"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/atomic-block-components\/image-frontend.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2ff2080d2d38b66bf6e2d5e3d2c64bb5.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2ff2080d2d38b66bf6e2d5e3d2c64bb5.json new file mode 100644 index 0000000..893a93a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-2ff2080d2d38b66bf6e2d5e3d2c64bb5.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Shopping cart.":["Carrito de compras."],"Cart":["Carrito"],"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/cart-checkout\/cart\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-3239989f0cbcc3489b2cf8c18d04dc05.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-3239989f0cbcc3489b2cf8c18d04dc05.json new file mode 100644 index 0000000..dd1749d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-3239989f0cbcc3489b2cf8c18d04dc05.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"%1$s (%2$d unit)":["%1$s (%2$d unidad)","%1$s (%2$d unidades)"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/base\/components\/cart-checkout\/shipping-rates-control\/package.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-324138858b6bcb278c27e314613e684c.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-324138858b6bcb278c27e314613e684c.json new file mode 100644 index 0000000..2a60199 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-324138858b6bcb278c27e314613e684c.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Edit your cart":["Edita tu carrito"],"Please edit your cart and try again.":["Por favor, modifica tu carrito e int\u00e9ntalo de nuevo."],"There is a problem with your cart":["Ha habido un problema con tu carrito"],"Checkout error":["Error al finalizar compra"],"There was a problem checking out. Please try again. If the problem persists, please get in touch with us so we can assist.":["Ha ocurrido un problema durante el registro. Por favor, int\u00e9ntalo de nuevo. Si persiste el problema, por favor, ponte en contacto con nosotros para que podamos ayudarte."],"Retry":["Volver a intentar"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/cart-checkout\/checkout\/checkout-order-error\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-3305d9de59961a847c212b100798fb50.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-3305d9de59961a847c212b100798fb50.json new file mode 100644 index 0000000..e59bc3d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-3305d9de59961a847c212b100798fb50.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Discounted price:":["Precio con descuento:"],"Previous price:":["Precio anterior:"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/atomic-block-components\/price-frontend.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-34b7393e5b07373be089898508bfd837.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-34b7393e5b07373be089898508bfd837.json new file mode 100644 index 0000000..ee675af --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-34b7393e5b07373be089898508bfd837.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Payment Methods":["M\u00e9todos de pago"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/base\/components\/payment-methods\/payment-method-options.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-354416042f4f6ddf578099737d7be093.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-354416042f4f6ddf578099737d7be093.json new file mode 100644 index 0000000..ee06742 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-354416042f4f6ddf578099737d7be093.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Please select a value.":["Por favor, selecciona un valor."]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/base\/components\/select\/validated.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-36e7818bfdfd4a6943db89e1565c4cc7.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-36e7818bfdfd4a6943db89e1565c4cc7.json new file mode 100644 index 0000000..eca6af1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-36e7818bfdfd4a6943db89e1565c4cc7.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"A search box to allow customers to search for products by keyword.":["Una caja de b\u00fasqueda para permitir a los clientes buscar productos mediante el teclado."],"Search products\u2026":["Buscar productos..."],"Product Search":["B\u00fasqueda de productos"],"Search":["Buscar"],"WooCommerce":["WooCommerce"]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/blocks\/product-search\/index.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-376011c6441a11bdb03699ed8ce0becc.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-376011c6441a11bdb03699ed8ce0becc.json new file mode 100644 index 0000000..1f07627 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-376011c6441a11bdb03699ed8ce0becc.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Between %1$s and %2$s":["Entre %1$s y %2$s"],"Remove \"%s\"":["Eliminar \u00ab%s\u00bb"],"Clear All Filters":["Vaciar todos los filtros"],"Remove %s filter":["Eliminar el filtro %s"],"Clear All":["Vaciar todo"],"Blue":["Azul"],"Color":["Color"],"Small":["Peque\u00f1o"],"Size":["Tama\u00f1o"],"Up to %s":["Hasta %s"],"From %s":["Desde %s"],"Oops!":["\u00a1Vaya!"],"There was an error loading the content.":["Ha habido un error al cargar este contenido."],"Error:":["Error:"],"and":["y"],"Price":["Precio"],"Remove":["Eliminar"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/active-filters-frontend.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-38946f5d8b83961eb0af530272a1d081.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-38946f5d8b83961eb0af530272a1d081.json new file mode 100644 index 0000000..509472f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-38946f5d8b83961eb0af530272a1d081.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"Choose a product to display its categories.":["Elige un producto para mostrar sus categor\u00edas."]}},"comment":{"reference":"packages\/woocommerce-blocks\/assets\/js\/atomic\/blocks\/product-elements\/category-list\/edit.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-38b8e72fdda975a53bd48996f0a154e3.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-38b8e72fdda975a53bd48996f0a154e3.json new file mode 100644 index 0000000..a8ca277 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-38b8e72fdda975a53bd48996f0a154e3.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"%d left in stock":["Quedan %d disponibles"],"In Stock":["Con existencias"],"Out of Stock":["Sin existencias"],"Available on backorder":["Disponible para reserva"]}},"comment":{"reference":"packages\/woocommerce-blocks\/build\/atomic-block-components\/stock-indicator-frontend.js"}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-3925e1feb7b90b12ac3114967c21e6f9.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-3925e1feb7b90b12ac3114967c21e6f9.json new file mode 100644 index 0000000..c5ae475 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/languages/plugins/woocommerce-es_ES-3925e1feb7b90b12ac3114967c21e6f9.json @@ -0,0 +1 @@ +{"translation-revision-date":"2020-12-08 17:56:20+0000","generator":"GlotPress\/3.0.0-alpha.2","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=2; plural=n != 1;","lang":"es"},"There was an error registering the payment method with id '%s': ":["Ocurri\u00f3 un error al registrar el m\u00e9todo de pago con el id '%s':"],"%1$s (%2$d unit)":["%1$s (%2$d unidad)","%1$s (%2$d unidades)"],"Remove \"%s\"":["Eliminar \u00ab%s\u00bb"],"Shipping to %s":["Enviar a %s"],"The cart has encountered an unexpected error. ' + + ''; + $items.append( $row ); + + return false; + }, + + remove: function() { + if ( window.confirm( woocommerce_admin_meta_boxes.remove_item_meta ) ) { + var $row = $( this ).closest( 'tr' ); + $row.find( ':input' ).val( '' ); + $row.hide(); + } + return false; + } + }, + + backbone: { + + init: function( e, target ) { + if ( 'wc-modal-add-products' === target ) { + $( document.body ).trigger( 'wc-enhanced-select-init' ); + + $( this ).on( 'change', '.wc-product-search', function() { + if ( ! $( this ).closest( 'tr' ).is( ':last-child' ) ) { + return; + } + var item_table = $( this ).closest( 'table.widefat' ), + item_table_body = item_table.find( 'tbody' ), + index = item_table_body.find( 'tr' ).length, + row = item_table_body.data( 'row' ).replace( /\[0\]/g, '[' + index + ']' ); + + item_table_body.append( '' + row + '' ); + $( document.body ).trigger( 'wc-enhanced-select-init' ); + } ); + } + }, + + response: function( e, target, data ) { + if ( 'wc-modal-add-tax' === target ) { + var rate_id = data.add_order_tax; + var manual_rate_id = ''; + + if ( data.manual_tax_rate_id ) { + manual_rate_id = data.manual_tax_rate_id; + } + + wc_meta_boxes_order_items.backbone.add_tax( rate_id, manual_rate_id ); + } + if ( 'wc-modal-add-products' === target ) { + // Build array of data. + var item_table = $( this ).find( 'table.widefat' ), + item_table_body = item_table.find( 'tbody' ), + rows = item_table_body.find( 'tr' ), + add_items = []; + + $( rows ).each( function() { + var item_id = $( this ).find( ':input[name="item_id"]' ).val(), + item_qty = $( this ).find( ':input[name="item_qty"]' ).val(); + + add_items.push( { + 'id' : item_id, + 'qty': item_qty ? item_qty: 1 + } ); + } ); + + return wc_meta_boxes_order_items.backbone.add_items( add_items ); + } + }, + + add_items: function( add_items ) { + wc_meta_boxes_order_items.block(); + + var data = { + action : 'woocommerce_add_order_item', + order_id : woocommerce_admin_meta_boxes.post_id, + security : woocommerce_admin_meta_boxes.order_item_nonce, + data : add_items + }; + + // Check if items have changed, if so pass them through so we can save them before adding a new item. + if ( 'true' === $( 'button.cancel-action' ).attr( 'data-reload' ) ) { + data.items = $( 'table.woocommerce_order_items :input[name], .wc-order-totals-items :input[name]' ).serialize(); + } + + $.ajax({ + type: 'POST', + url: woocommerce_admin_meta_boxes.ajax_url, + data: data, + success: function( response ) { + if ( response.success ) { + $( '#woocommerce-order-items' ).find( '.inside' ).empty(); + $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html ); + + // Update notes. + if ( response.data.notes_html ) { + $( 'ul.order_notes' ).empty(); + $( 'ul.order_notes' ).append( $( response.data.notes_html ).find( 'li' ) ); + } + + wc_meta_boxes_order_items.reloaded_items(); + wc_meta_boxes_order_items.unblock(); + } else { + wc_meta_boxes_order_items.unblock(); + window.alert( response.data.error ); + } + }, + complete: function() { + window.wcTracks.recordEvent( 'order_edit_add_products', { + order_id: data.post_id, + status: $( '#order_status' ).val() + } ); + }, + dataType: 'json' + }); + }, + + add_tax: function( rate_id, manual_rate_id ) { + if ( manual_rate_id ) { + rate_id = manual_rate_id; + } + + if ( ! rate_id ) { + return false; + } + + var rates = $( '.order-tax-id' ).map( function() { + return $( this ).val(); + }).get(); + + // Test if already exists + if ( -1 === $.inArray( rate_id, rates ) ) { + wc_meta_boxes_order_items.block(); + + var data = { + action: 'woocommerce_add_order_tax', + rate_id: rate_id, + order_id: woocommerce_admin_meta_boxes.post_id, + security: woocommerce_admin_meta_boxes.order_item_nonce + }; + + $.ajax({ + url : woocommerce_admin_meta_boxes.ajax_url, + data : data, + dataType : 'json', + type : 'POST', + success : function( response ) { + if ( response.success ) { + $( '#woocommerce-order-items' ).find( '.inside' ).empty(); + $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html ); + wc_meta_boxes_order_items.reloaded_items(); + } else { + window.alert( response.data.error ); + } + wc_meta_boxes_order_items.unblock(); + }, + complete: function() { + window.wcTracks.recordEvent( 'order_edit_add_tax', { + order_id: data.post_id, + status: $( '#order_status' ).val() + } ); + } + }); + } else { + window.alert( woocommerce_admin_meta_boxes.i18n_tax_rate_already_exists ); + } + } + }, + + stupidtable: { + init: function() { + $( '.woocommerce_order_items' ).stupidtable(); + $( '.woocommerce_order_items' ).on( 'aftertablesort', this.add_arrows ); + }, + + add_arrows: function( event, data ) { + var th = $( this ).find( 'th' ); + var arrow = data.direction === 'asc' ? '↑' : '↓'; + var index = data.column; + th.find( '.wc-arrow' ).remove(); + th.eq( index ).append( '' + arrow + '' ); + } + } + }; + + /** + * Order Notes Panel + */ + var wc_meta_boxes_order_notes = { + init: function() { + $( '#woocommerce-order-notes' ) + .on( 'click', 'button.add_note', this.add_order_note ) + .on( 'click', 'a.delete_note', this.delete_order_note ); + + }, + + add_order_note: function() { + if ( ! $( 'textarea#add_order_note' ).val() ) { + return; + } + + $( '#woocommerce-order-notes' ).block({ + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + + var data = { + action: 'woocommerce_add_order_note', + post_id: woocommerce_admin_meta_boxes.post_id, + note: $( 'textarea#add_order_note' ).val(), + note_type: $( 'select#order_note_type' ).val(), + security: woocommerce_admin_meta_boxes.add_order_note_nonce + }; + + $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) { + $( 'ul.order_notes .no-items' ).remove(); + $( 'ul.order_notes' ).prepend( response ); + $( '#woocommerce-order-notes' ).unblock(); + $( '#add_order_note' ).val( '' ); + window.wcTracks.recordEvent( 'order_edit_add_order_note', { + order_id: data.post_id, + note_type: data.note_type || 'private', + status: $( '#order_status' ).val() + } ); + }); + + return false; + }, + + delete_order_note: function() { + if ( window.confirm( woocommerce_admin_meta_boxes.i18n_delete_note ) ) { + var note = $( this ).closest( 'li.note' ); + + $( note ).block({ + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + + var data = { + action: 'woocommerce_delete_order_note', + note_id: $( note ).attr( 'rel' ), + security: woocommerce_admin_meta_boxes.delete_order_note_nonce + }; + + $.post( woocommerce_admin_meta_boxes.ajax_url, data, function() { + $( note ).remove(); + }); + } + + return false; + } + }; + + /** + * Order Downloads Panel + */ + var wc_meta_boxes_order_downloads = { + init: function() { + $( '.order_download_permissions' ) + .on( 'click', 'button.grant_access', this.grant_access ) + .on( 'click', 'button.revoke_access', this.revoke_access ) + .on( 'click', '#copy-download-link', this.copy_link ) + .on( 'aftercopy', '#copy-download-link', this.copy_success ) + .on( 'aftercopyfailure', '#copy-download-link', this.copy_fail ); + }, + + grant_access: function() { + var products = $( '#grant_access_id' ).val(); + + if ( ! products ) { + return; + } + + $( '.order_download_permissions' ).block({ + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + + var data = { + action: 'woocommerce_grant_access_to_download', + product_ids: products, + loop: $('.order_download_permissions .wc-metabox').length, + order_id: woocommerce_admin_meta_boxes.post_id, + security: woocommerce_admin_meta_boxes.grant_access_nonce + }; + + $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) { + + if ( response ) { + $( '.order_download_permissions .wc-metaboxes' ).append( response ); + } else { + window.alert( woocommerce_admin_meta_boxes.i18n_download_permission_fail ); + } + + $( document.body ).trigger( 'wc-init-datepickers' ); + $( '#grant_access_id' ).val( '' ).change(); + $( '.order_download_permissions' ).unblock(); + }); + + return false; + }, + + revoke_access: function () { + if ( window.confirm( woocommerce_admin_meta_boxes.i18n_permission_revoke ) ) { + var el = $( this ).parent().parent(); + var product = $( this ).attr( 'rel' ).split( ',' )[0]; + var file = $( this ).attr( 'rel' ).split( ',' )[1]; + var permission_id = $( this ).data( 'permission_id' ); + + if ( product > 0 ) { + $( el ).block({ + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + + var data = { + action: 'woocommerce_revoke_access_to_download', + product_id: product, + download_id: file, + permission_id: permission_id, + order_id: woocommerce_admin_meta_boxes.post_id, + security: woocommerce_admin_meta_boxes.revoke_access_nonce + }; + + $.post( woocommerce_admin_meta_boxes.ajax_url, data, function() { + // Success + $( el ).fadeOut( '300', function () { + $( el ).remove(); + }); + }); + + } else { + $( el ).fadeOut( '300', function () { + $( el ).remove(); + }); + } + } + return false; + }, + + /** + * Copy download link. + * + * @param {Object} evt Copy event. + */ + copy_link: function( evt ) { + wcClearClipboard(); + wcSetClipboard( $( this ).attr( 'href' ), $( this ) ); + evt.preventDefault(); + }, + + /** + * Display a "Copied!" tip when success copying + */ + copy_success: function() { + $( this ).tipTip({ + 'attribute': 'data-tip', + 'activation': 'focus', + 'fadeIn': 50, + 'fadeOut': 50, + 'delay': 0 + }).focus(); + }, + + /** + * Displays the copy error message when failure copying. + */ + copy_fail: function() { + $( this ).tipTip({ + 'attribute': 'data-tip-failed', + 'activation': 'focus', + 'fadeIn': 50, + 'fadeOut': 50, + 'delay': 0 + }).focus(); + } + }; + + wc_meta_boxes_order.init(); + wc_meta_boxes_order_items.init(); + wc_meta_boxes_order_notes.init(); + wc_meta_boxes_order_downloads.init(); +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-order.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-order.min.js new file mode 100644 index 0000000..f567faf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-order.min.js @@ -0,0 +1 @@ +jQuery(function(u){window.wcTracks=window.wcTracks||{},window.wcTracks.recordEvent=window.wcTracks.recordEvent||function(){};var p={states:null,init:function(){"undefined"!=typeof woocommerce_admin_meta_boxes_order&&"undefined"!=typeof woocommerce_admin_meta_boxes_order.countries&&(this.states=JSON.parse(woocommerce_admin_meta_boxes_order.countries.replace(/"/g,'"'))),u(".js_field-country").selectWoo().change(this.change_country),u(".js_field-country").trigger("change",[!0]),u(document.body).on("change","select.js_field-state",this.change_state),u("#woocommerce-order-actions input, #woocommerce-order-actions a").click(function(){window.onbeforeunload=""}),u("a.edit_address").click(this.edit_address),u("a.billing-same-as-shipping").on("click",this.copy_billing_to_shipping),u("a.load_customer_billing").on("click",this.load_billing),u("a.load_customer_shipping").on("click",this.load_shipping),u("#customer_user").on("change",this.change_customer_user)},change_country:function(e,o){var t,a,r,i,n,d,c,_,s,m,l;void 0===o&&(o=!1),null!==p.states&&(a=(t=u(this)).val(),m=(r=t.parents("div.edit_address").find(":input.js_field-state")).parent(),i=r.val(),n=r.attr("name"),d=r.attr("id"),c=t.data("woocommerce.stickState-"+a)?t.data("woocommerce.stickState-"+a):i,_=r.attr("placeholder"),o&&t.data("woocommerce.stickState-"+a,c),m.show().find(".select2-container").remove(),u.isEmptyObject(p.states[a])?(l=u('').prop("id",d).prop("name",n).prop("placeholder",_).addClass("js_field-state").val(i),r.replaceWith(l)):(s=p.states[a],m=u('').text(woocommerce_admin_meta_boxes_order.i18n_select_state_text),l=u("").prop("id",d).prop("name",n).prop("placeholder",_).addClass("js_field-state select short").append(m),u.each(s,function(e){var o=u("").prop("value",e).text(s[e]);e===i&&o.prop("selected"),l.append(o)}),l.val(c),r.replaceWith(l),l.show().selectWoo().hide().change()),u(document.body).trigger("contry-change.woocommerce",[a,u(this).closest("div")]),u(document.body).trigger("country-change.woocommerce",[a,u(this).closest("div")]))},change_state:function(){var e=u(this),o=e.val(),t=e.parents("div.edit_address").find(":input.js_field-country"),e=t.val();t.data("woocommerce.stickState-"+e,o)},init_tiptip:function(){u("#tiptip_holder").removeAttr("style"),u("#tiptip_arrow").removeAttr("style"),u(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200,keepAlive:!0})},edit_address:function(e){e.preventDefault();var o=u(this),t=o.closest(".order_data_column"),a=t.find("div.edit_address"),r=t.find("div.address"),i=a.find(".js_field-country"),e=a.find(".js_field-state"),t=Boolean(a.find('input[name^="_billing_"]').length);r.hide(),o.parent().find("a").toggle(),i.val()||(i.val(woocommerce_admin_meta_boxes_order.default_country).change(),e.val(woocommerce_admin_meta_boxes_order.default_state).change()),a.show();t=t?"order_edit_billing_address_click":"order_edit_shipping_address_click";window.wcTracks.recordEvent(t,{order_id:woocommerce_admin_meta_boxes.post_id,status:u("#order_status").val()})},change_customer_user:function(){u("#_billing_country").val()||(u("a.edit_address").click(),p.load_billing(!0),p.load_shipping(!0))},load_billing:function(e){if(!0===e||window.confirm(woocommerce_admin_meta_boxes.load_billing)){e=u("#customer_user").val();if(!e)return window.alert(woocommerce_admin_meta_boxes.no_customer_selected),!1;e={user_id:e,action:"woocommerce_get_customer_details",security:woocommerce_admin_meta_boxes.get_customer_details_nonce};u(this).closest("div.edit_address").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),u.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:e,type:"POST",success:function(e){e&&e.billing&&u.each(e.billing,function(e,o){u(":input#_billing_"+e).val(o).change()}),u("div.edit_address").unblock()}})}return!1},load_shipping:function(e){if(!0===e||window.confirm(woocommerce_admin_meta_boxes.load_shipping)){e=u("#customer_user").val();if(!e)return window.alert(woocommerce_admin_meta_boxes.no_customer_selected),!1;e={user_id:e,action:"woocommerce_get_customer_details",security:woocommerce_admin_meta_boxes.get_customer_details_nonce};u(this).closest("div.edit_address").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),u.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:e,type:"POST",success:function(e){e&&e.billing&&u.each(e.shipping,function(e,o){u(":input#_shipping_"+e).val(o).change()}),u("div.edit_address").unblock()}})}return!1},copy_billing_to_shipping:function(){return window.confirm(woocommerce_admin_meta_boxes.copy_billing)&&u('.order_data_column :input[name^="_billing_"]').each(function(){var e=(e=u(this).attr("name")).replace("_billing_","_shipping_");u(":input#"+e).val(u(this).val()).change()}),!1}},d={init:function(){this.stupidtable.init(),u("#woocommerce-order-items").on("click","button.add-line-item",this.add_line_item).on("click","button.add-coupon",this.add_coupon).on("click","a.remove-coupon",this.remove_coupon).on("click","button.refund-items",this.refund_items).on("click",".cancel-action",this.cancel).on("click",".refund-actions .cancel-action",this.track_cancel).on("click","button.add-order-item",this.add_item).on("click","button.add-order-fee",this.add_fee).on("click","button.add-order-shipping",this.add_shipping).on("click","button.add-order-tax",this.add_tax).on("click","button.save-action",this.save_line_items).on("click","a.delete-order-tax",this.delete_tax).on("click","button.calculate-action",this.recalculate).on("click","a.edit-order-item",this.edit_item).on("click","a.delete-order-item",this.delete_item).on("click",".delete_refund",this.refunds.delete_refund).on("click","button.do-api-refund, button.do-manual-refund",this.refunds.do_refund).on("change",".refund input.refund_line_total, .refund input.refund_line_tax",this.refunds.input_changed).on("change keyup",".wc-order-refund-items #refund_amount",this.refunds.amount_changed).on("change","input.refund_order_item_qty",this.refunds.refund_quantity_changed).on("change","input.quantity",this.quantity_changed).on("keyup change",".split-input :input",function(){var e=u(this).parent().prev().find(":input");e&&(""===e.val()||e.is(".match-total"))&&e.val(u(this).val()).addClass("match-total")}).on("keyup",".split-input :input",function(){u(this).removeClass("match-total")}).on("click","button.add_order_item_meta",this.item_meta.add).on("click","button.remove_order_item_meta",this.item_meta.remove).on("wc_order_items_reload",this.reload_items).on("wc_order_items_reloaded",this.reloaded_items),u(document.body).on("wc_backbone_modal_loaded",this.backbone.init).on("wc_backbone_modal_response",this.backbone.response)},block:function(){u("#woocommerce-order-items").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){u("#woocommerce-order-items").unblock()},reload_items:function(){var e={order_id:woocommerce_admin_meta_boxes.post_id,action:"woocommerce_load_order_items",security:woocommerce_admin_meta_boxes.order_item_nonce};d.block(),u.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:e,type:"POST",success:function(e){u("#woocommerce-order-items").find(".inside").empty(),u("#woocommerce-order-items").find(".inside").append(e),d.reloaded_items(),d.unblock()}})},reloaded_items:function(){p.init_tiptip(),d.stupidtable.init()},quantity_changed:function(){var i=u(this).closest("tr.item"),n=u(this).val(),d=u(this).attr("data-qty"),e=u("input.line_total",i),o=u("input.line_subtotal",i),t=accounting.unformat(e.attr("data-total"),woocommerce_admin.mon_decimal_point)/d;e.val(parseFloat(accounting.formatNumber(t*n,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point));t=accounting.unformat(o.attr("data-subtotal"),woocommerce_admin.mon_decimal_point)/d;o.val(parseFloat(accounting.formatNumber(t*n,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point)),u("input.line_tax",i).each(function(){var e=u(this),o=e.data("tax_id"),t=accounting.unformat(e.attr("data-total_tax"),woocommerce_admin.mon_decimal_point)/d,a=u('input.line_subtotal_tax[data-tax_id="'+o+'"]',i),r=accounting.unformat(a.attr("data-subtotal_tax"),woocommerce_admin.mon_decimal_point)/d,o="yes"===woocommerce_admin_meta_boxes.round_at_subtotal,o=woocommerce_admin_meta_boxes[o?"rounding_precision":"currency_format_num_decimals"];0';return o.append(t),!1},remove:function(){var e;return window.confirm(woocommerce_admin_meta_boxes.remove_item_meta)&&((e=u(this).closest("tr")).find(":input").val(""),e.hide()),!1}},backbone:{init:function(e,o){"wc-modal-add-products"===o&&(u(document.body).trigger("wc-enhanced-select-init"),u(this).on("change",".wc-product-search",function(){var e,o;u(this).closest("tr").is(":last-child")&&(o=(e=u(this).closest("table.widefat").find("tbody")).find("tr").length,o=e.data("row").replace(/\[0\]/g,"["+o+"]"),e.append(""+o+""),u(document.body).trigger("wc-enhanced-select-init"))}))},response:function(e,o,t){var a,r;if("wc-modal-add-tax"===o&&(a=t.add_order_tax,r="",t.manual_tax_rate_id&&(r=t.manual_tax_rate_id),d.backbone.add_tax(a,r)),"wc-modal-add-products"===o){var o=u(this).find("table.widefat").find("tbody").find("tr"),i=[];return u(o).each(function(){var e=u(this).find(':input[name="item_id"]').val(),o=u(this).find(':input[name="item_qty"]').val();i.push({id:e,qty:o||1})}),d.backbone.add_items(i)}},add_items:function(e){d.block();var o={action:"woocommerce_add_order_item",order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.order_item_nonce,data:e};"true"===u("button.cancel-action").attr("data-reload")&&(o.items=u("table.woocommerce_order_items :input[name], .wc-order-totals-items :input[name]").serialize()),u.ajax({type:"POST",url:woocommerce_admin_meta_boxes.ajax_url,data:o,success:function(e){e.success?(u("#woocommerce-order-items").find(".inside").empty(),u("#woocommerce-order-items").find(".inside").append(e.data.html),e.data.notes_html&&(u("ul.order_notes").empty(),u("ul.order_notes").append(u(e.data.notes_html).find("li"))),d.reloaded_items(),d.unblock()):(d.unblock(),window.alert(e.data.error))},complete:function(){window.wcTracks.recordEvent("order_edit_add_products",{order_id:o.post_id,status:u("#order_status").val()})},dataType:"json"})},add_tax:function(e,o){if(o&&(e=o),!e)return!1;var t,o=u(".order-tax-id").map(function(){return u(this).val()}).get();-1===u.inArray(e,o)?(d.block(),t={action:"woocommerce_add_order_tax",rate_id:e,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.order_item_nonce},u.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:t,dataType:"json",type:"POST",success:function(e){e.success?(u("#woocommerce-order-items").find(".inside").empty(),u("#woocommerce-order-items").find(".inside").append(e.data.html),d.reloaded_items()):window.alert(e.data.error),d.unblock()},complete:function(){window.wcTracks.recordEvent("order_edit_add_tax",{order_id:t.post_id,status:u("#order_status").val()})}})):window.alert(woocommerce_admin_meta_boxes.i18n_tax_rate_already_exists)}},stupidtable:{init:function(){u(".woocommerce_order_items").stupidtable(),u(".woocommerce_order_items").on("aftertablesort",this.add_arrows)},add_arrows:function(e,o){var t=u(this).find("th"),a="asc"===o.direction?"↑":"↓",o=o.column;t.find(".wc-arrow").remove(),t.eq(o).append(''+a+"")}}},e={init:function(){u("#woocommerce-order-notes").on("click","button.add_note",this.add_order_note).on("click","a.delete_note",this.delete_order_note)},add_order_note:function(){if(u("textarea#add_order_note").val()){u("#woocommerce-order-notes").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var o={action:"woocommerce_add_order_note",post_id:woocommerce_admin_meta_boxes.post_id,note:u("textarea#add_order_note").val(),note_type:u("select#order_note_type").val(),security:woocommerce_admin_meta_boxes.add_order_note_nonce};return u.post(woocommerce_admin_meta_boxes.ajax_url,o,function(e){u("ul.order_notes .no-items").remove(),u("ul.order_notes").prepend(e),u("#woocommerce-order-notes").unblock(),u("#add_order_note").val(""),window.wcTracks.recordEvent("order_edit_add_order_note",{order_id:o.post_id,note_type:o.note_type||"private",status:u("#order_status").val()})}),!1}},delete_order_note:function(){var e,o;return window.confirm(woocommerce_admin_meta_boxes.i18n_delete_note)&&(e=u(this).closest("li.note"),u(e).block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),o={action:"woocommerce_delete_order_note",note_id:u(e).attr("rel"),security:woocommerce_admin_meta_boxes.delete_order_note_nonce},u.post(woocommerce_admin_meta_boxes.ajax_url,o,function(){u(e).remove()})),!1}},o={init:function(){u(".order_download_permissions").on("click","button.grant_access",this.grant_access).on("click","button.revoke_access",this.revoke_access).on("click","#copy-download-link",this.copy_link).on("aftercopy","#copy-download-link",this.copy_success).on("aftercopyfailure","#copy-download-link",this.copy_fail)},grant_access:function(){var e=u("#grant_access_id").val();if(e){u(".order_download_permissions").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});e={action:"woocommerce_grant_access_to_download",product_ids:e,loop:u(".order_download_permissions .wc-metabox").length,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.grant_access_nonce};return u.post(woocommerce_admin_meta_boxes.ajax_url,e,function(e){e?u(".order_download_permissions .wc-metaboxes").append(e):window.alert(woocommerce_admin_meta_boxes.i18n_download_permission_fail),u(document.body).trigger("wc-init-datepickers"),u("#grant_access_id").val("").change(),u(".order_download_permissions").unblock()}),!1}},revoke_access:function(){var e,o,t,a;return window.confirm(woocommerce_admin_meta_boxes.i18n_permission_revoke)&&(e=u(this).parent().parent(),o=u(this).attr("rel").split(",")[0],t=u(this).attr("rel").split(",")[1],a=u(this).data("permission_id"),0').submit(); + } else { + postForm.append('').submit(); + } + }, + + /** + * Discart changes. + * + * @return {Bool} + */ + cancel_variations: function() { + var current = parseInt( $( '#variable_product_options' ).find( '.woocommerce_variations' ).attr( 'data-page' ), 10 ); + + $( '#variable_product_options' ).find( '.woocommerce_variations .variation-needs-update' ) + .removeClass( 'variation-needs-update' ); + $( '.variations-defaults select' ).each( function() { + $( this ).val( $( this ).attr( 'data-current' ) ); + }); + + wc_meta_boxes_product_variations_pagenav.go_to_page( current ); + + return false; + }, + + /** + * Add variation + * + * @return {Bool} + */ + add_variation: function() { + wc_meta_boxes_product_variations_ajax.block(); + + var data = { + action: 'woocommerce_add_variation', + post_id: woocommerce_admin_meta_boxes_variations.post_id, + loop: $( '.woocommerce_variation' ).length, + security: woocommerce_admin_meta_boxes_variations.add_variation_nonce + }; + + $.post( woocommerce_admin_meta_boxes_variations.ajax_url, data, function( response ) { + var variation = $( response ); + variation.addClass( 'variation-needs-update' ); + + $( '.woocommerce-notice-invalid-variation' ).remove(); + $( '#variable_product_options' ).find( '.woocommerce_variations' ).prepend( variation ); + $( 'button.cancel-variation-changes, button.save-variation-changes' ).removeAttr( 'disabled' ); + $( '#variable_product_options' ).trigger( 'woocommerce_variations_added', 1 ); + wc_meta_boxes_product_variations_ajax.unblock(); + }); + + return false; + }, + + /** + * Remove variation + * + * @return {Bool} + */ + remove_variation: function() { + wc_meta_boxes_product_variations_ajax.check_for_changes(); + + if ( window.confirm( woocommerce_admin_meta_boxes_variations.i18n_remove_variation ) ) { + var variation = $( this ).attr( 'rel' ), + variation_ids = [], + data = { + action: 'woocommerce_remove_variations' + }; + + wc_meta_boxes_product_variations_ajax.block(); + + if ( 0 < variation ) { + variation_ids.push( variation ); + + data.variation_ids = variation_ids; + data.security = woocommerce_admin_meta_boxes_variations.delete_variations_nonce; + + $.post( woocommerce_admin_meta_boxes_variations.ajax_url, data, function() { + var wrapper = $( '#variable_product_options' ).find( '.woocommerce_variations' ), + current_page = parseInt( wrapper.attr( 'data-page' ), 10 ), + total_pages = Math.ceil( ( + parseInt( wrapper.attr( 'data-total' ), 10 ) - 1 + ) / woocommerce_admin_meta_boxes_variations.variations_per_page ), + page = 1; + + $( '#woocommerce-product-data' ).trigger( 'woocommerce_variations_removed' ); + + if ( current_page === total_pages || current_page <= total_pages ) { + page = current_page; + } else if ( current_page > total_pages && 0 !== total_pages ) { + page = total_pages; + } + + wc_meta_boxes_product_variations_pagenav.go_to_page( page, -1 ); + }); + + } else { + wc_meta_boxes_product_variations_ajax.unblock(); + } + } + + return false; + }, + + /** + * Link all variations (or at least try :p) + * + * @return {Bool} + */ + link_all_variations: function() { + wc_meta_boxes_product_variations_ajax.check_for_changes(); + + if ( window.confirm( woocommerce_admin_meta_boxes_variations.i18n_link_all_variations ) ) { + wc_meta_boxes_product_variations_ajax.block(); + + var data = { + action: 'woocommerce_link_all_variations', + post_id: woocommerce_admin_meta_boxes_variations.post_id, + security: woocommerce_admin_meta_boxes_variations.link_variation_nonce + }; + + $.post( woocommerce_admin_meta_boxes_variations.ajax_url, data, function( response ) { + var count = parseInt( response, 10 ); + + if ( 1 === count ) { + window.alert( count + ' ' + woocommerce_admin_meta_boxes_variations.i18n_variation_added ); + } else if ( 0 === count || count > 1 ) { + window.alert( count + ' ' + woocommerce_admin_meta_boxes_variations.i18n_variations_added ); + } else { + window.alert( woocommerce_admin_meta_boxes_variations.i18n_no_variations_added ); + } + + if ( count > 0 ) { + wc_meta_boxes_product_variations_pagenav.go_to_page( 1, count ); + $( '#variable_product_options' ).trigger( 'woocommerce_variations_added', count ); + } else { + wc_meta_boxes_product_variations_ajax.unblock(); + } + }); + } + + return false; + }, + + /** + * Add new class when have changes in some input + */ + input_changed: function() { + $( this ) + .closest( '.woocommerce_variation' ) + .addClass( 'variation-needs-update' ); + + $( 'button.cancel-variation-changes, button.save-variation-changes' ).removeAttr( 'disabled' ); + + $( '#variable_product_options' ).trigger( 'woocommerce_variations_input_changed' ); + }, + + /** + * Added new .variation-needs-update class when defaults is changed + */ + defaults_changed: function() { + $( this ) + .closest( '#variable_product_options' ) + .find( '.woocommerce_variation:first' ) + .addClass( 'variation-needs-update' ); + + $( 'button.cancel-variation-changes, button.save-variation-changes' ).removeAttr( 'disabled' ); + + $( '#variable_product_options' ).trigger( 'woocommerce_variations_defaults_changed' ); + }, + + /** + * Actions + */ + do_variation_action: function() { + var do_variation_action = $( 'select.variation_actions' ).val(), + data = {}, + changes = 0, + value; + + switch ( do_variation_action ) { + case 'add_variation' : + wc_meta_boxes_product_variations_ajax.add_variation(); + return; + case 'link_all_variations' : + wc_meta_boxes_product_variations_ajax.link_all_variations(); + return; + case 'delete_all' : + if ( window.confirm( woocommerce_admin_meta_boxes_variations.i18n_delete_all_variations ) ) { + if ( window.confirm( woocommerce_admin_meta_boxes_variations.i18n_last_warning ) ) { + data.allowed = true; + changes = parseInt( $( '#variable_product_options' ).find( '.woocommerce_variations' ) + .attr( 'data-total' ), 10 ) * -1; + } + } + break; + case 'variable_regular_price_increase' : + case 'variable_regular_price_decrease' : + case 'variable_sale_price_increase' : + case 'variable_sale_price_decrease' : + value = window.prompt( woocommerce_admin_meta_boxes_variations.i18n_enter_a_value_fixed_or_percent ); + + if ( value != null ) { + if ( value.indexOf( '%' ) >= 0 ) { + data.value = accounting.unformat( value.replace( /\%/, '' ), woocommerce_admin.mon_decimal_point ) + '%'; + } else { + data.value = accounting.unformat( value, woocommerce_admin.mon_decimal_point ); + } + } else { + return; + } + break; + case 'variable_regular_price' : + case 'variable_sale_price' : + case 'variable_stock' : + case 'variable_weight' : + case 'variable_length' : + case 'variable_width' : + case 'variable_height' : + case 'variable_download_limit' : + case 'variable_download_expiry' : + value = window.prompt( woocommerce_admin_meta_boxes_variations.i18n_enter_a_value ); + + if ( value != null ) { + data.value = value; + } else { + return; + } + break; + case 'variable_sale_schedule' : + data.date_from = window.prompt( woocommerce_admin_meta_boxes_variations.i18n_scheduled_sale_start ); + data.date_to = window.prompt( woocommerce_admin_meta_boxes_variations.i18n_scheduled_sale_end ); + + if ( null === data.date_from ) { + data.date_from = false; + } + + if ( null === data.date_to ) { + data.date_to = false; + } + + if ( false === data.date_to && false === data.date_from ) { + return; + } + break; + default : + $( 'select.variation_actions' ).trigger( do_variation_action ); + data = $( 'select.variation_actions' ).triggerHandler( do_variation_action + '_ajax_data', data ); + break; + } + + if ( 'delete_all' === do_variation_action && data.allowed ) { + $( '#variable_product_options' ).find( '.variation-needs-update' ).removeClass( 'variation-needs-update' ); + } else { + wc_meta_boxes_product_variations_ajax.check_for_changes(); + } + + wc_meta_boxes_product_variations_ajax.block(); + + $.ajax({ + url: woocommerce_admin_meta_boxes_variations.ajax_url, + data: { + action: 'woocommerce_bulk_edit_variations', + security: woocommerce_admin_meta_boxes_variations.bulk_edit_variations_nonce, + product_id: woocommerce_admin_meta_boxes_variations.post_id, + product_type: $( '#product-type' ).val(), + bulk_action: do_variation_action, + data: data + }, + type: 'POST', + success: function() { + wc_meta_boxes_product_variations_pagenav.go_to_page( 1, changes ); + } + }); + } + }; + + /** + * Product variations pagenav + */ + var wc_meta_boxes_product_variations_pagenav = { + + /** + * Initialize products variations meta box + */ + init: function() { + $( document.body ) + .on( 'woocommerce_variations_added', this.update_single_quantity ) + .on( 'change', '.variations-pagenav .page-selector', this.page_selector ) + .on( 'click', '.variations-pagenav .first-page', this.first_page ) + .on( 'click', '.variations-pagenav .prev-page', this.prev_page ) + .on( 'click', '.variations-pagenav .next-page', this.next_page ) + .on( 'click', '.variations-pagenav .last-page', this.last_page ); + }, + + /** + * Set variations count + * + * @param {Int} qty + * + * @return {Int} + */ + update_variations_count: function( qty ) { + var wrapper = $( '#variable_product_options' ).find( '.woocommerce_variations' ), + total = parseInt( wrapper.attr( 'data-total' ), 10 ) + qty, + displaying_num = $( '.variations-pagenav .displaying-num' ); + + // Set the new total of variations + wrapper.attr( 'data-total', total ); + + if ( 1 === total ) { + displaying_num.text( woocommerce_admin_meta_boxes_variations.i18n_variation_count_single.replace( '%qty%', total ) ); + } else { + displaying_num.text( woocommerce_admin_meta_boxes_variations.i18n_variation_count_plural.replace( '%qty%', total ) ); + } + + return total; + }, + + /** + * Update variations quantity when add a new variation + * + * @param {Object} event + * @param {Int} qty + */ + update_single_quantity: function( event, qty ) { + if ( 1 === qty ) { + var page_nav = $( '.variations-pagenav' ); + + wc_meta_boxes_product_variations_pagenav.update_variations_count( qty ); + + if ( page_nav.is( ':hidden' ) ) { + $( 'option, optgroup', '.variation_actions' ).show(); + $( '.variation_actions' ).val( 'add_variation' ); + $( '#variable_product_options' ).find( '.toolbar' ).show(); + page_nav.show(); + $( '.pagination-links', page_nav ).hide(); + } + } + }, + + /** + * Set the pagenav fields + * + * @param {Int} qty + */ + set_paginav: function( qty ) { + var wrapper = $( '#variable_product_options' ).find( '.woocommerce_variations' ), + new_qty = wc_meta_boxes_product_variations_pagenav.update_variations_count( qty ), + toolbar = $( '#variable_product_options' ).find( '.toolbar' ), + variation_action = $( '.variation_actions' ), + page_nav = $( '.variations-pagenav' ), + displaying_links = $( '.pagination-links', page_nav ), + total_pages = Math.ceil( new_qty / woocommerce_admin_meta_boxes_variations.variations_per_page ), + options = ''; + + // Set the new total of pages + wrapper.attr( 'data-total_pages', total_pages ); + + $( '.total-pages', page_nav ).text( total_pages ); + + // Set the new pagenav options + for ( var i = 1; i <= total_pages; i++ ) { + options += ''; + } + + $( '.page-selector', page_nav ).empty().html( options ); + + // Show/hide pagenav + if ( 0 === new_qty ) { + toolbar.not( '.toolbar-top, .toolbar-buttons' ).hide(); + page_nav.hide(); + $( 'option, optgroup', variation_action ).hide(); + $( '.variation_actions' ).val( 'add_variation' ); + $( 'option[data-global="true"]', variation_action ).show(); + + } else { + toolbar.show(); + page_nav.show(); + $( 'option, optgroup', variation_action ).show(); + $( '.variation_actions' ).val( 'add_variation' ); + + // Show/hide links + if ( 1 === total_pages ) { + displaying_links.hide(); + } else { + displaying_links.show(); + } + } + }, + + /** + * Check button if enabled and if don't have changes + * + * @return {Bool} + */ + check_is_enabled: function( current ) { + return ! $( current ).hasClass( 'disabled' ); + }, + + /** + * Change "disabled" class on pagenav + */ + change_classes: function( selected, total ) { + var first_page = $( '.variations-pagenav .first-page' ), + prev_page = $( '.variations-pagenav .prev-page' ), + next_page = $( '.variations-pagenav .next-page' ), + last_page = $( '.variations-pagenav .last-page' ); + + if ( 1 === selected ) { + first_page.addClass( 'disabled' ); + prev_page.addClass( 'disabled' ); + } else { + first_page.removeClass( 'disabled' ); + prev_page.removeClass( 'disabled' ); + } + + if ( total === selected ) { + next_page.addClass( 'disabled' ); + last_page.addClass( 'disabled' ); + } else { + next_page.removeClass( 'disabled' ); + last_page.removeClass( 'disabled' ); + } + }, + + /** + * Set page + */ + set_page: function( page ) { + $( '.variations-pagenav .page-selector' ).val( page ).first().change(); + }, + + /** + * Navigate on variations pages + * + * @param {Int} page + * @param {Int} qty + */ + go_to_page: function( page, qty ) { + page = page || 1; + qty = qty || 0; + + wc_meta_boxes_product_variations_pagenav.set_paginav( qty ); + wc_meta_boxes_product_variations_pagenav.set_page( page ); + }, + + /** + * Paginav pagination selector + */ + page_selector: function() { + var selected = parseInt( $( this ).val(), 10 ), + wrapper = $( '#variable_product_options' ).find( '.woocommerce_variations' ); + + $( '.variations-pagenav .page-selector' ).val( selected ); + + wc_meta_boxes_product_variations_ajax.check_for_changes(); + wc_meta_boxes_product_variations_pagenav.change_classes( selected, parseInt( wrapper.attr( 'data-total_pages' ), 10 ) ); + wc_meta_boxes_product_variations_ajax.load_variations( selected ); + }, + + /** + * Go to first page + * + * @return {Bool} + */ + first_page: function() { + if ( wc_meta_boxes_product_variations_pagenav.check_is_enabled( this ) ) { + wc_meta_boxes_product_variations_pagenav.set_page( 1 ); + } + + return false; + }, + + /** + * Go to previous page + * + * @return {Bool} + */ + prev_page: function() { + if ( wc_meta_boxes_product_variations_pagenav.check_is_enabled( this ) ) { + var wrapper = $( '#variable_product_options' ).find( '.woocommerce_variations' ), + prev_page = parseInt( wrapper.attr( 'data-page' ), 10 ) - 1, + new_page = ( 0 < prev_page ) ? prev_page : 1; + + wc_meta_boxes_product_variations_pagenav.set_page( new_page ); + } + + return false; + }, + + /** + * Go to next page + * + * @return {Bool} + */ + next_page: function() { + if ( wc_meta_boxes_product_variations_pagenav.check_is_enabled( this ) ) { + var wrapper = $( '#variable_product_options' ).find( '.woocommerce_variations' ), + total_pages = parseInt( wrapper.attr( 'data-total_pages' ), 10 ), + next_page = parseInt( wrapper.attr( 'data-page' ), 10 ) + 1, + new_page = ( total_pages >= next_page ) ? next_page : total_pages; + + wc_meta_boxes_product_variations_pagenav.set_page( new_page ); + } + + return false; + }, + + /** + * Go to last page + * + * @return {Bool} + */ + last_page: function() { + if ( wc_meta_boxes_product_variations_pagenav.check_is_enabled( this ) ) { + var last_page = $( '#variable_product_options' ).find( '.woocommerce_variations' ).attr( 'data-total_pages' ); + + wc_meta_boxes_product_variations_pagenav.set_page( last_page ); + } + + return false; + } + }; + + wc_meta_boxes_product_variations_actions.init(); + wc_meta_boxes_product_variations_media.init(); + wc_meta_boxes_product_variations_ajax.init(); + wc_meta_boxes_product_variations_pagenav.init(); + +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-product-variation.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-product-variation.min.js new file mode 100644 index 0000000..34f8835 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-product-variation.min.js @@ -0,0 +1 @@ +jQuery(function(c){"use strict";var o={init:function(){c("#variable_product_options").on("change","input.variable_is_downloadable",this.variable_is_downloadable).on("change","input.variable_is_virtual",this.variable_is_virtual).on("change","input.variable_manage_stock",this.variable_manage_stock).on("click","button.notice-dismiss",this.notice_dismiss).on("click","h3 .sort",this.set_menu_order).on("reload",this.reload),c("input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock").change(),c("#woocommerce-product-data").on("woocommerce_variations_loaded",this.variations_loaded),c(document.body).on("woocommerce_variations_added",this.variation_added)},reload:function(){n.load_variations(1),d.set_paginav(0)},variable_is_downloadable:function(){c(this).closest(".woocommerce_variation").find(".show_if_variation_downloadable").hide(),c(this).is(":checked")&&c(this).closest(".woocommerce_variation").find(".show_if_variation_downloadable").show()},variable_is_virtual:function(){c(this).closest(".woocommerce_variation").find(".hide_if_variation_virtual").show(),c(this).is(":checked")&&c(this).closest(".woocommerce_variation").find(".hide_if_variation_virtual").hide()},variable_manage_stock:function(){c(this).closest(".woocommerce_variation").find(".show_if_variation_manage_stock").hide(),c(this).closest(".woocommerce_variation").find(".variable_stock_status").show(),c(this).is(":checked")&&(c(this).closest(".woocommerce_variation").find(".show_if_variation_manage_stock").show(),c(this).closest(".woocommerce_variation").find(".variable_stock_status").hide()),c("input#_manage_stock:checked").length&&c(this).closest(".woocommerce_variation").find(".variable_stock_status").hide()},notice_dismiss:function(){c(this).closest("div.notice").remove()},variations_loaded:function(a,e){e=e||!1;var i=c("#woocommerce-product-data");e||(c("input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock",i).change(),c(".woocommerce_variation",i).each(function(a,e){var i=c(e),o=c(".sale_price_dates_from",i).val(),e=c(".sale_price_dates_to",i).val();""===o&&""===e||c("a.sale_schedule",i).click()}),c(".woocommerce_variations .variation-needs-update",i).removeClass("variation-needs-update"),c("button.cancel-variation-changes, button.save-variation-changes",i).attr("disabled","disabled")),c("#tiptip_holder").removeAttr("style"),c("#tiptip_arrow").removeAttr("style"),c(".woocommerce_variations .tips, .woocommerce_variations .help_tip, .woocommerce_variations .woocommerce-help-tip",i).tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}),c(".sale_price_dates_fields",i).find("input").datepicker({defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:!0,onSelect:function(){var a=c(this).is(".sale_price_dates_from")?"minDate":"maxDate",e=c(this).closest(".sale_price_dates_fields").find("input"),i=c(this).datepicker("getDate");e.not(this).datepicker("option",a,i),c(this).change()}}),c(".woocommerce_variations",i).sortable({items:".woocommerce_variation",cursor:"move",axis:"y",handle:".sort",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65,stop:function(){o.variation_row_indexes()}}),c(document.body).trigger("wc-enhanced-select-init")},variation_added:function(a,e){1===e&&o.variations_loaded(null,!0)},set_menu_order:function(a){a.preventDefault();var e=c(this).closest(".woocommerce_variation").find(".variation_menu_order"),a=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_enter_menu_order,e.val());null!=a&&(e.val(parseInt(a,10)).change(),n.save_variations())},variation_row_indexes:function(){var a=c("#variable_product_options").find(".woocommerce_variations"),a=parseInt(a.attr("data-page"),10),i=parseInt((a-1)*woocommerce_admin_meta_boxes_variations.variations_per_page,10);c(".woocommerce_variations .woocommerce_variation").each(function(a,e){c(".variation_menu_order",e).val(parseInt(c(e).index(".woocommerce_variations .woocommerce_variation"),10)+1+i).change()})}},t={variable_image_frame:null,setting_variation_image_id:null,setting_variation_image:null,wp_media_post_id:wp.media.model.settings.post.id,init:function(){c("#variable_product_options").on("click",".upload_image_button",this.add_image),c("a.add_media").on("click",this.restore_wp_media_post_id)},add_image:function(a){var e=c(this),i=e.attr("rel"),o=e.closest(".upload_image");if(t.setting_variation_image=o,t.setting_variation_image_id=i,a.preventDefault(),e.is(".remove"))c(".upload_image_id",t.setting_variation_image).val("").change(),t.setting_variation_image.find("img").eq(0).attr("src",woocommerce_admin_meta_boxes_variations.woocommerce_placeholder_img_src),t.setting_variation_image.find(".upload_image_button").removeClass("remove");else{if(t.variable_image_frame)return t.variable_image_frame.uploader.uploader.param("post_id",t.setting_variation_image_id),void t.variable_image_frame.open();wp.media.model.settings.post.id=t.setting_variation_image_id,t.variable_image_frame=wp.media.frames.variable_image=wp.media({title:woocommerce_admin_meta_boxes_variations.i18n_choose_image,button:{text:woocommerce_admin_meta_boxes_variations.i18n_set_image},states:[new wp.media.controller.Library({title:woocommerce_admin_meta_boxes_variations.i18n_choose_image,filterable:"all"})]}),t.variable_image_frame.on("select",function(){var a=t.variable_image_frame.state().get("selection").first().toJSON(),e=(a.sizes&&a.sizes.thumbnail?a.sizes.thumbnail:a).url;c(".upload_image_id",t.setting_variation_image).val(a.id).change(),t.setting_variation_image.find(".upload_image_button").addClass("remove"),t.setting_variation_image.find("img").eq(0).attr("src",e),wp.media.model.settings.post.id=t.wp_media_post_id}),t.variable_image_frame.open()}},restore_wp_media_post_id:function(){wp.media.model.settings.post.id=t.wp_media_post_id}},n={init:function(){c("li.variations_tab a").on("click",this.initial_load),c("#variable_product_options").on("click","button.save-variation-changes",this.save_variations).on("click","button.cancel-variation-changes",this.cancel_variations).on("click",".remove_variation",this.remove_variation).on("click",".downloadable_files a.delete",this.input_changed),c(document.body).on("change","#variable_product_options .woocommerce_variations :input",this.input_changed).on("change",".variations-defaults select",this.defaults_changed);var a=c("form#post");a.on("submit",this.save_on_submit),c("input:submit",a).bind("click keypress",function(){a.data("callerid",this.id)}),c(".wc-metaboxes-wrapper").on("click","a.do_variation_action",this.do_variation_action)},check_for_changes:function(){var a=c("#variable_product_options").find(".woocommerce_variations .variation-needs-update");if(0'):a.append('')).submit()},cancel_variations:function(){var a=parseInt(c("#variable_product_options").find(".woocommerce_variations").attr("data-page"),10);return c("#variable_product_options").find(".woocommerce_variations .variation-needs-update").removeClass("variation-needs-update"),c(".variations-defaults select").each(function(){c(this).val(c(this).attr("data-current"))}),d.go_to_page(a),!1},add_variation:function(){n.block();var a={action:"woocommerce_add_variation",post_id:woocommerce_admin_meta_boxes_variations.post_id,loop:c(".woocommerce_variation").length,security:woocommerce_admin_meta_boxes_variations.add_variation_nonce};return c.post(woocommerce_admin_meta_boxes_variations.ajax_url,a,function(a){a=c(a);a.addClass("variation-needs-update"),c(".woocommerce-notice-invalid-variation").remove(),c("#variable_product_options").find(".woocommerce_variations").prepend(a),c("button.cancel-variation-changes, button.save-variation-changes").removeAttr("disabled"),c("#variable_product_options").trigger("woocommerce_variations_added",1),n.unblock()}),!1},remove_variation:function(){var a,e,i;return n.check_for_changes(),window.confirm(woocommerce_admin_meta_boxes_variations.i18n_remove_variation)&&(a=c(this).attr("rel"),e=[],i={action:"woocommerce_remove_variations"},n.block(),0'+s+"";c(".page-selector",n).empty().html(_),0===i?(o.not(".toolbar-top, .toolbar-buttons").hide(),n.hide(),c("option, optgroup",t).hide(),c(".variation_actions").val("add_variation"),c('option[data-global="true"]',t).show()):(o.show(),n.show(),c("option, optgroup",t).show(),c(".variation_actions").val("add_variation"),1===r?a.hide():a.show())},check_is_enabled:function(a){return!c(a).hasClass("disabled")},change_classes:function(a,e){var i=c(".variations-pagenav .first-page"),o=c(".variations-pagenav .prev-page"),t=c(".variations-pagenav .next-page"),n=c(".variations-pagenav .last-page");1===a?(i.addClass("disabled"),o.addClass("disabled")):(i.removeClass("disabled"),o.removeClass("disabled")),e===a?(t.addClass("disabled"),n.addClass("disabled")):(t.removeClass("disabled"),n.removeClass("disabled"))},set_page:function(a){c(".variations-pagenav .page-selector").val(a).first().change()},go_to_page:function(a,e){a=a||1,e=e||0,d.set_paginav(e),d.set_page(a)},page_selector:function(){var a=parseInt(c(this).val(),10),e=c("#variable_product_options").find(".woocommerce_variations");c(".variations-pagenav .page-selector").val(a),n.check_for_changes(),d.change_classes(a,parseInt(e.attr("data-total_pages"),10)),n.load_variations(a)},first_page:function(){return d.check_is_enabled(this)&&d.set_page(1),!1},prev_page:function(){var a;return d.check_is_enabled(this)&&(a=c("#variable_product_options").find(".woocommerce_variations"),a=0<(a=parseInt(a.attr("data-page"),10)-1)?a:1,d.set_page(a)),!1},next_page:function(){var a,e;return d.check_is_enabled(this)&&(a=c("#variable_product_options").find(".woocommerce_variations"),e=parseInt(a.attr("data-total_pages"),10),e=(a=parseInt(a.attr("data-page"),10)+1)<=e?a:e,d.set_page(e)),!1},last_page:function(){var a;return d.check_is_enabled(this)&&(a=c("#variable_product_options").find(".woocommerce_variations").attr("data-total_pages"),d.set_page(a)),!1}};o.init(),t.init(),n.init(),d.init()}); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-product.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-product.js new file mode 100644 index 0000000..d54284d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-product.js @@ -0,0 +1,686 @@ +/*global woocommerce_admin_meta_boxes */ +jQuery( function( $ ) { + + // Scroll to first checked category + // https://github.com/scribu/wp-category-checklist-tree/blob/d1c3c1f449e1144542efa17dde84a9f52ade1739/category-checklist-tree.php + $( function() { + $( '[id$="-all"] > ul.categorychecklist' ).each( function() { + var $list = $( this ); + var $firstChecked = $list.find( ':checked' ).first(); + + if ( ! $firstChecked.length ) { + return; + } + + var pos_first = $list.find( 'input' ).position().top; + var pos_checked = $firstChecked.position().top; + + $list.closest( '.tabs-panel' ).scrollTop( pos_checked - pos_first + 5 ); + }); + }); + + // Prevent enter submitting post form. + $( '#upsell_product_data' ).bind( 'keypress', function( e ) { + if ( e.keyCode === 13 ) { + return false; + } + }); + + // Type box. + if ( $( 'body' ).hasClass( 'wc-wp-version-gte-55' ) ) { + $( '.type_box' ).appendTo( '#woocommerce-product-data .hndle' ); + } else { + $( '.type_box' ).appendTo( '#woocommerce-product-data .hndle span' ); + } + + $( function() { + // Prevent inputs in meta box headings opening/closing contents. + $( '#woocommerce-product-data' ).find( '.hndle' ).unbind( 'click.postboxes' ); + + $( '#woocommerce-product-data' ).on( 'click', '.hndle', function( event ) { + + // If the user clicks on some form input inside the h3 the box should not be toggled. + if ( $( event.target ).filter( 'input, option, label, select' ).length ) { + return; + } + + $( '#woocommerce-product-data' ).toggleClass( 'closed' ); + }); + }); + + // Catalog Visibility. + $( '#catalog-visibility' ).find( '.edit-catalog-visibility' ).click( function() { + if ( $( '#catalog-visibility-select' ).is( ':hidden' ) ) { + $( '#catalog-visibility-select' ).slideDown( 'fast' ); + $( this ).hide(); + } + return false; + }); + $( '#catalog-visibility' ).find( '.save-post-visibility' ).click( function() { + $( '#catalog-visibility-select' ).slideUp( 'fast' ); + $( '#catalog-visibility' ).find( '.edit-catalog-visibility' ).show(); + + var label = $( 'input[name=_visibility]:checked' ).attr( 'data-label' ); + + if ( $( 'input[name=_featured]' ).is( ':checked' ) ) { + label = label + ', ' + woocommerce_admin_meta_boxes.featured_label; + $( 'input[name=_featured]' ).attr( 'checked', 'checked' ); + } + + $( '#catalog-visibility-display' ).text( label ); + return false; + }); + $( '#catalog-visibility' ).find( '.cancel-post-visibility' ).click( function() { + $( '#catalog-visibility-select' ).slideUp( 'fast' ); + $( '#catalog-visibility' ).find( '.edit-catalog-visibility' ).show(); + + var current_visibility = $( '#current_visibility' ).val(); + var current_featured = $( '#current_featured' ).val(); + + $( 'input[name=_visibility]' ).removeAttr( 'checked' ); + $( 'input[name=_visibility][value=' + current_visibility + ']' ).attr( 'checked', 'checked' ); + + var label = $( 'input[name=_visibility]:checked' ).attr( 'data-label' ); + + if ( 'yes' === current_featured ) { + label = label + ', ' + woocommerce_admin_meta_boxes.featured_label; + $( 'input[name=_featured]' ).attr( 'checked', 'checked' ); + } else { + $( 'input[name=_featured]' ).removeAttr( 'checked' ); + } + + $( '#catalog-visibility-display' ).text( label ); + return false; + }); + + // Product type specific options. + $( 'select#product-type' ).change( function() { + + // Get value. + var select_val = $( this ).val(); + + if ( 'variable' === select_val ) { + $( 'input#_manage_stock' ).change(); + $( 'input#_downloadable' ).prop( 'checked', false ); + $( 'input#_virtual' ).removeAttr( 'checked' ); + } else if ( 'grouped' === select_val ) { + $( 'input#_downloadable' ).prop( 'checked', false ); + $( 'input#_virtual' ).removeAttr( 'checked' ); + } else if ( 'external' === select_val ) { + $( 'input#_downloadable' ).prop( 'checked', false ); + $( 'input#_virtual' ).removeAttr( 'checked' ); + } + + show_and_hide_panels(); + + $( 'ul.wc-tabs li:visible' ).eq( 0 ).find( 'a' ).click(); + + $( document.body ).trigger( 'woocommerce-product-type-change', select_val, $( this ) ); + + }).change(); + + $( 'input#_downloadable, input#_virtual' ).change( function() { + show_and_hide_panels(); + }); + + function show_and_hide_panels() { + var product_type = $( 'select#product-type' ).val(); + var is_virtual = $( 'input#_virtual:checked' ).length; + var is_downloadable = $( 'input#_downloadable:checked' ).length; + + // Hide/Show all with rules. + var hide_classes = '.hide_if_downloadable, .hide_if_virtual'; + var show_classes = '.show_if_downloadable, .show_if_virtual'; + + $.each( woocommerce_admin_meta_boxes.product_types, function( index, value ) { + hide_classes = hide_classes + ', .hide_if_' + value; + show_classes = show_classes + ', .show_if_' + value; + }); + + $( hide_classes ).show(); + $( show_classes ).hide(); + + // Shows rules. + if ( is_downloadable ) { + $( '.show_if_downloadable' ).show(); + } + if ( is_virtual ) { + $( '.show_if_virtual' ).show(); + } + + $( '.show_if_' + product_type ).show(); + + // Hide rules. + if ( is_downloadable ) { + $( '.hide_if_downloadable' ).hide(); + } + if ( is_virtual ) { + $( '.hide_if_virtual' ).hide(); + } + + $( '.hide_if_' + product_type ).hide(); + + $( 'input#_manage_stock' ).change(); + + // Hide empty panels/tabs after display. + $( '.woocommerce_options_panel' ).each( function() { + var $children = $( this ).children( '.options_group' ); + + if ( 0 === $children.length ) { + return; + } + + var $invisble = $children.filter( function() { + return 'none' === $( this ).css( 'display' ); + }); + + // Hide panel. + if ( $invisble.length === $children.length ) { + var $id = $( this ).prop( 'id' ); + $( '.product_data_tabs' ).find( 'li a[href="#' + $id + '"]' ).parent().hide(); + } + }); + } + + // Sale price schedule. + $( '.sale_price_dates_fields' ).each( function() { + var $these_sale_dates = $( this ); + var sale_schedule_set = false; + var $wrap = $these_sale_dates.closest( 'div, table' ); + + $these_sale_dates.find( 'input' ).each( function() { + if ( '' !== $( this ).val() ) { + sale_schedule_set = true; + } + }); + + if ( sale_schedule_set ) { + $wrap.find( '.sale_schedule' ).hide(); + $wrap.find( '.sale_price_dates_fields' ).show(); + } else { + $wrap.find( '.sale_schedule' ).show(); + $wrap.find( '.sale_price_dates_fields' ).hide(); + } + }); + + $( '#woocommerce-product-data' ).on( 'click', '.sale_schedule', function() { + var $wrap = $( this ).closest( 'div, table' ); + + $( this ).hide(); + $wrap.find( '.cancel_sale_schedule' ).show(); + $wrap.find( '.sale_price_dates_fields' ).show(); + + return false; + }); + $( '#woocommerce-product-data' ).on( 'click', '.cancel_sale_schedule', function() { + var $wrap = $( this ).closest( 'div, table' ); + + $( this ).hide(); + $wrap.find( '.sale_schedule' ).show(); + $wrap.find( '.sale_price_dates_fields' ).hide(); + $wrap.find( '.sale_price_dates_fields' ).find( 'input' ).val(''); + + return false; + }); + + // File inputs. + $( '#woocommerce-product-data' ).on( 'click','.downloadable_files a.insert', function() { + $( this ).closest( '.downloadable_files' ).find( 'tbody' ).append( $( this ).data( 'row' ) ); + return false; + }); + $( '#woocommerce-product-data' ).on( 'click','.downloadable_files a.delete',function() { + $( this ).closest( 'tr' ).remove(); + return false; + }); + + // Stock options. + $( 'input#_manage_stock' ).change( function() { + if ( $( this ).is( ':checked' ) ) { + $( 'div.stock_fields' ).show(); + $( 'p.stock_status_field' ).hide(); + } else { + var product_type = $( 'select#product-type' ).val(); + + $( 'div.stock_fields' ).hide(); + $( 'p.stock_status_field:not( .hide_if_' + product_type + ' )' ).show(); + } + + $( 'input.variable_manage_stock' ).change(); + }).change(); + + // Date picker fields. + function date_picker_select( datepicker ) { + var option = $( datepicker ).next().is( '.hasDatepicker' ) ? 'minDate' : 'maxDate', + otherDateField = 'minDate' === option ? $( datepicker ).next() : $( datepicker ).prev(), + date = $( datepicker ).datepicker( 'getDate' ); + + $( otherDateField ).datepicker( 'option', option, date ); + $( datepicker ).change(); + } + + $( '.sale_price_dates_fields' ).each( function() { + $( this ).find( 'input' ).datepicker({ + defaultDate: '', + dateFormat: 'yy-mm-dd', + numberOfMonths: 1, + showButtonPanel: true, + onSelect: function() { + date_picker_select( $( this ) ); + } + }); + $( this ).find( 'input' ).each( function() { date_picker_select( $( this ) ); } ); + }); + + // Attribute Tables. + + // Initial order. + var woocommerce_attribute_items = $( '.product_attributes' ).find( '.woocommerce_attribute' ).get(); + + woocommerce_attribute_items.sort( function( a, b ) { + var compA = parseInt( $( a ).attr( 'rel' ), 10 ); + var compB = parseInt( $( b ).attr( 'rel' ), 10 ); + return ( compA < compB ) ? -1 : ( compA > compB ) ? 1 : 0; + }); + $( woocommerce_attribute_items ).each( function( index, el ) { + $( '.product_attributes' ).append( el ); + }); + + function attribute_row_indexes() { + $( '.product_attributes .woocommerce_attribute' ).each( function( index, el ) { + $( '.attribute_position', el ).val( parseInt( $( el ).index( '.product_attributes .woocommerce_attribute' ), 10 ) ); + }); + } + + $( '.product_attributes .woocommerce_attribute' ).each( function( index, el ) { + if ( $( el ).css( 'display' ) !== 'none' && $( el ).is( '.taxonomy' ) ) { + $( 'select.attribute_taxonomy' ).find( 'option[value="' + $( el ).data( 'taxonomy' ) + '"]' ).attr( 'disabled', 'disabled' ); + } + }); + + // Add rows. + $( 'button.add_attribute' ).on( 'click', function() { + var size = $( '.product_attributes .woocommerce_attribute' ).length; + var attribute = $( 'select.attribute_taxonomy' ).val(); + var $wrapper = $( this ).closest( '#product_attributes' ); + var $attributes = $wrapper.find( '.product_attributes' ); + var product_type = $( 'select#product-type' ).val(); + var data = { + action: 'woocommerce_add_attribute', + taxonomy: attribute, + i: size, + security: woocommerce_admin_meta_boxes.add_attribute_nonce + }; + + $wrapper.block({ + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + + $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) { + $attributes.append( response ); + + if ( 'variable' !== product_type ) { + $attributes.find( '.enable_variation' ).hide(); + } + + $( document.body ).trigger( 'wc-enhanced-select-init' ); + + attribute_row_indexes(); + + $attributes.find( '.woocommerce_attribute' ).last().find( 'h3' ).click(); + + $wrapper.unblock(); + + $( document.body ).trigger( 'woocommerce_added_attribute' ); + }); + + if ( attribute ) { + $( 'select.attribute_taxonomy' ).find( 'option[value="' + attribute + '"]' ).attr( 'disabled','disabled' ); + $( 'select.attribute_taxonomy' ).val( '' ); + } + + return false; + }); + + $( '.product_attributes' ).on( 'blur', 'input.attribute_name', function() { + $( this ).closest( '.woocommerce_attribute' ).find( 'strong.attribute_name' ).text( $( this ).val() ); + }); + + $( '.product_attributes' ).on( 'click', 'button.select_all_attributes', function() { + $( this ).closest( 'td' ).find( 'select option' ).attr( 'selected', 'selected' ); + $( this ).closest( 'td' ).find( 'select' ).change(); + return false; + }); + + $( '.product_attributes' ).on( 'click', 'button.select_no_attributes', function() { + $( this ).closest( 'td' ).find( 'select option' ).removeAttr( 'selected' ); + $( this ).closest( 'td' ).find( 'select' ).change(); + return false; + }); + + $( '.product_attributes' ).on( 'click', '.remove_row', function() { + if ( window.confirm( woocommerce_admin_meta_boxes.remove_attribute ) ) { + var $parent = $( this ).parent().parent(); + + if ( $parent.is( '.taxonomy' ) ) { + $parent.find( 'select, input[type=text]' ).val( '' ); + $parent.hide(); + $( 'select.attribute_taxonomy' ).find( 'option[value="' + $parent.data( 'taxonomy' ) + '"]' ).removeAttr( 'disabled' ); + } else { + $parent.find( 'select, input[type=text]' ).val( '' ); + $parent.hide(); + attribute_row_indexes(); + } + } + return false; + }); + + // Attribute ordering. + $( '.product_attributes' ).sortable({ + items: '.woocommerce_attribute', + cursor: 'move', + axis: 'y', + handle: 'h3', + scrollSensitivity: 40, + forcePlaceholderSize: true, + helper: 'clone', + opacity: 0.65, + placeholder: 'wc-metabox-sortable-placeholder', + start: function( event, ui ) { + ui.item.css( 'background-color', '#f6f6f6' ); + }, + stop: function( event, ui ) { + ui.item.removeAttr( 'style' ); + attribute_row_indexes(); + } + }); + + // Add a new attribute (via ajax). + $( '.product_attributes' ).on( 'click', 'button.add_new_attribute', function() { + + $( '.product_attributes' ).block({ + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + + var $wrapper = $( this ).closest( '.woocommerce_attribute' ); + var attribute = $wrapper.data( 'taxonomy' ); + var new_attribute_name = window.prompt( woocommerce_admin_meta_boxes.new_attribute_prompt ); + + if ( new_attribute_name ) { + + var data = { + action: 'woocommerce_add_new_attribute', + taxonomy: attribute, + term: new_attribute_name, + security: woocommerce_admin_meta_boxes.add_attribute_nonce + }; + + $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) { + + if ( response.error ) { + // Error. + window.alert( response.error ); + } else if ( response.slug ) { + // Success. + $wrapper.find( 'select.attribute_values' ) + .append( '' ); + $wrapper.find( 'select.attribute_values' ).change(); + } + + $( '.product_attributes' ).unblock(); + }); + + } else { + $( '.product_attributes' ).unblock(); + } + + return false; + }); + + // Save attributes and update variations. + $( '.save_attributes' ).on( 'click', function() { + + $( '.product_attributes' ).block({ + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + var original_data = $( '.product_attributes' ).find( 'input, select, textarea' ); + var data = { + post_id : woocommerce_admin_meta_boxes.post_id, + product_type: $( '#product-type' ).val(), + data : original_data.serialize(), + action : 'woocommerce_save_attributes', + security : woocommerce_admin_meta_boxes.save_attributes_nonce + }; + + $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) { + if ( response.error ) { + // Error. + window.alert( response.error ); + } else if ( response.data ) { + // Success. + $( '.product_attributes' ).html( response.data.html ); + $( '.product_attributes' ).unblock(); + + // Hide the 'Used for variations' checkbox if not viewing a variable product + show_and_hide_panels(); + + // Make sure the dropdown is not disabled for empty value attributes. + $( 'select.attribute_taxonomy' ).find( 'option' ).prop( 'disabled', false ); + + $( '.product_attributes .woocommerce_attribute' ).each( function( index, el ) { + if ( $( el ).css( 'display' ) !== 'none' && $( el ).is( '.taxonomy' ) ) { + $( 'select.attribute_taxonomy' ) + .find( 'option[value="' + $( el ).data( 'taxonomy' ) + '"]' ) + .prop( 'disabled', true ); + } + }); + + // Reload variations panel. + var this_page = window.location.toString(); + this_page = this_page.replace( 'post-new.php?', 'post.php?post=' + woocommerce_admin_meta_boxes.post_id + '&action=edit&' ); + + $( '#variable_product_options' ).load( this_page + ' #variable_product_options_inner', function() { + $( '#variable_product_options' ).trigger( 'reload' ); + } ); + } + }); + }); + + // Uploading files. + var downloadable_file_frame; + var file_path_field; + + $( document.body ).on( 'click', '.upload_file_button', function( event ) { + var $el = $( this ); + + file_path_field = $el.closest( 'tr' ).find( 'td.file_url input' ); + + event.preventDefault(); + + // If the media frame already exists, reopen it. + if ( downloadable_file_frame ) { + downloadable_file_frame.open(); + return; + } + + var downloadable_file_states = [ + // Main states. + new wp.media.controller.Library({ + library: wp.media.query(), + multiple: true, + title: $el.data('choose'), + priority: 20, + filterable: 'uploaded' + }) + ]; + + // Create the media frame. + downloadable_file_frame = wp.media.frames.downloadable_file = wp.media({ + // Set the title of the modal. + title: $el.data('choose'), + library: { + type: '' + }, + button: { + text: $el.data('update') + }, + multiple: true, + states: downloadable_file_states + }); + + // When an image is selected, run a callback. + downloadable_file_frame.on( 'select', function() { + var file_path = ''; + var selection = downloadable_file_frame.state().get( 'selection' ); + + selection.map( function( attachment ) { + attachment = attachment.toJSON(); + if ( attachment.url ) { + file_path = attachment.url; + } + }); + + file_path_field.val( file_path ).change(); + }); + + // Set post to 0 and set our custom type. + downloadable_file_frame.on( 'ready', function() { + downloadable_file_frame.uploader.options.uploader.params = { + type: 'downloadable_product' + }; + }); + + // Finally, open the modal. + downloadable_file_frame.open(); + }); + + // Download ordering. + $( '.downloadable_files tbody' ).sortable({ + items: 'tr', + cursor: 'move', + axis: 'y', + handle: 'td.sort', + scrollSensitivity: 40, + forcePlaceholderSize: true, + helper: 'clone', + opacity: 0.65 + }); + + // Product gallery file uploads. + var product_gallery_frame; + var $image_gallery_ids = $( '#product_image_gallery' ); + var $product_images = $( '#product_images_container' ).find( 'ul.product_images' ); + + $( '.add_product_images' ).on( 'click', 'a', function( event ) { + var $el = $( this ); + + event.preventDefault(); + + // If the media frame already exists, reopen it. + if ( product_gallery_frame ) { + product_gallery_frame.open(); + return; + } + + // Create the media frame. + product_gallery_frame = wp.media.frames.product_gallery = wp.media({ + // Set the title of the modal. + title: $el.data( 'choose' ), + button: { + text: $el.data( 'update' ) + }, + states: [ + new wp.media.controller.Library({ + title: $el.data( 'choose' ), + filterable: 'all', + multiple: true + }) + ] + }); + + // When an image is selected, run a callback. + product_gallery_frame.on( 'select', function() { + var selection = product_gallery_frame.state().get( 'selection' ); + var attachment_ids = $image_gallery_ids.val(); + + selection.map( function( attachment ) { + attachment = attachment.toJSON(); + + if ( attachment.id ) { + attachment_ids = attachment_ids ? attachment_ids + ',' + attachment.id : attachment.id; + var attachment_image = attachment.sizes && attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url; + + $product_images.append( + '
  • ' + ); + } + }); + + $image_gallery_ids.val( attachment_ids ); + }); + + // Finally, open the modal. + product_gallery_frame.open(); + }); + + // Image ordering. + $product_images.sortable({ + items: 'li.image', + cursor: 'move', + scrollSensitivity: 40, + forcePlaceholderSize: true, + forceHelperSize: false, + helper: 'clone', + opacity: 0.65, + placeholder: 'wc-metabox-sortable-placeholder', + start: function( event, ui ) { + ui.item.css( 'background-color', '#f6f6f6' ); + }, + stop: function( event, ui ) { + ui.item.removeAttr( 'style' ); + }, + update: function() { + var attachment_ids = ''; + + $( '#product_images_container' ).find( 'ul li.image' ).css( 'cursor', 'default' ).each( function() { + var attachment_id = $( this ).attr( 'data-attachment_id' ); + attachment_ids = attachment_ids + attachment_id + ','; + }); + + $image_gallery_ids.val( attachment_ids ); + } + }); + + // Remove images. + $( '#product_images_container' ).on( 'click', 'a.delete', function() { + $( this ).closest( 'li.image' ).remove(); + + var attachment_ids = ''; + + $( '#product_images_container' ).find( 'ul li.image' ).css( 'cursor', 'default' ).each( function() { + var attachment_id = $( this ).attr( 'data-attachment_id' ); + attachment_ids = attachment_ids + attachment_id + ','; + }); + + $image_gallery_ids.val( attachment_ids ); + + // Remove any lingering tooltips. + $( '#tiptip_holder' ).removeAttr( 'style' ); + $( '#tiptip_arrow' ).removeAttr( 'style' ); + + return false; + }); +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-product.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-product.min.js new file mode 100644 index 0000000..fd49c91 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes-product.min.js @@ -0,0 +1 @@ +jQuery(function(c){function e(){var t=c("select#product-type").val(),e=c("input#_virtual:checked").length,i=c("input#_downloadable:checked").length,o=".hide_if_downloadable, .hide_if_virtual",a=".show_if_downloadable, .show_if_virtual";c.each(woocommerce_admin_meta_boxes.product_types,function(t,e){o=o+", .hide_if_"+e,a=a+", .show_if_"+e}),c(o).show(),c(a).hide(),i&&c(".show_if_downloadable").show(),e&&c(".show_if_virtual").show(),c(".show_if_"+t).show(),i&&c(".hide_if_downloadable").hide(),e&&c(".hide_if_virtual").hide(),c(".hide_if_"+t).hide(),c("input#_manage_stock").change(),c(".woocommerce_options_panel").each(function(){var t=c(this).children(".options_group");0!==t.length&&t.filter(function(){return"none"===c(this).css("display")}).length===t.length&&(t=c(this).prop("id"),c(".product_data_tabs").find('li a[href="#'+t+'"]').parent().hide())})}function t(t){var e=c(t).next().is(".hasDatepicker")?"minDate":"maxDate",i="minDate"==e?c(t).next():c(t).prev(),o=c(t).datepicker("getDate");c(i).datepicker("option",e,o),c(t).change()}c(function(){c('[id$="-all"] > ul.categorychecklist').each(function(){var t,e=c(this),i=e.find(":checked").first();i.length&&(t=e.find("input").position().top,i=i.position().top,e.closest(".tabs-panel").scrollTop(i-t+5))})}),c("#upsell_product_data").bind("keypress",function(t){if(13===t.keyCode)return!1}),c("body").hasClass("wc-wp-version-gte-55")?c(".type_box").appendTo("#woocommerce-product-data .hndle"):c(".type_box").appendTo("#woocommerce-product-data .hndle span"),c(function(){c("#woocommerce-product-data").find(".hndle").unbind("click.postboxes"),c("#woocommerce-product-data").on("click",".hndle",function(t){c(t.target).filter("input, option, label, select").length||c("#woocommerce-product-data").toggleClass("closed")})}),c("#catalog-visibility").find(".edit-catalog-visibility").click(function(){return c("#catalog-visibility-select").is(":hidden")&&(c("#catalog-visibility-select").slideDown("fast"),c(this).hide()),!1}),c("#catalog-visibility").find(".save-post-visibility").click(function(){c("#catalog-visibility-select").slideUp("fast"),c("#catalog-visibility").find(".edit-catalog-visibility").show();var t=c("input[name=_visibility]:checked").attr("data-label");return c("input[name=_featured]").is(":checked")&&(t=t+", "+woocommerce_admin_meta_boxes.featured_label,c("input[name=_featured]").attr("checked","checked")),c("#catalog-visibility-display").text(t),!1}),c("#catalog-visibility").find(".cancel-post-visibility").click(function(){c("#catalog-visibility-select").slideUp("fast"),c("#catalog-visibility").find(".edit-catalog-visibility").show();var t=c("#current_visibility").val(),e=c("#current_featured").val();c("input[name=_visibility]").removeAttr("checked"),c("input[name=_visibility][value="+t+"]").attr("checked","checked");t=c("input[name=_visibility]:checked").attr("data-label");return"yes"===e?(t=t+", "+woocommerce_admin_meta_boxes.featured_label,c("input[name=_featured]").attr("checked","checked")):c("input[name=_featured]").removeAttr("checked"),c("#catalog-visibility-display").text(t),!1}),c("select#product-type").change(function(){var t=c(this).val();"variable"===t?(c("input#_manage_stock").change(),c("input#_downloadable").prop("checked",!1),c("input#_virtual").removeAttr("checked")):"grouped"!==t&&"external"!==t||(c("input#_downloadable").prop("checked",!1),c("input#_virtual").removeAttr("checked")),e(),c("ul.wc-tabs li:visible").eq(0).find("a").click(),c(document.body).trigger("woocommerce-product-type-change",t,c(this))}).change(),c("input#_downloadable, input#_virtual").change(function(){e()}),c(".sale_price_dates_fields").each(function(){var t=c(this),e=!1,i=t.closest("div, table");t.find("input").each(function(){""!==c(this).val()&&(e=!0)}),e?(i.find(".sale_schedule").hide(),i.find(".sale_price_dates_fields").show()):(i.find(".sale_schedule").show(),i.find(".sale_price_dates_fields").hide())}),c("#woocommerce-product-data").on("click",".sale_schedule",function(){var t=c(this).closest("div, table");return c(this).hide(),t.find(".cancel_sale_schedule").show(),t.find(".sale_price_dates_fields").show(),!1}),c("#woocommerce-product-data").on("click",".cancel_sale_schedule",function(){var t=c(this).closest("div, table");return c(this).hide(),t.find(".sale_schedule").show(),t.find(".sale_price_dates_fields").hide(),t.find(".sale_price_dates_fields").find("input").val(""),!1}),c("#woocommerce-product-data").on("click",".downloadable_files a.insert",function(){return c(this).closest(".downloadable_files").find("tbody").append(c(this).data("row")),!1}),c("#woocommerce-product-data").on("click",".downloadable_files a.delete",function(){return c(this).closest("tr").remove(),!1}),c("input#_manage_stock").change(function(){var t;c(this).is(":checked")?(c("div.stock_fields").show(),c("p.stock_status_field").hide()):(t=c("select#product-type").val(),c("div.stock_fields").hide(),c("p.stock_status_field:not( .hide_if_"+t+" )").show()),c("input.variable_manage_stock").change()}).change(),c(".sale_price_dates_fields").each(function(){c(this).find("input").datepicker({defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:!0,onSelect:function(){t(c(this))}}),c(this).find("input").each(function(){t(c(this))})});var i,o,a,n=c(".product_attributes").find(".woocommerce_attribute").get();function r(){c(".product_attributes .woocommerce_attribute").each(function(t,e){c(".attribute_position",e).val(parseInt(c(e).index(".product_attributes .woocommerce_attribute"),10))})}n.sort(function(t,e){t=parseInt(c(t).attr("rel"),10),e=parseInt(c(e).attr("rel"),10);return t'+t.name+""),e.find("select.attribute_values").change()),c(".product_attributes").unblock()})):c(".product_attributes").unblock(),!1}),c(".save_attributes").on("click",function(){c(".product_attributes").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var t=c(".product_attributes").find("input, select, textarea"),t={post_id:woocommerce_admin_meta_boxes.post_id,product_type:c("#product-type").val(),data:t.serialize(),action:"woocommerce_save_attributes",security:woocommerce_admin_meta_boxes.save_attributes_nonce};c.post(woocommerce_admin_meta_boxes.ajax_url,t,function(t){t.error?window.alert(t.error):t.data&&(c(".product_attributes").html(t.data.html),c(".product_attributes").unblock(),e(),c("select.attribute_taxonomy").find("option").prop("disabled",!1),c(".product_attributes .woocommerce_attribute").each(function(t,e){"none"!==c(e).css("display")&&c(e).is(".taxonomy")&&c("select.attribute_taxonomy").find('option[value="'+c(e).data("taxonomy")+'"]').prop("disabled",!0)}),t=(t=window.location.toString()).replace("post-new.php?","post.php?post="+woocommerce_admin_meta_boxes.post_id+"&action=edit&"),c("#variable_product_options").load(t+" #variable_product_options_inner",function(){c("#variable_product_options").trigger("reload")}))})}),c(document.body).on("click",".upload_file_button",function(t){var e=c(this);o=e.closest("tr").find("td.file_url input"),t.preventDefault(),i||(t=[new wp.media.controller.Library({library:wp.media.query(),multiple:!0,title:e.data("choose"),priority:20,filterable:"uploaded"})],(i=wp.media.frames.downloadable_file=wp.media({title:e.data("choose"),library:{type:""},button:{text:e.data("update")},multiple:!0,states:t})).on("select",function(){var e="";i.state().get("selection").map(function(t){(t=t.toJSON()).url&&(e=t.url)}),o.val(e).change()}),i.on("ready",function(){i.uploader.options.uploader.params={type:"downloadable_product"}})),i.open()}),c(".downloadable_files tbody").sortable({items:"tr",cursor:"move",axis:"y",handle:"td.sort",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65});var l=c("#product_image_gallery"),s=c("#product_images_container").find("ul.product_images");c(".add_product_images").on("click","a",function(t){var o=c(this);t.preventDefault(),a||(a=wp.media.frames.product_gallery=wp.media({title:o.data("choose"),button:{text:o.data("update")},states:[new wp.media.controller.Library({title:o.data("choose"),filterable:"all",multiple:!0})]})).on("select",function(){var t=a.state().get("selection"),i=l.val();t.map(function(t){var e;(t=t.toJSON()).id&&(i=i?i+","+t.id:t.id,e=(t.sizes&&t.sizes.thumbnail?t.sizes.thumbnail:t).url,s.append('
  • "))}),l.val(i)}),a.open()}),s.sortable({items:"li.image",cursor:"move",scrollSensitivity:40,forcePlaceholderSize:!0,forceHelperSize:!1,helper:"clone",opacity:.65,placeholder:"wc-metabox-sortable-placeholder",start:function(t,e){e.item.css("background-color","#f6f6f6")},stop:function(t,e){e.item.removeAttr("style")},update:function(){var e="";c("#product_images_container").find("ul li.image").css("cursor","default").each(function(){var t=c(this).attr("data-attachment_id");e=e+t+","}),l.val(e)}}),c("#product_images_container").on("click","a.delete",function(){c(this).closest("li.image").remove();var e="";return c("#product_images_container").find("ul li.image").css("cursor","default").each(function(){var t=c(this).attr("data-attachment_id");e=e+t+","}),l.val(e),c("#tiptip_holder").removeAttr("style"),c("#tiptip_arrow").removeAttr("style"),!1})}); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes.js new file mode 100644 index 0000000..13e2c4a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes.js @@ -0,0 +1,80 @@ +jQuery( function ( $ ) { + + // Run tipTip + function runTipTip() { + // Remove any lingering tooltips + $( '#tiptip_holder' ).removeAttr( 'style' ); + $( '#tiptip_arrow' ).removeAttr( 'style' ); + $( '.tips' ).tipTip({ + 'attribute': 'data-tip', + 'fadeIn': 50, + 'fadeOut': 50, + 'delay': 200, + 'keepAlive': true + }); + } + + runTipTip(); + + // Allow Tabbing + $( '#titlediv' ).find( '#title' ).keyup( function( event ) { + var code = event.keyCode || event.which; + + // Tab key + if ( code === '9' && $( '#woocommerce-coupon-description' ).length > 0 ) { + event.stopPropagation(); + $( '#woocommerce-coupon-description' ).focus(); + return false; + } + }); + + $( '.wc-metaboxes-wrapper' ).on( 'click', '.wc-metabox > h3', function() { + $( this ).parent( '.wc-metabox' ).toggleClass( 'closed' ).toggleClass( 'open' ); + }); + + // Tabbed Panels + $( document.body ).on( 'wc-init-tabbed-panels', function() { + $( 'ul.wc-tabs' ).show(); + $( 'ul.wc-tabs a' ).click( function( e ) { + e.preventDefault(); + var panel_wrap = $( this ).closest( 'div.panel-wrap' ); + $( 'ul.wc-tabs li', panel_wrap ).removeClass( 'active' ); + $( this ).parent().addClass( 'active' ); + $( 'div.panel', panel_wrap ).hide(); + $( $( this ).attr( 'href' ) ).show(); + }); + $( 'div.panel-wrap' ).each( function() { + $( this ).find( 'ul.wc-tabs li' ).eq( 0 ).find( 'a' ).click(); + }); + }).trigger( 'wc-init-tabbed-panels' ); + + // Date Picker + $( document.body ).on( 'wc-init-datepickers', function() { + $( '.date-picker-field, .date-picker' ).datepicker({ + dateFormat: 'yy-mm-dd', + numberOfMonths: 1, + showButtonPanel: true + }); + }).trigger( 'wc-init-datepickers' ); + + // Meta-Boxes - Open/close + $( '.wc-metaboxes-wrapper' ).on( 'click', '.wc-metabox h3', function( event ) { + // If the user clicks on some form input inside the h3, like a select list (for variations), the box should not be toggled + if ( $( event.target ).filter( ':input, option, .sort' ).length ) { + return; + } + + $( this ).next( '.wc-metabox-content' ).stop().slideToggle(); + }) + .on( 'click', '.expand_all', function() { + $( this ).closest( '.wc-metaboxes-wrapper' ).find( '.wc-metabox > .wc-metabox-content' ).show(); + return false; + }) + .on( 'click', '.close_all', function() { + $( this ).closest( '.wc-metaboxes-wrapper' ).find( '.wc-metabox > .wc-metabox-content' ).hide(); + return false; + }); + $( '.wc-metabox.closed' ).each( function() { + $( this ).find( '.wc-metabox-content' ).hide(); + }); +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes.min.js new file mode 100644 index 0000000..31e95bc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/meta-boxes.min.js @@ -0,0 +1 @@ +jQuery(function(e){e("#tiptip_holder").removeAttr("style"),e("#tiptip_arrow").removeAttr("style"),e(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200,keepAlive:!0}),e("#titlediv").find("#title").keyup(function(t){if("9"===(t.keyCode||t.which)&&0 h3",function(){e(this).parent(".wc-metabox").toggleClass("closed").toggleClass("open")}),e(document.body).on("wc-init-tabbed-panels",function(){e("ul.wc-tabs").show(),e("ul.wc-tabs a").click(function(t){t.preventDefault();t=e(this).closest("div.panel-wrap");e("ul.wc-tabs li",t).removeClass("active"),e(this).parent().addClass("active"),e("div.panel",t).hide(),e(e(this).attr("href")).show()}),e("div.panel-wrap").each(function(){e(this).find("ul.wc-tabs li").eq(0).find("a").click()})}).trigger("wc-init-tabbed-panels"),e(document.body).on("wc-init-datepickers",function(){e(".date-picker-field, .date-picker").datepicker({dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:!0})}).trigger("wc-init-datepickers"),e(".wc-metaboxes-wrapper").on("click",".wc-metabox h3",function(t){e(t.target).filter(":input, option, .sort").length||e(this).next(".wc-metabox-content").stop().slideToggle()}).on("click",".expand_all",function(){return e(this).closest(".wc-metaboxes-wrapper").find(".wc-metabox > .wc-metabox-content").show(),!1}).on("click",".close_all",function(){return e(this).closest(".wc-metaboxes-wrapper").find(".wc-metabox > .wc-metabox-content").hide(),!1}),e(".wc-metabox.closed").each(function(){e(this).find(".wc-metabox-content").hide()})}); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/network-orders.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/network-orders.js new file mode 100644 index 0000000..aa3a2ac --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/network-orders.js @@ -0,0 +1,90 @@ +/*global woocommerce_network_orders */ +(function( $, _, undefined ) { + + if ( 'undefined' === typeof woocommerce_network_orders ) { + return; + } + + var orders = [], + promises = [], // Track completion (pass or fail) of ajax requests. + deferred = [], // Tracks the ajax deferreds. + $tbody = $( document.getElementById( 'network-orders-tbody' ) ), + template = _.template( $( document.getElementById( 'network-orders-row-template') ).text() ), + $loadingIndicator = $( document.getElementById( 'woocommerce-network-order-table-loading' ) ), + $orderTable = $( document.getElementById( 'woocommerce-network-order-table' ) ), + $noneFound = $( document.getElementById( 'woocommerce-network-orders-no-orders' ) ); + + // No sites, so bail. + if ( ! woocommerce_network_orders.sites.length ) { + $loadingIndicator.removeClass( 'is-active' ); + $orderTable.removeClass( 'is-active' ); + $noneFound.addClass( 'is-active' ); + return; + } + + $.each( woocommerce_network_orders.sites, function( index, value ) { + promises[ index ] = $.Deferred(); + deferred.push( $.ajax( { + url : woocommerce_network_orders.order_endpoint, + data: { + _wpnonce: woocommerce_network_orders.nonce, + network_orders: true, + blog_id: value + }, + type: 'GET' + } ).success(function( response ) { + var orderindex; + + for ( orderindex in response ) { + orders.push( response[ orderindex ] ); + } + + promises[ index ].resolve(); + }).fail(function (){ + promises[ index ].resolve(); + }) ); + } ); + + if ( promises.length > 0 ) { + $.when.apply( $, promises ).done( function() { + var orderindex, + currentOrder; + + // Sort orders, newest first + orders.sort(function( a, b ) { + var adate, bdate; + + adate = Date.parse( a.date_created_gmt ); + bdate = Date.parse( b.date_created_gmt ); + + if ( adate === bdate ) { + return 0; + } + + if ( adate < bdate ) { + return 1; + } else { + return -1; + } + }); + + if ( orders.length > 0 ) { + for ( orderindex in orders ) { + currentOrder = orders[ orderindex ]; + + $tbody.append( template( currentOrder ) ); + } + + $noneFound.removeClass( 'is-active' ); + $loadingIndicator.removeClass( 'is-active' ); + $orderTable.addClass( 'is-active' ); + } else { + $noneFound.addClass( 'is-active' ); + $loadingIndicator.removeClass( 'is-active' ); + $orderTable.removeClass( 'is-active' ); + } + + } ); + } + +})( jQuery, _ ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/network-orders.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/network-orders.min.js new file mode 100644 index 0000000..ee4168a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/network-orders.min.js @@ -0,0 +1 @@ +!function(o,e){if("undefined"!=typeof woocommerce_network_orders){var t=[],n=[],s=[],r=o(document.getElementById("network-orders-tbody")),a=e.template(o(document.getElementById("network-orders-row-template")).text()),c=o(document.getElementById("woocommerce-network-order-table-loading")),d=o(document.getElementById("woocommerce-network-order-table")),i=o(document.getElementById("woocommerce-network-orders-no-orders"));if(!woocommerce_network_orders.sites.length)return c.removeClass("is-active"),d.removeClass("is-active"),i.addClass("is-active");o.each(woocommerce_network_orders.sites,function(r,e){n[r]=o.Deferred(),s.push(o.ajax({url:woocommerce_network_orders.order_endpoint,data:{_wpnonce:woocommerce_network_orders.nonce,network_orders:!0,blog_id:e},type:"GET"}).success(function(e){for(var o in e)t.push(e[o]);n[r].resolve()}).fail(function(){n[r].resolve()}))}),0' ); + + // Go do the sorting stuff via ajax + $.post( + ajaxurl, + { action: 'woocommerce_product_ordering', id: postid, previd: prevpostid, nextid: nextpostid }, + function( response ) { + $.each( response, function( key, value ) { + $( '#inline_' + key + ' .menu_order' ).html( value ); + }); + ui.item.find( '.check-column input' ).show().siblings( 'img' ).remove(); + $( 'table.widefat tbody th, table.widefat tbody td' ).css( 'cursor', 'move' ); + $( 'table.widefat tbody' ).sortable( 'enable' ); + } + ); + + // fix cell colors + $( 'table.widefat tbody tr' ).each( function() { + var i = $( 'table.widefat tbody tr' ).index( this ); + if ( i%2 === 0 ) { + $( this ).addClass( 'alternate' ); + } else { + $( this ).removeClass( 'alternate' ); + } + }); + } + }); +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/product-ordering.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/product-ordering.min.js new file mode 100644 index 0000000..54db47f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/product-ordering.min.js @@ -0,0 +1 @@ +jQuery(function(d){d("table.widefat tbody th, table.widefat tbody td").css("cursor","move"),d("table.widefat tbody").sortable({items:"tr:not(.inline-edit-row)",cursor:"move",axis:"y",containment:"table.widefat",scrollSensitivity:40,helper:function(t,e){return e.each(function(){d(this).width(d(this).width())}),e},start:function(t,e){e.item.css("background-color","#ffffff"),e.item.children("td, th").css("border-bottom-width","0"),e.item.css("outline","1px solid #dfdfdf")},stop:function(t,e){e.item.removeAttr("style"),e.item.children("td,th").css("border-bottom-width","1px")},update:function(t,e){d("table.widefat tbody th, table.widefat tbody td").css("cursor","default"),d("table.widefat tbody").sortable("disable");var i=e.item.find(".check-column input").val(),o=e.item.prev().find(".check-column input").val(),n=e.item.next().find(".check-column input").val();e.item.find(".check-column input").hide().after('processing'),d.post(ajaxurl,{action:"woocommerce_product_ordering",id:i,previd:o,nextid:n},function(t){d.each(t,function(t,e){d("#inline_"+t+" .menu_order").html(e)}),e.item.find(".check-column input").show().siblings("img").remove(),d("table.widefat tbody th, table.widefat tbody td").css("cursor","move"),d("table.widefat tbody").sortable("enable")}),d("table.widefat tbody tr").each(function(){d("table.widefat tbody tr").index(this)%2==0?d(this).addClass("alternate"):d(this).removeClass("alternate")})}})}); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/quick-edit.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/quick-edit.js new file mode 100644 index 0000000..ad5ccb0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/quick-edit.js @@ -0,0 +1,166 @@ +/*global inlineEditPost, woocommerce_admin, woocommerce_quick_edit */ +jQuery( + function( $ ) { + $( '#the-list' ).on( + 'click', + '.editinline', + function() { + + inlineEditPost.revert(); + + var post_id = $( this ).closest( 'tr' ).attr( 'id' ); + + post_id = post_id.replace( 'post-', '' ); + + var $wc_inline_data = $( '#woocommerce_inline_' + post_id ); + + var sku = $wc_inline_data.find( '.sku' ).text(), + regular_price = $wc_inline_data.find( '.regular_price' ).text(), + sale_price = $wc_inline_data.find( '.sale_price ' ).text(), + weight = $wc_inline_data.find( '.weight' ).text(), + length = $wc_inline_data.find( '.length' ).text(), + width = $wc_inline_data.find( '.width' ).text(), + height = $wc_inline_data.find( '.height' ).text(), + shipping_class = $wc_inline_data.find( '.shipping_class' ).text(), + visibility = $wc_inline_data.find( '.visibility' ).text(), + stock_status = $wc_inline_data.find( '.stock_status' ).text(), + stock = $wc_inline_data.find( '.stock' ).text(), + featured = $wc_inline_data.find( '.featured' ).text(), + manage_stock = $wc_inline_data.find( '.manage_stock' ).text(), + menu_order = $wc_inline_data.find( '.menu_order' ).text(), + tax_status = $wc_inline_data.find( '.tax_status' ).text(), + tax_class = $wc_inline_data.find( '.tax_class' ).text(), + backorders = $wc_inline_data.find( '.backorders' ).text(), + product_type = $wc_inline_data.find( '.product_type' ).text(); + + var formatted_regular_price = regular_price.replace( '.', woocommerce_admin.mon_decimal_point ), + formatted_sale_price = sale_price.replace( '.', woocommerce_admin.mon_decimal_point ); + + $( 'input[name="_sku"]', '.inline-edit-row' ).val( sku ); + $( 'input[name="_regular_price"]', '.inline-edit-row' ).val( formatted_regular_price ); + $( 'input[name="_sale_price"]', '.inline-edit-row' ).val( formatted_sale_price ); + $( 'input[name="_weight"]', '.inline-edit-row' ).val( weight ); + $( 'input[name="_length"]', '.inline-edit-row' ).val( length ); + $( 'input[name="_width"]', '.inline-edit-row' ).val( width ); + $( 'input[name="_height"]', '.inline-edit-row' ).val( height ); + + $( 'select[name="_shipping_class"] option:selected', '.inline-edit-row' ).attr( 'selected', false ).change(); + $( 'select[name="_shipping_class"] option[value="' + shipping_class + '"]' ).attr( 'selected', 'selected' ).change(); + + $( 'input[name="_stock"]', '.inline-edit-row' ).val( stock ); + $( 'input[name="menu_order"]', '.inline-edit-row' ).val( menu_order ); + + $( + 'select[name="_tax_status"] option, ' + + 'select[name="_tax_class"] option, ' + + 'select[name="_visibility"] option, ' + + 'select[name="_stock_status"] option, ' + + 'select[name="_backorders"] option' + ).removeAttr( 'selected' ); + + var is_variable_product = 'variable' === product_type; + $( 'select[name="_stock_status"] ~ .wc-quick-edit-warning', '.inline-edit-row' ).toggle( is_variable_product ); + $( 'select[name="_stock_status"] option[value="' + (is_variable_product ? '' : stock_status) + '"]', '.inline-edit-row' ) + .attr( 'selected', 'selected' ); + + $( 'select[name="_tax_status"] option[value="' + tax_status + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' ); + $( 'select[name="_tax_class"] option[value="' + tax_class + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' ); + $( 'select[name="_visibility"] option[value="' + visibility + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' ); + $( 'select[name="_backorders"] option[value="' + backorders + '"]', '.inline-edit-row' ).attr( 'selected', 'selected' ); + + if ( 'yes' === featured ) { + $( 'input[name="_featured"]', '.inline-edit-row' ).attr( 'checked', 'checked' ); + } else { + $( 'input[name="_featured"]', '.inline-edit-row' ).removeAttr( 'checked' ); + } + + // Conditional display. + var product_is_virtual = $wc_inline_data.find( '.product_is_virtual' ).text(); + + var product_supports_stock_status = 'external' !== product_type; + var product_supports_stock_fields = 'external' !== product_type && 'grouped' !== product_type; + + $( '.stock_fields, .manage_stock_field, .stock_status_field, .backorder_field' ).show(); + + if ( product_supports_stock_fields ) { + if ( 'yes' === manage_stock ) { + $( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).show().removeAttr( 'style' ); + $( '.stock_status_field' ).hide(); + $( '.manage_stock_field input' ).prop( 'checked', true ); + } else { + $( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).hide(); + $( '.stock_status_field' ).show().removeAttr( 'style' ); + $( '.manage_stock_field input' ).prop( 'checked', false ); + } + } else if ( product_supports_stock_status ) { + $( '.stock_fields, .manage_stock_field, .backorder_field' ).hide(); + } else { + $( '.stock_fields, .manage_stock_field, .stock_status_field, .backorder_field' ).hide(); + } + + if ( 'simple' === product_type || 'external' === product_type ) { + $( '.price_fields', '.inline-edit-row' ).show().removeAttr( 'style' ); + } else { + $( '.price_fields', '.inline-edit-row' ).hide(); + } + + if ( 'yes' === product_is_virtual ) { + $( '.dimension_fields', '.inline-edit-row' ).hide(); + } else { + $( '.dimension_fields', '.inline-edit-row' ).show().removeAttr( 'style' ); + } + + // Rename core strings. + $( 'input[name="comment_status"]' ).parent().find( '.checkbox-title' ).text( woocommerce_quick_edit.strings.allow_reviews ); + } + ); + + $( '#the-list' ).on( + 'change', + '.inline-edit-row input[name="_manage_stock"]', + function() { + + if ( $( this ).is( ':checked' ) ) { + $( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).show().removeAttr( 'style' ); + $( '.stock_status_field' ).hide(); + } else { + $( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).hide(); + $( '.stock_status_field' ).show().removeAttr( 'style' ); + } + + } + ); + + $( '#wpbody' ).on( + 'click', + '#doaction, #doaction2', + function() { + $( 'input.text', '.inline-edit-row' ).val( '' ); + $( '#woocommerce-fields' ).find( 'select' ).prop( 'selectedIndex', 0 ); + $( '#woocommerce-fields-bulk' ).find( '.inline-edit-group .change-input' ).hide(); + } + ); + + $( '#wpbody' ).on( + 'change', + '#woocommerce-fields-bulk .inline-edit-group .change_to', + function() { + + if ( 0 < $( this ).val() ) { + $( this ).closest( 'div' ).find( '.change-input' ).show(); + } else { + $( this ).closest( 'div' ).find( '.change-input' ).hide(); + } + + } + ); + + $( '#wpbody' ).on( + 'click', + '.trash-product', + function() { + return window.confirm( woocommerce_admin.i18n_delete_product_notice ); + } + ); + } +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/quick-edit.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/quick-edit.min.js new file mode 100644 index 0000000..edbb6bf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/quick-edit.min.js @@ -0,0 +1 @@ +jQuery(function(v){v("#the-list").on("click",".editinline",function(){inlineEditPost.revert();var e=(e=v(this).closest("tr").attr("id")).replace("post-",""),t=v("#woocommerce_inline_"+e),i=t.find(".sku").text(),n=t.find(".regular_price").text(),o=t.find(".sale_price ").text(),d=t.find(".weight").text(),s=t.find(".length").text(),l=t.find(".width").text(),c=t.find(".height").text(),a=t.find(".shipping_class").text(),r=t.find(".visibility").text(),_=t.find(".stock_status").text(),m=t.find(".stock").text(),p=t.find(".featured").text(),u=t.find(".manage_stock").text(),f=t.find(".menu_order").text(),w=t.find(".tax_status").text(),h=t.find(".tax_class").text(),k=t.find(".backorders").text(),e=t.find(".product_type").text(),n=n.replace(".",woocommerce_admin.mon_decimal_point),o=o.replace(".",woocommerce_admin.mon_decimal_point);v('input[name="_sku"]',".inline-edit-row").val(i),v('input[name="_regular_price"]',".inline-edit-row").val(n),v('input[name="_sale_price"]',".inline-edit-row").val(o),v('input[name="_weight"]',".inline-edit-row").val(d),v('input[name="_length"]',".inline-edit-row").val(s),v('input[name="_width"]',".inline-edit-row").val(l),v('input[name="_height"]',".inline-edit-row").val(c),v('select[name="_shipping_class"] option:selected',".inline-edit-row").attr("selected",!1).change(),v('select[name="_shipping_class"] option[value="'+a+'"]').attr("selected","selected").change(),v('input[name="_stock"]',".inline-edit-row").val(m),v('input[name="menu_order"]',".inline-edit-row").val(f),v('select[name="_tax_status"] option, select[name="_tax_class"] option, select[name="_visibility"] option, select[name="_stock_status"] option, select[name="_backorders"] option').removeAttr("selected");f="variable"===e;v('select[name="_stock_status"] ~ .wc-quick-edit-warning',".inline-edit-row").toggle(f),v('select[name="_stock_status"] option[value="'+(f?"":_)+'"]',".inline-edit-row").attr("selected","selected"),v('select[name="_tax_status"] option[value="'+w+'"]',".inline-edit-row").attr("selected","selected"),v('select[name="_tax_class"] option[value="'+h+'"]',".inline-edit-row").attr("selected","selected"),v('select[name="_visibility"] option[value="'+r+'"]',".inline-edit-row").attr("selected","selected"),v('select[name="_backorders"] option[value="'+k+'"]',".inline-edit-row").attr("selected","selected"),"yes"===p?v('input[name="_featured"]',".inline-edit-row").attr("checked","checked"):v('input[name="_featured"]',".inline-edit-row").removeAttr("checked");k=t.find(".product_is_virtual").text(),p="external"!==e,t="external"!==e&&"grouped"!==e;v(".stock_fields, .manage_stock_field, .stock_status_field, .backorder_field").show(),t?"yes"===u?(v(".stock_qty_field, .backorder_field",".inline-edit-row").show().removeAttr("style"),v(".stock_status_field").hide(),v(".manage_stock_field input").prop("checked",!0)):(v(".stock_qty_field, .backorder_field",".inline-edit-row").hide(),v(".stock_status_field").show().removeAttr("style"),v(".manage_stock_field input").prop("checked",!1)):v(p?".stock_fields, .manage_stock_field, .backorder_field":".stock_fields, .manage_stock_field, .stock_status_field, .backorder_field").hide(),"simple"===e||"external"===e?v(".price_fields",".inline-edit-row").show().removeAttr("style"):v(".price_fields",".inline-edit-row").hide(),"yes"===k?v(".dimension_fields",".inline-edit-row").hide():v(".dimension_fields",".inline-edit-row").show().removeAttr("style"),v('input[name="comment_status"]').parent().find(".checkbox-title").text(woocommerce_quick_edit.strings.allow_reviews)}),v("#the-list").on("change",'.inline-edit-row input[name="_manage_stock"]',function(){v(this).is(":checked")?(v(".stock_qty_field, .backorder_field",".inline-edit-row").show().removeAttr("style"),v(".stock_status_field").hide()):(v(".stock_qty_field, .backorder_field",".inline-edit-row").hide(),v(".stock_status_field").show().removeAttr("style"))}),v("#wpbody").on("click","#doaction, #doaction2",function(){v("input.text",".inline-edit-row").val(""),v("#woocommerce-fields").find("select").prop("selectedIndex",0),v("#woocommerce-fields-bulk").find(".inline-edit-group .change-input").hide()}),v("#wpbody").on("change","#woocommerce-fields-bulk .inline-edit-group .change_to",function(){0' + contents + '' ).css( { + top: y - 16, + left: x + 20 + }).appendTo( 'body' ).fadeIn( 200 ); + } + + var prev_data_index = null; + var prev_series_index = null; + + $( '.chart-placeholder' ).bind( 'plothover', function ( event, pos, item ) { + if ( item ) { + if ( prev_data_index !== item.dataIndex || prev_series_index !== item.seriesIndex ) { + prev_data_index = item.dataIndex; + prev_series_index = item.seriesIndex; + + $( '.chart-tooltip' ).remove(); + + if ( item.series.points.show || item.series.enable_tooltip ) { + + var y = item.series.data[item.dataIndex][1], + tooltip_content = ''; + + if ( item.series.prepend_label ) { + tooltip_content = tooltip_content + item.series.label + ': '; + } + + if ( item.series.prepend_tooltip ) { + tooltip_content = tooltip_content + item.series.prepend_tooltip; + } + + tooltip_content = tooltip_content + y; + + if ( item.series.append_tooltip ) { + tooltip_content = tooltip_content + item.series.append_tooltip; + } + + if ( item.series.pie.show ) { + showTooltip( pos.pageX, pos.pageY, tooltip_content ); + } else { + showTooltip( item.pageX, item.pageY, tooltip_content ); + } + } + } + } else { + $( '.chart-tooltip' ).remove(); + prev_data_index = null; + } + }); + + $( '.wc_sparkline.bars' ).each( function() { + var chart_data = $( this ).data( 'sparkline' ); + + var options = { + grid: { + show: false + } + }; + + // main series + var series = [{ + data: chart_data, + color: $( this ).data( 'color' ), + bars: { + fillColor: $( this ).data( 'color' ), + fill: true, + show: true, + lineWidth: 1, + barWidth: $( this ).data( 'barwidth' ), + align: 'center' + }, + shadowSize: 0 + }]; + + // draw the sparkline + $.plot( $( this ), series, options ); + }); + + $( '.wc_sparkline.lines' ).each( function() { + var chart_data = $( this ).data( 'sparkline' ); + + var options = { + grid: { + show: false + } + }; + + // main series + var series = [{ + data: chart_data, + color: $( this ).data( 'color' ), + lines: { + fill: false, + show: true, + lineWidth: 1, + align: 'center' + }, + shadowSize: 0 + }]; + + // draw the sparkline + $.plot( $( this ), series, options ); + }); + + var dates = $( '.range_datepicker' ).datepicker({ + changeMonth: true, + changeYear: true, + defaultDate: '', + dateFormat: 'yy-mm-dd', + numberOfMonths: 1, + minDate: '-20Y', + maxDate: '+1D', + showButtonPanel: true, + showOn: 'focus', + buttonImageOnly: true, + onSelect: function() { + var option = $( this ).is( '.from' ) ? 'minDate' : 'maxDate', + date = $( this ).datepicker( 'getDate' ); + + dates.not( this ).datepicker( 'option', option, date ); + } + }); + + var a = document.createElement( 'a' ); + + if ( typeof a.download === 'undefined' ) { + $( '.export_csv' ).hide(); + } + + // Export + $( '.export_csv' ).click( function() { + var exclude_series = $( this ).data( 'exclude_series' ) || ''; + exclude_series = exclude_series.toString(); + exclude_series = exclude_series.split( ',' ); + var xaxes_label = $( this ).data( 'xaxes' ); + var groupby = $( this ) .data( 'groupby' ); + var index_type = $( this ).data( 'index_type' ); + var export_format = $( this ).data( 'export' ); + var csv_data = ''; + var s, series_data, d; + + if ( 'table' === export_format ) { + + $( this ).offsetParent().find( 'thead tr,tbody tr' ).each( function() { + $( this ).find( 'th, td' ).each( function() { + var value = $( this ).text(); + value = value.replace( '[?]', '' ).replace( '#', '' ); + csv_data += '"' + value + '"' + ','; + }); + csv_data = csv_data.substring( 0, csv_data.length - 1 ); + csv_data += '\n'; + }); + + $( this ).offsetParent().find( 'tfoot tr' ).each( function() { + $( this ).find( 'th, td' ).each( function() { + var value = $( this ).text(); + value = value.replace( '[?]', '' ).replace( '#', '' ); + csv_data += '"' + value + '"' + ','; + if ( $( this ).attr( 'colspan' ) > 0 ) { + for ( i = 1; i < $(this).attr('colspan'); i++ ) { + csv_data += '"",'; + } + } + }); + csv_data = csv_data.substring( 0, csv_data.length - 1 ); + csv_data += '\n'; + }); + + } else { + + if ( ! window.main_chart ) { + return false; + } + + var the_series = window.main_chart.getData(); + var series = []; + csv_data += '"' + xaxes_label + '",'; + + $.each( the_series, function( index, value ) { + if ( ! exclude_series || $.inArray( index.toString(), exclude_series ) === -1 ) { + series.push( value ); + } + }); + + // CSV Headers + for ( s = 0; s < series.length; ++s ) { + csv_data += '"' + series[s].label + '",'; + } + + csv_data = csv_data.substring( 0, csv_data.length - 1 ); + csv_data += '\n'; + + // Get x axis values + var xaxis = {}; + + for ( s = 0; s < series.length; ++s ) { + series_data = series[s].data; + for ( d = 0; d < series_data.length; ++d ) { + xaxis[series_data[d][0]] = []; + // Zero values to start + for ( var i = 0; i < series.length; ++i ) { + xaxis[series_data[d][0]].push(0); + } + } + } + + // Add chart data + for ( s = 0; s < series.length; ++s ) { + series_data = series[s].data; + for ( d = 0; d < series_data.length; ++d ) { + xaxis[series_data[d][0]][s] = series_data[d][1]; + } + } + + // Loop data and output to csv string + $.each( xaxis, function( index, value ) { + var date = new Date( parseInt( index, 10 ) ); + + if ( 'none' === index_type ) { + csv_data += '"' + index + '",'; + } else { + if ( groupby === 'day' ) { + csv_data += '"' + + date.getUTCFullYear() + + '-' + + parseInt( date.getUTCMonth() + 1, 10 ) + + '-' + + date.getUTCDate() + + '",'; + } else { + csv_data += '"' + date.getUTCFullYear() + '-' + parseInt( date.getUTCMonth() + 1, 10 ) + '",'; + } + } + + for ( var d = 0; d < value.length; ++d ) { + var val = value[d]; + + if ( Math.round( val ) !== val ) { + val = parseFloat( val ); + val = val.toFixed( 2 ); + } + + csv_data += '"' + val + '",'; + } + csv_data = csv_data.substring( 0, csv_data.length - 1 ); + csv_data += '\n'; + } ); + } + + csv_data = 'data:text/csv;charset=utf-8,\uFEFF' + encodeURIComponent( csv_data ); + // Set data as href and return + $( this ).attr( 'href', csv_data ); + return true; + }); +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/reports.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/reports.min.js new file mode 100644 index 0000000..53e5c05 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/reports.min.js @@ -0,0 +1 @@ +jQuery(function(p){function r(t,e,a){p('
    '+a+"
    ").css({top:e-16,left:t+20}).appendTo("body").fadeIn(200)}var o=null,s=null;p(".chart-placeholder").bind("plothover",function(t,e,a){var n,i;a?o===a.dataIndex&&s===a.seriesIndex||(o=a.dataIndex,s=a.seriesIndex,p(".chart-tooltip").remove(),(a.series.points.show||a.series.enable_tooltip)&&(n=a.series.data[a.dataIndex][1],i="",a.series.prepend_label&&(i=i+a.series.label+": "),a.series.prepend_tooltip&&(i+=a.series.prepend_tooltip),i+=n,a.series.append_tooltip&&(i+=a.series.append_tooltip),a.series.pie.show?r(e.pageX,e.pageY,i):r(a.pageX,a.pageY,i))):(p(".chart-tooltip").remove(),o=null)}),p(".wc_sparkline.bars").each(function(){var t=[{data:p(this).data("sparkline"),color:p(this).data("color"),bars:{fillColor:p(this).data("color"),fill:!0,show:!0,lineWidth:1,barWidth:p(this).data("barwidth"),align:"center"},shadowSize:0}];p.plot(p(this),t,{grid:{show:!1}})}),p(".wc_sparkline.lines").each(function(){var t=[{data:p(this).data("sparkline"),color:p(this).data("color"),lines:{fill:!1,show:!0,lineWidth:1,align:"center"},shadowSize:0}];p.plot(p(this),t,{grid:{show:!1}})});var a=p(".range_datepicker").datepicker({changeMonth:!0,changeYear:!0,defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,minDate:"-20Y",maxDate:"+1D",showButtonPanel:!0,showOn:"focus",buttonImageOnly:!0,onSelect:function(){var t=p(this).is(".from")?"minDate":"maxDate",e=p(this).datepicker("getDate");a.not(this).datepicker("option",t,e)}});"undefined"==typeof document.createElement("a").download&&p(".export_csv").hide(),p(".export_csv").click(function(){var a=p(this).data("exclude_series")||"";a=(a=a.toString()).split(",");var t,e,n=p(this).data("xaxes"),r=p(this).data("groupby"),o=p(this).data("index_type"),i=p(this).data("export"),s="";if("table"===i)p(this).offsetParent().find("thead tr,tbody tr").each(function(){p(this).find("th, td").each(function(){var t=(t=p(this).text()).replace("[?]","").replace("#","");s+='"'+t+'",'}),s=s.substring(0,s.length-1),s+="\n"}),p(this).offsetParent().find("tfoot tr").each(function(){p(this).find("th, td").each(function(){var t=(t=p(this).text()).replace("[?]","").replace("#","");if(s+='"'+t+'",',0 0 ? '&' : '?' ) + 'action=woocommerce_tax_rates_save_changes', + data: { + current_class: data.current_class, + wc_tax_nonce: data.wc_tax_nonce, + changes: self.changes + }, + success: function( response, textStatus ) { + if ( 'success' === textStatus && response.success ) { + WCTaxTableModelInstance.set( 'rates', response.data.rates ); + WCTaxTableModelInstance.trigger( 'change:rates' ); + + WCTaxTableModelInstance.changes = {}; + WCTaxTableModelInstance.trigger( 'saved:rates' ); + + // Reload view. + WCTaxTableInstance.render(); + } + + self.unblock(); + } + }); + } + } ), + WCTaxTableViewConstructor = Backbone.View.extend({ + rowTemplate: rowTemplate, + per_page: data.limit, + page: data.page, + initialize: function() { + var qty_pages = Math.ceil( _.toArray( this.model.get( 'rates' ) ).length / this.per_page ); + + this.qty_pages = 0 === qty_pages ? 1 : qty_pages; + this.page = this.sanitizePage( data.page ); + + this.listenTo( this.model, 'change:rates', this.setUnloadConfirmation ); + this.listenTo( this.model, 'saved:rates', this.clearUnloadConfirmation ); + $tbody.on( 'change autocompletechange', ':input', { view: this }, this.updateModelOnChange ); + $search_field.on( 'keyup search', { view: this }, this.onSearchField ); + $pagination.on( 'click', 'a', { view: this }, this.onPageChange ); + $pagination.on( 'change', 'input', { view: this }, this.onPageChange ); + $( window ).on( 'beforeunload', { view: this }, this.unloadConfirmation ); + $submit.on( 'click', { view: this }, this.onSubmit ); + $save_button.prop( 'disabled', true ); + + // Can bind these directly to the buttons, as they won't get overwritten. + $table.find( '.insert' ).on( 'click', { view: this }, this.onAddNewRow ); + $table.find( '.remove_tax_rates' ).on( 'click', { view: this }, this.onDeleteRow ); + $table.find( '.export' ).on( 'click', { view: this }, this.onExport ); + }, + render: function() { + var rates = this.model.getFilteredRates(), + qty_rates = _.size( rates ), + qty_pages = Math.ceil( qty_rates / this.per_page ), + first_index = 0 === qty_rates ? 0 : this.per_page * ( this.page - 1 ), + last_index = this.per_page * this.page, + paged_rates = _.toArray( rates ).slice( first_index, last_index ), + view = this; + + // Blank out the contents. + this.$el.empty(); + + if ( paged_rates.length ) { + // Populate $tbody with the current page of results. + $.each( paged_rates, function( id, rowData ) { + view.$el.append( view.rowTemplate( rowData ) ); + } ); + } else { + view.$el.append( rowTemplateEmpty() ); + } + + // Initialize autocomplete for countries. + this.$el.find( 'td.country input' ).autocomplete({ + source: data.countries, + minLength: 2 + }); + + // Initialize autocomplete for states. + this.$el.find( 'td.state input' ).autocomplete({ + source: data.states, + minLength: 3 + }); + + // Postcode and city don't have `name` values by default. + // They're only created if the contents changes, to save on database queries (I think) + this.$el.find( 'td.postcode input, td.city input' ).change( function() { + $( this ).attr( 'name', $( this ).data( 'name' ) ); + }); + + if ( qty_pages > 1 ) { + // We've now displayed our initial page, time to render the pagination box. + $pagination.html( paginationTemplate( { + qty_rates: qty_rates, + current_page: this.page, + qty_pages: qty_pages + } ) ); + } else { + $pagination.empty(); + view.page = 1; + } + }, + updateUrl: function() { + if ( ! window.history.replaceState ) { + return; + } + + var url = data.base_url, + search = $search_field.val(); + + if ( 1 < this.page ) { + url += '&p=' + encodeURIComponent( this.page ); + } + + if ( search.length ) { + url += '&s=' + encodeURIComponent( search ); + } + + window.history.replaceState( {}, '', url ); + }, + onSubmit: function( event ) { + event.data.view.model.save(); + event.preventDefault(); + }, + onAddNewRow: function( event ) { + var view = event.data.view, + model = view.model, + rates = _.indexBy( model.get( 'rates' ), 'tax_rate_id' ), + changes = {}, + size = _.size( rates ), + newRow = _.extend( {}, data.default_rate, { + tax_rate_id: 'new-' + size + '-' + Date.now(), + newRow: true + } ), + $current, current_id, current_order, rates_to_reorder, reordered_rates; + + $current = $tbody.children( '.current' ); + + if ( $current.length ) { + current_id = $current.last().data( 'id' ); + current_order = parseInt( rates[ current_id ].tax_rate_order, 10 ); + newRow.tax_rate_order = 1 + current_order; + + rates_to_reorder = _.filter( rates, function( rate ) { + if ( parseInt( rate.tax_rate_order, 10 ) > current_order ) { + return true; + } + return false; + } ); + + reordered_rates = _.map( rates_to_reorder, function( rate ) { + rate.tax_rate_order++; + changes[ rate.tax_rate_id ] = _.extend( + changes[ rate.tax_rate_id ] || {}, { tax_rate_order : rate.tax_rate_order } + ); + return rate; + } ); + } else { + newRow.tax_rate_order = 1 + _.max( + _.pluck( rates, 'tax_rate_order' ), + function ( val ) { + // Cast them all to integers, because strings compare funky. Sighhh. + return parseInt( val, 10 ); + } + ); + // Move the last page + view.page = view.qty_pages; + } + + rates[ newRow.tax_rate_id ] = newRow; + changes[ newRow.tax_rate_id ] = newRow; + + model.set( 'rates', rates ); + model.logChanges( changes ); + + view.render(); + }, + onDeleteRow: function( event ) { + var view = event.data.view, + model = view.model, + rates = _.indexBy( model.get( 'rates' ), 'tax_rate_id' ), + changes = {}, + $current, current_id; + + event.preventDefault(); + + if ( $current = $tbody.children( '.current' ) ) { + $current.each(function(){ + current_id = $( this ).data('id'); + + delete rates[ current_id ]; + + changes[ current_id ] = _.extend( changes[ current_id ] || {}, { deleted : 'deleted' } ); + }); + + model.set( 'rates', rates ); + model.logChanges( changes ); + + view.render(); + } else { + window.alert( data.strings.no_rows_selected ); + } + }, + onSearchField: function( event ){ + event.data.view.updateUrl(); + event.data.view.render(); + }, + onPageChange: function( event ) { + var $target = $( event.currentTarget ); + + event.preventDefault(); + event.data.view.page = $target.data( 'goto' ) ? $target.data( 'goto' ) : $target.val(); + event.data.view.render(); + event.data.view.updateUrl(); + }, + onExport: function( event ) { + var csv_data = 'data:application/csv;charset=utf-8,' + data.strings.csv_data_cols.join(',') + '\n'; + + $.each( event.data.view.model.getFilteredRates(), function( id, rowData ) { + var row = ''; + + row += rowData.tax_rate_country + ','; + row += rowData.tax_rate_state + ','; + row += ( rowData.postcode ? rowData.postcode.join( '; ' ) : '' ) + ','; + row += ( rowData.city ? rowData.city.join( '; ' ) : '' ) + ','; + row += rowData.tax_rate + ','; + row += rowData.tax_rate_name + ','; + row += rowData.tax_rate_priority + ','; + row += rowData.tax_rate_compound + ','; + row += rowData.tax_rate_shipping + ','; + row += data.current_class; + + csv_data += row + '\n'; + }); + + $( this ).attr( 'href', encodeURI( csv_data ) ); + + return true; + }, + setUnloadConfirmation: function() { + this.needsUnloadConfirm = true; + $save_button.prop( 'disabled', false ); + }, + clearUnloadConfirmation: function() { + this.needsUnloadConfirm = false; + $save_button.prop( 'disabled', true ); + }, + unloadConfirmation: function( event ) { + if ( event.data.view.needsUnloadConfirm ) { + event.returnValue = data.strings.unload_confirmation_msg; + window.event.returnValue = data.strings.unload_confirmation_msg; + return data.strings.unload_confirmation_msg; + } + }, + updateModelOnChange: function( event ) { + var model = event.data.view.model, + $target = $( event.target ), + id = $target.closest( 'tr' ).data( 'id' ), + attribute = $target.data( 'attribute' ), + val = $target.val(); + + if ( 'city' === attribute || 'postcode' === attribute ) { + val = val.split( ';' ); + val = $.map( val, function( thing ) { + return thing.trim(); + }); + } + + if ( 'tax_rate_compound' === attribute || 'tax_rate_shipping' === attribute ) { + if ( $target.is( ':checked' ) ) { + val = 1; + } else { + val = 0; + } + } + + model.setRateAttribute( id, attribute, val ); + }, + sanitizePage: function( page_num ) { + page_num = parseInt( page_num, 10 ); + if ( page_num < 1 ) { + page_num = 1; + } else if ( page_num > this.qty_pages ) { + page_num = this.qty_pages; + } + return page_num; + } + } ), + WCTaxTableModelInstance = new WCTaxTableModelConstructor({ + rates: data.rates + } ), + WCTaxTableInstance = new WCTaxTableViewConstructor({ + model: WCTaxTableModelInstance, + el: '#rates' + } ); + + WCTaxTableInstance.render(); + + }); +})( jQuery, htmlSettingsTaxLocalizeScript, wp, ajaxurl ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/settings-views-html-settings-tax.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/settings-views-html-settings-tax.min.js new file mode 100644 index 0000000..f268ea8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/settings-views-html-settings-tax.min.js @@ -0,0 +1 @@ +!function(h,p,g,f){h(function(){String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")});var t=g.template("wc-tax-table-row"),o=g.template("wc-tax-table-row-empty"),s=g.template("wc-tax-table-pagination"),e=h(".wc_tax_rates"),c=h("#rates"),a=h(':input[name="save"]'),d=h("#rates-pagination"),n=h("#rates-search .wc-tax-rates-search-field"),i=h(".submit .button-primary[type=submit]"),r=Backbone.Model.extend({changes:{},setRateAttribute:function(t,e,a){var n=_.indexBy(this.get("rates"),"tax_rate_id"),i={};n[t][e]!==a&&(i[t]={},i[t][e]=a,n[t][e]=a),this.logChanges(i)},logChanges:function(t){var a=this.changes||{};_.each(t,function(t,e){a[e]=_.extend(a[e]||{tax_rate_id:e},t)}),this.changes=a,this.trigger("change:rates")},getFilteredRates:function(){var t=this.get("rates"),e=n.val().toLowerCase();return e.length&&(t=_.filter(t,function(t){return-1!==_.toArray(t).join(" ").toLowerCase().indexOf(e)})),t=_.sortBy(t,function(t){return parseInt(t.tax_rate_order,10)})},block:function(){h(".wc_tax_rates").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){h(".wc_tax_rates").unblock()},save:function(){var a=this;a.block(),Backbone.ajax({method:"POST",dataType:"json",url:f+(0e}),_.map(o,function(t){return t.tax_rate_order++,r[t.tax_rate_id]=_.extend(r[t.tax_rate_id]||{},{tax_rate_order:t.tax_rate_order}),t})):(t.tax_rate_order=1+_.max(_.pluck(i,"tax_rate_order"),function(t){return parseInt(t,10)}),a.page=a.qty_pages),i[t.tax_rate_id]=t,r[t.tax_rate_id]=t,n.set("rates",i),n.logChanges(r),a.render()},onDeleteRow:function(t){var e,a=t.data.view,n=a.model,i=_.indexBy(n.get("rates"),"tax_rate_id"),r={};t.preventDefault(),(t=c.children(".current"))?(t.each(function(){e=h(this).data("id"),delete i[e],r[e]=_.extend(r[e]||{},{deleted:"deleted"})}),n.set("rates",i),n.logChanges(r),a.render()):window.alert(p.strings.no_rows_selected)},onSearchField:function(t){t.data.view.updateUrl(),t.data.view.render()},onPageChange:function(t){var e=h(t.currentTarget);t.preventDefault(),t.data.view.page=e.data("goto")?e.data("goto"):e.val(),t.data.view.render(),t.data.view.updateUrl()},onExport:function(t){var n="data:application/csv;charset=utf-8,"+p.strings.csv_data_cols.join(",")+"\n";return h.each(t.data.view.model.getFilteredRates(),function(t,e){var a="";a+=e.tax_rate_country+",",a+=e.tax_rate_state+",",a+=(e.postcode?e.postcode.join("; "):"")+",",a+=(e.city?e.city.join("; "):"")+",",a+=e.tax_rate+",",a+=e.tax_rate_name+",",a+=e.tax_rate_priority+",",a+=e.tax_rate_compound+",",a+=e.tax_rate_shipping+",",a+=p.current_class,n+=a+"\n"}),h(this).attr("href",encodeURI(n)),!0},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,a.prop("disabled",!1)},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,a.prop("disabled",!0)},unloadConfirmation:function(t){if(t.data.view.needsUnloadConfirm)return t.returnValue=p.strings.unload_confirmation_msg,window.event.returnValue=p.strings.unload_confirmation_msg,p.strings.unload_confirmation_msg},updateModelOnChange:function(t){var e=t.data.view.model,a=h(t.target),n=a.closest("tr").data("id"),i=a.data("attribute"),t=a.val();"city"!==i&&"postcode"!==i||(t=t.split(";"),t=h.map(t,function(t){return t.trim()})),"tax_rate_compound"!==i&&"tax_rate_shipping"!==i||(t=a.is(":checked")?1:0),e.setRateAttribute(n,i,t)},sanitizePage:function(t){return(t=parseInt(t,10))<1?t=1:t>this.qty_pages&&(t=this.qty_pages),t}}),l=new r({rates:p.rates}),u=new t({model:l,el:"#rates"});u.render()})}(jQuery,htmlSettingsTaxLocalizeScript,wp,ajaxurl); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/settings.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/settings.js new file mode 100644 index 0000000..5ad5e4e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/settings.js @@ -0,0 +1,183 @@ +/* global woocommerce_settings_params, wp */ +( function( $, params, wp ) { + $( function() { + // Sell Countries + $( 'select#woocommerce_allowed_countries' ).change( function() { + if ( 'specific' === $( this ).val() ) { + $( this ).closest('tr').next( 'tr' ).hide(); + $( this ).closest('tr').next().next( 'tr' ).show(); + } else if ( 'all_except' === $( this ).val() ) { + $( this ).closest('tr').next( 'tr' ).show(); + $( this ).closest('tr').next().next( 'tr' ).hide(); + } else { + $( this ).closest('tr').next( 'tr' ).hide(); + $( this ).closest('tr').next().next( 'tr' ).hide(); + } + }).change(); + + // Ship Countries + $( 'select#woocommerce_ship_to_countries' ).change( function() { + if ( 'specific' === $( this ).val() ) { + $( this ).closest('tr').next( 'tr' ).show(); + } else { + $( this ).closest('tr').next( 'tr' ).hide(); + } + }).change(); + + // Stock management + $( 'input#woocommerce_manage_stock' ).change( function() { + if ( $( this ).is(':checked') ) { + $( this ).closest('tbody').find( '.manage_stock_field' ).closest( 'tr' ).show(); + } else { + $( this ).closest('tbody').find( '.manage_stock_field' ).closest( 'tr' ).hide(); + } + }).change(); + + // Color picker + $( '.colorpick' ) + + .iris({ + change: function( event, ui ) { + $( this ).parent().find( '.colorpickpreview' ).css({ backgroundColor: ui.color.toString() }); + }, + hide: true, + border: true + }) + + .on( 'click focus', function( event ) { + event.stopPropagation(); + $( '.iris-picker' ).hide(); + $( this ).closest( 'td' ).find( '.iris-picker' ).show(); + $( this ).data( 'original-value', $( this ).val() ); + }) + + .on( 'change', function() { + if ( $( this ).is( '.iris-error' ) ) { + var original_value = $( this ).data( 'original-value' ); + + if ( original_value.match( /^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/ ) ) { + $( this ).val( $( this ).data( 'original-value' ) ).change(); + } else { + $( this ).val( '' ).change(); + } + } + }); + + $( 'body' ).on( 'click', function() { + $( '.iris-picker' ).hide(); + }); + + // Edit prompt + $( function() { + var changed = false; + + $( 'input, textarea, select, checkbox' ).change( function() { + if ( ! changed ) { + window.onbeforeunload = function() { + return params.i18n_nav_warning; + }; + changed = true; + } + }); + + $( '.submit :input' ).click( function() { + window.onbeforeunload = ''; + }); + }); + + // Sorting + $( 'table.wc_gateways tbody, table.wc_shipping tbody' ).sortable({ + items: 'tr', + cursor: 'move', + axis: 'y', + handle: 'td.sort', + scrollSensitivity: 40, + helper: function( event, ui ) { + ui.children().each( function() { + $( this ).width( $( this ).width() ); + }); + ui.css( 'left', '0' ); + return ui; + }, + start: function( event, ui ) { + ui.item.css( 'background-color', '#f6f6f6' ); + }, + stop: function( event, ui ) { + ui.item.removeAttr( 'style' ); + ui.item.trigger( 'updateMoveButtons' ); + } + }); + + // Select all/none + $( '.woocommerce' ).on( 'click', '.select_all', function() { + $( this ).closest( 'td' ).find( 'select option' ).attr( 'selected', 'selected' ); + $( this ).closest( 'td' ).find( 'select' ).trigger( 'change' ); + return false; + }); + + $( '.woocommerce' ).on( 'click', '.select_none', function() { + $( this ).closest( 'td' ).find( 'select option' ).removeAttr( 'selected' ); + $( this ).closest( 'td' ).find( 'select' ).trigger( 'change' ); + return false; + }); + + // Re-order buttons. + $( '.wc-item-reorder-nav').find( '.wc-move-up, .wc-move-down' ).on( 'click', function() { + var moveBtn = $( this ), + $row = moveBtn.closest( 'tr' ); + + moveBtn.focus(); + + var isMoveUp = moveBtn.is( '.wc-move-up' ), + isMoveDown = moveBtn.is( '.wc-move-down' ); + + if ( isMoveUp ) { + var $previewRow = $row.prev( 'tr' ); + + if ( $previewRow && $previewRow.length ) { + $previewRow.before( $row ); + wp.a11y.speak( params.i18n_moved_up ); + } + } else if ( isMoveDown ) { + var $nextRow = $row.next( 'tr' ); + + if ( $nextRow && $nextRow.length ) { + $nextRow.after( $row ); + wp.a11y.speak( params.i18n_moved_down ); + } + } + + moveBtn.focus(); // Re-focus after the container was moved. + moveBtn.closest( 'table' ).trigger( 'updateMoveButtons' ); + } ); + + $( '.wc-item-reorder-nav').closest( 'table' ).on( 'updateMoveButtons', function() { + var table = $( this ), + lastRow = $( this ).find( 'tbody tr:last' ), + firstRow = $( this ).find( 'tbody tr:first' ); + + table.find( '.wc-item-reorder-nav .wc-move-disabled' ).removeClass( 'wc-move-disabled' ) + .attr( { 'tabindex': '0', 'aria-hidden': 'false' } ); + firstRow.find( '.wc-item-reorder-nav .wc-move-up' ).addClass( 'wc-move-disabled' ) + .attr( { 'tabindex': '-1', 'aria-hidden': 'true' } ); + lastRow.find( '.wc-item-reorder-nav .wc-move-down' ).addClass( 'wc-move-disabled' ) + .attr( { 'tabindex': '-1', 'aria-hidden': 'true' } ); + } ); + + $( '.wc-item-reorder-nav').closest( 'table' ).trigger( 'updateMoveButtons' ); + + + $( '.submit button' ).on( 'click', function() { + if ( + $( 'select#woocommerce_allowed_countries' ).val() === 'specific' && + ! $( '[name="woocommerce_specific_allowed_countries[]"]' ).val() + ) { + if ( window.confirm( woocommerce_settings_params.i18n_no_specific_countries_selected ) ) { + return true; + } + return false; + } + } ); + + }); +})( jQuery, woocommerce_settings_params, wp ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/settings.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/settings.min.js new file mode 100644 index 0000000..9dc857b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/settings.min.js @@ -0,0 +1 @@ +!function(c,s,n){c(function(){c("select#woocommerce_allowed_countries").change(function(){"specific"===c(this).val()?(c(this).closest("tr").next("tr").hide(),c(this).closest("tr").next().next("tr").show()):("all_except"===c(this).val()?c(this).closest("tr").next("tr").show():c(this).closest("tr").next("tr").hide(),c(this).closest("tr").next().next("tr").hide())}).change(),c("select#woocommerce_ship_to_countries").change(function(){"specific"===c(this).val()?c(this).closest("tr").next("tr").show():c(this).closest("tr").next("tr").hide()}).change(),c("input#woocommerce_manage_stock").change(function(){c(this).is(":checked")?c(this).closest("tbody").find(".manage_stock_field").closest("tr").show():c(this).closest("tbody").find(".manage_stock_field").closest("tr").hide()}).change(),c(".colorpick").iris({change:function(e,t){c(this).parent().find(".colorpickpreview").css({backgroundColor:t.color.toString()})},hide:!0,border:!0}).on("click focus",function(e){e.stopPropagation(),c(".iris-picker").hide(),c(this).closest("td").find(".iris-picker").show(),c(this).data("original-value",c(this).val())}).on("change",function(){c(this).is(".iris-error")&&(c(this).data("original-value").match(/^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/)?c(this).val(c(this).data("original-value")):c(this).val("")).change()}),c("body").on("click",function(){c(".iris-picker").hide()}),c(function(){var e=!1;c("input, textarea, select, checkbox").change(function(){e||(window.onbeforeunload=function(){return s.i18n_nav_warning},e=!0)}),c(".submit :input").click(function(){window.onbeforeunload=""})}),c("table.wc_gateways tbody, table.wc_shipping tbody").sortable({items:"tr",cursor:"move",axis:"y",handle:"td.sort",scrollSensitivity:40,helper:function(e,t){return t.children().each(function(){c(this).width(c(this).width())}),t.css("left","0"),t},start:function(e,t){t.item.css("background-color","#f6f6f6")},stop:function(e,t){t.item.removeAttr("style"),t.item.trigger("updateMoveButtons")}}),c(".woocommerce").on("click",".select_all",function(){return c(this).closest("td").find("select option").attr("selected","selected"),c(this).closest("td").find("select").trigger("change"),!1}),c(".woocommerce").on("click",".select_none",function(){return c(this).closest("td").find("select option").removeAttr("selected"),c(this).closest("td").find("select").trigger("change"),!1}),c(".wc-item-reorder-nav").find(".wc-move-up, .wc-move-down").on("click",function(){var e=c(this),t=e.closest("tr");e.focus();var i=e.is(".wc-move-up"),o=e.is(".wc-move-down");i?(i=t.prev("tr"))&&i.length&&(i.before(t),n.a11y.speak(s.i18n_moved_up)):!o||(o=t.next("tr"))&&o.length&&(o.after(t),n.a11y.speak(s.i18n_moved_down)),e.focus(),e.closest("table").trigger("updateMoveButtons")}),c(".wc-item-reorder-nav").closest("table").on("updateMoveButtons",function(){var e=c(this),t=c(this).find("tbody tr:last"),i=c(this).find("tbody tr:first");e.find(".wc-item-reorder-nav .wc-move-disabled").removeClass("wc-move-disabled").attr({tabindex:"0","aria-hidden":"false"}),i.find(".wc-item-reorder-nav .wc-move-up").addClass("wc-move-disabled").attr({tabindex:"-1","aria-hidden":"true"}),t.find(".wc-item-reorder-nav .wc-move-down").addClass("wc-move-disabled").attr({tabindex:"-1","aria-hidden":"true"})}),c(".wc-item-reorder-nav").closest("table").trigger("updateMoveButtons"),c(".submit button").on("click",function(){if("specific"===c("select#woocommerce_allowed_countries").val()&&!c('[name="woocommerce_specific_allowed_countries[]"]').val())return!!window.confirm(woocommerce_settings_params.i18n_no_specific_countries_selected)})})}(jQuery,woocommerce_settings_params,wp); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/system-status.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/system-status.js new file mode 100644 index 0000000..9f06641 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/system-status.js @@ -0,0 +1,126 @@ +/* global jQuery, woocommerce_admin_system_status, wcSetClipboard, wcClearClipboard */ +jQuery( function ( $ ) { + + /** + * Users country and state fields + */ + var wcSystemStatus = { + init: function() { + $( document.body ) + .on( 'click', 'a.help_tip, a.woocommerce-help-tip', this.preventTipTipClick ) + .on( 'click', 'a.debug-report', this.generateReport ) + .on( 'click', '#copy-for-support', this.copyReport ) + .on( 'aftercopy', '#copy-for-support', this.copySuccess ) + .on( 'aftercopyfailure', '#copy-for-support', this.copyFail ); + }, + + /** + * Prevent anchor behavior when click on TipTip. + * + * @return {Bool} + */ + preventTipTipClick: function() { + return false; + }, + + /** + * Generate system status report. + * + * @return {Bool} + */ + generateReport: function() { + var report = ''; + + $( '.wc_status_table thead, .wc_status_table tbody' ).each( function() { + if ( $( this ).is( 'thead' ) ) { + var label = $( this ).find( 'th:eq(0)' ).data( 'export-label' ) || $( this ).text(); + report = report + '\n### ' + $.trim( label ) + ' ###\n\n'; + } else { + $( 'tr', $( this ) ).each( function() { + var label = $( this ).find( 'td:eq(0)' ).data( 'export-label' ) || $( this ).find( 'td:eq(0)' ).text(); + var the_name = $.trim( label ).replace( /(<([^>]+)>)/ig, '' ); // Remove HTML. + + // Find value + var $value_html = $( this ).find( 'td:eq(2)' ).clone(); + $value_html.find( '.private' ).remove(); + $value_html.find( '.dashicons-yes' ).replaceWith( '✔' ); + $value_html.find( '.dashicons-no-alt, .dashicons-warning' ).replaceWith( '❌' ); + + // Format value + var the_value = $.trim( $value_html.text() ); + var value_array = the_value.split( ', ' ); + + if ( value_array.length > 1 ) { + // If value have a list of plugins ','. + // Split to add new line. + var temp_line =''; + $.each( value_array, function( key, line ) { + temp_line = temp_line + line + '\n'; + }); + + the_value = temp_line; + } + + report = report + '' + the_name + ': ' + the_value + '\n'; + }); + } + }); + + try { + $( '#debug-report' ).slideDown(); + $( '#debug-report' ).find( 'textarea' ).val( '`' + report + '`' ).focus().select(); + $( this ).fadeOut(); + return false; + } catch ( e ) { + /* jshint devel: true */ + console.log( e ); + } + + return false; + }, + + /** + * Copy for report. + * + * @param {Object} evt Copy event. + */ + copyReport: function( evt ) { + wcClearClipboard(); + wcSetClipboard( $( '#debug-report' ).find( 'textarea' ).val(), $( this ) ); + evt.preventDefault(); + }, + + /** + * Display a "Copied!" tip when success copying + */ + copySuccess: function() { + $( '#copy-for-support' ).tipTip({ + 'attribute': 'data-tip', + 'activation': 'focus', + 'fadeIn': 50, + 'fadeOut': 50, + 'delay': 0 + }).focus(); + }, + + /** + * Displays the copy error message when failure copying. + */ + copyFail: function() { + $( '.copy-error' ).removeClass( 'hidden' ); + $( '#debug-report' ).find( 'textarea' ).focus().select(); + } + }; + + wcSystemStatus.init(); + + $( '.wc_status_table' ).on( 'click', '.run-tool .button', function( evt ) { + evt.stopImmediatePropagation(); + return window.confirm( woocommerce_admin_system_status.run_tool_confirmation ); + }); + + $( '#log-viewer-select' ).on( 'click', 'h2 a.page-title-action', function( evt ) { + evt.stopImmediatePropagation(); + return window.confirm( woocommerce_admin_system_status.delete_log_confirmation ); + }); +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/system-status.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/system-status.min.js new file mode 100644 index 0000000..43e4835 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/system-status.min.js @@ -0,0 +1 @@ +jQuery(function(r){({init:function(){r(document.body).on("click","a.help_tip, a.woocommerce-help-tip",this.preventTipTipClick).on("click","a.debug-report",this.generateReport).on("click","#copy-for-support",this.copyReport).on("aftercopy","#copy-for-support",this.copySuccess).on("aftercopyfailure","#copy-for-support",this.copyFail)},preventTipTipClick:function(){return!1},generateReport:function(){var n="";r(".wc_status_table thead, .wc_status_table tbody").each(function(){var t;r(this).is("thead")?(t=r(this).find("th:eq(0)").data("export-label")||r(this).text(),n=n+"\n### "+r.trim(t)+" ###\n\n"):r("tr",r(this)).each(function(){var t=r(this).find("td:eq(0)").data("export-label")||r(this).find("td:eq(0)").text(),e=r.trim(t).replace(/(<([^>]+)>)/gi,""),o=r(this).find("td:eq(2)").clone();o.find(".private").remove(),o.find(".dashicons-yes").replaceWith("✔"),o.find(".dashicons-no-alt, .dashicons-warning").replaceWith("❌");var i,t=r.trim(o.text()),o=t.split(", ");1 tr'); + var rows_with_handle = $( table_selector ).find('tbody > tr > td.column-handle').parent(); + if ( all_table_rows.length !== rows_with_handle.length ) { + all_table_rows.each(function(index, elem){ + if ( ! rows_with_handle.is( elem ) ) { + $( elem ).append( column_handle ); + } + }); + } + $( table_selector ).find( '.column-handle' ).show(); + }; + + $( document ).ajaxComplete( function( event, request, options ) { + if ( + request && + 4 === request.readyState && + 200 === request.status && + options.data && + ( 0 <= options.data.indexOf( '_inline_edit' ) || 0 <= options.data.indexOf( 'add-tag' ) ) + ) { + $.wc_add_missing_sort_handles(); + $( document.body ).trigger( 'init_tooltips' ); + } + } ); + + $( table_selector ).sortable({ + items: item_selector, + cursor: 'move', + handle: '.column-handle', + axis: 'y', + forcePlaceholderSize: true, + helper: 'clone', + opacity: 0.65, + placeholder: 'product-cat-placeholder', + scrollSensitivity: 40, + start: function( event, ui ) { + if ( ! ui.item.hasClass( 'alternate' ) ) { + ui.item.css( 'background-color', '#ffffff' ); + } + ui.item.children( 'td, th' ).css( 'border-bottom-width', '0' ); + ui.item.css( 'outline', '1px solid #aaa' ); + }, + stop: function( event, ui ) { + ui.item.removeAttr( 'style' ); + ui.item.children( 'td, th' ).css( 'border-bottom-width', '1px' ); + }, + update: function( event, ui ) { + var termid = ui.item.find( term_id_selector ).val(); // this post id + var termparent = ui.item.find( '.parent' ).html(); // post parent + + var prevtermid = ui.item.prev().find( term_id_selector ).val(); + var nexttermid = ui.item.next().find( term_id_selector ).val(); + + // Can only sort in same tree + var prevtermparent, nexttermparent; + if ( prevtermid !== undefined ) { + prevtermparent = ui.item.prev().find( '.parent' ).html(); + if ( prevtermparent !== termparent) { + prevtermid = undefined; + } + } + + if ( nexttermid !== undefined ) { + nexttermparent = ui.item.next().find( '.parent' ).html(); + if ( nexttermparent !== termparent) { + nexttermid = undefined; + } + } + + // If previous and next not at same tree level, or next not at same tree level and + // the previous is the parent of the next, or just moved item beneath its own children. + if ( + ( prevtermid === undefined && nexttermid === undefined ) || + ( nexttermid === undefined && nexttermparent === prevtermid ) || + ( nexttermid !== undefined && prevtermparent === termid ) + ) { + $( table_selector ).sortable( 'cancel' ); + return; + } + + // Show Spinner + ui.item.find( '.check-column input' ).hide(); + ui.item + .find( '.check-column' ) + .append( 'processing' ); + + // Go do the sorting stuff via ajax. + $.post( + ajaxurl, + { + action: 'woocommerce_term_ordering', + id: termid, + nextid: nexttermid, + thetaxonomy: woocommerce_term_ordering_params.taxonomy + }, + function(response) { + if ( response === 'children' ) { + window.location.reload(); + } else { + ui.item.find( '.check-column input' ).show(); + ui.item.find( '.check-column' ).find( 'img' ).remove(); + } + } + ); + + // Fix cell colors + $( 'table.widefat tbody tr' ).each( function() { + var i = jQuery( 'table.widefat tbody tr' ).index( this ); + if ( i%2 === 0 ) { + jQuery( this ).addClass( 'alternate' ); + } else { + jQuery( this ).removeClass( 'alternate' ); + } + }); + } + }); + +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/term-ordering.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/term-ordering.min.js new file mode 100644 index 0000000..dc3f6bd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/term-ordering.min.js @@ -0,0 +1 @@ +jQuery(function(r){var c="table.wp-list-table",m='.column-handle input[name="term_id"]',i='';0===r(c).find(".column-handle").length&&(r(c).find("tr:not(.inline-edit-row)").append(i),m=".check-column input"),r(c).find(".column-handle").show(),r.wc_add_missing_sort_handles=function(){var e=r(c).find("tbody > tr"),n=r(c).find("tbody > tr > td.column-handle").parent();e.length!==n.length&&e.each(function(e,t){n.is(t)||r(t).append(i)}),r(c).find(".column-handle").show()},r(document).ajaxComplete(function(e,t,n){t&&4===t.readyState&&200===t.status&&n.data&&(0<=n.data.indexOf("_inline_edit")||0<=n.data.indexOf("add-tag"))&&(r.wc_add_missing_sort_handles(),r(document.body).trigger("init_tooltips"))}),r(c).sortable({items:"tbody tr:not(.inline-edit-row)",cursor:"move",handle:".column-handle",axis:"y",forcePlaceholderSize:!0,helper:"clone",opacity:.65,placeholder:"product-cat-placeholder",scrollSensitivity:40,start:function(e,t){t.item.hasClass("alternate")||t.item.css("background-color","#ffffff"),t.item.children("td, th").css("border-bottom-width","0"),t.item.css("outline","1px solid #aaa")},stop:function(e,t){t.item.removeAttr("style"),t.item.children("td, th").css("border-bottom-width","1px")},update:function(e,t){var n,i,d=t.item.find(m).val(),a=t.item.find(".parent").html(),o=t.item.prev().find(m).val(),l=t.item.next().find(m).val();o!==undefined&&(n=t.item.prev().find(".parent").html())!==a&&(o=undefined),l!==undefined&&(i=t.item.next().find(".parent").html())!==a&&(l=undefined),o===undefined&&l===undefined||l===undefined&&i===o||l!==undefined&&n===d?r(c).sortable("cancel"):(t.item.find(".check-column input").hide(),t.item.find(".check-column").append('processing'),r.post(ajaxurl,{action:"woocommerce_term_ordering",id:d,nextid:l,thetaxonomy:woocommerce_term_ordering_params.taxonomy},function(e){"children"===e?window.location.reload():(t.item.find(".check-column input").show(),t.item.find(".check-column").find("img").remove())}),r("table.widefat tbody tr").each(function(){jQuery("table.widefat tbody tr").index(this)%2==0?jQuery(this).addClass("alternate"):jQuery(this).removeClass("alternate")}))}})}); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/users.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/users.js new file mode 100644 index 0000000..5659bd8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/users.js @@ -0,0 +1,120 @@ +/*global wc_users_params */ +jQuery( function ( $ ) { + + /** + * Users country and state fields + */ + var wc_users_fields = { + states: null, + init: function() { + if ( typeof wc_users_params.countries !== 'undefined' ) { + /* State/Country select boxes */ + this.states = JSON.parse( wc_users_params.countries.replace( /"/g, '"' ) ); + } + + $( '.js_field-country' ).selectWoo().change( this.change_country ); + $( '.js_field-country' ).trigger( 'change', [ true ] ); + $( document.body ).on( 'change', 'select.js_field-state', this.change_state ); + + $( document.body ).on( 'click', 'button.js_copy-billing', this.copy_billing ); + }, + + change_country: function( e, stickValue ) { + // Check for stickValue before using it + if ( typeof stickValue === 'undefined' ) { + stickValue = false; + } + + // Prevent if we don't have the metabox data + if ( wc_users_fields.states === null ) { + return; + } + + var $this = $( this ), + country = $this.val(), + $state = $this.parents( '.form-table' ).find( ':input.js_field-state' ), + $parent = $state.parent(), + input_name = $state.attr( 'name' ), + input_id = $state.attr( 'id' ), + stickstatefield = 'woocommerce.stickState-' + country, + value = $this.data( stickstatefield ) ? $this.data( stickstatefield ) : $state.val(), + placeholder = $state.attr( 'placeholder' ), + $newstate; + + if ( stickValue ){ + $this.data( 'woocommerce.stickState-' + country, value ); + } + + // Remove the previous DOM element + $parent.show().find( '.select2-container' ).remove(); + + if ( ! $.isEmptyObject( wc_users_fields.states[ country ] ) ) { + var state = wc_users_fields.states[ country ], + $defaultOption = $( '' ) + .text( wc_users_fields.i18n_select_state_text ); + + $newstate = $( '' ) + .prop( 'id', input_id ) + .prop( 'name', input_name ) + .prop( 'placeholder', placeholder ) + .addClass( 'js_field-state' ) + .append( $defaultOption ); + + $.each( state, function( index ) { + var $option = $( '' ) + .prop( 'value', index ) + .text( state[ index ] ); + $newstate.append( $option ); + } ); + + $newstate.val( value ); + + $state.replaceWith( $newstate ); + + $newstate.show().selectWoo().hide().change(); + } else { + $newstate = $( '' ) + .prop( 'id', input_id ) + .prop( 'name', input_name ) + .prop( 'placeholder', placeholder ) + .addClass( 'js_field-state regular-text' ) + .val( value ); + $state.replaceWith( $newstate ); + } + + // This event has a typo - deprecated in 2.5.0 + $( document.body ).trigger( 'contry-change.woocommerce', [country, $( this ).closest( 'div' )] ); + $( document.body ).trigger( 'country-change.woocommerce', [country, $( this ).closest( 'div' )] ); + }, + + change_state: function() { + // Here we will find if state value on a select has changed and stick it to the country data + var $this = $( this ), + state = $this.val(), + $country = $this.parents( '.form-table' ).find( ':input.js_field-country' ), + country = $country.val(); + + $country.data( 'woocommerce.stickState-' + country, state ); + }, + + copy_billing: function( event ) { + event.preventDefault(); + + $( '#fieldset-billing' ).find( 'input, select' ).each( function( i, el ) { + // The address keys match up, except for the prefix + var shipName = el.name.replace( /^billing_/, 'shipping_' ); + // Swap prefix, then check if there are any elements + var shipEl = $( '[name="' + shipName + '"]' ); + // No corresponding shipping field, skip this item + if ( ! shipEl.length ) { + return; + } + // Found a matching shipping element, update the value + shipEl.val( el.value ).trigger( 'change' ); + } ); + } + }; + + wc_users_fields.init(); + +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/users.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/users.min.js new file mode 100644 index 0000000..492dd12 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/users.min.js @@ -0,0 +1 @@ +jQuery(function(u){var h={states:null,init:function(){"undefined"!=typeof wc_users_params.countries&&(this.states=JSON.parse(wc_users_params.countries.replace(/"/g,'"'))),u(".js_field-country").selectWoo().change(this.change_country),u(".js_field-country").trigger("change",[!0]),u(document.body).on("change","select.js_field-state",this.change_state),u(document.body).on("click","button.js_copy-billing",this.copy_billing)},change_country:function(e,t){var a,n,o,i,c,s,l,r,p,d;void 0===t&&(t=!1),null!==h.states&&(n=(a=u(this)).val(),p=(o=a.parents(".form-table").find(":input.js_field-state")).parent(),i=o.attr("name"),c=o.attr("id"),l="woocommerce.stickState-"+n,s=a.data(l)?a.data(l):o.val(),l=o.attr("placeholder"),t&&a.data("woocommerce.stickState-"+n,s),p.show().find(".select2-container").remove(),u.isEmptyObject(h.states[n])?(d=u('').prop("id",c).prop("name",i).prop("placeholder",l).addClass("js_field-state regular-text").val(s),o.replaceWith(d)):(r=h.states[n],p=u('').text(h.i18n_select_state_text),d=u('').prop("id",c).prop("name",i).prop("placeholder",l).addClass("js_field-state").append(p),u.each(r,function(e){e=u("").prop("value",e).text(r[e]);d.append(e)}),d.val(s),o.replaceWith(d),d.show().selectWoo().hide().change()),u(document.body).trigger("contry-change.woocommerce",[n,u(this).closest("div")]),u(document.body).trigger("country-change.woocommerce",[n,u(this).closest("div")]))},change_state:function(){var e=u(this),t=e.val(),a=e.parents(".form-table").find(":input.js_field-country"),e=a.val();a.data("woocommerce.stickState-"+e,t)},copy_billing:function(e){e.preventDefault(),u("#fieldset-billing").find("input, select").each(function(e,t){var a=t.name.replace(/^billing_/,"shipping_"),a=u('[name="'+a+'"]');a.length&&a.val(t.value).trigger("change")})}};h.init()}); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/wc-clipboard.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/wc-clipboard.js new file mode 100644 index 0000000..fc009d0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/assets/js/admin/wc-clipboard.js @@ -0,0 +1,38 @@ +/* exported wcSetClipboard, wcClearClipboard */ + +/** + * Simple text copy functions using native browser clipboard capabilities. + * @since 3.2.0 + */ + +/** + * Set the user's clipboard contents. + * + * @param string data: Text to copy to clipboard. + * @param object $el: jQuery element to trigger copy events on. (Default: document) + */ +function wcSetClipboard( data, $el ) { + if ( 'undefined' === typeof $el ) { + $el = jQuery( document ); + } + var $temp_input = jQuery( ' + get_description_html( $data ); // WPCS: XSS ok. ?> + + + + get_field_key( $key ); + $defaults = array( + 'title' => '', + 'label' => '', + 'disabled' => false, + 'class' => '', + 'css' => '', + 'type' => 'text', + 'desc_tip' => false, + 'description' => '', + 'custom_attributes' => array(), + ); + + $data = wp_parse_args( $data, $defaults ); + + if ( ! $data['label'] ) { + $data['label'] = $data['title']; + } + + ob_start(); + ?> + + + + + +
    + +
    + get_description_html( $data ); // WPCS: XSS ok. ?> +
    + + + get_field_key( $key ); + $defaults = array( + 'title' => '', + 'disabled' => false, + 'class' => '', + 'css' => '', + 'placeholder' => '', + 'type' => 'text', + 'desc_tip' => false, + 'description' => '', + 'custom_attributes' => array(), + 'options' => array(), + ); + + $data = wp_parse_args( $data, $defaults ); + + ob_start(); + ?> + + + + + +
    + + + get_description_html( $data ); // WPCS: XSS ok. ?> +
    + + + get_field_key( $key ); + $defaults = array( + 'title' => '', + 'disabled' => false, + 'class' => '', + 'css' => '', + 'placeholder' => '', + 'type' => 'text', + 'desc_tip' => false, + 'description' => '', + 'custom_attributes' => array(), + 'select_buttons' => false, + 'options' => array(), + ); + + $data = wp_parse_args( $data, $defaults ); + $value = (array) $this->get_option( $key, array() ); + + ob_start(); + ?> + + + + + +
    + + + get_description_html( $data ); // WPCS: XSS ok. ?> + +
    + +
    + + + get_field_key( $key ); + $defaults = array( + 'title' => '', + 'class' => '', + ); + + $data = wp_parse_args( $data, $defaults ); + + ob_start(); + ?> + +

    + +

    + + + array( + 'src' => true, + 'style' => true, + 'id' => true, + 'class' => true, + ), + ), + wp_kses_allowed_html( 'post' ) + ) + ); + } + + /** + * Validate Checkbox Field. + * + * If not set, return "no", otherwise return "yes". + * + * @param string $key Field key. + * @param string $value Posted Value. + * @return string + */ + public function validate_checkbox_field( $key, $value ) { + return ! is_null( $value ) ? 'yes' : 'no'; + } + + /** + * Validate Select Field. + * + * @param string $key Field key. + * @param string $value Posted Value. + * @return string + */ + public function validate_select_field( $key, $value ) { + $value = is_null( $value ) ? '' : $value; + return wc_clean( stripslashes( $value ) ); + } + + /** + * Validate Multiselect Field. + * + * @param string $key Field key. + * @param string $value Posted Value. + * @return string|array + */ + public function validate_multiselect_field( $key, $value ) { + return is_array( $value ) ? array_map( 'wc_clean', array_map( 'stripslashes', $value ) ) : ''; + } + + /** + * Validate the data on the "Settings" form. + * + * @deprecated 2.6.0 No longer used. + * @param array $form_fields Array of fields. + */ + public function validate_settings_fields( $form_fields = array() ) { + wc_deprecated_function( 'validate_settings_fields', '2.6' ); + } + + /** + * Format settings if needed. + * + * @deprecated 2.6.0 Unused. + * @param array $value Value to format. + * @return array + */ + public function format_settings( $value ) { + wc_deprecated_function( 'format_settings', '2.6' ); + return $value; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-shipping-method.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-shipping-method.php new file mode 100644 index 0000000..c27b0ae --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-shipping-method.php @@ -0,0 +1,569 @@ +instance_id = absint( $instance_id ); + } + + /** + * Check if a shipping method supports a given feature. + * + * Methods should override this to declare support (or lack of support) for a feature. + * + * @param string $feature The name of a feature to test support for. + * @return bool True if the shipping method supports the feature, false otherwise. + */ + public function supports( $feature ) { + return apply_filters( 'woocommerce_shipping_method_supports', in_array( $feature, $this->supports ), $feature, $this ); + } + + /** + * Called to calculate shipping rates for this method. Rates can be added using the add_rate() method. + * + * @param array $package Package array. + */ + public function calculate_shipping( $package = array() ) {} + + /** + * Whether or not we need to calculate tax on top of the shipping rate. + * + * @return boolean + */ + public function is_taxable() { + return wc_tax_enabled() && 'taxable' === $this->tax_status && ( WC()->customer && ! WC()->customer->get_is_vat_exempt() ); + } + + /** + * Whether or not this method is enabled in settings. + * + * @since 2.6.0 + * @return boolean + */ + public function is_enabled() { + return 'yes' === $this->enabled; + } + + /** + * Return the shipping method instance ID. + * + * @since 2.6.0 + * @return int + */ + public function get_instance_id() { + return $this->instance_id; + } + + /** + * Return the shipping method title. + * + * @since 2.6.0 + * @return string + */ + public function get_method_title() { + return apply_filters( 'woocommerce_shipping_method_title', $this->method_title, $this ); + } + + /** + * Return the shipping method description. + * + * @since 2.6.0 + * @return string + */ + public function get_method_description() { + return apply_filters( 'woocommerce_shipping_method_description', $this->method_description, $this ); + } + + /** + * Return the shipping title which is user set. + * + * @return string + */ + public function get_title() { + return apply_filters( 'woocommerce_shipping_method_title', $this->title, $this->id ); + } + + /** + * Return calculated rates for a package. + * + * @since 2.6.0 + * @param array $package Package array. + * @return array + */ + public function get_rates_for_package( $package ) { + $this->rates = array(); + if ( $this->is_available( $package ) && ( empty( $package['ship_via'] ) || in_array( $this->id, $package['ship_via'] ) ) ) { + $this->calculate_shipping( $package ); + } + return $this->rates; + } + + /** + * Returns a rate ID based on this methods ID and instance, with an optional + * suffix if distinguishing between multiple rates. + * + * @since 2.6.0 + * @param string $suffix Suffix. + * @return string + */ + public function get_rate_id( $suffix = '' ) { + $rate_id = array( $this->id ); + + if ( $this->instance_id ) { + $rate_id[] = $this->instance_id; + } + + if ( $suffix ) { + $rate_id[] = $suffix; + } + + return implode( ':', $rate_id ); + } + + /** + * Add a shipping rate. If taxes are not set they will be calculated based on cost. + * + * @param array $args Arguments (default: array()). + */ + public function add_rate( $args = array() ) { + $args = apply_filters( + 'woocommerce_shipping_method_add_rate_args', + wp_parse_args( + $args, + array( + 'id' => $this->get_rate_id(), // ID for the rate. If not passed, this id:instance default will be used. + 'label' => '', // Label for the rate. + 'cost' => '0', // Amount or array of costs (per item shipping). + 'taxes' => '', // Pass taxes, or leave empty to have it calculated for you, or 'false' to disable calculations. + 'calc_tax' => 'per_order', // Calc tax per_order or per_item. Per item needs an array of costs. + 'meta_data' => array(), // Array of misc meta data to store along with this rate - key value pairs. + 'package' => false, // Package array this rate was generated for @since 2.6.0. + 'price_decimals' => wc_get_price_decimals(), + ) + ), + $this + ); + + // ID and label are required. + if ( ! $args['id'] || ! $args['label'] ) { + return; + } + + // Total up the cost. + $total_cost = is_array( $args['cost'] ) ? array_sum( $args['cost'] ) : $args['cost']; + $taxes = $args['taxes']; + + // Taxes - if not an array and not set to false, calc tax based on cost and passed calc_tax variable. This saves shipping methods having to do complex tax calculations. + if ( ! is_array( $taxes ) && false !== $taxes && $total_cost > 0 && $this->is_taxable() ) { + $taxes = 'per_item' === $args['calc_tax'] ? $this->get_taxes_per_item( $args['cost'] ) : WC_Tax::calc_shipping_tax( $total_cost, WC_Tax::get_shipping_tax_rates() ); + } + + // Round the total cost after taxes have been calculated. + $total_cost = wc_format_decimal( $total_cost, $args['price_decimals'] ); + + // Create rate object. + $rate = new WC_Shipping_Rate(); + $rate->set_id( $args['id'] ); + $rate->set_method_id( $this->id ); + $rate->set_instance_id( $this->instance_id ); + $rate->set_label( $args['label'] ); + $rate->set_cost( $total_cost ); + $rate->set_taxes( $taxes ); + + if ( ! empty( $args['meta_data'] ) ) { + foreach ( $args['meta_data'] as $key => $value ) { + $rate->add_meta_data( $key, $value ); + } + } + + // Store package data. + if ( $args['package'] ) { + $items_in_package = array(); + foreach ( $args['package']['contents'] as $item ) { + $product = $item['data']; + $items_in_package[] = $product->get_name() . ' × ' . $item['quantity']; + } + $rate->add_meta_data( __( 'Items', 'woocommerce' ), implode( ', ', $items_in_package ) ); + } + + $this->rates[ $args['id'] ] = apply_filters( 'woocommerce_shipping_method_add_rate', $rate, $args, $this ); + } + + /** + * Calc taxes per item being shipping in costs array. + * + * @since 2.6.0 + * @param array $costs Costs. + * @return array of taxes + */ + protected function get_taxes_per_item( $costs ) { + $taxes = array(); + + // If we have an array of costs we can look up each items tax class and add tax accordingly. + if ( is_array( $costs ) ) { + + $cart = WC()->cart->get_cart(); + + foreach ( $costs as $cost_key => $amount ) { + if ( ! isset( $cart[ $cost_key ] ) ) { + continue; + } + + $item_taxes = WC_Tax::calc_shipping_tax( $amount, WC_Tax::get_shipping_tax_rates( $cart[ $cost_key ]['data']->get_tax_class() ) ); + + // Sum the item taxes. + foreach ( array_keys( $taxes + $item_taxes ) as $key ) { + $taxes[ $key ] = ( isset( $item_taxes[ $key ] ) ? $item_taxes[ $key ] : 0 ) + ( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 ); + } + } + + // Add any cost for the order - order costs are in the key 'order'. + if ( isset( $costs['order'] ) ) { + $item_taxes = WC_Tax::calc_shipping_tax( $costs['order'], WC_Tax::get_shipping_tax_rates() ); + + // Sum the item taxes. + foreach ( array_keys( $taxes + $item_taxes ) as $key ) { + $taxes[ $key ] = ( isset( $item_taxes[ $key ] ) ? $item_taxes[ $key ] : 0 ) + ( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 ); + } + } + } + + return $taxes; + } + + /** + * Is this method available? + * + * @param array $package Package. + * @return bool + */ + public function is_available( $package ) { + $available = $this->is_enabled(); + + // Country availability (legacy, for non-zone based methods). + if ( ! $this->instance_id && $available ) { + $countries = is_array( $this->countries ) ? $this->countries : array(); + + switch ( $this->availability ) { + case 'specific': + case 'including': + $available = in_array( $package['destination']['country'], array_intersect( $countries, array_keys( WC()->countries->get_shipping_countries() ) ) ); + break; + case 'excluding': + $available = in_array( $package['destination']['country'], array_diff( array_keys( WC()->countries->get_shipping_countries() ), $countries ) ); + break; + default: + $available = in_array( $package['destination']['country'], array_keys( WC()->countries->get_shipping_countries() ) ); + break; + } + } + + return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $available, $package, $this ); + } + + /** + * Get fee to add to shipping cost. + * + * @param string|float $fee Fee. + * @param float $total Total. + * @return float + */ + public function get_fee( $fee, $total ) { + if ( strstr( $fee, '%' ) ) { + $fee = ( $total / 100 ) * str_replace( '%', '', $fee ); + } + if ( ! empty( $this->minimum_fee ) && $this->minimum_fee > $fee ) { + $fee = $this->minimum_fee; + } + return $fee; + } + + /** + * Does this method have a settings page? + * + * @return bool + */ + public function has_settings() { + return $this->instance_id ? $this->supports( 'instance-settings' ) : $this->supports( 'settings' ); + } + + /** + * Return admin options as a html string. + * + * @return string + */ + public function get_admin_options_html() { + if ( $this->instance_id ) { + $settings_html = $this->generate_settings_html( $this->get_instance_form_fields(), false ); + } else { + $settings_html = $this->generate_settings_html( $this->get_form_fields(), false ); + } + + return '
    ' . $settings_html . '
    '; + } + + /** + * Output the shipping settings screen. + */ + public function admin_options() { + if ( ! $this->instance_id ) { + echo '

    ' . esc_html( $this->get_method_title() ) . '

    '; + } + echo wp_kses_post( wpautop( $this->get_method_description() ) ); + echo $this->get_admin_options_html(); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + } + + /** + * Get_option function. + * + * Gets and option from the settings API, using defaults if necessary to prevent undefined notices. + * + * @param string $key Key. + * @param mixed $empty_value Empty value. + * @return mixed The value specified for the option or a default value for the option. + */ + public function get_option( $key, $empty_value = null ) { + // Instance options take priority over global options. + if ( $this->instance_id && array_key_exists( $key, $this->get_instance_form_fields() ) ) { + return $this->get_instance_option( $key, $empty_value ); + } + + // Return global option. + $option = apply_filters( 'woocommerce_shipping_' . $this->id . '_option', parent::get_option( $key, $empty_value ), $key, $this ); + return $option; + } + + /** + * Gets an option from the settings API, using defaults if necessary to prevent undefined notices. + * + * @param string $key Key. + * @param mixed $empty_value Empty value. + * @return mixed The value specified for the option or a default value for the option. + */ + public function get_instance_option( $key, $empty_value = null ) { + if ( empty( $this->instance_settings ) ) { + $this->init_instance_settings(); + } + + // Get option default if unset. + if ( ! isset( $this->instance_settings[ $key ] ) ) { + $form_fields = $this->get_instance_form_fields(); + $this->instance_settings[ $key ] = $this->get_field_default( $form_fields[ $key ] ); + } + + if ( ! is_null( $empty_value ) && '' === $this->instance_settings[ $key ] ) { + $this->instance_settings[ $key ] = $empty_value; + } + + $instance_option = apply_filters( 'woocommerce_shipping_' . $this->id . '_instance_option', $this->instance_settings[ $key ], $key, $this ); + return $instance_option; + } + + /** + * Get settings fields for instances of this shipping method (within zones). + * Should be overridden by shipping methods to add options. + * + * @since 2.6.0 + * @return array + */ + public function get_instance_form_fields() { + return apply_filters( 'woocommerce_shipping_instance_form_fields_' . $this->id, array_map( array( $this, 'set_defaults' ), $this->instance_form_fields ) ); + } + + /** + * Return the name of the option in the WP DB. + * + * @since 2.6.0 + * @return string + */ + public function get_instance_option_key() { + return $this->instance_id ? $this->plugin_id . $this->id . '_' . $this->instance_id . '_settings' : ''; + } + + /** + * Initialise Settings for instances. + * + * @since 2.6.0 + */ + public function init_instance_settings() { + $this->instance_settings = get_option( $this->get_instance_option_key(), null ); + + // If there are no settings defined, use defaults. + if ( ! is_array( $this->instance_settings ) ) { + $form_fields = $this->get_instance_form_fields(); + $this->instance_settings = array_merge( array_fill_keys( array_keys( $form_fields ), '' ), wp_list_pluck( $form_fields, 'default' ) ); + } + } + + /** + * Processes and saves global shipping method options in the admin area. + * + * This method is usually attached to woocommerce_update_options_x hooks. + * + * @since 2.6.0 + * @return bool was anything saved? + */ + public function process_admin_options() { + if ( ! $this->instance_id ) { + return parent::process_admin_options(); + } + + // Check we are processing the correct form for this instance. + if ( ! isset( $_REQUEST['instance_id'] ) || absint( $_REQUEST['instance_id'] ) !== $this->instance_id ) { // WPCS: input var ok, CSRF ok. + return false; + } + + $this->init_instance_settings(); + + $post_data = $this->get_post_data(); + + foreach ( $this->get_instance_form_fields() as $key => $field ) { + if ( 'title' !== $this->get_field_type( $field ) ) { + try { + $this->instance_settings[ $key ] = $this->get_field_value( $key, $field, $post_data ); + } catch ( Exception $e ) { + $this->add_error( $e->getMessage() ); + } + } + } + + return update_option( $this->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $this->id . '_instance_settings_values', $this->instance_settings, $this ), 'yes' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-widget.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-widget.php new file mode 100644 index 0000000..10ac9e4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-widget.php @@ -0,0 +1,407 @@ + $this->widget_cssclass, + 'description' => $this->widget_description, + 'customize_selective_refresh' => true, + ); + + parent::__construct( $this->widget_id, $this->widget_name, $widget_ops ); + + add_action( 'save_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) ); + add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) ); + } + + /** + * Get cached widget. + * + * @param array $args Arguments. + * @return bool true if the widget is cached otherwise false + */ + public function get_cached_widget( $args ) { + // Don't get cache if widget_id doesn't exists. + if ( empty( $args['widget_id'] ) ) { + return false; + } + + $cache = wp_cache_get( $this->get_widget_id_for_cache( $this->widget_id ), 'widget' ); + + if ( ! is_array( $cache ) ) { + $cache = array(); + } + + if ( isset( $cache[ $this->get_widget_id_for_cache( $args['widget_id'] ) ] ) ) { + echo $cache[ $this->get_widget_id_for_cache( $args['widget_id'] ) ]; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + return true; + } + + return false; + } + + /** + * Cache the widget. + * + * @param array $args Arguments. + * @param string $content Content. + * @return string the content that was cached + */ + public function cache_widget( $args, $content ) { + // Don't set any cache if widget_id doesn't exist. + if ( empty( $args['widget_id'] ) ) { + return $content; + } + + $cache = wp_cache_get( $this->get_widget_id_for_cache( $this->widget_id ), 'widget' ); + + if ( ! is_array( $cache ) ) { + $cache = array(); + } + + $cache[ $this->get_widget_id_for_cache( $args['widget_id'] ) ] = $content; + + wp_cache_set( $this->get_widget_id_for_cache( $this->widget_id ), $cache, 'widget' ); + + return $content; + } + + /** + * Flush the cache. + */ + public function flush_widget_cache() { + foreach ( array( 'https', 'http' ) as $scheme ) { + wp_cache_delete( $this->get_widget_id_for_cache( $this->widget_id, $scheme ), 'widget' ); + } + } + + /** + * Get this widgets title. + * + * @param array $instance Array of instance options. + * @return string + */ + protected function get_instance_title( $instance ) { + if ( isset( $instance['title'] ) ) { + return $instance['title']; + } + + if ( isset( $this->settings, $this->settings['title'], $this->settings['title']['std'] ) ) { + return $this->settings['title']['std']; + } + + return ''; + } + + /** + * Output the html at the start of a widget. + * + * @param array $args Arguments. + * @param array $instance Instance. + */ + public function widget_start( $args, $instance ) { + echo $args['before_widget']; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + + $title = apply_filters( 'widget_title', $this->get_instance_title( $instance ), $instance, $this->id_base ); + + if ( $title ) { + echo $args['before_title'] . $title . $args['after_title']; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + } + } + + /** + * Output the html at the end of a widget. + * + * @param array $args Arguments. + */ + public function widget_end( $args ) { + echo $args['after_widget']; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + } + + /** + * Updates a particular instance of a widget. + * + * @see WP_Widget->update + * @param array $new_instance New instance. + * @param array $old_instance Old instance. + * @return array + */ + public function update( $new_instance, $old_instance ) { + + $instance = $old_instance; + + if ( empty( $this->settings ) ) { + return $instance; + } + + // Loop settings and get values to save. + foreach ( $this->settings as $key => $setting ) { + if ( ! isset( $setting['type'] ) ) { + continue; + } + + // Format the value based on settings type. + switch ( $setting['type'] ) { + case 'number': + $instance[ $key ] = absint( $new_instance[ $key ] ); + + if ( isset( $setting['min'] ) && '' !== $setting['min'] ) { + $instance[ $key ] = max( $instance[ $key ], $setting['min'] ); + } + + if ( isset( $setting['max'] ) && '' !== $setting['max'] ) { + $instance[ $key ] = min( $instance[ $key ], $setting['max'] ); + } + break; + case 'textarea': + $instance[ $key ] = wp_kses( trim( wp_unslash( $new_instance[ $key ] ) ), wp_kses_allowed_html( 'post' ) ); + break; + case 'checkbox': + $instance[ $key ] = empty( $new_instance[ $key ] ) ? 0 : 1; + break; + default: + $instance[ $key ] = isset( $new_instance[ $key ] ) ? sanitize_text_field( $new_instance[ $key ] ) : $setting['std']; + break; + } + + /** + * Sanitize the value of a setting. + */ + $instance[ $key ] = apply_filters( 'woocommerce_widget_settings_sanitize_option', $instance[ $key ], $new_instance, $key, $setting ); + } + + $this->flush_widget_cache(); + + return $instance; + } + + /** + * Outputs the settings update form. + * + * @see WP_Widget->form + * + * @param array $instance Instance. + */ + public function form( $instance ) { + + if ( empty( $this->settings ) ) { + return; + } + + foreach ( $this->settings as $key => $setting ) { + + $class = isset( $setting['class'] ) ? $setting['class'] : ''; + $value = isset( $instance[ $key ] ) ? $instance[ $key ] : $setting['std']; + + switch ( $setting['type'] ) { + + case 'text': + ?> +

    + + +

    + +

    + + +

    + +

    + + +

    + +

    + + + + + +

    + +

    + /> + +

    + slug, $queried_object->taxonomy ); + } + + // Min/Max. + if ( isset( $_GET['min_price'] ) ) { + $link = add_query_arg( 'min_price', wc_clean( wp_unslash( $_GET['min_price'] ) ), $link ); + } + + if ( isset( $_GET['max_price'] ) ) { + $link = add_query_arg( 'max_price', wc_clean( wp_unslash( $_GET['max_price'] ) ), $link ); + } + + // Order by. + if ( isset( $_GET['orderby'] ) ) { + $link = add_query_arg( 'orderby', wc_clean( wp_unslash( $_GET['orderby'] ) ), $link ); + } + + /** + * Search Arg. + * To support quote characters, first they are decoded from " entities, then URL encoded. + */ + if ( get_search_query() ) { + $link = add_query_arg( 's', rawurlencode( htmlspecialchars_decode( get_search_query() ) ), $link ); + } + + // Post Type Arg. + if ( isset( $_GET['post_type'] ) ) { + $link = add_query_arg( 'post_type', wc_clean( wp_unslash( $_GET['post_type'] ) ), $link ); + + // Prevent post type and page id when pretty permalinks are disabled. + if ( is_shop() ) { + $link = remove_query_arg( 'page_id', $link ); + } + } + + // Min Rating Arg. + if ( isset( $_GET['rating_filter'] ) ) { + $link = add_query_arg( 'rating_filter', wc_clean( wp_unslash( $_GET['rating_filter'] ) ), $link ); + } + + // All current filters. + if ( $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes() ) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.Found, WordPress.CodeAnalysis.AssignmentInCondition.Found + foreach ( $_chosen_attributes as $name => $data ) { + $filter_name = wc_attribute_taxonomy_slug( $name ); + if ( ! empty( $data['terms'] ) ) { + $link = add_query_arg( 'filter_' . $filter_name, implode( ',', $data['terms'] ), $link ); + } + if ( 'or' === $data['query_type'] ) { + $link = add_query_arg( 'query_type_' . $filter_name, 'or', $link ); + } + } + } + + return apply_filters( 'woocommerce_widget_get_current_page_url', $link, $this ); + } + + /** + * Get widget id plus scheme/protocol to prevent serving mixed content from (persistently) cached widgets. + * + * @since 3.4.0 + * @param string $widget_id Id of the cached widget. + * @param string $scheme Scheme for the widget id. + * @return string Widget id including scheme/protocol. + */ + protected function get_widget_id_for_cache( $widget_id, $scheme = '' ) { + if ( $scheme ) { + $widget_id_for_cache = $widget_id . '-' . $scheme; + } else { + $widget_id_for_cache = $widget_id . '-' . ( is_ssl() ? 'https' : 'http' ); + } + + return apply_filters( 'woocommerce_cached_widget_id', $widget_id_for_cache ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/abstracts/class-wc-background-process.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/abstracts/class-wc-background-process.php new file mode 100644 index 0000000..a48fa58 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/abstracts/class-wc-background-process.php @@ -0,0 +1,212 @@ +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 ) ); // @codingStandardsIgnoreLine. + + return ! ( $count > 0 ); + } + + /** + * 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 ) ); // @codingStandardsIgnoreLine. + + $batch = new stdClass(); + $batch->key = $query->$column; + $batch->data = array_filter( (array) maybe_unserialize( $query->$value_column ) ); + + return $batch; + } + + /** + * See if the batch limit has been exceeded. + * + * @return bool + */ + protected function batch_limit_exceeded() { + return $this->time_exceeded() || $this->memory_exceeded(); + } + + /** + * 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->batch_limit_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->batch_limit_exceeded() && ! $this->is_queue_empty() ); + + $this->unlock_process(); + + // Start next batch or complete process. + if ( ! $this->is_queue_empty() ) { + $this->dispatch(); + } else { + $this->complete(); + } + } + + /** + * 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 = '32G'; + } + + return wp_convert_hr_to_bytes( $memory_limit ); + } + + /** + * Schedule cron healthcheck. + * + * @param array $schedules Schedules. + * @return array + */ + 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, + /* translators: %d: interval */ + 'display' => sprintf( __( 'Every %d minutes', 'woocommerce' ), $interval ), + ); + + return $schedules; + } + + /** + * Delete all batches. + * + * @return WC_Background_Process + */ + public function delete_all_batches() { + global $wpdb; + + $table = $wpdb->options; + $column = 'option_name'; + + if ( is_multisite() ) { + $table = $wpdb->sitemeta; + $column = 'meta_key'; + } + + $key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%'; + + $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @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 ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-addons.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-addons.php new file mode 100644 index 0000000..ac072dc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-addons.php @@ -0,0 +1,711 @@ + 'WooCommerce Addons Page' ) ); + if ( ! is_wp_error( $raw_featured ) ) { + $featured = json_decode( wp_remote_retrieve_body( $raw_featured ) ); + if ( $featured ) { + set_transient( 'wc_addons_featured', $featured, WEEK_IN_SECONDS ); + } + } + } + + if ( is_object( $featured ) ) { + self::output_featured_sections( $featured->sections ); + return $featured; + } + } + + /** + * Build url parameter string + * + * @param string $category Addon (sub) category. + * @param string $term Search terms. + * @param string $country Store country. + * + * @return string url parameter string + */ + public static function build_parameter_string( $category, $term, $country ) { + + $parameters = array( + 'category' => $category, + 'term' => $term, + 'country' => $country, + ); + + return '?' . http_build_query( $parameters ); + } + + /** + * Call API to get extensions + * + * @param string $category Addon (sub) category. + * @param string $term Search terms. + * @param string $country Store country. + * + * @return array of extensions + */ + public static function get_extension_data( $category, $term, $country ) { + $parameters = self::build_parameter_string( $category, $term, $country ); + $raw_extensions = wp_remote_get( + 'https://woocommerce.com/wp-json/wccom-extensions/1.0/search' . $parameters + ); + if ( ! is_wp_error( $raw_extensions ) ) { + $addons = json_decode( wp_remote_retrieve_body( $raw_extensions ) )->products; + } + return $addons; + } + + /** + * Get sections for the addons screen + * + * @return array of objects + */ + public static function get_sections() { + $addon_sections = get_transient( 'wc_addons_sections' ); + if ( false === ( $addon_sections ) ) { + $raw_sections = wp_safe_remote_get( + 'https://woocommerce.com/wp-json/wccom-extensions/1.0/categories' + ); + if ( ! is_wp_error( $raw_sections ) ) { + $addon_sections = json_decode( wp_remote_retrieve_body( $raw_sections ) ); + if ( $addon_sections ) { + set_transient( 'wc_addons_sections', $addon_sections, WEEK_IN_SECONDS ); + } + } + } + return apply_filters( 'woocommerce_addons_sections', $addon_sections ); + } + + /** + * Get section for the addons screen. + * + * @param string $section_id Required section ID. + * + * @return object|bool + */ + public static function get_section( $section_id ) { + $sections = self::get_sections(); + if ( isset( $sections[ $section_id ] ) ) { + return $sections[ $section_id ]; + } + return false; + } + + /** + * Get section content for the addons screen. + * + * @param string $section_id Required section ID. + * + * @return array + */ + public static function get_section_data( $section_id ) { + $section = self::get_section( $section_id ); + $section_data = ''; + + if ( ! empty( $section->endpoint ) ) { + $section_data = get_transient( 'wc_addons_section_' . $section_id ); + if ( false === $section_data ) { + $raw_section = wp_safe_remote_get( esc_url_raw( $section->endpoint ), array( 'user-agent' => 'WooCommerce Addons Page' ) ); + + if ( ! is_wp_error( $raw_section ) ) { + $section_data = json_decode( wp_remote_retrieve_body( $raw_section ) ); + + if ( ! empty( $section_data->products ) ) { + set_transient( 'wc_addons_section_' . $section_id, $section_data, WEEK_IN_SECONDS ); + } + } + } + } + + return apply_filters( 'woocommerce_addons_section_data', $section_data->products, $section_id ); + } + + /** + * Handles the outputting of a contextually aware Storefront link (points to child themes if Storefront is already active). + */ + public static function output_storefront_button() { + $template = get_option( 'template' ); + $stylesheet = get_option( 'stylesheet' ); + + if ( 'storefront' === $template ) { + if ( 'storefront' === $stylesheet ) { + $url = 'https://woocommerce.com/product-category/themes/storefront-child-theme-themes/'; + $text = __( 'Need a fresh look? Try Storefront child themes', 'woocommerce' ); + $utm_content = 'nostorefrontchildtheme'; + } else { + $url = 'https://woocommerce.com/product-category/themes/storefront-child-theme-themes/'; + $text = __( 'View more Storefront child themes', 'woocommerce' ); + $utm_content = 'hasstorefrontchildtheme'; + } + } else { + $url = 'https://woocommerce.com/storefront/'; + $text = __( 'Need a theme? Try Storefront', 'woocommerce' ); + $utm_content = 'nostorefront'; + } + + $url = add_query_arg( + array( + 'utm_source' => 'addons', + 'utm_medium' => 'product', + 'utm_campaign' => 'woocommerceplugin', + 'utm_content' => $utm_content, + ), + $url + ); + + echo '' . esc_html( $text ) . '' . "\n"; + } + + /** + * Handles the outputting of a banner block. + * + * @param object $block Banner data. + */ + public static function output_banner_block( $block ) { + ?> +
    +

    title ); ?>

    +

    description ); ?>

    +
    + items as $item ) : ?> + +
    +
    + +
    +
    +

    title ); ?>

    +

    description ); ?>

    + href, + $item->button, + 'addons-button-solid', + $item->plugin + ); + ?> +
    +
    + + +
    +
    + container ) && 'column_container_start' === $block->container ) { + ?> +
    + module ) { + ?> +
    + +
    + container ) && 'column_container_end' === $block->container ) { + ?> +
    + +
    +

    title ); ?>

    +

    description ); ?>

    + items as $item ) : ?> + +
    +
    + +
    +
    +

    title ); ?>

    + href, + $item->button, + 'addons-button-solid', + $item->plugin + ); + ?> +

    description ); ?>

    +
    +
    + + +
    + + +
    + +
    +

    title ); ?>

    +

    description ); ?>

    +
    + buttons as $button ) : ?> + href, + $button->text, + 'addons-button-solid' + ); + ?> + +
    +
    +
    + +
    +

    title ); ?>

    +

    description ); ?>

    +
    + items as $item ) : ?> +
    + image ) ) : ?> +
    + +
    + + href, + $item->button, + 'addons-button-outline-white' + ); + ?> +
    + +
    +
    + 'woocommerce-services', + ) + ), + 'install-addon_woocommerce-services' + ); + + $defaults = array( + 'image' => WC()->plugin_url() . '/assets/images/wcs-extensions-banner-3x.png', + 'image_alt' => __( 'WooCommerce Shipping', 'woocommerce' ), + 'title' => __( 'Buy discounted shipping labels — then print them from your dashboard.', 'woocommerce' ), + 'description' => __( 'Integrate your store with USPS to buy discounted shipping labels, and print them directly from your WooCommerce dashboard. Powered by WooCommerce Shipping.', 'woocommerce' ), + 'button' => __( 'Free - Install now', 'woocommerce' ), + 'href' => $button_url, + 'logos' => array(), + ); + + switch ( $location['country'] ) { + case 'CA': + $local_defaults = array( + 'image' => WC()->plugin_url() . '/assets/images/wcs-truck-banner-3x.png', + 'title' => __( 'Show Canada Post shipping rates', 'woocommerce' ), + 'description' => __( 'Display live rates from Canada Post at checkout to make shipping a breeze. Powered by WooCommerce Shipping.', 'woocommerce' ), + 'logos' => array_merge( + $defaults['logos'], + array( + array( + 'link' => WC()->plugin_url() . '/assets/images/wcs-canada-post-logo.jpg', + 'alt' => 'Canada Post logo', + ), + ) + ), + ); + break; + case 'US': + $local_defaults = array( + 'logos' => array_merge( + $defaults['logos'], + array( + array( + 'link' => WC()->plugin_url() . '/assets/images/wcs-usps-logo.png', + 'alt' => 'USPS logo', + ), + ) + ), + ); + break; + default: + $local_defaults = array(); + } + + $block_data = array_merge( $defaults, $local_defaults, $block ); + ?> +
    +
    + <?php echo esc_attr( $block_data['image_alt'] ); ?> +
    +
    +

    +

    +
      + +
    • + +
    • + +
    + +
    +
    + 'woocommerce-payments', + ) + ), + 'install-addon_woocommerce-payments' + ); + + $defaults = array( + 'image' => WC()->plugin_url() . '/assets/images/wcpayments-icon-secure.png', + 'image_alt' => __( 'WooCommerce Payments', 'woocommerce' ), + 'title' => __( 'Payments made simple, with no monthly fees — exclusively for WooCommerce stores.', 'woocommerce' ), + 'description' => __( 'Securely accept cards in your store. See payments, track cash flow into your bank account, and stay on top of disputes – right from your dashboard.', 'woocommerce' ), + 'button' => __( 'Free - Install now', 'woocommerce' ), + 'href' => $button_url, + 'logos' => array(), + ); + + $block_data = array_merge( $defaults, $block ); + ?> +
    +
    + <?php echo esc_attr( $block_data['image_alt'] ); ?> +
    +
    +

    +

    + +
    +
    + module ) { + case 'banner_block': + self::output_banner_block( $section ); + break; + case 'column_start': + self::output_column( $section ); + break; + case 'column_end': + self::output_column( $section ); + break; + case 'column_block': + self::output_column_block( $section ); + break; + case 'small_light_block': + self::output_small_light_block( $section ); + break; + case 'small_dark_block': + self::output_small_dark_block( $section ); + break; + case 'wcs_banner_block': + self::output_wcs_banner_block( (array) $section ); + break; + case 'wcpay_banner_block': + self::output_wcpay_banner_block( (array) $section ); + break; + } + } + } + + /** + * Returns in-app-purchase URL params. + */ + public static function get_in_app_purchase_url_params() { + // Get url (from path onward) for the current page, + // so WCCOM "back" link returns user to where they were. + $back_admin_path = add_query_arg( array() ); + return array( + 'wccom-site' => site_url(), + 'wccom-back' => rawurlencode( $back_admin_path ), + 'wccom-woo-version' => Constants::get_constant( 'WC_VERSION' ), + 'wccom-connect-nonce' => wp_create_nonce( 'connect' ), + ); + } + + /** + * Add in-app-purchase URL params to link. + * + * Adds various url parameters to a url to support a streamlined + * flow for obtaining and setting up WooCommerce extensons. + * + * @param string $url Destination URL. + */ + public static function add_in_app_purchase_url_params( $url ) { + return add_query_arg( + self::get_in_app_purchase_url_params(), + $url + ); + } + + /** + * Outputs a button. + * + * @param string $url Destination URL. + * @param string $text Button label text. + * @param string $style Button style class. + * @param string $plugin The plugin the button is promoting. + */ + public static function output_button( $url, $text, $style, $plugin = '' ) { + $style = __( 'Free', 'woocommerce' ) === $text ? 'addons-button-outline-purple' : $style; + $style = is_plugin_active( $plugin ) ? 'addons-button-installed' : $style; + $text = is_plugin_active( $plugin ) ? __( 'Installed', 'woocommerce' ) : $text; + $url = self::add_in_app_purchase_url_params( $url ); + ?> + + + + countries->get_base_country(); + $addons = self::get_extension_data( $category, $term, $country ); + } + + /** + * Addon page view. + * + * @uses $addons + * @uses $sections + * @uses $theme + * @uses $current_section + */ + include_once dirname( __FILE__ ) . '/views/html-admin-page-addons.php'; + } + + /** + * Install WooCommerce Services from Extensions screens. + */ + public static function install_woocommerce_services_addon() { + check_admin_referer( 'install-addon_woocommerce-services' ); + + $services_plugin_id = 'woocommerce-services'; + $services_plugin = array( + 'name' => __( 'WooCommerce Services', 'woocommerce' ), + 'repo-slug' => 'woocommerce-services', + ); + + WC_Install::background_installer( $services_plugin_id, $services_plugin ); + + wp_safe_redirect( remove_query_arg( array( 'install-addon', '_wpnonce' ) ) ); + exit; + } + + /** + * Install WooCommerce Payments from the Extensions screens. + * + * @return void + */ + public static function install_woocommerce_payments_addon() { + check_admin_referer( 'install-addon_woocommerce-payments' ); + + $wcpay_plugin_id = 'woocommerce-payments'; + $wcpay_plugin = array( + 'name' => __( 'WooCommerce Payments', 'woocommerce' ), + 'repo-slug' => 'woocommerce-payments', + ); + + WC_Install::background_installer( $services_plugin_id, $wcpay_plugin ); + + wp_safe_redirect( remove_query_arg( array( 'install-addon', '_wpnonce' ) ) ); + exit; + } + + /** + * Should an extension be shown on the featured page. + * + * @param object $item Item data. + * @return boolean + */ + public static function show_extension( $item ) { + $location = WC()->countries->get_base_country(); + if ( isset( $item->geowhitelist ) && ! in_array( $location, $item->geowhitelist, true ) ) { + return false; + } + + if ( isset( $item->geoblacklist ) && in_array( $location, $item->geoblacklist, true ) ) { + return false; + } + + if ( is_plugin_active( $item->plugin ) ) { + return false; + } + + return true; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-api-keys-table-list.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-api-keys-table-list.php new file mode 100644 index 0000000..000652c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-api-keys-table-list.php @@ -0,0 +1,278 @@ + 'key', + 'plural' => 'keys', + 'ajax' => false, + ) + ); + } + + /** + * No items found text. + */ + public function no_items() { + esc_html_e( 'No keys found.', 'woocommerce' ); + } + + /** + * Get list columns. + * + * @return array + */ + public function get_columns() { + return array( + 'cb' => '', + 'title' => __( 'Description', 'woocommerce' ), + 'truncated_key' => __( 'Consumer key ending in', 'woocommerce' ), + 'user' => __( 'User', 'woocommerce' ), + 'permissions' => __( 'Permissions', 'woocommerce' ), + 'last_access' => __( 'Last access', 'woocommerce' ), + ); + } + + /** + * Column cb. + * + * @param array $key Key data. + * @return string + */ + public function column_cb( $key ) { + return sprintf( '', $key['key_id'] ); + } + + /** + * Return title column. + * + * @param array $key Key data. + * @return string + */ + public function column_title( $key ) { + $url = admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=keys&edit-key=' . $key['key_id'] ); + $user_id = intval( $key['user_id'] ); + + // Check if current user can edit other users or if it's the same user. + $can_edit = current_user_can( 'edit_user', $user_id ) || get_current_user_id() === $user_id; + + $output = ''; + if ( $can_edit ) { + $output .= ''; + } + if ( empty( $key['description'] ) ) { + $output .= esc_html__( 'API key', 'woocommerce' ); + } else { + $output .= esc_html( $key['description'] ); + } + if ( $can_edit ) { + $output .= ''; + } + $output .= ''; + + // Get actions. + $actions = array( + /* translators: %s: API key ID. */ + 'id' => sprintf( __( 'ID: %d', 'woocommerce' ), $key['key_id'] ), + ); + + if ( $can_edit ) { + $actions['edit'] = '' . __( 'View/Edit', 'woocommerce' ) . ''; + $actions['trash'] = '' . esc_html__( 'Revoke', 'woocommerce' ) . ''; + } + + $row_actions = array(); + + foreach ( $actions as $action => $link ) { + $row_actions[] = '' . $link . ''; + } + + $output .= '
    ' . implode( ' | ', $row_actions ) . '
    '; + + return $output; + } + + /** + * Return truncated consumer key column. + * + * @param array $key Key data. + * @return string + */ + public function column_truncated_key( $key ) { + return '…' . esc_html( $key['truncated_key'] ) . ''; + } + + /** + * Return user column. + * + * @param array $key Key data. + * @return string + */ + public function column_user( $key ) { + $user = get_user_by( 'id', $key['user_id'] ); + + if ( ! $user ) { + return ''; + } + + if ( current_user_can( 'edit_user', $user->ID ) ) { + return '' . esc_html( $user->display_name ) . ''; + } + + return esc_html( $user->display_name ); + } + + /** + * Return permissions column. + * + * @param array $key Key data. + * @return string + */ + public function column_permissions( $key ) { + $permission_key = $key['permissions']; + $permissions = array( + 'read' => __( 'Read', 'woocommerce' ), + 'write' => __( 'Write', 'woocommerce' ), + 'read_write' => __( 'Read/Write', 'woocommerce' ), + ); + + if ( isset( $permissions[ $permission_key ] ) ) { + return esc_html( $permissions[ $permission_key ] ); + } else { + return ''; + } + } + + /** + * Return last access column. + * + * @param array $key Key data. + * @return string + */ + public function column_last_access( $key ) { + if ( ! empty( $key['last_access'] ) ) { + /* translators: 1: last access date 2: last access time */ + $date = sprintf( __( '%1$s at %2$s', 'woocommerce' ), date_i18n( wc_date_format(), strtotime( $key['last_access'] ) ), date_i18n( wc_time_format(), strtotime( $key['last_access'] ) ) ); + + return apply_filters( 'woocommerce_api_key_last_access_datetime', $date, $key['last_access'] ); + } + + return __( 'Unknown', 'woocommerce' ); + } + + /** + * Get bulk actions. + * + * @return array + */ + protected function get_bulk_actions() { + if ( ! current_user_can( 'remove_users' ) ) { + return array(); + } + + return array( + 'revoke' => __( 'Revoke', 'woocommerce' ), + ); + } + + /** + * Search box. + * + * @param string $text Button text. + * @param string $input_id Input ID. + */ + public function search_box( $text, $input_id ) { + if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) { // WPCS: input var okay, CSRF ok. + return; + } + + $input_id = $input_id . '-search-input'; + $search_query = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : ''; // WPCS: input var okay, CSRF ok. + + echo ''; + } + + /** + * Prepare table list items. + */ + public function prepare_items() { + global $wpdb; + + $per_page = $this->get_items_per_page( 'woocommerce_keys_per_page' ); + $current_page = $this->get_pagenum(); + + if ( 1 < $current_page ) { + $offset = $per_page * ( $current_page - 1 ); + } else { + $offset = 0; + } + + $search = ''; + + if ( ! empty( $_REQUEST['s'] ) ) { // WPCS: input var okay, CSRF ok. + $search = "AND description LIKE '%" . esc_sql( $wpdb->esc_like( wc_clean( wp_unslash( $_REQUEST['s'] ) ) ) ) . "%' "; // WPCS: input var okay, CSRF ok. + } + + // Get the API keys. + $keys = $wpdb->get_results( + "SELECT key_id, user_id, description, permissions, truncated_key, last_access FROM {$wpdb->prefix}woocommerce_api_keys WHERE 1 = 1 {$search}" . + $wpdb->prepare( 'ORDER BY key_id DESC LIMIT %d OFFSET %d;', $per_page, $offset ), + ARRAY_A + ); // WPCS: unprepared SQL ok. + + $count = $wpdb->get_var( "SELECT COUNT(key_id) FROM {$wpdb->prefix}woocommerce_api_keys WHERE 1 = 1 {$search};" ); // WPCS: unprepared SQL ok. + + $this->items = $keys; + + // Set the pagination. + $this->set_pagination_args( + array( + 'total_items' => $count, + 'per_page' => $per_page, + 'total_pages' => ceil( $count / $per_page ), + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-api-keys.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-api-keys.php new file mode 100644 index 0000000..6c44032 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-api-keys.php @@ -0,0 +1,274 @@ +is_api_keys_settings_page() ) { // WPCS: input var okay, CSRF ok. + $keys_table_list = new WC_Admin_API_Keys_Table_List(); + + // Add screen option. + add_screen_option( + 'per_page', + array( + 'default' => 10, + 'option' => 'woocommerce_keys_per_page', + ) + ); + } + } + + /** + * Table list output. + */ + private static function table_list_output() { + global $wpdb, $keys_table_list; + + echo '

    ' . esc_html__( 'REST API', 'woocommerce' ) . ' ' . esc_html__( 'Add key', 'woocommerce' ) . '

    '; + + // Get the API keys count. + $count = $wpdb->get_var( "SELECT COUNT(key_id) FROM {$wpdb->prefix}woocommerce_api_keys WHERE 1 = 1;" ); + + if ( absint( $count ) && $count > 0 ) { + $keys_table_list->prepare_items(); + + echo ''; + echo ''; + echo ''; + + $keys_table_list->views(); + $keys_table_list->search_box( __( 'Search key', 'woocommerce' ), 'key' ); + $keys_table_list->display(); + } else { + echo '
    '; + ?> +

    + + + 0, + 'user_id' => '', + 'description' => '', + 'permissions' => '', + 'truncated_key' => '', + 'last_access' => '', + ); + + if ( 0 === $key_id ) { + return $empty; + } + + $key = $wpdb->get_row( + $wpdb->prepare( + "SELECT key_id, user_id, description, permissions, truncated_key, last_access + FROM {$wpdb->prefix}woocommerce_api_keys + WHERE key_id = %d", + $key_id + ), + ARRAY_A + ); + + if ( is_null( $key ) ) { + return $empty; + } + + return $key; + } + + /** + * API Keys admin actions. + */ + public function actions() { + if ( $this->is_api_keys_settings_page() ) { + // Revoke key. + if ( isset( $_REQUEST['revoke-key'] ) ) { // WPCS: input var okay, CSRF ok. + $this->revoke_key(); + } + + // Bulk actions. + if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['key'] ) ) { // WPCS: input var okay, CSRF ok. + $this->bulk_actions(); + } + } + } + + /** + * Notices. + */ + public static function notices() { + if ( isset( $_GET['revoked'] ) ) { // WPCS: input var okay, CSRF ok. + $revoked = absint( $_GET['revoked'] ); // WPCS: input var okay, CSRF ok. + + /* translators: %d: count */ + WC_Admin_Settings::add_message( sprintf( _n( '%d API key permanently revoked.', '%d API keys permanently revoked.', $revoked, 'woocommerce' ), $revoked ) ); + } + } + + /** + * Revoke key. + */ + private function revoke_key() { + global $wpdb; + + check_admin_referer( 'revoke' ); + + if ( isset( $_REQUEST['revoke-key'] ) ) { // WPCS: input var okay, CSRF ok. + $key_id = absint( $_REQUEST['revoke-key'] ); // WPCS: input var okay, CSRF ok. + $user_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM {$wpdb->prefix}woocommerce_api_keys WHERE key_id = %d", $key_id ) ); + + if ( $key_id && $user_id && ( current_user_can( 'edit_user', $user_id ) || get_current_user_id() === $user_id ) ) { + $this->remove_key( $key_id ); + } else { + wp_die( esc_html__( 'You do not have permission to revoke this API Key', 'woocommerce' ) ); + } + } + + wp_safe_redirect( esc_url_raw( add_query_arg( array( 'revoked' => 1 ), admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=keys' ) ) ) ); + exit(); + } + + /** + * Bulk actions. + */ + private function bulk_actions() { + check_admin_referer( 'woocommerce-settings' ); + + if ( ! current_user_can( 'manage_woocommerce' ) ) { + wp_die( esc_html__( 'You do not have permission to edit API Keys', 'woocommerce' ) ); + } + + if ( isset( $_REQUEST['action'] ) ) { // WPCS: input var okay, CSRF ok. + $action = sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ); // WPCS: input var okay, CSRF ok. + $keys = isset( $_REQUEST['key'] ) ? array_map( 'absint', (array) $_REQUEST['key'] ) : array(); // WPCS: input var okay, CSRF ok. + + if ( 'revoke' === $action ) { + $this->bulk_revoke_key( $keys ); + } + } + } + + /** + * Bulk revoke key. + * + * @param array $keys API Keys. + */ + private function bulk_revoke_key( $keys ) { + if ( ! current_user_can( 'remove_users' ) ) { + wp_die( esc_html__( 'You do not have permission to revoke API Keys', 'woocommerce' ) ); + } + + $qty = 0; + foreach ( $keys as $key_id ) { + $result = $this->remove_key( $key_id ); + + if ( $result ) { + $qty++; + } + } + + // Redirect to webhooks page. + wp_safe_redirect( esc_url_raw( add_query_arg( array( 'revoked' => $qty ), admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=keys' ) ) ) ); + exit(); + } + + /** + * Remove key. + * + * @param int $key_id API Key ID. + * @return bool + */ + private function remove_key( $key_id ) { + global $wpdb; + + $delete = $wpdb->delete( $wpdb->prefix . 'woocommerce_api_keys', array( 'key_id' => $key_id ), array( '%d' ) ); + + return $delete; + } +} + +new WC_Admin_API_Keys(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-assets.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-assets.php new file mode 100644 index 0000000..567e2ef --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-assets.php @@ -0,0 +1,487 @@ +id : ''; + + // Register admin styles. + wp_register_style( 'woocommerce_admin_menu_styles', WC()->plugin_url() . '/assets/css/menu.css', array(), $version ); + wp_register_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), $version ); + wp_register_style( 'jquery-ui-style', WC()->plugin_url() . '/assets/css/jquery-ui/jquery-ui.min.css', array(), $version ); + wp_register_style( 'woocommerce_admin_dashboard_styles', WC()->plugin_url() . '/assets/css/dashboard.css', array(), $version ); + wp_register_style( 'woocommerce_admin_print_reports_styles', WC()->plugin_url() . '/assets/css/reports-print.css', array(), $version, 'print' ); + wp_register_style( 'woocommerce_admin_marketplace_styles', WC()->plugin_url() . '/assets/css/marketplace-suggestions.css', array(), $version ); + wp_register_style( 'woocommerce_admin_privacy_styles', WC()->plugin_url() . '/assets/css/privacy.css', array(), $version ); + + // Add RTL support for admin styles. + wp_style_add_data( 'woocommerce_admin_menu_styles', 'rtl', 'replace' ); + wp_style_add_data( 'woocommerce_admin_styles', 'rtl', 'replace' ); + wp_style_add_data( 'woocommerce_admin_dashboard_styles', 'rtl', 'replace' ); + wp_style_add_data( 'woocommerce_admin_print_reports_styles', 'rtl', 'replace' ); + wp_style_add_data( 'woocommerce_admin_marketplace_styles', 'rtl', 'replace' ); + wp_style_add_data( 'woocommerce_admin_privacy_styles', 'rtl', 'replace' ); + + // Sitewide menu CSS. + wp_enqueue_style( 'woocommerce_admin_menu_styles' ); + + // Admin styles for WC pages only. + if ( in_array( $screen_id, wc_get_screen_ids() ) ) { + wp_enqueue_style( 'woocommerce_admin_styles' ); + wp_enqueue_style( 'jquery-ui-style' ); + wp_enqueue_style( 'wp-color-picker' ); + } + + if ( in_array( $screen_id, array( 'dashboard' ) ) ) { + wp_enqueue_style( 'woocommerce_admin_dashboard_styles' ); + } + + if ( in_array( $screen_id, array( 'woocommerce_page_wc-reports', 'toplevel_page_wc-reports' ) ) ) { + wp_enqueue_style( 'woocommerce_admin_print_reports_styles' ); + } + + // Privacy Policy Guide css for back-compat. + if ( isset( $_GET['wp-privacy-policy-guide'] ) || in_array( $screen_id, array( 'privacy-policy-guide' ) ) ) { + wp_enqueue_style( 'woocommerce_admin_privacy_styles' ); + } + + // @deprecated 2.3. + if ( has_action( 'woocommerce_admin_css' ) ) { + do_action( 'woocommerce_admin_css' ); + wc_deprecated_function( 'The woocommerce_admin_css action', '2.3', 'admin_enqueue_scripts' ); + } + + if ( WC_Marketplace_Suggestions::show_suggestions_for_screen( $screen_id ) ) { + wp_enqueue_style( 'woocommerce_admin_marketplace_styles' ); + } + } + + + /** + * Enqueue scripts. + */ + public function admin_scripts() { + global $wp_query, $post; + + $screen = get_current_screen(); + $screen_id = $screen ? $screen->id : ''; + $wc_screen_id = sanitize_title( __( 'WooCommerce', 'woocommerce' ) ); + $suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min'; + $version = Constants::get_constant( 'WC_VERSION' ); + + // Register scripts. + wp_register_script( 'woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array( 'jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip' ), $version ); + wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70', true ); + wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array( 'jquery' ), $version, true ); + wp_register_script( 'round', WC()->plugin_url() . '/assets/js/round/round' . $suffix . '.js', array( 'jquery' ), $version ); + wp_register_script( 'wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable', 'jquery-tiptip' ), $version ); + wp_register_script( 'zeroclipboard', WC()->plugin_url() . '/assets/js/zeroclipboard/jquery.zeroclipboard' . $suffix . '.js', array( 'jquery' ), $version ); + wp_register_script( 'qrcode', WC()->plugin_url() . '/assets/js/jquery-qrcode/jquery.qrcode' . $suffix . '.js', array( 'jquery' ), $version ); + wp_register_script( 'stupidtable', WC()->plugin_url() . '/assets/js/stupidtable/stupidtable' . $suffix . '.js', array( 'jquery' ), $version ); + wp_register_script( 'serializejson', WC()->plugin_url() . '/assets/js/jquery-serializejson/jquery.serializejson' . $suffix . '.js', array( 'jquery' ), '2.8.1' ); + wp_register_script( 'flot', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot' . $suffix . '.js', array( 'jquery' ), $version ); + wp_register_script( 'flot-resize', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.resize' . $suffix . '.js', array( 'jquery', 'flot' ), $version ); + wp_register_script( 'flot-time', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.time' . $suffix . '.js', array( 'jquery', 'flot' ), $version ); + wp_register_script( 'flot-pie', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.pie' . $suffix . '.js', array( 'jquery', 'flot' ), $version ); + wp_register_script( 'flot-stack', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.stack' . $suffix . '.js', array( 'jquery', 'flot' ), $version ); + wp_register_script( 'wc-settings-tax', WC()->plugin_url() . '/assets/js/admin/settings-views-html-settings-tax' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-blockui' ), $version ); + wp_register_script( 'wc-backbone-modal', WC()->plugin_url() . '/assets/js/admin/backbone-modal' . $suffix . '.js', array( 'underscore', 'backbone', 'wp-util' ), $version ); + wp_register_script( 'wc-shipping-zones', WC()->plugin_url() . '/assets/js/admin/wc-shipping-zones' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable', 'wc-enhanced-select', 'wc-backbone-modal' ), $version ); + wp_register_script( 'wc-shipping-zone-methods', WC()->plugin_url() . '/assets/js/admin/wc-shipping-zone-methods' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable', 'wc-backbone-modal' ), $version ); + wp_register_script( 'wc-shipping-classes', WC()->plugin_url() . '/assets/js/admin/wc-shipping-classes' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone' ), $version ); + wp_register_script( 'wc-clipboard', WC()->plugin_url() . '/assets/js/admin/wc-clipboard' . $suffix . '.js', array( 'jquery' ), $version ); + wp_register_script( 'select2', WC()->plugin_url() . '/assets/js/select2/select2.full' . $suffix . '.js', array( 'jquery' ), '4.0.3' ); + wp_register_script( 'selectWoo', WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), '1.0.6' ); + wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), $version ); + wp_register_script( 'js-cookie', WC()->plugin_url() . '/assets/js/js-cookie/js.cookie' . $suffix . '.js', array(), '2.1.4', true ); + + wp_localize_script( + 'wc-enhanced-select', + 'wc_enhanced_select_params', + array( + 'i18n_no_matches' => _x( 'No matches found', 'enhanced select', 'woocommerce' ), + 'i18n_ajax_error' => _x( 'Loading failed', 'enhanced select', 'woocommerce' ), + 'i18n_input_too_short_1' => _x( 'Please enter 1 or more characters', 'enhanced select', 'woocommerce' ), + 'i18n_input_too_short_n' => _x( 'Please enter %qty% or more characters', 'enhanced select', 'woocommerce' ), + 'i18n_input_too_long_1' => _x( 'Please delete 1 character', 'enhanced select', 'woocommerce' ), + 'i18n_input_too_long_n' => _x( 'Please delete %qty% characters', 'enhanced select', 'woocommerce' ), + 'i18n_selection_too_long_1' => _x( 'You can only select 1 item', 'enhanced select', 'woocommerce' ), + 'i18n_selection_too_long_n' => _x( 'You can only select %qty% items', 'enhanced select', 'woocommerce' ), + 'i18n_load_more' => _x( 'Loading more results…', 'enhanced select', 'woocommerce' ), + 'i18n_searching' => _x( 'Searching…', 'enhanced select', 'woocommerce' ), + 'ajax_url' => admin_url( 'admin-ajax.php' ), + 'search_products_nonce' => wp_create_nonce( 'search-products' ), + 'search_customers_nonce' => wp_create_nonce( 'search-customers' ), + 'search_categories_nonce' => wp_create_nonce( 'search-categories' ), + ) + ); + + wp_register_script( 'accounting', WC()->plugin_url() . '/assets/js/accounting/accounting' . $suffix . '.js', array( 'jquery' ), '0.4.2' ); + wp_localize_script( + 'accounting', + 'accounting_params', + array( + 'mon_decimal_point' => wc_get_price_decimal_separator(), + ) + ); + + wp_register_script( 'wc-orders', WC()->plugin_url() . '/assets/js/admin/wc-orders' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-blockui' ), $version ); + wp_localize_script( + 'wc-orders', + 'wc_orders_params', + array( + 'ajax_url' => admin_url( 'admin-ajax.php' ), + 'preview_nonce' => wp_create_nonce( 'woocommerce-preview-order' ), + ) + ); + + // WooCommerce admin pages. + if ( in_array( $screen_id, wc_get_screen_ids() ) ) { + wp_enqueue_script( 'iris' ); + wp_enqueue_script( 'woocommerce_admin' ); + wp_enqueue_script( 'wc-enhanced-select' ); + wp_enqueue_script( 'jquery-ui-sortable' ); + wp_enqueue_script( 'jquery-ui-autocomplete' ); + + $locale = localeconv(); + $decimal = isset( $locale['decimal_point'] ) ? $locale['decimal_point'] : '.'; + + $params = array( + /* translators: %s: decimal */ + 'i18n_decimal_error' => sprintf( __( 'Please enter with one decimal point (%s) without thousand separators.', 'woocommerce' ), $decimal ), + /* translators: %s: price decimal separator */ + 'i18n_mon_decimal_error' => sprintf( __( 'Please enter with one monetary decimal point (%s) without thousand separators and currency symbols.', 'woocommerce' ), wc_get_price_decimal_separator() ), + 'i18n_country_iso_error' => __( 'Please enter in country code with two capital letters.', 'woocommerce' ), + 'i18n_sale_less_than_regular_error' => __( 'Please enter in a value less than the regular price.', 'woocommerce' ), + 'i18n_delete_product_notice' => __( 'This product has produced sales and may be linked to existing orders. Are you sure you want to delete it?', 'woocommerce' ), + 'i18n_remove_personal_data_notice' => __( 'This action cannot be reversed. Are you sure you wish to erase personal data from the selected orders?', 'woocommerce' ), + 'decimal_point' => $decimal, + 'mon_decimal_point' => wc_get_price_decimal_separator(), + 'ajax_url' => admin_url( 'admin-ajax.php' ), + 'strings' => array( + 'import_products' => __( 'Import', 'woocommerce' ), + 'export_products' => __( 'Export', 'woocommerce' ), + ), + 'nonces' => array( + 'gateway_toggle' => wp_create_nonce( 'woocommerce-toggle-payment-gateway-enabled' ), + ), + 'urls' => array( + 'import_products' => current_user_can( 'import' ) ? esc_url_raw( admin_url( 'edit.php?post_type=product&page=product_importer' ) ) : null, + 'export_products' => current_user_can( 'export' ) ? esc_url_raw( admin_url( 'edit.php?post_type=product&page=product_exporter' ) ) : null, + ), + ); + + wp_localize_script( 'woocommerce_admin', 'woocommerce_admin', $params ); + } + + // Edit product category pages. + if ( in_array( $screen_id, array( 'edit-product_cat' ) ) ) { + wp_enqueue_media(); + } + + // Products. + if ( in_array( $screen_id, array( 'edit-product' ) ) ) { + wp_enqueue_script( 'woocommerce_quick-edit', WC()->plugin_url() . '/assets/js/admin/quick-edit' . $suffix . '.js', array( 'jquery', 'woocommerce_admin' ), $version ); + + $params = array( + 'strings' => array( + 'allow_reviews' => esc_js( __( 'Enable reviews', 'woocommerce' ) ), + ), + ); + + wp_localize_script( 'woocommerce_quick-edit', 'woocommerce_quick_edit', $params ); + } + + // Meta boxes. + if ( in_array( $screen_id, array( 'product', 'edit-product' ) ) ) { + wp_enqueue_media(); + wp_register_script( 'wc-admin-product-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'media-models' ), $version ); + wp_register_script( 'wc-admin-variation-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product-variation' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'serializejson', 'media-models' ), $version ); + + wp_enqueue_script( 'wc-admin-product-meta-boxes' ); + wp_enqueue_script( 'wc-admin-variation-meta-boxes' ); + + $params = array( + 'post_id' => isset( $post->ID ) ? $post->ID : '', + 'plugin_url' => WC()->plugin_url(), + 'ajax_url' => admin_url( 'admin-ajax.php' ), + 'woocommerce_placeholder_img_src' => wc_placeholder_img_src(), + 'add_variation_nonce' => wp_create_nonce( 'add-variation' ), + 'link_variation_nonce' => wp_create_nonce( 'link-variations' ), + 'delete_variations_nonce' => wp_create_nonce( 'delete-variations' ), + 'load_variations_nonce' => wp_create_nonce( 'load-variations' ), + 'save_variations_nonce' => wp_create_nonce( 'save-variations' ), + 'bulk_edit_variations_nonce' => wp_create_nonce( 'bulk-edit-variations' ), + /* translators: %d: Number of variations */ + 'i18n_link_all_variations' => esc_js( sprintf( __( 'Are you sure you want to link all variations? This will create a new variation for each and every possible combination of variation attributes (max %d per run).', 'woocommerce' ), Constants::is_defined( 'WC_MAX_LINKED_VARIATIONS' ) ? Constants::get_constant( 'WC_MAX_LINKED_VARIATIONS' ) : 50 ) ), + 'i18n_enter_a_value' => esc_js( __( 'Enter a value', 'woocommerce' ) ), + 'i18n_enter_menu_order' => esc_js( __( 'Variation menu order (determines position in the list of variations)', 'woocommerce' ) ), + 'i18n_enter_a_value_fixed_or_percent' => esc_js( __( 'Enter a value (fixed or %)', 'woocommerce' ) ), + 'i18n_delete_all_variations' => esc_js( __( 'Are you sure you want to delete all variations? This cannot be undone.', 'woocommerce' ) ), + 'i18n_last_warning' => esc_js( __( 'Last warning, are you sure?', 'woocommerce' ) ), + 'i18n_choose_image' => esc_js( __( 'Choose an image', 'woocommerce' ) ), + 'i18n_set_image' => esc_js( __( 'Set variation image', 'woocommerce' ) ), + 'i18n_variation_added' => esc_js( __( 'variation added', 'woocommerce' ) ), + 'i18n_variations_added' => esc_js( __( 'variations added', 'woocommerce' ) ), + 'i18n_no_variations_added' => esc_js( __( 'No variations added', 'woocommerce' ) ), + 'i18n_remove_variation' => esc_js( __( 'Are you sure you want to remove this variation?', 'woocommerce' ) ), + 'i18n_scheduled_sale_start' => esc_js( __( 'Sale start date (YYYY-MM-DD format or leave blank)', 'woocommerce' ) ), + 'i18n_scheduled_sale_end' => esc_js( __( 'Sale end date (YYYY-MM-DD format or leave blank)', 'woocommerce' ) ), + 'i18n_edited_variations' => esc_js( __( 'Save changes before changing page?', 'woocommerce' ) ), + 'i18n_variation_count_single' => esc_js( __( '%qty% variation', 'woocommerce' ) ), + 'i18n_variation_count_plural' => esc_js( __( '%qty% variations', 'woocommerce' ) ), + 'variations_per_page' => absint( apply_filters( 'woocommerce_admin_meta_boxes_variations_per_page', 15 ) ), + ); + + wp_localize_script( 'wc-admin-variation-meta-boxes', 'woocommerce_admin_meta_boxes_variations', $params ); + } + if ( in_array( str_replace( 'edit-', '', $screen_id ), wc_get_order_types( 'order-meta-boxes' ) ) ) { + $default_location = wc_get_customer_default_location(); + + wp_enqueue_script( 'wc-admin-order-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-order' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'wc-backbone-modal', 'selectWoo', 'wc-clipboard' ), $version ); + wp_localize_script( + 'wc-admin-order-meta-boxes', + 'woocommerce_admin_meta_boxes_order', + array( + 'countries' => wp_json_encode( array_merge( WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states() ) ), + 'i18n_select_state_text' => esc_attr__( 'Select an option…', 'woocommerce' ), + 'default_country' => isset( $default_location['country'] ) ? $default_location['country'] : '', + 'default_state' => isset( $default_location['state'] ) ? $default_location['state'] : '', + 'placeholder_name' => esc_attr__( 'Name (required)', 'woocommerce' ), + 'placeholder_value' => esc_attr__( 'Value (required)', 'woocommerce' ), + ) + ); + } + if ( in_array( $screen_id, array( 'shop_coupon', 'edit-shop_coupon' ) ) ) { + wp_enqueue_script( 'wc-admin-coupon-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-coupon' . $suffix . '.js', array( 'wc-admin-meta-boxes' ), $version ); + wp_localize_script( + 'wc-admin-coupon-meta-boxes', + 'woocommerce_admin_meta_boxes_coupon', + array( + 'generate_button_text' => esc_html__( 'Generate coupon code', 'woocommerce' ), + 'characters' => apply_filters( 'woocommerce_coupon_code_generator_characters', 'ABCDEFGHJKMNPQRSTUVWXYZ23456789' ), + 'char_length' => apply_filters( 'woocommerce_coupon_code_generator_character_length', 8 ), + 'prefix' => apply_filters( 'woocommerce_coupon_code_generator_prefix', '' ), + 'suffix' => apply_filters( 'woocommerce_coupon_code_generator_suffix', '' ), + ) + ); + } + if ( in_array( str_replace( 'edit-', '', $screen_id ), array_merge( array( 'shop_coupon', 'product' ), wc_get_order_types( 'order-meta-boxes' ) ) ) ) { + $post_id = isset( $post->ID ) ? $post->ID : ''; + $currency = ''; + $remove_item_notice = __( 'Are you sure you want to remove the selected items?', 'woocommerce' ); + + if ( $post_id && in_array( get_post_type( $post_id ), wc_get_order_types( 'order-meta-boxes' ) ) ) { + $order = wc_get_order( $post_id ); + if ( $order ) { + $currency = $order->get_currency(); + + if ( ! $order->has_status( array( 'pending', 'failed', 'cancelled' ) ) ) { + $remove_item_notice = $remove_item_notice . ' ' . __( "You may need to manually restore the item's stock.", 'woocommerce' ); + } + } + } + + $params = array( + 'remove_item_notice' => $remove_item_notice, + 'i18n_select_items' => __( 'Please select some items.', 'woocommerce' ), + 'i18n_do_refund' => __( 'Are you sure you wish to process this refund? This action cannot be undone.', 'woocommerce' ), + 'i18n_delete_refund' => __( 'Are you sure you wish to delete this refund? This action cannot be undone.', 'woocommerce' ), + 'i18n_delete_tax' => __( 'Are you sure you wish to delete this tax column? This action cannot be undone.', 'woocommerce' ), + 'remove_item_meta' => __( 'Remove this item meta?', 'woocommerce' ), + 'remove_attribute' => __( 'Remove this attribute?', 'woocommerce' ), + 'name_label' => __( 'Name', 'woocommerce' ), + 'remove_label' => __( 'Remove', 'woocommerce' ), + 'click_to_toggle' => __( 'Click to toggle', 'woocommerce' ), + 'values_label' => __( 'Value(s)', 'woocommerce' ), + 'text_attribute_tip' => __( 'Enter some text, or some attributes by pipe (|) separating values.', 'woocommerce' ), + 'visible_label' => __( 'Visible on the product page', 'woocommerce' ), + 'used_for_variations_label' => __( 'Used for variations', 'woocommerce' ), + 'new_attribute_prompt' => __( 'Enter a name for the new attribute term:', 'woocommerce' ), + 'calc_totals' => __( 'Recalculate totals? This will calculate taxes based on the customers country (or the store base country) and update totals.', 'woocommerce' ), + 'copy_billing' => __( 'Copy billing information to shipping information? This will remove any currently entered shipping information.', 'woocommerce' ), + 'load_billing' => __( "Load the customer's billing information? This will remove any currently entered billing information.", 'woocommerce' ), + 'load_shipping' => __( "Load the customer's shipping information? This will remove any currently entered shipping information.", 'woocommerce' ), + 'featured_label' => __( 'Featured', 'woocommerce' ), + 'prices_include_tax' => esc_attr( get_option( 'woocommerce_prices_include_tax' ) ), + 'tax_based_on' => esc_attr( get_option( 'woocommerce_tax_based_on' ) ), + 'round_at_subtotal' => esc_attr( get_option( 'woocommerce_tax_round_at_subtotal' ) ), + 'no_customer_selected' => __( 'No customer selected', 'woocommerce' ), + 'plugin_url' => WC()->plugin_url(), + 'ajax_url' => admin_url( 'admin-ajax.php' ), + 'order_item_nonce' => wp_create_nonce( 'order-item' ), + 'add_attribute_nonce' => wp_create_nonce( 'add-attribute' ), + 'save_attributes_nonce' => wp_create_nonce( 'save-attributes' ), + 'calc_totals_nonce' => wp_create_nonce( 'calc-totals' ), + 'get_customer_details_nonce' => wp_create_nonce( 'get-customer-details' ), + 'search_products_nonce' => wp_create_nonce( 'search-products' ), + 'grant_access_nonce' => wp_create_nonce( 'grant-access' ), + 'revoke_access_nonce' => wp_create_nonce( 'revoke-access' ), + 'add_order_note_nonce' => wp_create_nonce( 'add-order-note' ), + 'delete_order_note_nonce' => wp_create_nonce( 'delete-order-note' ), + 'calendar_image' => WC()->plugin_url() . '/assets/images/calendar.png', + 'post_id' => isset( $post->ID ) ? $post->ID : '', + 'base_country' => WC()->countries->get_base_country(), + 'currency_format_num_decimals' => wc_get_price_decimals(), + 'currency_format_symbol' => get_woocommerce_currency_symbol( $currency ), + 'currency_format_decimal_sep' => esc_attr( wc_get_price_decimal_separator() ), + 'currency_format_thousand_sep' => esc_attr( wc_get_price_thousand_separator() ), + 'currency_format' => esc_attr( str_replace( array( '%1$s', '%2$s' ), array( '%s', '%v' ), get_woocommerce_price_format() ) ), // For accounting JS. + 'rounding_precision' => wc_get_rounding_precision(), + 'tax_rounding_mode' => wc_get_tax_rounding_mode(), + 'product_types' => array_unique( array_merge( array( 'simple', 'grouped', 'variable', 'external' ), array_keys( wc_get_product_types() ) ) ), + 'i18n_download_permission_fail' => __( 'Could not grant access - the user may already have permission for this file or billing email is not set. Ensure the billing email is set, and the order has been saved.', 'woocommerce' ), + 'i18n_permission_revoke' => __( 'Are you sure you want to revoke access to this download?', 'woocommerce' ), + 'i18n_tax_rate_already_exists' => __( 'You cannot add the same tax rate twice!', 'woocommerce' ), + 'i18n_delete_note' => __( 'Are you sure you wish to delete this note? This action cannot be undone.', 'woocommerce' ), + 'i18n_apply_coupon' => __( 'Enter a coupon code to apply. Discounts are applied to line totals, before taxes.', 'woocommerce' ), + 'i18n_add_fee' => __( 'Enter a fixed amount or percentage to apply as a fee.', 'woocommerce' ), + ); + + wp_localize_script( 'wc-admin-meta-boxes', 'woocommerce_admin_meta_boxes', $params ); + } + + // Term ordering - only when sorting by term_order. + if ( ( strstr( $screen_id, 'edit-pa_' ) || ( ! empty( $_GET['taxonomy'] ) && in_array( wp_unslash( $_GET['taxonomy'] ), apply_filters( 'woocommerce_sortable_taxonomies', array( 'product_cat' ) ) ) ) ) && ! isset( $_GET['orderby'] ) ) { + + wp_register_script( 'woocommerce_term_ordering', WC()->plugin_url() . '/assets/js/admin/term-ordering' . $suffix . '.js', array( 'jquery-ui-sortable' ), $version ); + wp_enqueue_script( 'woocommerce_term_ordering' ); + + $taxonomy = isset( $_GET['taxonomy'] ) ? wc_clean( wp_unslash( $_GET['taxonomy'] ) ) : ''; + + $woocommerce_term_order_params = array( + 'taxonomy' => $taxonomy, + ); + + wp_localize_script( 'woocommerce_term_ordering', 'woocommerce_term_ordering_params', $woocommerce_term_order_params ); + } + + // Product sorting - only when sorting by menu order on the products page. + if ( current_user_can( 'edit_others_pages' ) && 'edit-product' === $screen_id && isset( $wp_query->query['orderby'] ) && 'menu_order title' === $wp_query->query['orderby'] ) { + wp_register_script( 'woocommerce_product_ordering', WC()->plugin_url() . '/assets/js/admin/product-ordering' . $suffix . '.js', array( 'jquery-ui-sortable' ), $version, true ); + wp_enqueue_script( 'woocommerce_product_ordering' ); + } + + // Reports Pages. + if ( in_array( $screen_id, apply_filters( 'woocommerce_reports_screen_ids', array( $wc_screen_id . '_page_wc-reports', 'toplevel_page_wc-reports', 'dashboard' ) ) ) ) { + wp_register_script( 'wc-reports', WC()->plugin_url() . '/assets/js/admin/reports' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker' ), $version ); + + wp_enqueue_script( 'wc-reports' ); + wp_enqueue_script( 'flot' ); + wp_enqueue_script( 'flot-resize' ); + wp_enqueue_script( 'flot-time' ); + wp_enqueue_script( 'flot-pie' ); + wp_enqueue_script( 'flot-stack' ); + } + + // API settings. + if ( $wc_screen_id . '_page_wc-settings' === $screen_id && isset( $_GET['section'] ) && 'keys' == $_GET['section'] ) { + wp_register_script( 'wc-api-keys', WC()->plugin_url() . '/assets/js/admin/api-keys' . $suffix . '.js', array( 'jquery', 'woocommerce_admin', 'underscore', 'backbone', 'wp-util', 'qrcode', 'wc-clipboard' ), $version, true ); + wp_enqueue_script( 'wc-api-keys' ); + wp_localize_script( + 'wc-api-keys', + 'woocommerce_admin_api_keys', + array( + 'ajax_url' => admin_url( 'admin-ajax.php' ), + 'update_api_nonce' => wp_create_nonce( 'update-api-key' ), + 'clipboard_failed' => esc_html__( 'Copying to clipboard failed. Please press Ctrl/Cmd+C to copy.', 'woocommerce' ), + ) + ); + } + + // System status. + if ( $wc_screen_id . '_page_wc-status' === $screen_id ) { + wp_register_script( 'wc-admin-system-status', WC()->plugin_url() . '/assets/js/admin/system-status' . $suffix . '.js', array( 'wc-clipboard' ), $version ); + wp_enqueue_script( 'wc-admin-system-status' ); + wp_localize_script( + 'wc-admin-system-status', + 'woocommerce_admin_system_status', + array( + 'delete_log_confirmation' => esc_js( __( 'Are you sure you want to delete this log?', 'woocommerce' ) ), + 'run_tool_confirmation' => esc_js( __( 'Are you sure you want to run this tool?', 'woocommerce' ) ), + ) + ); + } + + if ( in_array( $screen_id, array( 'user-edit', 'profile' ) ) ) { + wp_register_script( 'wc-users', WC()->plugin_url() . '/assets/js/admin/users' . $suffix . '.js', array( 'jquery', 'wc-enhanced-select', 'selectWoo' ), $version, true ); + wp_enqueue_script( 'wc-users' ); + wp_localize_script( + 'wc-users', + 'wc_users_params', + array( + 'countries' => wp_json_encode( array_merge( WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states() ) ), + 'i18n_select_state_text' => esc_attr__( 'Select an option…', 'woocommerce' ), + ) + ); + } + + if ( WC_Marketplace_Suggestions::show_suggestions_for_screen( $screen_id ) ) { + $active_plugin_slugs = array_map( 'dirname', get_option( 'active_plugins' ) ); + wp_register_script( + 'marketplace-suggestions', + WC()->plugin_url() . '/assets/js/admin/marketplace-suggestions' . $suffix . '.js', + array( 'jquery', 'underscore', 'js-cookie' ), + $version, + true + ); + wp_localize_script( + 'marketplace-suggestions', + 'marketplace_suggestions', + array( + 'dismiss_suggestion_nonce' => wp_create_nonce( 'add_dismissed_marketplace_suggestion' ), + 'active_plugins' => $active_plugin_slugs, + 'dismissed_suggestions' => WC_Marketplace_Suggestions::get_dismissed_suggestions(), + 'suggestions_data' => WC_Marketplace_Suggestions::get_suggestions_api_data(), + 'manage_suggestions_url' => admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=woocommerce_com' ), + 'in_app_purchase_params' => WC_Admin_Addons::get_in_app_purchase_url_params(), + 'i18n_marketplace_suggestions_default_cta' + => esc_html__( 'Learn More', 'woocommerce' ), + 'i18n_marketplace_suggestions_dismiss_tooltip' + => esc_attr__( 'Dismiss this suggestion', 'woocommerce' ), + 'i18n_marketplace_suggestions_manage_suggestions' + => esc_html__( 'Manage suggestions', 'woocommerce' ), + ) + ); + wp_enqueue_script( 'marketplace-suggestions' ); + } + + } + + } + +endif; + +return new WC_Admin_Assets(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-attributes.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-attributes.php new file mode 100644 index 0000000..9dc884f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-attributes.php @@ -0,0 +1,477 @@ +

    ' . wp_kses_post( $result->get_error_message() ) . '

    '; + } + + // Show admin interface. + if ( ! empty( $_GET['edit'] ) ) { + self::edit_attribute(); + } else { + self::add_attribute(); + } + } + + /** + * Get and sanitize posted attribute data. + * + * @return array + */ + private static function get_posted_attribute() { + $attribute = array( + 'attribute_label' => isset( $_POST['attribute_label'] ) ? wc_clean( wp_unslash( $_POST['attribute_label'] ) ) : '', // WPCS: input var ok, CSRF ok. + 'attribute_name' => isset( $_POST['attribute_name'] ) ? wc_sanitize_taxonomy_name( wp_unslash( $_POST['attribute_name'] ) ) : '', // WPCS: input var ok, CSRF ok, sanitization ok. + 'attribute_type' => isset( $_POST['attribute_type'] ) ? wc_clean( wp_unslash( $_POST['attribute_type'] ) ) : 'select', // WPCS: input var ok, CSRF ok. + 'attribute_orderby' => isset( $_POST['attribute_orderby'] ) ? wc_clean( wp_unslash( $_POST['attribute_orderby'] ) ) : '', // WPCS: input var ok, CSRF ok. + 'attribute_public' => isset( $_POST['attribute_public'] ) ? 1 : 0, // WPCS: input var ok, CSRF ok. + ); + + if ( empty( $attribute['attribute_type'] ) ) { + $attribute['attribute_type'] = 'select'; + } + if ( empty( $attribute['attribute_label'] ) ) { + $attribute['attribute_label'] = ucfirst( $attribute['attribute_name'] ); + } + if ( empty( $attribute['attribute_name'] ) ) { + $attribute['attribute_name'] = wc_sanitize_taxonomy_name( $attribute['attribute_label'] ); + } + + return $attribute; + } + + /** + * Add an attribute. + * + * @return bool|WP_Error + */ + private static function process_add_attribute() { + check_admin_referer( 'woocommerce-add-new_attribute' ); + + $attribute = self::get_posted_attribute(); + $args = array( + 'name' => $attribute['attribute_label'], + 'slug' => $attribute['attribute_name'], + 'type' => $attribute['attribute_type'], + 'order_by' => $attribute['attribute_orderby'], + 'has_archives' => $attribute['attribute_public'], + ); + + $id = wc_create_attribute( $args ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + return true; + } + + /** + * Edit an attribute. + * + * @return bool|WP_Error + */ + private static function process_edit_attribute() { + $attribute_id = isset( $_GET['edit'] ) ? absint( $_GET['edit'] ) : 0; + check_admin_referer( 'woocommerce-save-attribute_' . $attribute_id ); + + $attribute = self::get_posted_attribute(); + $args = array( + 'name' => $attribute['attribute_label'], + 'slug' => $attribute['attribute_name'], + 'type' => $attribute['attribute_type'], + 'order_by' => $attribute['attribute_orderby'], + 'has_archives' => $attribute['attribute_public'], + ); + + $id = wc_update_attribute( $attribute_id, $args ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + self::$edited_attribute_id = $id; + + return true; + } + + /** + * Delete an attribute. + * + * @return bool + */ + private static function process_delete_attribute() { + $attribute_id = isset( $_GET['delete'] ) ? absint( $_GET['delete'] ) : 0; + check_admin_referer( 'woocommerce-delete-attribute_' . $attribute_id ); + + return wc_delete_attribute( $attribute_id ); + } + + /** + * Edit Attribute admin panel. + * + * Shows the interface for changing an attributes type between select and text. + */ + public static function edit_attribute() { + global $wpdb; + + $edit = isset( $_GET['edit'] ) ? absint( $_GET['edit'] ) : 0; + + $attribute_to_edit = $wpdb->get_row( + $wpdb->prepare( + " + SELECT attribute_type, attribute_label, attribute_name, attribute_orderby, attribute_public + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = %d + ", + $edit + ) + ); + + ?> +
    +

    + +

    ' . esc_html__( 'Error: non-existing attribute ID.', 'woocommerce' ) . '

    '; + } else { + if ( self::$edited_attribute_id > 0 ) { + echo '

    ' . esc_html__( 'Attribute updated successfully', 'woocommerce' ) . '

    ' . esc_html__( 'Back to Attributes', 'woocommerce' ) . '

    '; + self::$edited_attribute_id = null; + } + $att_type = $attribute_to_edit->attribute_type; + $att_label = format_to_edit( $attribute_to_edit->attribute_label ); + $att_name = $attribute_to_edit->attribute_name; + $att_orderby = $attribute_to_edit->attribute_orderby; + $att_public = $attribute_to_edit->attribute_public; + ?> +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +

    +
    + + + +

    +
    + + + /> +

    +
    + + + +

    +
    + + + +

    +
    +

    + +
    + + + +
    +

    + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + attribute_label ); ?> + +
    |
    +
    attribute_name ); ?>attribute_type ) ); ?> attribute_public ? esc_html__( '(Public)', 'woocommerce' ) : ''; ?> + attribute_orderby ) { + case 'name': + esc_html_e( 'Name', 'woocommerce' ); + break; + case 'name_num': + esc_html_e( 'Name (numeric)', 'woocommerce' ); + break; + case 'id': + esc_html_e( 'Term ID', 'woocommerce' ); + break; + default: + esc_html_e( 'Custom ordering', 'woocommerce' ); + break; + } + ?> + + attribute_name ); + + if ( taxonomy_exists( $taxonomy ) ) { + $terms = get_terms( $taxonomy, 'hide_empty=0' ); + $terms_string = implode( ', ', wp_list_pluck( $terms, 'name' ) ); + if ( $terms_string ) { + echo esc_html( $terms_string ); + } else { + echo ''; + } + } else { + echo ''; + } + ?> +
    +
    +
    +
    +
    +
    +
    +

    +

    +
    + + +
    + + +

    +
    + +
    + + +

    +
    + +
    + + +

    +
    + + +
    + + +

    +
    + + +
    + + +

    +
    + + + +

    + +
    +
    +
    +
    +
    + +
    + __( 'WooCommerce Endpoints', 'woocommerce' ), + 'type_label' => __( 'WooCommerce Endpoint', 'woocommerce' ), + 'type' => 'woocommerce_nav', + 'object' => 'woocommerce_endpoint', + ); + + return $item_types; + } + + /** + * Register account endpoints to customize nav menu items. + * + * @since 3.1.0 + * @param array $items List of nav menu items. + * @param string $type Nav menu type. + * @param string $object Nav menu object. + * @param integer $page Page number. + * @return array + */ + public function register_customize_nav_menu_items( $items = array(), $type = '', $object = '', $page = 0 ) { + if ( 'woocommerce_endpoint' !== $object ) { + return $items; + } + + // Don't allow pagination since all items are loaded at once. + if ( 0 < $page ) { + return $items; + } + + // Get items from account menu. + $endpoints = wc_get_account_menu_items(); + + // Remove dashboard item. + if ( isset( $endpoints['dashboard'] ) ) { + unset( $endpoints['dashboard'] ); + } + + // Include missing lost password. + $endpoints['lost-password'] = __( 'Lost password', 'woocommerce' ); + + $endpoints = apply_filters( 'woocommerce_custom_nav_menu_items', $endpoints ); + + foreach ( $endpoints as $endpoint => $title ) { + $items[] = array( + 'id' => $endpoint, + 'title' => $title, + 'type_label' => __( 'Custom Link', 'woocommerce' ), + 'url' => esc_url_raw( wc_get_account_endpoint_url( $endpoint ) ), + ); + } + + return $items; + } + } + +endif; + +return new WC_Admin_Customize(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-dashboard.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-dashboard.php new file mode 100644 index 0000000..6f3435f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-dashboard.php @@ -0,0 +1,423 @@ +register_network_order_widget(); + } + } + + /** + * Register the network order dashboard widget. + */ + public function register_network_order_widget() { + wp_add_dashboard_widget( 'woocommerce_network_orders', __( 'WooCommerce Network Orders', 'woocommerce' ), array( $this, 'network_orders' ) ); + } + + /** + * Get top seller from DB. + * + * @return object + */ + private function get_top_seller() { + global $wpdb; + + $query = array(); + $query['fields'] = "SELECT SUM( order_item_meta.meta_value ) as qty, order_item_meta_2.meta_value as product_id + FROM {$wpdb->posts} as posts"; + $query['join'] = "INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON posts.ID = order_id "; + $query['join'] .= "INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id "; + $query['join'] .= "INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta_2 ON order_items.order_item_id = order_item_meta_2.order_item_id "; + $query['where'] = "WHERE posts.post_type IN ( '" . implode( "','", wc_get_order_types( 'order-count' ) ) . "' ) "; + $query['where'] .= "AND posts.post_status IN ( 'wc-" . implode( "','wc-", apply_filters( 'woocommerce_reports_order_statuses', array( 'completed', 'processing', 'on-hold' ) ) ) . "' ) "; + $query['where'] .= "AND order_item_meta.meta_key = '_qty' "; + $query['where'] .= "AND order_item_meta_2.meta_key = '_product_id' "; + $query['where'] .= "AND posts.post_date >= '" . gmdate( 'Y-m-01', current_time( 'timestamp' ) ) . "' "; + $query['where'] .= "AND posts.post_date <= '" . gmdate( 'Y-m-d H:i:s', current_time( 'timestamp' ) ) . "' "; + $query['groupby'] = 'GROUP BY product_id'; + $query['orderby'] = 'ORDER BY qty DESC'; + $query['limits'] = 'LIMIT 1'; + + return $wpdb->get_row( implode( ' ', apply_filters( 'woocommerce_dashboard_status_widget_top_seller_query', $query ) ) ); //phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + } + + /** + * Get sales report data. + * + * @return object + */ + private function get_sales_report_data() { + include_once dirname( __FILE__ ) . '/reports/class-wc-report-sales-by-date.php'; + + $sales_by_date = new WC_Report_Sales_By_Date(); + $sales_by_date->start_date = strtotime( gmdate( 'Y-m-01', current_time( 'timestamp' ) ) ); + $sales_by_date->end_date = strtotime( gmdate( 'Y-m-d', current_time( 'timestamp' ) ) ); + $sales_by_date->chart_groupby = 'day'; + $sales_by_date->group_by_query = 'YEAR(posts.post_date), MONTH(posts.post_date), DAY(posts.post_date)'; + + return $sales_by_date->get_report_data(); + } + + /** + * Show status widget. + */ + public function status_widget() { + include_once dirname( __FILE__ ) . '/reports/class-wc-admin-report.php'; + + $reports = new WC_Admin_Report(); + + echo ''; + } + + /** + * Show order data is status widget. + */ + private function status_widget_order_rows() { + if ( ! current_user_can( 'edit_shop_orders' ) ) { + return; + } + $on_hold_count = 0; + $processing_count = 0; + + foreach ( wc_get_order_types( 'order-count' ) as $type ) { + $counts = (array) wp_count_posts( $type ); + $on_hold_count += isset( $counts['wc-on-hold'] ) ? $counts['wc-on-hold'] : 0; + $processing_count += isset( $counts['wc-processing'] ) ? $counts['wc-processing'] : 0; + } + ?> +
  • + + %s order awaiting processing', '%s orders awaiting processing', $processing_count, 'woocommerce' ), + $processing_count + ); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + ?> + +
  • +
  • + + %s order on-hold', '%s orders on-hold', $on_hold_count, 'woocommerce' ), + $on_hold_count + ); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + ?> + +
  • + get_var( + $wpdb->prepare( + "SELECT COUNT( product_id ) + FROM {$wpdb->wc_product_meta_lookup} AS lookup + INNER JOIN {$wpdb->posts} as posts ON lookup.product_id = posts.ID + WHERE stock_quantity <= %d + AND stock_quantity > %d + AND posts.post_status = 'publish'", + $stock, + $nostock + ) + ); + } + + set_transient( $transient_name, (int) $lowinstock_count, DAY_IN_SECONDS * 30 ); + } + + $transient_name = 'wc_outofstock_count'; + $outofstock_count = get_transient( $transient_name ); + + if ( false === $outofstock_count ) { + /** + * Status widget out of stock count pre query. + * + * @since 4.3.0 + * @param null|string $outofstock_count Out of stock count, by default null. + * @param int $nostock No stock amount + */ + $outofstock_count = apply_filters( 'woocommerce_status_widget_out_of_stock_count_pre_query', null, $nostock ); + + if ( is_null( $outofstock_count ) ) { + $outofstock_count = (int) $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT( product_id ) + FROM {$wpdb->wc_product_meta_lookup} AS lookup + INNER JOIN {$wpdb->posts} as posts ON lookup.product_id = posts.ID + WHERE stock_quantity <= %d + AND posts.post_status = 'publish'", + $nostock + ) + ); + } + + set_transient( $transient_name, (int) $outofstock_count, DAY_IN_SECONDS * 30 ); + } + ?> +
  • + + %s product low in stock', '%s products low in stock', $lowinstock_count, 'woocommerce' ), + $lowinstock_count + ); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + ?> + +
  • +
  • + + %s product out of stock', '%s products out of stock', $outofstock_count, 'woocommerce' ), + $outofstock_count + ); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + ?> + +
  • + comments} comments + LEFT JOIN {$wpdb->posts} posts ON (comments.comment_post_ID = posts.ID) + WHERE comments.comment_approved = '1' + AND comments.comment_type = 'review' + AND posts.post_password = '' + AND posts.post_type = 'product' + AND comments.comment_parent = 0 + ORDER BY comments.comment_date_gmt DESC + LIMIT 5" + ); + + $comments = $wpdb->get_results( + "SELECT posts.ID, posts.post_title, comments.comment_author, comments.comment_author_email, comments.comment_ID, comments.comment_content {$query_from};" // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared + ); + + if ( $comments ) { + echo '
      '; + foreach ( $comments as $comment ) { + + echo '
    • '; + + echo get_avatar( $comment->comment_author_email, '32' ); + + $rating = intval( get_comment_meta( $comment->comment_ID, 'rating', true ) ); + + /* translators: %s: rating */ + echo '
      ' . sprintf( esc_html__( '%s out of 5', 'woocommerce' ), esc_html( $rating ) ) . '
      '; + + /* translators: %s: review author */ + echo '

      ' . esc_html( apply_filters( 'woocommerce_admin_dashboard_recent_reviews', $comment->post_title, $comment ) ) . ' ' . sprintf( esc_html__( 'reviewed by %s', 'woocommerce' ), esc_html( $comment->comment_author ) ) . '

      '; + echo '
      ' . wp_kses_data( $comment->comment_content ) . '
    • '; + + } + echo '
    '; + } else { + echo '

    ' . esc_html__( 'There are no product reviews yet.', 'woocommerce' ) . '

    '; + } + } + + /** + * Network orders widget. + */ + public function network_orders() { + $suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min'; + $version = Constants::get_constant( 'WC_VERSION' ); + + wp_enqueue_style( 'wc-network-orders', WC()->plugin_url() . '/assets/css/network-order-widget.css', array(), $version ); + + wp_enqueue_script( 'wc-network-orders', WC()->plugin_url() . '/assets/js/admin/network-orders' . $suffix . '.js', array( 'jquery', 'underscore' ), $version, true ); + + $user = wp_get_current_user(); + $blogs = get_blogs_of_user( $user->ID ); + $blog_ids = wp_list_pluck( $blogs, 'userblog_id' ); + + wp_localize_script( + 'wc-network-orders', + 'woocommerce_network_orders', + array( + 'nonce' => wp_create_nonce( 'wp_rest' ), + 'sites' => array_values( $blog_ids ), + 'order_endpoint' => get_rest_url( null, 'wc/v3/orders/network' ), + ) + ); + ?> +
    +
    +

    + +

    + +
    + + + + + + + + + + + +
    +
    +

    + +

    +
    + + + +
    + post_type ) { + return $actions; + } + + // Add Class to Delete Permanently link in row actions. + if ( empty( $the_product ) || $the_product->get_id() !== $post->ID ) { + $the_product = wc_get_product( $post ); + } + + if ( 'publish' === $post->post_status && $the_product && 0 < $the_product->get_total_sales() ) { + $actions['trash'] = sprintf( + '%s', + get_delete_post_link( $the_product->get_id(), '', false ), + /* translators: %s: post title */ + esc_attr( sprintf( __( 'Move “%s” to the Trash', 'woocommerce' ), $the_product->get_name() ) ), + esc_html__( 'Trash', 'woocommerce' ) + ); + } + + $actions['duplicate'] = '' . esc_html__( 'Duplicate', 'woocommerce' ) . ''; + + return $actions; + } + + /** + * Show the dupe product link in admin. + */ + public function dupe_button() { + global $post; + + if ( ! current_user_can( apply_filters( 'woocommerce_duplicate_product_capability', 'manage_woocommerce' ) ) ) { + return; + } + + if ( ! is_object( $post ) ) { + return; + } + + if ( 'product' !== $post->post_type ) { + return; + } + + $notify_url = wp_nonce_url( admin_url( 'edit.php?post_type=product&action=duplicate_product&post=' . absint( $post->ID ) ), 'woocommerce-duplicate-product_' . $post->ID ); + ?> +
    + product_duplicate( $product ); + + // Hook rename to match other woocommerce_product_* hooks, and to move away from depending on a response from the wp_posts table. + do_action( 'woocommerce_product_duplicate', $duplicate, $product ); + wc_do_deprecated_action( 'woocommerce_duplicate_product', array( $duplicate->get_id(), $this->get_product_to_duplicate( $product_id ) ), '3.0', 'Use woocommerce_product_duplicate action instead.' ); + + // Redirect to the edit screen for the new draft page. + wp_redirect( admin_url( 'post.php?action=edit&post=' . $duplicate->get_id() ) ); + exit; + } + + /** + * Function to create the duplicate of the product. + * + * @param WC_Product $product The product to duplicate. + * @return WC_Product The duplicate. + */ + public function product_duplicate( $product ) { + /** + * Filter to allow us to exclude meta keys from product duplication.. + * + * @param array $exclude_meta The keys to exclude from the duplicate. + * @param array $existing_meta_keys The meta keys that the product already has. + * @since 2.6 + */ + $meta_to_exclude = array_filter( + apply_filters( + 'woocommerce_duplicate_product_exclude_meta', + array(), + array_map( + function ( $datum ) { + return $datum->key; + }, + $product->get_meta_data() + ) + ) + ); + + $duplicate = clone $product; + $duplicate->set_id( 0 ); + /* translators: %s contains the name of the original product. */ + $duplicate->set_name( sprintf( esc_html__( '%s (Copy)', 'woocommerce' ), $duplicate->get_name() ) ); + $duplicate->set_total_sales( 0 ); + if ( '' !== $product->get_sku( 'edit' ) ) { + $duplicate->set_sku( wc_product_generate_unique_sku( 0, $product->get_sku( 'edit' ) ) ); + } + $duplicate->set_status( 'draft' ); + $duplicate->set_date_created( null ); + $duplicate->set_slug( '' ); + $duplicate->set_rating_counts( 0 ); + $duplicate->set_average_rating( 0 ); + $duplicate->set_review_count( 0 ); + + foreach ( $meta_to_exclude as $meta_key ) { + $duplicate->delete_meta_data( $meta_key ); + } + + /** + * This action can be used to modify the object further before it is created - it will be passed by reference. + * + * @since 3.0 + */ + do_action( 'woocommerce_product_duplicate_before_save', $duplicate, $product ); + + // Save parent product. + $duplicate->save(); + + // Duplicate children of a variable product. + if ( ! apply_filters( 'woocommerce_duplicate_product_exclude_children', false, $product ) && $product->is_type( 'variable' ) ) { + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + $child_duplicate = clone $child; + $child_duplicate->set_parent_id( $duplicate->get_id() ); + $child_duplicate->set_id( 0 ); + $child_duplicate->set_date_created( null ); + + // If we wait and let the insertion generate the slug, we will see extreme performance degradation + // in the case where a product is used as a template. Every time the template is duplicated, each + // variation will query every consecutive slug until it finds an empty one. To avoid this, we can + // optimize the generation ourselves, avoiding the issue altogether. + $this->generate_unique_slug( $child_duplicate ); + + if ( '' !== $child->get_sku( 'edit' ) ) { + $child_duplicate->set_sku( wc_product_generate_unique_sku( 0, $child->get_sku( 'edit' ) ) ); + } + + foreach ( $meta_to_exclude as $meta_key ) { + $child_duplicate->delete_meta_data( $meta_key ); + } + + /** + * This action can be used to modify the object further before it is created - it will be passed by reference. + * + * @since 3.0 + */ + do_action( 'woocommerce_product_duplicate_before_save', $child_duplicate, $child ); + + $child_duplicate->save(); + } + + // Get new object to reflect new children. + $duplicate = wc_get_product( $duplicate->get_id() ); + } + + return $duplicate; + } + + /** + * Get a product from the database to duplicate. + * + * @deprecated 3.0.0 + * @param mixed $id The ID of the product to duplicate. + * @return object|bool + * @see duplicate_product + */ + private function get_product_to_duplicate( $id ) { + global $wpdb; + + $id = absint( $id ); + + if ( ! $id ) { + return false; + } + + $post = $wpdb->get_row( $wpdb->prepare( "SELECT {$wpdb->posts}.* FROM {$wpdb->posts} WHERE ID = %d", $id ) ); + + if ( isset( $post->post_type ) && 'revision' === $post->post_type ) { + $id = $post->post_parent; + $post = $wpdb->get_row( $wpdb->prepare( "SELECT {$wpdb->posts}.* FROM {$wpdb->posts} WHERE ID = %d", $id ) ); + } + + return $post; + } + + /** + * Generates a unique slug for a given product. We do this so that we can override the + * behavior of wp_unique_post_slug(). The normal slug generation will run single + * select queries on every non-unique slug, resulting in very bad performance. + * + * @param WC_Product $product The product to generate a slug for. + * @since 3.9.0 + */ + private function generate_unique_slug( $product ) { + global $wpdb; + + // We want to remove the suffix from the slug so that we can find the maximum suffix using this root slug. + // This will allow us to find the next-highest suffix that is unique. While this does not support gap + // filling, this shouldn't matter for our use-case. + $root_slug = preg_replace( '/-[0-9]+$/', '', $product->get_slug() ); + + $results = $wpdb->get_results( + $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_name LIKE %s AND post_type IN ( 'product', 'product_variation' )", $root_slug . '%' ) + ); + + // The slug is already unique! + if ( empty( $results ) ) { + return; + } + + // Find the maximum suffix so we can ensure uniqueness. + $max_suffix = 1; + foreach ( $results as $result ) { + // Pull a numerical suffix off the slug after the last hyphen. + $suffix = intval( substr( $result->post_name, strrpos( $result->post_name, '-' ) + 1 ) ); + if ( $suffix > $max_suffix ) { + $max_suffix = $suffix; + } + } + + $product->set_slug( $root_slug . '-' . ( $max_suffix + 1 ) ); + } +} + +return new WC_Admin_Duplicate_Product(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-exporters.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-exporters.php new file mode 100644 index 0000000..c6dbc48 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-exporters.php @@ -0,0 +1,196 @@ +export_allowed() ) { + return; + } + + add_action( 'admin_menu', array( $this, 'add_to_menus' ) ); + add_action( 'admin_head', array( $this, 'hide_from_menus' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) ); + add_action( 'admin_init', array( $this, 'download_export_file' ) ); + add_action( 'wp_ajax_woocommerce_do_ajax_product_export', array( $this, 'do_ajax_product_export' ) ); + + // Register WooCommerce exporters. + $this->exporters['product_exporter'] = array( + 'menu' => 'edit.php?post_type=product', + 'name' => __( 'Product Export', 'woocommerce' ), + 'capability' => 'export', + 'callback' => array( $this, 'product_exporter' ), + ); + } + + /** + * Return true if WooCommerce export is allowed for current user, false otherwise. + * + * @return bool Whether current user can perform export. + */ + protected function export_allowed() { + return current_user_can( 'edit_products' ) && current_user_can( 'export' ); + } + + /** + * Add menu items for our custom exporters. + */ + public function add_to_menus() { + foreach ( $this->exporters as $id => $exporter ) { + add_submenu_page( $exporter['menu'], $exporter['name'], $exporter['name'], $exporter['capability'], $id, $exporter['callback'] ); + } + } + + /** + * Hide menu items from view so the pages exist, but the menu items do not. + */ + public function hide_from_menus() { + global $submenu; + + foreach ( $this->exporters as $id => $exporter ) { + if ( isset( $submenu[ $exporter['menu'] ] ) ) { + foreach ( $submenu[ $exporter['menu'] ] as $key => $menu ) { + if ( $id === $menu[2] ) { + unset( $submenu[ $exporter['menu'] ][ $key ] ); + } + } + } + } + } + + /** + * Enqueue scripts. + */ + public function admin_scripts() { + $suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min'; + $version = Constants::get_constant( 'WC_VERSION' ); + wp_register_script( 'wc-product-export', WC()->plugin_url() . '/assets/js/admin/wc-product-export' . $suffix . '.js', array( 'jquery' ), $version ); + wp_localize_script( + 'wc-product-export', + 'wc_product_export_params', + array( + 'export_nonce' => wp_create_nonce( 'wc-product-export' ), + ) + ); + } + + /** + * Export page UI. + */ + public function product_exporter() { + include_once WC_ABSPATH . 'includes/export/class-wc-product-csv-exporter.php'; + include_once dirname( __FILE__ ) . '/views/html-admin-page-product-export.php'; + } + + /** + * Serve the generated file. + */ + public function download_export_file() { + if ( isset( $_GET['action'], $_GET['nonce'] ) && wp_verify_nonce( wp_unslash( $_GET['nonce'] ), 'product-csv' ) && 'download_product_csv' === wp_unslash( $_GET['action'] ) ) { // WPCS: input var ok, sanitization ok. + include_once WC_ABSPATH . 'includes/export/class-wc-product-csv-exporter.php'; + $exporter = new WC_Product_CSV_Exporter(); + + if ( ! empty( $_GET['filename'] ) ) { // WPCS: input var ok. + $exporter->set_filename( wp_unslash( $_GET['filename'] ) ); // WPCS: input var ok, sanitization ok. + } + + $exporter->export(); + } + } + + /** + * AJAX callback for doing the actual export to the CSV file. + */ + public function do_ajax_product_export() { + check_ajax_referer( 'wc-product-export', 'security' ); + + if ( ! $this->export_allowed() ) { + wp_send_json_error( array( 'message' => __( 'Insufficient privileges to export products.', 'woocommerce' ) ) ); + } + + include_once WC_ABSPATH . 'includes/export/class-wc-product-csv-exporter.php'; + + $step = isset( $_POST['step'] ) ? absint( $_POST['step'] ) : 1; // WPCS: input var ok, sanitization ok. + $exporter = new WC_Product_CSV_Exporter(); + + if ( ! empty( $_POST['columns'] ) ) { // WPCS: input var ok. + $exporter->set_column_names( wp_unslash( $_POST['columns'] ) ); // WPCS: input var ok, sanitization ok. + } + + if ( ! empty( $_POST['selected_columns'] ) ) { // WPCS: input var ok. + $exporter->set_columns_to_export( wp_unslash( $_POST['selected_columns'] ) ); // WPCS: input var ok, sanitization ok. + } + + if ( ! empty( $_POST['export_meta'] ) ) { // WPCS: input var ok. + $exporter->enable_meta_export( true ); + } + + if ( ! empty( $_POST['export_types'] ) ) { // WPCS: input var ok. + $exporter->set_product_types_to_export( wp_unslash( $_POST['export_types'] ) ); // WPCS: input var ok, sanitization ok. + } + + if ( ! empty( $_POST['export_category'] ) && is_array( $_POST['export_category'] ) ) {// WPCS: input var ok. + $exporter->set_product_category_to_export( wp_unslash( array_values( $_POST['export_category'] ) ) ); // WPCS: input var ok, sanitization ok. + } + + if ( ! empty( $_POST['filename'] ) ) { // WPCS: input var ok. + $exporter->set_filename( wp_unslash( $_POST['filename'] ) ); // WPCS: input var ok, sanitization ok. + } + + $exporter->set_page( $step ); + $exporter->generate_file(); + + $query_args = apply_filters( + 'woocommerce_export_get_ajax_query_args', + array( + 'nonce' => wp_create_nonce( 'product-csv' ), + 'action' => 'download_product_csv', + 'filename' => $exporter->get_filename(), + ) + ); + + if ( 100 === $exporter->get_percent_complete() ) { + wp_send_json_success( + array( + 'step' => 'done', + 'percentage' => 100, + 'url' => add_query_arg( $query_args, admin_url( 'edit.php?post_type=product&page=product_exporter' ) ), + ) + ); + } else { + wp_send_json_success( + array( + 'step' => ++$step, + 'percentage' => $exporter->get_percent_complete(), + 'columns' => $exporter->get_column_names(), + ) + ); + } + } +} + +new WC_Admin_Exporters(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-help.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-help.php new file mode 100644 index 0000000..e2654e8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-help.php @@ -0,0 +1,85 @@ +id, wc_get_screen_ids() ) ) { + return; + } + + $screen->add_help_tab( + array( + 'id' => 'woocommerce_support_tab', + 'title' => __( 'Help & Support', 'woocommerce' ), + 'content' => + '

    ' . __( 'Help & Support', 'woocommerce' ) . '

    ' . + '

    ' . sprintf( + /* translators: %s: Documentation URL */ + __( 'Should you need help understanding, using, or extending WooCommerce, please read our documentation. You will find all kinds of resources including snippets, tutorials and much more.', 'woocommerce' ), + 'https://docs.woocommerce.com/documentation/plugins/woocommerce/?utm_source=helptab&utm_medium=product&utm_content=docs&utm_campaign=woocommerceplugin' + ) . '

    ' . + '

    ' . sprintf( + /* translators: %s: Forum URL */ + __( 'For further assistance with WooCommerce core, use the community forum. For help with premium extensions sold on WooCommerce.com, open a support request at WooCommerce.com.', 'woocommerce' ), + 'https://wordpress.org/support/plugin/woocommerce', + 'https://woocommerce.com/my-account/create-a-ticket/?utm_source=helptab&utm_medium=product&utm_content=tickets&utm_campaign=woocommerceplugin' + ) . '

    ' . + '

    ' . __( 'Before asking for help, we recommend checking the system status page to identify any problems with your configuration.', 'woocommerce' ) . '

    ' . + '

    ' . __( 'System status', 'woocommerce' ) . ' ' . __( 'Community forum', 'woocommerce' ) . ' ' . __( 'WooCommerce.com support', 'woocommerce' ) . '

    ', + ) + ); + + $screen->add_help_tab( + array( + 'id' => 'woocommerce_bugs_tab', + 'title' => __( 'Found a bug?', 'woocommerce' ), + 'content' => + '

    ' . __( 'Found a bug?', 'woocommerce' ) . '

    ' . + /* translators: 1: GitHub issues URL 2: GitHub contribution guide URL 3: System status report URL */ + '

    ' . sprintf( __( 'If you find a bug within WooCommerce core you can create a ticket via Github issues. Ensure you read the contribution guide prior to submitting your report. To help us solve your issue, please be as descriptive as possible and include your system status report.', 'woocommerce' ), 'https://github.com/woocommerce/woocommerce/issues?state=open', 'https://github.com/woocommerce/woocommerce/blob/master/.github/CONTRIBUTING.md', admin_url( 'admin.php?page=wc-status' ) ) . '

    ' . + '

    ' . __( 'Report a bug', 'woocommerce' ) . ' ' . __( 'System status', 'woocommerce' ) . '

    ', + + ) + ); + + $screen->set_help_sidebar( + '

    ' . __( 'For more information:', 'woocommerce' ) . '

    ' . + '

    ' . __( 'About WooCommerce', 'woocommerce' ) . '

    ' . + '

    ' . __( 'WordPress.org project', 'woocommerce' ) . '

    ' . + '

    ' . __( 'Github project', 'woocommerce' ) . '

    ' . + '

    ' . __( 'Official theme', 'woocommerce' ) . '

    ' . + '

    ' . __( 'Official extensions', 'woocommerce' ) . '

    ' + ); + } +} + +return new WC_Admin_Help(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-importers.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-importers.php new file mode 100644 index 0000000..95f9e3b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-importers.php @@ -0,0 +1,306 @@ +import_allowed() ) { + return; + } + + add_action( 'admin_menu', array( $this, 'add_to_menus' ) ); + add_action( 'admin_init', array( $this, 'register_importers' ) ); + add_action( 'admin_head', array( $this, 'hide_from_menus' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) ); + add_action( 'wp_ajax_woocommerce_do_ajax_product_import', array( $this, 'do_ajax_product_import' ) ); + + // Register WooCommerce importers. + $this->importers['product_importer'] = array( + 'menu' => 'edit.php?post_type=product', + 'name' => __( 'Product Import', 'woocommerce' ), + 'capability' => 'import', + 'callback' => array( $this, 'product_importer' ), + ); + } + + /** + * Return true if WooCommerce imports are allowed for current user, false otherwise. + * + * @return bool Whether current user can perform imports. + */ + protected function import_allowed() { + return current_user_can( 'edit_products' ) && current_user_can( 'import' ); + } + + /** + * Add menu items for our custom importers. + */ + public function add_to_menus() { + foreach ( $this->importers as $id => $importer ) { + add_submenu_page( $importer['menu'], $importer['name'], $importer['name'], $importer['capability'], $id, $importer['callback'] ); + } + } + + /** + * Hide menu items from view so the pages exist, but the menu items do not. + */ + public function hide_from_menus() { + global $submenu; + + foreach ( $this->importers as $id => $importer ) { + if ( isset( $submenu[ $importer['menu'] ] ) ) { + foreach ( $submenu[ $importer['menu'] ] as $key => $menu ) { + if ( $id === $menu[2] ) { + unset( $submenu[ $importer['menu'] ][ $key ] ); + } + } + } + } + } + + /** + * Register importer scripts. + */ + public function admin_scripts() { + $suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min'; + $version = Constants::get_constant( 'WC_VERSION' ); + wp_register_script( 'wc-product-import', WC()->plugin_url() . '/assets/js/admin/wc-product-import' . $suffix . '.js', array( 'jquery' ), $version, true ); + } + + /** + * The product importer. + * + * This has a custom screen - the Tools > Import item is a placeholder. + * If we're on that screen, redirect to the custom one. + */ + public function product_importer() { + if ( Constants::is_defined( 'WP_LOAD_IMPORTERS' ) ) { + wp_safe_redirect( admin_url( 'edit.php?post_type=product&page=product_importer' ) ); + exit; + } + + include_once WC_ABSPATH . 'includes/import/class-wc-product-csv-importer.php'; + include_once WC_ABSPATH . 'includes/admin/importers/class-wc-product-csv-importer-controller.php'; + + $importer = new WC_Product_CSV_Importer_Controller(); + $importer->dispatch(); + } + + /** + * Register WordPress based importers. + */ + public function register_importers() { + if ( Constants::is_defined( 'WP_LOAD_IMPORTERS' ) ) { + add_action( 'import_start', array( $this, 'post_importer_compatibility' ) ); + register_importer( 'woocommerce_product_csv', __( 'WooCommerce products (CSV)', 'woocommerce' ), __( 'Import products to your store via a csv file.', 'woocommerce' ), array( $this, 'product_importer' ) ); + register_importer( 'woocommerce_tax_rate_csv', __( 'WooCommerce tax rates (CSV)', 'woocommerce' ), __( 'Import tax rates to your store via a csv file.', 'woocommerce' ), array( $this, 'tax_rates_importer' ) ); + } + } + + /** + * The tax rate importer which extends WP_Importer. + */ + public function tax_rates_importer() { + require_once ABSPATH . 'wp-admin/includes/import.php'; + + if ( ! class_exists( 'WP_Importer' ) ) { + $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php'; + + if ( file_exists( $class_wp_importer ) ) { + require $class_wp_importer; + } + } + + require dirname( __FILE__ ) . '/importers/class-wc-tax-rate-importer.php'; + + $importer = new WC_Tax_Rate_Importer(); + $importer->dispatch(); + } + + /** + * When running the WP XML importer, ensure attributes exist. + * + * WordPress import should work - however, it fails to import custom product attribute taxonomies. + * This code grabs the file before it is imported and ensures the taxonomies are created. + */ + public function post_importer_compatibility() { + global $wpdb; + + if ( empty( $_POST['import_id'] ) || ! class_exists( 'WXR_Parser' ) ) { // PHPCS: input var ok, CSRF ok. + return; + } + + $id = absint( $_POST['import_id'] ); // PHPCS: input var ok. + $file = get_attached_file( $id ); + $parser = new WXR_Parser(); + $import_data = $parser->parse( $file ); + + if ( isset( $import_data['posts'] ) && ! empty( $import_data['posts'] ) ) { + foreach ( $import_data['posts'] as $post ) { + if ( 'product' === $post['post_type'] && ! empty( $post['terms'] ) ) { + foreach ( $post['terms'] as $term ) { + if ( strstr( $term['domain'], 'pa_' ) ) { + if ( ! taxonomy_exists( $term['domain'] ) ) { + $attribute_name = wc_attribute_taxonomy_slug( $term['domain'] ); + + // Create the taxonomy. + if ( ! in_array( $attribute_name, wc_get_attribute_taxonomies(), true ) ) { + wc_create_attribute( + array( + 'name' => $attribute_name, + 'slug' => $attribute_name, + 'type' => 'select', + 'order_by' => 'menu_order', + 'has_archives' => false, + ) + ); + } + + // Register the taxonomy now so that the import works! + register_taxonomy( + $term['domain'], + apply_filters( 'woocommerce_taxonomy_objects_' . $term['domain'], array( 'product' ) ), + apply_filters( + 'woocommerce_taxonomy_args_' . $term['domain'], + array( + 'hierarchical' => true, + 'show_ui' => false, + 'query_var' => true, + 'rewrite' => false, + ) + ) + ); + } + } + } + } + } + } + } + + /** + * Ajax callback for importing one batch of products from a CSV. + */ + public function do_ajax_product_import() { + global $wpdb; + + check_ajax_referer( 'wc-product-import', 'security' ); + + if ( ! $this->import_allowed() || ! isset( $_POST['file'] ) ) { // PHPCS: input var ok. + wp_send_json_error( array( 'message' => __( 'Insufficient privileges to import products.', 'woocommerce' ) ) ); + } + + 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( wp_unslash( $_POST['file'] ) ); // PHPCS: input var ok. + $params = array( + 'delimiter' => ! empty( $_POST['delimiter'] ) ? wc_clean( wp_unslash( $_POST['delimiter'] ) ) : ',', // PHPCS: input var ok. + 'start_pos' => isset( $_POST['position'] ) ? absint( $_POST['position'] ) : 0, // PHPCS: input var ok. + 'mapping' => isset( $_POST['mapping'] ) ? (array) wc_clean( wp_unslash( $_POST['mapping'] ) ) : array(), // PHPCS: input var ok. + 'update_existing' => isset( $_POST['update_existing'] ) ? (bool) $_POST['update_existing'] : false, // PHPCS: input var ok. + 'lines' => apply_filters( 'woocommerce_product_import_batch_size', 30 ), + 'parse' => true, + ); + + // Log failures. + if ( 0 !== $params['start_pos'] ) { + $error_log = array_filter( (array) get_user_option( 'product_import_error_log' ) ); + } else { + $error_log = array(); + } + + $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 ) { + // @codingStandardsIgnoreStart. + $wpdb->delete( $wpdb->postmeta, array( 'meta_key' => '_original_id' ) ); + $wpdb->delete( $wpdb->posts, array( + 'post_type' => 'product', + 'post_status' => 'importing', + ) ); + $wpdb->delete( $wpdb->posts, array( + 'post_type' => 'product_variation', + 'post_status' => 'importing', + ) ); + // @codingStandardsIgnoreEnd. + + // Clean up orphaned data. + $wpdb->query( + " + DELETE {$wpdb->posts}.* FROM {$wpdb->posts} + LEFT JOIN {$wpdb->posts} wp ON wp.ID = {$wpdb->posts}.post_parent + WHERE wp.ID IS NULL AND {$wpdb->posts}.post_type = 'product_variation' + " + ); + $wpdb->query( + " + DELETE {$wpdb->postmeta}.* FROM {$wpdb->postmeta} + LEFT JOIN {$wpdb->posts} wp ON wp.ID = {$wpdb->postmeta}.post_id + WHERE wp.ID IS NULL + " + ); + // @codingStandardsIgnoreStart. + $wpdb->query( " + DELETE tr.* FROM {$wpdb->term_relationships} tr + LEFT JOIN {$wpdb->posts} wp ON wp.ID = tr.object_id + LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id + WHERE wp.ID IS NULL + AND tt.taxonomy IN ( '" . implode( "','", array_map( 'esc_sql', get_object_taxonomies( 'product' ) ) ) . "' ) + " ); + // @codingStandardsIgnoreEnd. + + // Send success. + wp_send_json_success( + array( + 'position' => 'done', + 'percentage' => 100, + 'url' => add_query_arg( array( '_wpnonce' => wp_create_nonce( 'woocommerce-csv-importer' ) ), 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( + 'position' => $importer->get_file_position(), + 'percentage' => $percent_complete, + 'imported' => count( $results['imported'] ), + 'failed' => count( $results['failed'] ), + 'updated' => count( $results['updated'] ), + 'skipped' => count( $results['skipped'] ), + ) + ); + } + } +} + +new WC_Admin_Importers(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-log-table-list.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-log-table-list.php new file mode 100644 index 0000000..2d9b922 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-log-table-list.php @@ -0,0 +1,395 @@ + 'log', + 'plural' => 'logs', + 'ajax' => false, + ) + ); + } + + /** + * Display level dropdown + * + * @global wpdb $wpdb + */ + public function level_dropdown() { + + $levels = array( + array( + 'value' => WC_Log_Levels::EMERGENCY, + 'label' => __( 'Emergency', 'woocommerce' ), + ), + array( + 'value' => WC_Log_Levels::ALERT, + 'label' => __( 'Alert', 'woocommerce' ), + ), + array( + 'value' => WC_Log_Levels::CRITICAL, + 'label' => __( 'Critical', 'woocommerce' ), + ), + array( + 'value' => WC_Log_Levels::ERROR, + 'label' => __( 'Error', 'woocommerce' ), + ), + array( + 'value' => WC_Log_Levels::WARNING, + 'label' => __( 'Warning', 'woocommerce' ), + ), + array( + 'value' => WC_Log_Levels::NOTICE, + 'label' => __( 'Notice', 'woocommerce' ), + ), + array( + 'value' => WC_Log_Levels::INFO, + 'label' => __( 'Info', 'woocommerce' ), + ), + array( + 'value' => WC_Log_Levels::DEBUG, + 'label' => __( 'Debug', 'woocommerce' ), + ), + ); + + $selected_level = isset( $_REQUEST['level'] ) ? $_REQUEST['level'] : ''; + ?> + + + '', + 'timestamp' => __( 'Timestamp', 'woocommerce' ), + 'level' => __( 'Level', 'woocommerce' ), + 'message' => __( 'Message', 'woocommerce' ), + 'source' => __( 'Source', 'woocommerce' ), + ); + } + + /** + * Column cb. + * + * @param array $log + * @return string + */ + public function column_cb( $log ) { + return sprintf( '', esc_attr( $log['log_id'] ) ); + } + + /** + * Timestamp column. + * + * @param array $log + * @return string + */ + public function column_timestamp( $log ) { + return esc_html( + mysql2date( + 'Y-m-d H:i:s', + $log['timestamp'] + ) + ); + } + + /** + * Level column. + * + * @param array $log + * @return string + */ + public function column_level( $log ) { + $level_key = WC_Log_Levels::get_severity_level( $log['level'] ); + $levels = array( + 'emergency' => __( 'Emergency', 'woocommerce' ), + 'alert' => __( 'Alert', 'woocommerce' ), + 'critical' => __( 'Critical', 'woocommerce' ), + 'error' => __( 'Error', 'woocommerce' ), + 'warning' => __( 'Warning', 'woocommerce' ), + 'notice' => __( 'Notice', 'woocommerce' ), + 'info' => __( 'Info', 'woocommerce' ), + 'debug' => __( 'Debug', 'woocommerce' ), + ); + + if ( ! isset( $levels[ $level_key ] ) ) { + return ''; + } + + $level = $levels[ $level_key ]; + $level_class = sanitize_html_class( 'log-level--' . $level_key ); + return '' . esc_html( $level ) . ''; + } + + /** + * Message column. + * + * @param array $log + * @return string + */ + public function column_message( $log ) { + return esc_html( $log['message'] ); + } + + /** + * Source column. + * + * @param array $log + * @return string + */ + public function column_source( $log ) { + return esc_html( $log['source'] ); + } + + /** + * Get bulk actions. + * + * @return array + */ + protected function get_bulk_actions() { + return array( + 'delete' => __( 'Delete', 'woocommerce' ), + ); + } + + /** + * Extra controls to be displayed between bulk actions and pagination. + * + * @param string $which + */ + protected function extra_tablenav( $which ) { + if ( 'top' === $which ) { + echo '
    '; + $this->level_dropdown(); + $this->source_dropdown(); + submit_button( __( 'Filter', 'woocommerce' ), '', 'filter-action', false ); + echo '
    '; + } + } + + /** + * Get a list of sortable columns. + * + * @return array + */ + protected function get_sortable_columns() { + return array( + 'timestamp' => array( 'timestamp', true ), + 'level' => array( 'level', true ), + 'source' => array( 'source', true ), + ); + } + + /** + * Display source dropdown + * + * @global wpdb $wpdb + */ + protected function source_dropdown() { + global $wpdb; + + $sources = $wpdb->get_col( + "SELECT DISTINCT source + FROM {$wpdb->prefix}woocommerce_log + WHERE source != '' + ORDER BY source ASC" + ); + + if ( ! empty( $sources ) ) { + $selected_source = isset( $_REQUEST['source'] ) ? $_REQUEST['source'] : ''; + ?> + + + prepare_column_headers(); + + $per_page = $this->get_items_per_page( 'woocommerce_status_log_items_per_page', 10 ); + + $where = $this->get_items_query_where(); + $order = $this->get_items_query_order(); + $limit = $this->get_items_query_limit(); + $offset = $this->get_items_query_offset(); + + $query_items = " + SELECT log_id, timestamp, level, message, source + FROM {$wpdb->prefix}woocommerce_log + {$where} {$order} {$limit} {$offset} + "; + + $this->items = $wpdb->get_results( $query_items, ARRAY_A ); + + $query_count = "SELECT COUNT(log_id) FROM {$wpdb->prefix}woocommerce_log {$where}"; + $total_items = $wpdb->get_var( $query_count ); + + $this->set_pagination_args( + array( + 'total_items' => $total_items, + 'per_page' => $per_page, + 'total_pages' => ceil( $total_items / $per_page ), + ) + ); + } + + /** + * Get prepared LIMIT clause for items query + * + * @global wpdb $wpdb + * + * @return string Prepared LIMIT clause for items query. + */ + protected function get_items_query_limit() { + global $wpdb; + + $per_page = $this->get_items_per_page( 'woocommerce_status_log_items_per_page', 10 ); + return $wpdb->prepare( 'LIMIT %d', $per_page ); + } + + /** + * Get prepared OFFSET clause for items query + * + * @global wpdb $wpdb + * + * @return string Prepared OFFSET clause for items query. + */ + protected function get_items_query_offset() { + global $wpdb; + + $per_page = $this->get_items_per_page( 'woocommerce_status_log_items_per_page', 10 ); + $current_page = $this->get_pagenum(); + if ( 1 < $current_page ) { + $offset = $per_page * ( $current_page - 1 ); + } else { + $offset = 0; + } + + return $wpdb->prepare( 'OFFSET %d', $offset ); + } + + /** + * Get prepared ORDER BY clause for items query + * + * @return string Prepared ORDER BY clause for items query. + */ + protected function get_items_query_order() { + $valid_orders = array( 'level', 'source', 'timestamp' ); + if ( ! empty( $_REQUEST['orderby'] ) && in_array( $_REQUEST['orderby'], $valid_orders ) ) { + $by = wc_clean( $_REQUEST['orderby'] ); + } else { + $by = 'timestamp'; + } + $by = esc_sql( $by ); + + if ( ! empty( $_REQUEST['order'] ) && 'asc' === strtolower( $_REQUEST['order'] ) ) { + $order = 'ASC'; + } else { + $order = 'DESC'; + } + + return "ORDER BY {$by} {$order}, log_id {$order}"; + } + + /** + * Get prepared WHERE clause for items query + * + * @global wpdb $wpdb + * + * @return string Prepared WHERE clause for items query. + */ + protected function get_items_query_where() { + global $wpdb; + + $where_conditions = array(); + $where_values = array(); + if ( ! empty( $_REQUEST['level'] ) && WC_Log_Levels::is_valid_level( $_REQUEST['level'] ) ) { + $where_conditions[] = 'level >= %d'; + $where_values[] = WC_Log_Levels::get_level_severity( $_REQUEST['level'] ); + } + if ( ! empty( $_REQUEST['source'] ) ) { + $where_conditions[] = 'source = %s'; + $where_values[] = wc_clean( $_REQUEST['source'] ); + } + if ( ! empty( $_REQUEST['s'] ) ) { + $where_conditions[] = 'message like %s'; + $where_values[] = '%' . $wpdb->esc_like( wc_clean( wp_unslash( $_REQUEST['s'] ) ) ) . '%'; + } + + if ( empty( $where_conditions ) ) { + return ''; + } + + return $wpdb->prepare( 'WHERE 1 = 1 AND ' . implode( ' AND ', $where_conditions ), $where_values ); + } + + /** + * Set _column_headers property for table list + */ + protected function prepare_column_headers() { + $this->_column_headers = array( + $this->get_columns(), + array(), + $this->get_sortable_columns(), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-menus.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-menus.php new file mode 100644 index 0000000..abb8680 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-menus.php @@ -0,0 +1,390 @@ + Menus > Pages. + add_action( 'admin_head-nav-menus.php', array( $this, 'add_nav_menu_meta_boxes' ) ); + + // Admin bar menus. + if ( apply_filters( 'woocommerce_show_admin_bar_visit_store', true ) ) { + add_action( 'admin_bar_menu', array( $this, 'admin_bar_menus' ), 31 ); + } + + // Handle saving settings earlier than load-{page} hook to avoid race conditions in conditional menus. + add_action( 'wp_loaded', array( $this, 'save_settings' ) ); + } + + /** + * Add menu items. + */ + public function admin_menu() { + global $menu; + + if ( current_user_can( 'edit_others_shop_orders' ) ) { + $menu[] = array( '', 'read', 'separator-woocommerce', '', 'wp-menu-separator woocommerce' ); // WPCS: override ok. + } + + add_menu_page( __( 'WooCommerce', 'woocommerce' ), __( 'WooCommerce', 'woocommerce' ), 'edit_others_shop_orders', 'woocommerce', null, null, '55.5' ); + + add_submenu_page( 'edit.php?post_type=product', __( 'Attributes', 'woocommerce' ), __( 'Attributes', 'woocommerce' ), 'manage_product_terms', 'product_attributes', array( $this, 'attributes_page' ) ); + } + + /** + * Add menu item. + */ + public function reports_menu() { + if ( current_user_can( 'edit_others_shop_orders' ) ) { + add_submenu_page( 'woocommerce', __( 'Reports', 'woocommerce' ), __( 'Reports', 'woocommerce' ), 'view_woocommerce_reports', 'wc-reports', array( $this, 'reports_page' ) ); + } else { + add_menu_page( __( 'Sales reports', 'woocommerce' ), __( 'Sales reports', 'woocommerce' ), 'view_woocommerce_reports', 'wc-reports', array( $this, 'reports_page' ), null, '55.6' ); + } + } + + /** + * Add menu item. + */ + public function settings_menu() { + $settings_page = add_submenu_page( 'woocommerce', __( 'WooCommerce settings', 'woocommerce' ), __( 'Settings', 'woocommerce' ), 'manage_woocommerce', 'wc-settings', array( $this, 'settings_page' ) ); + + add_action( 'load-' . $settings_page, array( $this, 'settings_page_init' ) ); + } + + /** + * Loads gateways and shipping methods into memory for use within settings. + */ + public function settings_page_init() { + WC()->payment_gateways(); + WC()->shipping(); + + // Include settings pages. + WC_Admin_Settings::get_settings_pages(); + + // Add any posted messages. + if ( ! empty( $_GET['wc_error'] ) ) { // WPCS: input var okay, CSRF ok. + WC_Admin_Settings::add_error( wp_kses_post( wp_unslash( $_GET['wc_error'] ) ) ); // WPCS: input var okay, CSRF ok. + } + + if ( ! empty( $_GET['wc_message'] ) ) { // WPCS: input var okay, CSRF ok. + WC_Admin_Settings::add_message( wp_kses_post( wp_unslash( $_GET['wc_message'] ) ) ); // WPCS: input var okay, CSRF ok. + } + + do_action( 'woocommerce_settings_page_init' ); + } + + /** + * Handle saving of settings. + * + * @return void + */ + public function save_settings() { + global $current_tab, $current_section; + + // We should only save on the settings page. + if ( ! is_admin() || ! isset( $_GET['page'] ) || 'wc-settings' !== $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + return; + } + + // Include settings pages. + WC_Admin_Settings::get_settings_pages(); + + // Get current tab/section. + $current_tab = empty( $_GET['tab'] ) ? 'general' : sanitize_title( wp_unslash( $_GET['tab'] ) ); // WPCS: input var okay, CSRF ok. + $current_section = empty( $_REQUEST['section'] ) ? '' : sanitize_title( wp_unslash( $_REQUEST['section'] ) ); // WPCS: input var okay, CSRF ok. + + // Save settings if data has been posted. + if ( '' !== $current_section && apply_filters( "woocommerce_save_settings_{$current_tab}_{$current_section}", ! empty( $_POST['save'] ) ) ) { // WPCS: input var okay, CSRF ok. + WC_Admin_Settings::save(); + } elseif ( '' === $current_section && apply_filters( "woocommerce_save_settings_{$current_tab}", ! empty( $_POST['save'] ) ) ) { // WPCS: input var okay, CSRF ok. + WC_Admin_Settings::save(); + } + } + + /** + * Add menu item. + */ + public function status_menu() { + add_submenu_page( 'woocommerce', __( 'WooCommerce status', 'woocommerce' ), __( 'Status', 'woocommerce' ), 'manage_woocommerce', 'wc-status', array( $this, 'status_page' ) ); + } + + /** + * Addons menu item. + */ + public function addons_menu() { + $count_html = WC_Helper_Updater::get_updates_count_html(); + /* translators: %s: extensions count */ + $menu_title = sprintf( __( 'Extensions %s', 'woocommerce' ), $count_html ); + add_submenu_page( 'woocommerce', __( 'WooCommerce extensions', 'woocommerce' ), $menu_title, 'manage_woocommerce', 'wc-addons', array( $this, 'addons_page' ) ); + } + + /** + * Highlights the correct top level admin menu item for post type add screens. + */ + public function menu_highlight() { + global $parent_file, $submenu_file, $post_type; + + switch ( $post_type ) { + case 'shop_order': + case 'shop_coupon': + $parent_file = 'woocommerce'; // WPCS: override ok. + break; + case 'product': + $screen = get_current_screen(); + if ( $screen && taxonomy_is_product_attribute( $screen->taxonomy ) ) { + $submenu_file = 'product_attributes'; // WPCS: override ok. + $parent_file = 'edit.php?post_type=product'; // WPCS: override ok. + } + break; + } + } + + /** + * Adds the order processing count to the menu. + */ + public function menu_order_count() { + global $submenu; + + if ( isset( $submenu['woocommerce'] ) ) { + // Remove 'WooCommerce' sub menu item. + unset( $submenu['woocommerce'][0] ); + + // Add count if user has access. + if ( apply_filters( 'woocommerce_include_processing_order_count_in_menu', true ) && current_user_can( 'edit_others_shop_orders' ) ) { + $order_count = apply_filters( 'woocommerce_menu_order_count', wc_processing_order_count() ); + + if ( $order_count ) { + foreach ( $submenu['woocommerce'] as $key => $menu_item ) { + if ( 0 === strpos( $menu_item[0], _x( 'Orders', 'Admin menu name', 'woocommerce' ) ) ) { + $submenu['woocommerce'][ $key ][0] .= ' ' . number_format_i18n( $order_count ) . ''; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + break; + } + } + } + } + } + } + + /** + * Reorder the WC menu items in admin. + * + * @param int $menu_order Menu order. + * @return array + */ + public function menu_order( $menu_order ) { + // Initialize our custom order array. + $woocommerce_menu_order = array(); + + // Get the index of our custom separator. + $woocommerce_separator = array_search( 'separator-woocommerce', $menu_order, true ); + + // Get index of product menu. + $woocommerce_product = array_search( 'edit.php?post_type=product', $menu_order, true ); + + // Loop through menu order and do some rearranging. + foreach ( $menu_order as $index => $item ) { + + if ( 'woocommerce' === $item ) { + $woocommerce_menu_order[] = 'separator-woocommerce'; + $woocommerce_menu_order[] = $item; + $woocommerce_menu_order[] = 'edit.php?post_type=product'; + unset( $menu_order[ $woocommerce_separator ] ); + unset( $menu_order[ $woocommerce_product ] ); + } elseif ( ! in_array( $item, array( 'separator-woocommerce' ), true ) ) { + $woocommerce_menu_order[] = $item; + } + } + + // Return order. + return $woocommerce_menu_order; + } + + /** + * Custom menu order. + * + * @param bool $enabled Whether custom menu ordering is already enabled. + * @return bool + */ + public function custom_menu_order( $enabled ) { + return $enabled || current_user_can( 'edit_others_shop_orders' ); + } + + /** + * Validate screen options on update. + * + * @param bool|int $status Screen option value. Default false to skip. + * @param string $option The option name. + * @param int $value The number of rows to use. + */ + public function set_screen_option( $status, $option, $value ) { + if ( in_array( $option, array( 'woocommerce_keys_per_page', 'woocommerce_webhooks_per_page' ), true ) ) { + return $value; + } + + return $status; + } + + /** + * Init the reports page. + */ + public function reports_page() { + WC_Admin_Reports::output(); + } + + /** + * Init the settings page. + */ + public function settings_page() { + WC_Admin_Settings::output(); + } + + /** + * Init the attributes page. + */ + public function attributes_page() { + WC_Admin_Attributes::output(); + } + + /** + * Init the status page. + */ + public function status_page() { + WC_Admin_Status::output(); + } + + /** + * Init the addons page. + */ + public function addons_page() { + WC_Admin_Addons::output(); + } + + /** + * Add custom nav meta box. + * + * Adapted from http://www.johnmorrisonline.com/how-to-add-a-fully-functional-custom-meta-box-to-wordpress-navigation-menus/. + */ + public function add_nav_menu_meta_boxes() { + add_meta_box( 'woocommerce_endpoints_nav_link', __( 'WooCommerce endpoints', 'woocommerce' ), array( $this, 'nav_menu_links' ), 'nav-menus', 'side', 'low' ); + } + + /** + * Output menu links. + */ + public function nav_menu_links() { + // Get items from account menu. + $endpoints = wc_get_account_menu_items(); + + // Remove dashboard item. + if ( isset( $endpoints['dashboard'] ) ) { + unset( $endpoints['dashboard'] ); + } + + // Include missing lost password. + $endpoints['lost-password'] = __( 'Lost password', 'woocommerce' ); + + $endpoints = apply_filters( 'woocommerce_custom_nav_menu_items', $endpoints ); + + ?> +
    +
    +
      + $value ) : + ?> +
    • + + + + + +
    • + +
    +
    +

    + + + + + + + +

    +
    + add_node( + array( + 'parent' => 'site-name', + 'id' => 'view-store', + 'title' => __( 'Visit Store', 'woocommerce' ), + 'href' => wc_get_page_permalink( 'shop' ), + ) + ); + } +} + +return new WC_Admin_Menus(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-meta-boxes.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-meta-boxes.php new file mode 100644 index 0000000..df1db14 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-meta-boxes.php @@ -0,0 +1,227 @@ +'; + + foreach ( $errors as $error ) { + echo '

    ' . wp_kses_post( $error ) . '

    '; + } + + echo ''; + + // Clear. + delete_option( 'woocommerce_meta_box_errors' ); + } + } + + /** + * Add WC Meta boxes. + */ + public function add_meta_boxes() { + $screen = get_current_screen(); + $screen_id = $screen ? $screen->id : ''; + + // Products. + add_meta_box( 'postexcerpt', __( 'Product short description', 'woocommerce' ), 'WC_Meta_Box_Product_Short_Description::output', 'product', 'normal' ); + add_meta_box( 'woocommerce-product-data', __( 'Product data', 'woocommerce' ), 'WC_Meta_Box_Product_Data::output', 'product', 'normal', 'high' ); + add_meta_box( 'woocommerce-product-images', __( 'Product gallery', 'woocommerce' ), 'WC_Meta_Box_Product_Images::output', 'product', 'side', 'low' ); + + // Orders. + foreach ( wc_get_order_types( 'order-meta-boxes' ) as $type ) { + $order_type_object = get_post_type_object( $type ); + /* Translators: %s order type name. */ + add_meta_box( 'woocommerce-order-data', sprintf( __( '%s data', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Data::output', $type, 'normal', 'high' ); + add_meta_box( 'woocommerce-order-items', __( 'Items', 'woocommerce' ), 'WC_Meta_Box_Order_Items::output', $type, 'normal', 'high' ); + /* Translators: %s order type name. */ + add_meta_box( 'woocommerce-order-notes', sprintf( __( '%s notes', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Notes::output', $type, 'side', 'default' ); + add_meta_box( 'woocommerce-order-downloads', __( 'Downloadable product permissions', 'woocommerce' ) . wc_help_tip( __( 'Note: Permissions for order items will automatically be granted when the order status changes to processing/completed.', 'woocommerce' ) ), 'WC_Meta_Box_Order_Downloads::output', $type, 'normal', 'default' ); + /* Translators: %s order type name. */ + add_meta_box( 'woocommerce-order-actions', sprintf( __( '%s actions', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Actions::output', $type, 'side', 'high' ); + } + + // Coupons. + add_meta_box( 'woocommerce-coupon-data', __( 'Coupon data', 'woocommerce' ), 'WC_Meta_Box_Coupon_Data::output', 'shop_coupon', 'normal', 'high' ); + + // Comment rating. + if ( 'comment' === $screen_id && isset( $_GET['c'] ) && metadata_exists( 'comment', wc_clean( wp_unslash( $_GET['c'] ) ), 'rating' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + add_meta_box( 'woocommerce-rating', __( 'Rating', 'woocommerce' ), 'WC_Meta_Box_Product_Reviews::output', 'comment', 'normal', 'high' ); + } + } + + /** + * Remove bloat. + */ + public function remove_meta_boxes() { + remove_meta_box( 'postexcerpt', 'product', 'normal' ); + remove_meta_box( 'product_shipping_classdiv', 'product', 'side' ); + remove_meta_box( 'commentsdiv', 'product', 'normal' ); + remove_meta_box( 'commentstatusdiv', 'product', 'side' ); + remove_meta_box( 'commentstatusdiv', 'product', 'normal' ); + remove_meta_box( 'woothemes-settings', 'shop_coupon', 'normal' ); + remove_meta_box( 'commentstatusdiv', 'shop_coupon', 'normal' ); + remove_meta_box( 'slugdiv', 'shop_coupon', 'normal' ); + + foreach ( wc_get_order_types( 'order-meta-boxes' ) as $type ) { + remove_meta_box( 'commentsdiv', $type, 'normal' ); + remove_meta_box( 'woothemes-settings', $type, 'normal' ); + remove_meta_box( 'commentstatusdiv', $type, 'normal' ); + remove_meta_box( 'slugdiv', $type, 'normal' ); + remove_meta_box( 'submitdiv', $type, 'side' ); + } + } + + /** + * Rename core meta boxes. + */ + public function rename_meta_boxes() { + global $post; + + // Comments/Reviews. + if ( isset( $post ) && ( 'publish' === $post->post_status || 'private' === $post->post_status ) && post_type_supports( 'product', 'comments' ) ) { + remove_meta_box( 'commentsdiv', 'product', 'normal' ); + add_meta_box( 'commentsdiv', __( 'Reviews', 'woocommerce' ), 'post_comment_meta_box', 'product', 'normal' ); + } + } + + /** + * Check if we're saving, the trigger an action based on the post type. + * + * @param int $post_id Post ID. + * @param object $post Post object. + */ + public function save_meta_boxes( $post_id, $post ) { + $post_id = absint( $post_id ); + + // $post_id and $post are required + if ( empty( $post_id ) || empty( $post ) || self::$saved_meta_boxes ) { + return; + } + + // Dont' save meta boxes for revisions or autosaves. + if ( Constants::is_true( 'DOING_AUTOSAVE' ) || is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) { + return; + } + + // Check the nonce. + if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['woocommerce_meta_nonce'] ), 'woocommerce_save_data' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + return; + } + + // Check the post being saved == the $post_id to prevent triggering this call for other save_post events. + if ( empty( $_POST['post_ID'] ) || absint( $_POST['post_ID'] ) !== $post_id ) { + return; + } + + // Check user has permission to edit. + if ( ! current_user_can( 'edit_post', $post_id ) ) { + return; + } + + // We need this save event to run once to avoid potential endless loops. This would have been perfect: + // remove_action( current_filter(), __METHOD__ ); + // But cannot be used due to https://github.com/woocommerce/woocommerce/issues/6485 + // When that is patched in core we can use the above. + self::$saved_meta_boxes = true; + + // Check the post type. + if ( in_array( $post->post_type, wc_get_order_types( 'order-meta-boxes' ), true ) ) { + do_action( 'woocommerce_process_shop_order_meta', $post_id, $post ); + } elseif ( in_array( $post->post_type, array( 'product', 'shop_coupon' ), true ) ) { + do_action( 'woocommerce_process_' . $post->post_type . '_meta', $post_id, $post ); + } + } +} + +new WC_Admin_Meta_Boxes(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-notices.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-notices.php new file mode 100644 index 0000000..70c76ee --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-notices.php @@ -0,0 +1,605 @@ + callback. + * + * @var array + */ + private static $core_notices = array( + 'update' => 'update_notice', + 'template_files' => 'template_file_check_notice', + 'legacy_shipping' => 'legacy_shipping_notice', + 'no_shipping_methods' => 'no_shipping_methods_notice', + 'regenerating_thumbnails' => 'regenerating_thumbnails_notice', + 'regenerating_lookup_table' => 'regenerating_lookup_table_notice', + 'no_secure_connection' => 'secure_connection_notice', + WC_PHP_MIN_REQUIREMENTS_NOTICE => 'wp_php_min_requirements_notice', + 'maxmind_license_key' => 'maxmind_missing_license_key_notice', + 'redirect_download_method' => 'redirect_download_method_notice', + 'uploads_directory_is_unprotected' => 'uploads_directory_is_unprotected_notice', + 'base_tables_missing' => 'base_tables_missing_notice', + ); + + /** + * Constructor. + */ + public static function init() { + self::$notices = get_option( 'woocommerce_admin_notices', array() ); + + add_action( 'switch_theme', array( __CLASS__, 'reset_admin_notices' ) ); + add_action( 'woocommerce_installed', array( __CLASS__, 'reset_admin_notices' ) ); + add_action( 'wp_loaded', array( __CLASS__, 'add_redirect_download_method_notice' ) ); + add_action( 'wp_loaded', array( __CLASS__, 'hide_notices' ) ); + // @TODO: This prevents Action Scheduler async jobs from storing empty list of notices during WC installation. + // That could lead to OBW not starting and 'Run setup wizard' notice not appearing in WP admin, which we want + // to avoid. + if ( ! WC_Install::is_new_install() || ! wc_is_running_from_async_action_scheduler() ) { + add_action( 'shutdown', array( __CLASS__, 'store_notices' ) ); + } + + if ( current_user_can( 'manage_woocommerce' ) ) { + add_action( 'admin_print_styles', array( __CLASS__, 'add_notices' ) ); + } + } + + /** + * Store notices to DB + */ + public static function store_notices() { + update_option( 'woocommerce_admin_notices', self::get_notices() ); + } + + /** + * Get notices + * + * @return array + */ + public static function get_notices() { + return self::$notices; + } + + /** + * Remove all notices. + */ + public static function remove_all_notices() { + self::$notices = array(); + } + + /** + * Reset notices for themes when switched or a new version of WC is installed. + */ + public static function reset_admin_notices() { + if ( ! self::is_ssl() ) { + self::add_notice( 'no_secure_connection' ); + } + if ( ! self::is_uploads_directory_protected() ) { + self::add_notice( 'uploads_directory_is_unprotected' ); + } + self::add_notice( 'template_files' ); + self::add_min_version_notice(); + self::add_maxmind_missing_license_key_notice(); + } + + /** + * Show a notice. + * + * @param string $name Notice name. + * @param bool $force_save Force saving inside this method instead of at the 'shutdown'. + */ + public static function add_notice( $name, $force_save = false ) { + self::$notices = array_unique( array_merge( self::get_notices(), array( $name ) ) ); + + if ( $force_save ) { + // Adding early save to prevent more race conditions with notices. + self::store_notices(); + } + } + + /** + * Remove a notice from being displayed. + * + * @param string $name Notice name. + * @param bool $force_save Force saving inside this method instead of at the 'shutdown'. + */ + public static function remove_notice( $name, $force_save = false ) { + self::$notices = array_diff( self::get_notices(), array( $name ) ); + delete_option( 'woocommerce_admin_notice_' . $name ); + + if ( $force_save ) { + // Adding early save to prevent more race conditions with notices. + self::store_notices(); + } + } + + /** + * See if a notice is being shown. + * + * @param string $name Notice name. + * + * @return boolean + */ + public static function has_notice( $name ) { + return in_array( $name, self::get_notices(), true ); + } + + /** + * Hide a notice if the GET variable is set. + */ + public static function hide_notices() { + if ( isset( $_GET['wc-hide-notice'] ) && isset( $_GET['_wc_notice_nonce'] ) ) { // WPCS: input var ok, CSRF ok. + if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['_wc_notice_nonce'] ) ), 'woocommerce_hide_notices_nonce' ) ) { // WPCS: input var ok, CSRF ok. + wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) ); + } + + if ( ! current_user_can( 'manage_woocommerce' ) ) { + wp_die( esc_html__( 'You don’t have permission to do this.', 'woocommerce' ) ); + } + + $hide_notice = sanitize_text_field( wp_unslash( $_GET['wc-hide-notice'] ) ); // WPCS: input var ok, CSRF ok. + + self::remove_notice( $hide_notice ); + + update_user_meta( get_current_user_id(), 'dismissed_' . $hide_notice . '_notice', true ); + + do_action( 'woocommerce_hide_' . $hide_notice . '_notice' ); + } + } + + /** + * Add notices + styles if needed. + */ + public static function add_notices() { + $notices = self::get_notices(); + + if ( empty( $notices ) ) { + return; + } + + $screen = get_current_screen(); + $screen_id = $screen ? $screen->id : ''; + $show_on_screens = array( + 'dashboard', + 'plugins', + ); + + // Notices should only show on WooCommerce screens, the main dashboard, and on the plugins screen. + if ( ! in_array( $screen_id, wc_get_screen_ids(), true ) && ! in_array( $screen_id, $show_on_screens, true ) ) { + return; + } + + wp_enqueue_style( 'woocommerce-activation', plugins_url( '/assets/css/activation.css', WC_PLUGIN_FILE ), array(), Constants::get_constant( 'WC_VERSION' ) ); + + // Add RTL support. + wp_style_add_data( 'woocommerce-activation', 'rtl', 'replace' ); + + foreach ( $notices as $notice ) { + if ( ! empty( self::$core_notices[ $notice ] ) && apply_filters( 'woocommerce_show_admin_notice', true, $notice ) ) { + add_action( 'admin_notices', array( __CLASS__, self::$core_notices[ $notice ] ) ); + } else { + add_action( 'admin_notices', array( __CLASS__, 'output_custom_notices' ) ); + } + } + } + + /** + * Add a custom notice. + * + * @param string $name Notice name. + * @param string $notice_html Notice HTML. + */ + public static function add_custom_notice( $name, $notice_html ) { + self::add_notice( $name ); + update_option( 'woocommerce_admin_notice_' . $name, wp_kses_post( $notice_html ) ); + } + + /** + * Output any stored custom notices. + */ + public static function output_custom_notices() { + $notices = self::get_notices(); + + if ( ! empty( $notices ) ) { + foreach ( $notices as $notice ) { + if ( empty( self::$core_notices[ $notice ] ) ) { + $notice_html = get_option( 'woocommerce_admin_notice_' . $notice ); + + if ( $notice_html ) { + include dirname( __FILE__ ) . '/views/html-notice-custom.php'; + } + } + } + } + } + + /** + * If we need to update the database, include a message with the DB update button. + */ + public static function update_notice() { + $screen = get_current_screen(); + $screen_id = $screen ? $screen->id : ''; + if ( WC()->is_wc_admin_active() && in_array( $screen_id, wc_get_screen_ids(), true ) ) { + return; + } + + if ( WC_Install::needs_db_update() ) { + $next_scheduled_date = WC()->queue()->get_next( 'woocommerce_run_update_callback', null, 'woocommerce-db-updates' ); + + if ( $next_scheduled_date || ! empty( $_GET['do_update_woocommerce'] ) ) { // WPCS: input var ok, CSRF ok. + include dirname( __FILE__ ) . '/views/html-notice-updating.php'; + } else { + include dirname( __FILE__ ) . '/views/html-notice-update.php'; + } + } else { + include dirname( __FILE__ ) . '/views/html-notice-updated.php'; + } + } + + /** + * If we have just installed, show a message with the install pages button. + * + * @deprecated 4.6.0 + */ + public static function install_notice() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Show a notice highlighting bad template files. + */ + public static function template_file_check_notice() { + $core_templates = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates' ); + $outdated = false; + + foreach ( $core_templates as $file ) { + + $theme_file = false; + if ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . $file; + } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file; + } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { + $theme_file = get_template_directory() . '/' . $file; + } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_template_directory() . '/' . WC()->template_path() . $file; + } + + if ( false !== $theme_file ) { + $core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); + $theme_version = WC_Admin_Status::get_file_version( $theme_file ); + + if ( $core_version && $theme_version && version_compare( $theme_version, $core_version, '<' ) ) { + $outdated = true; + break; + } + } + } + + if ( $outdated ) { + include dirname( __FILE__ ) . '/views/html-notice-template-check.php'; + } else { + self::remove_notice( 'template_files' ); + } + } + + /** + * Show a notice asking users to convert to shipping zones. + * + * @todo remove in 4.0.0 + */ + public static function legacy_shipping_notice() { + $maybe_load_legacy_methods = array( 'flat_rate', 'free_shipping', 'international_delivery', 'local_delivery', 'local_pickup' ); + $enabled = false; + + foreach ( $maybe_load_legacy_methods as $method ) { + $options = get_option( 'woocommerce_' . $method . '_settings' ); + if ( $options && isset( $options['enabled'] ) && 'yes' === $options['enabled'] ) { + $enabled = true; + } + } + + if ( $enabled ) { + include dirname( __FILE__ ) . '/views/html-notice-legacy-shipping.php'; + } else { + self::remove_notice( 'template_files' ); + } + } + + /** + * No shipping methods. + */ + public static function no_shipping_methods_notice() { + if ( wc_shipping_enabled() && ( empty( $_GET['page'] ) || empty( $_GET['tab'] ) || 'wc-settings' !== $_GET['page'] || 'shipping' !== $_GET['tab'] ) ) { // WPCS: input var ok, CSRF ok. + $product_count = wp_count_posts( 'product' ); + $method_count = wc_get_shipping_method_count(); + + if ( $product_count->publish > 0 && 0 === $method_count ) { + include dirname( __FILE__ ) . '/views/html-notice-no-shipping-methods.php'; + } + + if ( $method_count > 0 ) { + self::remove_notice( 'no_shipping_methods' ); + } + } + } + + /** + * Notice shown when regenerating thumbnails background process is running. + */ + public static function regenerating_thumbnails_notice() { + include dirname( __FILE__ ) . '/views/html-notice-regenerating-thumbnails.php'; + } + + /** + * Notice about secure connection. + */ + public static function secure_connection_notice() { + if ( self::is_ssl() || get_user_meta( get_current_user_id(), 'dismissed_no_secure_connection_notice', true ) ) { + return; + } + + include dirname( __FILE__ ) . '/views/html-notice-secure-connection.php'; + } + + /** + * Notice shown when regenerating thumbnails background process is running. + * + * @since 3.6.0 + */ + public static function regenerating_lookup_table_notice() { + // See if this is still relevent. + if ( ! wc_update_product_lookup_tables_is_running() ) { + self::remove_notice( 'regenerating_lookup_table' ); + return; + } + + include dirname( __FILE__ ) . '/views/html-notice-regenerating-lookup-table.php'; + } + + /** + * Add notice about minimum PHP and WordPress requirement. + * + * @since 3.6.5 + */ + public static function add_min_version_notice() { + if ( version_compare( phpversion(), WC_NOTICE_MIN_PHP_VERSION, '<' ) || version_compare( get_bloginfo( 'version' ), WC_NOTICE_MIN_WP_VERSION, '<' ) ) { + self::add_notice( WC_PHP_MIN_REQUIREMENTS_NOTICE ); + } + } + + /** + * Notice about WordPress and PHP minimum requirements. + * + * @since 3.6.5 + * @return void + */ + public static function wp_php_min_requirements_notice() { + if ( apply_filters( 'woocommerce_hide_php_wp_nag', get_user_meta( get_current_user_id(), 'dismissed_' . WC_PHP_MIN_REQUIREMENTS_NOTICE . '_notice', true ) ) ) { + self::remove_notice( WC_PHP_MIN_REQUIREMENTS_NOTICE ); + return; + } + + $old_php = version_compare( phpversion(), WC_NOTICE_MIN_PHP_VERSION, '<' ); + $old_wp = version_compare( get_bloginfo( 'version' ), WC_NOTICE_MIN_WP_VERSION, '<' ); + + // Both PHP and WordPress up to date version => no notice. + if ( ! $old_php && ! $old_wp ) { + return; + } + + if ( $old_php && $old_wp ) { + $msg = sprintf( + /* translators: 1: Minimum PHP version 2: Minimum WordPress version */ + __( 'Update required: WooCommerce will soon require PHP version %1$s and WordPress version %2$s or newer.', 'woocommerce' ), + WC_NOTICE_MIN_PHP_VERSION, + WC_NOTICE_MIN_WP_VERSION + ); + } elseif ( $old_php ) { + $msg = sprintf( + /* translators: %s: Minimum PHP version */ + __( 'Update required: WooCommerce will soon require PHP version %s or newer.', 'woocommerce' ), + WC_NOTICE_MIN_PHP_VERSION + ); + } elseif ( $old_wp ) { + $msg = sprintf( + /* translators: %s: Minimum WordPress version */ + __( 'Update required: WooCommerce will soon require WordPress version %s or newer.', 'woocommerce' ), + WC_NOTICE_MIN_WP_VERSION + ); + } + + include dirname( __FILE__ ) . '/views/html-notice-wp-php-minimum-requirements.php'; + } + + /** + * Add MaxMind missing license key notice. + * + * @since 3.9.0 + */ + public static function add_maxmind_missing_license_key_notice() { + $default_address = get_option( 'woocommerce_default_customer_address' ); + + if ( ! in_array( $default_address, array( 'geolocation', 'geolocation_ajax' ), true ) ) { + return; + } + + $integration_options = get_option( 'woocommerce_maxmind_geolocation_settings' ); + if ( empty( $integration_options['license_key'] ) ) { + self::add_notice( 'maxmind_license_key' ); + + } + } + + /** + * Add notice about Redirect-only download method, nudging user to switch to a different method instead. + */ + public static function add_redirect_download_method_notice() { + if ( 'redirect' === get_option( 'woocommerce_file_download_method' ) ) { + self::add_notice( 'redirect_download_method' ); + } else { + self::remove_notice( 'redirect_download_method' ); + } + } + + /** + * Display MaxMind missing license key notice. + * + * @since 3.9.0 + */ + public static function maxmind_missing_license_key_notice() { + $user_dismissed_notice = get_user_meta( get_current_user_id(), 'dismissed_maxmind_license_key_notice', true ); + $filter_dismissed_notice = ! apply_filters( 'woocommerce_maxmind_geolocation_display_notices', true ); + + if ( $user_dismissed_notice || $filter_dismissed_notice ) { + self::remove_notice( 'maxmind_license_key' ); + return; + } + + include dirname( __FILE__ ) . '/views/html-notice-maxmind-license-key.php'; + } + + /** + * Notice about Redirect-Only download method. + * + * @since 4.0 + */ + public static function redirect_download_method_notice() { + if ( apply_filters( 'woocommerce_hide_redirect_method_nag', get_user_meta( get_current_user_id(), 'dismissed_redirect_download_method_notice', true ) ) ) { + self::remove_notice( 'redirect_download_method' ); + return; + } + + include dirname( __FILE__ ) . '/views/html-notice-redirect-only-download.php'; + } + + /** + * Notice about uploads directory begin unprotected. + * + * @since 4.2.0 + */ + public static function uploads_directory_is_unprotected_notice() { + if ( get_user_meta( get_current_user_id(), 'dismissed_uploads_directory_is_unprotected_notice', true ) || self::is_uploads_directory_protected() ) { + self::remove_notice( 'uploads_directory_is_unprotected' ); + return; + } + + include dirname( __FILE__ ) . '/views/html-notice-uploads-directory-is-unprotected.php'; + } + + /** + * Notice about base tables missing. + */ + public static function base_tables_missing_notice() { + $notice_dismissed = apply_filters( + 'woocommerce_hide_base_tables_missing_nag', + get_user_meta( get_current_user_id(), 'dismissed_base_tables_missing_notice', true ) + ); + if ( $notice_dismissed ) { + self::remove_notice( 'base_tables_missing' ); + } + + include dirname( __FILE__ ) . '/views/html-notice-base-table-missing.php'; + } + + /** + * Determine if the store is running SSL. + * + * @return bool Flag SSL enabled. + * @since 3.5.1 + */ + protected static function is_ssl() { + $shop_page = wc_get_page_permalink( 'shop' ); + + return ( is_ssl() && 'https' === substr( $shop_page, 0, 5 ) ); + } + + /** + * Wrapper for is_plugin_active. + * + * @param string $plugin Plugin to check. + * @return boolean + */ + protected static function is_plugin_active( $plugin ) { + if ( ! function_exists( 'is_plugin_active' ) ) { + include_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + return is_plugin_active( $plugin ); + } + + /** + * Simplify Commerce is no longer in core. + * + * @deprecated 3.6.0 No longer shown. + */ + public static function simplify_commerce_notice() { + wc_deprecated_function( 'WC_Admin_Notices::simplify_commerce_notice', '3.6.0' ); + } + + /** + * Show the Theme Check notice. + * + * @deprecated 3.3.0 No longer shown. + */ + public static function theme_check_notice() { + wc_deprecated_function( 'WC_Admin_Notices::theme_check_notice', '3.3.0' ); + } + + /** + * Check if uploads directory is protected. + * + * @since 4.2.0 + * @return bool + */ + protected static function is_uploads_directory_protected() { + $cache_key = '_woocommerce_upload_directory_status'; + $status = get_transient( $cache_key ); + + // Check for cache. + if ( false !== $status ) { + return 'protected' === $status; + } + + // Get only data from the uploads directory. + $uploads = wp_get_upload_dir(); + + // Check for the "uploads/woocommerce_uploads" directory. + $response = wp_safe_remote_get( + esc_url_raw( $uploads['baseurl'] . '/woocommerce_uploads/' ), + array( + 'redirection' => 0, + ) + ); + $response_code = intval( wp_remote_retrieve_response_code( $response ) ); + $response_content = wp_remote_retrieve_body( $response ); + + // Check if returns 200 with empty content in case can open an index.html file, + // and check for non-200 codes in case the directory is protected. + $is_protected = ( 200 === $response_code && empty( $response_content ) ) || ( 200 !== $response_code ); + set_transient( $cache_key, $is_protected ? 'protected' : 'unprotected', 1 * DAY_IN_SECONDS ); + + return $is_protected; + } +} + +WC_Admin_Notices::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-permalink-settings.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-permalink-settings.php new file mode 100644 index 0000000..abcd784 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-permalink-settings.php @@ -0,0 +1,217 @@ +settings_init(); + $this->settings_save(); + } + + /** + * Init our settings. + */ + public function settings_init() { + add_settings_section( 'woocommerce-permalink', __( 'Product permalinks', 'woocommerce' ), array( $this, 'settings' ), 'permalink' ); + + add_settings_field( + 'woocommerce_product_category_slug', + __( 'Product category base', 'woocommerce' ), + array( $this, 'product_category_slug_input' ), + 'permalink', + 'optional' + ); + add_settings_field( + 'woocommerce_product_tag_slug', + __( 'Product tag base', 'woocommerce' ), + array( $this, 'product_tag_slug_input' ), + 'permalink', + 'optional' + ); + add_settings_field( + 'woocommerce_product_attribute_slug', + __( 'Product attribute base', 'woocommerce' ), + array( $this, 'product_attribute_slug_input' ), + 'permalink', + 'optional' + ); + + $this->permalinks = wc_get_permalink_structure(); + } + + /** + * Show a slug input box. + */ + public function product_category_slug_input() { + ?> + + + + + /attribute-name/attribute/ + shop would make your product links like %sshop/sample-product/. This setting affects product URLs only, not things such as product categories.', 'woocommerce' ), esc_url( home_url( '/' ) ) ) ) ); + + $shop_page_id = wc_get_page_id( 'shop' ); + $base_slug = urldecode( ( $shop_page_id > 0 && get_post( $shop_page_id ) ) ? get_page_uri( $shop_page_id ) : _x( 'shop', 'default-slug', 'woocommerce' ) ); + $product_base = _x( 'product', 'default-slug', 'woocommerce' ); + + $structures = array( + 0 => '', + 1 => '/' . trailingslashit( $base_slug ), + 2 => '/' . trailingslashit( $base_slug ) . trailingslashit( '%product_cat%' ), + ); + ?> + + + + + + + + + + + + + + + + + + + + + + + + + 0 && get_post( $shop_page_id ) ) ? get_page_uri( $shop_page_id ) : _x( 'shop', 'default-slug', 'woocommerce' ); + + if ( $shop_page_id && stristr( trim( $permalinks['product_base'], '/' ), $shop_permalink ) ) { + $permalinks['use_verbose_page_rules'] = true; + } + + update_option( 'woocommerce_permalinks', $permalinks ); + wc_restore_locale(); + } + } +} + +return new WC_Admin_Permalink_Settings(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-pointers.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-pointers.php new file mode 100644 index 0000000..1ca7302 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-pointers.php @@ -0,0 +1,287 @@ +id ) { + case 'product': + $this->create_product_tutorial(); + break; + } + } + + /** + * Pointers for creating a product. + */ + public function create_product_tutorial() { + if ( ! isset( $_GET['tutorial'] ) || ! current_user_can( 'manage_options' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + return; + } + + // These pointers will chain - they will not be shown at once. + $pointers = array( + 'pointers' => array( + 'title' => array( + 'target' => '#title', + 'next' => 'content', + 'next_trigger' => array( + 'target' => '#title', + 'event' => 'input', + ), + 'options' => array( + 'content' => '

    ' . esc_html__( 'Product name', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'Give your new product a name here. This is a required field and will be what your customers will see in your store.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'top', + 'align' => 'left', + ), + ), + ), + 'content' => array( + 'target' => '#wp-content-editor-container', + 'next' => 'product-type', + 'next_trigger' => array(), + 'options' => array( + 'content' => '

    ' . esc_html__( 'Product description', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'This is your products main body of content. Here you should describe your product in detail.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'bottom', + 'align' => 'middle', + ), + ), + ), + 'product-type' => array( + 'target' => '#product-type', + 'next' => 'virtual', + 'next_trigger' => array( + 'target' => '#product-type', + 'event' => 'change blur click', + ), + 'options' => array( + 'content' => '

    ' . esc_html__( 'Choose product type', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'Choose a type for this product. Simple is suitable for most physical goods and services (we recommend setting up a simple product for now).', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'Variable is for more complex products such as t-shirts with multiple sizes.', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'Grouped products are for grouping several simple products into one.', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'Finally, external products are for linking off-site.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'bottom', + 'align' => 'middle', + ), + ), + ), + 'virtual' => array( + 'target' => '#_virtual', + 'next' => 'downloadable', + 'next_trigger' => array( + 'target' => '#_virtual', + 'event' => 'change', + ), + 'options' => array( + 'content' => '

    ' . esc_html__( 'Virtual products', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'Check the "Virtual" box if this is a non-physical item, for example a service, which does not need shipping.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'bottom', + 'align' => 'middle', + ), + ), + ), + 'downloadable' => array( + 'target' => '#_downloadable', + 'next' => 'regular_price', + 'next_trigger' => array( + 'target' => '#_downloadable', + 'event' => 'change', + ), + 'options' => array( + 'content' => '

    ' . esc_html__( 'Downloadable products', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'If purchasing this product gives a customer access to a downloadable file, e.g. software, check this box.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'bottom', + 'align' => 'middle', + ), + ), + ), + 'regular_price' => array( + 'target' => '#_regular_price', + 'next' => 'postexcerpt', + 'next_trigger' => array( + 'target' => '#_regular_price', + 'event' => 'input', + ), + 'options' => array( + 'content' => '

    ' . esc_html__( 'Prices', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'Next you need to give your product a price.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'bottom', + 'align' => 'middle', + ), + ), + ), + 'postexcerpt' => array( + 'target' => '#postexcerpt', + 'next' => 'postimagediv', + 'next_trigger' => array( + 'target' => '#postexcerpt', + 'event' => 'input', + ), + 'options' => array( + 'content' => '

    ' . esc_html__( 'Product short description', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'Add a quick summary for your product here. This will appear on the product page under the product name.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'bottom', + 'align' => 'middle', + ), + ), + ), + 'postimagediv' => array( + 'target' => '#postimagediv', + 'next' => 'product_tag', + 'options' => array( + 'content' => '

    ' . esc_html__( 'Product images', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( "Upload or assign an image to your product here. This image will be shown in your store's catalog.", 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'right', + 'align' => 'middle', + ), + ), + ), + 'product_tag' => array( + 'target' => '#tagsdiv-product_tag', + 'next' => 'product_catdiv', + 'options' => array( + 'content' => '

    ' . esc_html__( 'Product tags', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'You can optionally "tag" your products here. Tags are a method of labeling your products to make them easier for customers to find.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'right', + 'align' => 'middle', + ), + ), + ), + 'product_catdiv' => array( + 'target' => '#product_catdiv', + 'next' => 'submitdiv', + 'options' => array( + 'content' => '

    ' . esc_html__( 'Product categories', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'Optionally assign categories to your products to make them easier to browse through and find in your store.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'right', + 'align' => 'middle', + ), + ), + ), + 'submitdiv' => array( + 'target' => '#submitdiv', + 'next' => '', + 'options' => array( + 'content' => '

    ' . esc_html__( 'Publish your product!', 'woocommerce' ) . '

    ' . + '

    ' . esc_html__( 'When you are finished editing your product, hit the "Publish" button to publish your product to your store.', 'woocommerce' ) . '

    ', + 'position' => array( + 'edge' => 'right', + 'align' => 'middle', + ), + ), + ), + ), + ); + + $this->enqueue_pointers( $pointers ); + } + + /** + * Enqueue pointers and add script to page. + * + * @param array $pointers Pointers data. + */ + public function enqueue_pointers( $pointers ) { + $pointers = rawurlencode( wp_json_encode( $pointers ) ); + wp_enqueue_style( 'wp-pointer' ); + wp_enqueue_script( 'wp-pointer' ); + wc_enqueue_js( + "jQuery( function( $ ) { + var wc_pointers = JSON.parse( decodeURIComponent( '{$pointers}' ) ); + + setTimeout( init_wc_pointers, 800 ); + + function init_wc_pointers() { + $.each( wc_pointers.pointers, function( i ) { + show_wc_pointer( i ); + return false; + }); + } + + function show_wc_pointer( id ) { + var pointer = wc_pointers.pointers[ id ]; + var options = $.extend( pointer.options, { + pointerClass: 'wp-pointer wc-pointer', + close: function() { + if ( pointer.next ) { + show_wc_pointer( pointer.next ); + } + }, + buttons: function( event, t ) { + var close = '" . esc_js( __( 'Dismiss', 'woocommerce' ) ) . "', + next = '" . esc_js( __( 'Next', 'woocommerce' ) ) . "', + button = $( '' + close + '' ), + button2 = $( '' + next + '' ), + wrapper = $( '
    ' ); + + button.bind( 'click.pointer', function(e) { + e.preventDefault(); + t.element.pointer('destroy'); + }); + + button2.bind( 'click.pointer', function(e) { + e.preventDefault(); + t.element.pointer('close'); + }); + + wrapper.append( button ); + wrapper.append( button2 ); + + return wrapper; + }, + } ); + var this_pointer = $( pointer.target ).pointer( options ); + this_pointer.pointer( 'open' ); + + if ( pointer.next_trigger ) { + $( pointer.next_trigger.target ).on( pointer.next_trigger.event, function() { + setTimeout( function() { this_pointer.pointer( 'close' ); }, 400 ); + }); + } + } + });" + ); + } +} + +new WC_Admin_Pointers(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php new file mode 100644 index 0000000..e2d1452 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php @@ -0,0 +1,992 @@ +request_data(); + + $screen_id = false; + + if ( function_exists( 'get_current_screen' ) ) { + $screen = get_current_screen(); + $screen_id = isset( $screen, $screen->id ) ? $screen->id : ''; + } + + if ( ! empty( $request_data['screen'] ) ) { + $screen_id = wc_clean( wp_unslash( $request_data['screen'] ) ); + } + + switch ( $screen_id ) { + case 'edit-shop_order': + include_once __DIR__ . '/list-tables/class-wc-admin-list-table-orders.php'; + $wc_list_table = new WC_Admin_List_Table_Orders(); + break; + case 'edit-shop_coupon': + include_once __DIR__ . '/list-tables/class-wc-admin-list-table-coupons.php'; + $wc_list_table = new WC_Admin_List_Table_Coupons(); + break; + case 'edit-product': + include_once __DIR__ . '/list-tables/class-wc-admin-list-table-products.php'; + $wc_list_table = new WC_Admin_List_Table_Products(); + break; + } + + // Ensure the table handler is only loaded once. Prevents multiple loads if a plugin calls check_ajax_referer many times. + remove_action( 'current_screen', array( $this, 'setup_screen' ) ); + remove_action( 'check_ajax_referer', array( $this, 'setup_screen' ) ); + } + + /** + * Change messages when a post type is updated. + * + * @param array $messages Array of messages. + * @return array + */ + public function post_updated_messages( $messages ) { + global $post; + + $messages['product'] = array( + 0 => '', // Unused. Messages start at index 1. + /* translators: %s: Product view URL. */ + 1 => sprintf( __( 'Product updated. View Product', 'woocommerce' ), esc_url( get_permalink( $post->ID ) ) ), + 2 => __( 'Custom field updated.', 'woocommerce' ), + 3 => __( 'Custom field deleted.', 'woocommerce' ), + 4 => __( 'Product updated.', 'woocommerce' ), + 5 => __( 'Revision restored.', 'woocommerce' ), + /* translators: %s: product url */ + 6 => sprintf( __( 'Product published. View Product', 'woocommerce' ), esc_url( get_permalink( $post->ID ) ) ), + 7 => __( 'Product saved.', 'woocommerce' ), + /* translators: %s: product url */ + 8 => sprintf( __( 'Product submitted. Preview product', 'woocommerce' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ), + 9 => sprintf( + /* translators: 1: date 2: product url */ + __( 'Product scheduled for: %1$s. Preview product', 'woocommerce' ), + '' . date_i18n( __( 'M j, Y @ G:i', 'woocommerce' ), strtotime( $post->post_date ) ) . '', + esc_url( get_permalink( $post->ID ) ) + ), + /* translators: %s: product url */ + 10 => sprintf( __( 'Product draft updated. Preview product', 'woocommerce' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) ), + ); + + $messages['shop_order'] = array( + 0 => '', // Unused. Messages start at index 1. + 1 => __( 'Order updated.', 'woocommerce' ), + 2 => __( 'Custom field updated.', 'woocommerce' ), + 3 => __( 'Custom field deleted.', 'woocommerce' ), + 4 => __( 'Order updated.', 'woocommerce' ), + 5 => __( 'Revision restored.', 'woocommerce' ), + 6 => __( 'Order updated.', 'woocommerce' ), + 7 => __( 'Order saved.', 'woocommerce' ), + 8 => __( 'Order submitted.', 'woocommerce' ), + 9 => sprintf( + /* translators: %s: date */ + __( 'Order scheduled for: %s.', 'woocommerce' ), + '' . date_i18n( __( 'M j, Y @ G:i', 'woocommerce' ), strtotime( $post->post_date ) ) . '' + ), + 10 => __( 'Order draft updated.', 'woocommerce' ), + 11 => __( 'Order updated and sent.', 'woocommerce' ), + ); + + $messages['shop_coupon'] = array( + 0 => '', // Unused. Messages start at index 1. + 1 => __( 'Coupon updated.', 'woocommerce' ), + 2 => __( 'Custom field updated.', 'woocommerce' ), + 3 => __( 'Custom field deleted.', 'woocommerce' ), + 4 => __( 'Coupon updated.', 'woocommerce' ), + 5 => __( 'Revision restored.', 'woocommerce' ), + 6 => __( 'Coupon updated.', 'woocommerce' ), + 7 => __( 'Coupon saved.', 'woocommerce' ), + 8 => __( 'Coupon submitted.', 'woocommerce' ), + 9 => sprintf( + /* translators: %s: date */ + __( 'Coupon scheduled for: %s.', 'woocommerce' ), + '' . date_i18n( __( 'M j, Y @ G:i', 'woocommerce' ), strtotime( $post->post_date ) ) . '' + ), + 10 => __( 'Coupon draft updated.', 'woocommerce' ), + ); + + return $messages; + } + + /** + * Specify custom bulk actions messages for different post types. + * + * @param array $bulk_messages Array of messages. + * @param array $bulk_counts Array of how many objects were updated. + * @return array + */ + public function bulk_post_updated_messages( $bulk_messages, $bulk_counts ) { + $bulk_messages['product'] = array( + /* translators: %s: product count */ + 'updated' => _n( '%s product updated.', '%s products updated.', $bulk_counts['updated'], 'woocommerce' ), + /* translators: %s: product count */ + 'locked' => _n( '%s product not updated, somebody is editing it.', '%s products not updated, somebody is editing them.', $bulk_counts['locked'], 'woocommerce' ), + /* translators: %s: product count */ + 'deleted' => _n( '%s product permanently deleted.', '%s products permanently deleted.', $bulk_counts['deleted'], 'woocommerce' ), + /* translators: %s: product count */ + 'trashed' => _n( '%s product moved to the Trash.', '%s products moved to the Trash.', $bulk_counts['trashed'], 'woocommerce' ), + /* translators: %s: product count */ + 'untrashed' => _n( '%s product restored from the Trash.', '%s products restored from the Trash.', $bulk_counts['untrashed'], 'woocommerce' ), + ); + + $bulk_messages['shop_order'] = array( + /* translators: %s: order count */ + 'updated' => _n( '%s order updated.', '%s orders updated.', $bulk_counts['updated'], 'woocommerce' ), + /* translators: %s: order count */ + 'locked' => _n( '%s order not updated, somebody is editing it.', '%s orders not updated, somebody is editing them.', $bulk_counts['locked'], 'woocommerce' ), + /* translators: %s: order count */ + 'deleted' => _n( '%s order permanently deleted.', '%s orders permanently deleted.', $bulk_counts['deleted'], 'woocommerce' ), + /* translators: %s: order count */ + 'trashed' => _n( '%s order moved to the Trash.', '%s orders moved to the Trash.', $bulk_counts['trashed'], 'woocommerce' ), + /* translators: %s: order count */ + 'untrashed' => _n( '%s order restored from the Trash.', '%s orders restored from the Trash.', $bulk_counts['untrashed'], 'woocommerce' ), + ); + + $bulk_messages['shop_coupon'] = array( + /* translators: %s: coupon count */ + 'updated' => _n( '%s coupon updated.', '%s coupons updated.', $bulk_counts['updated'], 'woocommerce' ), + /* translators: %s: coupon count */ + 'locked' => _n( '%s coupon not updated, somebody is editing it.', '%s coupons not updated, somebody is editing them.', $bulk_counts['locked'], 'woocommerce' ), + /* translators: %s: coupon count */ + 'deleted' => _n( '%s coupon permanently deleted.', '%s coupons permanently deleted.', $bulk_counts['deleted'], 'woocommerce' ), + /* translators: %s: coupon count */ + 'trashed' => _n( '%s coupon moved to the Trash.', '%s coupons moved to the Trash.', $bulk_counts['trashed'], 'woocommerce' ), + /* translators: %s: coupon count */ + 'untrashed' => _n( '%s coupon restored from the Trash.', '%s coupons restored from the Trash.', $bulk_counts['untrashed'], 'woocommerce' ), + ); + + return $bulk_messages; + } + + /** + * Custom bulk edit - form. + * + * @param string $column_name Column being shown. + * @param string $post_type Post type being shown. + */ + public function bulk_edit( $column_name, $post_type ) { + if ( 'price' !== $column_name || 'product' !== $post_type ) { + return; + } + + $shipping_class = get_terms( + 'product_shipping_class', + array( + 'hide_empty' => false, + ) + ); + + include WC()->plugin_path() . '/includes/admin/views/html-bulk-edit-product.php'; + } + + /** + * Custom quick edit - form. + * + * @param string $column_name Column being shown. + * @param string $post_type Post type being shown. + */ + public function quick_edit( $column_name, $post_type ) { + if ( 'price' !== $column_name || 'product' !== $post_type ) { + return; + } + + $shipping_class = get_terms( + 'product_shipping_class', + array( + 'hide_empty' => false, + ) + ); + + include WC()->plugin_path() . '/includes/admin/views/html-quick-edit-product.php'; + } + + /** + * Offers a way to hook into save post without causing an infinite loop + * when quick/bulk saving product info. + * + * @since 3.0.0 + * @param int $post_id Post ID being saved. + * @param object $post Post object being saved. + */ + public function bulk_and_quick_edit_hook( $post_id, $post ) { + remove_action( 'save_post', array( $this, 'bulk_and_quick_edit_hook' ) ); + do_action( 'woocommerce_product_bulk_and_quick_edit', $post_id, $post ); + add_action( 'save_post', array( $this, 'bulk_and_quick_edit_hook' ), 10, 2 ); + } + + /** + * Quick and bulk edit saving. + * + * @param int $post_id Post ID being saved. + * @param object $post Post object being saved. + * @return int + */ + public function bulk_and_quick_edit_save_post( $post_id, $post ) { + $request_data = $this->request_data(); + + // If this is an autosave, our form has not been submitted, so we don't want to do anything. + if ( Constants::is_true( 'DOING_AUTOSAVE' ) ) { + return $post_id; + } + + // Don't save revisions and autosaves. + if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) || 'product' !== $post->post_type || ! current_user_can( 'edit_post', $post_id ) ) { + return $post_id; + } + + // Check nonce. + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + if ( ! isset( $request_data['woocommerce_quick_edit_nonce'] ) || ! wp_verify_nonce( $request_data['woocommerce_quick_edit_nonce'], 'woocommerce_quick_edit_nonce' ) ) { + return $post_id; + } + + // Get the product and save. + $product = wc_get_product( $post ); + + if ( ! empty( $request_data['woocommerce_quick_edit'] ) ) { // WPCS: input var ok. + $this->quick_edit_save( $post_id, $product ); + } else { + $this->bulk_edit_save( $post_id, $product ); + } + + return $post_id; + } + + /** + * Quick edit. + * + * @param int $post_id Post ID being saved. + * @param WC_Product $product Product object. + */ + private function quick_edit_save( $post_id, $product ) { + $request_data = $this->request_data(); + + $data_store = $product->get_data_store(); + $old_regular_price = $product->get_regular_price(); + $old_sale_price = $product->get_sale_price(); + $input_to_props = array( + '_weight' => 'weight', + '_length' => 'length', + '_width' => 'width', + '_height' => 'height', + '_visibility' => 'catalog_visibility', + '_tax_class' => 'tax_class', + '_tax_status' => 'tax_status', + ); + + foreach ( $input_to_props as $input_var => $prop ) { + if ( isset( $request_data[ $input_var ] ) ) { + $product->{"set_{$prop}"}( wc_clean( wp_unslash( $request_data[ $input_var ] ) ) ); + } + } + + if ( isset( $request_data['_sku'] ) ) { + $sku = $product->get_sku(); + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $new_sku = (string) wc_clean( $request_data['_sku'] ); + + if ( $new_sku !== $sku ) { + if ( ! empty( $new_sku ) ) { + $unique_sku = wc_product_has_unique_sku( $post_id, $new_sku ); + if ( $unique_sku ) { + $product->set_sku( wc_clean( wp_unslash( $new_sku ) ) ); + } + } else { + $product->set_sku( '' ); + } + } + } + + if ( ! empty( $request_data['_shipping_class'] ) ) { + if ( '_no_shipping_class' === $request_data['_shipping_class'] ) { + $product->set_shipping_class_id( 0 ); + } else { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $request_data['_shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + } + + $product->set_featured( isset( $request_data['_featured'] ) ); + + if ( $product->is_type( 'simple' ) || $product->is_type( 'external' ) ) { + + if ( isset( $request_data['_regular_price'] ) ) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $new_regular_price = ( '' === $request_data['_regular_price'] ) ? '' : wc_format_decimal( $request_data['_regular_price'] ); + $product->set_regular_price( $new_regular_price ); + } else { + $new_regular_price = null; + } + if ( isset( $request_data['_sale_price'] ) ) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $new_sale_price = ( '' === $request_data['_sale_price'] ) ? '' : wc_format_decimal( $request_data['_sale_price'] ); + $product->set_sale_price( $new_sale_price ); + } else { + $new_sale_price = null; + } + + // Handle price - remove dates and set to lowest. + $price_changed = false; + + if ( ! is_null( $new_regular_price ) && $new_regular_price !== $old_regular_price ) { + $price_changed = true; + } elseif ( ! is_null( $new_sale_price ) && $new_sale_price !== $old_sale_price ) { + $price_changed = true; + } + + if ( $price_changed ) { + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + } + } + + // Handle Stock Data. + // phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $manage_stock = ! empty( $request_data['_manage_stock'] ) && 'grouped' !== $product->get_type() ? 'yes' : 'no'; + $backorders = ! empty( $request_data['_backorders'] ) ? wc_clean( $request_data['_backorders'] ) : 'no'; + if ( ! empty( $request_data['_stock_status'] ) ) { + $stock_status = wc_clean( $request_data['_stock_status'] ); + } else { + $stock_status = $product->is_type( 'variable' ) ? null : 'instock'; + } + // phpcs:enable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + $product->set_manage_stock( $manage_stock ); + $product->set_backorders( $backorders ); + + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + $stock_amount = 'yes' === $manage_stock && isset( $request_data['_stock'] ) && is_numeric( wp_unslash( $request_data['_stock'] ) ) ? wc_stock_amount( wp_unslash( $request_data['_stock'] ) ) : ''; + $product->set_stock_quantity( $stock_amount ); + } + + $product = $this->maybe_update_stock_status( $product, $stock_status ); + + $product->save(); + + do_action( 'woocommerce_product_quick_edit_save', $product ); + } + + /** + * Bulk edit. + * + * @param int $post_id Post ID being saved. + * @param WC_Product $product Product object. + */ + public function bulk_edit_save( $post_id, $product ) { + // phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash + + $request_data = $this->request_data(); + + $data_store = $product->get_data_store(); + + if ( ! empty( $request_data['change_weight'] ) && isset( $request_data['_weight'] ) ) { + $product->set_weight( wc_clean( wp_unslash( $request_data['_weight'] ) ) ); + } + + if ( ! empty( $request_data['change_dimensions'] ) ) { + if ( isset( $request_data['_length'] ) ) { + $product->set_length( wc_clean( wp_unslash( $request_data['_length'] ) ) ); + } + if ( isset( $request_data['_width'] ) ) { + $product->set_width( wc_clean( wp_unslash( $request_data['_width'] ) ) ); + } + if ( isset( $request_data['_height'] ) ) { + $product->set_height( wc_clean( wp_unslash( $request_data['_height'] ) ) ); + } + } + + if ( ! empty( $request_data['_tax_status'] ) ) { + $product->set_tax_status( wc_clean( $request_data['_tax_status'] ) ); + } + + if ( ! empty( $request_data['_tax_class'] ) ) { + $tax_class = wc_clean( wp_unslash( $request_data['_tax_class'] ) ); + if ( 'standard' === $tax_class ) { + $tax_class = ''; + } + $product->set_tax_class( $tax_class ); + } + + if ( ! empty( $request_data['_shipping_class'] ) ) { + if ( '_no_shipping_class' === $request_data['_shipping_class'] ) { + $product->set_shipping_class_id( 0 ); + } else { + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $request_data['_shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + } + + if ( ! empty( $request_data['_visibility'] ) ) { + $product->set_catalog_visibility( wc_clean( $request_data['_visibility'] ) ); + } + + if ( ! empty( $request_data['_featured'] ) ) { + // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $product->set_featured( wp_unslash( $request_data['_featured'] ) ); + // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + } + + if ( ! empty( $request_data['_sold_individually'] ) ) { + if ( 'yes' === $request_data['_sold_individually'] ) { + $product->set_sold_individually( 'yes' ); + } else { + $product->set_sold_individually( '' ); + } + } + + // Handle price - remove dates and set to lowest. + $change_price_product_types = apply_filters( 'woocommerce_bulk_edit_save_price_product_types', array( 'simple', 'external' ) ); + $can_product_type_change_price = false; + foreach ( $change_price_product_types as $product_type ) { + if ( $product->is_type( $product_type ) ) { + $can_product_type_change_price = true; + break; + } + } + + if ( $can_product_type_change_price ) { + $regular_price_changed = $this->set_new_price( $product, 'regular' ); + $sale_price_changed = $this->set_new_price( $product, 'sale' ); + + if ( $regular_price_changed || $sale_price_changed ) { + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + + if ( $product->get_regular_price() < $product->get_sale_price() ) { + $product->set_sale_price( '' ); + } + } + } + + // Handle Stock Data. + $was_managing_stock = $product->get_manage_stock() ? 'yes' : 'no'; + $backorders = $product->get_backorders(); + $backorders = ! empty( $request_data['_backorders'] ) ? wc_clean( $request_data['_backorders'] ) : $backorders; + + if ( ! empty( $request_data['_manage_stock'] ) ) { + $manage_stock = 'yes' === wc_clean( $request_data['_manage_stock'] ) && 'grouped' !== $product->get_type() ? 'yes' : 'no'; + } else { + $manage_stock = $was_managing_stock; + } + + $stock_amount = 'yes' === $manage_stock && ! empty( $request_data['change_stock'] ) && isset( $request_data['_stock'] ) ? wc_stock_amount( $request_data['_stock'] ) : $product->get_stock_quantity(); + + $product->set_manage_stock( $manage_stock ); + $product->set_backorders( $backorders ); + + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + $change_stock = absint( $request_data['change_stock'] ); + switch ( $change_stock ) { + case 2: + wc_update_product_stock( $product, $stock_amount, 'increase', true ); + break; + case 3: + wc_update_product_stock( $product, $stock_amount, 'decrease', true ); + break; + default: + wc_update_product_stock( $product, $stock_amount, 'set', true ); + break; + } + } else { + // Reset values if WooCommerce Setting - Manage Stock status is disabled. + $product->set_stock_quantity( '' ); + $product->set_manage_stock( 'no' ); + } + + $stock_status = empty( $request_data['_stock_status'] ) ? null : wc_clean( $request_data['_stock_status'] ); + $product = $this->maybe_update_stock_status( $product, $stock_status ); + + $product->save(); + + do_action( 'woocommerce_product_bulk_edit_save', $product ); + + // phpcs:enable WordPress.Security.ValidatedSanitizedInput.MissingUnslash + } + + /** + * Disable the auto-save functionality for Orders. + */ + public function disable_autosave() { + global $post; + + if ( $post && in_array( get_post_type( $post->ID ), wc_get_order_types( 'order-meta-boxes' ), true ) ) { + wp_dequeue_script( 'autosave' ); + } + } + + /** + * Output extra data on post forms. + * + * @param WP_Post $post Current post object. + */ + public function edit_form_top( $post ) { + echo ''; + } + + /** + * Change title boxes in admin. + * + * @param string $text Text to shown. + * @param WP_Post $post Current post object. + * @return string + */ + public function enter_title_here( $text, $post ) { + switch ( $post->post_type ) { + case 'product': + $text = esc_html__( 'Product name', 'woocommerce' ); + break; + case 'shop_coupon': + $text = esc_html__( 'Coupon code', 'woocommerce' ); + break; + } + return $text; + } + + /** + * Print coupon description textarea field. + * + * @param WP_Post $post Current post object. + */ + public function edit_form_after_title( $post ) { + // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped + if ( 'shop_coupon' === $post->post_type ) { + ?> + + post_type && 'post' === $screen->base ) { + $hidden = array_merge( $hidden, array( 'postcustom' ) ); + } + + return $hidden; + } + + /** + * Output product visibility options. + */ + public function product_data_visibility() { + global $post, $thepostid, $product_object; + + if ( 'product' !== $post->post_type ) { + return; + } + + $thepostid = $post->ID; + $product_object = $thepostid ? wc_get_product( $thepostid ) : new WC_Product(); + $current_visibility = $product_object->get_catalog_visibility(); + $current_featured = wc_bool_to_string( $product_object->get_featured() ); + $visibility_options = wc_get_product_visibility_options(); + ?> +
    + + + + + + + +
    + + + + + ' . esc_html__( 'This setting determines which shop pages products will be listed on.', 'woocommerce' ) . '

    '; + + foreach ( $visibility_options as $name => $label ) { + echo '
    '; + } + + echo '

    '; + ?> +

    + + +

    +
    +
    + unique_filename( $full_filename, $ext ); + // phpcs:enable WordPress.Security.NonceVerification.Missing + } + + /** + * Change filename to append random text. + * + * @param string $full_filename Original filename with extension. + * @param string $ext Extension. + * + * @return string Modified filename. + */ + public function unique_filename( $full_filename, $ext ) { + $ideal_random_char_length = 6; // Not going with a larger length because then downloaded filename will not be pretty. + $max_filename_length = 255; // Max file name length for most file systems. + $length_to_prepend = min( $ideal_random_char_length, $max_filename_length - strlen( $full_filename ) - 1 ); + + if ( 1 > $length_to_prepend ) { + return $full_filename; + } + + $suffix = strtolower( wp_generate_password( $length_to_prepend, false, false ) ); + $filename = $full_filename; + + if ( strlen( $ext ) > 0 ) { + $filename = substr( $filename, 0, strlen( $filename ) - strlen( $ext ) ); + } + + $full_filename = str_replace( + $filename, + "$filename-$suffix", + $full_filename + ); + + return $full_filename; + } + + /** + * Run a filter when uploading a downloadable product. + */ + public function woocommerce_media_upload_downloadable_product() { + do_action( 'media_upload_file' ); + } + + /** + * Grant downloadable file access to any newly added files on any existing. + * orders for this product that have previously been granted downloadable file access. + * + * @param int $product_id product identifier. + * @param int $variation_id optional product variation identifier. + * @param array $downloadable_files newly set files. + * @deprecated 3.3.0 and moved to post-data class. + */ + public function process_product_file_download_paths( $product_id, $variation_id, $downloadable_files ) { + wc_deprecated_function( 'WC_Admin_Post_Types::process_product_file_download_paths', '3.3', '' ); + WC_Post_Data::process_product_file_download_paths( $product_id, $variation_id, $downloadable_files ); + } + + /** + * When editing the shop page, we should hide templates. + * + * @param array $page_templates Templates array. + * @param string $theme Classname. + * @param WP_Post $post The current post object. + * @return array + */ + public function hide_cpt_archive_templates( $page_templates, $theme, $post ) { + $shop_page_id = wc_get_page_id( 'shop' ); + + if ( $post && absint( $post->ID ) === $shop_page_id ) { + $page_templates = array(); + } + + return $page_templates; + } + + /** + * Show a notice above the CPT archive. + * + * @param WP_Post $post The current post object. + */ + public function show_cpt_archive_notice( $post ) { + $shop_page_id = wc_get_page_id( 'shop' ); + + if ( $post && absint( $post->ID ) === $shop_page_id ) { + echo '
    '; + /* translators: %s: URL to read more about the shop page. */ + echo '

    ' . sprintf( wp_kses_post( __( 'This is the WooCommerce shop page. The shop page is a special archive that lists your products. You can read more about this here.', 'woocommerce' ) ), 'https://docs.woocommerce.com/document/woocommerce-pages/#section-4' ) . '

    '; + echo '
    '; + } + } + + /** + * Add a post display state for special WC pages in the page list table. + * + * @param array $post_states An array of post display states. + * @param WP_Post $post The current post object. + */ + public function add_display_post_states( $post_states, $post ) { + if ( wc_get_page_id( 'shop' ) === $post->ID ) { + $post_states['wc_page_for_shop'] = __( 'Shop Page', 'woocommerce' ); + } + + if ( wc_get_page_id( 'cart' ) === $post->ID ) { + $post_states['wc_page_for_cart'] = __( 'Cart Page', 'woocommerce' ); + } + + if ( wc_get_page_id( 'checkout' ) === $post->ID ) { + $post_states['wc_page_for_checkout'] = __( 'Checkout Page', 'woocommerce' ); + } + + if ( wc_get_page_id( 'myaccount' ) === $post->ID ) { + $post_states['wc_page_for_myaccount'] = __( 'My Account Page', 'woocommerce' ); + } + + if ( wc_get_page_id( 'terms' ) === $post->ID ) { + $post_states['wc_page_for_terms'] = __( 'Terms and Conditions Page', 'woocommerce' ); + } + + return $post_states; + } + + /** + * Apply product type constraints to stock status. + * + * @param WC_Product $product The product whose stock status will be adjusted. + * @param string|null $stock_status The stock status to use for adjustment, or null if no new stock status has been supplied in the request. + * @return WC_Product The supplied product, or the synced product if it was a variable product. + */ + private function maybe_update_stock_status( $product, $stock_status ) { + if ( $product->is_type( 'external' ) ) { + // External products are always in stock. + $product->set_stock_status( 'instock' ); + } elseif ( isset( $stock_status ) ) { + if ( $product->is_type( 'variable' ) && ! $product->get_manage_stock() ) { + // Stock status is determined by children. + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! $product->get_manage_stock() ) { + $child->set_stock_status( $stock_status ); + $child->save(); + } + } + $product = WC_Product_Variable::sync( $product, false ); + } else { + $product->set_stock_status( $stock_status ); + } + } + + return $product; + } + + /** + * Set the new regular or sale price if requested. + * + * @param WC_Product $product The product to set the new price for. + * @param string $price_type 'regular' or 'sale'. + * @return bool true if a new price has been set, false otherwise. + */ + private function set_new_price( $product, $price_type ) { + // phpcs:disable WordPress.Security.NonceVerification.Recommended + + $request_data = $this->request_data(); + + if ( empty( $request_data[ "change_{$price_type}_price" ] ) || ! isset( $request_data[ "_{$price_type}_price" ] ) ) { + return false; + } + + $old_price = $product->{"get_{$price_type}_price"}(); + $price_changed = false; + + $change_price = absint( $request_data[ "change_{$price_type}_price" ] ); + $raw_price = wc_clean( wp_unslash( $request_data[ "_{$price_type}_price" ] ) ); + $is_percentage = (bool) strstr( $raw_price, '%' ); + $price = wc_format_decimal( $raw_price ); + + switch ( $change_price ) { + case 1: + $new_price = $price; + break; + case 2: + if ( $is_percentage ) { + $percent = $price / 100; + $new_price = $old_price + ( $old_price * $percent ); + } else { + $new_price = $old_price + $price; + } + break; + case 3: + if ( $is_percentage ) { + $percent = $price / 100; + $new_price = max( 0, $old_price - ( $old_price * $percent ) ); + } else { + $new_price = max( 0, $old_price - $price ); + } + break; + case 4: + if ( 'sale' !== $price_type ) { + break; + } + $regular_price = $product->get_regular_price(); + if ( $is_percentage ) { + $percent = $price / 100; + $new_price = max( 0, $regular_price - ( NumberUtil::round( $regular_price * $percent, wc_get_price_decimals() ) ) ); + } else { + $new_price = max( 0, $regular_price - $price ); + } + break; + + default: + break; + } + + if ( isset( $new_price ) && $new_price !== $old_price ) { + $price_changed = true; + $new_price = NumberUtil::round( $new_price, wc_get_price_decimals() ); + $product->{"set_{$price_type}_price"}( $new_price ); + } + + return $price_changed; + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + } + + /** + * Get the current request data ($_REQUEST superglobal). + * This method is added to ease unit testing. + * + * @return array The $_REQUEST superglobal. + */ + protected function request_data() { + return $_REQUEST; + } +} + +new WC_Admin_Post_Types(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-profile.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-profile.php new file mode 100644 index 0000000..9418072 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-profile.php @@ -0,0 +1,248 @@ + array( + 'title' => __( 'Customer billing address', 'woocommerce' ), + 'fields' => array( + 'billing_first_name' => array( + 'label' => __( 'First name', 'woocommerce' ), + 'description' => '', + ), + 'billing_last_name' => array( + 'label' => __( 'Last name', 'woocommerce' ), + 'description' => '', + ), + 'billing_company' => array( + 'label' => __( 'Company', 'woocommerce' ), + 'description' => '', + ), + 'billing_address_1' => array( + 'label' => __( 'Address line 1', 'woocommerce' ), + 'description' => '', + ), + 'billing_address_2' => array( + 'label' => __( 'Address line 2', 'woocommerce' ), + 'description' => '', + ), + 'billing_city' => array( + 'label' => __( 'City', 'woocommerce' ), + 'description' => '', + ), + 'billing_postcode' => array( + 'label' => __( 'Postcode / ZIP', 'woocommerce' ), + 'description' => '', + ), + 'billing_country' => array( + 'label' => __( 'Country / Region', 'woocommerce' ), + 'description' => '', + 'class' => 'js_field-country', + 'type' => 'select', + 'options' => array( '' => __( 'Select a country / region…', 'woocommerce' ) ) + WC()->countries->get_allowed_countries(), + ), + 'billing_state' => array( + 'label' => __( 'State / County', 'woocommerce' ), + 'description' => __( 'State / County or state code', 'woocommerce' ), + 'class' => 'js_field-state', + ), + 'billing_phone' => array( + 'label' => __( 'Phone', 'woocommerce' ), + 'description' => '', + ), + 'billing_email' => array( + 'label' => __( 'Email address', 'woocommerce' ), + 'description' => '', + ), + ), + ), + 'shipping' => array( + 'title' => __( 'Customer shipping address', 'woocommerce' ), + 'fields' => array( + 'copy_billing' => array( + 'label' => __( 'Copy from billing address', 'woocommerce' ), + 'description' => '', + 'class' => 'js_copy-billing', + 'type' => 'button', + 'text' => __( 'Copy', 'woocommerce' ), + ), + 'shipping_first_name' => array( + 'label' => __( 'First name', 'woocommerce' ), + 'description' => '', + ), + 'shipping_last_name' => array( + 'label' => __( 'Last name', 'woocommerce' ), + 'description' => '', + ), + 'shipping_company' => array( + 'label' => __( 'Company', 'woocommerce' ), + 'description' => '', + ), + 'shipping_address_1' => array( + 'label' => __( 'Address line 1', 'woocommerce' ), + 'description' => '', + ), + 'shipping_address_2' => array( + 'label' => __( 'Address line 2', 'woocommerce' ), + 'description' => '', + ), + 'shipping_city' => array( + 'label' => __( 'City', 'woocommerce' ), + 'description' => '', + ), + 'shipping_postcode' => array( + 'label' => __( 'Postcode / ZIP', 'woocommerce' ), + 'description' => '', + ), + 'shipping_country' => array( + 'label' => __( 'Country / Region', 'woocommerce' ), + 'description' => '', + 'class' => 'js_field-country', + 'type' => 'select', + 'options' => array( '' => __( 'Select a country / region…', 'woocommerce' ) ) + WC()->countries->get_allowed_countries(), + ), + 'shipping_state' => array( + 'label' => __( 'State / County', 'woocommerce' ), + 'description' => __( 'State / County or state code', 'woocommerce' ), + 'class' => 'js_field-state', + ), + ), + ), + ) + ); + return $show_fields; + } + + /** + * Show Address Fields on edit user pages. + * + * @param WP_User $user + */ + public function add_customer_meta_fields( $user ) { + if ( ! apply_filters( 'woocommerce_current_user_can_edit_customer_meta_fields', current_user_can( 'manage_woocommerce' ), $user->ID ) ) { + return; + } + + $show_fields = $this->get_customer_meta_fields(); + + foreach ( $show_fields as $fieldset_key => $fieldset ) : + ?> +

    + + $field ) : ?> + + + + + +
    + + + + + + ID, $key, true ), 1, true ); ?> /> + + + + + +

    +
    + get_customer_meta_fields(); + + foreach ( $save_fields as $fieldset ) { + + foreach ( $fieldset['fields'] as $key => $field ) { + + if ( isset( $field['type'] ) && 'checkbox' === $field['type'] ) { + update_user_meta( $user_id, $key, isset( $_POST[ $key ] ) ); + } elseif ( isset( $_POST[ $key ] ) ) { + update_user_meta( $user_id, $key, wc_clean( $_POST[ $key ] ) ); + } + } + } + } + + /** + * Get user meta for a given key, with fallbacks to core user info for pre-existing fields. + * + * @since 3.1.0 + * @param int $user_id User ID of the user being edited + * @param string $key Key for user meta field + * @return string + */ + protected function get_user_meta( $user_id, $key ) { + $value = get_user_meta( $user_id, $key, true ); + $existing_fields = array( 'billing_first_name', 'billing_last_name' ); + if ( ! $value && in_array( $key, $existing_fields ) ) { + $value = get_user_meta( $user_id, str_replace( 'billing_', '', $key ), true ); + } elseif ( ! $value && ( 'billing_email' === $key ) ) { + $user = get_userdata( $user_id ); + $value = $user->user_email; + } + + return $value; + } + } + +endif; + +return new WC_Admin_Profile(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-reports.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-reports.php new file mode 100644 index 0000000..0d5dc43 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-reports.php @@ -0,0 +1,179 @@ + array( + 'title' => __( 'Orders', 'woocommerce' ), + 'reports' => array( + 'sales_by_date' => array( + 'title' => __( 'Sales by date', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + 'sales_by_product' => array( + 'title' => __( 'Sales by product', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + 'sales_by_category' => array( + 'title' => __( 'Sales by category', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + 'coupon_usage' => array( + 'title' => __( 'Coupons by date', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + 'downloads' => array( + 'title' => __( 'Customer downloads', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + ), + ), + 'customers' => array( + 'title' => __( 'Customers', 'woocommerce' ), + 'reports' => array( + 'customers' => array( + 'title' => __( 'Customers vs. guests', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + 'customer_list' => array( + 'title' => __( 'Customer list', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + ), + ), + 'stock' => array( + 'title' => __( 'Stock', 'woocommerce' ), + 'reports' => array( + 'low_in_stock' => array( + 'title' => __( 'Low in stock', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + 'out_of_stock' => array( + 'title' => __( 'Out of stock', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + 'most_stocked' => array( + 'title' => __( 'Most stocked', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + ), + ), + ); + + if ( wc_tax_enabled() ) { + $reports['taxes'] = array( + 'title' => __( 'Taxes', 'woocommerce' ), + 'reports' => array( + 'taxes_by_code' => array( + 'title' => __( 'Taxes by code', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + 'taxes_by_date' => array( + 'title' => __( 'Taxes by date', 'woocommerce' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( __CLASS__, 'get_report' ), + ), + ), + ); + } + + $reports = apply_filters( 'woocommerce_admin_reports', $reports ); + $reports = apply_filters( 'woocommerce_reports_charts', $reports ); // Backwards compatibility. + + foreach ( $reports as $key => $report_group ) { + if ( isset( $reports[ $key ]['charts'] ) ) { + $reports[ $key ]['reports'] = $reports[ $key ]['charts']; + } + + foreach ( $reports[ $key ]['reports'] as $report_key => $report ) { + if ( isset( $reports[ $key ]['reports'][ $report_key ]['function'] ) ) { + $reports[ $key ]['reports'][ $report_key ]['callback'] = $reports[ $key ]['reports'][ $report_key ]['function']; + } + } + } + + return $reports; + } + + /** + * Get a report from our reports subfolder. + * + * @param string $name + */ + public static function get_report( $name ) { + $name = sanitize_title( str_replace( '_', '-', $name ) ); + $class = 'WC_Report_' . str_replace( '-', '_', $name ); + + include_once apply_filters( 'wc_admin_reports_path', 'reports/class-wc-report-' . $name . '.php', $name, $class ); + + if ( ! class_exists( $class ) ) { + return; + } + + $report = new $class(); + $report->output_report(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-settings.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-settings.php new file mode 100644 index 0000000..b36d9a8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-settings.php @@ -0,0 +1,900 @@ +query->init_query_vars(); + WC()->query->add_endpoints(); + + do_action( 'woocommerce_settings_saved' ); + } + + /** + * Add a message. + * + * @param string $text Message. + */ + public static function add_message( $text ) { + self::$messages[] = $text; + } + + /** + * Add an error. + * + * @param string $text Message. + */ + public static function add_error( $text ) { + self::$errors[] = $text; + } + + /** + * Output messages + errors. + */ + public static function show_messages() { + if ( count( self::$errors ) > 0 ) { + foreach ( self::$errors as $error ) { + echo '

    ' . esc_html( $error ) . '

    '; + } + } elseif ( count( self::$messages ) > 0 ) { + foreach ( self::$messages as $message ) { + echo '

    ' . esc_html( $message ) . '

    '; + } + } + } + + /** + * Settings page. + * + * Handles the display of the main woocommerce settings page in admin. + */ + public static function output() { + global $current_section, $current_tab; + + $suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min'; + + do_action( 'woocommerce_settings_start' ); + + wp_enqueue_script( 'woocommerce_settings', WC()->plugin_url() . '/assets/js/admin/settings' . $suffix . '.js', array( 'jquery', 'wp-util', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'iris', 'selectWoo' ), WC()->version, true ); + + wp_localize_script( + 'woocommerce_settings', + 'woocommerce_settings_params', + array( + 'i18n_nav_warning' => __( 'The changes you made will be lost if you navigate away from this page.', 'woocommerce' ), + 'i18n_moved_up' => __( 'Item moved up', 'woocommerce' ), + 'i18n_moved_down' => __( 'Item moved down', 'woocommerce' ), + 'i18n_no_specific_countries_selected' => __( 'Selecting no country / region to sell to prevents from completing the checkout. Continue anyway?', 'woocommerce' ), + ) + ); + + // Get tabs for the settings page. + $tabs = apply_filters( 'woocommerce_settings_tabs_array', array() ); + + include dirname( __FILE__ ) . '/views/html-admin-settings.php'; + } + + /** + * Get a setting from the settings API. + * + * @param string $option_name Option name. + * @param mixed $default Default value. + * @return mixed + */ + public static function get_option( $option_name, $default = '' ) { + if ( ! $option_name ) { + return $default; + } + + // Array value. + if ( strstr( $option_name, '[' ) ) { + + parse_str( $option_name, $option_array ); + + // Option name is first key. + $option_name = current( array_keys( $option_array ) ); + + // Get value. + $option_values = get_option( $option_name, '' ); + + $key = key( $option_array[ $option_name ] ); + + if ( isset( $option_values[ $key ] ) ) { + $option_value = $option_values[ $key ]; + } else { + $option_value = null; + } + } else { + // Single value. + $option_value = get_option( $option_name, null ); + } + + if ( is_array( $option_value ) ) { + $option_value = wp_unslash( $option_value ); + } elseif ( ! is_null( $option_value ) ) { + $option_value = stripslashes( $option_value ); + } + + return ( null === $option_value ) ? $default : $option_value; + } + + /** + * Output admin fields. + * + * Loops through the woocommerce options array and outputs each field. + * + * @param array[] $options Opens array to output. + */ + public static function output_fields( $options ) { + foreach ( $options as $value ) { + if ( ! isset( $value['type'] ) ) { + continue; + } + if ( ! isset( $value['id'] ) ) { + $value['id'] = ''; + } + if ( ! isset( $value['title'] ) ) { + $value['title'] = isset( $value['name'] ) ? $value['name'] : ''; + } + if ( ! isset( $value['class'] ) ) { + $value['class'] = ''; + } + if ( ! isset( $value['css'] ) ) { + $value['css'] = ''; + } + if ( ! isset( $value['default'] ) ) { + $value['default'] = ''; + } + if ( ! isset( $value['desc'] ) ) { + $value['desc'] = ''; + } + if ( ! isset( $value['desc_tip'] ) ) { + $value['desc_tip'] = false; + } + if ( ! isset( $value['placeholder'] ) ) { + $value['placeholder'] = ''; + } + if ( ! isset( $value['suffix'] ) ) { + $value['suffix'] = ''; + } + if ( ! isset( $value['value'] ) ) { + $value['value'] = self::get_option( $value['id'], $value['default'] ); + } + + // Custom attribute handling. + $custom_attributes = array(); + + if ( ! empty( $value['custom_attributes'] ) && is_array( $value['custom_attributes'] ) ) { + foreach ( $value['custom_attributes'] as $attribute => $attribute_value ) { + $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"'; + } + } + + // Description handling. + $field_description = self::get_field_description( $value ); + $description = $field_description['description']; + $tooltip_html = $field_description['tooltip_html']; + + // Switch based on type. + switch ( $value['type'] ) { + + // Section Titles. + case 'title': + if ( ! empty( $value['title'] ) ) { + echo '

    ' . esc_html( $value['title'] ) . '

    '; + } + if ( ! empty( $value['desc'] ) ) { + echo '
    '; + echo wp_kses_post( wpautop( wptexturize( $value['desc'] ) ) ); + echo '
    '; + } + echo '' . "\n\n"; + if ( ! empty( $value['id'] ) ) { + do_action( 'woocommerce_settings_' . sanitize_title( $value['id'] ) ); + } + break; + + // Section Ends. + case 'sectionend': + if ( ! empty( $value['id'] ) ) { + do_action( 'woocommerce_settings_' . sanitize_title( $value['id'] ) . '_end' ); + } + echo '
    '; + if ( ! empty( $value['id'] ) ) { + do_action( 'woocommerce_settings_' . sanitize_title( $value['id'] ) . '_after' ); + } + break; + + // Standard text inputs and subtypes like 'number'. + case 'text': + case 'password': + case 'datetime': + case 'datetime-local': + case 'date': + case 'month': + case 'time': + case 'week': + case 'number': + case 'email': + case 'url': + case 'tel': + $option_value = $value['value']; + + ?> + + + + + + /> + + + + + + + + ‎ +   + + />‎ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
      + $val ) { + ?> +
    • + +
    • + +
    +
    + + + + + + +
    + +
    + + + + + +
    + + + +
    + ' . esc_html__( 'The settings of this image size have been disabled because its values are being overwritten by a filter.', 'woocommerce' ) . '

    '; + } + + ?> + + + + + + + id="-width" type="text" size="3" value="" /> × id="-height" type="text" size="3" value="" />px + + + + + + $value['id'], + 'id' => $value['id'], + 'sort_column' => 'menu_order', + 'sort_order' => 'ASC', + 'show_option_none' => ' ', + 'class' => $value['class'], + 'echo' => false, + 'selected' => absint( $value['value'] ), + 'post_status' => 'publish,private,draft', + ); + + if ( isset( $value['args'] ) ) { + $args = wp_parse_args( $value['args'], $args ); + } + + ?> + + + + + + + + + + + + + + + + + countries->countries; + } + + asort( $countries ); + ?> + + + + + +
    + + + __( 'Day(s)', 'woocommerce' ), + 'weeks' => __( 'Week(s)', 'woocommerce' ), + 'months' => __( 'Month(s)', 'woocommerce' ), + 'years' => __( 'Year(s)', 'woocommerce' ), + ); + $option_value = wc_parse_relative_date_option( $value['value'] ); + ?> + + + + + + + />  + + + + ' . wp_kses_post( $description ) . '

    '; + } elseif ( $description && in_array( $value['type'], array( 'checkbox' ), true ) ) { + $description = wp_kses_post( $description ); + } elseif ( $description ) { + $description = '

    ' . wp_kses_post( $description ) . '

    '; + } + + if ( $tooltip_html && in_array( $value['type'], array( 'checkbox' ), true ) ) { + $tooltip_html = '

    ' . $tooltip_html . '

    '; + } elseif ( $tooltip_html ) { + $tooltip_html = wc_help_tip( $tooltip_html ); + } + + return array( + 'description' => $description, + 'tooltip_html' => $tooltip_html, + ); + } + + /** + * Save admin fields. + * + * Loops through the woocommerce options array and outputs each field. + * + * @param array $options Options array to output. + * @param array $data Optional. Data to use for saving. Defaults to $_POST. + * @return bool + */ + public static function save_fields( $options, $data = null ) { + if ( is_null( $data ) ) { + $data = $_POST; // WPCS: input var okay, CSRF ok. + } + if ( empty( $data ) ) { + return false; + } + + // Options to update will be stored here and saved later. + $update_options = array(); + $autoload_options = array(); + + // Loop options and get values to save. + foreach ( $options as $option ) { + if ( ! isset( $option['id'] ) || ! isset( $option['type'] ) || ( isset( $option['is_option'] ) && false === $option['is_option'] ) ) { + continue; + } + + // Get posted value. + if ( strstr( $option['id'], '[' ) ) { + parse_str( $option['id'], $option_name_array ); + $option_name = current( array_keys( $option_name_array ) ); + $setting_name = key( $option_name_array[ $option_name ] ); + $raw_value = isset( $data[ $option_name ][ $setting_name ] ) ? wp_unslash( $data[ $option_name ][ $setting_name ] ) : null; + } else { + $option_name = $option['id']; + $setting_name = ''; + $raw_value = isset( $data[ $option['id'] ] ) ? wp_unslash( $data[ $option['id'] ] ) : null; + } + + // Format the value based on option type. + switch ( $option['type'] ) { + case 'checkbox': + $value = '1' === $raw_value || 'yes' === $raw_value ? 'yes' : 'no'; + break; + case 'textarea': + $value = wp_kses_post( trim( $raw_value ) ); + break; + case 'multiselect': + case 'multi_select_countries': + $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); + break; + case 'image_width': + $value = array(); + if ( isset( $raw_value['width'] ) ) { + $value['width'] = wc_clean( $raw_value['width'] ); + $value['height'] = wc_clean( $raw_value['height'] ); + $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; + } else { + $value['width'] = $option['default']['width']; + $value['height'] = $option['default']['height']; + $value['crop'] = $option['default']['crop']; + } + break; + case 'select': + $allowed_values = empty( $option['options'] ) ? array() : array_map( 'strval', array_keys( $option['options'] ) ); + if ( empty( $option['default'] ) && empty( $allowed_values ) ) { + $value = null; + break; + } + $default = ( empty( $option['default'] ) ? $allowed_values[0] : $option['default'] ); + $value = in_array( $raw_value, $allowed_values, true ) ? $raw_value : $default; + break; + case 'relative_date_selector': + $value = wc_parse_relative_date_option( $raw_value ); + break; + default: + $value = wc_clean( $raw_value ); + break; + } + + /** + * Fire an action when a certain 'type' of field is being saved. + * + * @deprecated 2.4.0 - doesn't allow manipulation of values! + */ + if ( has_action( 'woocommerce_update_option_' . sanitize_title( $option['type'] ) ) ) { + wc_deprecated_function( 'The woocommerce_update_option_X action', '2.4.0', 'woocommerce_admin_settings_sanitize_option filter' ); + do_action( 'woocommerce_update_option_' . sanitize_title( $option['type'] ), $option ); + continue; + } + + /** + * Sanitize the value of an option. + * + * @since 2.4.0 + */ + $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $option, $raw_value ); + + /** + * Sanitize the value of an option by option name. + * + * @since 2.4.0 + */ + $value = apply_filters( "woocommerce_admin_settings_sanitize_option_$option_name", $value, $option, $raw_value ); + + if ( is_null( $value ) ) { + continue; + } + + // Check if option is an array and handle that differently to single values. + if ( $option_name && $setting_name ) { + if ( ! isset( $update_options[ $option_name ] ) ) { + $update_options[ $option_name ] = get_option( $option_name, array() ); + } + if ( ! is_array( $update_options[ $option_name ] ) ) { + $update_options[ $option_name ] = array(); + } + $update_options[ $option_name ][ $setting_name ] = $value; + } else { + $update_options[ $option_name ] = $value; + } + + $autoload_options[ $option_name ] = isset( $option['autoload'] ) ? (bool) $option['autoload'] : true; + + /** + * Fire an action before saved. + * + * @deprecated 2.4.0 - doesn't allow manipulation of values! + */ + do_action( 'woocommerce_update_option', $option ); + } + + // Save all options in our array. + foreach ( $update_options as $name => $value ) { + update_option( $name, $value, $autoload_options[ $name ] ? 'yes' : 'no' ); + } + + return true; + } + + /** + * Checks which method we're using to serve downloads. + * + * If using force or x-sendfile, this ensures the .htaccess is in place. + */ + public static function check_download_folder_protection() { + $upload_dir = wp_get_upload_dir(); + $downloads_path = $upload_dir['basedir'] . '/woocommerce_uploads'; + $download_method = get_option( 'woocommerce_file_download_method' ); + $file_path = $downloads_path . '/.htaccess'; + $file_content = 'redirect' === $download_method ? 'Options -Indexes' : 'deny from all'; + $create = false; + + if ( wp_mkdir_p( $downloads_path ) && ! file_exists( $file_path ) ) { + $create = true; + } else { + $current_content = @file_get_contents( $file_path ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents + + if ( $current_content !== $file_content ) { + unlink( $file_path ); + $create = true; + } + } + + if ( $create ) { + $file_handle = @fopen( $file_path, 'wb' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen + if ( $file_handle ) { + fwrite( $file_handle, $file_content ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite + fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose + } + } + } + } + +endif; diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-setup-wizard.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-setup-wizard.php new file mode 100644 index 0000000..14c1108 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-setup-wizard.php @@ -0,0 +1,2306 @@ +countries->get_base_country(); + // https://developers.taxjar.com/api/reference/#countries . + $tax_supported_countries = array_merge( + array( 'US', 'CA', 'AU' ), + WC()->countries->get_european_union_countries() + ); + + return in_array( $country_code, $tax_supported_countries, true ); + } + + /** + * Should we show the MailChimp install option? + * True only if the user can install plugins. + * + * @deprecated 4.6.0 + * @return boolean + */ + protected function should_show_mailchimp() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + return current_user_can( 'install_plugins' ); + } + + /** + * Should we show the Facebook install option? + * True only if the user can install plugins, + * and up until the end date of the recommendation. + * + * @deprecated 4.6.0 + * @return boolean + */ + protected function should_show_facebook() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + return current_user_can( 'install_plugins' ); + } + + /** + * Is the WooCommerce Admin actively included in the WooCommerce core? + * Based on presence of a basic WC Admin function. + * + * @deprecated 4.6.0 + * @return boolean + */ + protected function is_wc_admin_active() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + return function_exists( 'wc_admin_url' ); + } + + /** + * Should we show the WooCommerce Admin install option? + * True only if the user can install plugins, + * and is running the correct version of WordPress. + * + * @see WC_Admin_Setup_Wizard::$wc_admin_plugin_minimum_wordpress_version + * + * @deprecated 4.6.0 + * @return boolean + */ + protected function should_show_wc_admin() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $wordpress_minimum_met = version_compare( get_bloginfo( 'version' ), $this->wc_admin_plugin_minimum_wordpress_version, '>=' ); + return current_user_can( 'install_plugins' ) && $wordpress_minimum_met && ! $this->is_wc_admin_active(); + } + + /** + * Should we show the new WooCommerce Admin onboarding experience? + * + * @deprecated 4.6.0 + * @return boolean + */ + protected function should_show_wc_admin_onboarding() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + // As of WooCommerce 4.1, all new sites should use the latest OBW from wc-admin package. + // This filter will allow for forcing the old wizard while we migrate e2e tests. + return ! apply_filters( 'woocommerce_setup_wizard_force_legacy', false ); + } + + /** + * Should we display the 'Recommended' step? + * True if at least one of the recommendations will be displayed. + * + * @deprecated 4.6.0 + * @return boolean + */ + protected function should_show_recommended_step() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + return $this->should_show_theme() + || $this->should_show_automated_tax() + || $this->should_show_mailchimp() + || $this->should_show_facebook() + || $this->should_show_wc_admin(); + } + + /** + * Register/enqueue scripts and styles for the Setup Wizard. + * + * Hooked onto 'admin_enqueue_scripts'. + * + * @deprecated 4.6.0 + */ + public function enqueue_scripts() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + } + + /** + * Show the setup wizard. + * + * @deprecated 4.6.0 + */ + public function setup_wizard() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + if ( empty( $_GET['page'] ) || 'wc-setup' !== $_GET['page'] ) { // WPCS: CSRF ok, input var ok. + return; + } + $default_steps = array( + 'new_onboarding' => array( + 'name' => '', + 'view' => array( $this, 'wc_setup_new_onboarding' ), + 'handler' => array( $this, 'wc_setup_new_onboarding_save' ), + ), + 'store_setup' => array( + 'name' => __( 'Store setup', 'woocommerce' ), + 'view' => array( $this, 'wc_setup_store_setup' ), + 'handler' => array( $this, 'wc_setup_store_setup_save' ), + ), + 'payment' => array( + 'name' => __( 'Payment', 'woocommerce' ), + 'view' => array( $this, 'wc_setup_payment' ), + 'handler' => array( $this, 'wc_setup_payment_save' ), + ), + 'shipping' => array( + 'name' => __( 'Shipping', 'woocommerce' ), + 'view' => array( $this, 'wc_setup_shipping' ), + 'handler' => array( $this, 'wc_setup_shipping_save' ), + ), + 'recommended' => array( + 'name' => __( 'Recommended', 'woocommerce' ), + 'view' => array( $this, 'wc_setup_recommended' ), + 'handler' => array( $this, 'wc_setup_recommended_save' ), + ), + 'activate' => array( + 'name' => __( 'Activate', 'woocommerce' ), + 'view' => array( $this, 'wc_setup_activate' ), + 'handler' => array( $this, 'wc_setup_activate_save' ), + ), + 'next_steps' => array( + 'name' => __( 'Ready!', 'woocommerce' ), + 'view' => array( $this, 'wc_setup_ready' ), + 'handler' => '', + ), + ); + + // Hide the new/improved onboarding experience screen if the user is not part of the a/b test. + if ( ! $this->should_show_wc_admin_onboarding() ) { + unset( $default_steps['new_onboarding'] ); + } + + // Hide recommended step if nothing is going to be shown there. + if ( ! $this->should_show_recommended_step() ) { + unset( $default_steps['recommended'] ); + } + + // Hide shipping step if the store is selling digital products only. + if ( 'virtual' === get_option( 'woocommerce_product_type' ) ) { + unset( $default_steps['shipping'] ); + } + + // Hide activate section when the user does not have capabilities to install plugins, think multiside admins not being a super admin. + if ( ! current_user_can( 'install_plugins' ) ) { + unset( $default_steps['activate'] ); + } + + $this->steps = apply_filters( 'woocommerce_setup_wizard_steps', $default_steps ); + $this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) ); // WPCS: CSRF ok, input var ok. + + // @codingStandardsIgnoreStart + if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { + call_user_func( $this->steps[ $this->step ]['handler'], $this ); + } + // @codingStandardsIgnoreEnd + + ob_start(); + $this->setup_wizard_header(); + $this->setup_wizard_steps(); + $this->setup_wizard_content(); + $this->setup_wizard_footer(); + exit; + } + + /** + * Get the URL for the next step's screen. + * + * @param string $step slug (default: current step). + * @return string URL for next step if a next step exists. + * Admin URL if it's the last step. + * Empty string on failure. + * + * @deprecated 4.6.0 + * @since 3.0.0 + */ + public function get_next_step_link( $step = '' ) { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + if ( ! $step ) { + $step = $this->step; + } + + $keys = array_keys( $this->steps ); + if ( end( $keys ) === $step ) { + return admin_url(); + } + + $step_index = array_search( $step, $keys, true ); + if ( false === $step_index ) { + return ''; + } + + return add_query_arg( 'step', $keys[ $step_index + 1 ], remove_query_arg( 'activate_error' ) ); + } + + /** + * Setup Wizard Header. + * + * @deprecated 4.6.0 + */ + public function setup_wizard_header() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + // same as default WP from wp-admin/admin-header.php. + $wp_version_class = 'branch-' . str_replace( array( '.', ',' ), '-', floatval( get_bloginfo( 'version' ) ) ); + + set_current_screen(); + ?> + + > + + + + <?php esc_html_e( 'WooCommerce › Setup Wizard', 'woocommerce' ); ?> + + + + + + +

    <?php esc_attr_e( 'WooCommerce', 'woocommerce' ); ?>

    + step; + ?> + + + + + + + + + steps; + $selected_features = array_filter( $this->wc_setup_activate_get_feature_list() ); + + // Hide the activate step if Jetpack is already active, unless WooCommerce Services + // features are selected, or unless the Activate step was already taken. + if ( class_exists( 'Jetpack' ) && Jetpack::is_active() && empty( $selected_features ) && 'yes' !== get_transient( 'wc_setup_activated' ) ) { + unset( $output_steps['activate'] ); + } + + unset( $output_steps['new_onboarding'] ); + + ?> +
      + $step ) { + $is_completed = array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ); + + if ( $step_key === $this->step ) { + ?> +
    1. + +
    2. + +
    3. + +
    4. + +
    + '; + if ( ! empty( $this->steps[ $this->step ]['view'] ) ) { + call_user_func( $this->steps[ $this->step ]['view'], $this ); + } + echo '
    '; + } + + /** + * Display's a prompt for users to try out the new improved WooCommerce onboarding experience in WooCommerce Admin. + * + * @deprecated 4.6.0 + */ + public function wc_setup_new_onboarding() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + ?> +
    +

    +

    <?php esc_attr_e( 'WooCommerce', 'woocommerce' ); ?>

    +

    + +
    + + +

    + +

    +
    + is_wc_admin_active() ) : ?> +

    + +
    + countries->get_base_address(); + $address_2 = WC()->countries->get_base_address_2(); + $city = WC()->countries->get_base_city(); + $state = WC()->countries->get_base_state(); + $country = WC()->countries->get_base_country(); + $postcode = WC()->countries->get_base_postcode(); + $currency = get_option( 'woocommerce_currency', 'GBP' ); + $product_type = get_option( 'woocommerce_product_type', 'both' ); + $sell_in_person = get_option( 'woocommerce_sell_in_person', 'none_selected' ); + + if ( empty( $country ) ) { + $user_location = WC_Geolocation::geolocate_ip(); + $country = $user_location['country']; + $state = $user_location['state']; + } + + $locale_info = include WC()->plugin_path() . '/i18n/locale-info.php'; + $currency_by_country = wp_list_pluck( $locale_info, 'currency_code' ); + ?> +
    + + +

    + +
    + + + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    + +
    + + + +
    + +
    + + +
    + +
    + + /> + +
    + + /> + + tracking_modal(); ?> + +

    + +

    +
    + + + close_http_connection(); + foreach ( $this->deferred_actions as $action ) { + $action['func']( ...$action['args'] ); + + // Clear the background installation flag if this is a plugin. + if ( + isset( $action['func'][1] ) && + 'background_installer' === $action['func'][1] && + isset( $action['args'][0] ) + ) { + delete_option( 'woocommerce_setup_background_installing_' . $action['args'][0] ); + } + } + } + + /** + * Helper method to queue the background install of a plugin. + * + * @param string $plugin_id Plugin id used for background install. + * @param array $plugin_info Plugin info array containing name and repo-slug, and optionally file if different from [repo-slug].php. + * + * @deprecated 4.6.0 + */ + protected function install_plugin( $plugin_id, $plugin_info ) { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + // Make sure we don't trigger multiple simultaneous installs. + if ( get_option( 'woocommerce_setup_background_installing_' . $plugin_id ) ) { + return; + } + + $plugin_file = isset( $plugin_info['file'] ) ? $plugin_info['file'] : $plugin_info['repo-slug'] . '.php'; + if ( is_plugin_active( $plugin_info['repo-slug'] . '/' . $plugin_file ) ) { + return; + } + + if ( empty( $this->deferred_actions ) ) { + add_action( 'shutdown', array( $this, 'run_deferred_actions' ) ); + } + + array_push( + $this->deferred_actions, + array( + 'func' => array( 'WC_Install', 'background_installer' ), + 'args' => array( $plugin_id, $plugin_info ), + ) + ); + + // Set the background installation flag for this plugin. + update_option( 'woocommerce_setup_background_installing_' . $plugin_id, true ); + } + + + /** + * Helper method to queue the background install of a theme. + * + * @param string $theme_id Theme id used for background install. + * + * @deprecated 4.6.0 + */ + protected function install_theme( $theme_id ) { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + if ( empty( $this->deferred_actions ) ) { + add_action( 'shutdown', array( $this, 'run_deferred_actions' ) ); + } + array_push( + $this->deferred_actions, + array( + 'func' => array( 'WC_Install', 'theme_background_installer' ), + 'args' => array( $theme_id ), + ) + ); + } + + /** + * Helper method to install Jetpack. + * + * @deprecated 4.6.0 + */ + protected function install_jetpack() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $this->install_plugin( + 'jetpack', + array( + 'name' => __( 'Jetpack', 'woocommerce' ), + 'repo-slug' => 'jetpack', + ) + ); + } + + /** + * Helper method to install WooCommerce Services and its Jetpack dependency. + * + * @deprecated 4.6.0 + */ + protected function install_woocommerce_services() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $this->install_jetpack(); + $this->install_plugin( + 'woocommerce-services', + array( + 'name' => __( 'WooCommerce Services', 'woocommerce' ), + 'repo-slug' => 'woocommerce-services', + ) + ); + } + + /** + * Retrieve info for missing WooCommerce Services and/or Jetpack plugin. + * + * @deprecated 4.6.0 + * @return array + */ + protected function get_wcs_requisite_plugins() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $plugins = array(); + if ( ! is_plugin_active( 'woocommerce-services/woocommerce-services.php' ) && ! get_option( 'woocommerce_setup_background_installing_woocommerce-services' ) ) { + $plugins[] = array( + 'name' => __( 'WooCommerce Services', 'woocommerce' ), + 'slug' => 'woocommerce-services', + ); + } + if ( ! is_plugin_active( 'jetpack/jetpack.php' ) && ! get_option( 'woocommerce_setup_background_installing_jetpack' ) ) { + $plugins[] = array( + 'name' => __( 'Jetpack', 'woocommerce' ), + 'slug' => 'jetpack', + ); + } + return $plugins; + } + + /** + * Plugin install info message markup with heading. + * + * @deprecated 4.6.0 + */ + public function plugin_install_info() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + ?> + + + + + array( + 'name' => __( 'Flat Rate', 'woocommerce' ), + 'description' => __( 'Set a fixed price to cover shipping costs.', 'woocommerce' ), + 'settings' => array( + 'cost' => array( + 'type' => 'text', + 'default_value' => __( 'Cost', 'woocommerce' ), + 'description' => __( 'What would you like to charge for flat rate shipping?', 'woocommerce' ), + 'required' => true, + ), + ), + ), + 'free_shipping' => array( + 'name' => __( 'Free Shipping', 'woocommerce' ), + 'description' => __( "Don't charge for shipping.", 'woocommerce' ), + ), + ); + + return $shipping_methods; + } + + /** + * Render the available shipping methods for a given country code. + * + * @param string $country_code Country code. + * @param string $currency_code Currency code. + * @param string $input_prefix Input prefix. + * + * @deprecated 4.6.0 + */ + protected function shipping_method_selection_form( $country_code, $currency_code, $input_prefix ) { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $selected = 'flat_rate'; + $shipping_methods = $this->get_wizard_shipping_methods( $country_code, $currency_code ); + ?> +
    +
    + +
    +
    + $method ) : ?> +

    + +

    + +
    +
    + +
    + $method ) : ?> + +
    + $setting ) : ?> + + + /> +

    + +

    + +
    + +
    + + + + + + + + + countries->get_base_country(); + $country_name = WC()->countries->countries[ $country_code ]; + $prefixed_country_name = WC()->countries->estimated_for_prefix( $country_code ) . $country_name; + $currency_code = get_woocommerce_currency(); + $existing_zones = WC_Shipping_Zones::get_zones(); + $intro_text = ''; + + if ( empty( $existing_zones ) ) { + $intro_text = sprintf( + /* translators: %s: country name including the 'the' prefix if needed */ + __( "We've created two Shipping Zones - for %s and for the rest of the world. Below you can set Flat Rate shipping costs for these Zones or offer Free Shipping.", 'woocommerce' ), + $prefixed_country_name + ); + } + + $is_wcs_labels_supported = $this->is_wcs_shipping_labels_supported_country( $country_code ); + $is_shipstation_supported = $this->is_shipstation_supported_country( $country_code ); + + ?> +

    + +

    + +
    + + + + + +
      +
    • +
      +

      +
      +
      +

      +
      +
    • +
    • +
      +

      +
      +
      + shipping_method_selection_form( $country_code, $currency_code, 'shipping_zones[domestic]' ); ?> +
      +
      + + + +
      +
    • +
    • +
      +

      +
      +
      + shipping_method_selection_form( $country_code, $currency_code, 'shipping_zones[intl]' ); ?> +
      +
      + + + +
      +
    • +
    • +

      + live rates from a specific carrier (e.g. UPS) you can find a variety of extensions available for WooCommerce here.', 'woocommerce' ), + array( + 'span' => array( + 'class' => array(), + 'data-tip' => array(), + ), + 'a' => array( + 'href' => array(), + 'target' => array(), + ), + ) + ), + esc_attr__( 'A live rate is the exact cost to ship an order, quoted directly from the shipping carrier.', 'woocommerce' ), + 'https://woocommerce.com/product-category/woocommerce-extensions/shipping-methods/shipping-carriers/' + ); + ?> +

      +
    • +
    + + +
    +

    + get_product_weight_selection(), + $this->get_product_dimension_selection() + ), + array( + 'span' => array( + 'class' => array(), + ), + 'select' => array( + 'id' => array(), + 'name' => array(), + 'class' => array(), + ), + 'option' => array( + 'value' => array(), + 'selected' => array(), + ), + ) + ); + ?> +

    +
    + +

    + plugin_install_info(); ?> + + +

    +
    + user_email; + + return $user_email; + } + + /** + * Array of all possible "in cart" gateways that can be offered. + * + * @deprecated 4.6.0 + * @return array + */ + protected function get_wizard_available_in_cart_payment_gateways() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $user_email = $this->get_current_user_email(); + + $stripe_description = '

    ' . sprintf( + /* translators: %s: URL */ + __( 'Accept debit and credit cards in 135+ currencies, methods such as Alipay, and one-touch checkout with Apple Pay. Learn more.', 'woocommerce' ), + 'https://woocommerce.com/products/stripe/' + ) . '

    '; + $paypal_checkout_description = '

    ' . sprintf( + /* translators: %s: URL */ + __( 'Safe and secure payments using credit cards or your customer\'s PayPal account. Learn more.', 'woocommerce' ), + 'https://woocommerce.com/products/woocommerce-gateway-paypal-checkout/' + ) . '

    '; + $klarna_checkout_description = '

    ' . sprintf( + /* translators: %s: URL */ + __( 'Full checkout experience with pay now, pay later and slice it. No credit card numbers, no passwords, no worries. Learn more about Klarna.', 'woocommerce' ), + 'https://woocommerce.com/products/klarna-checkout/' + ) . '

    '; + $klarna_payments_description = '

    ' . sprintf( + /* translators: %s: URL */ + __( 'Choose the payment that you want, pay now, pay later or slice it. No credit card numbers, no passwords, no worries. Learn more about Klarna.', 'woocommerce' ), + 'https://woocommerce.com/products/klarna-payments/ ' + ) . '

    '; + $square_description = '

    ' . sprintf( + /* translators: %s: URL */ + __( 'Securely accept credit and debit cards with one low rate, no surprise fees (custom rates available). Sell online and in store and track sales and inventory in one place. Learn more about Square.', 'woocommerce' ), + 'https://woocommerce.com/products/square/' + ) . '

    '; + + return array( + 'stripe' => array( + 'name' => __( 'WooCommerce Stripe Gateway', 'woocommerce' ), + 'image' => WC()->plugin_url() . '/assets/images/stripe.png', + 'description' => $stripe_description, + 'class' => 'checked stripe-logo', + 'repo-slug' => 'woocommerce-gateway-stripe', + 'settings' => array( + 'create_account' => array( + 'label' => __( 'Set up Stripe for me using this email:', 'woocommerce' ), + 'type' => 'checkbox', + 'value' => 'yes', + 'default' => 'yes', + 'placeholder' => '', + 'required' => false, + 'plugins' => $this->get_wcs_requisite_plugins(), + ), + 'email' => array( + 'label' => __( 'Stripe email address:', 'woocommerce' ), + 'type' => 'email', + 'value' => $user_email, + 'placeholder' => __( 'Stripe email address', 'woocommerce' ), + 'required' => true, + ), + ), + ), + 'ppec_paypal' => array( + 'name' => __( 'WooCommerce PayPal Checkout Gateway', 'woocommerce' ), + 'image' => WC()->plugin_url() . '/assets/images/paypal.png', + 'description' => $paypal_checkout_description, + 'enabled' => false, + 'class' => 'checked paypal-logo', + 'repo-slug' => 'woocommerce-gateway-paypal-express-checkout', + 'settings' => array( + 'reroute_requests' => array( + 'label' => __( 'Set up PayPal for me using this email:', 'woocommerce' ), + 'type' => 'checkbox', + 'value' => 'yes', + 'default' => 'yes', + 'placeholder' => '', + 'required' => false, + 'plugins' => $this->get_wcs_requisite_plugins(), + ), + 'email' => array( + 'label' => __( 'Direct payments to email address:', 'woocommerce' ), + 'type' => 'email', + 'value' => $user_email, + 'placeholder' => __( 'Email address to receive payments', 'woocommerce' ), + 'required' => true, + ), + ), + ), + 'paypal' => array( + 'name' => __( 'PayPal Standard', 'woocommerce' ), + 'description' => __( 'Accept payments via PayPal using account balance or credit card.', 'woocommerce' ), + 'image' => '', + 'settings' => array( + 'email' => array( + 'label' => __( 'PayPal email address:', 'woocommerce' ), + 'type' => 'email', + 'value' => $user_email, + 'placeholder' => __( 'PayPal email address', 'woocommerce' ), + 'required' => true, + ), + ), + ), + 'klarna_checkout' => array( + 'name' => __( 'Klarna Checkout for WooCommerce', 'woocommerce' ), + 'description' => $klarna_checkout_description, + 'image' => WC()->plugin_url() . '/assets/images/klarna-black.png', + 'enabled' => true, + 'class' => 'klarna-logo', + 'repo-slug' => 'klarna-checkout-for-woocommerce', + ), + 'klarna_payments' => array( + 'name' => __( 'Klarna Payments for WooCommerce', 'woocommerce' ), + 'description' => $klarna_payments_description, + 'image' => WC()->plugin_url() . '/assets/images/klarna-black.png', + 'enabled' => true, + 'class' => 'klarna-logo', + 'repo-slug' => 'klarna-payments-for-woocommerce', + ), + 'square' => array( + 'name' => __( 'WooCommerce Square', 'woocommerce' ), + 'description' => $square_description, + 'image' => WC()->plugin_url() . '/assets/images/square-black.png', + 'class' => 'square-logo', + 'enabled' => false, + 'repo-slug' => 'woocommerce-square', + ), + 'eway' => array( + 'name' => __( 'WooCommerce eWAY Gateway', 'woocommerce' ), + 'description' => __( 'The eWAY extension for WooCommerce allows you to take credit card payments directly on your store without redirecting your customers to a third party site to make payment.', 'woocommerce' ), + 'image' => WC()->plugin_url() . '/assets/images/eway-logo.jpg', + 'enabled' => false, + 'class' => 'eway-logo', + 'repo-slug' => 'woocommerce-gateway-eway', + ), + 'payfast' => array( + 'name' => __( 'WooCommerce PayFast Gateway', 'woocommerce' ), + 'description' => __( 'The PayFast extension for WooCommerce enables you to accept payments by Credit Card and EFT via one of South Africa’s most popular payment gateways. No setup fees or monthly subscription costs.', 'woocommerce' ), + 'image' => WC()->plugin_url() . '/assets/images/payfast.png', + 'class' => 'payfast-logo', + 'enabled' => false, + 'repo-slug' => 'woocommerce-payfast-gateway', + 'file' => 'gateway-payfast.php', + ), + ); + } + + /** + * Simple array of "in cart" gateways to show in wizard. + * + * @deprecated 4.6.0 + * @return array + */ + public function get_wizard_in_cart_payment_gateways() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $gateways = $this->get_wizard_available_in_cart_payment_gateways(); + $country = WC()->countries->get_base_country(); + $currency = get_woocommerce_currency(); + + $can_stripe = $this->is_stripe_supported_country( $country ); + $can_eway = $this->is_eway_payments_supported_country( $country ); + $can_payfast = ( 'ZA' === $country ); // South Africa. + $can_paypal = $this->is_paypal_supported_currency( $currency ); + + if ( ! current_user_can( 'install_plugins' ) ) { + return $can_paypal ? array( 'paypal' => $gateways['paypal'] ) : array(); + } + + $klarna_or_square = false; + + if ( $this->is_klarna_checkout_supported_country( $country ) ) { + $klarna_or_square = 'klarna_checkout'; + } elseif ( $this->is_klarna_payments_supported_country( $country ) ) { + $klarna_or_square = 'klarna_payments'; + } elseif ( $this->is_square_supported_country( $country ) && get_option( 'woocommerce_sell_in_person' ) ) { + $klarna_or_square = 'square'; + } + + $offered_gateways = array(); + + if ( $can_stripe ) { + $gateways['stripe']['enabled'] = true; + $gateways['stripe']['featured'] = true; + $offered_gateways += array( 'stripe' => $gateways['stripe'] ); + } elseif ( $can_paypal ) { + $gateways['ppec_paypal']['enabled'] = true; + } + + if ( $klarna_or_square ) { + if ( in_array( $klarna_or_square, array( 'klarna_checkout', 'klarna_payments' ), true ) ) { + $gateways[ $klarna_or_square ]['enabled'] = true; + $gateways[ $klarna_or_square ]['featured'] = false; + $offered_gateways += array( + $klarna_or_square => $gateways[ $klarna_or_square ], + ); + } else { + $offered_gateways += array( + $klarna_or_square => $gateways[ $klarna_or_square ], + ); + } + } + + if ( $can_paypal ) { + $offered_gateways += array( 'ppec_paypal' => $gateways['ppec_paypal'] ); + } + + if ( $can_eway ) { + $offered_gateways += array( 'eway' => $gateways['eway'] ); + } + + if ( $can_payfast ) { + $offered_gateways += array( 'payfast' => $gateways['payfast'] ); + } + + return $offered_gateways; + } + + /** + * Simple array of "manual" gateways to show in wizard. + * + * @deprecated 4.6.0 + * @return array + */ + public function get_wizard_manual_payment_gateways() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $gateways = array( + 'cheque' => array( + 'name' => _x( 'Check payments', 'Check payment method', 'woocommerce' ), + 'description' => __( 'A simple offline gateway that lets you accept a check as method of payment.', 'woocommerce' ), + 'image' => '', + 'class' => '', + ), + 'bacs' => array( + 'name' => __( 'Bank transfer (BACS) payments', 'woocommerce' ), + 'description' => __( 'A simple offline gateway that lets you accept BACS payment.', 'woocommerce' ), + 'image' => '', + 'class' => '', + ), + 'cod' => array( + 'name' => __( 'Cash on delivery', 'woocommerce' ), + 'description' => __( 'A simple offline gateway that lets you accept cash on delivery.', 'woocommerce' ), + 'image' => '', + 'class' => '', + ), + ); + + return $gateways; + } + + /** + * Display service item in list. + * + * @param int $item_id Item ID. + * @param array $item_info Item info array. + * + * @deprecated 4.6.0 + */ + public function display_service_item( $item_id, $item_info ) { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $item_class = 'wc-wizard-service-item'; + if ( isset( $item_info['class'] ) ) { + $item_class .= ' ' . $item_info['class']; + } + + $previously_saved_settings = get_option( 'woocommerce_' . $item_id . '_settings' ); + + // Show the user-saved state if it was previously saved. + // Otherwise, rely on the item info. + if ( is_array( $previously_saved_settings ) ) { + $should_enable_toggle = ( isset( $previously_saved_settings['enabled'] ) && 'yes' === $previously_saved_settings['enabled'] ) ? true : ( isset( $item_info['enabled'] ) && $item_info['enabled'] ); + } else { + $should_enable_toggle = isset( $item_info['enabled'] ) && $item_info['enabled']; + } + + $plugins = null; + if ( isset( $item_info['repo-slug'] ) ) { + $plugin = array( + 'slug' => $item_info['repo-slug'], + 'name' => $item_info['name'], + ); + $plugins = array( $plugin ); + } + + ?> +
  • +
    + + <?php echo esc_attr( $item_info['name'] ); ?> + +

    + +
    +
    + + + data-plugins="" + /> + +
    +
    + + +
    + $setting ) : ?> + + +
    + + + + data-plugins="" + /> + + + +
    + +
    + +
    +
  • + is_featured_service( $service ); + } + + /** + * Payment Step. + * + * @deprecated 4.6.0 + */ + public function wc_setup_payment() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $featured_gateways = array_filter( $this->get_wizard_in_cart_payment_gateways(), array( $this, 'is_featured_service' ) ); + $in_cart_gateways = array_filter( $this->get_wizard_in_cart_payment_gateways(), array( $this, 'is_not_featured_service' ) ); + $manual_gateways = $this->get_wizard_manual_payment_gateways(); + ?> +

    +
    +

    + Additional payment methods can be installed later.', 'woocommerce' ), + array( + 'a' => array( + 'href' => array(), + 'target' => array(), + ), + ) + ), + esc_url( admin_url( 'admin.php?page=wc-addons§ion=payment-gateways' ) ) + ); + ?> +

    + + + + +
      + $gateway ) { + $this->display_service_item( $gateway_id, $gateway ); + } + ?> +
    + +
      +
    • +
      + +
      +
      + +
      +
      + + +
      +
    • + $gateway ) { + $this->display_service_item( $gateway_id, $gateway ); + } + ?> +
    +

    + plugin_install_info(); ?> + + +

    +
    + + + +

    +

    + +

    +
    + +

    + plugin_install_info(); ?> + + +

    +
    + get_next_step_link() ) ) ); + exit; + } + } + + /** + * + * @deprecated 4.6.0 + */ + protected function wc_setup_activate_get_feature_list() { + $features = array(); + + $stripe_settings = get_option( 'woocommerce_stripe_settings', false ); + $stripe_enabled = is_array( $stripe_settings ) + && isset( $stripe_settings['create_account'] ) && 'yes' === $stripe_settings['create_account'] + && isset( $stripe_settings['enabled'] ) && 'yes' === $stripe_settings['enabled']; + $ppec_settings = get_option( 'woocommerce_ppec_paypal_settings', false ); + $ppec_enabled = is_array( $ppec_settings ) + && isset( $ppec_settings['reroute_requests'] ) && 'yes' === $ppec_settings['reroute_requests'] + && isset( $ppec_settings['enabled'] ) && 'yes' === $ppec_settings['enabled']; + + $features['payment'] = $stripe_enabled || $ppec_enabled; + $features['taxes'] = (bool) get_option( 'woocommerce_setup_automated_taxes', false ); + $features['labels'] = (bool) get_option( 'woocommerce_setup_shipping_labels', false ); + + return $features; + } + + /** + * + * @deprecated 4.6.0 + */ + protected function wc_setup_activate_get_feature_list_str() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $features = $this->wc_setup_activate_get_feature_list(); + if ( $features['payment'] && $features['taxes'] && $features['labels'] ) { + return __( 'payment setup, automated taxes and discounted shipping labels', 'woocommerce' ); + } else if ( $features['payment'] && $features['taxes'] ) { + return __( 'payment setup and automated taxes', 'woocommerce' ); + } else if ( $features['payment'] && $features['labels'] ) { + return __( 'payment setup and discounted shipping labels', 'woocommerce' ); + } else if ( $features['payment'] ) { + return __( 'payment setup', 'woocommerce' ); + } else if ( $features['taxes'] && $features['labels'] ) { + return __( 'automated taxes and discounted shipping labels', 'woocommerce' ); + } else if ( $features['taxes'] ) { + return __( 'automated taxes', 'woocommerce' ); + } else if ( $features['labels'] ) { + return __( 'discounted shipping labels', 'woocommerce' ); + } + return false; + } + + /** + * Activate step. + * + * @deprecated 4.6.0 + */ + public function wc_setup_activate() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $this->wc_setup_activate_actions(); + + $jetpack_connected = class_exists( 'Jetpack' ) && Jetpack::is_active(); + + $has_jetpack_error = false; + if ( isset( $_GET['activate_error'] ) ) { + $has_jetpack_error = true; + + $title = __( "Sorry, we couldn't connect your store to Jetpack", 'woocommerce' ); + + $error_message = $this->get_activate_error_message( sanitize_text_field( wp_unslash( $_GET['activate_error'] ) ) ); + $description = $error_message; + } else { + $feature_list = $this->wc_setup_activate_get_feature_list_str(); + + $description = false; + + if ( $feature_list ) { + if ( ! $jetpack_connected ) { + /* translators: %s: list of features, potentially comma separated */ + $description_base = __( 'Your store is almost ready! To activate services like %s, just connect with Jetpack.', 'woocommerce' ); + } else { + $description_base = __( 'Thanks for using Jetpack! Your store is almost ready: to activate services like %s, just connect your store.', 'woocommerce' ); + } + $description = sprintf( $description_base, $feature_list ); + } + + if ( ! $jetpack_connected ) { + $title = $feature_list ? + __( 'Connect your store to Jetpack', 'woocommerce' ) : + __( 'Connect your store to Jetpack to enable extra features', 'woocommerce' ); + $button_text = __( 'Continue with Jetpack', 'woocommerce' ); + } elseif ( $feature_list ) { + $title = __( 'Connect your store to activate WooCommerce Services', 'woocommerce' ); + $button_text = __( 'Continue with WooCommerce Services', 'woocommerce' ); + } else { + wp_redirect( esc_url_raw( $this->get_next_step_link() ) ); + exit; + } + } + ?> +

    +

    + + +
    + + +
    + + + + + +

    + + + +

    + +

    + Terms of Service and to share details with WordPress.com', 'woocommerce' ) ), + 'https://wordpress.com/tos', + 'https://jetpack.com/support/what-data-does-jetpack-sync' + ); + ?> +

    +
    +

    + +

    + + +
    + +

    + +

    +
      +
    • +

      + +

      +

      + +

      +
    • +
    • +

      + +

      +

      + +

      +
    • +
    • +

      + +

      +

      + +

      +
    • +
    • +

      + +

      +

      + +

      +
    • +
    + + + __( "Sorry! We tried, but we couldn't connect Jetpack just now 😭. Please go to the Plugins tab to connect Jetpack, so that you can finish setting up your store.", 'woocommerce' ), + 'jetpack_cant_be_installed' => __( "Sorry! We tried, but we couldn't install Jetpack for you 😭. Please go to the Plugins tab to install it, and finish setting up your store.", 'woocommerce' ), + 'register_http_request_failed' => __( "Sorry! We couldn't contact Jetpack just now 😭. Please make sure that your site is visible over the internet, and that it accepts incoming and outgoing requests via curl. You can also try to connect to Jetpack again, and if you run into any more issues, please contact support.", 'woocommerce' ), + 'siteurl_private_ip_dev' => __( "Your site might be on a private network. Jetpack can only connect to public sites. Please make sure your site is visible over the internet, and then try connecting again 🙏." , 'woocommerce' ), + ); + } + + /** + * + * @deprecated 4.6.0 + */ + protected function get_activate_error_message( $code = '' ) { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + $errors = $this->get_all_activate_errors(); + return array_key_exists( $code, $errors ) ? $errors[ $code ] : $errors['default']; + } + + /** + * Activate step save. + * + * Install, activate, and launch connection flow for Jetpack. + * + * @deprecated 4.6.0 + */ + public function wc_setup_activate_save() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + } + + /** + * Final step. + * + * @deprecated 4.6.0 + */ + public function wc_setup_ready() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', 'Onboarding is maintained in WooCommerce Admin.' ); + // We've made it! Don't prompt the user to run the wizard again. + WC_Admin_Notices::remove_notice( 'install', true ); + + $user_email = $this->get_current_user_email(); + $docs_url = 'https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/?utm_source=setupwizard&utm_medium=product&utm_content=docs&utm_campaign=woocommerceplugin'; + $help_text = sprintf( + /* translators: %1$s: link to docs */ + __( 'Visit WooCommerce.com to learn more about getting started.', 'woocommerce' ), + $docs_url + ); + ?> +

    + +
    +

    +
    + +
    +
    + + +

    + execute_tool( $action ); + + $tool = $tools[ $action ]; + $tool = array( + 'id' => $action, + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ); + $tool = array_merge( $tool, $response ); + + /** + * Fires after a WooCommerce system status tool has been executed. + * + * @param array $tool Details about the tool that has been executed. + */ + do_action( 'woocommerce_system_status_tool_executed', $tool ); + } else { + $response = array( + 'success' => false, + 'message' => __( 'Tool does not exist.', 'woocommerce' ), + ); + } + + if ( $response['success'] ) { + echo '

    ' . esc_html( $response['message'] ) . '

    '; + } else { + echo '

    ' . esc_html( $response['message'] ) . '

    '; + } + } + + // Display message if settings settings have been saved. + if ( isset( $_REQUEST['settings-updated'] ) ) { // WPCS: input var ok. + echo '

    ' . esc_html__( 'Your changes have been saved.', 'woocommerce' ) . '

    '; + } + + include_once __DIR__ . '/views/html-admin-page-status-tools.php'; + } + + /** + * Get tools. + * + * @return array of tools + */ + public static function get_tools() { + $tools_controller = new WC_REST_System_Status_Tools_Controller(); + return $tools_controller->get_tools(); + } + + /** + * Show the logs page. + */ + public static function status_logs() { + $log_handler = Constants::get_constant( 'WC_LOG_HANDLER' ); + + if ( 'WC_Log_Handler_DB' === $log_handler ) { + self::status_logs_db(); + } else { + self::status_logs_file(); + } + } + + /** + * Show the log page contents for file log handler. + */ + public static function status_logs_file() { + $logs = self::scan_log_files(); + + if ( ! empty( $_REQUEST['log_file'] ) && isset( $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ] ) ) { // WPCS: input var ok, CSRF ok. + $viewed_log = $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ]; // WPCS: input var ok, CSRF ok. + } elseif ( ! empty( $logs ) ) { + $viewed_log = current( $logs ); + } + + $handle = ! empty( $viewed_log ) ? self::get_log_file_handle( $viewed_log ) : ''; + + if ( ! empty( $_REQUEST['handle'] ) ) { // WPCS: input var ok, CSRF ok. + self::remove_log(); + } + + include_once __DIR__ . '/views/html-admin-page-status-logs.php'; + } + + /** + * Show the log page contents for db log handler. + */ + public static function status_logs_db() { + if ( ! empty( $_REQUEST['flush-logs'] ) ) { // WPCS: input var ok, CSRF ok. + self::flush_db_logs(); + } + + if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['log'] ) ) { // WPCS: input var ok, CSRF ok. + self::log_table_bulk_actions(); + } + + $log_table_list = new WC_Admin_Log_Table_List(); + $log_table_list->prepare_items(); + + include_once __DIR__ . '/views/html-admin-page-status-logs-db.php'; + } + + /** + * Retrieve metadata from a file. Based on WP Core's get_file_data function. + * + * @since 2.1.1 + * @param string $file Path to the file. + * @return string + */ + public static function get_file_version( $file ) { + + // Avoid notices if file does not exist. + if ( ! file_exists( $file ) ) { + return ''; + } + + // We don't need to write to the file, so just open for reading. + $fp = fopen( $file, 'r' ); // @codingStandardsIgnoreLine. + + // Pull only the first 8kiB of the file in. + $file_data = fread( $fp, 8192 ); // @codingStandardsIgnoreLine. + + // PHP will close file handle, but we are good citizens. + fclose( $fp ); // @codingStandardsIgnoreLine. + + // Make sure we catch CR-only line endings. + $file_data = str_replace( "\r", "\n", $file_data ); + $version = ''; + + if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( '@version', '/' ) . '(.*)$/mi', $file_data, $match ) && $match[1] ) { + $version = _cleanup_header_comment( $match[1] ); + } + + return $version; + } + + /** + * Return the log file handle. + * + * @param string $filename Filename to get the handle for. + * @return string + */ + public static function get_log_file_handle( $filename ) { + return substr( $filename, 0, strlen( $filename ) > 48 ? strlen( $filename ) - 48 : strlen( $filename ) - 4 ); + } + + /** + * Scan the template files. + * + * @param string $template_path Path to the template directory. + * @return array + */ + public static function scan_template_files( $template_path ) { + $files = @scandir( $template_path ); // @codingStandardsIgnoreLine. + $result = array(); + + if ( ! empty( $files ) ) { + + foreach ( $files as $key => $value ) { + + if ( ! in_array( $value, array( '.', '..' ), true ) ) { + + if ( is_dir( $template_path . DIRECTORY_SEPARATOR . $value ) ) { + $sub_files = self::scan_template_files( $template_path . DIRECTORY_SEPARATOR . $value ); + foreach ( $sub_files as $sub_file ) { + $result[] = $value . DIRECTORY_SEPARATOR . $sub_file; + } + } else { + $result[] = $value; + } + } + } + } + return $result; + } + + /** + * Scan the log files. + * + * @return array + */ + public static function scan_log_files() { + return WC_Log_Handler_File::get_log_files(); + } + + /** + * Get latest version of a theme by slug. + * + * @param object $theme WP_Theme object. + * @return string Version number if found. + */ + public static function get_latest_theme_version( $theme ) { + include_once ABSPATH . 'wp-admin/includes/theme.php'; + + $api = themes_api( + 'theme_information', + array( + 'slug' => $theme->get_stylesheet(), + 'fields' => array( + 'sections' => false, + 'tags' => false, + ), + ) + ); + + $update_theme_version = 0; + + // Check .org for updates. + if ( is_object( $api ) && ! is_wp_error( $api ) ) { + $update_theme_version = $api->version; + } elseif ( strstr( $theme->{'Author URI'}, 'woothemes' ) ) { // Check WooThemes Theme Version. + $theme_dir = substr( strtolower( str_replace( ' ', '', $theme->Name ) ), 0, 45 ); // @codingStandardsIgnoreLine. + $theme_version_data = get_transient( $theme_dir . '_version_data' ); + + if ( false === $theme_version_data ) { + $theme_changelog = wp_safe_remote_get( 'http://dzv365zjfbd8v.cloudfront.net/changelogs/' . $theme_dir . '/changelog.txt' ); + $cl_lines = explode( "\n", wp_remote_retrieve_body( $theme_changelog ) ); + if ( ! empty( $cl_lines ) ) { + foreach ( $cl_lines as $line_num => $cl_line ) { + if ( preg_match( '/^[0-9]/', $cl_line ) ) { + $theme_date = str_replace( '.', '-', trim( substr( $cl_line, 0, strpos( $cl_line, '-' ) ) ) ); + $theme_version = preg_replace( '~[^0-9,.]~', '', stristr( $cl_line, 'version' ) ); + $theme_update = trim( str_replace( '*', '', $cl_lines[ $line_num + 1 ] ) ); + $theme_version_data = array( + 'date' => $theme_date, + 'version' => $theme_version, + 'update' => $theme_update, + 'changelog' => $theme_changelog, + ); + set_transient( $theme_dir . '_version_data', $theme_version_data, DAY_IN_SECONDS ); + break; + } + } + } + } + + if ( ! empty( $theme_version_data['version'] ) ) { + $update_theme_version = $theme_version_data['version']; + } + } + + return $update_theme_version; + } + + /** + * Remove/delete the chosen file. + */ + public static function remove_log() { + if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( wp_unslash( $_REQUEST['_wpnonce'] ), 'remove_log' ) ) { // WPCS: input var ok, sanitization ok. + wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) ); + } + + if ( ! empty( $_REQUEST['handle'] ) ) { // WPCS: input var ok. + $log_handler = new WC_Log_Handler_File(); + $log_handler->remove( wp_unslash( $_REQUEST['handle'] ) ); // WPCS: input var ok, sanitization ok. + } + + wp_safe_redirect( esc_url_raw( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) ); + exit(); + } + + /** + * Clear DB log table. + * + * @since 3.0.0 + */ + private static function flush_db_logs() { + if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-status-logs' ) ) { // WPCS: input var ok, sanitization ok. + wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) ); + } + + WC_Log_Handler_DB::flush(); + + wp_safe_redirect( esc_url_raw( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) ); + exit(); + } + + /** + * Bulk DB log table actions. + * + * @since 3.0.0 + */ + private static function log_table_bulk_actions() { + if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-status-logs' ) ) { // WPCS: input var ok, sanitization ok. + wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) ); + } + + $log_ids = array_map( 'absint', (array) isset( $_REQUEST['log'] ) ? wp_unslash( $_REQUEST['log'] ) : array() ); // WPCS: input var ok, sanitization ok. + + if ( ( isset( $_REQUEST['action'] ) && 'delete' === $_REQUEST['action'] ) || ( isset( $_REQUEST['action2'] ) && 'delete' === $_REQUEST['action2'] ) ) { // WPCS: input var ok, sanitization ok. + WC_Log_Handler_DB::delete( $log_ids ); + wp_safe_redirect( esc_url_raw( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) ); + exit(); + } + } + + /** + * Prints table info if a base table is not present. + */ + private static function output_tables_info() { + $missing_tables = WC_Install::verify_base_tables( false ); + if ( 0 === count( $missing_tables ) ) { + return; + } + ?> + +
    + + + + + + ' . $plugin_name . ''; + } + + $has_newer_version = false; + $version_string = $plugin['version']; + $network_string = ''; + if ( strstr( $plugin['url'], 'woothemes.com' ) || strstr( $plugin['url'], 'woocommerce.com' ) ) { + if ( ! empty( $plugin['version_latest'] ) && version_compare( $plugin['version_latest'], $plugin['version'], '>' ) ) { + /* translators: 1: current version. 2: latest version */ + $version_string = sprintf( __( '%1$s (update to version %2$s is available)', 'woocommerce' ), $plugin['version'], $plugin['version_latest'] ); + } + + if ( false !== $plugin['network_activated'] ) { + $network_string = ' – ' . esc_html__( 'Network enabled', 'woocommerce' ) . ''; + } + } + $untested_string = ''; + if ( array_key_exists( $plugin['plugin'], $untested_plugins ) ) { + $untested_string = ' – '; + + /* translators: %s: version */ + $untested_string .= esc_html( sprintf( __( 'Installed version not tested with active version of WooCommerce %s', 'woocommerce' ), $wc_version ) ); + + $untested_string .= ''; + } + ?> + + +   + + + + + default_cat_id = get_option( 'default_product_cat', 0 ); + + // Category/term ordering. + add_action( 'create_term', array( $this, 'create_term' ), 5, 3 ); + + // Add form. + add_action( 'product_cat_add_form_fields', array( $this, 'add_category_fields' ) ); + add_action( 'product_cat_edit_form_fields', array( $this, 'edit_category_fields' ), 10 ); + add_action( 'created_term', array( $this, 'save_category_fields' ), 10, 3 ); + add_action( 'edit_term', array( $this, 'save_category_fields' ), 10, 3 ); + + // Add columns. + add_filter( 'manage_edit-product_cat_columns', array( $this, 'product_cat_columns' ) ); + add_filter( 'manage_product_cat_custom_column', array( $this, 'product_cat_column' ), 10, 3 ); + + // Add row actions. + add_filter( 'product_cat_row_actions', array( $this, 'product_cat_row_actions' ), 10, 2 ); + add_filter( 'admin_init', array( $this, 'handle_product_cat_row_actions' ) ); + + // Taxonomy page descriptions. + add_action( 'product_cat_pre_add_form', array( $this, 'product_cat_description' ) ); + add_action( 'after-product_cat-table', array( $this, 'product_cat_notes' ) ); + + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + if ( ! empty( $attribute_taxonomies ) ) { + foreach ( $attribute_taxonomies as $attribute ) { + add_action( 'pa_' . $attribute->attribute_name . '_pre_add_form', array( $this, 'product_attribute_description' ) ); + } + } + + // Maintain hierarchy of terms. + add_filter( 'wp_terms_checklist_args', array( $this, 'disable_checked_ontop' ) ); + + // Admin footer scripts for this product categories admin screen. + add_action( 'admin_footer', array( $this, 'scripts_at_product_cat_screen_footer' ) ); + } + + /** + * Order term when created (put in position 0). + * + * @param mixed $term_id Term ID. + * @param mixed $tt_id Term taxonomy ID. + * @param string $taxonomy Taxonomy slug. + */ + public function create_term( $term_id, $tt_id = '', $taxonomy = '' ) { + if ( 'product_cat' != $taxonomy && ! taxonomy_is_product_attribute( $taxonomy ) ) { + return; + } + + $meta_name = taxonomy_is_product_attribute( $taxonomy ) ? 'order_' . esc_attr( $taxonomy ) : 'order'; + + update_term_meta( $term_id, $meta_name, 0 ); + } + + /** + * When a term is deleted, delete its meta. + * + * @deprecated 3.6.0 No longer needed. + * @param mixed $term_id Term ID. + */ + public function delete_term( $term_id ) { + wc_deprecated_function( 'delete_term', '3.6' ); + } + + /** + * Category thumbnail fields. + */ + public function add_category_fields() { + ?> +
    + + +
    +
    + +
    +
    + + + +
    + +
    +
    + term_id, 'display_type', true ); + $thumbnail_id = absint( get_term_meta( $term->term_id, 'thumbnail_id', true ) ); + + if ( $thumbnail_id ) { + $image = wp_get_attachment_thumb_url( $thumbnail_id ); + } else { + $image = wc_placeholder_img_src(); + } + ?> + + + + + + + + + +
    +
    + + + +
    + +
    + + + array() ) + ); + } + + /** + * Add some notes to describe the behavior of the default category. + */ + public function product_cat_notes() { + $category_id = get_option( 'default_product_cat', 0 ); + $category = get_term( $category_id, 'product_cat' ); + $category_name = ( ! $category || is_wp_error( $category ) ) ? _x( 'Uncategorized', 'Default category slug', 'woocommerce' ) : $category->name; + ?> +
    +

    +
    + ' . esc_html( $category_name ) . '' + ); + ?> +

    +
    +
    Note: Deleting a term will remove it from all products and variations to which it has been assigned. Recreating a term will not automatically assign it back to products.', 'woocommerce' ) ), + array( 'p' => array() ) + ); + } + + /** + * Thumbnail column added to category admin. + * + * @param mixed $columns Columns array. + * @return array + */ + public function product_cat_columns( $columns ) { + $new_columns = array(); + + if ( isset( $columns['cb'] ) ) { + $new_columns['cb'] = $columns['cb']; + unset( $columns['cb'] ); + } + + $new_columns['thumb'] = __( 'Image', 'woocommerce' ); + + $columns = array_merge( $new_columns, $columns ); + $columns['handle'] = ''; + + return $columns; + } + + /** + * Adjust row actions. + * + * @param array $actions Array of actions. + * @param object $term Term object. + * @return array + */ + public function product_cat_row_actions( $actions, $term ) { + $default_category_id = absint( get_option( 'default_product_cat', 0 ) ); + + if ( $default_category_id !== $term->term_id && current_user_can( 'edit_term', $term->term_id ) ) { + $actions['make_default'] = sprintf( + '%s', + wp_nonce_url( 'edit-tags.php?action=make_default&taxonomy=product_cat&post_type=product&tag_ID=' . absint( $term->term_id ), 'make_default_' . absint( $term->term_id ) ), + /* translators: %s: taxonomy term name */ + esc_attr( sprintf( __( 'Make “%s” the default category', 'woocommerce' ), $term->name ) ), + __( 'Make default', 'woocommerce' ) + ); + } + + return $actions; + } + + /** + * Handle custom row actions. + */ + public function handle_product_cat_row_actions() { + if ( isset( $_GET['action'], $_GET['tag_ID'], $_GET['_wpnonce'] ) && 'make_default' === $_GET['action'] ) { // WPCS: CSRF ok, input var ok. + $make_default_id = absint( $_GET['tag_ID'] ); // WPCS: Input var ok. + + if ( wp_verify_nonce( $_GET['_wpnonce'], 'make_default_' . $make_default_id ) && current_user_can( 'edit_term', $make_default_id ) ) { // WPCS: Sanitization ok, input var ok, CSRF ok. + update_option( 'default_product_cat', $make_default_id ); + } + } + } + + /** + * Thumbnail column value added to category admin. + * + * @param string $columns Column HTML output. + * @param string $column Column name. + * @param int $id Product ID. + * + * @return string + */ + public function product_cat_column( $columns, $column, $id ) { + if ( 'thumb' === $column ) { + // Prepend tooltip for default category. + $default_category_id = absint( get_option( 'default_product_cat', 0 ) ); + + if ( $default_category_id === $id ) { + $columns .= wc_help_tip( __( 'This is the default category and it cannot be deleted. It will be automatically assigned to products with no category.', 'woocommerce' ) ); + } + + $thumbnail_id = get_term_meta( $id, 'thumbnail_id', true ); + + if ( $thumbnail_id ) { + $image = wp_get_attachment_thumb_url( $thumbnail_id ); + } else { + $image = wc_placeholder_img_src(); + } + + // Prevent esc_url from breaking spaces in urls for image embeds. Ref: https://core.trac.wordpress.org/ticket/23605 . + $image = str_replace( ' ', '%20', $image ); + $columns .= '' . esc_attr__( 'Thumbnail', 'woocommerce' ) . ''; + } + if ( 'handle' === $column ) { + $columns .= ''; + } + return $columns; + } + + /** + * Maintain term hierarchy when editing a product. + * + * @param array $args Term checklist args. + * @return array + */ + public function disable_checked_ontop( $args ) { + if ( ! empty( $args['taxonomy'] ) && 'product_cat' === $args['taxonomy'] ) { + $args['checked_ontop'] = false; + } + return $args; + } + + /** + * Admin footer scripts for the product categories admin screen + * + * @return void + */ + public function scripts_at_product_cat_screen_footer() { + if ( ! isset( $_GET['taxonomy'] ) || 'product_cat' !== $_GET['taxonomy'] ) { // WPCS: CSRF ok, input var ok. + return; + } + // Ensure the tooltip is displayed when the image column is disabled on product categories. + wc_enqueue_js( + "(function( $ ) { + 'use strict'; + var product_cat = $( 'tr#tag-" . absint( $this->default_cat_id ) . "' ); + product_cat.find( 'th' ).empty(); + product_cat.find( 'td.thumb span' ).detach( 'span' ).appendTo( product_cat.find( 'th' ) ); + })( jQuery );" + ); + } +} + +$wc_admin_taxonomies = WC_Admin_Taxonomies::get_instance(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-webhooks-table-list.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-webhooks-table-list.php new file mode 100644 index 0000000..d2c6ea5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-webhooks-table-list.php @@ -0,0 +1,316 @@ + 'webhook', + 'plural' => 'webhooks', + 'ajax' => false, + ) + ); + } + + /** + * No items found text. + */ + public function no_items() { + esc_html_e( 'No webhooks found.', 'woocommerce' ); + } + + /** + * Get list columns. + * + * @return array + */ + public function get_columns() { + return array( + 'cb' => '', + 'title' => __( 'Name', 'woocommerce' ), + 'status' => __( 'Status', 'woocommerce' ), + 'topic' => __( 'Topic', 'woocommerce' ), + 'delivery_url' => __( 'Delivery URL', 'woocommerce' ), + ); + } + + /** + * Column cb. + * + * @param WC_Webhook $webhook Webhook instance. + * @return string + */ + public function column_cb( $webhook ) { + return sprintf( '', $this->_args['singular'], $webhook->get_id() ); + } + + /** + * Return title column. + * + * @param WC_Webhook $webhook Webhook instance. + * @return string + */ + public function column_title( $webhook ) { + $edit_link = admin_url( 'admin.php?page=wc-settings&tab=advanced&section=webhooks&edit-webhook=' . $webhook->get_id() ); + $output = ''; + + // Title. + $output .= '' . esc_html( $webhook->get_name() ) . ''; + + // Get actions. + $actions = array( + /* translators: %s: webhook ID. */ + 'id' => sprintf( __( 'ID: %d', 'woocommerce' ), $webhook->get_id() ), + 'edit' => '' . esc_html__( 'Edit', 'woocommerce' ) . '', + /* translators: %s: webhook name */ + 'delete' => 'get_name() ) ) . '" href="' . esc_url( + wp_nonce_url( + add_query_arg( + array( + 'delete' => $webhook->get_id(), + ), + admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=webhooks' ) + ), + 'delete-webhook' + ) + ) . '">' . esc_html__( 'Delete permanently', 'woocommerce' ) . '', + ); + + $actions = apply_filters( 'webhook_row_actions', $actions, $webhook ); + $row_actions = array(); + + foreach ( $actions as $action => $link ) { + $row_actions[] = '' . $link . ''; + } + + $output .= '
    ' . implode( ' | ', $row_actions ) . '
    '; + + return $output; + } + + /** + * Return status column. + * + * @param WC_Webhook $webhook Webhook instance. + * @return string + */ + public function column_status( $webhook ) { + return $webhook->get_i18n_status(); + } + + /** + * Return topic column. + * + * @param WC_Webhook $webhook Webhook instance. + * @return string + */ + public function column_topic( $webhook ) { + return $webhook->get_topic(); + } + + /** + * Return delivery URL column. + * + * @param WC_Webhook $webhook Webhook instance. + * @return string + */ + public function column_delivery_url( $webhook ) { + return $webhook->get_delivery_url(); + } + + /** + * Get the status label for webhooks. + * + * @param string $status_name Status name. + * @param int $amount Amount of webhooks. + * @return array + */ + private function get_status_label( $status_name, $amount ) { + $statuses = wc_get_webhook_statuses(); + + if ( isset( $statuses[ $status_name ] ) ) { + return array( + 'singular' => sprintf( '%s (%s)', esc_html( $statuses[ $status_name ] ), $amount ), + 'plural' => sprintf( '%s (%s)', esc_html( $statuses[ $status_name ] ), $amount ), + 'context' => '', + 'domain' => 'woocommerce', + ); + } + + return array( + 'singular' => sprintf( '%s (%s)', esc_html( $status_name ), $amount ), + 'plural' => sprintf( '%s (%s)', esc_html( $status_name ), $amount ), + 'context' => '', + 'domain' => 'woocommerce', + ); + } + + /** + * Table list views. + * + * @return array + */ + protected function get_views() { + $status_links = array(); + $data_store = WC_Data_Store::load( 'webhook' ); + $num_webhooks = $data_store->get_count_webhooks_by_status(); + $total_webhooks = array_sum( (array) $num_webhooks ); + $statuses = array_keys( wc_get_webhook_statuses() ); + $class = empty( $_REQUEST['status'] ) ? ' class="current"' : ''; // WPCS: input var okay. CSRF ok. + + /* translators: %s: count */ + $status_links['all'] = "" . sprintf( _nx( 'All (%s)', 'All (%s)', $total_webhooks, 'posts', 'woocommerce' ), number_format_i18n( $total_webhooks ) ) . ''; + + foreach ( $statuses as $status_name ) { + $class = ''; + + if ( empty( $num_webhooks[ $status_name ] ) ) { + continue; + } + + if ( isset( $_REQUEST['status'] ) && sanitize_key( wp_unslash( $_REQUEST['status'] ) ) === $status_name ) { // WPCS: input var okay, CSRF ok. + $class = ' class="current"'; + } + + $label = $this->get_status_label( $status_name, $num_webhooks[ $status_name ] ); + + $status_links[ $status_name ] = "" . sprintf( translate_nooped_plural( $label, $num_webhooks[ $status_name ] ), number_format_i18n( $num_webhooks[ $status_name ] ) ) . ''; + } + + return $status_links; + } + + /** + * Get bulk actions. + * + * @return array + */ + protected function get_bulk_actions() { + return array( + 'delete' => __( 'Delete permanently', 'woocommerce' ), + ); + } + + /** + * Process bulk actions. + */ + public function process_bulk_action() { + $action = $this->current_action(); + $webhooks = isset( $_REQUEST['webhook'] ) ? array_map( 'absint', (array) $_REQUEST['webhook'] ) : array(); // WPCS: input var okay, CSRF ok. + + if ( ! current_user_can( 'manage_woocommerce' ) ) { + wp_die( esc_html__( 'You do not have permission to edit Webhooks', 'woocommerce' ) ); + } + + if ( 'delete' === $action ) { + WC_Admin_Webhooks::bulk_delete( $webhooks ); + } + } + + /** + * Generate the table navigation above or below the table. + * Included to remove extra nonce input. + * + * @param string $which The location of the extra table nav markup: 'top' or 'bottom'. + */ + protected function display_tablenav( $which ) { + echo '
    '; + + if ( $this->has_items() ) { + echo '
    '; + $this->bulk_actions( $which ); + echo '
    '; + } + + $this->extra_tablenav( $which ); + $this->pagination( $which ); + echo '
    '; + echo '
    '; + } + + /** + * Search box. + * + * @param string $text Button text. + * @param string $input_id Input ID. + */ + public function search_box( $text, $input_id ) { + if ( empty( $_REQUEST['s'] ) && ! $this->has_items() ) { // WPCS: input var okay, CSRF ok. + return; + } + + $input_id = $input_id . '-search-input'; + $search_query = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : ''; // WPCS: input var okay, CSRF ok. + + echo ''; + } + + /** + * Prepare table list items. + */ + public function prepare_items() { + $per_page = $this->get_items_per_page( 'woocommerce_webhooks_per_page' ); + $current_page = $this->get_pagenum(); + + // Query args. + $args = array( + 'limit' => $per_page, + 'offset' => $per_page * ( $current_page - 1 ), + ); + + // Handle the status query. + if ( ! empty( $_REQUEST['status'] ) ) { // WPCS: input var okay, CSRF ok. + $args['status'] = sanitize_key( wp_unslash( $_REQUEST['status'] ) ); // WPCS: input var okay, CSRF ok. + } + + if ( ! empty( $_REQUEST['s'] ) ) { // WPCS: input var okay, CSRF ok. + $args['search'] = sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ); // WPCS: input var okay, CSRF ok. + } + + $args['paginate'] = true; + + // Get the webhooks. + $data_store = WC_Data_Store::load( 'webhook' ); + $webhooks = $data_store->search_webhooks( $args ); + $this->items = array_map( 'wc_get_webhook', $webhooks->webhooks ); + + // Set the pagination. + $this->set_pagination_args( + array( + 'total_items' => $webhooks->total, + 'per_page' => $per_page, + 'total_pages' => $webhooks->max_num_pages, + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-webhooks.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-webhooks.php new file mode 100644 index 0000000..9614c9d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-webhooks.php @@ -0,0 +1,349 @@ +set_name( $name ); + + if ( ! $webhook->get_user_id() ) { + $webhook->set_user_id( get_current_user_id() ); + } + + // Status. + $webhook->set_status( ! empty( $_POST['webhook_status'] ) ? sanitize_text_field( wp_unslash( $_POST['webhook_status'] ) ) : 'disabled' ); // WPCS: input var okay, CSRF ok. + + // Delivery URL. + $delivery_url = ! empty( $_POST['webhook_delivery_url'] ) ? esc_url_raw( wp_unslash( $_POST['webhook_delivery_url'] ) ) : ''; // WPCS: input var okay, CSRF ok. + + if ( wc_is_valid_url( $delivery_url ) ) { + $webhook->set_delivery_url( $delivery_url ); + } + + // Secret. + $secret = ! empty( $_POST['webhook_secret'] ) ? sanitize_text_field( wp_unslash( $_POST['webhook_secret'] ) ) : wp_generate_password( 50, true, true ); // WPCS: input var okay, CSRF ok. + $webhook->set_secret( $secret ); + + // Topic. + if ( ! empty( $_POST['webhook_topic'] ) ) { // WPCS: input var okay, CSRF ok. + $resource = ''; + $event = ''; + + switch ( $_POST['webhook_topic'] ) { // WPCS: input var okay, CSRF ok. + case 'action': + $resource = 'action'; + $event = ! empty( $_POST['webhook_action_event'] ) ? sanitize_text_field( wp_unslash( $_POST['webhook_action_event'] ) ) : ''; // WPCS: input var okay, CSRF ok. + break; + + default: + list( $resource, $event ) = explode( '.', sanitize_text_field( wp_unslash( $_POST['webhook_topic'] ) ) ); // WPCS: input var okay, CSRF ok. + break; + } + + $topic = $resource . '.' . $event; + + if ( wc_is_webhook_valid_topic( $topic ) ) { + $webhook->set_topic( $topic ); + } else { + $errors[] = __( 'Webhook topic unknown. Please select a valid topic.', 'woocommerce' ); + } + } + + // API version. + $rest_api_versions = wc_get_webhook_rest_api_versions(); + $webhook->set_api_version( ! empty( $_POST['webhook_api_version'] ) ? sanitize_text_field( wp_unslash( $_POST['webhook_api_version'] ) ) : end( $rest_api_versions ) ); // WPCS: input var okay, CSRF ok. + + $webhook->save(); + + // Run actions. + do_action( 'woocommerce_webhook_options_save', $webhook->get_id() ); + if ( $errors ) { + // Redirect to webhook edit page to avoid settings save actions. + wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=webhooks&edit-webhook=' . $webhook->get_id() . '&error=' . rawurlencode( implode( '|', $errors ) ) ) ); + exit(); + } elseif ( isset( $_POST['webhook_status'] ) && 'active' === $_POST['webhook_status'] && $webhook->get_pending_delivery() ) { // WPCS: input var okay, CSRF ok. + // Ping the webhook at the first time that is activated. + $result = $webhook->deliver_ping(); + + if ( is_wp_error( $result ) ) { + // Redirect to webhook edit page to avoid settings save actions. + wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=webhooks&edit-webhook=' . $webhook->get_id() . '&error=' . rawurlencode( $result->get_error_message() ) ) ); + exit(); + } + } + + // Redirect to webhook edit page to avoid settings save actions. + wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=webhooks&edit-webhook=' . $webhook->get_id() . '&updated=1' ) ); + exit(); + } + + /** + * Bulk delete. + * + * @param array $webhooks List of webhooks IDs. + */ + public static function bulk_delete( $webhooks ) { + foreach ( $webhooks as $webhook_id ) { + $webhook = new WC_Webhook( (int) $webhook_id ); + $webhook->delete( true ); + } + + $qty = count( $webhooks ); + $status = isset( $_GET['status'] ) ? '&status=' . sanitize_text_field( wp_unslash( $_GET['status'] ) ) : ''; // WPCS: input var okay, CSRF ok. + + // Redirect to webhooks page. + wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=webhooks' . $status . '&deleted=' . $qty ) ); + exit(); + } + + /** + * Delete webhook. + */ + private function delete() { + check_admin_referer( 'delete-webhook' ); + + if ( isset( $_GET['delete'] ) ) { // WPCS: input var okay, CSRF ok. + $webhook_id = absint( $_GET['delete'] ); // WPCS: input var okay, CSRF ok. + + if ( $webhook_id ) { + $this->bulk_delete( array( $webhook_id ) ); + } + } + } + + /** + * Webhooks admin actions. + */ + public function actions() { + if ( $this->is_webhook_settings_page() ) { + // Save. + if ( isset( $_POST['save'] ) && isset( $_POST['webhook_id'] ) ) { // WPCS: input var okay, CSRF ok. + $this->save(); + } + + // Delete webhook. + if ( isset( $_GET['delete'] ) ) { // WPCS: input var okay, CSRF ok. + $this->delete(); + } + } + } + + /** + * Page output. + */ + public static function page_output() { + // Hide the save button. + $GLOBALS['hide_save_button'] = true; + + if ( isset( $_GET['edit-webhook'] ) ) { // WPCS: input var okay, CSRF ok. + $webhook_id = absint( $_GET['edit-webhook'] ); // WPCS: input var okay, CSRF ok. + $webhook = new WC_Webhook( $webhook_id ); + + include __DIR__ . '/settings/views/html-webhooks-edit.php'; + return; + } + + self::table_list_output(); + } + + /** + * Notices. + */ + public static function notices() { + if ( isset( $_GET['deleted'] ) ) { // WPCS: input var okay, CSRF ok. + $deleted = absint( $_GET['deleted'] ); // WPCS: input var okay, CSRF ok. + + /* translators: %d: count */ + WC_Admin_Settings::add_message( sprintf( _n( '%d webhook permanently deleted.', '%d webhooks permanently deleted.', $deleted, 'woocommerce' ), $deleted ) ); + } + + if ( isset( $_GET['updated'] ) ) { // WPCS: input var okay, CSRF ok. + WC_Admin_Settings::add_message( __( 'Webhook updated successfully.', 'woocommerce' ) ); + } + + if ( isset( $_GET['created'] ) ) { // WPCS: input var okay, CSRF ok. + WC_Admin_Settings::add_message( __( 'Webhook created successfully.', 'woocommerce' ) ); + } + + if ( isset( $_GET['error'] ) ) { // WPCS: input var okay, CSRF ok. + foreach ( explode( '|', sanitize_text_field( wp_unslash( $_GET['error'] ) ) ) as $message ) { // WPCS: input var okay, CSRF ok. + WC_Admin_Settings::add_error( trim( $message ) ); + } + } + } + + /** + * Add screen option. + */ + public function screen_option() { + global $webhooks_table_list; + + if ( ! isset( $_GET['edit-webhook'] ) && $this->is_webhook_settings_page() ) { // WPCS: input var okay, CSRF ok. + $webhooks_table_list = new WC_Admin_Webhooks_Table_List(); + + // Add screen option. + add_screen_option( + 'per_page', + array( + 'default' => 10, + 'option' => 'woocommerce_webhooks_per_page', + ) + ); + } + } + + /** + * Table list output. + */ + private static function table_list_output() { + global $webhooks_table_list; + + echo '

    ' . esc_html__( 'Webhooks', 'woocommerce' ) . ' ' . esc_html__( 'Add webhook', 'woocommerce' ) . '

    '; + + // Get the webhooks count. + $data_store = WC_Data_Store::load( 'webhook' ); + $num_webhooks = $data_store->get_count_webhooks_by_status(); + $count = array_sum( $num_webhooks ); + + if ( 0 < $count ) { + $webhooks_table_list->process_bulk_action(); + $webhooks_table_list->prepare_items(); + + echo ''; + echo ''; + echo ''; + + $webhooks_table_list->views(); + $webhooks_table_list->search_box( __( 'Search webhooks', 'woocommerce' ), 'webhook' ); + $webhooks_table_list->display(); + } else { + echo '
    '; + ?> +

    + + + get_topic(); + $event = ''; + $resource = ''; + + if ( $topic ) { + list( $resource, $event ) = explode( '.', $topic ); + + if ( 'action' === $resource ) { + $topic = 'action'; + } elseif ( ! in_array( $resource, array( 'coupon', 'customer', 'order', 'product' ), true ) ) { + $topic = 'custom'; + } + } + + return array( + 'topic' => $topic, + 'event' => $event, + 'resource' => $resource, + ); + } + + /** + * Get the logs navigation. + * + * @deprecated 3.3.0 + * @param int $total Deprecated. + * @param WC_Webhook $webhook Deprecated. + */ + public static function get_logs_navigation( $total, $webhook ) { + wc_deprecated_function( 'WC_Admin_Webhooks::get_logs_navigation', '3.3' ); + } +} + +new WC_Admin_Webhooks(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin.php new file mode 100644 index 0000000..d83cccc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/class-wc-admin.php @@ -0,0 +1,311 @@ +id ) { + case 'dashboard': + case 'dashboard-network': + include __DIR__ . '/class-wc-admin-dashboard.php'; + break; + case 'options-permalink': + include __DIR__ . '/class-wc-admin-permalink-settings.php'; + break; + case 'plugins': + include __DIR__ . '/plugin-updates/class-wc-plugins-screen-updates.php'; + break; + case 'update-core': + include __DIR__ . '/plugin-updates/class-wc-updates-screen-updates.php'; + break; + case 'users': + case 'user': + case 'profile': + case 'user-edit': + include __DIR__ . '/class-wc-admin-profile.php'; + break; + } + } + + /** + * Handle redirects to setup/welcome page after install and updates. + * + * The user must have access rights, and we must ignore the network/bulk plugin updaters. + */ + public function admin_redirects() { + // Don't run this fn from Action Scheduler requests, as it would clear _wc_activation_redirect transient. + // That means OBW would never be shown. + if ( wc_is_running_from_async_action_scheduler() ) { + return; + } + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + // Nonced plugin install redirects. + if ( ! empty( $_GET['wc-install-plugin-redirect'] ) ) { + $plugin_slug = wc_clean( wp_unslash( $_GET['wc-install-plugin-redirect'] ) ); + + if ( current_user_can( 'install_plugins' ) && in_array( $plugin_slug, array( 'woocommerce-gateway-stripe' ), true ) ) { + $nonce = wp_create_nonce( 'install-plugin_' . $plugin_slug ); + $url = self_admin_url( 'update.php?action=install-plugin&plugin=' . $plugin_slug . '&_wpnonce=' . $nonce ); + } else { + $url = admin_url( 'plugin-install.php?tab=search&type=term&s=' . $plugin_slug ); + } + + wp_safe_redirect( $url ); + exit; + } + + // phpcs:enable WordPress.Security.NonceVerification.Recommended + } + + /** + * Prevent any user who cannot 'edit_posts' (subscribers, customers etc) from accessing admin. + */ + public function prevent_admin_access() { + $prevent_access = false; + + if ( apply_filters( 'woocommerce_disable_admin_bar', true ) && ! is_ajax() && isset( $_SERVER['SCRIPT_FILENAME'] ) && basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_FILENAME'] ) ) ) !== 'admin-post.php' ) { + $has_cap = false; + $access_caps = array( 'edit_posts', 'manage_woocommerce', 'view_admin_dashboard' ); + + foreach ( $access_caps as $access_cap ) { + if ( current_user_can( $access_cap ) ) { + $has_cap = true; + break; + } + } + + if ( ! $has_cap ) { + $prevent_access = true; + } + } + + if ( apply_filters( 'woocommerce_prevent_admin_access', $prevent_access ) ) { + wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) ); + exit; + } + } + + /** + * Preview email template. + */ + public function preview_emails() { + + if ( isset( $_GET['preview_woocommerce_mail'] ) ) { + if ( ! ( isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'preview-mail' ) ) ) { + die( 'Security check' ); + } + + // load the mailer class. + $mailer = WC()->mailer(); + + // get the preview email subject. + $email_heading = __( 'HTML email template', 'woocommerce' ); + + // get the preview email content. + ob_start(); + include __DIR__ . '/views/html-email-template-preview.php'; + $message = ob_get_clean(); + + // create a new email. + $email = new WC_Email(); + + // wrap the content with the email template and then add styles. + $message = apply_filters( 'woocommerce_mail_content', $email->style_inline( $mailer->wrap_message( $email_heading, $message ) ) ); + + // print the preview email. + // phpcs:ignore WordPress.Security.EscapeOutput + echo $message; + // phpcs:enable + exit; + } + } + + /** + * Change the admin footer text on WooCommerce admin pages. + * + * @since 2.3 + * @param string $footer_text text to be rendered in the footer. + * @return string + */ + public function admin_footer_text( $footer_text ) { + if ( ! current_user_can( 'manage_woocommerce' ) || ! function_exists( 'wc_get_screen_ids' ) ) { + return $footer_text; + } + $current_screen = get_current_screen(); + $wc_pages = wc_get_screen_ids(); + + // Set only WC pages. + $wc_pages = array_diff( $wc_pages, array( 'profile', 'user-edit' ) ); + + // Check to make sure we're on a WooCommerce admin page. + if ( isset( $current_screen->id ) && apply_filters( 'woocommerce_display_admin_footer_text', in_array( $current_screen->id, $wc_pages, true ) ) ) { + // Change the footer text. + if ( ! get_option( 'woocommerce_admin_footer_text_rated' ) ) { + $footer_text = sprintf( + /* translators: 1: WooCommerce 2:: five stars */ + __( 'If you like %1$s please leave us a %2$s rating. A huge thanks in advance!', 'woocommerce' ), + sprintf( '%s', esc_html__( 'WooCommerce', 'woocommerce' ) ), + '★★★★★' + ); + wc_enqueue_js( + "jQuery( 'a.wc-rating-link' ).click( function() { + jQuery.post( '" . WC()->ajax_url() . "', { action: 'woocommerce_rated' } ); + jQuery( this ).parent().text( jQuery( this ).data( 'rated' ) ); + });" + ); + } else { + $footer_text = __( 'Thank you for selling with WooCommerce.', 'woocommerce' ); + } + } + + return $footer_text; + } + + /** + * Check on a Jetpack install queued by the Setup Wizard. + * + * See: WC_Admin_Setup_Wizard::install_jetpack() + */ + public function setup_wizard_check_jetpack() { + $jetpack_active = class_exists( 'Jetpack' ); + + wp_send_json_success( + array( + 'is_active' => $jetpack_active ? 'yes' : 'no', + ) + ); + } + + /** + * Disable WXR export of scheduled action posts. + * + * @since 3.6.2 + * + * @param array $args Scehduled action post type registration args. + * + * @return array + */ + public function disable_webhook_post_export( $args ) { + $args['can_export'] = false; + return $args; + } + + /** + * Include admin classes. + * + * @since 4.2.0 + * @param string $classes Body classes string. + * @return string + */ + public function include_admin_body_class( $classes ) { + if ( in_array( array( 'wc-wp-version-gte-53', 'wc-wp-version-gte-55' ), explode( ' ', $classes ), true ) ) { + return $classes; + } + + $raw_version = get_bloginfo( 'version' ); + $version_parts = explode( '-', $raw_version ); + $version = count( $version_parts ) > 1 ? $version_parts[0] : $raw_version; + + // Add WP 5.3+ compatibility class. + if ( $raw_version && version_compare( $version, '5.3', '>=' ) ) { + $classes .= ' wc-wp-version-gte-53'; + } + + // Add WP 5.5+ compatibility class. + if ( $raw_version && version_compare( $version, '5.5', '>=' ) ) { + $classes .= ' wc-wp-version-gte-55'; + } + + return $classes; + } +} + +return new WC_Admin(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-api.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-api.php new file mode 100644 index 0000000..50ce432 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-api.php @@ -0,0 +1,170 @@ + parse_url( $url, PHP_URL_HOST ), + 'request_uri' => $request_uri, + 'method' => ! empty( $args['method'] ) ? $args['method'] : 'GET', + ); + + if ( ! empty( $args['body'] ) ) { + $data['body'] = $args['body']; + } + + $signature = hash_hmac( 'sha256', json_encode( $data ), $auth['access_token_secret'] ); + if ( empty( $args['headers'] ) ) { + $args['headers'] = array(); + } + + $headers = array( + 'Authorization' => 'Bearer ' . $auth['access_token'], + 'X-Woo-Signature' => $signature, + ); + $args['headers'] = wp_parse_args( $headers, $args['headers'] ); + + $url = add_query_arg( + array( + 'token' => $auth['access_token'], + 'signature' => $signature, + ), + $url + ); + + return true; + } + + /** + * Wrapper for self::request(). + * + * @param string $endpoint The helper API endpoint to request. + * @param array $args Arguments passed to wp_remote_request(). + * + * @return array The response object from wp_safe_remote_request(). + */ + public static function get( $endpoint, $args = array() ) { + $args['method'] = 'GET'; + return self::request( $endpoint, $args ); + } + + /** + * Wrapper for self::request(). + * + * @param string $endpoint The helper API endpoint to request. + * @param array $args Arguments passed to wp_remote_request(). + * + * @return array The response object from wp_safe_remote_request(). + */ + public static function post( $endpoint, $args = array() ) { + $args['method'] = 'POST'; + return self::request( $endpoint, $args ); + } + + /** + * Wrapper for self::request(). + * + * @param string $endpoint The helper API endpoint to request. + * @param array $args Arguments passed to wp_remote_request(). + * + * @return array The response object from wp_safe_remote_request(). + */ + public static function put( $endpoint, $args = array() ) { + $args['method'] = 'PUT'; + return self::request( $endpoint, $args ); + } + + /** + * Using the API base, form a request URL from a given endpoint. + * + * @param string $endpoint The endpoint to request. + * + * @return string The absolute endpoint URL. + */ + public static function url( $endpoint ) { + $endpoint = ltrim( $endpoint, '/' ); + $endpoint = sprintf( '%s/%s', self::$api_base, $endpoint ); + $endpoint = esc_url_raw( $endpoint ); + return $endpoint; + } +} + +WC_Helper_API::load(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-compat.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-compat.php new file mode 100644 index 0000000..50d02ff --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-compat.php @@ -0,0 +1,204 @@ +admin, 'maybe_display_activation_notice' ) ); + remove_action( 'admin_notices', array( $GLOBALS['woothemes_updater']->admin, 'maybe_display_activation_notice' ) ); + remove_action( 'network_admin_menu', array( $GLOBALS['woothemes_updater']->admin, 'register_settings_screen' ) ); + remove_action( 'admin_menu', array( $GLOBALS['woothemes_updater']->admin, 'register_settings_screen' ) ); + } + + /** + * Attempt to migrate a legacy connection to a new one. + */ + public static function migrate_connection() { + // Don't attempt to migrate if attempted before. + if ( WC_Helper_Options::get( 'did-migrate' ) ) { + return; + } + + $auth = WC_Helper_Options::get( 'auth' ); + if ( ! empty( $auth ) ) { + return; + } + + WC_Helper::log( 'Attempting oauth/migrate' ); + WC_Helper_Options::update( 'did-migrate', true ); + + $master_key = get_option( 'woothemes_helper_master_key' ); + if ( empty( $master_key ) ) { + WC_Helper::log( 'Master key not found, aborting' ); + return; + } + + $request = WC_Helper_API::post( + 'oauth/migrate', + array( + 'body' => array( + 'home_url' => home_url(), + 'master_key' => $master_key, + ), + ) + ); + + if ( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) !== 200 ) { + WC_Helper::log( 'Call to oauth/migrate returned a non-200 response code' ); + return; + } + + $request_token = json_decode( wp_remote_retrieve_body( $request ) ); + if ( empty( $request_token ) ) { + WC_Helper::log( 'Call to oauth/migrate returned an empty token' ); + return; + } + + // Obtain an access token. + $request = WC_Helper_API::post( + 'oauth/access_token', + array( + 'body' => array( + 'request_token' => $request_token, + 'home_url' => home_url(), + 'migrate' => true, + ), + ) + ); + + if ( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) !== 200 ) { + WC_Helper::log( 'Call to oauth/access_token returned a non-200 response code' ); + return; + } + + $access_token = json_decode( wp_remote_retrieve_body( $request ), true ); + if ( empty( $access_token ) ) { + WC_Helper::log( 'Call to oauth/access_token returned an invalid token' ); + return; + } + + WC_Helper_Options::update( + 'auth', + array( + 'access_token' => $access_token['access_token'], + 'access_token_secret' => $access_token['access_token_secret'], + 'site_id' => $access_token['site_id'], + 'user_id' => null, // Set this later + 'updated' => time(), + ) + ); + + // Obtain the connected user info. + if ( ! WC_Helper::_flush_authentication_cache() ) { + WC_Helper::log( 'Could not obtain connected user info in migrate_connection' ); + WC_Helper_Options::update( 'auth', array() ); + return; + } + } + + /** + * Attempt to deactivate the legacy helper plugin. + */ + public static function deactivate_plugin() { + include_once ABSPATH . 'wp-admin/includes/plugin.php'; + if ( ! function_exists( 'deactivate_plugins' ) ) { + return; + } + + if ( is_plugin_active( 'woothemes-updater/woothemes-updater.php' ) ) { + deactivate_plugins( 'woothemes-updater/woothemes-updater.php' ); + + // Notify the user when the plugin is deactivated. + add_action( 'pre_current_active_plugins', array( __CLASS__, 'plugin_deactivation_notice' ) ); + } + } + + /** + * Display admin notice directing the user where to go. + */ + public static function plugin_deactivation_notice() { + ?> +
    +

    Manage subscriptions from the extensions tab instead.', 'woocommerce' ), esc_url( admin_url( 'admin.php?page=wc-addons§ion=helper' ) ) ); ?>

    +
    + 'wc-addons', + 'section' => 'helper', + ), + admin_url( 'admin.php' ) + ); + include WC_Helper::get_view_filename( 'html-helper-compat.php' ); + } +} + +WC_Helper_Compat::load(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-options.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-options.php new file mode 100644 index 0000000..4f1611c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-options.php @@ -0,0 +1,60 @@ +slug ) ) { + return $response; + } + + // Only for slugs that start with woo- + if ( 0 !== strpos( $args->slug, 'woocommerce-com-' ) ) { + return $response; + } + + $clean_slug = str_replace( 'woocommerce-com-', '', $args->slug ); + + // Look through update data by slug. + $update_data = WC_Helper_Updater::get_update_data(); + $products = wp_list_filter( $update_data, array( 'slug' => $clean_slug ) ); + + if ( empty( $products ) ) { + return $response; + } + + $product_id = array_keys( $products ); + $product_id = array_shift( $product_id ); + + // Fetch the product information from the Helper API. + $request = WC_Helper_API::get( + add_query_arg( + array( + 'product_id' => absint( $product_id ), + ), + 'info' + ), + array( 'authenticated' => true ) + ); + + $results = json_decode( wp_remote_retrieve_body( $request ), true ); + if ( ! empty( $results ) ) { + $response = (object) $results; + } + + return $response; + } +} + +WC_Helper_Plugin_Info::load(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-updater.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-updater.php new file mode 100644 index 0000000..e187231 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper-updater.php @@ -0,0 +1,488 @@ + 'woocommerce-com-' . $plugin['_product_id'], + 'slug' => 'woocommerce-com-' . $data['slug'], + 'plugin' => $filename, + 'new_version' => $data['version'], + 'url' => $data['url'], + 'package' => $data['package'], + 'upgrade_notice' => $data['upgrade_notice'], + ); + + // We don't want to deliver a valid upgrade package when their subscription has expired. + // To avoid the generic "no_package" error that empty strings give, we will store an + // indication of expiration for the `upgrader_pre_download` filter to error on. + if ( ! self::_has_active_subscription( $plugin['_product_id'] ) ) { + $item['package'] = 'woocommerce-com-expired-' . $plugin['_product_id']; + } + + if ( version_compare( $plugin['Version'], $data['version'], '<' ) ) { + $transient->response[ $filename ] = (object) $item; + unset( $transient->no_update[ $filename ] ); + } else { + $transient->no_update[ $filename ] = (object) $item; + unset( $transient->response[ $filename ] ); + } + } + + $translations = self::get_translations_update_data(); + $transient->translations = array_merge( isset( $transient->translations ) ? $transient->translations : array(), $translations ); + + return $transient; + } + + /** + * Runs on pre_set_site_transient_update_themes, provides custom + * packages for WooCommerce.com-hosted extensions. + * + * @param object $transient The update_themes transient object. + * + * @return object The same or a modified version of the transient. + */ + public static function transient_update_themes( $transient ) { + $update_data = self::get_update_data(); + + foreach ( WC_Helper::get_local_woo_themes() as $theme ) { + if ( empty( $update_data[ $theme['_product_id'] ] ) ) { + continue; + } + + $data = $update_data[ $theme['_product_id'] ]; + $slug = $theme['_stylesheet']; + + $item = array( + 'theme' => $slug, + 'new_version' => $data['version'], + 'url' => $data['url'], + 'package' => '', + ); + + if ( self::_has_active_subscription( $theme['_product_id'] ) ) { + $item['package'] = $data['package']; + } + + if ( version_compare( $theme['Version'], $data['version'], '<' ) ) { + $transient->response[ $slug ] = $item; + } else { + unset( $transient->response[ $slug ] ); + $transient->checked[ $slug ] = $data['version']; + } + } + + return $transient; + } + + /** + * Get update data for all extensions. + * + * Scans through all subscriptions for the connected user, as well + * as all Woo extensions without a subscription, and obtains update + * data for each product. + * + * @return array Update data {product_id => data} + */ + public static function get_update_data() { + $payload = array(); + + // Scan subscriptions. + foreach ( WC_Helper::get_subscriptions() as $subscription ) { + $payload[ $subscription['product_id'] ] = array( + 'product_id' => $subscription['product_id'], + 'file_id' => '', + ); + } + + // Scan local plugins which may or may not have a subscription. + foreach ( WC_Helper::get_local_woo_plugins() as $data ) { + if ( ! isset( $payload[ $data['_product_id'] ] ) ) { + $payload[ $data['_product_id'] ] = array( + 'product_id' => $data['_product_id'], + ); + } + + $payload[ $data['_product_id'] ]['file_id'] = $data['_file_id']; + } + + // Scan local themes. + foreach ( WC_Helper::get_local_woo_themes() as $data ) { + if ( ! isset( $payload[ $data['_product_id'] ] ) ) { + $payload[ $data['_product_id'] ] = array( + 'product_id' => $data['_product_id'], + ); + } + + $payload[ $data['_product_id'] ]['file_id'] = $data['_file_id']; + } + + return self::_update_check( $payload ); + } + + /** + * Get translations updates informations. + * + * Scans through all subscriptions for the connected user, as well + * as all Woo extensions without a subscription, and obtains update + * data for each product. + * + * @return array Update data {product_id => data} + */ + public static function get_translations_update_data() { + $payload = array(); + + $installed_translations = wp_get_installed_translations( 'plugins' ); + + $locales = array_values( get_available_languages() ); + /** + * Filters the locales requested for plugin translations. + * + * @since 3.7.0 + * @since 4.5.0 The default value of the `$locales` parameter changed to include all locales. + * + * @param array $locales Plugin locales. Default is all available locales of the site. + */ + $locales = apply_filters( 'plugins_update_check_locales', $locales ); + $locales = array_unique( $locales ); + + // No locales, the respone will be empty, we can return now. + if ( empty( $locales ) ) { + return array(); + } + + // Scan local plugins which may or may not have a subscription. + $plugins = WC_Helper::get_local_woo_plugins(); + $active_woo_plugins = array_intersect( array_keys( $plugins ), get_option( 'active_plugins', array() ) ); + + /* + * Use only plugins that are subscribed to the automatic translations updates. + */ + $active_for_translations = array_filter( + $active_woo_plugins, + function( $plugin ) use ( $plugins ) { + return apply_filters( 'woocommerce_translations_updates_for_' . $plugins[ $plugin ]['slug'], false ); + } + ); + + // Nothing to check for, exit. + if ( empty( $active_for_translations ) ) { + return array(); + } + + if ( wp_doing_cron() ) { + $timeout = 30; + } else { + // Three seconds, plus one extra second for every 10 plugins. + $timeout = 3 + (int) ( count( $active_for_translations ) / 10 ); + } + + $request_body = array( + 'locales' => $locales, + 'plugins' => array(), + ); + + foreach ( $active_for_translations as $active_plugin ) { + $plugin = $plugins[ $active_plugin ]; + $request_body['plugins'][ $plugin['slug'] ] = array( 'version' => $plugin['Version'] ); + } + + $raw_response = wp_remote_post( + 'https://translate.wordpress.com/api/translations-updates/woocommerce', + array( + 'body' => json_encode( $request_body ), + 'headers' => array( 'Content-Type: application/json' ), + 'timeout' => $timeout, + ) + ); + + // Something wrong happened on the translate server side. + $response_code = wp_remote_retrieve_response_code( $raw_response ); + if ( 200 !== $response_code ) { + return array(); + } + + $response = json_decode( wp_remote_retrieve_body( $raw_response ), true ); + + // API error, api returned but something was wrong. + if ( array_key_exists( 'success', $response ) && false === $response['success'] ) { + return array(); + } + + $translations = array(); + + foreach ( $response['data'] as $plugin_name => $language_packs ) { + foreach ( $language_packs as $language_pack ) { + // Maybe we have this language pack already installed so lets check revision date. + if ( array_key_exists( $plugin_name, $installed_translations ) && array_key_exists( $language_pack['wp_locale'], $installed_translations[ $plugin_name ] ) ) { + $installed_translation_revision_time = new DateTime( $installed_translations[ $plugin_name ][ $language_pack['wp_locale'] ]['PO-Revision-Date'] ); + $new_translation_revision_time = new DateTime( $language_pack['last_modified'] ); + // Skip if translation language pack is not newer than what is installed already. + if ( $new_translation_revision_time <= $installed_translation_revision_time ) { + continue; + } + } + $translations[] = array( + 'type' => 'plugin', + 'slug' => $plugin_name, + 'language' => $language_pack['wp_locale'], + 'version' => $language_pack['version'], + 'updated' => $language_pack['last_modified'], + 'package' => $language_pack['package'], + 'autoupdate' => true, + ); + } + } + + return $translations; + } + + /** + * Run an update check API call. + * + * The call is cached based on the payload (product ids, file ids). If + * the payload changes, the cache is going to miss. + * + * @param array $payload Information about the plugin to update. + * @return array Update data for each requested product. + */ + private static function _update_check( $payload ) { + ksort( $payload ); + $hash = md5( wp_json_encode( $payload ) ); + + $cache_key = '_woocommerce_helper_updates'; + $data = get_transient( $cache_key ); + if ( false !== $data ) { + if ( hash_equals( $hash, $data['hash'] ) ) { + return $data['products']; + } + } + + $data = array( + 'hash' => $hash, + 'updated' => time(), + 'products' => array(), + 'errors' => array(), + ); + + $request = WC_Helper_API::post( + 'update-check', + array( + 'body' => wp_json_encode( array( 'products' => $payload ) ), + 'authenticated' => true, + ) + ); + + if ( wp_remote_retrieve_response_code( $request ) !== 200 ) { + $data['errors'][] = 'http-error'; + } else { + $data['products'] = json_decode( wp_remote_retrieve_body( $request ), true ); + } + + set_transient( $cache_key, $data, 12 * HOUR_IN_SECONDS ); + return $data['products']; + } + + /** + * Check for an active subscription. + * + * Checks a given product id against all subscriptions on + * the current site. Returns true if at least one active + * subscription is found. + * + * @param int $product_id The product id to look for. + * + * @return bool True if active subscription found. + */ + private static function _has_active_subscription( $product_id ) { + if ( ! isset( $auth ) ) { + $auth = WC_Helper_Options::get( 'auth' ); + } + + if ( ! isset( $subscriptions ) ) { + $subscriptions = WC_Helper::get_subscriptions(); + } + + if ( empty( $auth['site_id'] ) || empty( $subscriptions ) ) { + return false; + } + + // Check for an active subscription. + foreach ( $subscriptions as $subscription ) { + if ( $subscription['product_id'] != $product_id ) { + continue; + } + + if ( in_array( absint( $auth['site_id'] ), $subscription['connections'] ) ) { + return true; + } + } + + return false; + } + + /** + * Get the number of products that have updates. + * + * @return int The number of products with updates. + */ + public static function get_updates_count() { + $cache_key = '_woocommerce_helper_updates_count'; + $count = get_transient( $cache_key ); + if ( false !== $count ) { + return $count; + } + + // Don't fetch any new data since this function in high-frequency. + if ( ! get_transient( '_woocommerce_helper_subscriptions' ) ) { + return 0; + } + + if ( ! get_transient( '_woocommerce_helper_updates' ) ) { + return 0; + } + + $count = 0; + $update_data = self::get_update_data(); + + if ( empty( $update_data ) ) { + set_transient( $cache_key, $count, 12 * HOUR_IN_SECONDS ); + return $count; + } + + // Scan local plugins. + foreach ( WC_Helper::get_local_woo_plugins() as $plugin ) { + if ( empty( $update_data[ $plugin['_product_id'] ] ) ) { + continue; + } + + if ( version_compare( $plugin['Version'], $update_data[ $plugin['_product_id'] ]['version'], '<' ) ) { + $count++; + } + } + + // Scan local themes. + foreach ( WC_Helper::get_local_woo_themes() as $theme ) { + if ( empty( $update_data[ $theme['_product_id'] ] ) ) { + continue; + } + + if ( version_compare( $theme['Version'], $update_data[ $theme['_product_id'] ]['version'], '<' ) ) { + $count++; + } + } + + set_transient( $cache_key, $count, 12 * HOUR_IN_SECONDS ); + return $count; + } + + /** + * Return the updates count markup. + * + * @return string Updates count markup, empty string if no updates avairable. + */ + public static function get_updates_count_html() { + $count = self::get_updates_count(); + if ( ! $count ) { + return ''; + } + + $count_html = sprintf( '%d', $count, number_format_i18n( $count ) ); + return $count_html; + } + + /** + * Flushes cached update data. + */ + public static function flush_updates_cache() { + delete_transient( '_woocommerce_helper_updates' ); + delete_transient( '_woocommerce_helper_updates_count' ); + delete_site_transient( 'update_plugins' ); + delete_site_transient( 'update_themes' ); + } + + /** + * Fires when a user successfully updated a theme or a plugin. + */ + public static function upgrader_process_complete() { + delete_transient( '_woocommerce_helper_updates_count' ); + } + + /** + * Hooked into the upgrader_pre_download filter in order to better handle error messaging around expired + * plugin updates. Initially we were using an empty string, but the error message that no_package + * results in does not fit the cause. + * + * @since 4.1.0 + * @param bool $reply Holds the current filtered response. + * @param string $package The path to the package file for the update. + * @return false|WP_Error False to proceed with the update as normal, anything else to be returned instead of updating. + */ + public static function block_expired_updates( $reply, $package ) { + // Don't override a reply that was set already. + if ( false !== $reply ) { + return $reply; + } + + // Only for packages with expired subscriptions. + if ( 0 !== strpos( $package, 'woocommerce-com-expired-' ) ) { + return false; + } + + return new WP_Error( + 'woocommerce_subscription_expired', + sprintf( + // translators: %s: URL of WooCommerce.com subscriptions tab. + __( 'Please visit the subscriptions page and renew to continue receiving updates.', 'woocommerce' ), + esc_url( admin_url( 'admin.php?page=wc-addons§ion=helper' ) ) + ) + ); + } +} + +WC_Helper_Updater::load(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper.php new file mode 100644 index 0000000..6fb43c2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/class-wc-helper.php @@ -0,0 +1,1641 @@ + 'wc-addons', + 'section' => 'helper', + 'wc-helper-connect' => 1, + 'wc-helper-nonce' => wp_create_nonce( 'connect' ), + ), + admin_url( 'admin.php' ) + ); + + include self::get_view_filename( 'html-oauth-start.php' ); + return; + } + $disconnect_url = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'wc-helper-disconnect' => 1, + 'wc-helper-nonce' => wp_create_nonce( 'disconnect' ), + ), + admin_url( 'admin.php' ) + ); + + $current_filter = self::get_current_filter(); + $refresh_url = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'filter' => $current_filter, + 'wc-helper-refresh' => 1, + 'wc-helper-nonce' => wp_create_nonce( 'refresh' ), + ), + admin_url( 'admin.php' ) + ); + + // Installed plugins and themes, with or without an active subscription. + $woo_plugins = self::get_local_woo_plugins(); + $woo_themes = self::get_local_woo_themes(); + + $site_id = absint( $auth['site_id'] ); + $subscriptions = self::get_subscriptions(); + $updates = WC_Helper_Updater::get_update_data(); + $subscriptions_product_ids = wp_list_pluck( $subscriptions, 'product_id' ); + + foreach ( $subscriptions as &$subscription ) { + $subscription['active'] = in_array( $site_id, $subscription['connections'] ); + + $subscription['activate_url'] = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'filter' => $current_filter, + 'wc-helper-activate' => 1, + 'wc-helper-product-key' => $subscription['product_key'], + 'wc-helper-product-id' => $subscription['product_id'], + 'wc-helper-nonce' => wp_create_nonce( 'activate:' . $subscription['product_key'] ), + ), + admin_url( 'admin.php' ) + ); + + $subscription['deactivate_url'] = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'filter' => $current_filter, + 'wc-helper-deactivate' => 1, + 'wc-helper-product-key' => $subscription['product_key'], + 'wc-helper-product-id' => $subscription['product_id'], + 'wc-helper-nonce' => wp_create_nonce( 'deactivate:' . $subscription['product_key'] ), + ), + admin_url( 'admin.php' ) + ); + + $subscription['local'] = array( + 'installed' => false, + 'active' => false, + 'version' => null, + ); + + $subscription['update_url'] = admin_url( 'update-core.php' ); + + $local = wp_list_filter( array_merge( $woo_plugins, $woo_themes ), array( '_product_id' => $subscription['product_id'] ) ); + + if ( ! empty( $local ) ) { + $local = array_shift( $local ); + $subscription['local']['installed'] = true; + $subscription['local']['version'] = $local['Version']; + + if ( 'plugin' == $local['_type'] ) { + if ( is_plugin_active( $local['_filename'] ) ) { + $subscription['local']['active'] = true; + } elseif ( is_multisite() && is_plugin_active_for_network( $local['_filename'] ) ) { + $subscription['local']['active'] = true; + } + + // A magic update_url. + $subscription['update_url'] = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $local['_filename'], 'upgrade-plugin_' . $local['_filename'] ); + + } elseif ( 'theme' == $local['_type'] ) { + if ( in_array( $local['_stylesheet'], array( get_stylesheet(), get_template() ) ) ) { + $subscription['local']['active'] = true; + } + + // Another magic update_url. + $subscription['update_url'] = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-theme&theme=' . $local['_stylesheet'] ), 'upgrade-theme_' . $local['_stylesheet'] ); + } + } + + $subscription['has_update'] = false; + if ( $subscription['local']['installed'] && ! empty( $updates[ $subscription['product_id'] ] ) ) { + $subscription['has_update'] = version_compare( $updates[ $subscription['product_id'] ]['version'], $subscription['local']['version'], '>' ); + } + + $subscription['download_primary'] = true; + $subscription['download_url'] = 'https://woocommerce.com/my-account/downloads/'; + if ( ! $subscription['local']['installed'] && ! empty( $updates[ $subscription['product_id'] ] ) ) { + $subscription['download_url'] = $updates[ $subscription['product_id'] ]['package']; + } + + $subscription['actions'] = array(); + + if ( $subscription['has_update'] && ! $subscription['expired'] ) { + $action = array( + /* translators: %s: version number */ + 'message' => sprintf( __( 'Version %s is available.', 'woocommerce' ), esc_html( $updates[ $subscription['product_id'] ]['version'] ) ), + 'button_label' => __( 'Update', 'woocommerce' ), + 'button_url' => $subscription['update_url'], + 'status' => 'update-available', + 'icon' => 'dashicons-update', + ); + + // Subscription is not active on this site. + if ( ! $subscription['active'] ) { + $action['message'] .= ' ' . __( 'To enable this update you need to activate this subscription.', 'woocommerce' ); + $action['button_label'] = null; + $action['button_url'] = null; + } + + $subscription['actions'][] = $action; + } + + if ( $subscription['has_update'] && $subscription['expired'] ) { + $action = array( + /* translators: %s: version number */ + 'message' => sprintf( __( 'Version %s is available.', 'woocommerce' ), esc_html( $updates[ $subscription['product_id'] ]['version'] ) ), + 'status' => 'expired', + 'icon' => 'dashicons-info', + ); + + $action['message'] .= ' ' . __( 'To enable this update you need to purchase a new subscription.', 'woocommerce' ); + $action['button_label'] = __( 'Purchase', 'woocommerce' ); + $action['button_url'] = $subscription['product_url']; + + $subscription['actions'][] = $action; + } elseif ( $subscription['expired'] && ! empty( $subscription['master_user_email'] ) ) { + $action = array( + 'message' => sprintf( __( 'This subscription has expired. Contact the owner to renew the subscription to receive updates and support.', 'woocommerce' ) ), + 'status' => 'expired', + 'icon' => 'dashicons-info', + ); + + $subscription['actions'][] = $action; + } elseif ( $subscription['expired'] ) { + $action = array( + 'message' => sprintf( __( 'This subscription has expired. Please renew to receive updates and support.', 'woocommerce' ) ), + 'button_label' => __( 'Renew', 'woocommerce' ), + 'button_url' => 'https://woocommerce.com/my-account/my-subscriptions/', + 'status' => 'expired', + 'icon' => 'dashicons-info', + ); + + $subscription['actions'][] = $action; + } + + if ( $subscription['expiring'] && ! $subscription['autorenew'] ) { + $action = array( + 'message' => __( 'Subscription is expiring soon.', 'woocommerce' ), + 'button_label' => __( 'Enable auto-renew', 'woocommerce' ), + 'button_url' => 'https://woocommerce.com/my-account/my-subscriptions/', + 'status' => 'expired', + 'icon' => 'dashicons-info', + ); + + $subscription['download_primary'] = false; + $subscription['actions'][] = $action; + } elseif ( $subscription['expiring'] ) { + $action = array( + 'message' => sprintf( __( 'This subscription is expiring soon. Please renew to continue receiving updates and support.', 'woocommerce' ) ), + 'button_label' => __( 'Renew', 'woocommerce' ), + 'button_url' => 'https://woocommerce.com/my-account/my-subscriptions/', + 'status' => 'expired', + 'icon' => 'dashicons-info', + ); + + $subscription['download_primary'] = false; + $subscription['actions'][] = $action; + } + + // Mark the first action primary. + foreach ( $subscription['actions'] as $key => $action ) { + if ( ! empty( $action['button_label'] ) ) { + $subscription['actions'][ $key ]['primary'] = true; + break; + } + } + } + + // Break the by-ref. + unset( $subscription ); + + // Installed products without a subscription. + $no_subscriptions = array(); + foreach ( array_merge( $woo_plugins, $woo_themes ) as $filename => $data ) { + if ( in_array( $data['_product_id'], $subscriptions_product_ids ) ) { + continue; + } + + $data['_product_url'] = '#'; + $data['_has_update'] = false; + + if ( ! empty( $updates[ $data['_product_id'] ] ) ) { + $data['_has_update'] = version_compare( $updates[ $data['_product_id'] ]['version'], $data['Version'], '>' ); + + if ( ! empty( $updates[ $data['_product_id'] ]['url'] ) ) { + $data['_product_url'] = $updates[ $data['_product_id'] ]['url']; + } elseif ( ! empty( $data['PluginURI'] ) ) { + $data['_product_url'] = $data['PluginURI']; + } + } + + $data['_actions'] = array(); + + if ( $data['_has_update'] ) { + $action = array( + /* translators: %s: version number */ + 'message' => sprintf( __( 'Version %s is available. To enable this update you need to purchase a new subscription.', 'woocommerce' ), esc_html( $updates[ $data['_product_id'] ]['version'] ) ), + 'button_label' => __( 'Purchase', 'woocommerce' ), + 'button_url' => $data['_product_url'], + 'status' => 'expired', + 'icon' => 'dashicons-info', + ); + + $data['_actions'][] = $action; + } else { + $action = array( + /* translators: 1: subscriptions docs 2: subscriptions docs */ + 'message' => sprintf( __( 'To receive updates and support for this extension, you need to purchase a new subscription or consolidate your extensions to one connected account by sharing or transferring this extension to this connected account.', 'woocommerce' ), 'https://docs.woocommerce.com/document/managing-woocommerce-com-subscriptions/#section-10', 'https://docs.woocommerce.com/document/managing-woocommerce-com-subscriptions/#section-5' ), + 'button_label' => __( 'Purchase', 'woocommerce' ), + 'button_url' => $data['_product_url'], + 'status' => 'expired', + 'icon' => 'dashicons-info', + ); + + $data['_actions'][] = $action; + } + + $no_subscriptions[ $filename ] = $data; + } + + // Update the user id if it came from a migrated connection. + if ( empty( $auth['user_id'] ) ) { + $auth['user_id'] = get_current_user_id(); + WC_Helper_Options::update( 'auth', $auth ); + } + + // Sort alphabetically. + uasort( $subscriptions, array( __CLASS__, '_sort_by_product_name' ) ); + uasort( $no_subscriptions, array( __CLASS__, '_sort_by_name' ) ); + + // Filters. + self::get_filters_counts( $subscriptions ); // Warm it up. + self::_filter( $subscriptions, self::get_current_filter() ); + + // We have an active connection. + include self::get_view_filename( 'html-main.php' ); + return; + } + + /** + * Get available subscriptions filters. + * + * @return array An array of filter keys and labels. + */ + public static function get_filters() { + $filters = array( + 'all' => __( 'All', 'woocommerce' ), + 'active' => __( 'Active', 'woocommerce' ), + 'inactive' => __( 'Inactive', 'woocommerce' ), + 'installed' => __( 'Installed', 'woocommerce' ), + 'update-available' => __( 'Update Available', 'woocommerce' ), + 'expiring' => __( 'Expiring Soon', 'woocommerce' ), + 'expired' => __( 'Expired', 'woocommerce' ), + 'download' => __( 'Download', 'woocommerce' ), + ); + + return $filters; + } + + /** + * Get counts data for the filters array. + * + * @param array $subscriptions The array of all available subscriptions. + * + * @return array Filter counts (filter => count). + */ + public static function get_filters_counts( $subscriptions = null ) { + static $filters; + + if ( isset( $filters ) ) { + return $filters; + } + + $filters = array_fill_keys( array_keys( self::get_filters() ), 0 ); + if ( empty( $subscriptions ) ) { + return array(); + } + + foreach ( $filters as $key => $count ) { + $_subs = $subscriptions; + self::_filter( $_subs, $key ); + $filters[ $key ] = count( $_subs ); + } + + return $filters; + } + + /** + * Get current filter. + * + * @return string The current filter. + */ + public static function get_current_filter() { + $current_filter = 'all'; + $valid_filters = array_keys( self::get_filters() ); + + if ( ! empty( $_GET['filter'] ) && in_array( wp_unslash( $_GET['filter'] ), $valid_filters ) ) { + $current_filter = wc_clean( wp_unslash( $_GET['filter'] ) ); + } + + return $current_filter; + } + + /** + * Filter an array of subscriptions by $filter. + * + * @param array $subscriptions The subscriptions array, passed by ref. + * @param string $filter The filter. + */ + private static function _filter( &$subscriptions, $filter ) { + switch ( $filter ) { + case 'active': + $subscriptions = wp_list_filter( $subscriptions, array( 'active' => true ) ); + break; + + case 'inactive': + $subscriptions = wp_list_filter( $subscriptions, array( 'active' => false ) ); + break; + + case 'installed': + foreach ( $subscriptions as $key => $subscription ) { + if ( empty( $subscription['local']['installed'] ) ) { + unset( $subscriptions[ $key ] ); + } + } + break; + + case 'update-available': + $subscriptions = wp_list_filter( $subscriptions, array( 'has_update' => true ) ); + break; + + case 'expiring': + $subscriptions = wp_list_filter( $subscriptions, array( 'expiring' => true ) ); + break; + + case 'expired': + $subscriptions = wp_list_filter( $subscriptions, array( 'expired' => true ) ); + break; + + case 'download': + foreach ( $subscriptions as $key => $subscription ) { + if ( $subscription['local']['installed'] || $subscription['expired'] ) { + unset( $subscriptions[ $key ] ); + } + } + break; + } + } + + /** + * Enqueue admin scripts and styles. + */ + public static function admin_enqueue_scripts() { + $screen = get_current_screen(); + $screen_id = $screen ? $screen->id : ''; + $wc_screen_id = sanitize_title( __( 'WooCommerce', 'woocommerce' ) ); + + if ( $wc_screen_id . '_page_wc-addons' === $screen_id && isset( $_GET['section'] ) && 'helper' === $_GET['section'] ) { + wp_enqueue_style( 'woocommerce-helper', WC()->plugin_url() . '/assets/css/helper.css', array(), Constants::get_constant( 'WC_VERSION' ) ); + wp_style_add_data( 'woocommerce-helper', 'rtl', 'replace' ); + } + } + + /** + * Various success/error notices. + * + * Runs during admin page render, so no headers/redirects here. + * + * @return array Array pairs of message/type strings with notices. + */ + private static function _get_return_notices() { + $return_status = isset( $_GET['wc-helper-status'] ) ? wc_clean( wp_unslash( $_GET['wc-helper-status'] ) ) : null; + $notices = array(); + + switch ( $return_status ) { + case 'activate-success': + $product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0; + $subscription = self::_get_subscriptions_from_product_id( $product_id ); + $notices[] = array( + 'type' => 'updated', + 'message' => sprintf( + /* translators: %s: product name */ + __( '%s activated successfully. You will now receive updates for this product.', 'woocommerce' ), + '' . esc_html( $subscription['product_name'] ) . '' + ), + ); + break; + + case 'activate-error': + $product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0; + $subscription = self::_get_subscriptions_from_product_id( $product_id ); + $notices[] = array( + 'type' => 'error', + 'message' => sprintf( + /* translators: %s: product name */ + __( 'An error has occurred when activating %s. Please try again later.', 'woocommerce' ), + '' . esc_html( $subscription['product_name'] ) . '' + ), + ); + break; + + case 'deactivate-success': + $product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0; + $subscription = self::_get_subscriptions_from_product_id( $product_id ); + $local = self::_get_local_from_product_id( $product_id ); + + $message = sprintf( + /* translators: %s: product name */ + __( 'Subscription for %s deactivated successfully. You will no longer receive updates for this product.', 'woocommerce' ), + '' . esc_html( $subscription['product_name'] ) . '' + ); + + if ( $local && is_plugin_active( $local['_filename'] ) && current_user_can( 'activate_plugins' ) ) { + $deactivate_plugin_url = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'filter' => self::get_current_filter(), + 'wc-helper-deactivate-plugin' => 1, + 'wc-helper-product-id' => $subscription['product_id'], + 'wc-helper-nonce' => wp_create_nonce( 'deactivate-plugin:' . $subscription['product_id'] ), + ), + admin_url( 'admin.php' ) + ); + + $message = sprintf( + /* translators: %1$s: product name, %2$s: deactivate url */ + __( 'Subscription for %1$s deactivated successfully. You will no longer receive updates for this product. Click here if you wish to deactivate the plugin as well.', 'woocommerce' ), + '' . esc_html( $subscription['product_name'] ) . '', + esc_url( $deactivate_plugin_url ) + ); + } + + $notices[] = array( + 'message' => $message, + 'type' => 'updated', + ); + break; + + case 'deactivate-error': + $product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0; + $subscription = self::_get_subscriptions_from_product_id( $product_id ); + $notices[] = array( + 'type' => 'error', + 'message' => sprintf( + /* translators: %s: product name */ + __( 'An error has occurred when deactivating the subscription for %s. Please try again later.', 'woocommerce' ), + '' . esc_html( $subscription['product_name'] ) . '' + ), + ); + break; + + case 'deactivate-plugin-success': + $product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0; + $subscription = self::_get_subscriptions_from_product_id( $product_id ); + $notices[] = array( + 'type' => 'updated', + 'message' => sprintf( + /* translators: %s: product name */ + __( 'The extension %s has been deactivated successfully.', 'woocommerce' ), + '' . esc_html( $subscription['product_name'] ) . '' + ), + ); + break; + + case 'deactivate-plugin-error': + $product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0; + $subscription = self::_get_subscriptions_from_product_id( $product_id ); + $notices[] = array( + 'type' => 'error', + 'message' => sprintf( + /* translators: %1$s: product name, %2$s: plugins screen url */ + __( 'An error has occurred when deactivating the extension %1$s. Please proceed to the Plugins screen to deactivate it manually.', 'woocommerce' ), + '' . esc_html( $subscription['product_name'] ) . '', + admin_url( 'plugins.php' ) + ), + ); + break; + + case 'helper-connected': + $notices[] = array( + 'message' => __( 'You have successfully connected your store to WooCommerce.com', 'woocommerce' ), + 'type' => 'updated', + ); + break; + + case 'helper-disconnected': + $notices[] = array( + 'message' => __( 'You have successfully disconnected your store from WooCommerce.com', 'woocommerce' ), + 'type' => 'updated', + ); + break; + + case 'helper-refreshed': + $notices[] = array( + 'message' => __( 'Authentication and subscription caches refreshed successfully.', 'woocommerce' ), + 'type' => 'updated', + ); + break; + } + + return $notices; + } + + /** + * Various early-phase actions with possible redirects. + * + * @param object $screen WP screen object. + */ + public static function current_screen( $screen ) { + $wc_screen_id = sanitize_title( __( 'WooCommerce', 'woocommerce' ) ); + + if ( $wc_screen_id . '_page_wc-addons' !== $screen->id ) { + return; + } + + if ( empty( $_GET['section'] ) || 'helper' !== $_GET['section'] ) { + return; + } + + if ( ! empty( $_GET['wc-helper-connect'] ) ) { + return self::_helper_auth_connect(); + } + + if ( ! empty( $_GET['wc-helper-return'] ) ) { + return self::_helper_auth_return(); + } + + if ( ! empty( $_GET['wc-helper-disconnect'] ) ) { + return self::_helper_auth_disconnect(); + } + + if ( ! empty( $_GET['wc-helper-refresh'] ) ) { + return self::_helper_auth_refresh(); + } + + if ( ! empty( $_GET['wc-helper-activate'] ) ) { + return self::_helper_subscription_activate(); + } + + if ( ! empty( $_GET['wc-helper-deactivate'] ) ) { + return self::_helper_subscription_deactivate(); + } + + if ( ! empty( $_GET['wc-helper-deactivate-plugin'] ) ) { + return self::_helper_plugin_deactivate(); + } + } + + /** + * Initiate a new OAuth connection. + */ + private static function _helper_auth_connect() { + if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'connect' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + self::log( 'Could not verify nonce in _helper_auth_connect' ); + wp_die( 'Could not verify nonce' ); + } + + $redirect_uri = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'wc-helper-return' => 1, + 'wc-helper-nonce' => wp_create_nonce( 'connect' ), + ), + admin_url( 'admin.php' ) + ); + + $request = WC_Helper_API::post( + 'oauth/request_token', + array( + 'body' => array( + 'home_url' => home_url(), + 'redirect_uri' => $redirect_uri, + ), + ) + ); + + $code = wp_remote_retrieve_response_code( $request ); + + if ( 200 !== $code ) { + self::log( sprintf( 'Call to oauth/request_token returned a non-200 response code (%d)', $code ) ); + wp_die( 'Something went wrong' ); + } + + $secret = json_decode( wp_remote_retrieve_body( $request ) ); + if ( empty( $secret ) ) { + self::log( sprintf( 'Call to oauth/request_token returned an invalid body: %s', wp_remote_retrieve_body( $request ) ) ); + wp_die( 'Something went wrong' ); + } + + /** + * Fires when the Helper connection process is initiated. + */ + do_action( 'woocommerce_helper_connect_start' ); + + $connect_url = add_query_arg( + array( + 'home_url' => rawurlencode( home_url() ), + 'redirect_uri' => rawurlencode( $redirect_uri ), + 'secret' => rawurlencode( $secret ), + ), + WC_Helper_API::url( 'oauth/authorize' ) + ); + + wp_redirect( esc_url_raw( $connect_url ) ); + die(); + } + + /** + * Return from WooCommerce.com OAuth flow. + */ + private static function _helper_auth_return() { + if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'connect' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + self::log( 'Could not verify nonce in _helper_auth_return' ); + wp_die( 'Something went wrong' ); + } + + // Bail if the user clicked deny. + if ( ! empty( $_GET['deny'] ) ) { + /** + * Fires when the Helper connection process is denied/cancelled. + */ + do_action( 'woocommerce_helper_denied' ); + wp_safe_redirect( admin_url( 'admin.php?page=wc-addons§ion=helper' ) ); + die(); + } + + // We do need a request token... + if ( empty( $_GET['request_token'] ) ) { + self::log( 'Request token not found in _helper_auth_return' ); + wp_die( 'Something went wrong' ); + } + + // Obtain an access token. + $request = WC_Helper_API::post( + 'oauth/access_token', + array( + 'body' => array( + 'request_token' => wp_unslash( $_GET['request_token'] ), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + 'home_url' => home_url(), + ), + ) + ); + + $code = wp_remote_retrieve_response_code( $request ); + + if ( 200 !== $code ) { + self::log( sprintf( 'Call to oauth/access_token returned a non-200 response code (%d)', $code ) ); + wp_die( 'Something went wrong' ); + } + + $access_token = json_decode( wp_remote_retrieve_body( $request ), true ); + if ( ! $access_token ) { + self::log( sprintf( 'Call to oauth/access_token returned an invalid body: %s', wp_remote_retrieve_body( $request ) ) ); + wp_die( 'Something went wrong' ); + } + + WC_Helper_Options::update( + 'auth', + array( + 'access_token' => $access_token['access_token'], + 'access_token_secret' => $access_token['access_token_secret'], + 'site_id' => $access_token['site_id'], + 'user_id' => get_current_user_id(), + 'updated' => time(), + ) + ); + + // Obtain the connected user info. + if ( ! self::_flush_authentication_cache() ) { + self::log( 'Could not obtain connected user info in _helper_auth_return' ); + WC_Helper_Options::update( 'auth', array() ); + wp_die( 'Something went wrong.' ); + } + + self::_flush_subscriptions_cache(); + self::_flush_updates_cache(); + + /** + * Fires when the Helper connection process has completed successfully. + */ + do_action( 'woocommerce_helper_connected' ); + + // Enable tracking when connected. + if ( class_exists( 'WC_Tracker' ) ) { + update_option( 'woocommerce_allow_tracking', 'yes' ); + WC_Tracker::send_tracking_data( true ); + } + + // If connecting through in-app purchase, redirects back to WooCommerce.com + // for product installation. + if ( ! empty( $_GET['wccom-install-url'] ) ) { + wp_redirect( wp_unslash( $_GET['wccom-install-url'] ) ); + exit; + } + + wp_safe_redirect( + add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'wc-helper-status' => 'helper-connected', + ), + admin_url( 'admin.php' ) + ) + ); + die(); + } + + /** + * Disconnect from WooCommerce.com, clear OAuth tokens. + */ + private static function _helper_auth_disconnect() { + if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'disconnect' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + self::log( 'Could not verify nonce in _helper_auth_disconnect' ); + wp_die( 'Could not verify nonce' ); + } + + /** + * Fires when the Helper has been disconnected. + */ + do_action( 'woocommerce_helper_disconnected' ); + + $redirect_uri = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'wc-helper-status' => 'helper-disconnected', + ), + admin_url( 'admin.php' ) + ); + + WC_Helper_API::post( + 'oauth/invalidate_token', + array( + 'authenticated' => true, + ) + ); + + WC_Helper_Options::update( 'auth', array() ); + WC_Helper_Options::update( 'auth_user_data', array() ); + + self::_flush_subscriptions_cache(); + self::_flush_updates_cache(); + + wp_safe_redirect( $redirect_uri ); + die(); + } + + /** + * User hit the Refresh button, clear all caches. + */ + private static function _helper_auth_refresh() { + if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'refresh' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + self::log( 'Could not verify nonce in _helper_auth_refresh' ); + wp_die( 'Could not verify nonce' ); + } + + /** + * Fires when Helper subscriptions are refreshed. + */ + do_action( 'woocommerce_helper_subscriptions_refresh' ); + + $redirect_uri = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'filter' => self::get_current_filter(), + 'wc-helper-status' => 'helper-refreshed', + ), + admin_url( 'admin.php' ) + ); + + self::_flush_authentication_cache(); + self::_flush_subscriptions_cache(); + self::_flush_updates_cache(); + + wp_safe_redirect( $redirect_uri ); + die(); + } + + /** + * Active a product subscription. + */ + private static function _helper_subscription_activate() { + $product_key = isset( $_GET['wc-helper-product-key'] ) ? wc_clean( wp_unslash( $_GET['wc-helper-product-key'] ) ) : ''; + $product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0; + + if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'activate:' . $product_key ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + self::log( 'Could not verify nonce in _helper_subscription_activate' ); + wp_die( 'Could not verify nonce' ); + } + + // Activate subscription. + $activation_response = WC_Helper_API::post( + 'activate', + array( + 'authenticated' => true, + 'body' => wp_json_encode( + array( + 'product_key' => $product_key, + ) + ), + ) + ); + + $activated = wp_remote_retrieve_response_code( $activation_response ) === 200; + $body = json_decode( wp_remote_retrieve_body( $activation_response ), true ); + + if ( ! $activated && ! empty( $body['code'] ) && 'already_connected' === $body['code'] ) { + $activated = true; + } + + if ( $activated ) { + /** + * Fires when the Helper activates a product successfully. + * + * @param int $product_id Product ID being activated. + * @param string $product_key Subscription product key. + * @param array $activation_response The response object from wp_safe_remote_request(). + */ + do_action( 'woocommerce_helper_subscription_activate_success', $product_id, $product_key, $activation_response ); + } else { + /** + * Fires when the Helper fails to activate a product. + * + * @param int $product_id Product ID being activated. + * @param string $product_key Subscription product key. + * @param array $activation_response The response object from wp_safe_remote_request(). + */ + do_action( 'woocommerce_helper_subscription_activate_error', $product_id, $product_key, $activation_response ); + } + + // Attempt to activate this plugin. + $local = self::_get_local_from_product_id( $product_id ); + if ( $local && 'plugin' == $local['_type'] && current_user_can( 'activate_plugins' ) && ! is_plugin_active( $local['_filename'] ) ) { + activate_plugin( $local['_filename'] ); + } + + self::_flush_subscriptions_cache(); + self::_flush_updates_cache(); + + $redirect_uri = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'filter' => self::get_current_filter(), + 'wc-helper-status' => $activated ? 'activate-success' : 'activate-error', + 'wc-helper-product-id' => $product_id, + ), + admin_url( 'admin.php' ) + ); + + wp_safe_redirect( $redirect_uri ); + die(); + } + + /** + * Deactivate a product subscription. + */ + private static function _helper_subscription_deactivate() { + $product_key = isset( $_GET['wc-helper-product-key'] ) ? wc_clean( wp_unslash( $_GET['wc-helper-product-key'] ) ) : ''; + $product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0; + + if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'deactivate:' . $product_key ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + self::log( 'Could not verify nonce in _helper_subscription_deactivate' ); + wp_die( 'Could not verify nonce' ); + } + + $deactivation_response = WC_Helper_API::post( + 'deactivate', + array( + 'authenticated' => true, + 'body' => wp_json_encode( + array( + 'product_key' => $product_key, + ) + ), + ) + ); + + $code = wp_remote_retrieve_response_code( $deactivation_response ); + $deactivated = 200 === $code; + + if ( $deactivated ) { + /** + * Fires when the Helper activates a product successfully. + * + * @param int $product_id Product ID being deactivated. + * @param string $product_key Subscription product key. + * @param array $deactivation_response The response object from wp_safe_remote_request(). + */ + do_action( 'woocommerce_helper_subscription_deactivate_success', $product_id, $product_key, $deactivation_response ); + } else { + self::log( sprintf( 'Deactivate API call returned a non-200 response code (%d)', $code ) ); + + /** + * Fires when the Helper fails to activate a product. + * + * @param int $product_id Product ID being deactivated. + * @param string $product_key Subscription product key. + * @param array $deactivation_response The response object from wp_safe_remote_request(). + */ + do_action( 'woocommerce_helper_subscription_deactivate_error', $product_id, $product_key, $deactivation_response ); + } + + self::_flush_subscriptions_cache(); + + $redirect_uri = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'filter' => self::get_current_filter(), + 'wc-helper-status' => $deactivated ? 'deactivate-success' : 'deactivate-error', + 'wc-helper-product-id' => $product_id, + ), + admin_url( 'admin.php' ) + ); + + wp_safe_redirect( $redirect_uri ); + die(); + } + + /** + * Deactivate a plugin. + */ + private static function _helper_plugin_deactivate() { + $product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0; + $deactivated = false; + + if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'deactivate-plugin:' . $product_id ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + self::log( 'Could not verify nonce in _helper_plugin_deactivate' ); + wp_die( 'Could not verify nonce' ); + } + + if ( ! current_user_can( 'activate_plugins' ) ) { + wp_die( 'You are not allowed to manage plugins on this site.' ); + } + + $local = wp_list_filter( + array_merge( + self::get_local_woo_plugins(), + self::get_local_woo_themes() + ), + array( '_product_id' => $product_id ) + ); + + // Attempt to deactivate this plugin or theme. + if ( ! empty( $local ) ) { + $local = array_shift( $local ); + if ( is_plugin_active( $local['_filename'] ) ) { + deactivate_plugins( $local['_filename'] ); + } + + $deactivated = ! is_plugin_active( $local['_filename'] ); + } + + $redirect_uri = add_query_arg( + array( + 'page' => 'wc-addons', + 'section' => 'helper', + 'filter' => self::get_current_filter(), + 'wc-helper-status' => $deactivated ? 'deactivate-plugin-success' : 'deactivate-plugin-error', + 'wc-helper-product-id' => $product_id, + ), + admin_url( 'admin.php' ) + ); + + wp_safe_redirect( $redirect_uri ); + die(); + } + + /** + * Get a local plugin/theme entry from product_id. + * + * @param int $product_id The product id. + * + * @return array|bool The array containing the local plugin/theme data or false. + */ + private static function _get_local_from_product_id( $product_id ) { + $local = wp_list_filter( + array_merge( + self::get_local_woo_plugins(), + self::get_local_woo_themes() + ), + array( '_product_id' => $product_id ) + ); + + if ( ! empty( $local ) ) { + return array_shift( $local ); + } + + return false; + } + + /** + * Checks whether current site has product subscription of a given ID. + * + * @since 3.7.0 + * + * @param int $product_id The product id. + * + * @return bool Returns true if product subscription exists, false otherwise. + */ + public static function has_product_subscription( $product_id ) { + $subscription = self::_get_subscriptions_from_product_id( $product_id, true ); + return ! empty( $subscription ); + } + + /** + * Get a subscription entry from product_id. If multiple subscriptions are + * found with the same product id and $single is set to true, will return the + * first one in the list, so you can use this method to get things like extension + * name, version, etc. + * + * @param int $product_id The product id. + * @param bool $single Whether to return a single subscription or all matching a product id. + * + * @return array|bool The array containing sub data or false. + */ + private static function _get_subscriptions_from_product_id( $product_id, $single = true ) { + $subscriptions = wp_list_filter( self::get_subscriptions(), array( 'product_id' => $product_id ) ); + if ( ! empty( $subscriptions ) ) { + return $single ? array_shift( $subscriptions ) : $subscriptions; + } + + return false; + } + + /** + * Obtain a list of data about locally installed Woo extensions. + */ + public static function get_local_woo_plugins() { + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $plugins = get_plugins(); + + /** + * Check if plugins have WC headers, if not then clear cache and fetch again. + * WC Headers will not be present if `wc_enable_wc_plugin_headers` hook was added after a `get_plugins` call -- for example when WC is activated/updated. + * Also, get_plugins call is expensive so we should clear this cache very conservatively. + */ + if ( ! empty( $plugins ) && ! array_key_exists( 'Woo', current( $plugins ) ) ) { + wp_clean_plugins_cache( false ); + $plugins = get_plugins(); + } + + $woo_plugins = array(); + + // Backwards compatibility for woothemes_queue_update(). + $_compat = array(); + if ( ! empty( $GLOBALS['woothemes_queued_updates'] ) ) { + foreach ( $GLOBALS['woothemes_queued_updates'] as $_compat_plugin ) { + $_compat[ $_compat_plugin->file ] = array( + 'product_id' => $_compat_plugin->product_id, + 'file_id' => $_compat_plugin->file_id, + ); + } + } + + foreach ( $plugins as $filename => $data ) { + if ( empty( $data['Woo'] ) && ! empty( $_compat[ $filename ] ) ) { + $data['Woo'] = sprintf( '%d:%s', $_compat[ $filename ]['product_id'], $_compat[ $filename ]['file_id'] ); + } + + if ( empty( $data['Woo'] ) ) { + continue; + } + + list( $product_id, $file_id ) = explode( ':', $data['Woo'] ); + if ( empty( $product_id ) || empty( $file_id ) ) { + continue; + } + + $data['_filename'] = $filename; + $data['_product_id'] = absint( $product_id ); + $data['_file_id'] = $file_id; + $data['_type'] = 'plugin'; + $data['slug'] = dirname( $filename ); + $woo_plugins[ $filename ] = $data; + } + + return $woo_plugins; + } + + /** + * Get locally installed Woo themes. + */ + public static function get_local_woo_themes() { + $themes = wp_get_themes(); + $woo_themes = array(); + + foreach ( $themes as $theme ) { + $header = $theme->get( 'Woo' ); + + // Backwards compatibility for theme_info.txt. + if ( ! $header ) { + $txt = $theme->get_stylesheet_directory() . '/theme_info.txt'; + if ( is_readable( $txt ) ) { + $txt = file_get_contents( $txt ); + $txt = preg_split( '#\s#', $txt ); + if ( count( $txt ) >= 2 ) { + $header = sprintf( '%d:%s', $txt[0], $txt[1] ); + } + } + } + + if ( empty( $header ) ) { + continue; + } + + list( $product_id, $file_id ) = explode( ':', $header ); + if ( empty( $product_id ) || empty( $file_id ) ) { + continue; + } + + $data = array( + 'Name' => $theme->get( 'Name' ), + 'Version' => $theme->get( 'Version' ), + 'Woo' => $header, + + '_filename' => $theme->get_stylesheet() . '/style.css', + '_stylesheet' => $theme->get_stylesheet(), + '_product_id' => absint( $product_id ), + '_file_id' => $file_id, + '_type' => 'theme', + ); + + $woo_themes[ $data['_filename'] ] = $data; + } + + return $woo_themes; + } + + /** + * Get the connected user's subscriptions. + * + * @return array + */ + public static function get_subscriptions() { + $cache_key = '_woocommerce_helper_subscriptions'; + $data = get_transient( $cache_key ); + if ( false !== $data ) { + return $data; + } + + // Obtain the connected user info. + $request = WC_Helper_API::get( + 'subscriptions', + array( + 'authenticated' => true, + ) + ); + + if ( wp_remote_retrieve_response_code( $request ) !== 200 ) { + set_transient( $cache_key, array(), 15 * MINUTE_IN_SECONDS ); + return array(); + } + + $data = json_decode( wp_remote_retrieve_body( $request ), true ); + if ( empty( $data ) || ! is_array( $data ) ) { + $data = array(); + } + + set_transient( $cache_key, $data, 1 * HOUR_IN_SECONDS ); + return $data; + } + + /** + * Runs when any plugin is activated. + * + * Depending on the activated plugin attempts to look through available + * subscriptions and auto-activate one if possible, so the user does not + * need to visit the Helper UI at all after installing a new extension. + * + * @param string $filename The filename of the activated plugin. + */ + public static function activated_plugin( $filename ) { + $plugins = self::get_local_woo_plugins(); + + // Not a local woo plugin. + if ( empty( $plugins[ $filename ] ) ) { + return; + } + + // Make sure we have a connection. + $auth = WC_Helper_Options::get( 'auth' ); + if ( empty( $auth ) ) { + return; + } + + $plugin = $plugins[ $filename ]; + $product_id = $plugin['_product_id']; + $subscriptions = self::_get_subscriptions_from_product_id( $product_id, false ); + + // No valid subscriptions for this product. + if ( empty( $subscriptions ) ) { + return; + } + + $subscription = null; + foreach ( $subscriptions as $_sub ) { + + // Don't attempt to activate expired subscriptions. + if ( $_sub['expired'] ) { + continue; + } + + // No more sites available in this subscription. + if ( $_sub['sites_max'] && $_sub['sites_active'] >= $_sub['sites_max'] ) { + continue; + } + + // Looks good. + $subscription = $_sub; + break; + } + + // No valid subscription found. + if ( ! $subscription ) { + return; + } + + $product_key = $subscription['product_key']; + $activation_response = WC_Helper_API::post( + 'activate', + array( + 'authenticated' => true, + 'body' => wp_json_encode( + array( + 'product_key' => $product_key, + ) + ), + ) + ); + + $activated = wp_remote_retrieve_response_code( $activation_response ) === 200; + $body = json_decode( wp_remote_retrieve_body( $activation_response ), true ); + + if ( ! $activated && ! empty( $body['code'] ) && 'already_connected' === $body['code'] ) { + $activated = true; + } + + if ( $activated ) { + self::log( 'Auto-activated a subscription for ' . $filename ); + /** + * Fires when the Helper activates a product successfully. + * + * @param int $product_id Product ID being activated. + * @param string $product_key Subscription product key. + * @param array $activation_response The response object from wp_safe_remote_request(). + */ + do_action( 'woocommerce_helper_subscription_activate_success', $product_id, $product_key, $activation_response ); + } else { + self::log( 'Could not activate a subscription upon plugin activation: ' . $filename ); + + /** + * Fires when the Helper fails to activate a product. + * + * @param int $product_id Product ID being activated. + * @param string $product_key Subscription product key. + * @param array $activation_response The response object from wp_safe_remote_request(). + */ + do_action( 'woocommerce_helper_subscription_activate_error', $product_id, $product_key, $activation_response ); + } + + self::_flush_subscriptions_cache(); + self::_flush_updates_cache(); + } + + /** + * Runs when any plugin is deactivated. + * + * When a user deactivates a plugin, attempt to deactivate any subscriptions + * associated with the extension. + * + * @param string $filename The filename of the deactivated plugin. + */ + public static function deactivated_plugin( $filename ) { + $plugins = self::get_local_woo_plugins(); + + // Not a local woo plugin. + if ( empty( $plugins[ $filename ] ) ) { + return; + } + + // Make sure we have a connection. + $auth = WC_Helper_Options::get( 'auth' ); + if ( empty( $auth ) ) { + return; + } + + $plugin = $plugins[ $filename ]; + $product_id = $plugin['_product_id']; + $subscriptions = self::_get_subscriptions_from_product_id( $product_id, false ); + $site_id = absint( $auth['site_id'] ); + + // No valid subscriptions for this product. + if ( empty( $subscriptions ) ) { + return; + } + + $deactivated = 0; + + foreach ( $subscriptions as $subscription ) { + // Don't touch subscriptions that aren't activated on this site. + if ( ! in_array( $site_id, $subscription['connections'], true ) ) { + continue; + } + + $product_key = $subscription['product_key']; + $deactivation_response = WC_Helper_API::post( + 'deactivate', + array( + 'authenticated' => true, + 'body' => wp_json_encode( + array( + 'product_key' => $product_key, + ) + ), + ) + ); + + if ( wp_remote_retrieve_response_code( $deactivation_response ) === 200 ) { + $deactivated++; + + /** + * Fires when the Helper activates a product successfully. + * + * @param int $product_id Product ID being deactivated. + * @param string $product_key Subscription product key. + * @param array $deactivation_response The response object from wp_safe_remote_request(). + */ + do_action( 'woocommerce_helper_subscription_deactivate_success', $product_id, $product_key, $deactivation_response ); + } else { + /** + * Fires when the Helper fails to activate a product. + * + * @param int $product_id Product ID being deactivated. + * @param string $product_key Subscription product key. + * @param array $deactivation_response The response object from wp_safe_remote_request(). + */ + do_action( 'woocommerce_helper_subscription_deactivate_error', $product_id, $product_key, $deactivation_response ); + } + } + + if ( $deactivated ) { + self::log( sprintf( 'Auto-deactivated %d subscription(s) for %s', $deactivated, $filename ) ); + self::_flush_subscriptions_cache(); + self::_flush_updates_cache(); + } + } + + /** + * Various Helper-related admin notices. + */ + public static function admin_notices() { + if ( apply_filters( 'woocommerce_helper_suppress_admin_notices', false ) ) { + return; + } + + $screen = get_current_screen(); + $screen_id = $screen ? $screen->id : ''; + + if ( 'update-core' !== $screen_id ) { + return; + } + + // Don't nag if Woo doesn't have an update available. + if ( ! self::_woo_core_update_available() ) { + return; + } + + // Add a note about available extension updates if Woo core has an update available. + $notice = self::_get_extensions_update_notice(); + if ( ! empty( $notice ) ) { + echo '

    ' . $notice . '

    '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + + /** + * Get an update notice if one or more Woo extensions has an update available. + * + * @return string|null The update notice or null if everything is up to date. + */ + private static function _get_extensions_update_notice() { + $plugins = self::get_local_woo_plugins(); + $updates = WC_Helper_Updater::get_update_data(); + $available = 0; + + foreach ( $plugins as $data ) { + if ( empty( $updates[ $data['_product_id'] ] ) ) { + continue; + } + + $product_id = $data['_product_id']; + if ( version_compare( $updates[ $product_id ]['version'], $data['Version'], '>' ) ) { + $available++; + } + } + + if ( ! $available ) { + return; + } + + return sprintf( + /* translators: %1$s: helper url, %2$d: number of extensions */ + _n( 'Note: You currently have %2$d paid extension which should be updated first before updating WooCommerce.', 'Note: You currently have %2$d paid extensions which should be updated first before updating WooCommerce.', $available, 'woocommerce' ), + admin_url( 'admin.php?page=wc-addons§ion=helper' ), + $available + ); + } + + /** + * Whether WooCommerce has an update available. + * + * @return bool True if a Woo core update is available. + */ + private static function _woo_core_update_available() { + $updates = get_site_transient( 'update_plugins' ); + if ( empty( $updates->response ) ) { + return false; + } + + if ( empty( $updates->response['woocommerce/woocommerce.php'] ) ) { + return false; + } + + $data = $updates->response['woocommerce/woocommerce.php']; + if ( version_compare( Constants::get_constant( 'WC_VERSION' ), $data->new_version, '>=' ) ) { + return false; + } + + return true; + } + + /** + * Flush subscriptions cache. + */ + public static function _flush_subscriptions_cache() { + delete_transient( '_woocommerce_helper_subscriptions' ); + } + + /** + * Flush auth cache. + */ + public static function _flush_authentication_cache() { + $request = WC_Helper_API::get( + 'oauth/me', + array( + 'authenticated' => true, + ) + ); + + if ( wp_remote_retrieve_response_code( $request ) !== 200 ) { + return false; + } + + $user_data = json_decode( wp_remote_retrieve_body( $request ), true ); + if ( ! $user_data ) { + return false; + } + + WC_Helper_Options::update( + 'auth_user_data', + array( + 'name' => $user_data['name'], + 'email' => $user_data['email'], + ) + ); + + return true; + } + + /** + * Flush updates cache. + */ + private static function _flush_updates_cache() { + WC_Helper_Updater::flush_updates_cache(); + } + + /** + * Sort subscriptions by the product_name. + * + * @param array $a Subscription array. + * @param array $b Subscription array. + * + * @return int + */ + public static function _sort_by_product_name( $a, $b ) { + return strcmp( $a['product_name'], $b['product_name'] ); + } + + /** + * Sort subscriptions by the Name. + * + * @param array $a Product array. + * @param array $b Product array. + * + * @return int + */ + public static function _sort_by_name( $a, $b ) { + return strcmp( $a['Name'], $b['Name'] ); + } + + /** + * Log a helper event. + * + * @param string $message Log message. + * @param string $level Optional, defaults to info, valid levels: emergency|alert|critical|error|warning|notice|info|debug. + */ + public static function log( $message, $level = 'info' ) { + if ( ! Constants::is_true( 'WP_DEBUG' ) ) { + return; + } + + if ( ! isset( self::$log ) ) { + self::$log = wc_get_logger(); + } + + self::$log->log( $level, $message, array( 'source' => 'helper' ) ); + } +} + +WC_Helper::load(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-helper-compat.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-helper-compat.php new file mode 100644 index 0000000..24ecce5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-helper-compat.php @@ -0,0 +1,6 @@ + + +
    +

    +

    View and manage your extensions now.', 'woocommerce' ), esc_url( $helper_url ) ); ?>

    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-main.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-main.php new file mode 100644 index 0000000..3023a19 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-main.php @@ -0,0 +1,214 @@ + + +
    + +

    + + + +
    +

    + +

    Plugins screen.', 'woocommerce' ), admin_url( 'plugins.php' ) ); ?>

    +
    + +
      + + + + $label ) : + // Don't show empty filters. + if ( empty( $counts[ $key ] ) ) { + continue; + } + + $url = admin_url( 'admin.php?page=wc-addons§ion=helper&filter=' . $key ); + $class_html = $current_filter === $key ? 'class="current"' : ''; + ?> +
    • + href=""> + + () + +
    • + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + 0 ) { + /* translators: %1$d: sites active, %2$d max sites active */ + printf( __( 'Subscription: Using %1$d of %2$d sites available', 'woocommerce' ), absint( $subscription['sites_active'] ), absint( $subscription['sites_max'] ) ); + } else { + _e( 'Subscription: Unlimited', 'woocommerce' ); + } + + // Check shared. + if ( ! empty( $subscription['is_shared'] ) && ! empty( $subscription['owner_email'] ) ) { + printf( '
    ' . __( 'Shared by %s', 'woocommerce' ), esc_html( $subscription['owner_email'] ) ); + } elseif ( isset( $subscription['master_user_email'] ) ) { + printf( '
    ' . __( 'Shared by %s', 'woocommerce' ), esc_html( $subscription['master_user_email'] ) ); + } + ?> +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    +

    + +

    +
    + + + +
    + + +

    +

    Below is a list of WooCommerce.com products available on your site - but are either out-dated or do not have a valid subscription.

    + + + + $data ) : ?> + + + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    + + + + +
    +

    + +

    +
    + +
    + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-oauth-start.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-oauth-start.php new file mode 100644 index 0000000..4b2e8cb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-oauth-start.php @@ -0,0 +1,30 @@ + WooCommerce -> Extensions -> WooCommerce.com Subscriptions main page. + * + * @package WooCommerce\Views + */ + +defined( 'ABSPATH' ) || exit(); + +?> + +
    + +

    + + +
    +
    + <?php esc_attr_e( 'WooCommerce', 'woocommerce' ); ?> + + +

    + + +

    +

    +

    +
    +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-section-account.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-section-account.php new file mode 100644 index 0000000..72f2c60 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-section-account.php @@ -0,0 +1,15 @@ + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-section-nav.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-section-nav.php new file mode 100644 index 0000000..9af76fe --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-section-nav.php @@ -0,0 +1,19 @@ + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-section-notices.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-section-notices.php new file mode 100644 index 0000000..46792da --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/helper/views/html-section-notices.php @@ -0,0 +1,7 @@ + + + +
    + +
    + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/class-wc-product-csv-importer-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/class-wc-product-csv-importer-controller.php new file mode 100644 index 0000000..0de8250 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/class-wc-product-csv-importer-controller.php @@ -0,0 +1,748 @@ + 'text/csv', + 'txt' => 'text/plain', + ) + ); + } + + /** + * Constructor. + */ + public function __construct() { + $default_steps = array( + 'upload' => array( + 'name' => __( 'Upload CSV file', 'woocommerce' ), + 'view' => array( $this, 'upload_form' ), + 'handler' => array( $this, 'upload_form_handler' ), + ), + 'mapping' => array( + 'name' => __( 'Column mapping', 'woocommerce' ), + 'view' => array( $this, 'mapping_form' ), + 'handler' => '', + ), + 'import' => array( + 'name' => __( 'Import', 'woocommerce' ), + 'view' => array( $this, 'import' ), + 'handler' => '', + ), + 'done' => array( + 'name' => __( 'Done!', 'woocommerce' ), + 'view' => array( $this, 'done' ), + 'handler' => '', + ), + ); + + $this->steps = apply_filters( 'woocommerce_product_csv_importer_steps', $default_steps ); + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + $this->step = isset( $_REQUEST['step'] ) ? sanitize_key( $_REQUEST['step'] ) : current( array_keys( $this->steps ) ); + $this->file = isset( $_REQUEST['file'] ) ? wc_clean( wp_unslash( $_REQUEST['file'] ) ) : ''; + $this->update_existing = isset( $_REQUEST['update_existing'] ) ? (bool) $_REQUEST['update_existing'] : false; + $this->delimiter = ! empty( $_REQUEST['delimiter'] ) ? wc_clean( wp_unslash( $_REQUEST['delimiter'] ) ) : ','; + $this->map_preferences = isset( $_REQUEST['map_preferences'] ) ? (bool) $_REQUEST['map_preferences'] : false; + // phpcs:enable + + // Import mappings for CSV data. + include_once dirname( __FILE__ ) . '/mappings/mappings.php'; + + if ( $this->map_preferences ) { + add_filter( 'woocommerce_csv_product_import_mapped_columns', array( $this, 'auto_map_user_preferences' ), 9999 ); + } + } + + /** + * Get the URL for the next step's screen. + * + * @param string $step slug (default: current step). + * @return string URL for next step if a next step exists. + * Admin URL if it's the last step. + * Empty string on failure. + */ + public function get_next_step_link( $step = '' ) { + if ( ! $step ) { + $step = $this->step; + } + + $keys = array_keys( $this->steps ); + + if ( end( $keys ) === $step ) { + return admin_url(); + } + + $step_index = array_search( $step, $keys, true ); + + if ( false === $step_index ) { + return ''; + } + + $params = array( + 'step' => $keys[ $step_index + 1 ], + 'file' => str_replace( DIRECTORY_SEPARATOR, '/', $this->file ), + 'delimiter' => $this->delimiter, + 'update_existing' => $this->update_existing, + 'map_preferences' => $this->map_preferences, + '_wpnonce' => wp_create_nonce( 'woocommerce-csv-importer' ), // wp_nonce_url() escapes & to & breaking redirects. + ); + + return add_query_arg( $params ); + } + + /** + * Output header view. + */ + protected function output_header() { + include dirname( __FILE__ ) . '/views/html-csv-import-header.php'; + } + + /** + * Output steps view. + */ + protected function output_steps() { + include dirname( __FILE__ ) . '/views/html-csv-import-steps.php'; + } + + /** + * Output footer view. + */ + protected function output_footer() { + include dirname( __FILE__ ) . '/views/html-csv-import-footer.php'; + } + + /** + * Add error message. + * + * @param string $message Error message. + * @param array $actions List of actions with 'url' and 'label'. + */ + protected function add_error( $message, $actions = array() ) { + $this->errors[] = array( + 'message' => $message, + 'actions' => $actions, + ); + } + + /** + * Add error message. + */ + protected function output_errors() { + if ( ! $this->errors ) { + return; + } + + foreach ( $this->errors as $error ) { + echo '
    '; + echo '

    ' . esc_html( $error['message'] ) . '

    '; + + if ( ! empty( $error['actions'] ) ) { + echo '

    '; + foreach ( $error['actions'] as $action ) { + echo '' . esc_html( $action['label'] ) . ' '; + } + echo '

    '; + } + echo '
    '; + } + } + + /** + * Dispatch current step and show correct view. + */ + public function dispatch() { + // phpcs:ignore WordPress.Security.NonceVerification.Missing + if ( ! empty( $_POST['save_step'] ) && ! empty( $this->steps[ $this->step ]['handler'] ) ) { + call_user_func( $this->steps[ $this->step ]['handler'], $this ); + } + $this->output_header(); + $this->output_steps(); + $this->output_errors(); + call_user_func( $this->steps[ $this->step ]['view'], $this ); + $this->output_footer(); + } + + /** + * Output information about the uploading process. + */ + protected function upload_form() { + $bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() ); + $size = size_format( $bytes ); + $upload_dir = wp_upload_dir(); + + include dirname( __FILE__ ) . '/views/html-product-csv-import-form.php'; + } + + /** + * Handle the upload form and store options. + */ + public function upload_form_handler() { + check_admin_referer( 'woocommerce-csv-importer' ); + + $file = $this->handle_upload(); + + if ( is_wp_error( $file ) ) { + $this->add_error( $file->get_error_message() ); + return; + } else { + $this->file = $file; + } + + wp_redirect( esc_url_raw( $this->get_next_step_link() ) ); + exit; + } + + /** + * Handles the CSV upload and initial parsing of the file to prepare for + * displaying author import options. + * + * @return string|WP_Error + */ + public function handle_upload() { + // phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce already verified in WC_Product_CSV_Importer_Controller::upload_form_handler() + $file_url = isset( $_POST['file_url'] ) ? wc_clean( wp_unslash( $_POST['file_url'] ) ) : ''; + + if ( empty( $file_url ) ) { + if ( ! isset( $_FILES['import'] ) ) { + return new WP_Error( 'woocommerce_product_csv_importer_upload_file_empty', __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.', 'woocommerce' ) ); + } + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated + if ( ! self::is_file_valid_csv( wc_clean( wp_unslash( $_FILES['import']['name'] ) ), false ) ) { + return new WP_Error( 'woocommerce_product_csv_importer_upload_file_invalid', __( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) ); + } + + $overrides = array( + 'test_form' => false, + 'mimes' => self::get_valid_csv_filetypes(), + ); + $import = $_FILES['import']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $upload = wp_handle_upload( $import, $overrides ); + + if ( isset( $upload['error'] ) ) { + return new WP_Error( 'woocommerce_product_csv_importer_upload_error', $upload['error'] ); + } + + // Construct the object array. + $object = array( + 'post_title' => basename( $upload['file'] ), + 'post_content' => $upload['url'], + 'post_mime_type' => $upload['type'], + 'guid' => $upload['url'], + 'context' => 'import', + 'post_status' => 'private', + ); + + // Save the data. + $id = wp_insert_attachment( $object, $upload['file'] ); + + /* + * Schedule a cleanup for one day from now in case of failed + * import or missing wp_import_cleanup() call. + */ + wp_schedule_single_event( time() + DAY_IN_SECONDS, 'importer_scheduled_cleanup', array( $id ) ); + + return $upload['file']; + } elseif ( file_exists( ABSPATH . $file_url ) ) { + if ( ! self::is_file_valid_csv( ABSPATH . $file_url ) ) { + return new WP_Error( 'woocommerce_product_csv_importer_upload_file_invalid', __( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) ); + } + + return ABSPATH . $file_url; + } + // phpcs:enable + + return new WP_Error( 'woocommerce_product_csv_importer_upload_invalid_file', __( 'Please upload or provide the link to a valid CSV file.', 'woocommerce' ) ); + } + + /** + * Mapping step. + */ + protected function mapping_form() { + check_admin_referer( 'woocommerce-csv-importer' ); + $args = array( + 'lines' => 1, + 'delimiter' => $this->delimiter, + ); + + $importer = self::get_importer( $this->file, $args ); + $headers = $importer->get_raw_keys(); + $mapped_items = $this->auto_map_columns( $headers ); + $sample = current( $importer->get_raw_data() ); + + if ( empty( $sample ) ) { + $this->add_error( + __( 'The file is empty or using a different encoding than UTF-8, please try again with a new file.', 'woocommerce' ), + array( + array( + 'url' => admin_url( 'edit.php?post_type=product&page=product_importer' ), + 'label' => __( 'Upload a new file', 'woocommerce' ), + ), + ) + ); + + // Force output the errors in the same page. + $this->output_errors(); + return; + } + + include_once dirname( __FILE__ ) . '/views/html-csv-import-mapping.php'; + } + + /** + * Import the file if it exists and is valid. + */ + public function import() { + // Displaying this page triggers Ajax action to run the import with a valid nonce, + // therefore this page needs to be nonce protected as well. + check_admin_referer( 'woocommerce-csv-importer' ); + + if ( ! self::is_file_valid_csv( $this->file ) ) { + $this->add_error( __( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) ); + $this->output_errors(); + return; + } + + if ( ! is_file( $this->file ) ) { + $this->add_error( __( 'The file does not exist, please try again.', 'woocommerce' ) ); + $this->output_errors(); + return; + } + + if ( ! empty( $_POST['map_from'] ) && ! empty( $_POST['map_to'] ) ) { + $mapping_from = wc_clean( wp_unslash( $_POST['map_from'] ) ); + $mapping_to = wc_clean( wp_unslash( $_POST['map_to'] ) ); + + // Save mapping preferences for future imports. + update_user_option( get_current_user_id(), 'woocommerce_product_import_mapping', $mapping_to ); + } else { + wp_redirect( esc_url_raw( $this->get_next_step_link( 'upload' ) ) ); + exit; + } + + wp_localize_script( + 'wc-product-import', + 'wc_product_import_params', + array( + 'import_nonce' => wp_create_nonce( 'wc-product-import' ), + 'mapping' => array( + 'from' => $mapping_from, + 'to' => $mapping_to, + ), + 'file' => $this->file, + 'update_existing' => $this->update_existing, + 'delimiter' => $this->delimiter, + ) + ); + wp_enqueue_script( 'wc-product-import' ); + + include_once dirname( __FILE__ ) . '/views/html-csv-import-progress.php'; + } + + /** + * Done step. + */ + protected function done() { + check_admin_referer( 'woocommerce-csv-importer' ); + $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; + $file_name = isset( $_GET['file-name'] ) ? sanitize_text_field( wp_unslash( $_GET['file-name'] ) ) : ''; + $errors = array_filter( (array) get_user_option( 'product_import_error_log' ) ); + + include_once dirname( __FILE__ ) . '/views/html-csv-import-done.php'; + } + + /** + * Columns to normalize. + * + * @param array $columns List of columns names and keys. + * @return array + */ + protected function normalize_columns_names( $columns ) { + $normalized = array(); + + foreach ( $columns as $key => $value ) { + $normalized[ strtolower( $key ) ] = $value; + } + + return $normalized; + } + + /** + * Auto map column names. + * + * @param array $raw_headers Raw header columns. + * @param bool $num_indexes If should use numbers or raw header columns as indexes. + * @return array + */ + protected function auto_map_columns( $raw_headers, $num_indexes = true ) { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + + /* + * @hooked wc_importer_generic_mappings - 10 + * @hooked wc_importer_wordpress_mappings - 10 + * @hooked wc_importer_default_english_mappings - 100 + */ + $default_columns = $this->normalize_columns_names( + apply_filters( + 'woocommerce_csv_product_import_mapping_default_columns', + array( + __( 'ID', 'woocommerce' ) => 'id', + __( 'Type', 'woocommerce' ) => 'type', + __( 'SKU', 'woocommerce' ) => 'sku', + __( 'Name', 'woocommerce' ) => 'name', + __( 'Published', 'woocommerce' ) => 'published', + __( 'Is featured?', 'woocommerce' ) => 'featured', + __( 'Visibility in catalog', 'woocommerce' ) => 'catalog_visibility', + __( 'Short description', 'woocommerce' ) => 'short_description', + __( 'Description', 'woocommerce' ) => 'description', + __( 'Date sale price starts', 'woocommerce' ) => 'date_on_sale_from', + __( 'Date sale price ends', 'woocommerce' ) => 'date_on_sale_to', + __( 'Tax status', 'woocommerce' ) => 'tax_status', + __( 'Tax class', 'woocommerce' ) => 'tax_class', + __( 'In stock?', 'woocommerce' ) => 'stock_status', + __( 'Stock', 'woocommerce' ) => 'stock_quantity', + __( 'Backorders allowed?', 'woocommerce' ) => 'backorders', + __( 'Low stock amount', 'woocommerce' ) => 'low_stock_amount', + __( 'Sold individually?', 'woocommerce' ) => 'sold_individually', + /* translators: %s: Weight unit */ + sprintf( __( 'Weight (%s)', 'woocommerce' ), $weight_unit ) => 'weight', + /* translators: %s: Length unit */ + sprintf( __( 'Length (%s)', 'woocommerce' ), $dimension_unit ) => 'length', + /* translators: %s: Width unit */ + sprintf( __( 'Width (%s)', 'woocommerce' ), $dimension_unit ) => 'width', + /* translators: %s: Height unit */ + sprintf( __( 'Height (%s)', 'woocommerce' ), $dimension_unit ) => 'height', + __( 'Allow customer reviews?', 'woocommerce' ) => 'reviews_allowed', + __( 'Purchase note', 'woocommerce' ) => 'purchase_note', + __( 'Sale price', 'woocommerce' ) => 'sale_price', + __( 'Regular price', 'woocommerce' ) => 'regular_price', + __( 'Categories', 'woocommerce' ) => 'category_ids', + __( 'Tags', 'woocommerce' ) => 'tag_ids', + __( 'Shipping class', 'woocommerce' ) => 'shipping_class_id', + __( 'Images', 'woocommerce' ) => 'images', + __( 'Download limit', 'woocommerce' ) => 'download_limit', + __( 'Download expiry days', 'woocommerce' ) => 'download_expiry', + __( 'Parent', 'woocommerce' ) => 'parent_id', + __( 'Upsells', 'woocommerce' ) => 'upsell_ids', + __( 'Cross-sells', 'woocommerce' ) => 'cross_sell_ids', + __( 'Grouped products', 'woocommerce' ) => 'grouped_products', + __( 'External URL', 'woocommerce' ) => 'product_url', + __( 'Button text', 'woocommerce' ) => 'button_text', + __( 'Position', 'woocommerce' ) => 'menu_order', + ), + $raw_headers + ) + ); + + $special_columns = $this->get_special_columns( + $this->normalize_columns_names( + apply_filters( + 'woocommerce_csv_product_import_mapping_special_columns', + array( + /* translators: %d: Attribute number */ + __( 'Attribute %d name', 'woocommerce' ) => 'attributes:name', + /* translators: %d: Attribute number */ + __( 'Attribute %d value(s)', 'woocommerce' ) => 'attributes:value', + /* translators: %d: Attribute number */ + __( 'Attribute %d visible', 'woocommerce' ) => 'attributes:visible', + /* translators: %d: Attribute number */ + __( 'Attribute %d global', 'woocommerce' ) => 'attributes:taxonomy', + /* translators: %d: Attribute number */ + __( 'Attribute %d default', 'woocommerce' ) => 'attributes:default', + /* translators: %d: Download number */ + __( 'Download %d name', 'woocommerce' ) => 'downloads:name', + /* translators: %d: Download number */ + __( 'Download %d URL', 'woocommerce' ) => 'downloads:url', + /* translators: %d: Meta number */ + __( 'Meta: %s', 'woocommerce' ) => 'meta:', + ), + $raw_headers + ) + ) + ); + + $headers = array(); + foreach ( $raw_headers as $key => $field ) { + $normalized_field = strtolower( $field ); + $index = $num_indexes ? $key : $field; + $headers[ $index ] = $normalized_field; + + if ( isset( $default_columns[ $normalized_field ] ) ) { + $headers[ $index ] = $default_columns[ $normalized_field ]; + } else { + foreach ( $special_columns as $regex => $special_key ) { + // Don't use the normalized field in the regex since meta might be case-sensitive. + if ( preg_match( $regex, $field, $matches ) ) { + $headers[ $index ] = $special_key . $matches[1]; + break; + } + } + } + } + + return apply_filters( 'woocommerce_csv_product_import_mapped_columns', $headers, $raw_headers ); + } + + /** + * Map columns using the user's lastest import mappings. + * + * @param array $headers Header columns. + * @return array + */ + public function auto_map_user_preferences( $headers ) { + $mapping_preferences = get_user_option( 'woocommerce_product_import_mapping' ); + + if ( ! empty( $mapping_preferences ) && is_array( $mapping_preferences ) ) { + return $mapping_preferences; + } + + return $headers; + } + + /** + * Sanitize special column name regex. + * + * @param string $value Raw special column name. + * @return string + */ + protected function sanitize_special_column_name_regex( $value ) { + return '/' . str_replace( array( '%d', '%s' ), '(.*)', trim( quotemeta( $value ) ) ) . '/i'; + } + + /** + * Get special columns. + * + * @param array $columns Raw special columns. + * @return array + */ + protected function get_special_columns( $columns ) { + $formatted = array(); + + foreach ( $columns as $key => $value ) { + $regex = $this->sanitize_special_column_name_regex( $key ); + + $formatted[ $regex ] = $value; + } + + return $formatted; + } + + /** + * Get mapping options. + * + * @param string $item Item name. + * @return array + */ + 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 ); + + // Available options. + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $options = array( + 'id' => __( 'ID', 'woocommerce' ), + 'type' => __( 'Type', 'woocommerce' ), + 'sku' => __( 'SKU', 'woocommerce' ), + 'name' => __( 'Name', 'woocommerce' ), + 'published' => __( 'Published', 'woocommerce' ), + 'featured' => __( 'Is featured?', 'woocommerce' ), + 'catalog_visibility' => __( 'Visibility in catalog', 'woocommerce' ), + 'short_description' => __( 'Short description', 'woocommerce' ), + 'description' => __( 'Description', 'woocommerce' ), + 'price' => array( + 'name' => __( 'Price', 'woocommerce' ), + 'options' => array( + 'regular_price' => __( 'Regular price', 'woocommerce' ), + 'sale_price' => __( 'Sale price', 'woocommerce' ), + 'date_on_sale_from' => __( 'Date sale price starts', 'woocommerce' ), + 'date_on_sale_to' => __( 'Date sale price ends', 'woocommerce' ), + ), + ), + 'tax_status' => __( 'Tax status', 'woocommerce' ), + 'tax_class' => __( 'Tax class', 'woocommerce' ), + 'stock_status' => __( 'In stock?', 'woocommerce' ), + 'stock_quantity' => _x( 'Stock', 'Quantity in stock', 'woocommerce' ), + 'backorders' => __( 'Backorders allowed?', 'woocommerce' ), + 'low_stock_amount' => __( 'Low stock amount', 'woocommerce' ), + 'sold_individually' => __( 'Sold individually?', 'woocommerce' ), + /* translators: %s: weight unit */ + 'weight' => sprintf( __( 'Weight (%s)', 'woocommerce' ), $weight_unit ), + 'dimensions' => array( + 'name' => __( 'Dimensions', 'woocommerce' ), + 'options' => array( + /* translators: %s: dimension unit */ + 'length' => sprintf( __( 'Length (%s)', 'woocommerce' ), $dimension_unit ), + /* translators: %s: dimension unit */ + 'width' => sprintf( __( 'Width (%s)', 'woocommerce' ), $dimension_unit ), + /* translators: %s: dimension unit */ + 'height' => sprintf( __( 'Height (%s)', 'woocommerce' ), $dimension_unit ), + ), + ), + 'category_ids' => __( 'Categories', 'woocommerce' ), + 'tag_ids' => __( 'Tags (comma separated)', 'woocommerce' ), + 'tag_ids_spaces' => __( 'Tags (space separated)', 'woocommerce' ), + 'shipping_class_id' => __( 'Shipping class', 'woocommerce' ), + 'images' => __( 'Images', 'woocommerce' ), + 'parent_id' => __( 'Parent', 'woocommerce' ), + 'upsell_ids' => __( 'Upsells', 'woocommerce' ), + 'cross_sell_ids' => __( 'Cross-sells', 'woocommerce' ), + 'grouped_products' => __( 'Grouped products', 'woocommerce' ), + 'external' => array( + 'name' => __( 'External product', 'woocommerce' ), + 'options' => array( + 'product_url' => __( 'External URL', 'woocommerce' ), + 'button_text' => __( 'Button text', 'woocommerce' ), + ), + ), + 'downloads' => array( + 'name' => __( 'Downloads', 'woocommerce' ), + 'options' => array( + 'downloads:name' . $index => __( 'Download name', 'woocommerce' ), + 'downloads:url' . $index => __( 'Download URL', 'woocommerce' ), + 'download_limit' => __( 'Download limit', 'woocommerce' ), + 'download_expiry' => __( 'Download expiry days', 'woocommerce' ), + ), + ), + 'attributes' => array( + 'name' => __( 'Attributes', 'woocommerce' ), + 'options' => array( + 'attributes:name' . $index => __( 'Attribute name', 'woocommerce' ), + 'attributes:value' . $index => __( 'Attribute value(s)', 'woocommerce' ), + 'attributes:taxonomy' . $index => __( 'Is a global attribute?', 'woocommerce' ), + 'attributes:visible' . $index => __( 'Attribute visibility', 'woocommerce' ), + 'attributes:default' . $index => __( 'Default attribute', 'woocommerce' ), + ), + ), + 'reviews_allowed' => __( 'Allow customer reviews?', 'woocommerce' ), + 'purchase_note' => __( 'Purchase note', 'woocommerce' ), + 'meta:' . $meta => __( 'Import as meta data', 'woocommerce' ), + 'menu_order' => __( 'Position', 'woocommerce' ), + ); + + return apply_filters( 'woocommerce_csv_product_import_mapping_options', $options, $item ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/class-wc-tax-rate-importer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/class-wc-tax-rate-importer.php new file mode 100644 index 0000000..79f9cd1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/class-wc-tax-rate-importer.php @@ -0,0 +1,341 @@ +import_page = 'woocommerce_tax_rate_csv'; + $this->delimiter = empty( $_POST['delimiter'] ) ? ',' : (string) wc_clean( wp_unslash( $_POST['delimiter'] ) ); // WPCS: CSRF ok. + } + + /** + * Registered callback function for the WordPress Importer. + * + * Manages the three separate stages of the CSV import process. + */ + public function dispatch() { + + $this->header(); + + $step = empty( $_GET['step'] ) ? 0 : (int) $_GET['step']; + + switch ( $step ) { + + case 0: + $this->greet(); + break; + + case 1: + check_admin_referer( 'import-upload' ); + + if ( $this->handle_upload() ) { + + if ( $this->id ) { + $file = get_attached_file( $this->id ); + } else { + $file = ABSPATH . $this->file_url; + } + + add_filter( 'http_request_timeout', array( $this, 'bump_request_timeout' ) ); + + $this->import( $file ); + } + break; + } + + $this->footer(); + } + + /** + * Import is starting. + */ + private function import_start() { + if ( function_exists( 'gc_enable' ) ) { + gc_enable(); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.gc_enableFound + } + wc_set_time_limit( 0 ); + @ob_flush(); + @flush(); + @ini_set( 'auto_detect_line_endings', '1' ); + } + + /** + * UTF-8 encode the data if `$enc` value isn't UTF-8. + * + * @param mixed $data Data. + * @param string $enc Encoding. + * @return string + */ + public function format_data_from_csv( $data, $enc ) { + return ( 'UTF-8' === $enc ) ? $data : utf8_encode( $data ); + } + + /** + * Import the file if it exists and is valid. + * + * @param mixed $file File. + */ + public function import( $file ) { + if ( ! is_file( $file ) ) { + $this->import_error( __( 'The file does not exist, please try again.', 'woocommerce' ) ); + } + + $this->import_start(); + + $loop = 0; + $handle = fopen( $file, 'r' ); + + if ( false !== $handle ) { + + $header = fgetcsv( $handle, 0, $this->delimiter ); + + if ( 10 === count( $header ) ) { + + $row = fgetcsv( $handle, 0, $this->delimiter ); + + while ( false !== $row ) { + + list( $country, $state, $postcode, $city, $rate, $name, $priority, $compound, $shipping, $class ) = $row; + + $tax_rate = array( + 'tax_rate_country' => $country, + 'tax_rate_state' => $state, + 'tax_rate' => $rate, + 'tax_rate_name' => $name, + 'tax_rate_priority' => $priority, + 'tax_rate_compound' => $compound ? 1 : 0, + 'tax_rate_shipping' => $shipping ? 1 : 0, + 'tax_rate_order' => $loop ++, + 'tax_rate_class' => $class, + ); + + $tax_rate_id = WC_Tax::_insert_tax_rate( $tax_rate ); + WC_Tax::_update_tax_rate_postcodes( $tax_rate_id, wc_clean( $postcode ) ); + WC_Tax::_update_tax_rate_cities( $tax_rate_id, wc_clean( $city ) ); + + $row = fgetcsv( $handle, 0, $this->delimiter ); + } + } else { + $this->import_error( __( 'The CSV is invalid.', 'woocommerce' ) ); + } + + fclose( $handle ); + } + + // Show Result. + echo '

    '; + printf( + /* translators: %s: tax rates count */ + esc_html__( 'Import complete - imported %s tax rates.', 'woocommerce' ), + '' . absint( $loop ) . '' + ); + echo '

    '; + + $this->import_end(); + } + + /** + * Performs post-import cleanup of files and the cache. + */ + public function import_end() { + echo '

    ' . esc_html__( 'All done!', 'woocommerce' ) . ' ' . esc_html__( 'View tax rates', 'woocommerce' ) . '

    '; + + do_action( 'import_end' ); + } + + /** + * Handles the CSV upload and initial parsing of the file to prepare for. + * displaying author import options. + * + * @return bool False if error uploading or invalid file, true otherwise + */ + public function handle_upload() { + $file_url = isset( $_POST['file_url'] ) ? wc_clean( wp_unslash( $_POST['file_url'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce already verified in WC_Tax_Rate_Importer::dispatch() + + if ( empty( $file_url ) ) { + $file = wp_import_handle_upload(); + + if ( isset( $file['error'] ) ) { + $this->import_error( $file['error'] ); + } + + if ( ! wc_is_file_valid_csv( $file['file'], false ) ) { + // Remove file if not valid. + wp_delete_attachment( $file['id'], true ); + + $this->import_error( __( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) ); + } + + $this->id = absint( $file['id'] ); + } elseif ( file_exists( ABSPATH . $file_url ) ) { + if ( ! wc_is_file_valid_csv( ABSPATH . $file_url ) ) { + $this->import_error( __( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) ); + } + + $this->file_url = esc_attr( $file_url ); + } else { + $this->import_error(); + } + + return true; + } + + /** + * Output header html. + */ + public function header() { + echo '
    '; + echo '

    ' . esc_html__( 'Import tax rates', 'woocommerce' ) . '

    '; + } + + /** + * Output footer html. + */ + public function footer() { + echo '
    '; + } + + /** + * Output information about the uploading process. + */ + public function greet() { + + echo '
    '; + echo '

    ' . esc_html__( 'Hi there! Upload a CSV file containing tax rates to import the contents into your shop. Choose a .csv file to upload, then click "Upload file and import".', 'woocommerce' ) . '

    '; + + /* translators: 1: Link to tax rates sample file 2: Closing link. */ + echo '

    ' . sprintf( esc_html__( 'Your CSV needs to include columns in a specific order. %1$sClick here to download a sample%2$s.', 'woocommerce' ), '', '' ) . '

    '; + + $action = 'admin.php?import=woocommerce_tax_rate_csv&step=1'; + + $bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() ); + $size = size_format( $bytes ); + $upload_dir = wp_upload_dir(); + if ( ! empty( $upload_dir['error'] ) ) : + ?> +
    +

    +

    +
    + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + +
    + + + +

    +

    + +

    +
    + '; + } + + /** + * Show import error and quit. + * + * @param string $message Error message. + */ + private function import_error( $message = '' ) { + echo '

    ' . esc_html__( 'Sorry, there has been an error.', 'woocommerce' ) . '
    '; + if ( $message ) { + echo esc_html( $message ); + } + echo '

    '; + $this->footer(); + die(); + } + + /** + * Added to http_request_timeout filter to force timeout at 60 seconds during import. + * + * @param int $val Value. + * @return int 60 + */ + public function bump_request_timeout( $val ) { + return 60; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/default.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/default.php new file mode 100644 index 0000000..4de9337 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/default.php @@ -0,0 +1,112 @@ + 'id', + 'Type' => 'type', + 'SKU' => 'sku', + 'Name' => 'name', + 'Published' => 'published', + 'Is featured?' => 'featured', + 'Visibility in catalog' => 'catalog_visibility', + 'Short description' => 'short_description', + 'Description' => 'description', + 'Date sale price starts' => 'date_on_sale_from', + 'Date sale price ends' => 'date_on_sale_to', + 'Tax status' => 'tax_status', + 'Tax class' => 'tax_class', + 'In stock?' => 'stock_status', + 'Stock' => 'stock_quantity', + 'Backorders allowed?' => 'backorders', + 'Low stock amount' => 'low_stock_amount', + 'Sold individually?' => 'sold_individually', + sprintf( 'Weight (%s)', $weight_unit ) => 'weight', + sprintf( 'Length (%s)', $dimension_unit ) => 'length', + sprintf( 'Width (%s)', $dimension_unit ) => 'width', + sprintf( 'Height (%s)', $dimension_unit ) => 'height', + 'Allow customer reviews?' => 'reviews_allowed', + 'Purchase note' => 'purchase_note', + 'Sale price' => 'sale_price', + 'Regular price' => 'regular_price', + 'Categories' => 'category_ids', + 'Tags' => 'tag_ids', + 'Shipping class' => 'shipping_class_id', + 'Images' => 'images', + 'Download limit' => 'download_limit', + 'Download expiry days' => 'download_expiry', + 'Parent' => 'parent_id', + 'Upsells' => 'upsell_ids', + 'Cross-sells' => 'cross_sell_ids', + 'Grouped products' => 'grouped_products', + 'External URL' => 'product_url', + 'Button text' => 'button_text', + 'Position' => 'menu_order', + ); + + return array_merge( $mappings, $new_mappings ); +} +add_filter( 'woocommerce_csv_product_import_mapping_default_columns', 'wc_importer_default_english_mappings', 100 ); + +/** + * Add English special mapping placeholders when not using English as current language. + * + * @since 3.1.0 + * @param array $mappings Importer columns mappings. + * @return array + */ +function wc_importer_default_special_english_mappings( $mappings ) { + if ( 'en_US' === wc_importer_current_locale() ) { + return $mappings; + } + + $new_mappings = array( + 'Attribute %d name' => 'attributes:name', + 'Attribute %d value(s)' => 'attributes:value', + 'Attribute %d visible' => 'attributes:visible', + 'Attribute %d global' => 'attributes:taxonomy', + 'Attribute %d default' => 'attributes:default', + 'Download %d name' => 'downloads:name', + 'Download %d URL' => 'downloads:url', + 'Meta: %s' => 'meta:', + ); + + return array_merge( $mappings, $new_mappings ); +} +add_filter( 'woocommerce_csv_product_import_mapping_special_columns', 'wc_importer_default_special_english_mappings', 100 ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/generic.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/generic.php new file mode 100644 index 0000000..d5b14ab --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/generic.php @@ -0,0 +1,31 @@ + 'name', + __( 'Product Title', 'woocommerce' ) => 'name', + __( 'Price', 'woocommerce' ) => 'regular_price', + __( 'Parent SKU', 'woocommerce' ) => 'parent_id', + __( 'Quantity', 'woocommerce' ) => 'stock_quantity', + __( 'Menu order', 'woocommerce' ) => 'menu_order', + ); + + return array_merge( $mappings, $generic_mappings ); +} +add_filter( 'woocommerce_csv_product_import_mapping_default_columns', 'wc_importer_generic_mappings' ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/mappings.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/mappings.php new file mode 100644 index 0000000..15587ae --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/mappings.php @@ -0,0 +1,15 @@ + 'sku', + 'Title' => 'name', + 'Body (HTML)' => 'description', + 'Quantity' => 'stock_quantity', + 'Variant Inventory Qty' => 'stock_quantity', + 'Image Src' => 'images', + 'Variant Image' => 'images', + 'Variant SKU' => 'sku', + 'Variant Price' => 'sale_price', + 'Variant Compare At Price' => 'regular_price', + 'Type' => 'category_ids', + 'Tags' => 'tag_ids_spaces', + 'Variant Grams' => 'weight', + 'Variant Requires Shipping' => 'meta:shopify_requires_shipping', + 'Variant Taxable' => 'tax_status', + ); + return array_merge( $mappings, $shopify_mappings ); +} +add_filter( 'woocommerce_csv_product_import_mapping_default_columns', 'wc_importer_shopify_mappings', 10, 2 ); + +/** + * Add special wildcard Shopify mappings. + * + * @since 3.7.0 + * @param array $mappings Importer columns mappings. + * @param array $raw_headers Raw headers from CSV being imported. + * @return array + */ +function wc_importer_shopify_special_mappings( $mappings, $raw_headers ) { + // Only map if this is looks like a Shopify export. + if ( 0 !== count( array_diff( array( 'Title', 'Body (HTML)', 'Type', 'Variant SKU' ), $raw_headers ) ) ) { + return $mappings; + } + $shopify_mappings = array( + 'Option%d Name' => 'attributes:name', + 'Option%d Value' => 'attributes:value', + ); + return array_merge( $mappings, $shopify_mappings ); +} +add_filter( 'woocommerce_csv_product_import_mapping_special_columns', 'wc_importer_shopify_special_mappings', 10, 2 ); + +/** + * Expand special Shopify columns to WC format. + * + * @since 3.7.0 + * @param array $data Array of data. + * @return array Expanded data. + */ +function wc_importer_shopify_expand_data( $data ) { + if ( isset( $data['meta:shopify_requires_shipping'] ) ) { + $requires_shipping = wc_string_to_bool( $data['meta:shopify_requires_shipping'] ); + + if ( ! $requires_shipping ) { + if ( isset( $data['type'] ) ) { + $data['type'][] = 'virtual'; + } else { + $data['type'] = array( 'virtual' ); + } + } + + unset( $data['meta:shopify_requires_shipping'] ); + } + return $data; +} +add_filter( 'woocommerce_product_importer_pre_expand_data', 'wc_importer_shopify_expand_data' ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/wordpress.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/wordpress.php new file mode 100644 index 0000000..755c507 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/mappings/wordpress.php @@ -0,0 +1,31 @@ + 'id', + 'post_title' => 'name', + 'post_content' => 'description', + 'post_excerpt' => 'short_description', + 'post_parent' => 'parent_id', + ); + + return array_merge( $mappings, $wp_mappings ); +} +add_filter( 'woocommerce_csv_product_import_mapping_default_columns', 'wc_importer_wordpress_mappings' ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-done.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-done.php new file mode 100644 index 0000000..1774001 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-done.php @@ -0,0 +1,104 @@ + +
    +
    + ' . number_format_i18n( $imported ) . '' + ); + } + + if ( 0 < $updated ) { + $results[] = sprintf( + /* translators: %d: products count */ + _n( '%s product updated', '%s products updated', $updated, 'woocommerce' ), + '' . number_format_i18n( $updated ) . '' + ); + } + + if ( 0 < $skipped ) { + $results[] = sprintf( + /* translators: %d: products count */ + _n( '%s product was skipped', '%s products were skipped', $skipped, 'woocommerce' ), + '' . number_format_i18n( $skipped ) . '' + ); + } + + if ( 0 < $failed ) { + $results [] = sprintf( + /* translators: %d: products count */ + _n( 'Failed to import %s product', 'Failed to import %s products', $failed, 'woocommerce' ), + '' . number_format_i18n( $failed ) . '' + ); + } + + if ( 0 < $failed || 0 < $skipped ) { + $results[] = '' . __( 'View import log', 'woocommerce' ) . ''; + } + + if ( ! empty( $file_name ) ) { + $results[] = sprintf( + /* translators: %s: File name */ + __( 'File uploaded: %s', 'woocommerce' ), + '' . $file_name . '' + ); + } + + /* translators: %d: import results */ + echo wp_kses_post( __( 'Import complete!', 'woocommerce' ) . ' ' . implode( '. ', $results ) ); + ?> +
    + + +
    + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-footer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-footer.php new file mode 100644 index 0000000..cf35e17 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-footer.php @@ -0,0 +1,13 @@ + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-header.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-header.php new file mode 100644 index 0000000..78c42e1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-header.php @@ -0,0 +1,15 @@ + +
    +

    + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-mapping.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-mapping.php new file mode 100644 index 0000000..20cdc42 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-mapping.php @@ -0,0 +1,65 @@ + +
    +
    +

    +

    +
    +
    + + + + + + + + + $name ) : ?> + + + + + + + +
    + + + + + + + +
    +
    +
    + + + + + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-progress.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-progress.php new file mode 100644 index 0000000..ea1ed33 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-progress.php @@ -0,0 +1,21 @@ + +
    +
    + +

    +

    +
    +
    + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-steps.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-steps.php new file mode 100644 index 0000000..2f8c8f8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-csv-import-steps.php @@ -0,0 +1,26 @@ + +
      + steps as $step_key => $step ) : ?> + step ) { + $step_class = 'active'; + } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) { + $step_class = 'done'; + } + ?> +
    1. + +
    2. + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-product-csv-import-form.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-product-csv-import-form.php new file mode 100644 index 0000000..3b96ec6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/importers/views/html-product-csv-import-form.php @@ -0,0 +1,104 @@ + +
    +
    +

    +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    +

    +

    +
    + + + + +
    + + + + +

    + + + +
    +
    + +
    + + + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/list-tables/abstract-class-wc-admin-list-table.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/list-tables/abstract-class-wc-admin-list-table.php new file mode 100644 index 0000000..4a0c93d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/list-tables/abstract-class-wc-admin-list-table.php @@ -0,0 +1,276 @@ +list_table_type ) { + add_action( 'manage_posts_extra_tablenav', array( $this, 'maybe_render_blank_state' ) ); + add_filter( 'view_mode_post_types', array( $this, 'disable_view_mode' ) ); + add_action( 'restrict_manage_posts', array( $this, 'restrict_manage_posts' ) ); + add_filter( 'request', array( $this, 'request_query' ) ); + add_filter( 'post_row_actions', array( $this, 'row_actions' ), 100, 2 ); + add_filter( 'default_hidden_columns', array( $this, 'default_hidden_columns' ), 10, 2 ); + add_filter( 'list_table_primary_column', array( $this, 'list_table_primary_column' ), 10, 2 ); + add_filter( 'manage_edit-' . $this->list_table_type . '_sortable_columns', array( $this, 'define_sortable_columns' ) ); + add_filter( 'manage_' . $this->list_table_type . '_posts_columns', array( $this, 'define_columns' ) ); + add_filter( 'bulk_actions-edit-' . $this->list_table_type, array( $this, 'define_bulk_actions' ) ); + add_action( 'manage_' . $this->list_table_type . '_posts_custom_column', array( $this, 'render_columns' ), 10, 2 ); + add_filter( 'handle_bulk_actions-edit-' . $this->list_table_type, array( $this, 'handle_bulk_actions' ), 10, 3 ); + } + } + + /** + * Show blank slate. + * + * @param string $which String which tablenav is being shown. + */ + public function maybe_render_blank_state( $which ) { + global $post_type; + + if ( $post_type === $this->list_table_type && 'bottom' === $which ) { + $counts = (array) wp_count_posts( $post_type ); + unset( $counts['auto-draft'] ); + $count = array_sum( $counts ); + + if ( 0 < $count ) { + return; + } + + $this->render_blank_state(); + + echo ''; + } + } + + /** + * Render blank state. Extend to add content. + */ + protected function render_blank_state() {} + + /** + * Removes this type from list of post types that support "View Mode" switching. + * View mode is seen on posts where you can switch between list or excerpt. Our post types don't support + * it, so we want to hide the useless UI from the screen options tab. + * + * @param array $post_types Array of post types supporting view mode. + * @return array Array of post types supporting view mode, without this type. + */ + public function disable_view_mode( $post_types ) { + unset( $post_types[ $this->list_table_type ] ); + return $post_types; + } + + /** + * See if we should render search filters or not. + */ + public function restrict_manage_posts() { + global $typenow; + + if ( $this->list_table_type === $typenow ) { + $this->render_filters(); + } + } + + /** + * Handle any filters. + * + * @param array $query_vars Query vars. + * @return array + */ + public function request_query( $query_vars ) { + global $typenow; + + if ( $this->list_table_type === $typenow ) { + return $this->query_filters( $query_vars ); + } + + return $query_vars; + } + + /** + * Render any custom filters and search inputs for the list table. + */ + protected function render_filters() {} + + /** + * Handle any custom filters. + * + * @param array $query_vars Query vars. + * @return array + */ + protected function query_filters( $query_vars ) { + return $query_vars; + } + + /** + * Set row actions. + * + * @param array $actions Array of actions. + * @param WP_Post $post Current post object. + * @return array + */ + public function row_actions( $actions, $post ) { + if ( $this->list_table_type === $post->post_type ) { + return $this->get_row_actions( $actions, $post ); + } + return $actions; + } + + /** + * Get row actions to show in the list table. + * + * @param array $actions Array of actions. + * @param WP_Post $post Current post object. + * @return array + */ + protected function get_row_actions( $actions, $post ) { + return $actions; + } + + /** + * Adjust which columns are displayed by default. + * + * @param array $hidden Current hidden columns. + * @param object $screen Current screen. + * @return array + */ + public function default_hidden_columns( $hidden, $screen ) { + if ( isset( $screen->id ) && 'edit-' . $this->list_table_type === $screen->id ) { + $hidden = array_merge( $hidden, $this->define_hidden_columns() ); + } + return $hidden; + } + + /** + * Set list table primary column. + * + * @param string $default Default value. + * @param string $screen_id Current screen ID. + * @return string + */ + public function list_table_primary_column( $default, $screen_id ) { + if ( 'edit-' . $this->list_table_type === $screen_id && $this->get_primary_column() ) { + return $this->get_primary_column(); + } + return $default; + } + + /** + * Define primary column. + * + * @return array + */ + protected function get_primary_column() { + return ''; + } + + /** + * Define hidden columns. + * + * @return array + */ + protected function define_hidden_columns() { + return array(); + } + + /** + * Define which columns are sortable. + * + * @param array $columns Existing columns. + * @return array + */ + public function define_sortable_columns( $columns ) { + return $columns; + } + + /** + * Define which columns to show on this screen. + * + * @param array $columns Existing columns. + * @return array + */ + public function define_columns( $columns ) { + return $columns; + } + + /** + * Define bulk actions. + * + * @param array $actions Existing actions. + * @return array + */ + public function define_bulk_actions( $actions ) { + return $actions; + } + + /** + * Pre-fetch any data for the row each column has access to it. + * + * @param int $post_id Post ID being shown. + */ + protected function prepare_row_data( $post_id ) {} + + /** + * Render individual columns. + * + * @param string $column Column ID to render. + * @param int $post_id Post ID being shown. + */ + public function render_columns( $column, $post_id ) { + $this->prepare_row_data( $post_id ); + + if ( ! $this->object ) { + return; + } + + if ( is_callable( array( $this, 'render_' . $column . '_column' ) ) ) { + $this->{"render_{$column}_column"}(); + } + } + + /** + * Handle bulk actions. + * + * @param string $redirect_to URL to redirect to. + * @param string $action Action name. + * @param array $ids List of ids. + * @return string + */ + public function handle_bulk_actions( $redirect_to, $action, $ids ) { + return esc_url_raw( $redirect_to ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-coupons.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-coupons.php new file mode 100644 index 0000000..91f499a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-coupons.php @@ -0,0 +1,232 @@ +'; + echo '

    ' . esc_html__( 'Coupons are a great way to offer discounts and rewards to your customers. They will appear here once created.', 'woocommerce' ) . '

    '; + echo '' . esc_html__( 'Create your first coupon', 'woocommerce' ) . ''; + echo '' . esc_html__( 'Learn more about coupons', 'woocommerce' ) . ''; + echo '
    '; + } + + /** + * Define primary column. + * + * @return string + */ + protected function get_primary_column() { + return 'coupon_code'; + } + + /** + * Get row actions to show in the list table. + * + * @param array $actions Array of actions. + * @param WP_Post $post Current post object. + * @return array + */ + protected function get_row_actions( $actions, $post ) { + unset( $actions['inline hide-if-no-js'] ); + return $actions; + } + + /** + * Define which columns to show on this screen. + * + * @param array $columns Existing columns. + * @return array + */ + public function define_columns( $columns ) { + $show_columns = array(); + $show_columns['cb'] = $columns['cb']; + $show_columns['coupon_code'] = __( 'Code', 'woocommerce' ); + $show_columns['type'] = __( 'Coupon type', 'woocommerce' ); + $show_columns['amount'] = __( 'Coupon amount', 'woocommerce' ); + $show_columns['description'] = __( 'Description', 'woocommerce' ); + $show_columns['products'] = __( 'Product IDs', 'woocommerce' ); + $show_columns['usage'] = __( 'Usage / Limit', 'woocommerce' ); + $show_columns['expiry_date'] = __( 'Expiry date', 'woocommerce' ); + + return $show_columns; + } + + /** + * Pre-fetch any data for the row each column has access to it. the_coupon global is there for bw compat. + * + * @param int $post_id Post ID being shown. + */ + protected function prepare_row_data( $post_id ) { + global $the_coupon; + + if ( empty( $this->object ) || $this->object->get_id() !== $post_id ) { + $this->object = new WC_Coupon( $post_id ); + $the_coupon = $this->object; + } + } + + /** + * Render columm: coupon_code. + */ + protected function render_coupon_code_column() { + global $post; + + $edit_link = get_edit_post_link( $this->object->get_id() ); + $title = $this->object->get_code(); + + echo '' . esc_html( $title ) . ''; + _post_states( $post ); + echo ''; + } + + /** + * Render columm: type. + */ + protected function render_type_column() { + echo esc_html( wc_get_coupon_type( $this->object->get_discount_type() ) ); + } + + /** + * Render columm: amount. + */ + protected function render_amount_column() { + echo esc_html( wc_format_localized_price( $this->object->get_amount() ) ); + } + /** + * Render columm: products. + */ + protected function render_products_column() { + $product_ids = $this->object->get_product_ids(); + + if ( count( $product_ids ) > 0 ) { + echo esc_html( implode( ', ', $product_ids ) ); + } else { + echo '–'; + } + } + + /** + * Render columm: usage_limit. + */ + protected function render_usage_limit_column() { + $usage_limit = $this->object->get_usage_limit(); + + if ( $usage_limit ) { + echo esc_html( $usage_limit ); + } else { + echo '–'; + } + } + + /** + * Render columm: usage. + */ + protected function render_usage_column() { + $usage_count = $this->object->get_usage_count(); + $usage_limit = $this->object->get_usage_limit(); + + printf( + /* translators: 1: count 2: limit */ + __( '%1$s / %2$s', 'woocommerce' ), + esc_html( $usage_count ), + $usage_limit ? esc_html( $usage_limit ) : '∞' + ); + } + + /** + * Render columm: expiry_date. + */ + protected function render_expiry_date_column() { + $expiry_date = $this->object->get_date_expires(); + + if ( $expiry_date ) { + echo esc_html( $expiry_date->date_i18n( 'F j, Y' ) ); + } else { + echo '–'; + } + } + + /** + * Render columm: description. + */ + protected function render_description_column() { + echo wp_kses_post( $this->object->get_description() ? $this->object->get_description() : '–' ); + } + + /** + * Render any custom filters and search inputs for the list table. + */ + protected function render_filters() { + ?> + + '; + + echo '

    ' . esc_html__( 'When you receive a new order, it will appear here.', 'woocommerce' ) . '

    '; + + echo ''; + + do_action( 'wc_marketplace_suggestions_orders_empty_state' ); + + echo '
    '; + } + + /** + * Define primary column. + * + * @return string + */ + protected function get_primary_column() { + return 'order_number'; + } + + /** + * Get row actions to show in the list table. + * + * @param array $actions Array of actions. + * @param WP_Post $post Current post object. + * @return array + */ + protected function get_row_actions( $actions, $post ) { + return array(); + } + + /** + * Define hidden columns. + * + * @return array + */ + protected function define_hidden_columns() { + return array( + 'shipping_address', + 'billing_address', + 'wc_actions', + ); + } + + /** + * Define which columns are sortable. + * + * @param array $columns Existing columns. + * @return array + */ + public function define_sortable_columns( $columns ) { + $custom = array( + 'order_number' => 'ID', + 'order_total' => 'order_total', + 'order_date' => 'date', + ); + unset( $columns['comments'] ); + + return wp_parse_args( $custom, $columns ); + } + + /** + * Define which columns to show on this screen. + * + * @param array $columns Existing columns. + * @return array + */ + public function define_columns( $columns ) { + $show_columns = array(); + $show_columns['cb'] = $columns['cb']; + $show_columns['order_number'] = __( 'Order', 'woocommerce' ); + $show_columns['order_date'] = __( 'Date', 'woocommerce' ); + $show_columns['order_status'] = __( 'Status', 'woocommerce' ); + $show_columns['billing_address'] = __( 'Billing', 'woocommerce' ); + $show_columns['shipping_address'] = __( 'Ship to', 'woocommerce' ); + $show_columns['order_total'] = __( 'Total', 'woocommerce' ); + $show_columns['wc_actions'] = __( 'Actions', 'woocommerce' ); + + wp_enqueue_script( 'wc-orders' ); + + return $show_columns; + } + + /** + * Define bulk actions. + * + * @param array $actions Existing actions. + * @return array + */ + public function define_bulk_actions( $actions ) { + if ( isset( $actions['edit'] ) ) { + unset( $actions['edit'] ); + } + + $actions['mark_processing'] = __( 'Change status to processing', 'woocommerce' ); + $actions['mark_on-hold'] = __( 'Change status to on-hold', 'woocommerce' ); + $actions['mark_completed'] = __( 'Change status to completed', 'woocommerce' ); + + if ( wc_string_to_bool( get_option( 'woocommerce_allow_bulk_remove_personal_data', 'no' ) ) ) { + $actions['remove_personal_data'] = __( 'Remove personal data', 'woocommerce' ); + } + + return $actions; + } + + /** + * Pre-fetch any data for the row each column has access to it. the_order global is there for bw compat. + * + * @param int $post_id Post ID being shown. + */ + protected function prepare_row_data( $post_id ) { + global $the_order; + + if ( empty( $this->object ) || $this->object->get_id() !== $post_id ) { + $this->object = wc_get_order( $post_id ); + $the_order = $this->object; + } + } + + /** + * Render columm: order_number. + */ + protected function render_order_number_column() { + $buyer = ''; + + if ( $this->object->get_billing_first_name() || $this->object->get_billing_last_name() ) { + /* translators: 1: first name 2: last name */ + $buyer = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->object->get_billing_first_name(), $this->object->get_billing_last_name() ) ); + } elseif ( $this->object->get_billing_company() ) { + $buyer = trim( $this->object->get_billing_company() ); + } elseif ( $this->object->get_customer_id() ) { + $user = get_user_by( 'id', $this->object->get_customer_id() ); + $buyer = ucwords( $user->display_name ); + } + + /** + * Filter buyer name in list table orders. + * + * @since 3.7.0 + * @param string $buyer Buyer name. + * @param WC_Order $order Order data. + */ + $buyer = apply_filters( 'woocommerce_admin_order_buyer_name', $buyer, $this->object ); + + if ( $this->object->get_status() === 'trash' ) { + echo '#' . esc_attr( $this->object->get_order_number() ) . ' ' . esc_html( $buyer ) . ''; + } else { + echo '' . esc_html( __( 'Preview', 'woocommerce' ) ) . ''; + echo '#' . esc_attr( $this->object->get_order_number() ) . ' ' . esc_html( $buyer ) . ''; + } + } + + /** + * Render columm: order_status. + */ + protected function render_order_status_column() { + $tooltip = ''; + $comment_count = get_comment_count( $this->object->get_id() ); + $approved_comments_count = absint( $comment_count['approved'] ); + + if ( $approved_comments_count ) { + $latest_notes = wc_get_order_notes( + array( + 'order_id' => $this->object->get_id(), + 'limit' => 1, + 'orderby' => 'date_created_gmt', + ) + ); + + $latest_note = current( $latest_notes ); + + if ( isset( $latest_note->content ) && 1 === $approved_comments_count ) { + $tooltip = wc_sanitize_tooltip( $latest_note->content ); + } elseif ( isset( $latest_note->content ) ) { + /* translators: %d: notes count */ + $tooltip = wc_sanitize_tooltip( $latest_note->content . '
    ' . sprintf( _n( 'Plus %d other note', 'Plus %d other notes', ( $approved_comments_count - 1 ), 'woocommerce' ), $approved_comments_count - 1 ) . '' ); + } else { + /* translators: %d: notes count */ + $tooltip = wc_sanitize_tooltip( sprintf( _n( '%d note', '%d notes', $approved_comments_count, 'woocommerce' ), $approved_comments_count ) ); + } + } + + if ( $tooltip ) { + printf( '%s', esc_attr( sanitize_html_class( 'status-' . $this->object->get_status() ) ), wp_kses_post( $tooltip ), esc_html( wc_get_order_status_name( $this->object->get_status() ) ) ); + } else { + printf( '%s', esc_attr( sanitize_html_class( 'status-' . $this->object->get_status() ) ), esc_html( wc_get_order_status_name( $this->object->get_status() ) ) ); + } + } + + /** + * Render columm: order_date. + */ + protected function render_order_date_column() { + $order_timestamp = $this->object->get_date_created() ? $this->object->get_date_created()->getTimestamp() : ''; + + if ( ! $order_timestamp ) { + echo '–'; + return; + } + + // Check if the order was created within the last 24 hours, and not in the future. + if ( $order_timestamp > strtotime( '-1 day', time() ) && $order_timestamp <= time() ) { + $show_date = sprintf( + /* translators: %s: human-readable time difference */ + _x( '%s ago', '%s = human-readable time difference', 'woocommerce' ), + human_time_diff( $this->object->get_date_created()->getTimestamp(), time() ) + ); + } else { + $show_date = $this->object->get_date_created()->date_i18n( apply_filters( 'woocommerce_admin_order_date_format', __( 'M j, Y', 'woocommerce' ) ) ); + } + printf( + '', + esc_attr( $this->object->get_date_created()->date( 'c' ) ), + esc_html( $this->object->get_date_created()->date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) ) ), + esc_html( $show_date ) + ); + } + + /** + * Render columm: order_total. + */ + protected function render_order_total_column() { + if ( $this->object->get_payment_method_title() ) { + /* translators: %s: method */ + echo '' . wp_kses_post( $this->object->get_formatted_order_total() ) . ''; + } else { + echo wp_kses_post( $this->object->get_formatted_order_total() ); + } + } + + /** + * Render columm: wc_actions. + */ + protected function render_wc_actions_column() { + echo '

    '; + + do_action( 'woocommerce_admin_order_actions_start', $this->object ); + + $actions = array(); + + if ( $this->object->has_status( array( 'pending', 'on-hold' ) ) ) { + $actions['processing'] = array( + 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=processing&order_id=' . $this->object->get_id() ), 'woocommerce-mark-order-status' ), + 'name' => __( 'Processing', 'woocommerce' ), + 'action' => 'processing', + ); + } + + if ( $this->object->has_status( array( 'pending', 'on-hold', 'processing' ) ) ) { + $actions['complete'] = array( + 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=' . $this->object->get_id() ), 'woocommerce-mark-order-status' ), + 'name' => __( 'Complete', 'woocommerce' ), + 'action' => 'complete', + ); + } + + $actions = apply_filters( 'woocommerce_admin_order_actions', $actions, $this->object ); + + echo wc_render_action_buttons( $actions ); // WPCS: XSS ok. + + do_action( 'woocommerce_admin_order_actions_end', $this->object ); + + echo '

    '; + } + + /** + * Render columm: billing_address. + */ + protected function render_billing_address_column() { + $address = $this->object->get_formatted_billing_address(); + + if ( $address ) { + echo esc_html( preg_replace( '##i', ', ', $address ) ); + + if ( $this->object->get_payment_method() ) { + /* translators: %s: payment method */ + echo '' . sprintf( __( 'via %s', 'woocommerce' ), esc_html( $this->object->get_payment_method_title() ) ) . ''; // WPCS: XSS ok. + } + } else { + echo '–'; + } + } + + /** + * Render columm: shipping_address. + */ + protected function render_shipping_address_column() { + $address = $this->object->get_formatted_shipping_address(); + + if ( $address ) { + echo '' . esc_html( preg_replace( '##i', ', ', $address ) ) . ''; + if ( $this->object->get_shipping_method() ) { + /* translators: %s: shipping method */ + echo '' . sprintf( __( 'via %s', 'woocommerce' ), esc_html( $this->object->get_shipping_method() ) ) . ''; // WPCS: XSS ok. + } + } else { + echo '–'; + } + } + + /** + * Template for order preview. + * + * @since 3.3.0 + */ + public function order_preview_template() { + ?> + + get_items(), $order ); + $columns = apply_filters( + 'woocommerce_admin_order_preview_line_item_columns', + array( + 'product' => __( 'Product', 'woocommerce' ), + 'quantity' => __( 'Quantity', 'woocommerce' ), + 'tax' => __( 'Tax', 'woocommerce' ), + 'total' => __( 'Total', 'woocommerce' ), + ), + $order + ); + + if ( ! wc_tax_enabled() ) { + unset( $columns['tax'] ); + } + + $html = ' +
    + + + '; + + foreach ( $columns as $column => $label ) { + $html .= ''; + } + + $html .= ' + + + '; + + foreach ( $line_items as $item_id => $item ) { + + $product_object = is_callable( array( $item, 'get_product' ) ) ? $item->get_product() : null; + $row_class = apply_filters( 'woocommerce_admin_html_order_preview_item_class', '', $item, $order ); + + $html .= ''; + + foreach ( $columns as $column => $label ) { + $html .= ''; + } + + $html .= ''; + } + + $html .= ' + +
    ' . esc_html( $label ) . '
    '; + switch ( $column ) { + case 'product': + $html .= wp_kses_post( $item->get_name() ); + + if ( $product_object ) { + $html .= '
    ' . esc_html( $product_object->get_sku() ) . '
    '; + } + + $meta_data = $item->get_formatted_meta_data( '' ); + + if ( $meta_data ) { + $html .= ''; + + foreach ( $meta_data as $meta_id => $meta ) { + if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) { + continue; + } + $html .= ''; + } + $html .= '
    ' . wp_kses_post( $meta->display_key ) . ':' . wp_kses_post( force_balance_tags( $meta->display_value ) ) . '
    '; + } + break; + case 'quantity': + $html .= esc_html( $item->get_quantity() ); + break; + case 'tax': + $html .= wc_price( $item->get_total_tax(), array( 'currency' => $order->get_currency() ) ); + break; + case 'total': + $html .= wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) ); + break; + default: + $html .= apply_filters( 'woocommerce_admin_order_preview_line_item_column_' . sanitize_key( $column ), '', $item, $item_id, $order ); + break; + } + $html .= '
    +
    '; + + return $html; + } + + /** + * Get actions to display in the preview as HTML. + * + * @param WC_Order $order Order object. + * @return string + */ + public static function get_order_preview_actions_html( $order ) { + $actions = array(); + $status_actions = array(); + + if ( $order->has_status( array( 'pending' ) ) ) { + $status_actions['on-hold'] = array( + 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=on-hold&order_id=' . $order->get_id() ), 'woocommerce-mark-order-status' ), + 'name' => __( 'On-hold', 'woocommerce' ), + 'title' => __( 'Change order status to on-hold', 'woocommerce' ), + 'action' => 'on-hold', + ); + } + + if ( $order->has_status( array( 'pending', 'on-hold' ) ) ) { + $status_actions['processing'] = array( + 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=processing&order_id=' . $order->get_id() ), 'woocommerce-mark-order-status' ), + 'name' => __( 'Processing', 'woocommerce' ), + 'title' => __( 'Change order status to processing', 'woocommerce' ), + 'action' => 'processing', + ); + } + + if ( $order->has_status( array( 'pending', 'on-hold', 'processing' ) ) ) { + $status_actions['complete'] = array( + 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=' . $order->get_id() ), 'woocommerce-mark-order-status' ), + 'name' => __( 'Completed', 'woocommerce' ), + 'title' => __( 'Change order status to completed', 'woocommerce' ), + 'action' => 'complete', + ); + } + + if ( $status_actions ) { + $actions['status'] = array( + 'group' => __( 'Change status: ', 'woocommerce' ), + 'actions' => $status_actions, + ); + } + + return wc_render_action_buttons( apply_filters( 'woocommerce_admin_order_preview_actions', $actions, $order ) ); + } + + /** + * Get order details to send to the ajax endpoint for previews. + * + * @param WC_Order $order Order object. + * @return array + */ + public static function order_preview_get_order_details( $order ) { + if ( ! $order ) { + return array(); + } + + $payment_via = $order->get_payment_method_title(); + $payment_method = $order->get_payment_method(); + $payment_gateways = WC()->payment_gateways() ? WC()->payment_gateways->payment_gateways() : array(); + $transaction_id = $order->get_transaction_id(); + + if ( $transaction_id ) { + + $url = isset( $payment_gateways[ $payment_method ] ) ? $payment_gateways[ $payment_method ]->get_transaction_url( $order ) : false; + + if ( $url ) { + $payment_via .= ' (' . esc_html( $transaction_id ) . ')'; + } else { + $payment_via .= ' (' . esc_html( $transaction_id ) . ')'; + } + } + + $billing_address = $order->get_formatted_billing_address(); + $shipping_address = $order->get_formatted_shipping_address(); + + return apply_filters( + 'woocommerce_admin_order_preview_get_order_details', + array( + 'data' => $order->get_data(), + 'order_number' => $order->get_order_number(), + 'item_html' => self::get_order_preview_item_html( $order ), + 'actions_html' => self::get_order_preview_actions_html( $order ), + 'ship_to_billing' => wc_ship_to_billing_address_only(), + 'needs_shipping' => $order->needs_shipping_address(), + 'formatted_billing_address' => $billing_address ? $billing_address : __( 'N/A', 'woocommerce' ), + 'formatted_shipping_address' => $shipping_address ? $shipping_address : __( 'N/A', 'woocommerce' ), + 'shipping_address_map_url' => $order->get_shipping_address_map_url(), + 'payment_via' => $payment_via, + 'shipping_via' => $order->get_shipping_method(), + 'status' => $order->get_status(), + 'status_name' => wc_get_order_status_name( $order->get_status() ), + ), + $order + ); + } + + /** + * Handle bulk actions. + * + * @param string $redirect_to URL to redirect to. + * @param string $action Action name. + * @param array $ids List of ids. + * @return string + */ + public function handle_bulk_actions( $redirect_to, $action, $ids ) { + $ids = apply_filters( 'woocommerce_bulk_action_ids', array_reverse( array_map( 'absint', $ids ) ), $action, 'order' ); + $changed = 0; + + if ( 'remove_personal_data' === $action ) { + $report_action = 'removed_personal_data'; + + foreach ( $ids as $id ) { + $order = wc_get_order( $id ); + + if ( $order ) { + do_action( 'woocommerce_remove_order_personal_data', $order ); + $changed++; + } + } + } elseif ( false !== strpos( $action, 'mark_' ) ) { + $order_statuses = wc_get_order_statuses(); + $new_status = substr( $action, 5 ); // Get the status name from action. + $report_action = 'marked_' . $new_status; + + // Sanity check: bail out if this is actually not a status, or is not a registered status. + if ( isset( $order_statuses[ 'wc-' . $new_status ] ) ) { + // Initialize payment gateways in case order has hooked status transition actions. + WC()->payment_gateways(); + + foreach ( $ids as $id ) { + $order = wc_get_order( $id ); + $order->update_status( $new_status, __( 'Order status changed by bulk edit:', 'woocommerce' ), true ); + do_action( 'woocommerce_order_edit_status', $id, $new_status ); + $changed++; + } + } + } + + if ( $changed ) { + $redirect_to = add_query_arg( + array( + 'post_type' => $this->list_table_type, + 'bulk_action' => $report_action, + 'changed' => $changed, + 'ids' => join( ',', $ids ), + ), + $redirect_to + ); + } + + return esc_url_raw( $redirect_to ); + } + + /** + * Show confirmation message that order status changed for number of orders. + */ + public function bulk_admin_notices() { + global $post_type, $pagenow; + + // Bail out if not on shop order list page. + if ( 'edit.php' !== $pagenow || 'shop_order' !== $post_type || ! isset( $_REQUEST['bulk_action'] ) ) { // WPCS: input var ok, CSRF ok. + return; + } + + $order_statuses = wc_get_order_statuses(); + $number = isset( $_REQUEST['changed'] ) ? absint( $_REQUEST['changed'] ) : 0; // WPCS: input var ok, CSRF ok. + $bulk_action = wc_clean( wp_unslash( $_REQUEST['bulk_action'] ) ); // WPCS: input var ok, CSRF ok. + + // Check if any status changes happened. + foreach ( $order_statuses as $slug => $name ) { + if ( 'marked_' . str_replace( 'wc-', '', $slug ) === $bulk_action ) { // WPCS: input var ok, CSRF ok. + /* translators: %d: orders count */ + $message = sprintf( _n( '%d order status changed.', '%d order statuses changed.', $number, 'woocommerce' ), number_format_i18n( $number ) ); + echo '

    ' . esc_html( $message ) . '

    '; + break; + } + } + + if ( 'removed_personal_data' === $bulk_action ) { // WPCS: input var ok, CSRF ok. + /* translators: %d: orders count */ + $message = sprintf( _n( 'Removed personal data from %d order.', 'Removed personal data from %d orders.', $number, 'woocommerce' ), number_format_i18n( $number ) ); + echo '

    ' . esc_html( $message ) . '

    '; + } + } + + /** + * See if we should render search filters or not. + */ + public function restrict_manage_posts() { + global $typenow; + + if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ), true ) ) { + $this->render_filters(); + } + } + + /** + * Render any custom filters and search inputs for the list table. + */ + protected function render_filters() { + $user_string = ''; + $user_id = ''; + + if ( ! empty( $_GET['_customer_user'] ) ) { // phpcs:disable WordPress.Security.NonceVerification.Recommended + $user_id = absint( $_GET['_customer_user'] ); // WPCS: input var ok, sanitization ok. + $user = get_user_by( 'id', $user_id ); + + $user_string = sprintf( + /* translators: 1: user display name 2: user ID 3: user email */ + esc_html__( '%1$s (#%2$s – %3$s)', 'woocommerce' ), + $user->display_name, + absint( $user->ID ), + $user->user_email + ); + } + ?> + + query_filters( $query_vars ); + } + + return $query_vars; + } + + /** + * Handle any custom filters. + * + * @param array $query_vars Query vars. + * @return array + */ + protected function query_filters( $query_vars ) { + global $wp_post_statuses; + + // Filter the orders by the posted customer. + if ( ! empty( $_GET['_customer_user'] ) ) { // WPCS: input var ok. + // @codingStandardsIgnoreStart. + $query_vars['meta_query'] = array( + array( + 'key' => '_customer_user', + 'value' => (int) $_GET['_customer_user'], // WPCS: input var ok, sanitization ok. + 'compare' => '=', + ), + ); + // @codingStandardsIgnoreEnd + } + + // Sorting. + if ( isset( $query_vars['orderby'] ) ) { + if ( 'order_total' === $query_vars['orderby'] ) { + // @codingStandardsIgnoreStart + $query_vars = array_merge( $query_vars, array( + 'meta_key' => '_order_total', + 'orderby' => 'meta_value_num', + ) ); + // @codingStandardsIgnoreEnd + } + } + + // Status. + if ( empty( $query_vars['post_status'] ) ) { + $post_statuses = wc_get_order_statuses(); + + foreach ( $post_statuses as $status => $value ) { + if ( isset( $wp_post_statuses[ $status ] ) && false === $wp_post_statuses[ $status ]->show_in_admin_all_list ) { + unset( $post_statuses[ $status ] ); + } + } + + $query_vars['post_status'] = array_keys( $post_statuses ); + } + return $query_vars; + } + + /** + * Change the label when searching orders. + * + * @param mixed $query Current search query. + * @return string + */ + public function search_label( $query ) { + global $pagenow, $typenow; + + if ( 'edit.php' !== $pagenow || 'shop_order' !== $typenow || ! get_query_var( 'shop_order_search' ) || ! isset( $_GET['s'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + return $query; + } + + return wc_clean( wp_unslash( $_GET['s'] ) ); // WPCS: input var ok, sanitization ok. + } + + /** + * Query vars for custom searches. + * + * @param mixed $public_query_vars Array of query vars. + * @return array + */ + public function add_custom_query_var( $public_query_vars ) { + $public_query_vars[] = 'shop_order_search'; + return $public_query_vars; + } + + /** + * Search custom fields as well as content. + * + * @param WP_Query $wp Query object. + */ + public function search_custom_fields( $wp ) { + global $pagenow; + + if ( 'edit.php' !== $pagenow || empty( $wp->query_vars['s'] ) || 'shop_order' !== $wp->query_vars['post_type'] || ! isset( $_GET['s'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + return; + } + + $post_ids = wc_order_search( wc_clean( wp_unslash( $_GET['s'] ) ) ); // WPCS: input var ok, sanitization ok. + + if ( ! empty( $post_ids ) ) { + // Remove "s" - we don't want to search order name. + unset( $wp->query_vars['s'] ); + + // so we know we're doing this. + $wp->query_vars['shop_order_search'] = true; + + // Search by found posts. + $wp->query_vars['post__in'] = array_merge( $post_ids, array( 0 ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-products.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-products.php new file mode 100644 index 0000000..a7990fa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-products.php @@ -0,0 +1,661 @@ +'; + + echo '

    ' . esc_html__( 'Ready to start selling something awesome?', 'woocommerce' ) . '

    '; + + echo ''; + + do_action( 'wc_marketplace_suggestions_products_empty_state' ); + + echo ''; + } + + /** + * Define primary column. + * + * @return string + */ + protected function get_primary_column() { + return 'name'; + } + + /** + * Get row actions to show in the list table. + * + * @param array $actions Array of actions. + * @param WP_Post $post Current post object. + * @return array + */ + protected function get_row_actions( $actions, $post ) { + /* translators: %d: product ID. */ + return array_merge( array( 'id' => sprintf( __( 'ID: %d', 'woocommerce' ), $post->ID ) ), $actions ); + } + + /** + * Define which columns are sortable. + * + * @param array $columns Existing columns. + * @return array + */ + public function define_sortable_columns( $columns ) { + $custom = array( + 'price' => 'price', + 'sku' => 'sku', + 'name' => 'title', + ); + return wp_parse_args( $custom, $columns ); + } + + /** + * Define which columns to show on this screen. + * + * @param array $columns Existing columns. + * @return array + */ + public function define_columns( $columns ) { + if ( empty( $columns ) && ! is_array( $columns ) ) { + $columns = array(); + } + + unset( $columns['title'], $columns['comments'], $columns['date'] ); + + $show_columns = array(); + $show_columns['cb'] = ''; + $show_columns['thumb'] = '' . __( 'Image', 'woocommerce' ) . ''; + $show_columns['name'] = __( 'Name', 'woocommerce' ); + + if ( wc_product_sku_enabled() ) { + $show_columns['sku'] = __( 'SKU', 'woocommerce' ); + } + + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + $show_columns['is_in_stock'] = __( 'Stock', 'woocommerce' ); + } + + $show_columns['price'] = __( 'Price', 'woocommerce' ); + $show_columns['product_cat'] = __( 'Categories', 'woocommerce' ); + $show_columns['product_tag'] = __( 'Tags', 'woocommerce' ); + $show_columns['featured'] = '' . __( 'Featured', 'woocommerce' ) . ''; + $show_columns['date'] = __( 'Date', 'woocommerce' ); + + return array_merge( $show_columns, $columns ); + } + + /** + * Pre-fetch any data for the row each column has access to it. the_product global is there for bw compat. + * + * @param int $post_id Post ID being shown. + */ + protected function prepare_row_data( $post_id ) { + global $the_product; + + if ( empty( $this->object ) || $this->object->get_id() !== $post_id ) { + $the_product = wc_get_product( $post_id ); + $this->object = $the_product; + } + } + + /** + * Render columm: thumb. + */ + protected function render_thumb_column() { + echo '' . $this->object->get_image( 'thumbnail' ) . ''; // WPCS: XSS ok. + } + + /** + * Render column: name. + */ + protected function render_name_column() { + global $post; + + $edit_link = get_edit_post_link( $this->object->get_id() ); + $title = _draft_or_post_title(); + + echo '' . esc_html( $title ) . ''; + + _post_states( $post ); + + echo ''; + + if ( $this->object->get_parent_id() > 0 ) { + echo '  ← ' . get_the_title( $this->object->get_parent_id() ) . ''; // @codingStandardsIgnoreLine. + } + + get_inline_data( $post ); + + /* Custom inline data for woocommerce. */ + echo ' + + '; + } + + /** + * Render columm: sku. + */ + protected function render_sku_column() { + echo $this->object->get_sku() ? esc_html( $this->object->get_sku() ) : ''; + } + + /** + * Render columm: price. + */ + protected function render_price_column() { + echo $this->object->get_price_html() ? wp_kses_post( $this->object->get_price_html() ) : ''; + } + + /** + * Render columm: product_cat. + */ + protected function render_product_cat_column() { + $terms = get_the_terms( $this->object->get_id(), 'product_cat' ); + if ( ! $terms ) { + echo ''; + } else { + $termlist = array(); + foreach ( $terms as $term ) { + $termlist[] = '' . esc_html( $term->name ) . ''; + } + + echo apply_filters( 'woocommerce_admin_product_term_list', implode( ', ', $termlist ), 'product_cat', $this->object->get_id(), $termlist, $terms ); // WPCS: XSS ok. + } + } + + /** + * Render columm: product_tag. + */ + protected function render_product_tag_column() { + $terms = get_the_terms( $this->object->get_id(), 'product_tag' ); + if ( ! $terms ) { + echo ''; + } else { + $termlist = array(); + foreach ( $terms as $term ) { + $termlist[] = '' . esc_html( $term->name ) . ''; + } + + echo apply_filters( 'woocommerce_admin_product_term_list', implode( ', ', $termlist ), 'product_tag', $this->object->get_id(), $termlist, $terms ); // WPCS: XSS ok. + } + } + + /** + * Render columm: featured. + */ + protected function render_featured_column() { + $url = wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_feature_product&product_id=' . $this->object->get_id() ), 'woocommerce-feature-product' ); + echo ''; + if ( $this->object->is_featured() ) { + echo '' . esc_html__( 'Yes', 'woocommerce' ) . ''; + } else { + echo '' . esc_html__( 'No', 'woocommerce' ) . ''; + } + echo ''; + } + + /** + * Render columm: is_in_stock. + */ + protected function render_is_in_stock_column() { + if ( $this->object->is_on_backorder() ) { + $stock_html = '' . __( 'On backorder', 'woocommerce' ) . ''; + } elseif ( $this->object->is_in_stock() ) { + $stock_html = '' . __( 'In stock', 'woocommerce' ) . ''; + } else { + $stock_html = '' . __( 'Out of stock', 'woocommerce' ) . ''; + } + + if ( $this->object->managing_stock() ) { + $stock_html .= ' (' . wc_stock_amount( $this->object->get_stock_quantity() ) . ')'; + } + + echo wp_kses_post( apply_filters( 'woocommerce_admin_stock_html', $stock_html, $this->object ) ); + } + + /** + * Query vars for custom searches. + * + * @param mixed $public_query_vars Array of query vars. + * @return array + */ + public function add_custom_query_var( $public_query_vars ) { + $public_query_vars[] = 'sku'; + return $public_query_vars; + } + + /** + * Render any custom filters and search inputs for the list table. + */ + protected function render_filters() { + $filters = apply_filters( + 'woocommerce_products_admin_list_table_filters', + array( + 'product_category' => array( $this, 'render_products_category_filter' ), + 'product_type' => array( $this, 'render_products_type_filter' ), + 'stock_status' => array( $this, 'render_products_stock_status_filter' ), + ) + ); + + ob_start(); + foreach ( $filters as $filter_callback ) { + call_user_func( $filter_callback ); + } + $output = ob_get_clean(); + + echo apply_filters( 'woocommerce_product_filters', $output ); // WPCS: XSS ok. + } + + /** + * Render the product category filter for the list table. + * + * @since 3.5.0 + */ + protected function render_products_category_filter() { + $categories_count = (int) wp_count_terms( 'product_cat' ); + + if ( $categories_count <= apply_filters( 'woocommerce_product_category_filter_threshold', 100 ) ) { + wc_product_dropdown_categories( + array( + 'option_select_text' => __( 'Filter by category', 'woocommerce' ), + 'hide_empty' => 0, + ) + ); + } else { + $current_category_slug = isset( $_GET['product_cat'] ) ? wc_clean( wp_unslash( $_GET['product_cat'] ) ) : false; // WPCS: input var ok, CSRF ok. + $current_category = $current_category_slug ? get_term_by( 'slug', $current_category_slug, 'product_cat' ) : false; + ?> + + '; + + foreach ( wc_get_product_types() as $value => $label ) { + $output .= ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + } + } + + /** + * Get country address formats. + * + * These define how addresses are formatted for display in various countries. + * + * @return array + */ + public function get_address_formats() { + if ( empty( $this->address_formats ) ) { + $this->address_formats = apply_filters( + 'woocommerce_localisation_address_formats', + array( + 'default' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode}\n{country}", + 'AU' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {state} {postcode}\n{country}", + 'AT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'BE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'CA' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {state_code} {postcode}\n{country}", + 'CH' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'CL' => "{company}\n{name}\n{address_1}\n{address_2}\n{state}\n{postcode} {city}\n{country}", + 'CN' => "{country} {postcode}\n{state}, {city}, {address_2}, {address_1}\n{company}\n{name}", + 'CZ' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'DE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'EE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'FI' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'DK' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'FR' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city_upper}\n{country}", + 'HK' => "{company}\n{first_name} {last_name_upper}\n{address_1}\n{address_2}\n{city_upper}\n{state_upper}\n{country}", + 'HU' => "{last_name} {first_name}\n{company}\n{city}\n{address_1}\n{address_2}\n{postcode}\n{country}", + 'IN' => "{company}\n{name}\n{address_1}\n{address_2}\n{city} {postcode}\n{state}, {country}", + 'IS' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'IT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode}\n{city}\n{state_upper}\n{country}", + 'JM' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode_upper}\n{country}", + 'JP' => "{postcode}\n{state} {city} {address_1}\n{address_2}\n{company}\n{last_name} {first_name}\n{country}", + 'TW' => "{company}\n{last_name} {first_name}\n{address_1}\n{address_2}\n{state}, {city} {postcode}\n{country}", + 'LI' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'NL' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'NZ' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {postcode}\n{country}", + 'NO' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'PL' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'PR' => "{company}\n{name}\n{address_1} {address_2}\n{city} \n{country} {postcode}", + 'PT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'SK' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'RS' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'SI' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'ES' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{state}\n{country}", + 'SE' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}", + 'TR' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city} {state}\n{country}", + 'UG' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}, {country}", + 'US' => "{name}\n{company}\n{address_1}\n{address_2}\n{city}, {state_code} {postcode}\n{country}", + 'VN' => "{name}\n{company}\n{address_1}\n{city}\n{country}", + ) + ); + } + return $this->address_formats; + } + + /** + * Get country address format. + * + * @param array $args Arguments. + * @param string $separator How to separate address lines. @since 3.5.0. + * @return string + */ + public function get_formatted_address( $args = array(), $separator = '
    ' ) { + $default_args = array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + ); + + $args = array_map( 'trim', wp_parse_args( $args, $default_args ) ); + $state = $args['state']; + $country = $args['country']; + + // Get all formats. + $formats = $this->get_address_formats(); + + // Get format for the address' country. + $format = ( $country && isset( $formats[ $country ] ) ) ? $formats[ $country ] : $formats['default']; + + // Handle full country name. + $full_country = ( isset( $this->countries[ $country ] ) ) ? $this->countries[ $country ] : $country; + + // Country is not needed if the same as base. + if ( $country === $this->get_base_country() && ! apply_filters( 'woocommerce_formatted_address_force_country_display', false ) ) { + $format = str_replace( '{country}', '', $format ); + } + + // Handle full state name. + $full_state = ( $country && $state && isset( $this->states[ $country ][ $state ] ) ) ? $this->states[ $country ][ $state ] : $state; + + // Substitute address parts into the string. + $replace = array_map( + 'esc_html', + apply_filters( + 'woocommerce_formatted_address_replacements', + array( + '{first_name}' => $args['first_name'], + '{last_name}' => $args['last_name'], + '{name}' => $args['first_name'] . ' ' . $args['last_name'], + '{company}' => $args['company'], + '{address_1}' => $args['address_1'], + '{address_2}' => $args['address_2'], + '{city}' => $args['city'], + '{state}' => $full_state, + '{postcode}' => $args['postcode'], + '{country}' => $full_country, + '{first_name_upper}' => wc_strtoupper( $args['first_name'] ), + '{last_name_upper}' => wc_strtoupper( $args['last_name'] ), + '{name_upper}' => wc_strtoupper( $args['first_name'] . ' ' . $args['last_name'] ), + '{company_upper}' => wc_strtoupper( $args['company'] ), + '{address_1_upper}' => wc_strtoupper( $args['address_1'] ), + '{address_2_upper}' => wc_strtoupper( $args['address_2'] ), + '{city_upper}' => wc_strtoupper( $args['city'] ), + '{state_upper}' => wc_strtoupper( $full_state ), + '{state_code}' => wc_strtoupper( $state ), + '{postcode_upper}' => wc_strtoupper( $args['postcode'] ), + '{country_upper}' => wc_strtoupper( $full_country ), + ), + $args + ) + ); + + $formatted_address = str_replace( array_keys( $replace ), $replace, $format ); + + // Clean up white space. + $formatted_address = preg_replace( '/ +/', ' ', trim( $formatted_address ) ); + $formatted_address = preg_replace( '/\n\n+/', "\n", $formatted_address ); + + // Break newlines apart and remove empty lines/trim commas and white space. + $formatted_address = array_filter( array_map( array( $this, 'trim_formatted_address_line' ), explode( "\n", $formatted_address ) ) ); + + // Add html breaks. + $formatted_address = implode( $separator, $formatted_address ); + + // We're done! + return $formatted_address; + } + + /** + * Trim white space and commas off a line. + * + * @param string $line Line. + * @return string + */ + private function trim_formatted_address_line( $line ) { + return trim( $line, ', ' ); + } + + /** + * Returns the fields we show by default. This can be filtered later on. + * + * @return array + */ + public function get_default_address_fields() { + if ( 'optional' === get_option( 'woocommerce_checkout_address_2_field', 'optional' ) ) { + $address_2_placeholder = __( 'Apartment, suite, unit, etc. (optional)', 'woocommerce' ); + } else { + $address_2_placeholder = __( 'Apartment, suite, unit, etc.', 'woocommerce' ); + } + + $fields = array( + 'first_name' => array( + 'label' => __( 'First name', 'woocommerce' ), + 'required' => true, + 'class' => array( 'form-row-first' ), + 'autocomplete' => 'given-name', + 'priority' => 10, + ), + 'last_name' => array( + 'label' => __( 'Last name', 'woocommerce' ), + 'required' => true, + 'class' => array( 'form-row-last' ), + 'autocomplete' => 'family-name', + 'priority' => 20, + ), + 'company' => array( + 'label' => __( 'Company name', 'woocommerce' ), + 'class' => array( 'form-row-wide' ), + 'autocomplete' => 'organization', + 'priority' => 30, + 'required' => 'required' === get_option( 'woocommerce_checkout_company_field', 'optional' ), + ), + 'country' => array( + 'type' => 'country', + 'label' => __( 'Country / Region', 'woocommerce' ), + 'required' => true, + 'class' => array( 'form-row-wide', 'address-field', 'update_totals_on_change' ), + 'autocomplete' => 'country', + 'priority' => 40, + ), + 'address_1' => array( + 'label' => __( 'Street address', 'woocommerce' ), + /* translators: use local order of street name and house number. */ + 'placeholder' => esc_attr__( 'House number and street name', 'woocommerce' ), + 'required' => true, + 'class' => array( 'form-row-wide', 'address-field' ), + 'autocomplete' => 'address-line1', + 'priority' => 50, + ), + 'address_2' => array( + 'placeholder' => esc_attr( $address_2_placeholder ), + 'class' => array( 'form-row-wide', 'address-field' ), + 'autocomplete' => 'address-line2', + 'priority' => 60, + 'required' => 'required' === get_option( 'woocommerce_checkout_address_2_field', 'optional' ), + ), + 'city' => array( + 'label' => __( 'Town / City', 'woocommerce' ), + 'required' => true, + 'class' => array( 'form-row-wide', 'address-field' ), + 'autocomplete' => 'address-level2', + 'priority' => 70, + ), + 'state' => array( + 'type' => 'state', + 'label' => __( 'State / County', 'woocommerce' ), + 'required' => true, + 'class' => array( 'form-row-wide', 'address-field' ), + 'validate' => array( 'state' ), + 'autocomplete' => 'address-level1', + 'priority' => 80, + ), + 'postcode' => array( + 'label' => __( 'Postcode / ZIP', 'woocommerce' ), + 'required' => true, + 'class' => array( 'form-row-wide', 'address-field' ), + 'validate' => array( 'postcode' ), + 'autocomplete' => 'postal-code', + 'priority' => 90, + ), + ); + + if ( 'hidden' === get_option( 'woocommerce_checkout_company_field', 'optional' ) ) { + unset( $fields['company'] ); + } + + if ( 'hidden' === get_option( 'woocommerce_checkout_address_2_field', 'optional' ) ) { + unset( $fields['address_2'] ); + } + + $default_address_fields = apply_filters( 'woocommerce_default_address_fields', $fields ); + // Sort each of the fields based on priority. + uasort( $default_address_fields, 'wc_checkout_fields_uasort_comparison' ); + + return $default_address_fields; + } + + /** + * Get JS selectors for fields which are shown/hidden depending on the locale. + * + * @return array + */ + public function get_country_locale_field_selectors() { + $locale_fields = array( + 'address_1' => '#billing_address_1_field, #shipping_address_1_field', + 'address_2' => '#billing_address_2_field, #shipping_address_2_field', + 'state' => '#billing_state_field, #shipping_state_field, #calc_shipping_state_field', + 'postcode' => '#billing_postcode_field, #shipping_postcode_field, #calc_shipping_postcode_field', + 'city' => '#billing_city_field, #shipping_city_field, #calc_shipping_city_field', + ); + return apply_filters( 'woocommerce_country_locale_field_selectors', $locale_fields ); + } + + /** + * Get country locale settings. + * + * These locales override the default country selections after a country is chosen. + * + * @return array + */ + public function get_country_locale() { + if ( empty( $this->locale ) ) { + $this->locale = apply_filters( + 'woocommerce_get_country_locale', + array( + 'AE' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + 'state' => array( + 'required' => false, + ), + ), + 'AF' => array( + 'state' => array( + 'required' => false, + ), + ), + 'AO' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + 'state' => array( + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'AT' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'AU' => array( + 'city' => array( + 'label' => __( 'Suburb', 'woocommerce' ), + ), + 'postcode' => array( + 'label' => __( 'Postcode', 'woocommerce' ), + ), + 'state' => array( + 'label' => __( 'State', 'woocommerce' ), + ), + ), + 'AX' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'BA' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'label' => __( 'Canton', 'woocommerce' ), + 'required' => false, + 'hidden' => true, + ), + ), + 'BD' => array( + 'postcode' => array( + 'required' => false, + ), + 'state' => array( + 'label' => __( 'District', 'woocommerce' ), + ), + ), + 'BE' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'BH' => array( + 'postcode' => array( + 'required' => false, + ), + 'state' => array( + 'required' => false, + ), + ), + 'BI' => array( + 'state' => array( + 'required' => false, + ), + ), + 'BO' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + ), + 'BS' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + ), + 'CA' => array( + 'postcode' => array( + 'label' => __( 'Postal code', 'woocommerce' ), + ), + 'state' => array( + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'CH' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'label' => __( 'Canton', 'woocommerce' ), + 'required' => false, + ), + ), + 'CL' => array( + 'city' => array( + 'required' => true, + ), + 'postcode' => array( + 'required' => false, + ), + 'state' => array( + 'label' => __( 'Region', 'woocommerce' ), + ), + ), + 'CN' => array( + 'state' => array( + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'CO' => array( + 'postcode' => array( + 'required' => false, + ), + ), + 'CZ' => array( + 'state' => array( + 'required' => false, + ), + ), + 'DE' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + 'hidden' => true, + ), + ), + 'DK' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + 'hidden' => true, + ), + ), + 'EE' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'FI' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'FR' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'GH' => array( + 'postcode' => array( + 'required' => false, + ), + 'state' => array( + 'label' => __( 'Region', 'woocommerce' ), + ), + ), + 'GP' => array( + 'state' => array( + 'required' => false, + ), + ), + 'GF' => array( + 'state' => array( + 'required' => false, + ), + ), + 'GR' => array( + 'state' => array( + 'required' => false, + ), + ), + 'HK' => array( + 'postcode' => array( + 'required' => false, + ), + 'city' => array( + 'label' => __( 'Town / District', 'woocommerce' ), + ), + 'state' => array( + 'label' => __( 'Region', 'woocommerce' ), + ), + ), + 'HU' => array( + 'last_name' => array( + 'class' => array( 'form-row-first' ), + 'priority' => 10, + ), + 'first_name' => array( + 'class' => array( 'form-row-last' ), + 'priority' => 20, + ), + 'postcode' => array( + 'class' => array( 'form-row-first', 'address-field' ), + 'priority' => 65, + ), + 'city' => array( + 'class' => array( 'form-row-last', 'address-field' ), + ), + 'address_1' => array( + 'priority' => 71, + ), + 'address_2' => array( + 'priority' => 72, + ), + 'state' => array( + 'label' => __( 'County', 'woocommerce' ), + ), + ), + 'ID' => array( + 'state' => array( + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'IE' => array( + 'postcode' => array( + 'required' => false, + 'label' => __( 'Eircode', 'woocommerce' ), + ), + 'state' => array( + 'label' => __( 'County', 'woocommerce' ), + ), + ), + 'IS' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'IL' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'IM' => array( + 'state' => array( + 'required' => false, + ), + ), + 'IN' => array( + 'postcode' => array( + 'label' => __( 'Pin code', 'woocommerce' ), + ), + 'state' => array( + 'label' => __( 'State', 'woocommerce' ), + ), + ), + 'IT' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => true, + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'JM' => array( + 'city' => array( + 'label' => __( 'Town / City / Post Office', 'woocommerce' ), + ), + 'postcode' => array( + 'required' => false, + 'label' => __( 'Postal Code', 'woocommerce' ), + ), + 'state' => array( + 'required' => true, + 'label' => __( 'Parish', 'woocommerce' ), + ), + ), + 'JP' => array( + 'last_name' => array( + 'class' => array( 'form-row-first' ), + 'priority' => 10, + ), + 'first_name' => array( + 'class' => array( 'form-row-last' ), + 'priority' => 20, + ), + 'postcode' => array( + 'class' => array( 'form-row-first', 'address-field' ), + 'priority' => 65, + ), + 'state' => array( + 'label' => __( 'Prefecture', 'woocommerce' ), + 'class' => array( 'form-row-last', 'address-field' ), + 'priority' => 66, + ), + 'city' => array( + 'priority' => 67, + ), + 'address_1' => array( + 'priority' => 68, + ), + 'address_2' => array( + 'priority' => 69, + ), + ), + 'KR' => array( + 'state' => array( + 'required' => false, + ), + ), + 'KW' => array( + 'state' => array( + 'required' => false, + ), + ), + 'LV' => array( + 'state' => array( + 'label' => __( 'Municipality', 'woocommerce' ), + 'required' => false, + ), + ), + 'LB' => array( + 'state' => array( + 'required' => false, + ), + ), + 'MQ' => array( + 'state' => array( + 'required' => false, + ), + ), + 'MT' => array( + 'state' => array( + 'required' => false, + ), + ), + 'MZ' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + 'state' => array( + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'NL' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'NG' => array( + 'postcode' => array( + 'label' => __( 'Postcode', 'woocommerce' ), + 'required' => false, + 'hidden' => true, + ), + 'state' => array( + 'label' => __( 'State', 'woocommerce' ), + ), + ), + 'NZ' => array( + 'postcode' => array( + 'label' => __( 'Postcode', 'woocommerce' ), + ), + 'state' => array( + 'required' => false, + 'label' => __( 'Region', 'woocommerce' ), + ), + ), + 'NO' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'NP' => array( + 'state' => array( + 'label' => __( 'State / Zone', 'woocommerce' ), + ), + 'postcode' => array( + 'required' => false, + ), + ), + 'PL' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'PR' => array( + 'city' => array( + 'label' => __( 'Municipality', 'woocommerce' ), + ), + 'state' => array( + 'required' => false, + 'hidden' => true, + ), + ), + 'PT' => array( + 'state' => array( + 'required' => false, + ), + ), + 'RE' => array( + 'state' => array( + 'required' => false, + ), + ), + 'RO' => array( + 'state' => array( + 'label' => __( 'County', 'woocommerce' ), + 'required' => true, + ), + ), + 'RS' => array( + 'city' => array( + 'required' => false, + ), + 'postcode' => array( + 'required' => false, + ), + 'state' => array( + 'label' => __( 'District', 'woocommerce' ), + 'required' => false, + ), + ), + 'SG' => array( + 'state' => array( + 'required' => false, + ), + 'city' => array( + 'required' => false, + ), + ), + 'SK' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'SI' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + ), + ), + 'SR' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + ), + 'ES' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'LI' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'label' => __( 'Municipality', 'woocommerce' ), + 'required' => false, + ), + ), + 'LK' => array( + 'state' => array( + 'required' => false, + ), + ), + 'LU' => array( + 'state' => array( + 'required' => false, + ), + ), + 'MD' => array( + 'state' => array( + 'label' => __( 'Municipality / District', 'woocommerce' ), + ), + ), + 'SE' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'required' => false, + 'hidden' => true, + ), + ), + 'TR' => array( + 'postcode' => array( + 'priority' => 65, + ), + 'state' => array( + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'UG' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + 'city' => array( + 'label' => __( 'Town / Village', 'woocommerce' ), + 'required' => true, + ), + 'state' => array( + 'label' => __( 'District', 'woocommerce' ), + 'required' => true, + ), + ), + 'US' => array( + 'postcode' => array( + 'label' => __( 'ZIP', 'woocommerce' ), + ), + 'state' => array( + 'label' => __( 'State', 'woocommerce' ), + ), + ), + 'GB' => array( + 'postcode' => array( + 'label' => __( 'Postcode', 'woocommerce' ), + ), + 'state' => array( + 'label' => __( 'County', 'woocommerce' ), + 'required' => false, + ), + ), + 'ST' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + 'state' => array( + 'label' => __( 'District', 'woocommerce' ), + ), + ), + 'VN' => array( + 'state' => array( + 'required' => false, + 'hidden' => true, + ), + 'postcode' => array( + 'priority' => 65, + 'required' => false, + 'hidden' => false, + ), + 'address_2' => array( + 'required' => false, + 'hidden' => true, + ), + ), + 'WS' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + ), + 'YT' => array( + 'state' => array( + 'required' => false, + ), + ), + 'ZA' => array( + 'state' => array( + 'label' => __( 'Province', 'woocommerce' ), + ), + ), + 'ZW' => array( + 'postcode' => array( + 'required' => false, + 'hidden' => true, + ), + ), + ) + ); + + $this->locale = array_intersect_key( $this->locale, array_merge( $this->get_allowed_countries(), $this->get_shipping_countries() ) ); + + // Default Locale Can be filtered to override fields in get_address_fields(). Countries with no specific locale will use default. + $this->locale['default'] = apply_filters( 'woocommerce_get_country_locale_default', $this->get_default_address_fields() ); + + // Filter default AND shop base locales to allow overides via a single function. These will be used when changing countries on the checkout. + if ( ! isset( $this->locale[ $this->get_base_country() ] ) ) { + $this->locale[ $this->get_base_country() ] = $this->locale['default']; + } + + $this->locale['default'] = apply_filters( 'woocommerce_get_country_locale_base', $this->locale['default'] ); + $this->locale[ $this->get_base_country() ] = apply_filters( 'woocommerce_get_country_locale_base', $this->locale[ $this->get_base_country() ] ); + } + + return $this->locale; + } + + /** + * Apply locale and get address fields. + * + * @param mixed $country Country. + * @param string $type Address type, defaults to 'billing_'. + * @return array + */ + public function get_address_fields( $country = '', $type = 'billing_' ) { + if ( ! $country ) { + $country = $this->get_base_country(); + } + + $fields = $this->get_default_address_fields(); + $locale = $this->get_country_locale(); + + if ( isset( $locale[ $country ] ) ) { + $fields = wc_array_overlay( $fields, $locale[ $country ] ); + } + + // Prepend field keys. + $address_fields = array(); + + foreach ( $fields as $key => $value ) { + if ( 'state' === $key ) { + $value['country_field'] = $type . 'country'; + $value['country'] = $country; + } + $address_fields[ $type . $key ] = $value; + } + + // Add email and phone fields. + if ( 'billing_' === $type ) { + if ( 'hidden' !== get_option( 'woocommerce_checkout_phone_field', 'required' ) ) { + $address_fields['billing_phone'] = array( + 'label' => __( 'Phone', 'woocommerce' ), + 'required' => 'required' === get_option( 'woocommerce_checkout_phone_field', 'required' ), + 'type' => 'tel', + 'class' => array( 'form-row-wide' ), + 'validate' => array( 'phone' ), + 'autocomplete' => 'tel', + 'priority' => 100, + ); + } + $address_fields['billing_email'] = array( + 'label' => __( 'Email address', 'woocommerce' ), + 'required' => true, + 'type' => 'email', + 'class' => array( 'form-row-wide' ), + 'validate' => array( 'email' ), + 'autocomplete' => 'no' === get_option( 'woocommerce_registration_generate_username' ) ? 'email' : 'email username', + 'priority' => 110, + ); + } + + /** + * Important note on this filter: Changes to address fields can and will be overridden by + * the woocommerce_default_address_fields. The locales/default locales apply on top based + * on country selection. If you want to change things like the required status of an + * address field, filter woocommerce_default_address_fields instead. + */ + $address_fields = apply_filters( 'woocommerce_' . $type . 'fields', $address_fields, $country ); + // Sort each of the fields based on priority. + uasort( $address_fields, 'wc_checkout_fields_uasort_comparison' ); + + return $address_fields; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-coupon.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-coupon.php new file mode 100644 index 0000000..12f6d4c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-coupon.php @@ -0,0 +1,1064 @@ + '', + 'amount' => 0, + 'date_created' => null, + 'date_modified' => null, + 'date_expires' => null, + 'discount_type' => 'fixed_cart', + 'description' => '', + 'usage_count' => 0, + 'individual_use' => false, + 'product_ids' => array(), + 'excluded_product_ids' => array(), + 'usage_limit' => 0, + 'usage_limit_per_user' => 0, + 'limit_usage_to_x_items' => null, + 'free_shipping' => false, + 'product_categories' => array(), + 'excluded_product_categories' => array(), + 'exclude_sale_items' => false, + 'minimum_amount' => '', + 'maximum_amount' => '', + 'email_restrictions' => array(), + 'used_by' => array(), + 'virtual' => false, + ); + + // Coupon message codes. + const E_WC_COUPON_INVALID_FILTERED = 100; + const E_WC_COUPON_INVALID_REMOVED = 101; + const E_WC_COUPON_NOT_YOURS_REMOVED = 102; + const E_WC_COUPON_ALREADY_APPLIED = 103; + const E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY = 104; + const E_WC_COUPON_NOT_EXIST = 105; + const E_WC_COUPON_USAGE_LIMIT_REACHED = 106; + const E_WC_COUPON_EXPIRED = 107; + const E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET = 108; + const E_WC_COUPON_NOT_APPLICABLE = 109; + const E_WC_COUPON_NOT_VALID_SALE_ITEMS = 110; + const E_WC_COUPON_PLEASE_ENTER = 111; + const E_WC_COUPON_MAX_SPEND_LIMIT_MET = 112; + const E_WC_COUPON_EXCLUDED_PRODUCTS = 113; + const E_WC_COUPON_EXCLUDED_CATEGORIES = 114; + const WC_COUPON_SUCCESS = 200; + const WC_COUPON_REMOVED = 201; + + /** + * Cache group. + * + * @var string + */ + protected $cache_group = 'coupons'; + + /** + * Coupon constructor. Loads coupon data. + * + * @param mixed $data Coupon data, object, ID or code. + */ + public function __construct( $data = '' ) { + parent::__construct( $data ); + + // If we already have a coupon object, read it again. + if ( $data instanceof WC_Coupon ) { + $this->set_id( absint( $data->get_id() ) ); + $this->read_object_from_database(); + return; + } + + // This filter allows custom coupon objects to be created on the fly. + $coupon = apply_filters( 'woocommerce_get_shop_coupon_data', false, $data, $this ); + + if ( $coupon ) { + $this->read_manual_coupon( $data, $coupon ); + return; + } + + // Try to load coupon using ID or code. + if ( is_int( $data ) && 'shop_coupon' === get_post_type( $data ) ) { + $this->set_id( $data ); + } elseif ( ! empty( $data ) ) { + $id = wc_get_coupon_id_by_code( $data ); + // Need to support numeric strings for backwards compatibility. + if ( ! $id && 'shop_coupon' === get_post_type( $data ) ) { + $this->set_id( $data ); + } else { + $this->set_id( $id ); + $this->set_code( $data ); + } + } else { + $this->set_object_read( true ); + } + + $this->read_object_from_database(); + } + + /** + * If the object has an ID, read using the data store. + * + * @since 3.4.1 + */ + protected function read_object_from_database() { + $this->data_store = WC_Data_Store::load( 'coupon' ); + + if ( $this->get_id() > 0 ) { + $this->data_store->read( $this ); + } + } + /** + * Checks the coupon type. + * + * @param string $type Array or string of types. + * @return bool + */ + public function is_type( $type ) { + return ( $this->get_discount_type() === $type || ( is_array( $type ) && in_array( $this->get_discount_type(), $type, true ) ) ); + } + + /** + * Prefix for action and filter hooks on data. + * + * @since 3.0.0 + * @return string + */ + protected function get_hook_prefix() { + return 'woocommerce_coupon_get_'; + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + | + | Methods for getting data from the coupon object. + | + */ + + /** + * Get coupon code. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_code( $context = 'view' ) { + return $this->get_prop( 'code', $context ); + } + + /** + * Get coupon description. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_description( $context = 'view' ) { + return $this->get_prop( 'description', $context ); + } + + /** + * Get discount type. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_discount_type( $context = 'view' ) { + return $this->get_prop( 'discount_type', $context ); + } + + /** + * Get coupon amount. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return float + */ + public function get_amount( $context = 'view' ) { + return wc_format_decimal( $this->get_prop( 'amount', $context ) ); + } + + /** + * Get coupon expiration date. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return WC_DateTime|NULL object if the date is set or null if there is no date. + */ + public function get_date_expires( $context = 'view' ) { + return $this->get_prop( 'date_expires', $context ); + } + + /** + * Get date_created + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return WC_DateTime|NULL object if the date is set or null if there is no date. + */ + public function get_date_created( $context = 'view' ) { + return $this->get_prop( 'date_created', $context ); + } + + /** + * Get date_modified + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return WC_DateTime|NULL object if the date is set or null if there is no date. + */ + public function get_date_modified( $context = 'view' ) { + return $this->get_prop( 'date_modified', $context ); + } + + /** + * Get coupon usage count. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return integer + */ + public function get_usage_count( $context = 'view' ) { + return $this->get_prop( 'usage_count', $context ); + } + + /** + * Get the "indvidual use" checkbox status. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return bool + */ + public function get_individual_use( $context = 'view' ) { + return $this->get_prop( 'individual_use', $context ); + } + + /** + * Get product IDs this coupon can apply to. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_product_ids( $context = 'view' ) { + return $this->get_prop( 'product_ids', $context ); + } + + /** + * Get product IDs that this coupon should not apply to. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_excluded_product_ids( $context = 'view' ) { + return $this->get_prop( 'excluded_product_ids', $context ); + } + + /** + * Get coupon usage limit. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return integer + */ + public function get_usage_limit( $context = 'view' ) { + return $this->get_prop( 'usage_limit', $context ); + } + + /** + * Get coupon usage limit per customer (for a single customer) + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return integer + */ + public function get_usage_limit_per_user( $context = 'view' ) { + return $this->get_prop( 'usage_limit_per_user', $context ); + } + + /** + * Usage limited to certain amount of items + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return integer|null + */ + public function get_limit_usage_to_x_items( $context = 'view' ) { + return $this->get_prop( 'limit_usage_to_x_items', $context ); + } + + /** + * If this coupon grants free shipping or not. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return bool + */ + public function get_free_shipping( $context = 'view' ) { + return $this->get_prop( 'free_shipping', $context ); + } + + /** + * Get product categories this coupon can apply to. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_product_categories( $context = 'view' ) { + return $this->get_prop( 'product_categories', $context ); + } + + /** + * Get product categories this coupon cannot not apply to. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_excluded_product_categories( $context = 'view' ) { + return $this->get_prop( 'excluded_product_categories', $context ); + } + + /** + * If this coupon should exclude items on sale. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return bool + */ + public function get_exclude_sale_items( $context = 'view' ) { + return $this->get_prop( 'exclude_sale_items', $context ); + } + + /** + * Get minimum spend amount. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return float + */ + public function get_minimum_amount( $context = 'view' ) { + return $this->get_prop( 'minimum_amount', $context ); + } + /** + * Get maximum spend amount. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return float + */ + public function get_maximum_amount( $context = 'view' ) { + return $this->get_prop( 'maximum_amount', $context ); + } + + /** + * Get emails to check customer usage restrictions. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_email_restrictions( $context = 'view' ) { + return $this->get_prop( 'email_restrictions', $context ); + } + + /** + * Get records of all users who have used the current coupon. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_used_by( $context = 'view' ) { + return $this->get_prop( 'used_by', $context ); + } + + /** + * If the filter is added through the woocommerce_get_shop_coupon_data filter, it's virtual and not in the DB. + * + * @since 3.2.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return boolean + */ + public function get_virtual( $context = 'view' ) { + return (bool) $this->get_prop( 'virtual', $context ); + } + + /** + * Get discount amount for a cart item. + * + * @param float $discounting_amount Amount the coupon is being applied to. + * @param array|null $cart_item Cart item being discounted if applicable. + * @param boolean $single True if discounting a single qty item, false if its the line. + * @return float Amount this coupon has discounted. + */ + public function get_discount_amount( $discounting_amount, $cart_item = null, $single = false ) { + $discount = 0; + $cart_item_qty = is_null( $cart_item ) ? 1 : $cart_item['quantity']; + + if ( $this->is_type( array( 'percent' ) ) ) { + $discount = (float) $this->get_amount() * ( $discounting_amount / 100 ); + } elseif ( $this->is_type( 'fixed_cart' ) && ! is_null( $cart_item ) && WC()->cart->subtotal_ex_tax ) { + /** + * This is the most complex discount - we need to divide the discount between rows based on their price in. + * proportion to the subtotal. This is so rows with different tax rates get a fair discount, and so rows. + * with no price (free) don't get discounted. + * + * Get item discount by dividing item cost by subtotal to get a %. + * + * Uses price inc tax if prices include tax to work around https://github.com/woocommerce/woocommerce/issues/7669 and https://github.com/woocommerce/woocommerce/issues/8074. + */ + if ( wc_prices_include_tax() ) { + $discount_percent = ( wc_get_price_including_tax( $cart_item['data'] ) * $cart_item_qty ) / WC()->cart->subtotal; + } else { + $discount_percent = ( wc_get_price_excluding_tax( $cart_item['data'] ) * $cart_item_qty ) / WC()->cart->subtotal_ex_tax; + } + $discount = ( (float) $this->get_amount() * $discount_percent ) / $cart_item_qty; + + } elseif ( $this->is_type( 'fixed_product' ) ) { + $discount = min( $this->get_amount(), $discounting_amount ); + $discount = $single ? $discount : $discount * $cart_item_qty; + } + + return apply_filters( + 'woocommerce_coupon_get_discount_amount', + NumberUtil::round( min( $discount, $discounting_amount ), wc_get_rounding_precision() ), + $discounting_amount, + $cart_item, + $single, + $this + ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + | + | Functions for setting coupon data. These should not update anything in the + | database itself and should only change what is stored in the class + | object. + | + */ + + /** + * Set coupon code. + * + * @since 3.0.0 + * @param string $code Coupon code. + */ + public function set_code( $code ) { + $this->set_prop( 'code', wc_format_coupon_code( $code ) ); + } + + /** + * Set coupon description. + * + * @since 3.0.0 + * @param string $description Description. + */ + public function set_description( $description ) { + $this->set_prop( 'description', $description ); + } + + /** + * Set discount type. + * + * @since 3.0.0 + * @param string $discount_type Discount type. + */ + public function set_discount_type( $discount_type ) { + if ( 'percent_product' === $discount_type ) { + $discount_type = 'percent'; // Backwards compatibility. + } + if ( ! in_array( $discount_type, array_keys( wc_get_coupon_types() ), true ) ) { + $this->error( 'coupon_invalid_discount_type', __( 'Invalid discount type', 'woocommerce' ) ); + } + $this->set_prop( 'discount_type', $discount_type ); + } + + /** + * Set amount. + * + * @since 3.0.0 + * @param float $amount Amount. + */ + public function set_amount( $amount ) { + $amount = wc_format_decimal( $amount ); + + if ( ! is_numeric( $amount ) ) { + $amount = 0; + } + + if ( $amount < 0 ) { + $this->error( 'coupon_invalid_amount', __( 'Invalid discount amount', 'woocommerce' ) ); + } + + if ( 'percent' === $this->get_discount_type() && $amount > 100 ) { + $this->error( 'coupon_invalid_amount', __( 'Invalid discount amount', 'woocommerce' ) ); + } + + $this->set_prop( 'amount', $amount ); + } + + /** + * Set expiration date. + * + * @since 3.0.0 + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if there is no date. + */ + public function set_date_expires( $date ) { + $this->set_date_prop( 'date_expires', $date ); + } + + /** + * Set date_created + * + * @since 3.0.0 + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if there is no date. + */ + public function set_date_created( $date ) { + $this->set_date_prop( 'date_created', $date ); + } + + /** + * Set date_modified + * + * @since 3.0.0 + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if there is no date. + */ + public function set_date_modified( $date ) { + $this->set_date_prop( 'date_modified', $date ); + } + + /** + * Set how many times this coupon has been used. + * + * @since 3.0.0 + * @param int $usage_count Usage count. + */ + public function set_usage_count( $usage_count ) { + $this->set_prop( 'usage_count', absint( $usage_count ) ); + } + + /** + * Set if this coupon can only be used once. + * + * @since 3.0.0 + * @param bool $is_individual_use If is for individual use. + */ + public function set_individual_use( $is_individual_use ) { + $this->set_prop( 'individual_use', (bool) $is_individual_use ); + } + + /** + * Set the product IDs this coupon can be used with. + * + * @since 3.0.0 + * @param array $product_ids Products IDs. + */ + public function set_product_ids( $product_ids ) { + $this->set_prop( 'product_ids', array_filter( wp_parse_id_list( (array) $product_ids ) ) ); + } + + /** + * Set the product IDs this coupon cannot be used with. + * + * @since 3.0.0 + * @param array $excluded_product_ids Exclude product IDs. + */ + public function set_excluded_product_ids( $excluded_product_ids ) { + $this->set_prop( 'excluded_product_ids', array_filter( wp_parse_id_list( (array) $excluded_product_ids ) ) ); + } + + /** + * Set the amount of times this coupon can be used. + * + * @since 3.0.0 + * @param int $usage_limit Usage limit. + */ + public function set_usage_limit( $usage_limit ) { + $this->set_prop( 'usage_limit', absint( $usage_limit ) ); + } + + /** + * Set the amount of times this coupon can be used per user. + * + * @since 3.0.0 + * @param int $usage_limit Usage limit. + */ + public function set_usage_limit_per_user( $usage_limit ) { + $this->set_prop( 'usage_limit_per_user', absint( $usage_limit ) ); + } + + /** + * Set usage limit to x number of items. + * + * @since 3.0.0 + * @param int|null $limit_usage_to_x_items Limit usage to X items. + */ + public function set_limit_usage_to_x_items( $limit_usage_to_x_items ) { + $this->set_prop( 'limit_usage_to_x_items', is_null( $limit_usage_to_x_items ) ? null : absint( $limit_usage_to_x_items ) ); + } + + /** + * Set if this coupon enables free shipping or not. + * + * @since 3.0.0 + * @param bool $free_shipping If grant free shipping. + */ + public function set_free_shipping( $free_shipping ) { + $this->set_prop( 'free_shipping', (bool) $free_shipping ); + } + + /** + * Set the product category IDs this coupon can be used with. + * + * @since 3.0.0 + * @param array $product_categories List of product categories. + */ + public function set_product_categories( $product_categories ) { + $this->set_prop( 'product_categories', array_filter( wp_parse_id_list( (array) $product_categories ) ) ); + } + + /** + * Set the product category IDs this coupon cannot be used with. + * + * @since 3.0.0 + * @param array $excluded_product_categories List of excluded product categories. + */ + public function set_excluded_product_categories( $excluded_product_categories ) { + $this->set_prop( 'excluded_product_categories', array_filter( wp_parse_id_list( (array) $excluded_product_categories ) ) ); + } + + /** + * Set if this coupon should excluded sale items or not. + * + * @since 3.0.0 + * @param bool $exclude_sale_items If should exclude sale items. + */ + public function set_exclude_sale_items( $exclude_sale_items ) { + $this->set_prop( 'exclude_sale_items', (bool) $exclude_sale_items ); + } + + /** + * Set the minimum spend amount. + * + * @since 3.0.0 + * @param float $amount Minium amount. + */ + public function set_minimum_amount( $amount ) { + $this->set_prop( 'minimum_amount', wc_format_decimal( $amount ) ); + } + + /** + * Set the maximum spend amount. + * + * @since 3.0.0 + * @param float $amount Maximum amount. + */ + public function set_maximum_amount( $amount ) { + $this->set_prop( 'maximum_amount', wc_format_decimal( $amount ) ); + } + + /** + * Set email restrictions. + * + * @since 3.0.0 + * @param array $emails List of emails. + */ + public function set_email_restrictions( $emails = array() ) { + $emails = array_filter( array_map( 'sanitize_email', array_map( 'strtolower', (array) $emails ) ) ); + foreach ( $emails as $email ) { + if ( ! is_email( $email ) ) { + $this->error( 'coupon_invalid_email_address', __( 'Invalid email address restriction', 'woocommerce' ) ); + } + } + $this->set_prop( 'email_restrictions', $emails ); + } + + /** + * Set which users have used this coupon. + * + * @since 3.0.0 + * @param array $used_by List of user IDs. + */ + public function set_used_by( $used_by ) { + $this->set_prop( 'used_by', array_filter( $used_by ) ); + } + + /** + * Set coupon virtual state. + * + * @param boolean $virtual Whether it is virtual or not. + * @since 3.2.0 + */ + public function set_virtual( $virtual ) { + $this->set_prop( 'virtual', (bool) $virtual ); + } + + /* + |-------------------------------------------------------------------------- + | Other Actions + |-------------------------------------------------------------------------- + */ + + /** + * Developers can programmatically return coupons. This function will read those values into our WC_Coupon class. + * + * @since 3.0.0 + * @param string $code Coupon code. + * @param array $coupon Array of coupon properties. + */ + public function read_manual_coupon( $code, $coupon ) { + foreach ( $coupon as $key => $value ) { + switch ( $key ) { + case 'excluded_product_ids': + case 'exclude_product_ids': + if ( ! is_array( $coupon[ $key ] ) ) { + wc_doing_it_wrong( $key, $key . ' should be an array instead of a string.', '3.0' ); + $coupon['excluded_product_ids'] = wc_string_to_array( $value ); + } + break; + case 'exclude_product_categories': + case 'excluded_product_categories': + if ( ! is_array( $coupon[ $key ] ) ) { + wc_doing_it_wrong( $key, $key . ' should be an array instead of a string.', '3.0' ); + $coupon['excluded_product_categories'] = wc_string_to_array( $value ); + } + break; + case 'product_ids': + if ( ! is_array( $coupon[ $key ] ) ) { + wc_doing_it_wrong( $key, $key . ' should be an array instead of a string.', '3.0' ); + $coupon[ $key ] = wc_string_to_array( $value ); + } + break; + case 'individual_use': + case 'free_shipping': + case 'exclude_sale_items': + if ( ! is_bool( $coupon[ $key ] ) ) { + wc_doing_it_wrong( $key, $key . ' should be true or false instead of yes or no.', '3.0' ); + $coupon[ $key ] = wc_string_to_bool( $value ); + } + break; + case 'expiry_date': + $coupon['date_expires'] = $value; + break; + } + } + $this->set_props( $coupon ); + $this->set_code( $code ); + $this->set_id( 0 ); + $this->set_virtual( true ); + } + + /** + * Increase usage count for current coupon. + * + * @param string $used_by Either user ID or billing email. + * @param WC_Order $order If provided, will clear the coupons held by this order. + */ + public function increase_usage_count( $used_by = '', $order = null ) { + if ( $this->get_id() && $this->data_store ) { + $new_count = $this->data_store->increase_usage_count( $this, $used_by, $order ); + + // Bypass set_prop and remove pending changes since the data store saves the count already. + $this->data['usage_count'] = $new_count; + if ( isset( $this->changes['usage_count'] ) ) { + unset( $this->changes['usage_count'] ); + } + } + } + + /** + * Decrease usage count for current coupon. + * + * @param string $used_by Either user ID or billing email. + */ + public function decrease_usage_count( $used_by = '' ) { + if ( $this->get_id() && $this->get_usage_count() > 0 && $this->data_store ) { + $new_count = $this->data_store->decrease_usage_count( $this, $used_by ); + + // Bypass set_prop and remove pending changes since the data store saves the count already. + $this->data['usage_count'] = $new_count; + if ( isset( $this->changes['usage_count'] ) ) { + unset( $this->changes['usage_count'] ); + } + } + } + + /* + |-------------------------------------------------------------------------- + | Validation & Error Handling + |-------------------------------------------------------------------------- + */ + + /** + * Returns the error_message string. + + * @return string + */ + public function get_error_message() { + return $this->error_message; + } + + /** + * Check if a coupon is valid for the cart. + * + * @deprecated 3.2.0 In favor of WC_Discounts->is_coupon_valid. + * @return bool + */ + public function is_valid() { + $discounts = new WC_Discounts( WC()->cart ); + $valid = $discounts->is_coupon_valid( $this ); + + if ( is_wp_error( $valid ) ) { + $this->error_message = $valid->get_error_message(); + return false; + } + + return $valid; + } + + /** + * Check if a coupon is valid. + * + * @return bool + */ + public function is_valid_for_cart() { + return apply_filters( 'woocommerce_coupon_is_valid_for_cart', $this->is_type( wc_get_cart_coupon_types() ), $this ); + } + + /** + * Check if a coupon is valid for a product. + * + * @param WC_Product $product Product instance. + * @param array $values Values. + * @return bool + */ + public function is_valid_for_product( $product, $values = array() ) { + if ( ! $this->is_type( wc_get_product_coupon_types() ) ) { + return apply_filters( 'woocommerce_coupon_is_valid_for_product', false, $product, $this, $values ); + } + + $valid = false; + $product_cats = wc_get_product_cat_ids( $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id() ); + $product_ids = array( $product->get_id(), $product->get_parent_id() ); + + // Specific products get the discount. + if ( count( $this->get_product_ids() ) && count( array_intersect( $product_ids, $this->get_product_ids() ) ) ) { + $valid = true; + } + + // Category discounts. + if ( count( $this->get_product_categories() ) && count( array_intersect( $product_cats, $this->get_product_categories() ) ) ) { + $valid = true; + } + + // No product ids - all items discounted. + if ( ! count( $this->get_product_ids() ) && ! count( $this->get_product_categories() ) ) { + $valid = true; + } + + // Specific product IDs excluded from the discount. + if ( count( $this->get_excluded_product_ids() ) && count( array_intersect( $product_ids, $this->get_excluded_product_ids() ) ) ) { + $valid = false; + } + + // Specific categories excluded from the discount. + if ( count( $this->get_excluded_product_categories() ) && count( array_intersect( $product_cats, $this->get_excluded_product_categories() ) ) ) { + $valid = false; + } + + // Sale Items excluded from discount. + if ( $this->get_exclude_sale_items() && $product->is_on_sale() ) { + $valid = false; + } + + return apply_filters( 'woocommerce_coupon_is_valid_for_product', $valid, $product, $this, $values ); + } + + /** + * Converts one of the WC_Coupon message/error codes to a message string and. + * displays the message/error. + * + * @param int $msg_code Message/error code. + */ + public function add_coupon_message( $msg_code ) { + $msg = $msg_code < 200 ? $this->get_coupon_error( $msg_code ) : $this->get_coupon_message( $msg_code ); + + if ( ! $msg ) { + return; + } + + if ( $msg_code < 200 ) { + wc_add_notice( $msg, 'error' ); + } else { + wc_add_notice( $msg ); + } + } + + /** + * Map one of the WC_Coupon message codes to a message string. + * + * @param integer $msg_code Message code. + * @return string Message/error string. + */ + public function get_coupon_message( $msg_code ) { + switch ( $msg_code ) { + case self::WC_COUPON_SUCCESS: + $msg = __( 'Coupon code applied successfully.', 'woocommerce' ); + break; + case self::WC_COUPON_REMOVED: + $msg = __( 'Coupon code removed successfully.', 'woocommerce' ); + break; + default: + $msg = ''; + break; + } + return apply_filters( 'woocommerce_coupon_message', $msg, $msg_code, $this ); + } + + /** + * Map one of the WC_Coupon error codes to a message string. + * + * @param int $err_code Message/error code. + * @return string Message/error string + */ + public function get_coupon_error( $err_code ) { + switch ( $err_code ) { + case self::E_WC_COUPON_INVALID_FILTERED: + $err = __( 'Coupon is not valid.', 'woocommerce' ); + break; + case self::E_WC_COUPON_NOT_EXIST: + /* translators: %s: coupon code */ + $err = sprintf( __( 'Coupon "%s" does not exist!', 'woocommerce' ), esc_html( $this->get_code() ) ); + break; + case self::E_WC_COUPON_INVALID_REMOVED: + /* translators: %s: coupon code */ + $err = sprintf( __( 'Sorry, it seems the coupon "%s" is invalid - it has now been removed from your order.', 'woocommerce' ), esc_html( $this->get_code() ) ); + break; + case self::E_WC_COUPON_NOT_YOURS_REMOVED: + /* translators: %s: coupon code */ + $err = sprintf( __( 'Sorry, it seems the coupon "%s" is not yours - it has now been removed from your order.', 'woocommerce' ), esc_html( $this->get_code() ) ); + break; + case self::E_WC_COUPON_ALREADY_APPLIED: + $err = __( 'Coupon code already applied!', 'woocommerce' ); + break; + case self::E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY: + /* translators: %s: coupon code */ + $err = sprintf( __( 'Sorry, coupon "%s" has already been applied and cannot be used in conjunction with other coupons.', 'woocommerce' ), esc_html( $this->get_code() ) ); + break; + case self::E_WC_COUPON_USAGE_LIMIT_REACHED: + $err = __( 'Coupon usage limit has been reached.', 'woocommerce' ); + break; + case self::E_WC_COUPON_EXPIRED: + $err = __( 'This coupon has expired.', 'woocommerce' ); + break; + case self::E_WC_COUPON_MIN_SPEND_LIMIT_NOT_MET: + /* translators: %s: coupon minimum amount */ + $err = sprintf( __( 'The minimum spend for this coupon is %s.', 'woocommerce' ), wc_price( $this->get_minimum_amount() ) ); + break; + case self::E_WC_COUPON_MAX_SPEND_LIMIT_MET: + /* translators: %s: coupon maximum amount */ + $err = sprintf( __( 'The maximum spend for this coupon is %s.', 'woocommerce' ), wc_price( $this->get_maximum_amount() ) ); + break; + case self::E_WC_COUPON_NOT_APPLICABLE: + $err = __( 'Sorry, this coupon is not applicable to your cart contents.', 'woocommerce' ); + break; + case self::E_WC_COUPON_EXCLUDED_PRODUCTS: + // Store excluded products that are in cart in $products. + $products = array(); + if ( ! WC()->cart->is_empty() ) { + foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { + if ( in_array( intval( $cart_item['product_id'] ), $this->get_excluded_product_ids(), true ) || in_array( intval( $cart_item['variation_id'] ), $this->get_excluded_product_ids(), true ) || in_array( intval( $cart_item['data']->get_parent_id() ), $this->get_excluded_product_ids(), true ) ) { + $products[] = $cart_item['data']->get_name(); + } + } + } + + /* translators: %s: products list */ + $err = sprintf( __( 'Sorry, this coupon is not applicable to the products: %s.', 'woocommerce' ), implode( ', ', $products ) ); + break; + case self::E_WC_COUPON_EXCLUDED_CATEGORIES: + // Store excluded categories that are in cart in $categories. + $categories = array(); + if ( ! WC()->cart->is_empty() ) { + foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { + $product_cats = wc_get_product_cat_ids( $cart_item['product_id'] ); + $intersect = array_intersect( $product_cats, $this->get_excluded_product_categories() ); + + if ( count( $intersect ) > 0 ) { + foreach ( $intersect as $cat_id ) { + $cat = get_term( $cat_id, 'product_cat' ); + $categories[] = $cat->name; + } + } + } + } + + /* translators: %s: categories list */ + $err = sprintf( __( 'Sorry, this coupon is not applicable to the categories: %s.', 'woocommerce' ), implode( ', ', array_unique( $categories ) ) ); + break; + case self::E_WC_COUPON_NOT_VALID_SALE_ITEMS: + $err = __( 'Sorry, this coupon is not valid for sale items.', 'woocommerce' ); + break; + default: + $err = ''; + break; + } + return apply_filters( 'woocommerce_coupon_error', $err, $err_code, $this ); + } + + /** + * Map one of the WC_Coupon error codes to an error string. + * No coupon instance will be available where a coupon does not exist, + * so this static method exists. + * + * @param int $err_code Error code. + * @return string Error string. + */ + public static function get_generic_coupon_error( $err_code ) { + switch ( $err_code ) { + case self::E_WC_COUPON_NOT_EXIST: + $err = __( 'Coupon does not exist!', 'woocommerce' ); + break; + case self::E_WC_COUPON_PLEASE_ENTER: + $err = __( 'Please enter a coupon code.', 'woocommerce' ); + break; + default: + $err = ''; + break; + } + // When using this static method, there is no $this to pass to filter. + return apply_filters( 'woocommerce_coupon_error', $err, $err_code, null ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-customer-download-log.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-customer-download-log.php new file mode 100644 index 0000000..cec6c05 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-customer-download-log.php @@ -0,0 +1,150 @@ + null, + 'permission_id' => 0, + 'user_id' => null, + 'user_ip_address' => null, + ); + + /** + * Constructor. + * + * @param int|object|array $download_log Download log ID. + */ + public function __construct( $download_log = 0 ) { + parent::__construct( $download_log ); + + if ( is_numeric( $download_log ) && $download_log > 0 ) { + $this->set_id( $download_log ); + } elseif ( $download_log instanceof self ) { + $this->set_id( $download_log->get_id() ); + } elseif ( is_object( $download_log ) && ! empty( $download_log->download_log_id ) ) { + $this->set_id( $download_log->download_log_id ); + $this->set_props( (array) $download_log ); + $this->set_object_read( true ); + } else { + $this->set_object_read( true ); + } + + $this->data_store = WC_Data_Store::load( 'customer-download-log' ); + + if ( $this->get_id() > 0 ) { + $this->data_store->read( $this ); + } + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get timestamp. + * + * @param string $context Get context. + * @return WC_DateTime|null Object if the date is set or null if there is no date. + */ + public function get_timestamp( $context = 'view' ) { + return $this->get_prop( 'timestamp', $context ); + } + + /** + * Get permission id. + * + * @param string $context Get context. + * @return integer + */ + public function get_permission_id( $context = 'view' ) { + return $this->get_prop( 'permission_id', $context ); + } + + /** + * Get user id. + * + * @param string $context Get context. + * @return integer + */ + public function get_user_id( $context = 'view' ) { + return $this->get_prop( 'user_id', $context ); + } + + /** + * Get user ip address. + * + * @param string $context Get context. + * @return string + */ + public function get_user_ip_address( $context = 'view' ) { + return $this->get_prop( 'user_ip_address', $context ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set timestamp. + * + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date. + */ + public function set_timestamp( $date = null ) { + $this->set_date_prop( 'timestamp', $date ); + } + + /** + * Set permission id. + * + * @param int $value Value to set. + */ + public function set_permission_id( $value ) { + $this->set_prop( 'permission_id', absint( $value ) ); + } + + /** + * Set user id. + * + * @param int $value Value to set. + */ + public function set_user_id( $value ) { + $this->set_prop( 'user_id', absint( $value ) ); + } + + /** + * Set user ip address. + * + * @param string $value Value to set. + */ + public function set_user_ip_address( $value ) { + $this->set_prop( 'user_ip_address', $value ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-customer-download.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-customer-download.php new file mode 100644 index 0000000..1e1a6d3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-customer-download.php @@ -0,0 +1,407 @@ + '', + 'product_id' => 0, + 'user_id' => 0, + 'user_email' => '', + 'order_id' => 0, + 'order_key' => '', + 'downloads_remaining' => '', + 'access_granted' => null, + 'access_expires' => null, + 'download_count' => 0, + ); + + /** + * Constructor. + * + * @param int|object|array $download Download ID, instance or data. + */ + public function __construct( $download = 0 ) { + parent::__construct( $download ); + + if ( is_numeric( $download ) && $download > 0 ) { + $this->set_id( $download ); + } elseif ( $download instanceof self ) { + $this->set_id( $download->get_id() ); + } elseif ( is_object( $download ) && ! empty( $download->permission_id ) ) { + $this->set_id( $download->permission_id ); + $this->set_props( (array) $download ); + $this->set_object_read( true ); + } else { + $this->set_object_read( true ); + } + + $this->data_store = WC_Data_Store::load( 'customer-download' ); + + if ( $this->get_id() > 0 ) { + $this->data_store->read( $this ); + } + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get download id. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_download_id( $context = 'view' ) { + return $this->get_prop( 'download_id', $context ); + } + + /** + * Get product id. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return integer + */ + public function get_product_id( $context = 'view' ) { + return $this->get_prop( 'product_id', $context ); + } + + /** + * Get user id. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return integer + */ + public function get_user_id( $context = 'view' ) { + return $this->get_prop( 'user_id', $context ); + } + + /** + * Get user_email. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_user_email( $context = 'view' ) { + return $this->get_prop( 'user_email', $context ); + } + + /** + * Get order_id. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return integer + */ + public function get_order_id( $context = 'view' ) { + return $this->get_prop( 'order_id', $context ); + } + + /** + * Get order_key. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_order_key( $context = 'view' ) { + return $this->get_prop( 'order_key', $context ); + } + + /** + * Get downloads_remaining. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return integer|string + */ + public function get_downloads_remaining( $context = 'view' ) { + return $this->get_prop( 'downloads_remaining', $context ); + } + + /** + * Get access_granted. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return WC_DateTime|null Object if the date is set or null if there is no date. + */ + public function get_access_granted( $context = 'view' ) { + return $this->get_prop( 'access_granted', $context ); + } + + /** + * Get access_expires. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return WC_DateTime|null Object if the date is set or null if there is no date. + */ + public function get_access_expires( $context = 'view' ) { + return $this->get_prop( 'access_expires', $context ); + } + + /** + * Get download_count. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return integer + */ + public function get_download_count( $context = 'view' ) { + // Check for count of download logs. + $data_store = WC_Data_Store::load( 'customer-download-log' ); + $download_log_ids = $data_store->get_download_logs_for_permission( $this->get_id() ); + + $download_log_count = 0; + if ( ! empty( $download_log_ids ) ) { + $download_log_count = count( $download_log_ids ); + } + + // Check download count in prop. + $download_count_prop = $this->get_prop( 'download_count', $context ); + + // Return the larger of the two in case they differ. + // If logs are removed for some reason, we should still respect the + // count stored in the prop. + return max( $download_log_count, $download_count_prop ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set download id. + * + * @param string $value Download ID. + */ + public function set_download_id( $value ) { + $this->set_prop( 'download_id', $value ); + } + /** + * Set product id. + * + * @param int $value Product ID. + */ + public function set_product_id( $value ) { + $this->set_prop( 'product_id', absint( $value ) ); + } + + /** + * Set user id. + * + * @param int $value User ID. + */ + public function set_user_id( $value ) { + $this->set_prop( 'user_id', absint( $value ) ); + } + + /** + * Set user_email. + * + * @param int $value User email. + */ + public function set_user_email( $value ) { + $this->set_prop( 'user_email', sanitize_email( $value ) ); + } + + /** + * Set order_id. + * + * @param int $value Order ID. + */ + public function set_order_id( $value ) { + $this->set_prop( 'order_id', absint( $value ) ); + } + + /** + * Set order_key. + * + * @param string $value Order key. + */ + public function set_order_key( $value ) { + $this->set_prop( 'order_key', $value ); + } + + /** + * Set downloads_remaining. + * + * @param integer|string $value Amount of downloads remaining. + */ + public function set_downloads_remaining( $value ) { + $this->set_prop( 'downloads_remaining', '' === $value ? '' : absint( $value ) ); + } + + /** + * Set access_granted. + * + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date. + */ + public function set_access_granted( $date = null ) { + $this->set_date_prop( 'access_granted', $date ); + } + + /** + * Set access_expires. + * + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date. + */ + public function set_access_expires( $date = null ) { + $this->set_date_prop( 'access_expires', $date ); + } + + /** + * Set download_count. + * + * @param int $value Download count. + */ + public function set_download_count( $value ) { + $this->set_prop( 'download_count', absint( $value ) ); + } + + /** + * Track a download on this permission. + * + * @since 3.3.0 + * @throws Exception When permission ID is invalid. + * @param int $user_id Id of the user performing the download. + * @param string $user_ip_address IP Address of the user performing the download. + */ + public function track_download( $user_id = null, $user_ip_address = null ) { + global $wpdb; + + // Must have a permission_id to track download log. + if ( ! ( $this->get_id() > 0 ) ) { + throw new Exception( __( 'Invalid permission ID.', 'woocommerce' ) ); + } + + // Increment download count, and decrement downloads remaining. + // Use SQL to avoid possible issues with downloads in quick succession. + // If downloads_remaining is blank, leave it blank (unlimited). + // Also, ensure downloads_remaining doesn't drop below zero. + $query = $wpdb->prepare( + " +UPDATE {$wpdb->prefix}woocommerce_downloadable_product_permissions +SET download_count = download_count + 1, +downloads_remaining = IF( downloads_remaining = '', '', GREATEST( 0, downloads_remaining - 1 ) ) +WHERE permission_id = %d", + $this->get_id() + ); + $wpdb->query( $query ); // WPCS: unprepared SQL ok. + + // Re-read this download from the data store to pull updated counts. + $this->data_store->read( $this ); + + // Track download in download log. + $download_log = new WC_Customer_Download_Log(); + $download_log->set_timestamp( current_time( 'timestamp', true ) ); + $download_log->set_permission_id( $this->get_id() ); + + if ( ! is_null( $user_id ) ) { + $download_log->set_user_id( $user_id ); + } + + if ( ! is_null( $user_ip_address ) ) { + $download_log->set_user_ip_address( $user_ip_address ); + } + + $download_log->save(); + } + + /* + |-------------------------------------------------------------------------- + | ArrayAccess/Backwards compatibility. + |-------------------------------------------------------------------------- + */ + + /** + * OffsetGet. + * + * @param string $offset Offset. + * @return mixed + */ + public function offsetGet( $offset ) { + if ( is_callable( array( $this, "get_$offset" ) ) ) { + return $this->{"get_$offset"}(); + } + } + + /** + * OffsetSet. + * + * @param string $offset Offset. + * @param mixed $value Value. + */ + public function offsetSet( $offset, $value ) { + if ( is_callable( array( $this, "set_$offset" ) ) ) { + $this->{"set_$offset"}( $value ); + } + } + + /** + * OffsetUnset + * + * @param string $offset Offset. + */ + public function offsetUnset( $offset ) { + if ( is_callable( array( $this, "set_$offset" ) ) ) { + $this->{"set_$offset"}( '' ); + } + } + + /** + * OffsetExists. + * + * @param string $offset Offset. + * @return bool + */ + public function offsetExists( $offset ) { + return in_array( $offset, array_keys( $this->data ), true ); + } + + /** + * Magic __isset method for backwards compatibility. Legacy properties which could be accessed directly in the past. + * + * @param string $key Key name. + * @return bool + */ + public function __isset( $key ) { + return in_array( $key, array_keys( $this->data ), true ); + } + + /** + * Magic __get method for backwards compatibility. Maps legacy vars to new getters. + * + * @param string $key Key name. + * @return mixed + */ + public function __get( $key ) { + if ( is_callable( array( $this, "get_$key" ) ) ) { + return $this->{"get_$key"}( '' ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-customer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-customer.php new file mode 100644 index 0000000..641ee9b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-customer.php @@ -0,0 +1,1084 @@ + null, + 'date_modified' => null, + 'email' => '', + 'first_name' => '', + 'last_name' => '', + 'display_name' => '', + 'role' => 'customer', + 'username' => '', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'postcode' => '', + 'country' => '', + 'state' => '', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'postcode' => '', + 'country' => '', + 'state' => '', + ), + 'is_paying_customer' => false, + ); + + /** + * Stores a password if this needs to be changed. Write-only and hidden from _data. + * + * @var string + */ + protected $password = ''; + + /** + * Stores if user is VAT exempt for this session. + * + * @var string + */ + protected $is_vat_exempt = false; + + /** + * Stores if user has calculated shipping in this session. + * + * @var string + */ + protected $calculated_shipping = false; + + /** + * Load customer data based on how WC_Customer is called. + * + * If $customer is 'new', you can build a new WC_Customer object. If it's empty, some + * data will be pulled from the session for the current user/customer. + * + * @param WC_Customer|int $data Customer ID or data. + * @param bool $is_session True if this is the customer session. + * @throws Exception If customer cannot be read/found and $data is set. + */ + public function __construct( $data = 0, $is_session = false ) { + parent::__construct( $data ); + + if ( $data instanceof WC_Customer ) { + $this->set_id( absint( $data->get_id() ) ); + } elseif ( is_numeric( $data ) ) { + $this->set_id( $data ); + } + + $this->data_store = WC_Data_Store::load( 'customer' ); + + // If we have an ID, load the user from the DB. + if ( $this->get_id() ) { + try { + $this->data_store->read( $this ); + } catch ( Exception $e ) { + $this->set_id( 0 ); + $this->set_object_read( true ); + } + } else { + $this->set_object_read( true ); + } + + // If this is a session, set or change the data store to sessions. Changes do not persist in the database. + if ( $is_session ) { + $this->data_store = WC_Data_Store::load( 'customer-session' ); + $this->data_store->read( $this ); + } + } + + /** + * Prefix for action and filter hooks on data. + * + * @since 3.0.0 + * @return string + */ + protected function get_hook_prefix() { + return 'woocommerce_customer_get_'; + } + + /** + * Delete a customer and reassign posts.. + * + * @param int $reassign Reassign posts and links to new User ID. + * @since 3.0.0 + * @return bool + */ + public function delete_and_reassign( $reassign = null ) { + if ( $this->data_store ) { + $this->data_store->delete( + $this, + array( + 'force_delete' => true, + 'reassign' => $reassign, + ) + ); + $this->set_id( 0 ); + return true; + } + return false; + } + + /** + * Is customer outside base country (for tax purposes)? + * + * @return bool + */ + public function is_customer_outside_base() { + list( $country, $state ) = $this->get_taxable_address(); + if ( $country ) { + $default = wc_get_base_location(); + if ( $default['country'] !== $country ) { + return true; + } + if ( $default['state'] && $default['state'] !== $state ) { + return true; + } + } + return false; + } + + /** + * Return this customer's avatar. + * + * @since 3.0.0 + * @return string + */ + public function get_avatar_url() { + return get_avatar_url( $this->get_email() ); + } + + /** + * Get taxable address. + * + * @return array + */ + public function get_taxable_address() { + $tax_based_on = get_option( 'woocommerce_tax_based_on' ); + + // Check shipping method at this point to see if we need special handling. + if ( true === apply_filters( 'woocommerce_apply_base_tax_for_local_pickup', true ) && count( array_intersect( wc_get_chosen_shipping_method_ids(), apply_filters( 'woocommerce_local_pickup_methods', array( 'legacy_local_pickup', 'local_pickup' ) ) ) ) > 0 ) { + $tax_based_on = 'base'; + } + + if ( 'base' === $tax_based_on ) { + $country = WC()->countries->get_base_country(); + $state = WC()->countries->get_base_state(); + $postcode = WC()->countries->get_base_postcode(); + $city = WC()->countries->get_base_city(); + } elseif ( 'billing' === $tax_based_on ) { + $country = $this->get_billing_country(); + $state = $this->get_billing_state(); + $postcode = $this->get_billing_postcode(); + $city = $this->get_billing_city(); + } else { + $country = $this->get_shipping_country(); + $state = $this->get_shipping_state(); + $postcode = $this->get_shipping_postcode(); + $city = $this->get_shipping_city(); + } + + return apply_filters( 'woocommerce_customer_taxable_address', array( $country, $state, $postcode, $city ) ); + } + + /** + * Gets a customer's downloadable products. + * + * @return array Array of downloadable products + */ + public function get_downloadable_products() { + $downloads = array(); + if ( $this->get_id() ) { + $downloads = wc_get_customer_available_downloads( $this->get_id() ); + } + return apply_filters( 'woocommerce_customer_get_downloadable_products', $downloads ); + } + + /** + * Is customer VAT exempt? + * + * @return bool + */ + public function is_vat_exempt() { + return $this->get_is_vat_exempt(); + } + + /** + * Has calculated shipping? + * + * @return bool + */ + public function has_calculated_shipping() { + return $this->get_calculated_shipping(); + } + + /** + * Get if customer is VAT exempt? + * + * @since 3.0.0 + * @return bool + */ + public function get_is_vat_exempt() { + return $this->is_vat_exempt; + } + + /** + * Get password (only used when updating the user object). + * + * @return string + */ + public function get_password() { + return $this->password; + } + + /** + * Has customer calculated shipping? + * + * @return bool + */ + public function get_calculated_shipping() { + return $this->calculated_shipping; + } + + /** + * Set if customer has tax exemption. + * + * @param bool $is_vat_exempt If is vat exempt. + */ + public function set_is_vat_exempt( $is_vat_exempt ) { + $this->is_vat_exempt = wc_string_to_bool( $is_vat_exempt ); + } + + /** + * Calculated shipping? + * + * @param bool $calculated If shipping is calculated. + */ + public function set_calculated_shipping( $calculated = true ) { + $this->calculated_shipping = wc_string_to_bool( $calculated ); + } + + /** + * Set customer's password. + * + * @since 3.0.0 + * @param string $password Password. + */ + public function set_password( $password ) { + $this->password = $password; + } + + /** + * Gets the customers last order. + * + * @return WC_Order|false + */ + public function get_last_order() { + return $this->data_store->get_last_order( $this ); + } + + /** + * Return the number of orders this customer has. + * + * @return integer + */ + public function get_order_count() { + return $this->data_store->get_order_count( $this ); + } + + /** + * Return how much money this customer has spent. + * + * @return float + */ + public function get_total_spent() { + return $this->data_store->get_total_spent( $this ); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Return the customer's username. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_username( $context = 'view' ) { + return $this->get_prop( 'username', $context ); + } + + /** + * Return the customer's email. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_email( $context = 'view' ) { + return $this->get_prop( 'email', $context ); + } + + /** + * Return customer's first name. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_first_name( $context = 'view' ) { + return $this->get_prop( 'first_name', $context ); + } + + /** + * Return customer's last name. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_last_name( $context = 'view' ) { + return $this->get_prop( 'last_name', $context ); + } + + /** + * Return customer's display name. + * + * @since 3.1.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_display_name( $context = 'view' ) { + return $this->get_prop( 'display_name', $context ); + } + + /** + * Return customer's user role. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_role( $context = 'view' ) { + return $this->get_prop( 'role', $context ); + } + + /** + * Return the date this customer was created. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return WC_DateTime|null object if the date is set or null if there is no date. + */ + public function get_date_created( $context = 'view' ) { + return $this->get_prop( 'date_created', $context ); + } + + /** + * Return the date this customer was last updated. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return WC_DateTime|null object if the date is set or null if there is no date. + */ + public function get_date_modified( $context = 'view' ) { + return $this->get_prop( 'date_modified', $context ); + } + + /** + * Gets a prop for a getter method. + * + * @since 3.0.0 + * @param string $prop Name of prop to get. + * @param string $address billing or shipping. + * @param string $context What the value is for. Valid values are 'view' and 'edit'. What the value is for. Valid values are view and edit. + * @return mixed + */ + protected function get_address_prop( $prop, $address = 'billing', $context = 'view' ) { + $value = null; + + if ( array_key_exists( $prop, $this->data[ $address ] ) ) { + $value = isset( $this->changes[ $address ][ $prop ] ) ? $this->changes[ $address ][ $prop ] : $this->data[ $address ][ $prop ]; + + if ( 'view' === $context ) { + $value = apply_filters( $this->get_hook_prefix() . $address . '_' . $prop, $value, $this ); + } + } + return $value; + } + + /** + * Get billing. + * + * @since 3.2.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_billing( $context = 'view' ) { + return $this->get_prop( 'billing', $context ); + } + + /** + * Get billing_first_name. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_first_name( $context = 'view' ) { + return $this->get_address_prop( 'first_name', 'billing', $context ); + } + + /** + * Get billing_last_name. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_last_name( $context = 'view' ) { + return $this->get_address_prop( 'last_name', 'billing', $context ); + } + + /** + * Get billing_company. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_company( $context = 'view' ) { + return $this->get_address_prop( 'company', 'billing', $context ); + } + + /** + * Get billing_address_1. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_address( $context = 'view' ) { + return $this->get_billing_address_1( $context ); + } + + /** + * Get billing_address_1. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_address_1( $context = 'view' ) { + return $this->get_address_prop( 'address_1', 'billing', $context ); + } + + /** + * Get billing_address_2. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string $value + */ + public function get_billing_address_2( $context = 'view' ) { + return $this->get_address_prop( 'address_2', 'billing', $context ); + } + + /** + * Get billing_city. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string $value + */ + public function get_billing_city( $context = 'view' ) { + return $this->get_address_prop( 'city', 'billing', $context ); + } + + /** + * Get billing_state. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_state( $context = 'view' ) { + return $this->get_address_prop( 'state', 'billing', $context ); + } + + /** + * Get billing_postcode. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_postcode( $context = 'view' ) { + return $this->get_address_prop( 'postcode', 'billing', $context ); + } + + /** + * Get billing_country. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_country( $context = 'view' ) { + return $this->get_address_prop( 'country', 'billing', $context ); + } + + /** + * Get billing_email. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_email( $context = 'view' ) { + return $this->get_address_prop( 'email', 'billing', $context ); + } + + /** + * Get billing_phone. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_billing_phone( $context = 'view' ) { + return $this->get_address_prop( 'phone', 'billing', $context ); + } + + /** + * Get shipping. + * + * @since 3.2.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_shipping( $context = 'view' ) { + return $this->get_prop( 'shipping', $context ); + } + + /** + * Get shipping_first_name. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_first_name( $context = 'view' ) { + return $this->get_address_prop( 'first_name', 'shipping', $context ); + } + + /** + * Get shipping_last_name. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_last_name( $context = 'view' ) { + return $this->get_address_prop( 'last_name', 'shipping', $context ); + } + + /** + * Get shipping_company. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_company( $context = 'view' ) { + return $this->get_address_prop( 'company', 'shipping', $context ); + } + + /** + * Get shipping_address_1. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_address( $context = 'view' ) { + return $this->get_shipping_address_1( $context ); + } + + /** + * Get shipping_address_1. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_address_1( $context = 'view' ) { + return $this->get_address_prop( 'address_1', 'shipping', $context ); + } + + /** + * Get shipping_address_2. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_address_2( $context = 'view' ) { + return $this->get_address_prop( 'address_2', 'shipping', $context ); + } + + /** + * Get shipping_city. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_city( $context = 'view' ) { + return $this->get_address_prop( 'city', 'shipping', $context ); + } + + /** + * Get shipping_state. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_state( $context = 'view' ) { + return $this->get_address_prop( 'state', 'shipping', $context ); + } + + /** + * Get shipping_postcode. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_postcode( $context = 'view' ) { + return $this->get_address_prop( 'postcode', 'shipping', $context ); + } + + /** + * Get shipping_country. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_country( $context = 'view' ) { + return $this->get_address_prop( 'country', 'shipping', $context ); + } + + /** + * Is the user a paying customer? + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return bool + */ + public function get_is_paying_customer( $context = 'view' ) { + return $this->get_prop( 'is_paying_customer', $context ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set customer's username. + * + * @since 3.0.0 + * @param string $username Username. + */ + public function set_username( $username ) { + $this->set_prop( 'username', $username ); + } + + /** + * Set customer's email. + * + * @since 3.0.0 + * @param string $value Email. + */ + public function set_email( $value ) { + if ( $value && ! is_email( $value ) ) { + $this->error( 'customer_invalid_email', __( 'Invalid email address', 'woocommerce' ) ); + } + $this->set_prop( 'email', sanitize_email( $value ) ); + } + + /** + * Set customer's first name. + * + * @since 3.0.0 + * @param string $first_name First name. + */ + public function set_first_name( $first_name ) { + $this->set_prop( 'first_name', $first_name ); + } + + /** + * Set customer's last name. + * + * @since 3.0.0 + * @param string $last_name Last name. + */ + public function set_last_name( $last_name ) { + $this->set_prop( 'last_name', $last_name ); + } + + /** + * Set customer's display name. + * + * @since 3.1.0 + * @param string $display_name Display name. + */ + public function set_display_name( $display_name ) { + /* translators: 1: first name 2: last name */ + $this->set_prop( 'display_name', is_email( $display_name ) ? sprintf( _x( '%1$s %2$s', 'display name', 'woocommerce' ), $this->get_first_name(), $this->get_last_name() ) : $display_name ); + } + + /** + * Set customer's user role(s). + * + * @since 3.0.0 + * @param mixed $role User role. + */ + public function set_role( $role ) { + global $wp_roles; + + if ( $role && ! empty( $wp_roles->roles ) && ! in_array( $role, array_keys( $wp_roles->roles ), true ) ) { + $this->error( 'customer_invalid_role', __( 'Invalid role', 'woocommerce' ) ); + } + $this->set_prop( 'role', $role ); + } + + /** + * Set the date this customer was last updated. + * + * @since 3.0.0 + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date. + */ + public function set_date_created( $date = null ) { + $this->set_date_prop( 'date_created', $date ); + } + + /** + * Set the date this customer was last updated. + * + * @since 3.0.0 + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date. + */ + public function set_date_modified( $date = null ) { + $this->set_date_prop( 'date_modified', $date ); + } + + /** + * Set customer address to match shop base address. + * + * @since 3.0.0 + */ + public function set_billing_address_to_base() { + $base = wc_get_customer_default_location(); + $this->set_billing_location( $base['country'], $base['state'], '', '' ); + } + + /** + * Set customer shipping address to base address. + * + * @since 3.0.0 + */ + public function set_shipping_address_to_base() { + $base = wc_get_customer_default_location(); + $this->set_shipping_location( $base['country'], $base['state'], '', '' ); + } + + /** + * Sets all address info at once. + * + * @param string $country Country. + * @param string $state State. + * @param string $postcode Postcode. + * @param string $city City. + */ + public function set_billing_location( $country, $state = '', $postcode = '', $city = '' ) { + $address_data = $this->get_prop( 'billing', 'edit' ); + + $address_data['address_1'] = ''; + $address_data['address_2'] = ''; + $address_data['city'] = $city; + $address_data['state'] = $state; + $address_data['postcode'] = $postcode; + $address_data['country'] = $country; + + $this->set_prop( 'billing', $address_data ); + } + + /** + * Sets all shipping info at once. + * + * @param string $country Country. + * @param string $state State. + * @param string $postcode Postcode. + * @param string $city City. + */ + public function set_shipping_location( $country, $state = '', $postcode = '', $city = '' ) { + $address_data = $this->get_prop( 'shipping', 'edit' ); + + $address_data['address_1'] = ''; + $address_data['address_2'] = ''; + $address_data['city'] = $city; + $address_data['state'] = $state; + $address_data['postcode'] = $postcode; + $address_data['country'] = $country; + + $this->set_prop( 'shipping', $address_data ); + } + + /** + * Sets a prop for a setter method. + * + * @since 3.0.0 + * @param string $prop Name of prop to set. + * @param string $address Name of address to set. billing or shipping. + * @param mixed $value Value of the prop. + */ + protected function set_address_prop( $prop, $address, $value ) { + if ( array_key_exists( $prop, $this->data[ $address ] ) ) { + if ( true === $this->object_read ) { + if ( $value !== $this->data[ $address ][ $prop ] || ( isset( $this->changes[ $address ] ) && array_key_exists( $prop, $this->changes[ $address ] ) ) ) { + $this->changes[ $address ][ $prop ] = $value; + } + } else { + $this->data[ $address ][ $prop ] = $value; + } + } + } + + /** + * Set billing_first_name. + * + * @param string $value Billing first name. + */ + public function set_billing_first_name( $value ) { + $this->set_address_prop( 'first_name', 'billing', $value ); + } + + /** + * Set billing_last_name. + * + * @param string $value Billing last name. + */ + public function set_billing_last_name( $value ) { + $this->set_address_prop( 'last_name', 'billing', $value ); + } + + /** + * Set billing_company. + * + * @param string $value Billing company. + */ + public function set_billing_company( $value ) { + $this->set_address_prop( 'company', 'billing', $value ); + } + + /** + * Set billing_address_1. + * + * @param string $value Billing address line 1. + */ + public function set_billing_address( $value ) { + $this->set_billing_address_1( $value ); + } + + /** + * Set billing_address_1. + * + * @param string $value Billing address line 1. + */ + public function set_billing_address_1( $value ) { + $this->set_address_prop( 'address_1', 'billing', $value ); + } + + /** + * Set billing_address_2. + * + * @param string $value Billing address line 2. + */ + public function set_billing_address_2( $value ) { + $this->set_address_prop( 'address_2', 'billing', $value ); + } + + /** + * Set billing_city. + * + * @param string $value Billing city. + */ + public function set_billing_city( $value ) { + $this->set_address_prop( 'city', 'billing', $value ); + } + + /** + * Set billing_state. + * + * @param string $value Billing state. + */ + public function set_billing_state( $value ) { + $this->set_address_prop( 'state', 'billing', $value ); + } + + /** + * Set billing_postcode. + * + * @param string $value Billing postcode. + */ + public function set_billing_postcode( $value ) { + $this->set_address_prop( 'postcode', 'billing', $value ); + } + + /** + * Set billing_country. + * + * @param string $value Billing country. + */ + public function set_billing_country( $value ) { + $this->set_address_prop( 'country', 'billing', $value ); + } + + /** + * Set billing_email. + * + * @param string $value Billing email. + */ + public function set_billing_email( $value ) { + if ( $value && ! is_email( $value ) ) { + $this->error( 'customer_invalid_billing_email', __( 'Invalid billing email address', 'woocommerce' ) ); + } + $this->set_address_prop( 'email', 'billing', sanitize_email( $value ) ); + } + + /** + * Set billing_phone. + * + * @param string $value Billing phone. + */ + public function set_billing_phone( $value ) { + $this->set_address_prop( 'phone', 'billing', $value ); + } + + /** + * Set shipping_first_name. + * + * @param string $value Shipping first name. + */ + public function set_shipping_first_name( $value ) { + $this->set_address_prop( 'first_name', 'shipping', $value ); + } + + /** + * Set shipping_last_name. + * + * @param string $value Shipping last name. + */ + public function set_shipping_last_name( $value ) { + $this->set_address_prop( 'last_name', 'shipping', $value ); + } + + /** + * Set shipping_company. + * + * @param string $value Shipping company. + */ + public function set_shipping_company( $value ) { + $this->set_address_prop( 'company', 'shipping', $value ); + } + + /** + * Set shipping_address_1. + * + * @param string $value Shipping address line 1. + */ + public function set_shipping_address( $value ) { + $this->set_shipping_address_1( $value ); + } + + /** + * Set shipping_address_1. + * + * @param string $value Shipping address line 1. + */ + public function set_shipping_address_1( $value ) { + $this->set_address_prop( 'address_1', 'shipping', $value ); + } + + /** + * Set shipping_address_2. + * + * @param string $value Shipping address line 2. + */ + public function set_shipping_address_2( $value ) { + $this->set_address_prop( 'address_2', 'shipping', $value ); + } + + /** + * Set shipping_city. + * + * @param string $value Shipping city. + */ + public function set_shipping_city( $value ) { + $this->set_address_prop( 'city', 'shipping', $value ); + } + + /** + * Set shipping_state. + * + * @param string $value Shipping state. + */ + public function set_shipping_state( $value ) { + $this->set_address_prop( 'state', 'shipping', $value ); + } + + /** + * Set shipping_postcode. + * + * @param string $value Shipping postcode. + */ + public function set_shipping_postcode( $value ) { + $this->set_address_prop( 'postcode', 'shipping', $value ); + } + + /** + * Set shipping_country. + * + * @param string $value Shipping country. + */ + public function set_shipping_country( $value ) { + $this->set_address_prop( 'country', 'shipping', $value ); + } + + /** + * Set if the user a paying customer. + * + * @since 3.0.0 + * @param bool $is_paying_customer If is a paying customer. + */ + public function set_is_paying_customer( $is_paying_customer ) { + $this->set_prop( 'is_paying_customer', (bool) $is_paying_customer ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-data-exception.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-data-exception.php new file mode 100644 index 0000000..0b29c49 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-data-exception.php @@ -0,0 +1,64 @@ +error_code = $code; + $this->error_data = array_merge( array( 'status' => $http_status_code ), $data ); + + parent::__construct( $message, $http_status_code ); + } + + /** + * Returns the error code. + * + * @return string + */ + public function getErrorCode() { + return $this->error_code; + } + + /** + * Returns error data. + * + * @return array + */ + public function getErrorData() { + return $this->error_data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-data-store.php new file mode 100644 index 0000000..f6723b1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-data-store.php @@ -0,0 +1,210 @@ + class name. + * Example: 'product' => 'WC_Product_Data_Store_CPT' + * You can also pass something like product_ for product stores and + * that type will be used first when available, if a store is requested like + * this and doesn't exist, then the store would fall back to 'product'. + * Ran through `woocommerce_data_stores`. + * + * @var array + */ + private $stores = array( + 'coupon' => 'WC_Coupon_Data_Store_CPT', + 'customer' => 'WC_Customer_Data_Store', + 'customer-download' => 'WC_Customer_Download_Data_Store', + 'customer-download-log' => 'WC_Customer_Download_Log_Data_Store', + 'customer-session' => 'WC_Customer_Data_Store_Session', + 'order' => 'WC_Order_Data_Store_CPT', + 'order-refund' => 'WC_Order_Refund_Data_Store_CPT', + 'order-item' => 'WC_Order_Item_Data_Store', + 'order-item-coupon' => 'WC_Order_Item_Coupon_Data_Store', + 'order-item-fee' => 'WC_Order_Item_Fee_Data_Store', + 'order-item-product' => 'WC_Order_Item_Product_Data_Store', + 'order-item-shipping' => 'WC_Order_Item_Shipping_Data_Store', + 'order-item-tax' => 'WC_Order_Item_Tax_Data_Store', + 'payment-token' => 'WC_Payment_Token_Data_Store', + 'product' => 'WC_Product_Data_Store_CPT', + 'product-grouped' => 'WC_Product_Grouped_Data_Store_CPT', + 'product-variable' => 'WC_Product_Variable_Data_Store_CPT', + 'product-variation' => 'WC_Product_Variation_Data_Store_CPT', + 'shipping-zone' => 'WC_Shipping_Zone_Data_Store', + 'webhook' => 'WC_Webhook_Data_Store', + ); + + /** + * Contains the name of the current data store's class name. + * + * @var string + */ + private $current_class_name = ''; + + /** + * The object type this store works with. + * + * @var string + */ + private $object_type = ''; + + + /** + * Tells WC_Data_Store which object (coupon, product, order, etc) + * store we want to work with. + * + * @throws Exception When validation fails. + * @param string $object_type Name of object. + */ + public function __construct( $object_type ) { + $this->object_type = $object_type; + $this->stores = apply_filters( 'woocommerce_data_stores', $this->stores ); + + // If this object type can't be found, check to see if we can load one + // level up (so if product-type isn't found, we try product). + if ( ! array_key_exists( $object_type, $this->stores ) ) { + $pieces = explode( '-', $object_type ); + $object_type = $pieces[0]; + } + + if ( array_key_exists( $object_type, $this->stores ) ) { + $store = apply_filters( 'woocommerce_' . $object_type . '_data_store', $this->stores[ $object_type ] ); + if ( is_object( $store ) ) { + if ( ! $store instanceof WC_Object_Data_Store_Interface ) { + throw new Exception( __( 'Invalid data store.', 'woocommerce' ) ); + } + $this->current_class_name = get_class( $store ); + $this->instance = $store; + } else { + if ( ! class_exists( $store ) ) { + throw new Exception( __( 'Invalid data store.', 'woocommerce' ) ); + } + $this->current_class_name = $store; + $this->instance = new $store(); + } + } else { + throw new Exception( __( 'Invalid data store.', 'woocommerce' ) ); + } + } + + /** + * Only store the object type to avoid serializing the data store instance. + * + * @return array + */ + public function __sleep() { + return array( 'object_type' ); + } + + /** + * Re-run the constructor with the object type. + * + * @throws Exception When validation fails. + */ + public function __wakeup() { + $this->__construct( $this->object_type ); + } + + /** + * Loads a data store. + * + * @param string $object_type Name of object. + * + * @since 3.0.0 + * @throws Exception When validation fails. + * @return WC_Data_Store + */ + public static function load( $object_type ) { + return new WC_Data_Store( $object_type ); + } + + /** + * Returns the class name of the current data store. + * + * @since 3.0.0 + * @return string + */ + public function get_current_class_name() { + return $this->current_class_name; + } + + /** + * Reads an object from the data store. + * + * @since 3.0.0 + * @param WC_Data $data WooCommerce data instance. + */ + public function read( &$data ) { + $this->instance->read( $data ); + } + + /** + * Create an object in the data store. + * + * @since 3.0.0 + * @param WC_Data $data WooCommerce data instance. + */ + public function create( &$data ) { + $this->instance->create( $data ); + } + + /** + * Update an object in the data store. + * + * @since 3.0.0 + * @param WC_Data $data WooCommerce data instance. + */ + public function update( &$data ) { + $this->instance->update( $data ); + } + + /** + * Delete an object from the data store. + * + * @since 3.0.0 + * @param WC_Data $data WooCommerce data instance. + * @param array $args Array of args to pass to the delete method. + */ + public function delete( &$data, $args = array() ) { + $this->instance->delete( $data, $args ); + } + + /** + * Data stores can define additional functions (for example, coupons have + * some helper methods for increasing or decreasing usage). This passes + * through to the instance if that function exists. + * + * @since 3.0.0 + * @param string $method Method. + * @param mixed $parameters Parameters. + * @return mixed + */ + public function __call( $method, $parameters ) { + if ( is_callable( array( $this->instance, $method ) ) ) { + $object = array_shift( $parameters ); + $parameters = array_merge( array( &$object ), $parameters ); + return $this->instance->$method( ...$parameters ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-datetime.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-datetime.php new file mode 100644 index 0000000..1778503 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-datetime.php @@ -0,0 +1,103 @@ +format( DATE_ATOM ); + } + + /** + * Set UTC offset - this is a fixed offset instead of a timezone. + * + * @param int $offset Offset. + */ + public function set_utc_offset( $offset ) { + $this->utc_offset = intval( $offset ); + } + + /** + * Get UTC offset if set, or default to the DateTime object's offset. + */ + public function getOffset() { + return $this->utc_offset ? $this->utc_offset : parent::getOffset(); + } + + /** + * Set timezone. + * + * @param DateTimeZone $timezone DateTimeZone instance. + * @return DateTime + */ + public function setTimezone( $timezone ) { + $this->utc_offset = 0; + return parent::setTimezone( $timezone ); + } + + /** + * Missing in PHP 5.2 so just here so it can be supported consistently. + * + * @since 3.0.0 + * @return int + */ + public function getTimestamp() { + return method_exists( 'DateTime', 'getTimestamp' ) ? parent::getTimestamp() : $this->format( 'U' ); + } + + /** + * Get the timestamp with the WordPress timezone offset added or subtracted. + * + * @since 3.0.0 + * @return int + */ + public function getOffsetTimestamp() { + return $this->getTimestamp() + $this->getOffset(); + } + + /** + * Format a date based on the offset timestamp. + * + * @since 3.0.0 + * @param string $format Date format. + * @return string + */ + public function date( $format ) { + return gmdate( $format, $this->getOffsetTimestamp() ); + } + + /** + * Return a localised date based on offset timestamp. Wrapper for date_i18n function. + * + * @since 3.0.0 + * @param string $format Date format. + * @return string + */ + public function date_i18n( $format = 'Y-m-d' ) { + return date_i18n( $format, $this->getOffsetTimestamp() ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-deprecated-action-hooks.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-deprecated-action-hooks.php new file mode 100644 index 0000000..39bc932 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-deprecated-action-hooks.php @@ -0,0 +1,191 @@ + 'old'. + * + * @var array + */ + protected $deprecated_hooks = array( + 'woocommerce_new_order_item' => array( + 'woocommerce_order_add_shipping', + 'woocommerce_order_add_coupon', + 'woocommerce_order_add_tax', + 'woocommerce_order_add_fee', + 'woocommerce_add_shipping_order_item', + 'woocommerce_add_order_item_meta', + 'woocommerce_add_order_fee_meta', + ), + 'woocommerce_update_order_item' => array( + 'woocommerce_order_edit_product', + 'woocommerce_order_update_coupon', + 'woocommerce_order_update_shipping', + 'woocommerce_order_update_fee', + 'woocommerce_order_update_tax', + ), + 'woocommerce_new_payment_token' => 'woocommerce_payment_token_created', + 'woocommerce_new_product_variation' => 'woocommerce_create_product_variation', + 'woocommerce_order_details_after_order_table_items' => 'woocommerce_order_items_table', + + 'woocommerce_settings_advanced_page_options' => array( + 'woocommerce_settings_checkout_page_options', + 'woocommerce_settings_account_page_options', + ), + 'woocommerce_settings_advanced_page_options_end' => array( + 'woocommerce_settings_checkout_page_options_end', + 'woocommerce_settings_account_page_options_end', + ), + 'woocommerce_settings_advanced_page_options_after' => array( + 'woocommerce_settings_checkout_page_options_after', + 'woocommerce_settings_account_page_options_after', + ), + ); + + /** + * Array of versions on each hook has been deprecated. + * + * @var array + */ + protected $deprecated_version = array( + 'woocommerce_order_add_shipping' => '3.0.0', + 'woocommerce_order_add_coupon' => '3.0.0', + 'woocommerce_order_add_tax' => '3.0.0', + 'woocommerce_order_add_fee' => '3.0.0', + 'woocommerce_add_shipping_order_item' => '3.0.0', + 'woocommerce_add_order_item_meta' => '3.0.0', + 'woocommerce_add_order_fee_meta' => '3.0.0', + 'woocommerce_order_edit_product' => '3.0.0', + 'woocommerce_order_update_coupon' => '3.0.0', + 'woocommerce_order_update_shipping' => '3.0.0', + 'woocommerce_order_update_fee' => '3.0.0', + 'woocommerce_order_update_tax' => '3.0.0', + 'woocommerce_payment_token_created' => '3.0.0', + 'woocommerce_create_product_variation' => '3.0.0', + 'woocommerce_order_items_table' => '3.0.0', + 'woocommerce_settings_checkout_page_options' => '3.4.0', + 'woocommerce_settings_account_page_options' => '3.4.0', + 'woocommerce_settings_checkout_page_options_end' => '3.4.0', + 'woocommerce_settings_account_page_options_end' => '3.4.0', + 'woocommerce_settings_checkout_page_options_after' => '3.4.0', + 'woocommerce_settings_account_page_options_after' => '3.4.0', + ); + + /** + * Hook into the new hook so we can handle deprecated hooks once fired. + * + * @param string $hook_name Hook name. + */ + public function hook_in( $hook_name ) { + add_action( $hook_name, array( $this, 'maybe_handle_deprecated_hook' ), -1000, 8 ); + } + + /** + * If the old hook is in-use, trigger it. + * + * @param string $new_hook New hook name. + * @param string $old_hook Old hook name. + * @param array $new_callback_args New callback args. + * @param mixed $return_value Returned value. + * @return mixed + */ + public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value ) { + if ( has_action( $old_hook ) ) { + $this->display_notice( $old_hook, $new_hook ); + $return_value = $this->trigger_hook( $old_hook, $new_callback_args ); + } + return $return_value; + } + + /** + * Fire off a legacy hook with it's args. + * + * @param string $old_hook Old hook name. + * @param array $new_callback_args New callback args. + * @return mixed + */ + protected function trigger_hook( $old_hook, $new_callback_args ) { + switch ( $old_hook ) { + case 'woocommerce_order_add_shipping': + case 'woocommerce_order_add_fee': + $item_id = $new_callback_args[0]; + $item = $new_callback_args[1]; + $order_id = $new_callback_args[2]; + if ( is_a( $item, 'WC_Order_Item_Shipping' ) || is_a( $item, 'WC_Order_Item_Fee' ) ) { + do_action( $old_hook, $order_id, $item_id, $item ); + } + break; + case 'woocommerce_order_add_coupon': + $item_id = $new_callback_args[0]; + $item = $new_callback_args[1]; + $order_id = $new_callback_args[2]; + if ( is_a( $item, 'WC_Order_Item_Coupon' ) ) { + do_action( $old_hook, $order_id, $item_id, $item->get_code(), $item->get_discount(), $item->get_discount_tax() ); + } + break; + case 'woocommerce_order_add_tax': + $item_id = $new_callback_args[0]; + $item = $new_callback_args[1]; + $order_id = $new_callback_args[2]; + if ( is_a( $item, 'WC_Order_Item_Tax' ) ) { + do_action( $old_hook, $order_id, $item_id, $item->get_rate_id(), $item->get_tax_total(), $item->get_shipping_tax_total() ); + } + break; + case 'woocommerce_add_shipping_order_item': + $item_id = $new_callback_args[0]; + $item = $new_callback_args[1]; + $order_id = $new_callback_args[2]; + if ( is_a( $item, 'WC_Order_Item_Shipping' ) ) { + do_action( $old_hook, $order_id, $item_id, $item->legacy_package_key ); + } + break; + case 'woocommerce_add_order_item_meta': + $item_id = $new_callback_args[0]; + $item = $new_callback_args[1]; + $order_id = $new_callback_args[2]; + if ( is_a( $item, 'WC_Order_Item_Product' ) ) { + do_action( $old_hook, $item_id, $item->legacy_values, $item->legacy_cart_item_key ); + } + break; + case 'woocommerce_add_order_fee_meta': + $item_id = $new_callback_args[0]; + $item = $new_callback_args[1]; + $order_id = $new_callback_args[2]; + if ( is_a( $item, 'WC_Order_Item_Fee' ) ) { + do_action( $old_hook, $order_id, $item_id, $item->legacy_fee, $item->legacy_fee_key ); + } + break; + case 'woocommerce_order_edit_product': + $item_id = $new_callback_args[0]; + $item = $new_callback_args[1]; + $order_id = $new_callback_args[2]; + if ( is_a( $item, 'WC_Order_Item_Product' ) ) { + do_action( $old_hook, $order_id, $item_id, $item, $item->get_product() ); + } + break; + case 'woocommerce_order_update_coupon': + case 'woocommerce_order_update_shipping': + case 'woocommerce_order_update_fee': + case 'woocommerce_order_update_tax': + if ( ! is_a( $item, 'WC_Order_Item_Product' ) ) { + do_action( $old_hook, $order_id, $item_id, $item ); + } + break; + default: + do_action_ref_array( $old_hook, $new_callback_args ); + break; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-deprecated-filter-hooks.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-deprecated-filter-hooks.php new file mode 100644 index 0000000..ddfcb75 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-deprecated-filter-hooks.php @@ -0,0 +1,144 @@ + 'old'. + * + * @var array + */ + protected $deprecated_hooks = array( + 'woocommerce_structured_data_order' => 'woocommerce_email_order_schema_markup', + 'woocommerce_add_to_cart_fragments' => 'add_to_cart_fragments', + 'woocommerce_add_to_cart_redirect' => 'add_to_cart_redirect', + 'woocommerce_product_get_width' => 'woocommerce_product_width', + 'woocommerce_product_get_height' => 'woocommerce_product_height', + 'woocommerce_product_get_length' => 'woocommerce_product_length', + 'woocommerce_product_get_weight' => 'woocommerce_product_weight', + 'woocommerce_product_get_sku' => 'woocommerce_get_sku', + 'woocommerce_product_get_price' => 'woocommerce_get_price', + 'woocommerce_product_get_regular_price' => 'woocommerce_get_regular_price', + 'woocommerce_product_get_sale_price' => 'woocommerce_get_sale_price', + 'woocommerce_product_get_tax_class' => 'woocommerce_product_tax_class', + 'woocommerce_product_get_stock_quantity' => 'woocommerce_get_stock_quantity', + 'woocommerce_product_get_attributes' => 'woocommerce_get_product_attributes', + 'woocommerce_product_get_gallery_image_ids' => 'woocommerce_product_gallery_attachment_ids', + 'woocommerce_product_get_review_count' => 'woocommerce_product_review_count', + 'woocommerce_product_get_downloads' => 'woocommerce_product_files', + 'woocommerce_order_get_currency' => 'woocommerce_get_currency', + 'woocommerce_order_get_discount_total' => 'woocommerce_order_amount_discount_total', + 'woocommerce_order_get_discount_tax' => 'woocommerce_order_amount_discount_tax', + 'woocommerce_order_get_shipping_total' => 'woocommerce_order_amount_shipping_total', + 'woocommerce_order_get_shipping_tax' => 'woocommerce_order_amount_shipping_tax', + 'woocommerce_order_get_cart_tax' => 'woocommerce_order_amount_cart_tax', + 'woocommerce_order_get_total' => 'woocommerce_order_amount_total', + 'woocommerce_order_get_total_tax' => 'woocommerce_order_amount_total_tax', + 'woocommerce_order_get_total_discount' => 'woocommerce_order_amount_total_discount', + 'woocommerce_order_get_subtotal' => 'woocommerce_order_amount_subtotal', + 'woocommerce_order_get_tax_totals' => 'woocommerce_order_tax_totals', + 'woocommerce_get_order_refund_get_amount' => 'woocommerce_refund_amount', + 'woocommerce_get_order_refund_get_reason' => 'woocommerce_refund_reason', + 'default_checkout_billing_country' => 'default_checkout_country', + 'default_checkout_billing_state' => 'default_checkout_state', + 'default_checkout_billing_postcode' => 'default_checkout_postcode', + 'woocommerce_system_status_environment_rows' => 'woocommerce_debug_posting', + 'woocommerce_credit_card_type_labels' => 'wocommerce_credit_card_type_labels', + 'woocommerce_settings_tabs_advanced' => 'woocommerce_settings_tabs_api', + 'woocommerce_settings_advanced' => 'woocommerce_settings_api', + ); + + /** + * Array of versions on each hook has been deprecated. + * + * @var array + */ + protected $deprecated_version = array( + 'woocommerce_email_order_schema_markup' => '3.0.0', + 'add_to_cart_fragments' => '3.0.0', + 'add_to_cart_redirect' => '3.0.0', + 'woocommerce_product_width' => '3.0.0', + 'woocommerce_product_height' => '3.0.0', + 'woocommerce_product_length' => '3.0.0', + 'woocommerce_product_weight' => '3.0.0', + 'woocommerce_get_sku' => '3.0.0', + 'woocommerce_get_price' => '3.0.0', + 'woocommerce_get_regular_price' => '3.0.0', + 'woocommerce_get_sale_price' => '3.0.0', + 'woocommerce_product_tax_class' => '3.0.0', + 'woocommerce_get_stock_quantity' => '3.0.0', + 'woocommerce_get_product_attributes' => '3.0.0', + 'woocommerce_product_gallery_attachment_ids' => '3.0.0', + 'woocommerce_product_review_count' => '3.0.0', + 'woocommerce_product_files' => '3.0.0', + 'woocommerce_get_currency' => '3.0.0', + 'woocommerce_order_amount_discount_total' => '3.0.0', + 'woocommerce_order_amount_discount_tax' => '3.0.0', + 'woocommerce_order_amount_shipping_total' => '3.0.0', + 'woocommerce_order_amount_shipping_tax' => '3.0.0', + 'woocommerce_order_amount_cart_tax' => '3.0.0', + 'woocommerce_order_amount_total' => '3.0.0', + 'woocommerce_order_amount_total_tax' => '3.0.0', + 'woocommerce_order_amount_total_discount' => '3.0.0', + 'woocommerce_order_amount_subtotal' => '3.0.0', + 'woocommerce_order_tax_totals' => '3.0.0', + 'woocommerce_refund_amount' => '3.0.0', + 'woocommerce_refund_reason' => '3.0.0', + 'default_checkout_country' => '3.0.0', + 'default_checkout_state' => '3.0.0', + 'default_checkout_postcode' => '3.0.0', + 'woocommerce_debug_posting' => '3.0.0', + 'wocommerce_credit_card_type_labels' => '3.0.0', + 'woocommerce_settings_tabs_api' => '3.4.0', + 'woocommerce_settings_api' => '3.4.0', + ); + + /** + * Hook into the new hook so we can handle deprecated hooks once fired. + * + * @param string $hook_name Hook name. + */ + public function hook_in( $hook_name ) { + add_filter( $hook_name, array( $this, 'maybe_handle_deprecated_hook' ), -1000, 8 ); + } + + /** + * If the old hook is in-use, trigger it. + * + * @param string $new_hook New hook name. + * @param string $old_hook Old hook name. + * @param array $new_callback_args New callback args. + * @param mixed $return_value Returned value. + * @return mixed + */ + public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value ) { + if ( has_filter( $old_hook ) ) { + $this->display_notice( $old_hook, $new_hook ); + $return_value = $this->trigger_hook( $old_hook, $new_callback_args ); + } + return $return_value; + } + + /** + * Fire off a legacy hook with it's args. + * + * @param string $old_hook Old hook name. + * @param array $new_callback_args New callback args. + * @return mixed + */ + protected function trigger_hook( $old_hook, $new_callback_args ) { + return apply_filters_ref_array( $old_hook, $new_callback_args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-discounts.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-discounts.php new file mode 100644 index 0000000..2800c43 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-discounts.php @@ -0,0 +1,985 @@ + Item Key => Value + */ + protected $discounts = array(); + + /** + * WC_Discounts Constructor. + * + * @param WC_Cart|WC_Order $object Cart or order object. + */ + public function __construct( $object = null ) { + if ( is_a( $object, 'WC_Cart' ) ) { + $this->set_items_from_cart( $object ); + } elseif ( is_a( $object, 'WC_Order' ) ) { + $this->set_items_from_order( $object ); + } + } + + /** + * Set items directly. Used by WC_Cart_Totals. + * + * @since 3.2.3 + * @param array $items Items to set. + */ + public function set_items( $items ) { + $this->items = $items; + $this->discounts = array(); + uasort( $this->items, array( $this, 'sort_by_price' ) ); + } + + /** + * Normalise cart items which will be discounted. + * + * @since 3.2.0 + * @param WC_Cart $cart Cart object. + */ + public function set_items_from_cart( $cart ) { + $this->items = array(); + $this->discounts = array(); + + if ( ! is_a( $cart, 'WC_Cart' ) ) { + return; + } + + $this->object = $cart; + + foreach ( $cart->get_cart() as $key => $cart_item ) { + $item = new stdClass(); + $item->key = $key; + $item->object = $cart_item; + $item->product = $cart_item['data']; + $item->quantity = $cart_item['quantity']; + $item->price = wc_add_number_precision_deep( $item->product->get_price() * $item->quantity ); + $this->items[ $key ] = $item; + } + + uasort( $this->items, array( $this, 'sort_by_price' ) ); + } + + /** + * Normalise order items which will be discounted. + * + * @since 3.2.0 + * @param WC_Order $order Order object. + */ + public function set_items_from_order( $order ) { + $this->items = array(); + $this->discounts = array(); + + if ( ! is_a( $order, 'WC_Order' ) ) { + return; + } + + $this->object = $order; + + foreach ( $order->get_items() as $order_item ) { + $item = new stdClass(); + $item->key = $order_item->get_id(); + $item->object = $order_item; + $item->product = $order_item->get_product(); + $item->quantity = $order_item->get_quantity(); + $item->price = wc_add_number_precision_deep( $order_item->get_subtotal() ); + + if ( $order->get_prices_include_tax() ) { + $item->price += wc_add_number_precision_deep( $order_item->get_subtotal_tax() ); + } + + $this->items[ $order_item->get_id() ] = $item; + } + + uasort( $this->items, array( $this, 'sort_by_price' ) ); + } + + /** + * Get the object concerned. + * + * @since 3.3.2 + * @return object + */ + public function get_object() { + return $this->object; + } + + /** + * Get items. + * + * @since 3.2.0 + * @return object[] + */ + public function get_items() { + return $this->items; + } + + /** + * Get items to validate. + * + * @since 3.3.2 + * @return object[] + */ + public function get_items_to_validate() { + return apply_filters( 'woocommerce_coupon_get_items_to_validate', $this->get_items(), $this ); + } + + /** + * Get discount by key with or without precision. + * + * @since 3.2.0 + * @param string $key name of discount row to return. + * @param bool $in_cents Should the totals be returned in cents, or without precision. + * @return float + */ + public function get_discount( $key, $in_cents = false ) { + $item_discount_totals = $this->get_discounts_by_item( $in_cents ); + return isset( $item_discount_totals[ $key ] ) ? $item_discount_totals[ $key ] : 0; + } + + /** + * Get all discount totals. + * + * @since 3.2.0 + * @param bool $in_cents Should the totals be returned in cents, or without precision. + * @return array + */ + public function get_discounts( $in_cents = false ) { + $discounts = $this->discounts; + return $in_cents ? $discounts : wc_remove_number_precision_deep( $discounts ); + } + + /** + * Get all discount totals per item. + * + * @since 3.2.0 + * @param bool $in_cents Should the totals be returned in cents, or without precision. + * @return array + */ + public function get_discounts_by_item( $in_cents = false ) { + $discounts = $this->discounts; + $item_discount_totals = (array) array_shift( $discounts ); + + foreach ( $discounts as $item_discounts ) { + foreach ( $item_discounts as $item_key => $item_discount ) { + $item_discount_totals[ $item_key ] += $item_discount; + } + } + + return $in_cents ? $item_discount_totals : wc_remove_number_precision_deep( $item_discount_totals ); + } + + /** + * Get all discount totals per coupon. + * + * @since 3.2.0 + * @param bool $in_cents Should the totals be returned in cents, or without precision. + * @return array + */ + public function get_discounts_by_coupon( $in_cents = false ) { + $coupon_discount_totals = array_map( 'array_sum', $this->discounts ); + + return $in_cents ? $coupon_discount_totals : wc_remove_number_precision_deep( $coupon_discount_totals ); + } + + /** + * Get discounted price of an item without precision. + * + * @since 3.2.0 + * @param object $item Get data for this item. + * @return float + */ + public function get_discounted_price( $item ) { + return wc_remove_number_precision_deep( $this->get_discounted_price_in_cents( $item ) ); + } + + /** + * Get discounted price of an item to precision (in cents). + * + * @since 3.2.0 + * @param object $item Get data for this item. + * @return int + */ + public function get_discounted_price_in_cents( $item ) { + return absint( NumberUtil::round( $item->price - $this->get_discount( $item->key, true ) ) ); + } + + /** + * Apply a discount to all items using a coupon. + * + * @since 3.2.0 + * @param WC_Coupon $coupon Coupon object being applied to the items. + * @param bool $validate Set to false to skip coupon validation. + * @throws Exception Error message when coupon isn't valid. + * @return bool|WP_Error True if applied or WP_Error instance in failure. + */ + public function apply_coupon( $coupon, $validate = true ) { + if ( ! is_a( $coupon, 'WC_Coupon' ) ) { + return new WP_Error( 'invalid_coupon', __( 'Invalid coupon', 'woocommerce' ) ); + } + + $is_coupon_valid = $validate ? $this->is_coupon_valid( $coupon ) : true; + + if ( is_wp_error( $is_coupon_valid ) ) { + return $is_coupon_valid; + } + + if ( ! isset( $this->discounts[ $coupon->get_code() ] ) ) { + $this->discounts[ $coupon->get_code() ] = array_fill_keys( array_keys( $this->items ), 0 ); + } + + $items_to_apply = $this->get_items_to_apply_coupon( $coupon ); + + // Core discounts are handled here as of 3.2. + switch ( $coupon->get_discount_type() ) { + case 'percent': + $this->apply_coupon_percent( $coupon, $items_to_apply ); + break; + case 'fixed_product': + $this->apply_coupon_fixed_product( $coupon, $items_to_apply ); + break; + case 'fixed_cart': + $this->apply_coupon_fixed_cart( $coupon, $items_to_apply ); + break; + default: + $this->apply_coupon_custom( $coupon, $items_to_apply ); + break; + } + + return true; + } + + /** + * Sort by price. + * + * @since 3.2.0 + * @param array $a First element. + * @param array $b Second element. + * @return int + */ + protected function sort_by_price( $a, $b ) { + $price_1 = $a->price * $a->quantity; + $price_2 = $b->price * $b->quantity; + if ( $price_1 === $price_2 ) { + return 0; + } + return ( $price_1 < $price_2 ) ? 1 : -1; + } + + /** + * Filter out all products which have been fully discounted to 0. + * Used as array_filter callback. + * + * @since 3.2.0 + * @param object $item Get data for this item. + * @return bool + */ + protected function filter_products_with_price( $item ) { + return $this->get_discounted_price_in_cents( $item ) > 0; + } + + /** + * Get items which the coupon should be applied to. + * + * @since 3.2.0 + * @param object $coupon Coupon object. + * @return array + */ + protected function get_items_to_apply_coupon( $coupon ) { + $items_to_apply = array(); + + foreach ( $this->get_items_to_validate() as $item ) { + $item_to_apply = clone $item; // Clone the item so changes to this item do not affect the originals. + + if ( 0 === $this->get_discounted_price_in_cents( $item_to_apply ) || 0 >= $item_to_apply->quantity ) { + continue; + } + + if ( ! $coupon->is_valid_for_product( $item_to_apply->product, $item_to_apply->object ) && ! $coupon->is_valid_for_cart() ) { + continue; + } + + $items_to_apply[] = $item_to_apply; + } + return $items_to_apply; + } + + /** + * Apply percent discount to items and return an array of discounts granted. + * + * @since 3.2.0 + * @param WC_Coupon $coupon Coupon object. Passed through filters. + * @param array $items_to_apply Array of items to apply the coupon to. + * @return int Total discounted. + */ + protected function apply_coupon_percent( $coupon, $items_to_apply ) { + $total_discount = 0; + $cart_total = 0; + $limit_usage_qty = 0; + $applied_count = 0; + $adjust_final_discount = true; + + if ( null !== $coupon->get_limit_usage_to_x_items() ) { + $limit_usage_qty = $coupon->get_limit_usage_to_x_items(); + } + + $coupon_amount = $coupon->get_amount(); + + foreach ( $items_to_apply as $item ) { + // Find out how much price is available to discount for the item. + $discounted_price = $this->get_discounted_price_in_cents( $item ); + + // Get the price we actually want to discount, based on settings. + $price_to_discount = ( 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ) ? $discounted_price : NumberUtil::round( $item->price ); + + // See how many and what price to apply to. + $apply_quantity = $limit_usage_qty && ( $limit_usage_qty - $applied_count ) < $item->quantity ? $limit_usage_qty - $applied_count : $item->quantity; + $apply_quantity = max( 0, apply_filters( 'woocommerce_coupon_get_apply_quantity', $apply_quantity, $item, $coupon, $this ) ); + $price_to_discount = ( $price_to_discount / $item->quantity ) * $apply_quantity; + + // Run coupon calculations. + $discount = floor( $price_to_discount * ( $coupon_amount / 100 ) ); + + if ( is_a( $this->object, 'WC_Cart' ) && has_filter( 'woocommerce_coupon_get_discount_amount' ) ) { + // Send through the legacy filter, but not as cents. + $filtered_discount = wc_add_number_precision( apply_filters( 'woocommerce_coupon_get_discount_amount', wc_remove_number_precision( $discount ), wc_remove_number_precision( $price_to_discount ), $item->object, false, $coupon ) ); + + if ( $filtered_discount !== $discount ) { + $discount = $filtered_discount; + $adjust_final_discount = false; + } + } + + $discount = wc_round_discount( min( $discounted_price, $discount ), 0 ); + $cart_total = $cart_total + $price_to_discount; + $total_discount = $total_discount + $discount; + $applied_count = $applied_count + $apply_quantity; + + // Store code and discount amount per item. + $this->discounts[ $coupon->get_code() ][ $item->key ] += $discount; + } + + // Work out how much discount would have been given to the cart as a whole and compare to what was discounted on all line items. + $cart_total_discount = wc_round_discount( $cart_total * ( $coupon_amount / 100 ), 0 ); + + if ( $total_discount < $cart_total_discount && $adjust_final_discount ) { + $total_discount += $this->apply_coupon_remainder( $coupon, $items_to_apply, $cart_total_discount - $total_discount ); + } + + return $total_discount; + } + + /** + * Apply fixed product discount to items. + * + * @since 3.2.0 + * @param WC_Coupon $coupon Coupon object. Passed through filters. + * @param array $items_to_apply Array of items to apply the coupon to. + * @param int $amount Fixed discount amount to apply in cents. Leave blank to pull from coupon. + * @return int Total discounted. + */ + protected function apply_coupon_fixed_product( $coupon, $items_to_apply, $amount = null ) { + $total_discount = 0; + $amount = $amount ? $amount : wc_add_number_precision( $coupon->get_amount() ); + $limit_usage_qty = 0; + $applied_count = 0; + + if ( null !== $coupon->get_limit_usage_to_x_items() ) { + $limit_usage_qty = $coupon->get_limit_usage_to_x_items(); + } + + foreach ( $items_to_apply as $item ) { + // Find out how much price is available to discount for the item. + $discounted_price = $this->get_discounted_price_in_cents( $item ); + + // Get the price we actually want to discount, based on settings. + $price_to_discount = ( 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ) ? $discounted_price : $item->price; + + // Run coupon calculations. + if ( $limit_usage_qty ) { + $apply_quantity = $limit_usage_qty - $applied_count < $item->quantity ? $limit_usage_qty - $applied_count : $item->quantity; + $apply_quantity = max( 0, apply_filters( 'woocommerce_coupon_get_apply_quantity', $apply_quantity, $item, $coupon, $this ) ); + $discount = min( $amount, $item->price / $item->quantity ) * $apply_quantity; + } else { + $apply_quantity = apply_filters( 'woocommerce_coupon_get_apply_quantity', $item->quantity, $item, $coupon, $this ); + $discount = $amount * $apply_quantity; + } + + if ( is_a( $this->object, 'WC_Cart' ) && has_filter( 'woocommerce_coupon_get_discount_amount' ) ) { + // Send through the legacy filter, but not as cents. + $discount = wc_add_number_precision( apply_filters( 'woocommerce_coupon_get_discount_amount', wc_remove_number_precision( $discount ), wc_remove_number_precision( $price_to_discount ), $item->object, false, $coupon ) ); + } + + $discount = min( $discounted_price, $discount ); + $total_discount = $total_discount + $discount; + $applied_count = $applied_count + $apply_quantity; + + // Store code and discount amount per item. + $this->discounts[ $coupon->get_code() ][ $item->key ] += $discount; + } + return $total_discount; + } + + /** + * Apply fixed cart discount to items. + * + * @since 3.2.0 + * @param WC_Coupon $coupon Coupon object. Passed through filters. + * @param array $items_to_apply Array of items to apply the coupon to. + * @param int $amount Fixed discount amount to apply in cents. Leave blank to pull from coupon. + * @return int Total discounted. + */ + protected function apply_coupon_fixed_cart( $coupon, $items_to_apply, $amount = null ) { + $total_discount = 0; + $amount = $amount ? $amount : wc_add_number_precision( $coupon->get_amount() ); + $items_to_apply = array_filter( $items_to_apply, array( $this, 'filter_products_with_price' ) ); + $item_count = array_sum( wp_list_pluck( $items_to_apply, 'quantity' ) ); + + if ( ! $item_count ) { + return $total_discount; + } + + if ( ! $amount ) { + // If there is no amount we still send it through so filters are fired. + $total_discount = $this->apply_coupon_fixed_product( $coupon, $items_to_apply, 0 ); + } else { + $per_item_discount = absint( $amount / $item_count ); // round it down to the nearest cent. + + if ( $per_item_discount > 0 ) { + $total_discount = $this->apply_coupon_fixed_product( $coupon, $items_to_apply, $per_item_discount ); + + /** + * If there is still discount remaining, repeat the process. + */ + if ( $total_discount > 0 && $total_discount < $amount ) { + $total_discount += $this->apply_coupon_fixed_cart( $coupon, $items_to_apply, $amount - $total_discount ); + } + } elseif ( $amount > 0 ) { + $total_discount += $this->apply_coupon_remainder( $coupon, $items_to_apply, $amount ); + } + } + return $total_discount; + } + + /** + * Apply custom coupon discount to items. + * + * @since 3.3 + * @param WC_Coupon $coupon Coupon object. Passed through filters. + * @param array $items_to_apply Array of items to apply the coupon to. + * @return int Total discounted. + */ + protected function apply_coupon_custom( $coupon, $items_to_apply ) { + $limit_usage_qty = 0; + $applied_count = 0; + + if ( null !== $coupon->get_limit_usage_to_x_items() ) { + $limit_usage_qty = $coupon->get_limit_usage_to_x_items(); + } + + // Apply the coupon to each item. + foreach ( $items_to_apply as $item ) { + // Find out how much price is available to discount for the item. + $discounted_price = $this->get_discounted_price_in_cents( $item ); + + // Get the price we actually want to discount, based on settings. + $price_to_discount = wc_remove_number_precision( ( 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ) ? $discounted_price : $item->price ); + + // See how many and what price to apply to. + $apply_quantity = $limit_usage_qty && ( $limit_usage_qty - $applied_count ) < $item->quantity ? $limit_usage_qty - $applied_count : $item->quantity; + $apply_quantity = max( 0, apply_filters( 'woocommerce_coupon_get_apply_quantity', $apply_quantity, $item, $coupon, $this ) ); + + // Run coupon calculations. + $discount = wc_add_number_precision( $coupon->get_discount_amount( $price_to_discount / $item->quantity, $item->object, true ) ) * $apply_quantity; + $discount = wc_round_discount( min( $discounted_price, $discount ), 0 ); + $applied_count = $applied_count + $apply_quantity; + + // Store code and discount amount per item. + $this->discounts[ $coupon->get_code() ][ $item->key ] += $discount; + } + + // Allow post-processing for custom coupon types (e.g. calculating discrepancy, etc). + $this->discounts[ $coupon->get_code() ] = apply_filters( 'woocommerce_coupon_custom_discounts_array', $this->discounts[ $coupon->get_code() ], $coupon ); + + return array_sum( $this->discounts[ $coupon->get_code() ] ); + } + + /** + * Deal with remaining fractional discounts by splitting it over items + * until the amount is expired, discounting 1 cent at a time. + * + * @since 3.2.0 + * @param WC_Coupon $coupon Coupon object if appliable. Passed through filters. + * @param array $items_to_apply Array of items to apply the coupon to. + * @param int $amount Fixed discount amount to apply. + * @return int Total discounted. + */ + protected function apply_coupon_remainder( $coupon, $items_to_apply, $amount ) { + $total_discount = 0; + + foreach ( $items_to_apply as $item ) { + for ( $i = 0; $i < $item->quantity; $i ++ ) { + // Find out how much price is available to discount for the item. + $price_to_discount = $this->get_discounted_price_in_cents( $item ); + + // Run coupon calculations. + $discount = min( $price_to_discount, 1 ); + + // Store totals. + $total_discount += $discount; + + // Store code and discount amount per item. + $this->discounts[ $coupon->get_code() ][ $item->key ] += $discount; + + if ( $total_discount >= $amount ) { + break 2; + } + } + if ( $total_discount >= $amount ) { + break; + } + } + return $total_discount; + } + + /** + * Ensure coupon exists or throw exception. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_exists( $coupon ) { + if ( ! $coupon->get_id() && ! $coupon->get_virtual() ) { + /* translators: %s: coupon code */ + throw new Exception( sprintf( __( 'Coupon "%s" does not exist!', 'woocommerce' ), esc_html( $coupon->get_code() ) ), 105 ); + } + + return true; + } + + /** + * Ensure coupon usage limit is valid or throw exception. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_usage_limit( $coupon ) { + if ( $coupon->get_usage_limit() > 0 && $coupon->get_usage_count() >= $coupon->get_usage_limit() ) { + throw new Exception( __( 'Coupon usage limit has been reached.', 'woocommerce' ), 106 ); + } + + return true; + } + + /** + * Ensure coupon user usage limit is valid or throw exception. + * + * Per user usage limit - check here if user is logged in (against user IDs). + * Checked again for emails later on in WC_Cart::check_customer_coupons(). + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @param int $user_id User ID. + * @return bool + */ + protected function validate_coupon_user_usage_limit( $coupon, $user_id = 0 ) { + if ( empty( $user_id ) ) { + if ( $this->object instanceof WC_Order ) { + $user_id = $this->object->get_customer_id(); + } else { + $user_id = get_current_user_id(); + } + } + + if ( $coupon && $user_id && apply_filters( 'woocommerce_coupon_validate_user_usage_limit', $coupon->get_usage_limit_per_user() > 0, $user_id, $coupon, $this ) && $coupon->get_id() && $coupon->get_data_store() ) { + $data_store = $coupon->get_data_store(); + $usage_count = $data_store->get_usage_by_user_id( $coupon, $user_id ); + if ( $usage_count >= $coupon->get_usage_limit_per_user() ) { + throw new Exception( __( 'Coupon usage limit has been reached.', 'woocommerce' ), 106 ); + } + } + + return true; + } + + /** + * Ensure coupon date is valid or throw exception. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_expiry_date( $coupon ) { + if ( $coupon->get_date_expires() && apply_filters( 'woocommerce_coupon_validate_expiry_date', time() > $coupon->get_date_expires()->getTimestamp(), $coupon, $this ) ) { + throw new Exception( __( 'This coupon has expired.', 'woocommerce' ), 107 ); + } + + return true; + } + + /** + * Ensure coupon amount is valid or throw exception. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_minimum_amount( $coupon ) { + $subtotal = wc_remove_number_precision( $this->get_object_subtotal() ); + + if ( $coupon->get_minimum_amount() > 0 && apply_filters( 'woocommerce_coupon_validate_minimum_amount', $coupon->get_minimum_amount() > $subtotal, $coupon, $subtotal ) ) { + /* translators: %s: coupon minimum amount */ + throw new Exception( sprintf( __( 'The minimum spend for this coupon is %s.', 'woocommerce' ), wc_price( $coupon->get_minimum_amount() ) ), 108 ); + } + + return true; + } + + /** + * Ensure coupon amount is valid or throw exception. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_maximum_amount( $coupon ) { + $subtotal = wc_remove_number_precision( $this->get_object_subtotal() ); + + if ( $coupon->get_maximum_amount() > 0 && apply_filters( 'woocommerce_coupon_validate_maximum_amount', $coupon->get_maximum_amount() < $subtotal, $coupon ) ) { + /* translators: %s: coupon maximum amount */ + throw new Exception( sprintf( __( 'The maximum spend for this coupon is %s.', 'woocommerce' ), wc_price( $coupon->get_maximum_amount() ) ), 112 ); + } + + return true; + } + + /** + * Ensure coupon is valid for products in the list is valid or throw exception. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_product_ids( $coupon ) { + if ( count( $coupon->get_product_ids() ) > 0 ) { + $valid = false; + + foreach ( $this->get_items_to_validate() as $item ) { + if ( $item->product && in_array( $item->product->get_id(), $coupon->get_product_ids(), true ) || in_array( $item->product->get_parent_id(), $coupon->get_product_ids(), true ) ) { + $valid = true; + break; + } + } + + if ( ! $valid ) { + throw new Exception( __( 'Sorry, this coupon is not applicable to selected products.', 'woocommerce' ), 109 ); + } + } + + return true; + } + + /** + * Ensure coupon is valid for product categories in the list is valid or throw exception. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_product_categories( $coupon ) { + if ( count( $coupon->get_product_categories() ) > 0 ) { + $valid = false; + + foreach ( $this->get_items_to_validate() as $item ) { + if ( $coupon->get_exclude_sale_items() && $item->product && $item->product->is_on_sale() ) { + continue; + } + + $product_cats = wc_get_product_cat_ids( $item->product->get_id() ); + + if ( $item->product->get_parent_id() ) { + $product_cats = array_merge( $product_cats, wc_get_product_cat_ids( $item->product->get_parent_id() ) ); + } + + // If we find an item with a cat in our allowed cat list, the coupon is valid. + if ( count( array_intersect( $product_cats, $coupon->get_product_categories() ) ) > 0 ) { + $valid = true; + break; + } + } + + if ( ! $valid ) { + throw new Exception( __( 'Sorry, this coupon is not applicable to selected products.', 'woocommerce' ), 109 ); + } + } + + return true; + } + + /** + * Ensure coupon is valid for sale items in the list is valid or throw exception. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_sale_items( $coupon ) { + if ( $coupon->get_exclude_sale_items() ) { + $valid = true; + + foreach ( $this->get_items_to_validate() as $item ) { + if ( $item->product && $item->product->is_on_sale() ) { + $valid = false; + break; + } + } + + if ( ! $valid ) { + throw new Exception( __( 'Sorry, this coupon is not valid for sale items.', 'woocommerce' ), 110 ); + } + } + + return true; + } + + /** + * All exclusion rules must pass at the same time for a product coupon to be valid. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_excluded_items( $coupon ) { + $items = $this->get_items_to_validate(); + if ( ! empty( $items ) && $coupon->is_type( wc_get_product_coupon_types() ) ) { + $valid = false; + + foreach ( $items as $item ) { + if ( $item->product && $coupon->is_valid_for_product( $item->product, $item->object ) ) { + $valid = true; + break; + } + } + + if ( ! $valid ) { + throw new Exception( __( 'Sorry, this coupon is not applicable to selected products.', 'woocommerce' ), 109 ); + } + } + + return true; + } + + /** + * Cart discounts cannot be added if non-eligible product is found. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_eligible_items( $coupon ) { + if ( ! $coupon->is_type( wc_get_product_coupon_types() ) ) { + $this->validate_coupon_sale_items( $coupon ); + $this->validate_coupon_excluded_product_ids( $coupon ); + $this->validate_coupon_excluded_product_categories( $coupon ); + } + + return true; + } + + /** + * Exclude products. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_excluded_product_ids( $coupon ) { + // Exclude Products. + if ( count( $coupon->get_excluded_product_ids() ) > 0 ) { + $products = array(); + + foreach ( $this->get_items_to_validate() as $item ) { + if ( $item->product && in_array( $item->product->get_id(), $coupon->get_excluded_product_ids(), true ) || in_array( $item->product->get_parent_id(), $coupon->get_excluded_product_ids(), true ) ) { + $products[] = $item->product->get_name(); + } + } + + if ( ! empty( $products ) ) { + /* translators: %s: products list */ + throw new Exception( sprintf( __( 'Sorry, this coupon is not applicable to the products: %s.', 'woocommerce' ), implode( ', ', $products ) ), 113 ); + } + } + + return true; + } + + /** + * Exclude categories from product list. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool + */ + protected function validate_coupon_excluded_product_categories( $coupon ) { + if ( count( $coupon->get_excluded_product_categories() ) > 0 ) { + $categories = array(); + + foreach ( $this->get_items_to_validate() as $item ) { + if ( ! $item->product ) { + continue; + } + + $product_cats = wc_get_product_cat_ids( $item->product->get_id() ); + + if ( $item->product->get_parent_id() ) { + $product_cats = array_merge( $product_cats, wc_get_product_cat_ids( $item->product->get_parent_id() ) ); + } + + $cat_id_list = array_intersect( $product_cats, $coupon->get_excluded_product_categories() ); + if ( count( $cat_id_list ) > 0 ) { + foreach ( $cat_id_list as $cat_id ) { + $cat = get_term( $cat_id, 'product_cat' ); + $categories[] = $cat->name; + } + } + } + + if ( ! empty( $categories ) ) { + /* translators: %s: categories list */ + throw new Exception( sprintf( __( 'Sorry, this coupon is not applicable to the categories: %s.', 'woocommerce' ), implode( ', ', array_unique( $categories ) ) ), 114 ); + } + } + + return true; + } + + /** + * Get the object subtotal + * + * @return int + */ + protected function get_object_subtotal() { + if ( is_a( $this->object, 'WC_Cart' ) ) { + return wc_add_number_precision( $this->object->get_displayed_subtotal() ); + } elseif ( is_a( $this->object, 'WC_Order' ) ) { + $subtotal = wc_add_number_precision( $this->object->get_subtotal() ); + + if ( $this->object->get_prices_include_tax() ) { + // Add tax to tax-exclusive subtotal. + $subtotal = $subtotal + wc_add_number_precision( NumberUtil::round( $this->object->get_total_tax(), wc_get_price_decimals() ) ); + } + + return $subtotal; + } else { + return array_sum( wp_list_pluck( $this->items, 'price' ) ); + } + } + + /** + * Check if a coupon is valid. + * + * Error Codes: + * - 100: Invalid filtered. + * - 101: Invalid removed. + * - 102: Not yours removed. + * - 103: Already applied. + * - 104: Individual use only. + * - 105: Not exists. + * - 106: Usage limit reached. + * - 107: Expired. + * - 108: Minimum spend limit not met. + * - 109: Not applicable. + * - 110: Not valid for sale items. + * - 111: Missing coupon code. + * - 112: Maximum spend limit met. + * - 113: Excluded products. + * - 114: Excluded categories. + * + * @since 3.2.0 + * @throws Exception Error message. + * @param WC_Coupon $coupon Coupon data. + * @return bool|WP_Error + */ + public function is_coupon_valid( $coupon ) { + try { + $this->validate_coupon_exists( $coupon ); + $this->validate_coupon_usage_limit( $coupon ); + $this->validate_coupon_user_usage_limit( $coupon ); + $this->validate_coupon_expiry_date( $coupon ); + $this->validate_coupon_minimum_amount( $coupon ); + $this->validate_coupon_maximum_amount( $coupon ); + $this->validate_coupon_product_ids( $coupon ); + $this->validate_coupon_product_categories( $coupon ); + $this->validate_coupon_excluded_items( $coupon ); + $this->validate_coupon_eligible_items( $coupon ); + + if ( ! apply_filters( 'woocommerce_coupon_is_valid', true, $coupon, $this ) ) { + throw new Exception( __( 'Coupon is not valid.', 'woocommerce' ), 100 ); + } + } catch ( Exception $e ) { + /** + * Filter the coupon error message. + * + * @param string $error_message Error message. + * @param int $error_code Error code. + * @param WC_Coupon $coupon Coupon data. + */ + $message = apply_filters( 'woocommerce_coupon_error', is_numeric( $e->getMessage() ) ? $coupon->get_coupon_error( $e->getMessage() ) : $e->getMessage(), $e->getCode(), $coupon ); + + return new WP_Error( + 'invalid_coupon', + $message, + array( + 'status' => 400, + ) + ); + } + return true; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-download-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-download-handler.php new file mode 100644 index 0000000..fa279c8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-download-handler.php @@ -0,0 +1,630 @@ +get_billing_email() : null; + + // Prepare email address hash. + $email_hash = function_exists( 'hash' ) ? hash( 'sha256', $email_address ) : sha1( $email_address ); + + if ( is_null( $email_address ) || ! hash_equals( wp_unslash( $_GET['uid'] ), $email_hash ) ) { // WPCS: input var ok, CSRF ok, sanitization ok. + self::download_error( __( 'Invalid download link.', 'woocommerce' ) ); + } + } + + $download_ids = $data_store->get_downloads( + array( + 'user_email' => sanitize_email( str_replace( ' ', '+', $email_address ) ), + 'order_key' => wc_clean( wp_unslash( $_GET['order'] ) ), // WPCS: input var ok, CSRF ok. + 'product_id' => $product_id, + 'download_id' => wc_clean( preg_replace( '/\s+/', ' ', wp_unslash( $_GET['key'] ) ) ), // WPCS: input var ok, CSRF ok, sanitization ok. + 'orderby' => 'downloads_remaining', + 'order' => 'DESC', + 'limit' => 1, + 'return' => 'ids', + ) + ); + + if ( empty( $download_ids ) ) { + self::download_error( __( 'Invalid download link.', 'woocommerce' ) ); + } + + $download = new WC_Customer_Download( current( $download_ids ) ); + + /** + * Filter download filepath. + * + * @since 4.0.0 + * @param string $file_path File path. + * @param string $email_address Email address. + * @param WC_Order|bool $order Order object or false. + * @param WC_Product $product Product object. + * @param WC_Customer_Download $download Download data. + */ + $file_path = apply_filters( + 'woocommerce_download_product_filepath', + $product->get_file_download_path( $download->get_download_id() ), + $email_address, + $order, + $product, + $download + ); + + $parsed_file_path = self::parse_file_path( $file_path ); + $download_range = self::get_download_range( @filesize( $parsed_file_path['file_path'] ) ); // @codingStandardsIgnoreLine. + + self::check_order_is_valid( $download ); + if ( ! $download_range['is_range_request'] ) { + // If the remaining download count goes to 0, allow range requests to be able to finish streaming from iOS devices. + self::check_downloads_remaining( $download ); + } + self::check_download_expiry( $download ); + self::check_download_login_required( $download ); + + do_action( + 'woocommerce_download_product', + $download->get_user_email(), + $download->get_order_key(), + $download->get_product_id(), + $download->get_user_id(), + $download->get_download_id(), + $download->get_order_id() + ); + $download->save(); + + // Track the download in logs and change remaining/counts. + $current_user_id = get_current_user_id(); + $ip_address = WC_Geolocation::get_ip_address(); + if ( ! $download_range['is_range_request'] ) { + $download->track_download( $current_user_id > 0 ? $current_user_id : null, ! empty( $ip_address ) ? $ip_address : null ); + } + + self::download( $file_path, $download->get_product_id() ); + } + + /** + * Check if an order is valid for downloading from. + * + * @param WC_Customer_Download $download Download instance. + */ + private static function check_order_is_valid( $download ) { + if ( $download->get_order_id() ) { + $order = wc_get_order( $download->get_order_id() ); + + if ( $order && ! $order->is_download_permitted() ) { + self::download_error( __( 'Invalid order.', 'woocommerce' ), '', 403 ); + } + } + } + + /** + * Check if there are downloads remaining. + * + * @param WC_Customer_Download $download Download instance. + */ + private static function check_downloads_remaining( $download ) { + if ( '' !== $download->get_downloads_remaining() && 0 >= $download->get_downloads_remaining() ) { + self::download_error( __( 'Sorry, you have reached your download limit for this file', 'woocommerce' ), '', 403 ); + } + } + + /** + * Check if the download has expired. + * + * @param WC_Customer_Download $download Download instance. + */ + private static function check_download_expiry( $download ) { + if ( ! is_null( $download->get_access_expires() ) && $download->get_access_expires()->getTimestamp() < strtotime( 'midnight', time() ) ) { + self::download_error( __( 'Sorry, this download has expired', 'woocommerce' ), '', 403 ); + } + } + + /** + * Check if a download requires the user to login first. + * + * @param WC_Customer_Download $download Download instance. + */ + private static function check_download_login_required( $download ) { + if ( $download->get_user_id() && 'yes' === get_option( 'woocommerce_downloads_require_login' ) ) { + if ( ! is_user_logged_in() ) { + if ( wc_get_page_id( 'myaccount' ) ) { + wp_safe_redirect( add_query_arg( 'wc_error', rawurlencode( __( 'You must be logged in to download files.', 'woocommerce' ) ), wc_get_page_permalink( 'myaccount' ) ) ); + exit; + } else { + self::download_error( __( 'You must be logged in to download files.', 'woocommerce' ) . ' ' . __( 'Login', 'woocommerce' ) . '', __( 'Log in to Download Files', 'woocommerce' ), 403 ); + } + } elseif ( ! current_user_can( 'download_file', $download ) ) { + self::download_error( __( 'This is not your download link.', 'woocommerce' ), '', 403 ); + } + } + } + + /** + * Count download. + * + * @deprecated 4.4.0 + * @param array $download_data Download data. + */ + public static function count_download( $download_data ) { + wc_deprecated_function( 'WC_Download_Handler::count_download', '4.4.0', '' ); + } + + /** + * Download a file - hook into init function. + * + * @param string $file_path URL to file. + * @param integer $product_id Product ID of the product being downloaded. + */ + public static function download( $file_path, $product_id ) { + if ( ! $file_path ) { + self::download_error( __( 'No file defined', 'woocommerce' ) ); + } + + $filename = basename( $file_path ); + + if ( strstr( $filename, '?' ) ) { + $filename = current( explode( '?', $filename ) ); + } + + $filename = apply_filters( 'woocommerce_file_download_filename', $filename, $product_id ); + + /** + * Filter download method. + * + * @since 4.5.0 + * @param string $method Download method. + * @param int $product_id Product ID. + * @param string $file_path URL to file. + */ + $file_download_method = apply_filters( 'woocommerce_file_download_method', get_option( 'woocommerce_file_download_method', 'force' ), $product_id, $file_path ); + + // Add action to prevent issues in IE. + add_action( 'nocache_headers', array( __CLASS__, 'ie_nocache_headers_fix' ) ); + + // Trigger download via one of the methods. + do_action( 'woocommerce_download_file_' . $file_download_method, $file_path, $filename ); + } + + /** + * Redirect to a file to start the download. + * + * @param string $file_path File path. + * @param string $filename File name. + */ + public static function download_file_redirect( $file_path, $filename = '' ) { + header( 'Location: ' . $file_path ); + exit; + } + + /** + * Parse file path and see if its remote or local. + * + * @param string $file_path File path. + * @return array + */ + public static function parse_file_path( $file_path ) { + $wp_uploads = wp_upload_dir(); + $wp_uploads_dir = $wp_uploads['basedir']; + $wp_uploads_url = $wp_uploads['baseurl']; + + /** + * Replace uploads dir, site url etc with absolute counterparts if we can. + * Note the str_replace on site_url is on purpose, so if https is forced + * via filters we can still do the string replacement on a HTTP file. + */ + $replacements = array( + $wp_uploads_url => $wp_uploads_dir, + network_site_url( '/', 'https' ) => ABSPATH, + str_replace( 'https:', 'http:', network_site_url( '/', 'http' ) ) => ABSPATH, + site_url( '/', 'https' ) => ABSPATH, + str_replace( 'https:', 'http:', site_url( '/', 'http' ) ) => ABSPATH, + ); + + $file_path = str_replace( array_keys( $replacements ), array_values( $replacements ), $file_path ); + $parsed_file_path = wp_parse_url( $file_path ); + $remote_file = true; + + // Paths that begin with '//' are always remote URLs. + if ( '//' === substr( $file_path, 0, 2 ) ) { + return array( + 'remote_file' => true, + 'file_path' => is_ssl() ? 'https:' . $file_path : 'http:' . $file_path, + ); + } + + // See if path needs an abspath prepended to work. + if ( file_exists( ABSPATH . $file_path ) ) { + $remote_file = false; + $file_path = ABSPATH . $file_path; + + } elseif ( '/wp-content' === substr( $file_path, 0, 11 ) ) { + $remote_file = false; + $file_path = realpath( WP_CONTENT_DIR . substr( $file_path, 11 ) ); + + // Check if we have an absolute path. + } elseif ( ( ! isset( $parsed_file_path['scheme'] ) || ! in_array( $parsed_file_path['scheme'], array( 'http', 'https', 'ftp' ), true ) ) && isset( $parsed_file_path['path'] ) && file_exists( $parsed_file_path['path'] ) ) { + $remote_file = false; + $file_path = $parsed_file_path['path']; + } + + return array( + 'remote_file' => $remote_file, + 'file_path' => $file_path, + ); + } + + /** + * Download a file using X-Sendfile, X-Lighttpd-Sendfile, or X-Accel-Redirect if available. + * + * @param string $file_path File path. + * @param string $filename File name. + */ + public static function download_file_xsendfile( $file_path, $filename ) { + $parsed_file_path = self::parse_file_path( $file_path ); + + /** + * Fallback on force download method for remote files. This is because: + * 1. xsendfile needs proxy configuration to work for remote files, which cannot be assumed to be available on most hosts. + * 2. Force download method is more secure than redirect method if `allow_url_fopen` is enabled in `php.ini`. We fallback to redirect method in force download method anyway in case `allow_url_fopen` is not enabled. + */ + if ( $parsed_file_path['remote_file'] && ! apply_filters( 'woocommerce_use_xsendfile_for_remote', false ) ) { + do_action( 'woocommerce_download_file_force', $file_path, $filename ); + return; + } + + if ( function_exists( 'apache_get_modules' ) && in_array( 'mod_xsendfile', apache_get_modules(), true ) ) { + self::download_headers( $parsed_file_path['file_path'], $filename ); + $filepath = apply_filters( 'woocommerce_download_file_xsendfile_file_path', $parsed_file_path['file_path'], $file_path, $filename, $parsed_file_path ); + header( 'X-Sendfile: ' . $filepath ); + exit; + } elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'lighttpd' ) ) { + self::download_headers( $parsed_file_path['file_path'], $filename ); + $filepath = apply_filters( 'woocommerce_download_file_xsendfile_lighttpd_file_path', $parsed_file_path['file_path'], $file_path, $filename, $parsed_file_path ); + header( 'X-Lighttpd-Sendfile: ' . $filepath ); + exit; + } elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'nginx' ) || stristr( getenv( 'SERVER_SOFTWARE' ), 'cherokee' ) ) { + self::download_headers( $parsed_file_path['file_path'], $filename ); + $xsendfile_path = trim( preg_replace( '`^' . str_replace( '\\', '/', getcwd() ) . '`', '', $parsed_file_path['file_path'] ), '/' ); + $xsendfile_path = apply_filters( 'woocommerce_download_file_xsendfile_x_accel_redirect_file_path', $xsendfile_path, $file_path, $filename, $parsed_file_path ); + header( "X-Accel-Redirect: /$xsendfile_path" ); + exit; + } + + // Fallback. + self::download_file_force( $file_path, $filename ); + } + + /** + * Parse the HTTP_RANGE request from iOS devices. + * Does not support multi-range requests. + * + * @param int $file_size Size of file in bytes. + * @return array { + * Information about range download request: beginning and length of + * file chunk, whether the range is valid/supported and whether the request is a range request. + * + * @type int $start Byte offset of the beginning of the range. Default 0. + * @type int $length Length of the requested file chunk in bytes. Optional. + * @type bool $is_range_valid Whether the requested range is a valid and supported range. + * @type bool $is_range_request Whether the request is a range request. + * } + */ + protected static function get_download_range( $file_size ) { + $start = 0; + $download_range = array( + 'start' => $start, + 'is_range_valid' => false, + 'is_range_request' => false, + ); + + if ( ! $file_size ) { + return $download_range; + } + + $end = $file_size - 1; + $download_range['length'] = $file_size; + + if ( isset( $_SERVER['HTTP_RANGE'] ) ) { // @codingStandardsIgnoreLine. + $http_range = sanitize_text_field( wp_unslash( $_SERVER['HTTP_RANGE'] ) ); // WPCS: input var ok. + $download_range['is_range_request'] = true; + + $c_start = $start; + $c_end = $end; + // Extract the range string. + list( , $range ) = explode( '=', $http_range, 2 ); + // Make sure the client hasn't sent us a multibyte range. + if ( strpos( $range, ',' ) !== false ) { + return $download_range; + } + + /* + * If the range starts with an '-' we start from the beginning. + * If not, we forward the file pointer + * and make sure to get the end byte if specified. + */ + if ( '-' === $range[0] ) { + // The n-number of the last bytes is requested. + $c_start = $file_size - substr( $range, 1 ); + } else { + $range = explode( '-', $range ); + $c_start = ( isset( $range[0] ) && is_numeric( $range[0] ) ) ? (int) $range[0] : 0; + $c_end = ( isset( $range[1] ) && is_numeric( $range[1] ) ) ? (int) $range[1] : $file_size; + } + + /* + * Check the range and make sure it's treated according to the specs: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html. + * End bytes can not be larger than $end. + */ + $c_end = ( $c_end > $end ) ? $end : $c_end; + // Validate the requested range and return an error if it's not correct. + if ( $c_start > $c_end || $c_start > $file_size - 1 || $c_end >= $file_size ) { + return $download_range; + } + $start = $c_start; + $end = $c_end; + $length = $end - $start + 1; + + $download_range['start'] = $start; + $download_range['length'] = $length; + $download_range['is_range_valid'] = true; + } + return $download_range; + } + + /** + * Force download - this is the default method. + * + * @param string $file_path File path. + * @param string $filename File name. + */ + public static function download_file_force( $file_path, $filename ) { + $parsed_file_path = self::parse_file_path( $file_path ); + $download_range = self::get_download_range( @filesize( $parsed_file_path['file_path'] ) ); // @codingStandardsIgnoreLine. + + self::download_headers( $parsed_file_path['file_path'], $filename, $download_range ); + + $start = isset( $download_range['start'] ) ? $download_range['start'] : 0; + $length = isset( $download_range['length'] ) ? $download_range['length'] : 0; + if ( ! self::readfile_chunked( $parsed_file_path['file_path'], $start, $length ) ) { + if ( $parsed_file_path['remote_file'] ) { + self::download_file_redirect( $file_path ); + } else { + self::download_error( __( 'File not found', 'woocommerce' ) ); + } + } + + exit; + } + + /** + * Get content type of a download. + * + * @param string $file_path File path. + * @return string + */ + private static function get_download_content_type( $file_path ) { + $file_extension = strtolower( substr( strrchr( $file_path, '.' ), 1 ) ); + $ctype = 'application/force-download'; + + foreach ( get_allowed_mime_types() as $mime => $type ) { + $mimes = explode( '|', $mime ); + if ( in_array( $file_extension, $mimes, true ) ) { + $ctype = $type; + break; + } + } + + return $ctype; + } + + /** + * Set headers for the download. + * + * @param string $file_path File path. + * @param string $filename File name. + * @param array $download_range Array containing info about range download request (see {@see get_download_range} for structure). + */ + private static function download_headers( $file_path, $filename, $download_range = array() ) { + self::check_server_config(); + self::clean_buffers(); + wc_nocache_headers(); + + header( 'X-Robots-Tag: noindex, nofollow', true ); + header( 'Content-Type: ' . self::get_download_content_type( $file_path ) ); + header( 'Content-Description: File Transfer' ); + header( 'Content-Disposition: attachment; filename="' . $filename . '";' ); + header( 'Content-Transfer-Encoding: binary' ); + + $file_size = @filesize( $file_path ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + if ( ! $file_size ) { + return; + } + + if ( isset( $download_range['is_range_request'] ) && true === $download_range['is_range_request'] ) { + if ( false === $download_range['is_range_valid'] ) { + header( 'HTTP/1.1 416 Requested Range Not Satisfiable' ); + header( 'Content-Range: bytes 0-' . ( $file_size - 1 ) . '/' . $file_size ); + exit; + } + + $start = $download_range['start']; + $end = $download_range['start'] + $download_range['length'] - 1; + $length = $download_range['length']; + + header( 'HTTP/1.1 206 Partial Content' ); + header( "Accept-Ranges: 0-$file_size" ); + header( "Content-Range: bytes $start-$end/$file_size" ); + header( "Content-Length: $length" ); + } else { + header( 'Content-Length: ' . $file_size ); + } + } + + /** + * Check and set certain server config variables to ensure downloads work as intended. + */ + private static function check_server_config() { + wc_set_time_limit( 0 ); + if ( function_exists( 'apache_setenv' ) ) { + @apache_setenv( 'no-gzip', 1 ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_apache_setenv + } + @ini_set( 'zlib.output_compression', 'Off' ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_ini_set + @session_write_close(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.VIP.SessionFunctionsUsage.session_session_write_close + } + + /** + * Clean all output buffers. + * + * Can prevent errors, for example: transfer closed with 3 bytes remaining to read. + */ + private static function clean_buffers() { + if ( ob_get_level() ) { + $levels = ob_get_level(); + for ( $i = 0; $i < $levels; $i++ ) { + @ob_end_clean(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + } + } else { + @ob_end_clean(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + } + } + + /** + * Read file chunked. + * + * Reads file in chunks so big downloads are possible without changing PHP.INI - http://codeigniter.com/wiki/Download_helper_for_large_files/. + * + * @param string $file File. + * @param int $start Byte offset/position of the beginning from which to read from the file. + * @param int $length Length of the chunk to be read from the file in bytes, 0 means full file. + * @return bool Success or fail + */ + public static function readfile_chunked( $file, $start = 0, $length = 0 ) { + if ( ! defined( 'WC_CHUNK_SIZE' ) ) { + define( 'WC_CHUNK_SIZE', 1024 * 1024 ); + } + $handle = @fopen( $file, 'r' ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen + + if ( false === $handle ) { + return false; + } + + if ( ! $length ) { + $length = @filesize( $file ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + } + + $read_length = (int) WC_CHUNK_SIZE; + + if ( $length ) { + $end = $start + $length - 1; + + @fseek( $handle, $start ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + $p = @ftell( $handle ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + + while ( ! @feof( $handle ) && $p <= $end ) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + // Don't run past the end of file. + if ( $p + $read_length > $end ) { + $read_length = $end - $p + 1; + } + + echo @fread( $handle, $read_length ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.XSS.EscapeOutput.OutputNotEscaped, WordPress.WP.AlternativeFunctions.file_system_read_fread + $p = @ftell( $handle ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + + if ( ob_get_length() ) { + ob_flush(); + flush(); + } + } + } else { + while ( ! @feof( $handle ) ) { // @codingStandardsIgnoreLine. + echo @fread( $handle, $read_length ); // @codingStandardsIgnoreLine. + if ( ob_get_length() ) { + ob_flush(); + flush(); + } + } + } + + return @fclose( $handle ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fclose + } + + /** + * Filter headers for IE to fix issues over SSL. + * + * IE bug prevents download via SSL when Cache Control and Pragma no-cache headers set. + * + * @param array $headers HTTP headers. + * @return array + */ + public static function ie_nocache_headers_fix( $headers ) { + if ( is_ssl() && ! empty( $GLOBALS['is_IE'] ) ) { + $headers['Cache-Control'] = 'private'; + unset( $headers['Pragma'] ); + } + return $headers; + } + + /** + * Die with an error message if the download fails. + * + * @param string $message Error message. + * @param string $title Error title. + * @param integer $status Error status. + */ + private static function download_error( $message, $title = '', $status = 404 ) { + if ( ! strstr( $message, '' . esc_html__( 'Go to shop', 'woocommerce' ) . ''; + } + wp_die( $message, $title, array( 'response' => $status ) ); // WPCS: XSS ok. + } +} + +WC_Download_Handler::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-emails.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-emails.php new file mode 100644 index 0000000..e4aeb5c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-emails.php @@ -0,0 +1,731 @@ +push_to_queue( + array( + 'filter' => current_filter(), + 'args' => func_get_args(), + ) + ); + } else { + self::send_transactional_email( ...$args ); + } + } + + /** + * Init the mailer instance and call the notifications for the current filter. + * + * @internal + * + * @param string $filter Filter name. + * @param array $args Email args (default: []). + */ + public static function send_queued_transactional_email( $filter = '', $args = array() ) { + if ( apply_filters( 'woocommerce_allow_send_queued_transactional_email', true, $filter, $args ) ) { + self::instance(); // Init self so emails exist. + + // Ensure gateways are loaded in case they need to insert data into the emails. + WC()->payment_gateways(); + WC()->shipping(); + + do_action_ref_array( $filter . '_notification', $args ); + } + } + + /** + * Init the mailer instance and call the notifications for the current filter. + * + * @internal + * + * @param array $args Email args (default: []). + */ + public static function send_transactional_email( $args = array() ) { + try { + $args = func_get_args(); + self::instance(); // Init self so emails exist. + do_action_ref_array( current_filter() . '_notification', $args ); + } catch ( Exception $e ) { + $error = 'Transactional email triggered fatal error for callback ' . current_filter(); + $logger = wc_get_logger(); + $logger->critical( + $error . PHP_EOL, + array( + 'source' => 'transactional-emails', + ) + ); + if ( Constants::is_true( 'WP_DEBUG' ) ) { + trigger_error( $error, E_USER_WARNING ); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped, WordPress.PHP.DevelopmentFunctions.error_log_trigger_error + } + } + } + + /** + * Constructor for the email class hooks in all emails that can be sent. + */ + public function __construct() { + $this->init(); + + // Email Header, Footer and content hooks. + add_action( 'woocommerce_email_header', array( $this, 'email_header' ) ); + add_action( 'woocommerce_email_footer', array( $this, 'email_footer' ) ); + add_action( 'woocommerce_email_order_details', array( $this, 'order_downloads' ), 10, 4 ); + add_action( 'woocommerce_email_order_details', array( $this, 'order_details' ), 10, 4 ); + add_action( 'woocommerce_email_order_meta', array( $this, 'order_meta' ), 10, 3 ); + add_action( 'woocommerce_email_customer_details', array( $this, 'customer_details' ), 10, 3 ); + add_action( 'woocommerce_email_customer_details', array( $this, 'email_addresses' ), 20, 3 ); + + // Hooks for sending emails during store events. + add_action( 'woocommerce_low_stock_notification', array( $this, 'low_stock' ) ); + add_action( 'woocommerce_no_stock_notification', array( $this, 'no_stock' ) ); + add_action( 'woocommerce_product_on_backorder_notification', array( $this, 'backorder' ) ); + add_action( 'woocommerce_created_customer_notification', array( $this, 'customer_new_account' ), 10, 3 ); + + // Hook for replacing {site_title} in email-footer. + add_filter( 'woocommerce_email_footer_text', array( $this, 'replace_placeholders' ) ); + + // Let 3rd parties unhook the above via this hook. + do_action( 'woocommerce_email', $this ); + } + + /** + * Init email classes. + */ + public function init() { + // Include email classes. + include_once dirname( __FILE__ ) . '/emails/class-wc-email.php'; + + $this->emails['WC_Email_New_Order'] = include __DIR__ . '/emails/class-wc-email-new-order.php'; + $this->emails['WC_Email_Cancelled_Order'] = include __DIR__ . '/emails/class-wc-email-cancelled-order.php'; + $this->emails['WC_Email_Failed_Order'] = include __DIR__ . '/emails/class-wc-email-failed-order.php'; + $this->emails['WC_Email_Customer_On_Hold_Order'] = include __DIR__ . '/emails/class-wc-email-customer-on-hold-order.php'; + $this->emails['WC_Email_Customer_Processing_Order'] = include __DIR__ . '/emails/class-wc-email-customer-processing-order.php'; + $this->emails['WC_Email_Customer_Completed_Order'] = include __DIR__ . '/emails/class-wc-email-customer-completed-order.php'; + $this->emails['WC_Email_Customer_Refunded_Order'] = include __DIR__ . '/emails/class-wc-email-customer-refunded-order.php'; + $this->emails['WC_Email_Customer_Invoice'] = include __DIR__ . '/emails/class-wc-email-customer-invoice.php'; + $this->emails['WC_Email_Customer_Note'] = include __DIR__ . '/emails/class-wc-email-customer-note.php'; + $this->emails['WC_Email_Customer_Reset_Password'] = include __DIR__ . '/emails/class-wc-email-customer-reset-password.php'; + $this->emails['WC_Email_Customer_New_Account'] = include __DIR__ . '/emails/class-wc-email-customer-new-account.php'; + + $this->emails = apply_filters( 'woocommerce_email_classes', $this->emails ); + } + + /** + * Return the email classes - used in admin to load settings. + * + * @return WC_Email[] + */ + public function get_emails() { + return $this->emails; + } + + /** + * Get from name for email. + * + * @return string + */ + public function get_from_name() { + return wp_specialchars_decode( get_option( 'woocommerce_email_from_name' ), ENT_QUOTES ); + } + + /** + * Get from email address. + * + * @return string + */ + public function get_from_address() { + return sanitize_email( get_option( 'woocommerce_email_from_address' ) ); + } + + /** + * Get the email header. + * + * @param mixed $email_heading Heading for the email. + */ + public function email_header( $email_heading ) { + wc_get_template( 'emails/email-header.php', array( 'email_heading' => $email_heading ) ); + } + + /** + * Get the email footer. + */ + public function email_footer() { + wc_get_template( 'emails/email-footer.php' ); + } + + /** + * Replace placeholder text in strings. + * + * @since 3.7.0 + * @param string $string Email footer text. + * @return string Email footer text with any replacements done. + */ + public function replace_placeholders( $string ) { + $domain = wp_parse_url( home_url(), PHP_URL_HOST ); + + return str_replace( + array( + '{site_title}', + '{site_address}', + '{site_url}', + '{woocommerce}', + '{WooCommerce}', + ), + array( + $this->get_blogname(), + $domain, + $domain, + 'WooCommerce', + 'WooCommerce', + ), + $string + ); + } + + /** + * Filter callback to replace {site_title} in email footer + * + * @since 3.3.0 + * @deprecated 3.7.0 + * @param string $string Email footer text. + * @return string Email footer text with any replacements done. + */ + public function email_footer_replace_site_title( $string ) { + wc_deprecated_function( 'WC_Emails::email_footer_replace_site_title', '3.7.0', 'WC_Emails::replace_placeholders' ); + return $this->replace_placeholders( $string ); + } + + /** + * Wraps a message in the woocommerce mail template. + * + * @param string $email_heading Heading text. + * @param string $message Email message. + * @param bool $plain_text Set true to send as plain text. Default to false. + * + * @return string + */ + public function wrap_message( $email_heading, $message, $plain_text = false ) { + // Buffer. + ob_start(); + + do_action( 'woocommerce_email_header', $email_heading, null ); + + echo wpautop( wptexturize( $message ) ); // WPCS: XSS ok. + + do_action( 'woocommerce_email_footer', null ); + + // Get contents. + $message = ob_get_clean(); + + return $message; + } + + /** + * Send the email. + * + * @param mixed $to Receiver. + * @param mixed $subject Email subject. + * @param mixed $message Message. + * @param string $headers Email headers (default: "Content-Type: text/html\r\n"). + * @param string $attachments Attachments (default: ""). + * @return bool + */ + public function send( $to, $subject, $message, $headers = "Content-Type: text/html\r\n", $attachments = '' ) { + // Send. + $email = new WC_Email(); + return $email->send( $to, $subject, $message, $headers, $attachments ); + } + + /** + * Prepare and send the customer invoice email on demand. + * + * @param int|WC_Order $order Order instance or ID. + */ + public function customer_invoice( $order ) { + $email = $this->emails['WC_Email_Customer_Invoice']; + + if ( ! is_object( $order ) ) { + $order = wc_get_order( absint( $order ) ); + } + + $email->trigger( $order->get_id(), $order ); + } + + /** + * Customer new account welcome email. + * + * @param int $customer_id Customer ID. + * @param array $new_customer_data New customer data. + * @param bool $password_generated If password is generated. + */ + public function customer_new_account( $customer_id, $new_customer_data = array(), $password_generated = false ) { + if ( ! $customer_id ) { + return; + } + + $user_pass = ! empty( $new_customer_data['user_pass'] ) ? $new_customer_data['user_pass'] : ''; + + $email = $this->emails['WC_Email_Customer_New_Account']; + $email->trigger( $customer_id, $user_pass, $password_generated ); + } + + /** + * Show the order details table + * + * @param WC_Order $order Order instance. + * @param bool $sent_to_admin If should sent to admin. + * @param bool $plain_text If is plain text email. + * @param string $email Email address. + */ + public function order_details( $order, $sent_to_admin = false, $plain_text = false, $email = '' ) { + if ( $plain_text ) { + wc_get_template( + 'emails/plain/email-order-details.php', + array( + 'order' => $order, + 'sent_to_admin' => $sent_to_admin, + 'plain_text' => $plain_text, + 'email' => $email, + ) + ); + } else { + wc_get_template( + 'emails/email-order-details.php', + array( + 'order' => $order, + 'sent_to_admin' => $sent_to_admin, + 'plain_text' => $plain_text, + 'email' => $email, + ) + ); + } + } + + /** + * Show order downloads in a table. + * + * @since 3.2.0 + * @param WC_Order $order Order instance. + * @param bool $sent_to_admin If should sent to admin. + * @param bool $plain_text If is plain text email. + * @param string $email Email address. + */ + public function order_downloads( $order, $sent_to_admin = false, $plain_text = false, $email = '' ) { + $show_downloads = $order->has_downloadable_item() && $order->is_download_permitted() && ! $sent_to_admin && ! is_a( $email, 'WC_Email_Customer_Refunded_Order' ); + + if ( ! $show_downloads ) { + return; + } + + $downloads = $order->get_downloadable_items(); + $columns = apply_filters( + 'woocommerce_email_downloads_columns', + array( + 'download-product' => __( 'Product', 'woocommerce' ), + 'download-expires' => __( 'Expires', 'woocommerce' ), + 'download-file' => __( 'Download', 'woocommerce' ), + ) + ); + + if ( $plain_text ) { + wc_get_template( + 'emails/plain/email-downloads.php', + array( + 'order' => $order, + 'sent_to_admin' => $sent_to_admin, + 'plain_text' => $plain_text, + 'email' => $email, + 'downloads' => $downloads, + 'columns' => $columns, + ) + ); + } else { + wc_get_template( + 'emails/email-downloads.php', + array( + 'order' => $order, + 'sent_to_admin' => $sent_to_admin, + 'plain_text' => $plain_text, + 'email' => $email, + 'downloads' => $downloads, + 'columns' => $columns, + ) + ); + } + } + + /** + * Add order meta to email templates. + * + * @param WC_Order $order Order instance. + * @param bool $sent_to_admin If should sent to admin. + * @param bool $plain_text If is plain text email. + */ + public function order_meta( $order, $sent_to_admin = false, $plain_text = false ) { + $fields = apply_filters( 'woocommerce_email_order_meta_fields', array(), $sent_to_admin, $order ); + + /** + * Deprecated woocommerce_email_order_meta_keys filter. + * + * @since 2.3.0 + */ + $_fields = apply_filters( 'woocommerce_email_order_meta_keys', array(), $sent_to_admin ); + + if ( $_fields ) { + foreach ( $_fields as $key => $field ) { + if ( is_numeric( $key ) ) { + $key = $field; + } + + $fields[ $key ] = array( + 'label' => wptexturize( $key ), + 'value' => wptexturize( get_post_meta( $order->get_id(), $field, true ) ), + ); + } + } + + if ( $fields ) { + + if ( $plain_text ) { + + foreach ( $fields as $field ) { + if ( isset( $field['label'] ) && isset( $field['value'] ) && $field['value'] ) { + echo $field['label'] . ': ' . $field['value'] . "\n"; // WPCS: XSS ok. + } + } + } else { + + foreach ( $fields as $field ) { + if ( isset( $field['label'] ) && isset( $field['value'] ) && $field['value'] ) { + echo '

    ' . $field['label'] . ': ' . $field['value'] . '

    '; // WPCS: XSS ok. + } + } + } + } + } + + /** + * Is customer detail field valid? + * + * @param array $field Field data to check if is valid. + * @return boolean + */ + public function customer_detail_field_is_valid( $field ) { + return isset( $field['label'] ) && ! empty( $field['value'] ); + } + + /** + * Allows developers to add additional customer details to templates. + * + * In versions prior to 3.2 this was used for notes, phone and email but this data has moved. + * + * @param WC_Order $order Order instance. + * @param bool $sent_to_admin If should sent to admin. + * @param bool $plain_text If is plain text email. + */ + public function customer_details( $order, $sent_to_admin = false, $plain_text = false ) { + if ( ! is_a( $order, 'WC_Order' ) ) { + return; + } + + $fields = array_filter( apply_filters( 'woocommerce_email_customer_details_fields', array(), $sent_to_admin, $order ), array( $this, 'customer_detail_field_is_valid' ) ); + + if ( ! empty( $fields ) ) { + if ( $plain_text ) { + wc_get_template( 'emails/plain/email-customer-details.php', array( 'fields' => $fields ) ); + } else { + wc_get_template( 'emails/email-customer-details.php', array( 'fields' => $fields ) ); + } + } + } + + /** + * Get the email addresses. + * + * @param WC_Order $order Order instance. + * @param bool $sent_to_admin If should sent to admin. + * @param bool $plain_text If is plain text email. + */ + public function email_addresses( $order, $sent_to_admin = false, $plain_text = false ) { + if ( ! is_a( $order, 'WC_Order' ) ) { + return; + } + if ( $plain_text ) { + wc_get_template( + 'emails/plain/email-addresses.php', + array( + 'order' => $order, + 'sent_to_admin' => $sent_to_admin, + ) + ); + } else { + wc_get_template( + 'emails/email-addresses.php', + array( + 'order' => $order, + 'sent_to_admin' => $sent_to_admin, + ) + ); + } + } + + /** + * Get blog name formatted for emails. + * + * @return string + */ + private function get_blogname() { + return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + } + + /** + * Low stock notification email. + * + * @param WC_Product $product Product instance. + */ + public function low_stock( $product ) { + if ( 'no' === get_option( 'woocommerce_notify_low_stock', 'yes' ) ) { + return; + } + + /** + * Determine if the current product should trigger a low stock notification + * + * @param int $product_id - The low stock product id + * + * @since 4.7.0 + */ + if ( false === apply_filters( 'woocommerce_should_send_low_stock_notification', true, $product->get_id() ) ) { + return; + } + + $subject = sprintf( '[%s] %s', $this->get_blogname(), __( 'Product low in stock', 'woocommerce' ) ); + $message = sprintf( + /* translators: 1: product name 2: items in stock */ + __( '%1$s is low in stock. There are %2$d left.', 'woocommerce' ), + html_entity_decode( wp_strip_all_tags( $product->get_formatted_name() ), ENT_QUOTES, get_bloginfo( 'charset' ) ), + html_entity_decode( wp_strip_all_tags( $product->get_stock_quantity() ) ) + ); + + wp_mail( + apply_filters( 'woocommerce_email_recipient_low_stock', get_option( 'woocommerce_stock_email_recipient' ), $product, null ), + apply_filters( 'woocommerce_email_subject_low_stock', $subject, $product, null ), + apply_filters( 'woocommerce_email_content_low_stock', $message, $product ), + apply_filters( 'woocommerce_email_headers', '', 'low_stock', $product, null ), + apply_filters( 'woocommerce_email_attachments', array(), 'low_stock', $product, null ) + ); + } + + /** + * No stock notification email. + * + * @param WC_Product $product Product instance. + */ + public function no_stock( $product ) { + if ( 'no' === get_option( 'woocommerce_notify_no_stock', 'yes' ) ) { + return; + } + + /** + * Determine if the current product should trigger a no stock notification + * + * @param int $product_id - The out of stock product id + * + * @since 4.6.0 + */ + if ( false === apply_filters( 'woocommerce_should_send_no_stock_notification', true, $product->get_id() ) ) { + return; + } + + $subject = sprintf( '[%s] %s', $this->get_blogname(), __( 'Product out of stock', 'woocommerce' ) ); + /* translators: %s: product name */ + $message = sprintf( __( '%s is out of stock.', 'woocommerce' ), html_entity_decode( wp_strip_all_tags( $product->get_formatted_name() ), ENT_QUOTES, get_bloginfo( 'charset' ) ) ); + + wp_mail( + apply_filters( 'woocommerce_email_recipient_no_stock', get_option( 'woocommerce_stock_email_recipient' ), $product, null ), + apply_filters( 'woocommerce_email_subject_no_stock', $subject, $product, null ), + apply_filters( 'woocommerce_email_content_no_stock', $message, $product ), + apply_filters( 'woocommerce_email_headers', '', 'no_stock', $product, null ), + apply_filters( 'woocommerce_email_attachments', array(), 'no_stock', $product, null ) + ); + } + + /** + * Backorder notification email. + * + * @param array $args Arguments. + */ + public function backorder( $args ) { + $args = wp_parse_args( + $args, + array( + 'product' => '', + 'quantity' => '', + 'order_id' => '', + ) + ); + + $order = wc_get_order( $args['order_id'] ); + if ( + ! $args['product'] || + ! is_object( $args['product'] ) || + ! $args['quantity'] || + ! $order + ) { + return; + } + + $subject = sprintf( '[%s] %s', $this->get_blogname(), __( 'Product backorder', 'woocommerce' ) ); + /* translators: 1: product quantity 2: product name 3: order number */ + $message = sprintf( __( '%1$s units of %2$s have been backordered in order #%3$s.', 'woocommerce' ), $args['quantity'], html_entity_decode( wp_strip_all_tags( $args['product']->get_formatted_name() ), ENT_QUOTES, get_bloginfo( 'charset' ) ), $order->get_order_number() ); + + wp_mail( + apply_filters( 'woocommerce_email_recipient_backorder', get_option( 'woocommerce_stock_email_recipient' ), $args, null ), + apply_filters( 'woocommerce_email_subject_backorder', $subject, $args, null ), + apply_filters( 'woocommerce_email_content_backorder', $message, $args ), + apply_filters( 'woocommerce_email_headers', '', 'backorder', $args, null ), + apply_filters( 'woocommerce_email_attachments', array(), 'backorder', $args, null ) + ); + } + + /** + * Adds Schema.org markup for order in JSON-LD format. + * + * @deprecated 3.0.0 + * @see WC_Structured_Data::generate_order_data() + * + * @since 2.6.0 + * @param WC_Order $order Order instance. + * @param bool $sent_to_admin If should sent to admin. + * @param bool $plain_text If is plain text email. + */ + public function order_schema_markup( $order, $sent_to_admin = false, $plain_text = false ) { + wc_deprecated_function( 'WC_Emails::order_schema_markup', '3.0', 'WC_Structured_Data::generate_order_data' ); + + WC()->structured_data->generate_order_data( $order, $sent_to_admin, $plain_text ); + WC()->structured_data->output_structured_data(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-embed.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-embed.php new file mode 100644 index 0000000..da14279 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-embed.php @@ -0,0 +1,178 @@ +' . $_product->get_price_html() . '

    '; // WPCS: XSS ok. + + if ( ! empty( $post->post_excerpt ) ) { + ob_start(); + woocommerce_template_single_excerpt(); + $excerpt = ob_get_clean(); + } + + // Add the button. + $excerpt .= self::product_buttons(); + } + return $excerpt; + } + + /** + * Create the button to go to the product page for embedded products. + * + * @since 2.4.11 + * @return string + */ + public static function product_buttons() { + $_product = wc_get_product( get_the_ID() ); + $buttons = array(); + $button = '%s'; + + if ( $_product->is_type( 'simple' ) && $_product->is_purchasable() && $_product->is_in_stock() ) { + $buttons[] = sprintf( $button, esc_url( add_query_arg( 'add-to-cart', get_the_ID(), wc_get_cart_url() ) ), esc_html__( 'Buy now', 'woocommerce' ) ); + } + + $buttons[] = sprintf( $button, get_the_permalink(), esc_html__( 'Read more', 'woocommerce' ) ); + + return '

    ' . implode( ' ', $buttons ) . '

    '; + } + + /** + * Prints the markup for the rating stars. + * + * @since 2.4.11 + */ + public static function get_ratings() { + // Make sure we're only affecting embedded products. + if ( ! self::is_embedded_product() ) { + return; + } + + $_product = wc_get_product( get_the_ID() ); + + if ( $_product && $_product->get_average_rating() > 0 ) { + ?> +
    + get_average_rating() ) + ); + ?> +
    + + + ID : 0; + } else { + $user_id = absint( $_GET['id'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + } + + // If the reset token is not for the current user, ignore the reset request (don't redirect). + $logged_in_user_id = get_current_user_id(); + if ( $logged_in_user_id && $logged_in_user_id !== $user_id ) { + wc_add_notice( __( 'This password reset key is for a different user account. Please log out and try again.', 'woocommerce' ), 'error' ); + return; + } + + $action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; + $value = sprintf( '%d:%s', $user_id, wp_unslash( $_GET['key'] ) ); // phpcs:ignore + WC_Shortcode_My_Account::set_reset_password_cookie( $value ); + wp_safe_redirect( + add_query_arg( + array( + 'show-reset-form' => 'true', + 'action' => $action, + ), + wc_lostpassword_url() + ) + ); + exit; + } + } + + /** + * Save and and update a billing or shipping address if the + * form was submitted through the user account page. + */ + public static function save_address() { + global $wp; + + $nonce_value = wc_get_var( $_REQUEST['woocommerce-edit-address-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + if ( ! wp_verify_nonce( $nonce_value, 'woocommerce-edit_address' ) ) { + return; + } + + if ( empty( $_POST['action'] ) || 'edit_address' !== $_POST['action'] ) { + return; + } + + wc_nocache_headers(); + + $user_id = get_current_user_id(); + + if ( $user_id <= 0 ) { + return; + } + + $customer = new WC_Customer( $user_id ); + + if ( ! $customer ) { + return; + } + + $load_address = isset( $wp->query_vars['edit-address'] ) ? wc_edit_address_i18n( sanitize_title( $wp->query_vars['edit-address'] ), true ) : 'billing'; + + if ( ! isset( $_POST[ $load_address . '_country' ] ) ) { + return; + } + + $address = WC()->countries->get_address_fields( wc_clean( wp_unslash( $_POST[ $load_address . '_country' ] ) ), $load_address . '_' ); + + foreach ( $address as $key => $field ) { + if ( ! isset( $field['type'] ) ) { + $field['type'] = 'text'; + } + + // Get Value. + if ( 'checkbox' === $field['type'] ) { + $value = (int) isset( $_POST[ $key ] ); + } else { + $value = isset( $_POST[ $key ] ) ? wc_clean( wp_unslash( $_POST[ $key ] ) ) : ''; + } + + // Hook to allow modification of value. + $value = apply_filters( 'woocommerce_process_myaccount_field_' . $key, $value ); + + // Validation: Required fields. + if ( ! empty( $field['required'] ) && empty( $value ) ) { + /* translators: %s: Field name. */ + wc_add_notice( sprintf( __( '%s is a required field.', 'woocommerce' ), $field['label'] ), 'error', array( 'id' => $key ) ); + } + + if ( ! empty( $value ) ) { + // Validation and formatting rules. + if ( ! empty( $field['validate'] ) && is_array( $field['validate'] ) ) { + foreach ( $field['validate'] as $rule ) { + switch ( $rule ) { + case 'postcode': + $country = wc_clean( wp_unslash( $_POST[ $load_address . '_country' ] ) ); + $value = wc_format_postcode( $value, $country ); + + if ( '' !== $value && ! WC_Validation::is_postcode( $value, $country ) ) { + switch ( $country ) { + case 'IE': + $postcode_validation_notice = __( 'Please enter a valid Eircode.', 'woocommerce' ); + break; + default: + $postcode_validation_notice = __( 'Please enter a valid postcode / ZIP.', 'woocommerce' ); + } + wc_add_notice( $postcode_validation_notice, 'error' ); + } + break; + case 'phone': + if ( '' !== $value && ! WC_Validation::is_phone( $value ) ) { + /* translators: %s: Phone number. */ + wc_add_notice( sprintf( __( '%s is not a valid phone number.', 'woocommerce' ), '' . $field['label'] . '' ), 'error' ); + } + break; + case 'email': + $value = strtolower( $value ); + + if ( ! is_email( $value ) ) { + /* translators: %s: Email address. */ + wc_add_notice( sprintf( __( '%s is not a valid email address.', 'woocommerce' ), '' . $field['label'] . '' ), 'error' ); + } + break; + } + } + } + } + + try { + // Set prop in customer object. + if ( is_callable( array( $customer, "set_$key" ) ) ) { + $customer->{"set_$key"}( $value ); + } else { + $customer->update_meta_data( $key, $value ); + } + } catch ( WC_Data_Exception $e ) { + // Set notices. Ignore invalid billing email, since is already validated. + if ( 'customer_invalid_billing_email' !== $e->getErrorCode() ) { + wc_add_notice( $e->getMessage(), 'error' ); + } + } + } + + /** + * Hook: woocommerce_after_save_address_validation. + * + * Allow developers to add custom validation logic and throw an error to prevent save. + * + * @param int $user_id User ID being saved. + * @param string $load_address Type of address e.g. billing or shipping. + * @param array $address The address fields. + * @param WC_Customer $customer The customer object being saved. @since 3.6.0 + */ + do_action( 'woocommerce_after_save_address_validation', $user_id, $load_address, $address, $customer ); + + if ( 0 < wc_notice_count( 'error' ) ) { + return; + } + + $customer->save(); + + wc_add_notice( __( 'Address changed successfully.', 'woocommerce' ) ); + + do_action( 'woocommerce_customer_save_address', $user_id, $load_address ); + + wp_safe_redirect( wc_get_endpoint_url( 'edit-address', '', wc_get_page_permalink( 'myaccount' ) ) ); + exit; + } + + /** + * Save the password/account details and redirect back to the my account page. + */ + public static function save_account_details() { + $nonce_value = wc_get_var( $_REQUEST['save-account-details-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + if ( ! wp_verify_nonce( $nonce_value, 'save_account_details' ) ) { + return; + } + + if ( empty( $_POST['action'] ) || 'save_account_details' !== $_POST['action'] ) { + return; + } + + wc_nocache_headers(); + + $user_id = get_current_user_id(); + + if ( $user_id <= 0 ) { + return; + } + + $account_first_name = ! empty( $_POST['account_first_name'] ) ? wc_clean( wp_unslash( $_POST['account_first_name'] ) ) : ''; + $account_last_name = ! empty( $_POST['account_last_name'] ) ? wc_clean( wp_unslash( $_POST['account_last_name'] ) ) : ''; + $account_display_name = ! empty( $_POST['account_display_name'] ) ? wc_clean( wp_unslash( $_POST['account_display_name'] ) ) : ''; + $account_email = ! empty( $_POST['account_email'] ) ? wc_clean( wp_unslash( $_POST['account_email'] ) ) : ''; + $pass_cur = ! empty( $_POST['password_current'] ) ? $_POST['password_current'] : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $pass1 = ! empty( $_POST['password_1'] ) ? $_POST['password_1'] : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $pass2 = ! empty( $_POST['password_2'] ) ? $_POST['password_2'] : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $save_pass = true; + + // Current user data. + $current_user = get_user_by( 'id', $user_id ); + $current_first_name = $current_user->first_name; + $current_last_name = $current_user->last_name; + $current_email = $current_user->user_email; + + // New user data. + $user = new stdClass(); + $user->ID = $user_id; + $user->first_name = $account_first_name; + $user->last_name = $account_last_name; + $user->display_name = $account_display_name; + + // Prevent display name to be changed to email. + if ( is_email( $account_display_name ) ) { + wc_add_notice( __( 'Display name cannot be changed to email address due to privacy concern.', 'woocommerce' ), 'error' ); + } + + // Handle required fields. + $required_fields = apply_filters( + 'woocommerce_save_account_details_required_fields', + array( + 'account_first_name' => __( 'First name', 'woocommerce' ), + 'account_last_name' => __( 'Last name', 'woocommerce' ), + 'account_display_name' => __( 'Display name', 'woocommerce' ), + 'account_email' => __( 'Email address', 'woocommerce' ), + ) + ); + + foreach ( $required_fields as $field_key => $field_name ) { + if ( empty( $_POST[ $field_key ] ) ) { + /* translators: %s: Field name. */ + wc_add_notice( sprintf( __( '%s is a required field.', 'woocommerce' ), '' . esc_html( $field_name ) . '' ), 'error', array( 'id' => $field_key ) ); + } + } + + if ( $account_email ) { + $account_email = sanitize_email( $account_email ); + if ( ! is_email( $account_email ) ) { + wc_add_notice( __( 'Please provide a valid email address.', 'woocommerce' ), 'error' ); + } elseif ( email_exists( $account_email ) && $account_email !== $current_user->user_email ) { + wc_add_notice( __( 'This email address is already registered.', 'woocommerce' ), 'error' ); + } + $user->user_email = $account_email; + } + + if ( ! empty( $pass_cur ) && empty( $pass1 ) && empty( $pass2 ) ) { + wc_add_notice( __( 'Please fill out all password fields.', 'woocommerce' ), 'error' ); + $save_pass = false; + } elseif ( ! empty( $pass1 ) && empty( $pass_cur ) ) { + wc_add_notice( __( 'Please enter your current password.', 'woocommerce' ), 'error' ); + $save_pass = false; + } elseif ( ! empty( $pass1 ) && empty( $pass2 ) ) { + wc_add_notice( __( 'Please re-enter your password.', 'woocommerce' ), 'error' ); + $save_pass = false; + } elseif ( ( ! empty( $pass1 ) || ! empty( $pass2 ) ) && $pass1 !== $pass2 ) { + wc_add_notice( __( 'New passwords do not match.', 'woocommerce' ), 'error' ); + $save_pass = false; + } elseif ( ! empty( $pass1 ) && ! wp_check_password( $pass_cur, $current_user->user_pass, $current_user->ID ) ) { + wc_add_notice( __( 'Your current password is incorrect.', 'woocommerce' ), 'error' ); + $save_pass = false; + } + + if ( $pass1 && $save_pass ) { + $user->user_pass = $pass1; + } + + // Allow plugins to return their own errors. + $errors = new WP_Error(); + do_action_ref_array( 'woocommerce_save_account_details_errors', array( &$errors, &$user ) ); + + if ( $errors->get_error_messages() ) { + foreach ( $errors->get_error_messages() as $error ) { + wc_add_notice( $error, 'error' ); + } + } + + if ( wc_notice_count( 'error' ) === 0 ) { + wp_update_user( $user ); + + // Update customer object to keep data in sync. + $customer = new WC_Customer( $user->ID ); + + if ( $customer ) { + // Keep billing data in sync if data changed. + if ( is_email( $user->user_email ) && $current_email !== $user->user_email ) { + $customer->set_billing_email( $user->user_email ); + } + + if ( $current_first_name !== $user->first_name ) { + $customer->set_billing_first_name( $user->first_name ); + } + + if ( $current_last_name !== $user->last_name ) { + $customer->set_billing_last_name( $user->last_name ); + } + + $customer->save(); + } + + wc_add_notice( __( 'Account details changed successfully.', 'woocommerce' ) ); + + do_action( 'woocommerce_save_account_details', $user->ID ); + + wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) ); + exit; + } + } + + /** + * Process the checkout form. + */ + public static function checkout_action() { + if ( isset( $_POST['woocommerce_checkout_place_order'] ) || isset( $_POST['woocommerce_checkout_update_totals'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing + wc_nocache_headers(); + + if ( WC()->cart->is_empty() ) { + wp_safe_redirect( wc_get_cart_url() ); + exit; + } + + wc_maybe_define_constant( 'WOOCOMMERCE_CHECKOUT', true ); + + WC()->checkout()->process_checkout(); + } + } + + /** + * Process the pay form. + * + * @throws Exception On payment error. + */ + public static function pay_action() { + global $wp; + + if ( isset( $_POST['woocommerce_pay'], $_GET['key'] ) ) { + wc_nocache_headers(); + + $nonce_value = wc_get_var( $_REQUEST['woocommerce-pay-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + if ( ! wp_verify_nonce( $nonce_value, 'woocommerce-pay' ) ) { + return; + } + + ob_start(); + + // Pay for existing order. + $order_key = wp_unslash( $_GET['key'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $order_id = absint( $wp->query_vars['order-pay'] ); + $order = wc_get_order( $order_id ); + + if ( $order_id === $order->get_id() && hash_equals( $order->get_order_key(), $order_key ) && $order->needs_payment() ) { + + do_action( 'woocommerce_before_pay_action', $order ); + + WC()->customer->set_props( + array( + 'billing_country' => $order->get_billing_country() ? $order->get_billing_country() : null, + 'billing_state' => $order->get_billing_state() ? $order->get_billing_state() : null, + 'billing_postcode' => $order->get_billing_postcode() ? $order->get_billing_postcode() : null, + 'billing_city' => $order->get_billing_city() ? $order->get_billing_city() : null, + ) + ); + WC()->customer->save(); + + if ( ! empty( $_POST['terms-field'] ) && empty( $_POST['terms'] ) ) { + wc_add_notice( __( 'Please read and accept the terms and conditions to proceed with your order.', 'woocommerce' ), 'error' ); + return; + } + + // Update payment method. + if ( $order->needs_payment() ) { + try { + $payment_method_id = isset( $_POST['payment_method'] ) ? wc_clean( wp_unslash( $_POST['payment_method'] ) ) : false; + + if ( ! $payment_method_id ) { + throw new Exception( __( 'Invalid payment method.', 'woocommerce' ) ); + } + + $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); + $payment_method = isset( $available_gateways[ $payment_method_id ] ) ? $available_gateways[ $payment_method_id ] : false; + + if ( ! $payment_method ) { + throw new Exception( __( 'Invalid payment method.', 'woocommerce' ) ); + } + + $order->set_payment_method( $payment_method ); + $order->save(); + + $payment_method->validate_fields(); + + if ( 0 === wc_notice_count( 'error' ) ) { + + $result = $payment_method->process_payment( $order_id ); + + // Redirect to success/confirmation/payment page. + if ( isset( $result['result'] ) && 'success' === $result['result'] ) { + $result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id ); + + wp_redirect( $result['redirect'] ); //phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect + exit; + } + } + } catch ( Exception $e ) { + wc_add_notice( $e->getMessage(), 'error' ); + } + } else { + // No payment was required for order. + $order->payment_complete(); + wp_safe_redirect( $order->get_checkout_order_received_url() ); + exit; + } + + do_action( 'woocommerce_after_pay_action', $order ); + + } + } + } + + /** + * Process the add payment method form. + */ + public static function add_payment_method_action() { + if ( isset( $_POST['woocommerce_add_payment_method'], $_POST['payment_method'] ) ) { + wc_nocache_headers(); + + $nonce_value = wc_get_var( $_REQUEST['woocommerce-add-payment-method-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + if ( ! wp_verify_nonce( $nonce_value, 'woocommerce-add-payment-method' ) ) { + return; + } + + if ( ! apply_filters( 'woocommerce_add_payment_method_form_is_valid', true ) ) { + return; + } + + // Test rate limit. + $current_user_id = get_current_user_id(); + $rate_limit_id = 'add_payment_method_' . $current_user_id; + $delay = (int) apply_filters( 'woocommerce_payment_gateway_add_payment_method_delay', 20 ); + + if ( WC_Rate_Limiter::retried_too_soon( $rate_limit_id ) ) { + wc_add_notice( + sprintf( + /* translators: %d number of seconds */ + _n( + 'You cannot add a new payment method so soon after the previous one. Please wait for %d second.', + 'You cannot add a new payment method so soon after the previous one. Please wait for %d seconds.', + $delay, + 'woocommerce' + ), + $delay + ), + 'error' + ); + return; + } + + WC_Rate_Limiter::set_rate_limit( $rate_limit_id, $delay ); + + ob_start(); + + $payment_method_id = wc_clean( wp_unslash( $_POST['payment_method'] ) ); + $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); + + if ( isset( $available_gateways[ $payment_method_id ] ) ) { + $gateway = $available_gateways[ $payment_method_id ]; + + if ( ! $gateway->supports( 'add_payment_method' ) && ! $gateway->supports( 'tokenization' ) ) { + wc_add_notice( __( 'Invalid payment gateway.', 'woocommerce' ), 'error' ); + return; + } + + $gateway->validate_fields(); + + if ( wc_notice_count( 'error' ) > 0 ) { + return; + } + + $result = $gateway->add_payment_method(); + + if ( 'success' === $result['result'] ) { + wc_add_notice( __( 'Payment method successfully added.', 'woocommerce' ) ); + } + + if ( 'failure' === $result['result'] ) { + wc_add_notice( __( 'Unable to add payment method to your account.', 'woocommerce' ), 'error' ); + } + + if ( ! empty( $result['redirect'] ) ) { + wp_redirect( $result['redirect'] ); //phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect + exit(); + } + } + } + } + + /** + * Process the delete payment method form. + */ + public static function delete_payment_method_action() { + global $wp; + + if ( isset( $wp->query_vars['delete-payment-method'] ) ) { + wc_nocache_headers(); + + $token_id = absint( $wp->query_vars['delete-payment-method'] ); + $token = WC_Payment_Tokens::get( $token_id ); + + if ( is_null( $token ) || get_current_user_id() !== $token->get_user_id() || ! isset( $_REQUEST['_wpnonce'] ) || false === wp_verify_nonce( wp_unslash( $_REQUEST['_wpnonce'] ), 'delete-payment-method-' . $token_id ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + wc_add_notice( __( 'Invalid payment method.', 'woocommerce' ), 'error' ); + } else { + WC_Payment_Tokens::delete( $token_id ); + wc_add_notice( __( 'Payment method deleted.', 'woocommerce' ) ); + } + + wp_safe_redirect( wc_get_account_endpoint_url( 'payment-methods' ) ); + exit(); + } + + } + + /** + * Process the delete payment method form. + */ + public static function set_default_payment_method_action() { + global $wp; + + if ( isset( $wp->query_vars['set-default-payment-method'] ) ) { + wc_nocache_headers(); + + $token_id = absint( $wp->query_vars['set-default-payment-method'] ); + $token = WC_Payment_Tokens::get( $token_id ); + + if ( is_null( $token ) || get_current_user_id() !== $token->get_user_id() || ! isset( $_REQUEST['_wpnonce'] ) || false === wp_verify_nonce( wp_unslash( $_REQUEST['_wpnonce'] ), 'set-default-payment-method-' . $token_id ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + wc_add_notice( __( 'Invalid payment method.', 'woocommerce' ), 'error' ); + } else { + WC_Payment_Tokens::set_users_default( $token->get_user_id(), intval( $token_id ) ); + wc_add_notice( __( 'This payment method was successfully set as your default.', 'woocommerce' ) ); + } + + wp_safe_redirect( wc_get_account_endpoint_url( 'payment-methods' ) ); + exit(); + } + + } + + /** + * Remove from cart/update. + */ + public static function update_cart_action() { + if ( ! ( isset( $_REQUEST['apply_coupon'] ) || isset( $_REQUEST['remove_coupon'] ) || isset( $_REQUEST['remove_item'] ) || isset( $_REQUEST['undo_item'] ) || isset( $_REQUEST['update_cart'] ) || isset( $_REQUEST['proceed'] ) ) ) { + return; + } + + wc_nocache_headers(); + + $nonce_value = wc_get_var( $_REQUEST['woocommerce-cart-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + if ( ! empty( $_POST['apply_coupon'] ) && ! empty( $_POST['coupon_code'] ) ) { + WC()->cart->add_discount( wc_format_coupon_code( wp_unslash( $_POST['coupon_code'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + } elseif ( isset( $_GET['remove_coupon'] ) ) { + WC()->cart->remove_coupon( wc_format_coupon_code( urldecode( wp_unslash( $_GET['remove_coupon'] ) ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + } elseif ( ! empty( $_GET['remove_item'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-cart' ) ) { + $cart_item_key = sanitize_text_field( wp_unslash( $_GET['remove_item'] ) ); + $cart_item = WC()->cart->get_cart_item( $cart_item_key ); + + if ( $cart_item ) { + WC()->cart->remove_cart_item( $cart_item_key ); + + $product = wc_get_product( $cart_item['product_id'] ); + + /* translators: %s: Item name. */ + $item_removed_title = apply_filters( 'woocommerce_cart_item_removed_title', $product ? sprintf( _x( '“%s”', 'Item name in quotes', 'woocommerce' ), $product->get_name() ) : __( 'Item', 'woocommerce' ), $cart_item ); + + // Don't show undo link if removed item is out of stock. + if ( $product && $product->is_in_stock() && $product->has_enough_stock( $cart_item['quantity'] ) ) { + /* Translators: %s Product title. */ + $removed_notice = sprintf( __( '%s removed.', 'woocommerce' ), $item_removed_title ); + $removed_notice .= ' ' . __( 'Undo?', 'woocommerce' ) . ''; + } else { + /* Translators: %s Product title. */ + $removed_notice = sprintf( __( '%s removed.', 'woocommerce' ), $item_removed_title ); + } + + wc_add_notice( $removed_notice, apply_filters( 'woocommerce_cart_item_removed_notice_type', 'success' ) ); + } + + $referer = wp_get_referer() ? remove_query_arg( array( 'remove_item', 'add-to-cart', 'added-to-cart', 'order_again', '_wpnonce' ), add_query_arg( 'removed_item', '1', wp_get_referer() ) ) : wc_get_cart_url(); + wp_safe_redirect( $referer ); + exit; + + } elseif ( ! empty( $_GET['undo_item'] ) && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-cart' ) ) { + + // Undo Cart Item. + $cart_item_key = sanitize_text_field( wp_unslash( $_GET['undo_item'] ) ); + + WC()->cart->restore_cart_item( $cart_item_key ); + + $referer = wp_get_referer() ? remove_query_arg( array( 'undo_item', '_wpnonce' ), wp_get_referer() ) : wc_get_cart_url(); + wp_safe_redirect( $referer ); + exit; + + } + + // Update Cart - checks apply_coupon too because they are in the same form. + if ( ( ! empty( $_POST['apply_coupon'] ) || ! empty( $_POST['update_cart'] ) || ! empty( $_POST['proceed'] ) ) && wp_verify_nonce( $nonce_value, 'woocommerce-cart' ) ) { + + $cart_updated = false; + $cart_totals = isset( $_POST['cart'] ) ? wp_unslash( $_POST['cart'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + if ( ! WC()->cart->is_empty() && is_array( $cart_totals ) ) { + foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) { + + $_product = $values['data']; + + // Skip product if no updated quantity was posted. + if ( ! isset( $cart_totals[ $cart_item_key ] ) || ! isset( $cart_totals[ $cart_item_key ]['qty'] ) ) { + continue; + } + + // Sanitize. + $quantity = apply_filters( 'woocommerce_stock_amount_cart_item', wc_stock_amount( preg_replace( '/[^0-9\.]/', '', $cart_totals[ $cart_item_key ]['qty'] ) ), $cart_item_key ); + + if ( '' === $quantity || $quantity === $values['quantity'] ) { + continue; + } + + // Update cart validation. + $passed_validation = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $values, $quantity ); + + // is_sold_individually. + if ( $_product->is_sold_individually() && $quantity > 1 ) { + /* Translators: %s Product title. */ + wc_add_notice( sprintf( __( 'You can only have 1 %s in your cart.', 'woocommerce' ), $_product->get_name() ), 'error' ); + $passed_validation = false; + } + + if ( $passed_validation ) { + WC()->cart->set_quantity( $cart_item_key, $quantity, false ); + $cart_updated = true; + } + } + } + + // Trigger action - let 3rd parties update the cart if they need to and update the $cart_updated variable. + $cart_updated = apply_filters( 'woocommerce_update_cart_action_cart_updated', $cart_updated ); + + if ( $cart_updated ) { + WC()->cart->calculate_totals(); + } + + if ( ! empty( $_POST['proceed'] ) ) { + wp_safe_redirect( wc_get_checkout_url() ); + exit; + } elseif ( $cart_updated ) { + wc_add_notice( __( 'Cart updated.', 'woocommerce' ), apply_filters( 'woocommerce_cart_updated_notice_type', 'success' ) ); + $referer = remove_query_arg( array( 'remove_coupon', 'add-to-cart' ), ( wp_get_referer() ? wp_get_referer() : wc_get_cart_url() ) ); + wp_safe_redirect( $referer ); + exit; + } + } + } + + /** + * Place a previous order again. + * + * @deprecated 3.5.0 Logic moved to cart session handling. + */ + public static function order_again() { + wc_deprecated_function( 'WC_Form_Handler::order_again', '3.5', 'This method should not be called manually.' ); + } + + /** + * Cancel a pending order. + */ + public static function cancel_order() { + if ( + isset( $_GET['cancel_order'] ) && + isset( $_GET['order'] ) && + isset( $_GET['order_id'] ) && + ( isset( $_GET['_wpnonce'] ) && wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ), 'woocommerce-cancel_order' ) ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + ) { + wc_nocache_headers(); + + $order_key = wp_unslash( $_GET['order'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $order_id = absint( $_GET['order_id'] ); + $order = wc_get_order( $order_id ); + $user_can_cancel = current_user_can( 'cancel_order', $order_id ); + $order_can_cancel = $order->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ); + $redirect = isset( $_GET['redirect'] ) ? wp_unslash( $_GET['redirect'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + if ( $user_can_cancel && $order_can_cancel && $order->get_id() === $order_id && hash_equals( $order->get_order_key(), $order_key ) ) { + + // Cancel the order + restore stock. + WC()->session->set( 'order_awaiting_payment', false ); + $order->update_status( 'cancelled', __( 'Order cancelled by customer.', 'woocommerce' ) ); + + wc_add_notice( apply_filters( 'woocommerce_order_cancelled_notice', __( 'Your order was cancelled.', 'woocommerce' ) ), apply_filters( 'woocommerce_order_cancelled_notice_type', 'notice' ) ); + + do_action( 'woocommerce_cancelled_order', $order->get_id() ); + + } elseif ( $user_can_cancel && ! $order_can_cancel ) { + wc_add_notice( __( 'Your order can no longer be cancelled. Please contact us if you need assistance.', 'woocommerce' ), 'error' ); + } else { + wc_add_notice( __( 'Invalid order.', 'woocommerce' ), 'error' ); + } + + if ( $redirect ) { + wp_safe_redirect( $redirect ); + exit; + } + } + } + + /** + * Add to cart action. + * + * Checks for a valid request, does validation (via hooks) and then redirects if valid. + * + * @param bool $url (default: false) URL to redirect to. + */ + public static function add_to_cart_action( $url = false ) { + if ( ! isset( $_REQUEST['add-to-cart'] ) || ! is_numeric( wp_unslash( $_REQUEST['add-to-cart'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + return; + } + + wc_nocache_headers(); + + $product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( wp_unslash( $_REQUEST['add-to-cart'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $was_added_to_cart = false; + $adding_to_cart = wc_get_product( $product_id ); + + if ( ! $adding_to_cart ) { + return; + } + + $add_to_cart_handler = apply_filters( 'woocommerce_add_to_cart_handler', $adding_to_cart->get_type(), $adding_to_cart ); + + if ( 'variable' === $add_to_cart_handler || 'variation' === $add_to_cart_handler ) { + $was_added_to_cart = self::add_to_cart_handler_variable( $product_id ); + } elseif ( 'grouped' === $add_to_cart_handler ) { + $was_added_to_cart = self::add_to_cart_handler_grouped( $product_id ); + } elseif ( has_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler ) ) { + do_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler, $url ); // Custom handler. + } else { + $was_added_to_cart = self::add_to_cart_handler_simple( $product_id ); + } + + // If we added the product to the cart we can now optionally do a redirect. + if ( $was_added_to_cart && 0 === wc_notice_count( 'error' ) ) { + $url = apply_filters( 'woocommerce_add_to_cart_redirect', $url, $adding_to_cart ); + + if ( $url ) { + wp_safe_redirect( $url ); + exit; + } elseif ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) { + wp_safe_redirect( wc_get_cart_url() ); + exit; + } + } + } + + /** + * Handle adding simple products to the cart. + * + * @since 2.4.6 Split from add_to_cart_action. + * @param int $product_id Product ID to add to the cart. + * @return bool success or not + */ + private static function add_to_cart_handler_simple( $product_id ) { + $quantity = empty( $_REQUEST['quantity'] ) ? 1 : wc_stock_amount( wp_unslash( $_REQUEST['quantity'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity ); + + if ( $passed_validation && false !== WC()->cart->add_to_cart( $product_id, $quantity ) ) { + wc_add_to_cart_message( array( $product_id => $quantity ), true ); + return true; + } + return false; + } + + /** + * Handle adding grouped products to the cart. + * + * @since 2.4.6 Split from add_to_cart_action. + * @param int $product_id Product ID to add to the cart. + * @return bool success or not + */ + private static function add_to_cart_handler_grouped( $product_id ) { + $was_added_to_cart = false; + $added_to_cart = array(); + $items = isset( $_REQUEST['quantity'] ) && is_array( $_REQUEST['quantity'] ) ? wp_unslash( $_REQUEST['quantity'] ) : array(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + if ( ! empty( $items ) ) { + $quantity_set = false; + + foreach ( $items as $item => $quantity ) { + $quantity = wc_stock_amount( $quantity ); + if ( $quantity <= 0 ) { + continue; + } + $quantity_set = true; + + // Add to cart validation. + $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $item, $quantity ); + + // Suppress total recalculation until finished. + remove_action( 'woocommerce_add_to_cart', array( WC()->cart, 'calculate_totals' ), 20, 0 ); + + if ( $passed_validation && false !== WC()->cart->add_to_cart( $item, $quantity ) ) { + $was_added_to_cart = true; + $added_to_cart[ $item ] = $quantity; + } + + add_action( 'woocommerce_add_to_cart', array( WC()->cart, 'calculate_totals' ), 20, 0 ); + } + + if ( ! $was_added_to_cart && ! $quantity_set ) { + wc_add_notice( __( 'Please choose the quantity of items you wish to add to your cart…', 'woocommerce' ), 'error' ); + } elseif ( $was_added_to_cart ) { + wc_add_to_cart_message( $added_to_cart ); + WC()->cart->calculate_totals(); + return true; + } + } elseif ( $product_id ) { + /* Link on product archives */ + wc_add_notice( __( 'Please choose a product to add to your cart…', 'woocommerce' ), 'error' ); + } + return false; + } + + /** + * Handle adding variable products to the cart. + * + * @since 2.4.6 Split from add_to_cart_action. + * @throws Exception If add to cart fails. + * @param int $product_id Product ID to add to the cart. + * @return bool success or not + */ + private static function add_to_cart_handler_variable( $product_id ) { + $variation_id = empty( $_REQUEST['variation_id'] ) ? '' : absint( wp_unslash( $_REQUEST['variation_id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $quantity = empty( $_REQUEST['quantity'] ) ? 1 : wc_stock_amount( wp_unslash( $_REQUEST['quantity'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $variations = array(); + + $product = wc_get_product( $product_id ); + + foreach ( $_REQUEST as $key => $value ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + if ( 'attribute_' !== substr( $key, 0, 10 ) ) { + continue; + } + + $variations[ sanitize_title( wp_unslash( $key ) ) ] = wp_unslash( $value ); + } + + $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations ); + + if ( ! $passed_validation ) { + return false; + } + + // Prevent parent variable product from being added to cart. + if ( empty( $variation_id ) && $product && $product->is_type( 'variable' ) ) { + /* translators: 1: product link, 2: product name */ + wc_add_notice( sprintf( __( 'Please choose product options by visiting %2$s.', 'woocommerce' ), esc_url( get_permalink( $product_id ) ), esc_html( $product->get_name() ) ), 'error' ); + + return false; + } + + if ( false !== WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ) ) { + wc_add_to_cart_message( array( $product_id => $quantity ), true ); + return true; + } + + return false; + } + + /** + * Process the login form. + * + * @throws Exception On login error. + */ + public static function process_login() { + // The global form-login.php template used `_wpnonce` in template versions < 3.3.0. + $nonce_value = wc_get_var( $_REQUEST['woocommerce-login-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + if ( isset( $_POST['login'], $_POST['username'], $_POST['password'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-login' ) ) { + + try { + $creds = array( + 'user_login' => trim( wp_unslash( $_POST['username'] ) ), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + 'user_password' => $_POST['password'], // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + 'remember' => isset( $_POST['rememberme'] ), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + ); + + $validation_error = new WP_Error(); + $validation_error = apply_filters( 'woocommerce_process_login_errors', $validation_error, $creds['user_login'], $creds['user_password'] ); + + if ( $validation_error->get_error_code() ) { + throw new Exception( '' . __( 'Error:', 'woocommerce' ) . ' ' . $validation_error->get_error_message() ); + } + + if ( empty( $creds['user_login'] ) ) { + throw new Exception( '' . __( 'Error:', 'woocommerce' ) . ' ' . __( 'Username is required.', 'woocommerce' ) ); + } + + // On multisite, ensure user exists on current site, if not add them before allowing login. + if ( is_multisite() ) { + $user_data = get_user_by( is_email( $creds['user_login'] ) ? 'email' : 'login', $creds['user_login'] ); + + if ( $user_data && ! is_user_member_of_blog( $user_data->ID, get_current_blog_id() ) ) { + add_user_to_blog( get_current_blog_id(), $user_data->ID, 'customer' ); + } + } + + // Perform the login. + $user = wp_signon( apply_filters( 'woocommerce_login_credentials', $creds ), is_ssl() ); + + if ( is_wp_error( $user ) ) { + throw new Exception( $user->get_error_message() ); + } else { + + if ( ! empty( $_POST['redirect'] ) ) { + $redirect = wp_unslash( $_POST['redirect'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + } elseif ( wc_get_raw_referer() ) { + $redirect = wc_get_raw_referer(); + } else { + $redirect = wc_get_page_permalink( 'myaccount' ); + } + + wp_redirect( wp_validate_redirect( apply_filters( 'woocommerce_login_redirect', remove_query_arg( 'wc_error', $redirect ), $user ), wc_get_page_permalink( 'myaccount' ) ) ); // phpcs:ignore + exit; + } + } catch ( Exception $e ) { + wc_add_notice( apply_filters( 'login_errors', $e->getMessage() ), 'error' ); + do_action( 'woocommerce_login_failed' ); + } + } + } + + /** + * Handle lost password form. + */ + public static function process_lost_password() { + if ( isset( $_POST['wc_reset_password'], $_POST['user_login'] ) ) { + $nonce_value = wc_get_var( $_REQUEST['woocommerce-lost-password-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + if ( ! wp_verify_nonce( $nonce_value, 'lost_password' ) ) { + return; + } + + $success = WC_Shortcode_My_Account::retrieve_password(); + + // If successful, redirect to my account with query arg set. + if ( $success ) { + wp_safe_redirect( add_query_arg( 'reset-link-sent', 'true', wc_get_account_endpoint_url( 'lost-password' ) ) ); + exit; + } + } + } + + /** + * Handle reset password form. + */ + public static function process_reset_password() { + $nonce_value = wc_get_var( $_REQUEST['woocommerce-reset-password-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + if ( ! wp_verify_nonce( $nonce_value, 'reset_password' ) ) { + return; + } + + $posted_fields = array( 'wc_reset_password', 'password_1', 'password_2', 'reset_key', 'reset_login' ); + + foreach ( $posted_fields as $field ) { + if ( ! isset( $_POST[ $field ] ) ) { + return; + } + + if ( in_array( $field, array( 'password_1', 'password_2' ), true ) ) { + // Don't unslash password fields + // @see https://github.com/woocommerce/woocommerce/issues/23922. + $posted_fields[ $field ] = $_POST[ $field ]; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + } else { + $posted_fields[ $field ] = wp_unslash( $_POST[ $field ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + } + } + + $user = WC_Shortcode_My_Account::check_password_reset_key( $posted_fields['reset_key'], $posted_fields['reset_login'] ); + + if ( $user instanceof WP_User ) { + if ( empty( $posted_fields['password_1'] ) ) { + wc_add_notice( __( 'Please enter your password.', 'woocommerce' ), 'error' ); + } + + if ( $posted_fields['password_1'] !== $posted_fields['password_2'] ) { + wc_add_notice( __( 'Passwords do not match.', 'woocommerce' ), 'error' ); + } + + $errors = new WP_Error(); + + do_action( 'validate_password_reset', $errors, $user ); + + wc_add_wp_error_notices( $errors ); + + if ( 0 === wc_notice_count( 'error' ) ) { + WC_Shortcode_My_Account::reset_password( $user, $posted_fields['password_1'] ); + + do_action( 'woocommerce_customer_reset_password', $user ); + + wp_safe_redirect( add_query_arg( 'password-reset', 'true', wc_get_page_permalink( 'myaccount' ) ) ); + exit; + } + } + } + + /** + * Process the registration form. + * + * @throws Exception On registration error. + */ + public static function process_registration() { + $nonce_value = isset( $_POST['_wpnonce'] ) ? wp_unslash( $_POST['_wpnonce'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $nonce_value = isset( $_POST['woocommerce-register-nonce'] ) ? wp_unslash( $_POST['woocommerce-register-nonce'] ) : $nonce_value; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + if ( isset( $_POST['register'], $_POST['email'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-register' ) ) { + $username = 'no' === get_option( 'woocommerce_registration_generate_username' ) && isset( $_POST['username'] ) ? wp_unslash( $_POST['username'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $password = 'no' === get_option( 'woocommerce_registration_generate_password' ) && isset( $_POST['password'] ) ? $_POST['password'] : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $email = wp_unslash( $_POST['email'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + try { + $validation_error = new WP_Error(); + $validation_error = apply_filters( 'woocommerce_process_registration_errors', $validation_error, $username, $password, $email ); + $validation_errors = $validation_error->get_error_messages(); + + if ( 1 === count( $validation_errors ) ) { + throw new Exception( $validation_error->get_error_message() ); + } elseif ( $validation_errors ) { + foreach ( $validation_errors as $message ) { + wc_add_notice( '' . __( 'Error:', 'woocommerce' ) . ' ' . $message, 'error' ); + } + throw new Exception(); + } + + $new_customer = wc_create_new_customer( sanitize_email( $email ), wc_clean( $username ), $password ); + + if ( is_wp_error( $new_customer ) ) { + throw new Exception( $new_customer->get_error_message() ); + } + + if ( 'yes' === get_option( 'woocommerce_registration_generate_password' ) ) { + wc_add_notice( __( 'Your account was created successfully and a password has been sent to your email address.', 'woocommerce' ) ); + } else { + wc_add_notice( __( 'Your account was created successfully. Your login details have been sent to your email address.', 'woocommerce' ) ); + } + + // Only redirect after a forced login - otherwise output a success notice. + if ( apply_filters( 'woocommerce_registration_auth_new_customer', true, $new_customer ) ) { + wc_set_customer_auth_cookie( $new_customer ); + + if ( ! empty( $_POST['redirect'] ) ) { + $redirect = wp_sanitize_redirect( wp_unslash( $_POST['redirect'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + } elseif ( wc_get_raw_referer() ) { + $redirect = wc_get_raw_referer(); + } else { + $redirect = wc_get_page_permalink( 'myaccount' ); + } + + wp_redirect( wp_validate_redirect( apply_filters( 'woocommerce_registration_redirect', $redirect ), wc_get_page_permalink( 'myaccount' ) ) ); //phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect + exit; + } + } catch ( Exception $e ) { + if ( $e->getMessage() ) { + wc_add_notice( '' . __( 'Error:', 'woocommerce' ) . ' ' . $e->getMessage(), 'error' ); + } + } + } + } +} + +WC_Form_Handler::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-frontend-scripts.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-frontend-scripts.php new file mode 100644 index 0000000..d9b1f7d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-frontend-scripts.php @@ -0,0 +1,618 @@ + array( + 'src' => self::get_asset_url( 'assets/css/woocommerce-layout.css' ), + 'deps' => '', + 'version' => $version, + 'media' => 'all', + 'has_rtl' => true, + ), + 'woocommerce-smallscreen' => array( + 'src' => self::get_asset_url( 'assets/css/woocommerce-smallscreen.css' ), + 'deps' => 'woocommerce-layout', + 'version' => $version, + 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')', + 'has_rtl' => true, + ), + 'woocommerce-general' => array( + 'src' => self::get_asset_url( 'assets/css/woocommerce.css' ), + 'deps' => '', + 'version' => $version, + 'media' => 'all', + 'has_rtl' => true, + ), + ) + ); + } + + /** + * Return asset URL. + * + * @param string $path Assets path. + * @return string + */ + private static function get_asset_url( $path ) { + return apply_filters( 'woocommerce_get_asset_url', plugins_url( $path, WC_PLUGIN_FILE ), $path ); + } + + /** + * Register a script for use. + * + * @uses wp_register_script() + * @param string $handle Name of the script. Should be unique. + * @param string $path Full URL of the script, or path of the script relative to the WordPress root directory. + * @param string[] $deps An array of registered script handles this script depends on. + * @param string $version String specifying script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If version is set to false, a version number is automatically added equal to current installed WordPress version. If set to null, no version is added. + * @param boolean $in_footer Whether to enqueue the script before instead of in the . Default 'false'. + */ + private static function register_script( $handle, $path, $deps = array( 'jquery' ), $version = WC_VERSION, $in_footer = true ) { + self::$scripts[] = $handle; + wp_register_script( $handle, $path, $deps, $version, $in_footer ); + } + + /** + * Register and enqueue a script for use. + * + * @uses wp_enqueue_script() + * @param string $handle Name of the script. Should be unique. + * @param string $path Full URL of the script, or path of the script relative to the WordPress root directory. + * @param string[] $deps An array of registered script handles this script depends on. + * @param string $version String specifying script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If version is set to false, a version number is automatically added equal to current installed WordPress version. If set to null, no version is added. + * @param boolean $in_footer Whether to enqueue the script before instead of in the . Default 'false'. + */ + private static function enqueue_script( $handle, $path = '', $deps = array( 'jquery' ), $version = WC_VERSION, $in_footer = true ) { + if ( ! in_array( $handle, self::$scripts, true ) && $path ) { + self::register_script( $handle, $path, $deps, $version, $in_footer ); + } + wp_enqueue_script( $handle ); + } + + /** + * Register a style for use. + * + * @uses wp_register_style() + * @param string $handle Name of the stylesheet. Should be unique. + * @param string $path Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory. + * @param string[] $deps An array of registered stylesheet handles this stylesheet depends on. + * @param string $version String specifying stylesheet version number, if it has one, which is added to the URL as a query string for cache busting purposes. If version is set to false, a version number is automatically added equal to current installed WordPress version. If set to null, no version is added. + * @param string $media The media for which this stylesheet has been defined. Accepts media types like 'all', 'print' and 'screen', or media queries like '(orientation: portrait)' and '(max-width: 640px)'. + * @param boolean $has_rtl If has RTL version to load too. + */ + private static function register_style( $handle, $path, $deps = array(), $version = WC_VERSION, $media = 'all', $has_rtl = false ) { + self::$styles[] = $handle; + wp_register_style( $handle, $path, $deps, $version, $media ); + + if ( $has_rtl ) { + wp_style_add_data( $handle, 'rtl', 'replace' ); + } + } + + /** + * Register and enqueue a styles for use. + * + * @uses wp_enqueue_style() + * @param string $handle Name of the stylesheet. Should be unique. + * @param string $path Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory. + * @param string[] $deps An array of registered stylesheet handles this stylesheet depends on. + * @param string $version String specifying stylesheet version number, if it has one, which is added to the URL as a query string for cache busting purposes. If version is set to false, a version number is automatically added equal to current installed WordPress version. If set to null, no version is added. + * @param string $media The media for which this stylesheet has been defined. Accepts media types like 'all', 'print' and 'screen', or media queries like '(orientation: portrait)' and '(max-width: 640px)'. + * @param boolean $has_rtl If has RTL version to load too. + */ + private static function enqueue_style( $handle, $path = '', $deps = array(), $version = WC_VERSION, $media = 'all', $has_rtl = false ) { + if ( ! in_array( $handle, self::$styles, true ) && $path ) { + self::register_style( $handle, $path, $deps, $version, $media, $has_rtl ); + } + wp_enqueue_style( $handle ); + } + + /** + * Register all WC scripts. + */ + private static function register_scripts() { + $suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min'; + $version = Constants::get_constant( 'WC_VERSION' ); + + $register_scripts = array( + 'flexslider' => array( + 'src' => self::get_asset_url( 'assets/js/flexslider/jquery.flexslider' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => '2.7.2', + ), + 'js-cookie' => array( + 'src' => self::get_asset_url( 'assets/js/js-cookie/js.cookie' . $suffix . '.js' ), + 'deps' => array(), + 'version' => '2.1.4', + ), + 'jquery-blockui' => array( + 'src' => self::get_asset_url( 'assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => '2.70', + ), + 'jquery-cookie' => array( // deprecated. + 'src' => self::get_asset_url( 'assets/js/jquery-cookie/jquery.cookie' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => '1.4.1', + ), + 'jquery-payment' => array( + 'src' => self::get_asset_url( 'assets/js/jquery-payment/jquery.payment' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => '3.0.0', + ), + 'photoswipe' => array( + 'src' => self::get_asset_url( 'assets/js/photoswipe/photoswipe' . $suffix . '.js' ), + 'deps' => array(), + 'version' => '4.1.1', + ), + 'photoswipe-ui-default' => array( + 'src' => self::get_asset_url( 'assets/js/photoswipe/photoswipe-ui-default' . $suffix . '.js' ), + 'deps' => array( 'photoswipe' ), + 'version' => '4.1.1', + ), + 'prettyPhoto' => array( // deprecated. + 'src' => self::get_asset_url( 'assets/js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => '3.1.6', + ), + 'prettyPhoto-init' => array( // deprecated. + 'src' => self::get_asset_url( 'assets/js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'prettyPhoto' ), + 'version' => $version, + ), + 'select2' => array( + 'src' => self::get_asset_url( 'assets/js/select2/select2.full' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => '4.0.3', + ), + 'selectWoo' => array( + 'src' => self::get_asset_url( 'assets/js/selectWoo/selectWoo.full' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => '1.0.6', + ), + 'wc-address-i18n' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/address-i18n' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'wc-country-select' ), + 'version' => $version, + ), + 'wc-add-payment-method' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/add-payment-method' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'woocommerce' ), + 'version' => $version, + ), + 'wc-cart' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/cart' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n' ), + 'version' => $version, + ), + 'wc-cart-fragments' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/cart-fragments' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'js-cookie' ), + 'version' => $version, + ), + 'wc-checkout' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/checkout' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n' ), + 'version' => $version, + ), + 'wc-country-select' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/country-select' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => $version, + ), + 'wc-credit-card-form' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/credit-card-form' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'jquery-payment' ), + 'version' => $version, + ), + 'wc-add-to-cart' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/add-to-cart' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'jquery-blockui' ), + 'version' => $version, + ), + 'wc-add-to-cart-variation' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/add-to-cart-variation' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'wp-util', 'jquery-blockui' ), + 'version' => $version, + ), + 'wc-geolocation' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/geolocation' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => $version, + ), + 'wc-lost-password' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/lost-password' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'woocommerce' ), + 'version' => $version, + ), + 'wc-password-strength-meter' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/password-strength-meter' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'password-strength-meter' ), + 'version' => $version, + ), + 'wc-single-product' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/single-product' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => $version, + ), + 'woocommerce' => array( + 'src' => self::get_asset_url( 'assets/js/frontend/woocommerce' . $suffix . '.js' ), + 'deps' => array( 'jquery', 'jquery-blockui', 'js-cookie' ), + 'version' => $version, + ), + 'zoom' => array( + 'src' => self::get_asset_url( 'assets/js/zoom/jquery.zoom' . $suffix . '.js' ), + 'deps' => array( 'jquery' ), + 'version' => '1.7.21', + ), + ); + foreach ( $register_scripts as $name => $props ) { + self::register_script( $name, $props['src'], $props['deps'], $props['version'] ); + } + } + + /** + * Register all WC styles. + */ + private static function register_styles() { + $version = Constants::get_constant( 'WC_VERSION' ); + + $register_styles = array( + 'photoswipe' => array( + 'src' => self::get_asset_url( 'assets/css/photoswipe/photoswipe.min.css' ), + 'deps' => array(), + 'version' => $version, + 'has_rtl' => false, + ), + 'photoswipe-default-skin' => array( + 'src' => self::get_asset_url( 'assets/css/photoswipe/default-skin/default-skin.min.css' ), + 'deps' => array( 'photoswipe' ), + 'version' => $version, + 'has_rtl' => false, + ), + 'select2' => array( + 'src' => self::get_asset_url( 'assets/css/select2.css' ), + 'deps' => array(), + 'version' => $version, + 'has_rtl' => false, + ), + 'woocommerce_prettyPhoto_css' => array( // deprecated. + 'src' => self::get_asset_url( 'assets/css/prettyPhoto.css' ), + 'deps' => array(), + 'version' => $version, + 'has_rtl' => true, + ), + ); + foreach ( $register_styles as $name => $props ) { + self::register_style( $name, $props['src'], $props['deps'], $props['version'], 'all', $props['has_rtl'] ); + } + } + + /** + * Register/queue frontend scripts. + */ + public static function load_scripts() { + global $post; + + if ( ! did_action( 'before_woocommerce_init' ) ) { + return; + } + + self::register_scripts(); + self::register_styles(); + + if ( 'yes' === get_option( 'woocommerce_enable_ajax_add_to_cart' ) ) { + self::enqueue_script( 'wc-add-to-cart' ); + } + if ( is_cart() ) { + self::enqueue_script( 'wc-cart' ); + } + if ( is_cart() || is_checkout() || is_account_page() ) { + self::enqueue_script( 'selectWoo' ); + self::enqueue_style( 'select2' ); + + // Password strength meter. Load in checkout, account login and edit account page. + if ( ( 'no' === get_option( 'woocommerce_registration_generate_password' ) && ! is_user_logged_in() ) || is_edit_account_page() || is_lost_password_page() ) { + self::enqueue_script( 'wc-password-strength-meter' ); + } + } + if ( is_checkout() ) { + self::enqueue_script( 'wc-checkout' ); + } + if ( is_add_payment_method_page() ) { + self::enqueue_script( 'wc-add-payment-method' ); + } + if ( is_lost_password_page() ) { + self::enqueue_script( 'wc-lost-password' ); + } + + // Load gallery scripts on product pages only if supported. + if ( is_product() || ( ! empty( $post->post_content ) && strstr( $post->post_content, '[product_page' ) ) ) { + if ( current_theme_supports( 'wc-product-gallery-zoom' ) ) { + self::enqueue_script( 'zoom' ); + } + if ( current_theme_supports( 'wc-product-gallery-slider' ) ) { + self::enqueue_script( 'flexslider' ); + } + if ( current_theme_supports( 'wc-product-gallery-lightbox' ) ) { + self::enqueue_script( 'photoswipe-ui-default' ); + self::enqueue_style( 'photoswipe-default-skin' ); + add_action( 'wp_footer', 'woocommerce_photoswipe' ); + } + self::enqueue_script( 'wc-single-product' ); + } + + if ( 'geolocation_ajax' === get_option( 'woocommerce_default_customer_address' ) ) { + $ua = strtolower( wc_get_user_agent() ); // Exclude common bots from geolocation by user agent. + + if ( ! strstr( $ua, 'bot' ) && ! strstr( $ua, 'spider' ) && ! strstr( $ua, 'crawl' ) ) { + self::enqueue_script( 'wc-geolocation' ); + } + } + + // Global frontend scripts. + self::enqueue_script( 'woocommerce' ); + self::enqueue_script( 'wc-cart-fragments' ); + + // CSS Styles. + $enqueue_styles = self::get_styles(); + if ( $enqueue_styles ) { + foreach ( $enqueue_styles as $handle => $args ) { + if ( ! isset( $args['has_rtl'] ) ) { + $args['has_rtl'] = false; + } + + self::enqueue_style( $handle, $args['src'], $args['deps'], $args['version'], $args['media'], $args['has_rtl'] ); + } + } + + // Placeholder style. + wp_register_style( 'woocommerce-inline', false ); // phpcs:ignore + wp_enqueue_style( 'woocommerce-inline' ); + + if ( true === wc_string_to_bool( get_option( 'woocommerce_checkout_highlight_required_fields', 'yes' ) ) ) { + wp_add_inline_style( 'woocommerce-inline', '.woocommerce form .form-row .required { visibility: visible; }' ); + } else { + wp_add_inline_style( 'woocommerce-inline', '.woocommerce form .form-row .required { visibility: hidden; }' ); + } + } + + /** + * Localize a WC script once. + * + * @since 2.3.0 this needs less wp_script_is() calls due to https://core.trac.wordpress.org/ticket/28404 being added in WP 4.0. + * @param string $handle Script handle the data will be attached to. + */ + private static function localize_script( $handle ) { + if ( ! in_array( $handle, self::$wp_localize_scripts, true ) && wp_script_is( $handle ) ) { + $data = self::get_script_data( $handle ); + + if ( ! $data ) { + return; + } + + $name = str_replace( '-', '_', $handle ) . '_params'; + self::$wp_localize_scripts[] = $handle; + wp_localize_script( $handle, $name, apply_filters( $name, $data ) ); + } + } + + /** + * Return data for script handles. + * + * @param string $handle Script handle the data will be attached to. + * @return array|bool + */ + private static function get_script_data( $handle ) { + global $wp; + + switch ( $handle ) { + case 'woocommerce': + $params = array( + 'ajax_url' => WC()->ajax_url(), + 'wc_ajax_url' => WC_AJAX::get_endpoint( '%%endpoint%%' ), + ); + break; + case 'wc-geolocation': + $params = array( + 'wc_ajax_url' => WC_AJAX::get_endpoint( '%%endpoint%%' ), + 'home_url' => remove_query_arg( 'lang', home_url() ), // FIX for WPML compatibility. + 'is_available' => ! ( is_cart() || is_account_page() || is_checkout() || is_customize_preview() ) ? '1' : '0', + 'hash' => isset( $_GET['v'] ) ? wc_clean( wp_unslash( $_GET['v'] ) ) : '', // WPCS: input var ok, CSRF ok. + ); + break; + case 'wc-single-product': + $params = array( + 'i18n_required_rating_text' => esc_attr__( 'Please select a rating', 'woocommerce' ), + 'review_rating_required' => wc_review_ratings_required() ? 'yes' : 'no', + 'flexslider' => apply_filters( + 'woocommerce_single_product_carousel_options', + array( + 'rtl' => is_rtl(), + 'animation' => 'slide', + 'smoothHeight' => true, + 'directionNav' => false, + 'controlNav' => 'thumbnails', + 'slideshow' => false, + 'animationSpeed' => 500, + 'animationLoop' => false, // Breaks photoswipe pagination if true. + 'allowOneSlide' => false, + ) + ), + 'zoom_enabled' => apply_filters( 'woocommerce_single_product_zoom_enabled', get_theme_support( 'wc-product-gallery-zoom' ) ), + 'zoom_options' => apply_filters( 'woocommerce_single_product_zoom_options', array() ), + 'photoswipe_enabled' => apply_filters( 'woocommerce_single_product_photoswipe_enabled', get_theme_support( 'wc-product-gallery-lightbox' ) ), + 'photoswipe_options' => apply_filters( + 'woocommerce_single_product_photoswipe_options', + array( + 'shareEl' => false, + 'closeOnScroll' => false, + 'history' => false, + 'hideAnimationDuration' => 0, + 'showAnimationDuration' => 0, + ) + ), + 'flexslider_enabled' => apply_filters( 'woocommerce_single_product_flexslider_enabled', get_theme_support( 'wc-product-gallery-slider' ) ), + ); + break; + case 'wc-checkout': + $params = array( + 'ajax_url' => WC()->ajax_url(), + 'wc_ajax_url' => WC_AJAX::get_endpoint( '%%endpoint%%' ), + 'update_order_review_nonce' => wp_create_nonce( 'update-order-review' ), + 'apply_coupon_nonce' => wp_create_nonce( 'apply-coupon' ), + 'remove_coupon_nonce' => wp_create_nonce( 'remove-coupon' ), + 'option_guest_checkout' => get_option( 'woocommerce_enable_guest_checkout' ), + 'checkout_url' => WC_AJAX::get_endpoint( 'checkout' ), + 'is_checkout' => is_checkout() && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ? 1 : 0, + 'debug_mode' => Constants::is_true( 'WP_DEBUG' ), + 'i18n_checkout_error' => esc_attr__( 'Error processing checkout. Please try again.', 'woocommerce' ), + ); + break; + case 'wc-address-i18n': + $params = array( + 'locale' => wp_json_encode( WC()->countries->get_country_locale() ), + 'locale_fields' => wp_json_encode( WC()->countries->get_country_locale_field_selectors() ), + 'i18n_required_text' => esc_attr__( 'required', 'woocommerce' ), + 'i18n_optional_text' => esc_html__( 'optional', 'woocommerce' ), + ); + break; + case 'wc-cart': + $params = array( + 'ajax_url' => WC()->ajax_url(), + 'wc_ajax_url' => WC_AJAX::get_endpoint( '%%endpoint%%' ), + 'update_shipping_method_nonce' => wp_create_nonce( 'update-shipping-method' ), + 'apply_coupon_nonce' => wp_create_nonce( 'apply-coupon' ), + 'remove_coupon_nonce' => wp_create_nonce( 'remove-coupon' ), + ); + break; + case 'wc-cart-fragments': + $params = array( + 'ajax_url' => WC()->ajax_url(), + 'wc_ajax_url' => WC_AJAX::get_endpoint( '%%endpoint%%' ), + 'cart_hash_key' => apply_filters( 'woocommerce_cart_hash_key', 'wc_cart_hash_' . md5( get_current_blog_id() . '_' . get_site_url( get_current_blog_id(), '/' ) . get_template() ) ), + 'fragment_name' => apply_filters( 'woocommerce_cart_fragment_name', 'wc_fragments_' . md5( get_current_blog_id() . '_' . get_site_url( get_current_blog_id(), '/' ) . get_template() ) ), + 'request_timeout' => 5000, + ); + break; + case 'wc-add-to-cart': + $params = array( + 'ajax_url' => WC()->ajax_url(), + 'wc_ajax_url' => WC_AJAX::get_endpoint( '%%endpoint%%' ), + 'i18n_view_cart' => esc_attr__( 'View cart', 'woocommerce' ), + 'cart_url' => apply_filters( 'woocommerce_add_to_cart_redirect', wc_get_cart_url(), null ), + 'is_cart' => is_cart(), + 'cart_redirect_after_add' => get_option( 'woocommerce_cart_redirect_after_add' ), + ); + break; + case 'wc-add-to-cart-variation': + // We also need the wp.template for this script :). + wc_get_template( 'single-product/add-to-cart/variation.php' ); + + $params = array( + 'wc_ajax_url' => WC_AJAX::get_endpoint( '%%endpoint%%' ), + 'i18n_no_matching_variations_text' => esc_attr__( 'Sorry, no products matched your selection. Please choose a different combination.', 'woocommerce' ), + 'i18n_make_a_selection_text' => esc_attr__( 'Please select some product options before adding this product to your cart.', 'woocommerce' ), + 'i18n_unavailable_text' => esc_attr__( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' ), + ); + break; + case 'wc-country-select': + $params = array( + 'countries' => wp_json_encode( array_merge( WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states() ) ), + 'i18n_select_state_text' => esc_attr__( 'Select an option…', 'woocommerce' ), + 'i18n_no_matches' => _x( 'No matches found', 'enhanced select', 'woocommerce' ), + 'i18n_ajax_error' => _x( 'Loading failed', 'enhanced select', 'woocommerce' ), + 'i18n_input_too_short_1' => _x( 'Please enter 1 or more characters', 'enhanced select', 'woocommerce' ), + 'i18n_input_too_short_n' => _x( 'Please enter %qty% or more characters', 'enhanced select', 'woocommerce' ), + 'i18n_input_too_long_1' => _x( 'Please delete 1 character', 'enhanced select', 'woocommerce' ), + 'i18n_input_too_long_n' => _x( 'Please delete %qty% characters', 'enhanced select', 'woocommerce' ), + 'i18n_selection_too_long_1' => _x( 'You can only select 1 item', 'enhanced select', 'woocommerce' ), + 'i18n_selection_too_long_n' => _x( 'You can only select %qty% items', 'enhanced select', 'woocommerce' ), + 'i18n_load_more' => _x( 'Loading more results…', 'enhanced select', 'woocommerce' ), + 'i18n_searching' => _x( 'Searching…', 'enhanced select', 'woocommerce' ), + ); + break; + case 'wc-password-strength-meter': + $params = array( + 'min_password_strength' => apply_filters( 'woocommerce_min_password_strength', 3 ), + 'stop_checkout' => apply_filters( 'woocommerce_enforce_password_strength_meter_on_checkout', false ), + 'i18n_password_error' => esc_attr__( 'Please enter a stronger password.', 'woocommerce' ), + 'i18n_password_hint' => esc_attr( wp_get_password_hint() ), + ); + break; + default: + $params = false; + } + + $params = apply_filters_deprecated( $handle . '_params', array( $params ), '3.0.0', 'woocommerce_get_script_data' ); + + return apply_filters( 'woocommerce_get_script_data', $params, $handle ); + } + + /** + * Localize scripts only when enqueued. + */ + public static function localize_printed_scripts() { + foreach ( self::$scripts as $handle ) { + self::localize_script( $handle ); + } + } +} + +WC_Frontend_Scripts::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-geo-ip.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-geo-ip.php new file mode 100644 index 0000000..c79be25 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-geo-ip.php @@ -0,0 +1,1814 @@ +log( $level, $message, array( 'source' => 'geoip' ) ); + } + + /** + * Open geoip file. + * + * @param string $filename + * @param int $flags + */ + public function geoip_open( $filename, $flags ) { + $this->flags = $flags; + if ( $this->flags & self::GEOIP_SHARED_MEMORY ) { + $this->shmid = @shmop_open( self::GEOIP_SHM_KEY, 'a', 0, 0 ); + } else { + if ( $this->filehandle = fopen( $filename, 'rb' ) ) { + if ( $this->flags & self::GEOIP_MEMORY_CACHE ) { + $s_array = fstat( $this->filehandle ); + $this->memory_buffer = fread( $this->filehandle, $s_array['size'] ); + } + } else { + $this->log( 'GeoIP API: Can not open ' . $filename, 'error' ); + } + } + + $this->_setup_segments(); + } + + /** + * Setup segments. + * + * @return WC_Geo_IP instance + */ + private function _setup_segments() { + $this->databaseType = self::GEOIP_COUNTRY_EDITION; + $this->record_length = self::STANDARD_RECORD_LENGTH; + + if ( $this->flags & self::GEOIP_SHARED_MEMORY ) { + $offset = @shmop_size( $this->shmid ) - 3; + + for ( $i = 0; $i < self::STRUCTURE_INFO_MAX_SIZE; $i++ ) { + $delim = @shmop_read( $this->shmid, $offset, 3 ); + $offset += 3; + + if ( ( chr( 255 ) . chr( 255 ) . chr( 255 ) ) == $delim ) { + $this->databaseType = ord( @shmop_read( $this->shmid, $offset, 1 ) ); + + if ( $this->databaseType >= 106 ) { + $this->databaseType -= 105; + } + + $offset++; + + if ( self::GEOIP_REGION_EDITION_REV0 == $this->databaseType ) { + $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV0; + } elseif ( self::GEOIP_REGION_EDITION_REV1 == $this->databaseType ) { + $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV1; + } elseif ( ( self::GEOIP_CITY_EDITION_REV0 == $this->databaseType ) + || ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) + || ( self::GEOIP_ORG_EDITION == $this->databaseType ) + || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType ) + || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_ISP_EDITION == $this->databaseType ) + || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_USERTYPE_EDITION == $this->databaseType ) + || ( self::GEOIP_USERTYPE_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_LOCATIONA_EDITION == $this->databaseType ) + || ( self::GEOIP_ACCURACYRADIUS_EDITION == $this->databaseType ) + || ( self::GEOIP_CITY_EDITION_REV0_V6 == $this->databaseType ) + || ( self::GEOIP_CITY_EDITION_REV1_V6 == $this->databaseType ) + || ( self::GEOIP_NETSPEED_EDITION_REV1 == $this->databaseType ) + || ( self::GEOIP_NETSPEED_EDITION_REV1_V6 == $this->databaseType ) + || ( self::GEOIP_ASNUM_EDITION == $this->databaseType ) + || ( self::GEOIP_ASNUM_EDITION_V6 == $this->databaseType ) + ) { + $this->databaseSegments = 0; + $buf = @shmop_read( $this->shmid, $offset, self::SEGMENT_RECORD_LENGTH ); + + for ( $j = 0; $j < self::SEGMENT_RECORD_LENGTH; $j++ ) { + $this->databaseSegments += ( ord( $buf[ $j ] ) << ( $j * 8 ) ); + } + + if ( ( self::GEOIP_ORG_EDITION == $this->databaseType ) + || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType ) + || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_ISP_EDITION == $this->databaseType ) + || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType ) + ) { + $this->record_length = self::ORG_RECORD_LENGTH; + } + } + + break; + } else { + $offset -= 4; + } + } + if ( ( self::GEOIP_COUNTRY_EDITION == $this->databaseType ) + || ( self::GEOIP_COUNTRY_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_PROXY_EDITION == $this->databaseType ) + || ( self::GEOIP_NETSPEED_EDITION == $this->databaseType ) + ) { + $this->databaseSegments = self::GEOIP_COUNTRY_BEGIN; + } + } else { + $filepos = ftell( $this->filehandle ); + fseek( $this->filehandle, -3, SEEK_END ); + + for ( $i = 0; $i < self::STRUCTURE_INFO_MAX_SIZE; $i++ ) { + + $delim = fread( $this->filehandle, 3 ); + if ( ( chr( 255 ) . chr( 255 ) . chr( 255 ) ) == $delim ) { + + $this->databaseType = ord( fread( $this->filehandle, 1 ) ); + if ( $this->databaseType >= 106 ) { + $this->databaseType -= 105; + } + + if ( self::GEOIP_REGION_EDITION_REV0 == $this->databaseType ) { + $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV0; + } elseif ( self::GEOIP_REGION_EDITION_REV1 == $this->databaseType ) { + $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV1; + } elseif ( ( self::GEOIP_CITY_EDITION_REV0 == $this->databaseType ) + || ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) + || ( self::GEOIP_CITY_EDITION_REV0_V6 == $this->databaseType ) + || ( self::GEOIP_CITY_EDITION_REV1_V6 == $this->databaseType ) + || ( self::GEOIP_ORG_EDITION == $this->databaseType ) + || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType ) + || ( self::GEOIP_ISP_EDITION == $this->databaseType ) + || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_LOCATIONA_EDITION == $this->databaseType ) + || ( self::GEOIP_ACCURACYRADIUS_EDITION == $this->databaseType ) + || ( self::GEOIP_NETSPEED_EDITION_REV1 == $this->databaseType ) + || ( self::GEOIP_NETSPEED_EDITION_REV1_V6 == $this->databaseType ) + || ( self::GEOIP_USERTYPE_EDITION == $this->databaseType ) + || ( self::GEOIP_USERTYPE_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_ASNUM_EDITION == $this->databaseType ) + || ( self::GEOIP_ASNUM_EDITION_V6 == $this->databaseType ) + ) { + $this->databaseSegments = 0; + $buf = fread( $this->filehandle, self::SEGMENT_RECORD_LENGTH ); + + for ( $j = 0; $j < self::SEGMENT_RECORD_LENGTH; $j++ ) { + $this->databaseSegments += ( ord( $buf[ $j ] ) << ( $j * 8 ) ); + } + + if ( ( self::GEOIP_ORG_EDITION == $this->databaseType ) + || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType ) + || ( self::GEOIP_ISP_EDITION == $this->databaseType ) + || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType ) + ) { + $this->record_length = self::ORG_RECORD_LENGTH; + } + } + + break; + } else { + fseek( $this->filehandle, -4, SEEK_CUR ); + } + } + + if ( ( self::GEOIP_COUNTRY_EDITION == $this->databaseType ) + || ( self::GEOIP_COUNTRY_EDITION_V6 == $this->databaseType ) + || ( self::GEOIP_PROXY_EDITION == $this->databaseType ) + || ( self::GEOIP_NETSPEED_EDITION == $this->databaseType ) + ) { + $this->databaseSegments = self::GEOIP_COUNTRY_BEGIN; + } + + fseek( $this->filehandle, $filepos, SEEK_SET ); + } + + return $this; + } + + /** + * Close geoip file. + * + * @return bool + */ + public function geoip_close() { + if ( $this->flags & self::GEOIP_SHARED_MEMORY ) { + return true; + } + + return fclose( $this->filehandle ); + } + + /** + * Common get record. + * + * @param string $seek_country + * @return WC_Geo_IP_Record instance + */ + private function _common_get_record( $seek_country ) { + // workaround php's broken substr, strpos, etc handling with + // mbstring.func_overload and mbstring.internal_encoding + $mbExists = extension_loaded( 'mbstring' ); + if ( $mbExists ) { + $enc = mb_internal_encoding(); + mb_internal_encoding( 'ISO-8859-1' ); + } + + $record_pointer = $seek_country + ( 2 * $this->record_length - 1 ) * $this->databaseSegments; + + if ( $this->flags & self::GEOIP_MEMORY_CACHE ) { + $record_buf = substr( $this->memory_buffer, $record_pointer, FULL_RECORD_LENGTH ); + } elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) { + $record_buf = @shmop_read( $this->shmid, $record_pointer, FULL_RECORD_LENGTH ); + } else { + fseek( $this->filehandle, $record_pointer, SEEK_SET ); + $record_buf = fread( $this->filehandle, FULL_RECORD_LENGTH ); + } + + $record = new WC_Geo_IP_Record(); + $record_buf_pos = 0; + $char = ord( substr( $record_buf, $record_buf_pos, 1 ) ); + $record->country_code = $this->GEOIP_COUNTRY_CODES[ $char ]; + $record->country_code3 = $this->GEOIP_COUNTRY_CODES3[ $char ]; + $record->country_name = $this->GEOIP_COUNTRY_NAMES[ $char ]; + $record->continent_code = $this->GEOIP_CONTINENT_CODES[ $char ]; + $str_length = 0; + + $record_buf_pos++; + + // Get region + $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); + while ( 0 != $char ) { + $str_length++; + $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); + } + + if ( $str_length > 0 ) { + $record->region = substr( $record_buf, $record_buf_pos, $str_length ); + } + + $record_buf_pos += $str_length + 1; + $str_length = 0; + + // Get city + $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); + while ( 0 != $char ) { + $str_length++; + $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); + } + + if ( $str_length > 0 ) { + $record->city = substr( $record_buf, $record_buf_pos, $str_length ); + } + + $record_buf_pos += $str_length + 1; + $str_length = 0; + + // Get postal code + $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); + while ( 0 != $char ) { + $str_length++; + $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); + } + + if ( $str_length > 0 ) { + $record->postal_code = substr( $record_buf, $record_buf_pos, $str_length ); + } + + $record_buf_pos += $str_length + 1; + + // Get latitude and longitude + $latitude = 0; + $longitude = 0; + for ( $j = 0; $j < 3; ++$j ) { + $char = ord( substr( $record_buf, $record_buf_pos++, 1 ) ); + $latitude += ( $char << ( $j * 8 ) ); + } + + $record->latitude = ( $latitude / 10000 ) - 180; + + for ( $j = 0; $j < 3; ++$j ) { + $char = ord( substr( $record_buf, $record_buf_pos++, 1 ) ); + $longitude += ( $char << ( $j * 8 ) ); + } + + $record->longitude = ( $longitude / 10000 ) - 180; + + if ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) { + $metroarea_combo = 0; + if ( 'US' === $record->country_code ) { + for ( $j = 0; $j < 3; ++$j ) { + $char = ord( substr( $record_buf, $record_buf_pos++, 1 ) ); + $metroarea_combo += ( $char << ( $j * 8 ) ); + } + + $record->metro_code = $record->dma_code = floor( $metroarea_combo / 1000 ); + $record->area_code = $metroarea_combo % 1000; + } + } + + if ( $mbExists ) { + mb_internal_encoding( $enc ); + } + + return $record; + } + + /** + * Get record. + * + * @param int $ipnum + * @return WC_Geo_IP_Record instance + */ + private function _get_record( $ipnum ) { + $seek_country = $this->_geoip_seek_country( $ipnum ); + if ( $seek_country == $this->databaseSegments ) { + return null; + } + + return $this->_common_get_record( $seek_country ); + } + + /** + * Seek country IPv6. + * + * @param int $ipnum + * @return string + */ + public function _geoip_seek_country_v6( $ipnum ) { + // arrays from unpack start with offset 1 + // yet another php mystery. array_merge work around + // this broken behaviour + $v6vec = array_merge( unpack( 'C16', $ipnum ) ); + + $offset = 0; + for ( $depth = 127; $depth >= 0; --$depth ) { + if ( $this->flags & self::GEOIP_MEMORY_CACHE ) { + $buf = $this->_safe_substr( + $this->memory_buffer, + 2 * $this->record_length * $offset, + 2 * $this->record_length + ); + } elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) { + $buf = @shmop_read( + $this->shmid, + 2 * $this->record_length * $offset, + 2 * $this->record_length + ); + } else { + if ( 0 != fseek( $this->filehandle, 2 * $this->record_length * $offset, SEEK_SET ) ) { + break; + } + + $buf = fread( $this->filehandle, 2 * $this->record_length ); + } + $x = array( 0, 0 ); + for ( $i = 0; $i < 2; ++$i ) { + for ( $j = 0; $j < $this->record_length; ++$j ) { + $x[ $i ] += ord( $buf[ $this->record_length * $i + $j ] ) << ( $j * 8 ); + } + } + + $bnum = 127 - $depth; + $idx = $bnum >> 3; + $b_mask = 1 << ( $bnum & 7 ^ 7 ); + if ( ( $v6vec[ $idx ] & $b_mask ) > 0 ) { + if ( $x[1] >= $this->databaseSegments ) { + return $x[1]; + } + $offset = $x[1]; + } else { + if ( $x[0] >= $this->databaseSegments ) { + return $x[0]; + } + $offset = $x[0]; + } + } + + $this->log( 'GeoIP API: Error traversing database - perhaps it is corrupt?', 'error' ); + + return false; + } + + /** + * Seek country. + * + * @param int $ipnum + * @return string + */ + private function _geoip_seek_country( $ipnum ) { + $offset = 0; + for ( $depth = 31; $depth >= 0; --$depth ) { + if ( $this->flags & self::GEOIP_MEMORY_CACHE ) { + $buf = $this->_safe_substr( + $this->memory_buffer, + 2 * $this->record_length * $offset, + 2 * $this->record_length + ); + } elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) { + $buf = @shmop_read( + $this->shmid, + 2 * $this->record_length * $offset, + 2 * $this->record_length + ); + } else { + if ( 0 != fseek( $this->filehandle, 2 * $this->record_length * $offset, SEEK_SET ) ) { + break; + } + + $buf = fread( $this->filehandle, 2 * $this->record_length ); + } + + $x = array( 0, 0 ); + for ( $i = 0; $i < 2; ++$i ) { + for ( $j = 0; $j < $this->record_length; ++$j ) { + $x[ $i ] += ord( $buf[ $this->record_length * $i + $j ] ) << ( $j * 8 ); + } + } + if ( $ipnum & ( 1 << $depth ) ) { + if ( $x[1] >= $this->databaseSegments ) { + return $x[1]; + } + + $offset = $x[1]; + } else { + if ( $x[0] >= $this->databaseSegments ) { + return $x[0]; + } + + $offset = $x[0]; + } + } + + $this->log( 'GeoIP API: Error traversing database - perhaps it is corrupt?', 'error' ); + + return false; + } + + /** + * Record by addr. + * + * @param string $addr + * + * @return WC_Geo_IP_Record + */ + public function geoip_record_by_addr( $addr ) { + if ( null == $addr ) { + return 0; + } + + $ipnum = ip2long( $addr ); + return $this->_get_record( $ipnum ); + } + + /** + * Country ID by addr IPv6. + * + * @param string $addr + * @return int|bool + */ + public function geoip_country_id_by_addr_v6( $addr ) { + if ( ! defined( 'AF_INET6' ) ) { + $this->log( 'GEOIP (geoip_country_id_by_addr_v6): PHP was compiled with --disable-ipv6 option' ); + return false; + } + $ipnum = inet_pton( $addr ); + return $this->_geoip_seek_country_v6( $ipnum ) - self::GEOIP_COUNTRY_BEGIN; + } + + /** + * Country ID by addr. + * + * @param string $addr + * @return int + */ + public function geoip_country_id_by_addr( $addr ) { + $ipnum = ip2long( $addr ); + return $this->_geoip_seek_country( $ipnum ) - self::GEOIP_COUNTRY_BEGIN; + } + + /** + * Country code by addr IPv6. + * + * @param string $addr + * @return string + */ + public function geoip_country_code_by_addr_v6( $addr ) { + $country_id = $this->geoip_country_id_by_addr_v6( $addr ); + if ( false !== $country_id && isset( $this->GEOIP_COUNTRY_CODES[ $country_id ] ) ) { + return $this->GEOIP_COUNTRY_CODES[ $country_id ]; + } + + return false; + } + + /** + * Country code by addr. + * + * @param string $addr + * @return string + */ + public function geoip_country_code_by_addr( $addr ) { + if ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) { + $record = $this->geoip_record_by_addr( $addr ); + if ( false !== $record ) { + return $record->country_code; + } + } else { + $country_id = $this->geoip_country_id_by_addr( $addr ); + if ( false !== $country_id && isset( $this->GEOIP_COUNTRY_CODES[ $country_id ] ) ) { + return $this->GEOIP_COUNTRY_CODES[ $country_id ]; + } + } + + return false; + } + + /** + * Encode string. + * + * @param string $string + * @param int $start + * @param int $length + * @return string + */ + private function _safe_substr( $string, $start, $length ) { + // workaround php's broken substr, strpos, etc handling with + // mbstring.func_overload and mbstring.internal_encoding + $mb_exists = extension_loaded( 'mbstring' ); + + if ( $mb_exists ) { + $enc = mb_internal_encoding(); + mb_internal_encoding( 'ISO-8859-1' ); + } + + $buf = substr( $string, $start, $length ); + + if ( $mb_exists ) { + mb_internal_encoding( $enc ); + } + + return $buf; + } +} + +/** + * Geo IP Record class. + */ +class WC_Geo_IP_Record { + + /** + * Country code. + * + * @var string + */ + public $country_code; + + /** + * 3 letters country code. + * + * @var string + */ + public $country_code3; + + /** + * Country name. + * + * @var string + */ + public $country_name; + + /** + * Region. + * + * @var string + */ + public $region; + + /** + * City. + * + * @var string + */ + public $city; + + /** + * Postal code. + * + * @var string + */ + public $postal_code; + + /** + * Latitude + * + * @var int + */ + public $latitude; + + /** + * Longitude. + * + * @var int + */ + public $longitude; + + /** + * Area code. + * + * @var int + */ + public $area_code; + + /** + * DMA Code. + * + * Metro and DMA code are the same. + * Use metro code instead. + * + * @var float + */ + public $dma_code; + + /** + * Metro code. + * + * @var float + */ + public $metro_code; + + /** + * Continent code. + * + * @var string + */ + public $continent_code; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-geolite-integration.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-geolite-integration.php new file mode 100644 index 0000000..c661aa0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-geolite-integration.php @@ -0,0 +1,92 @@ +database = $database; + } + + /** + * Get country 2-letters ISO by IP address. + * Returns empty string when not able to find any ISO code. + * + * @param string $ip_address User IP address. + * @return string + * @deprecated 3.9.0 + */ + public function get_country_iso( $ip_address ) { + wc_deprecated_function( 'get_country_iso', '3.9.0' ); + + $iso_code = ''; + + try { + $reader = new MaxMind\Db\Reader( $this->database ); // phpcs:ignore PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound + $data = $reader->get( $ip_address ); + + if ( isset( $data['country']['iso_code'] ) ) { + $iso_code = $data['country']['iso_code']; + } + + $reader->close(); + } catch ( Exception $e ) { + $this->log( $e->getMessage(), 'warning' ); + } + + return sanitize_text_field( strtoupper( $iso_code ) ); + } + + /** + * Logging method. + * + * @param string $message Log message. + * @param string $level Log level. + * Available options: 'emergency', 'alert', + * 'critical', 'error', 'warning', 'notice', + * 'info' and 'debug'. + * Defaults to 'info'. + */ + private function log( $message, $level = 'info' ) { + if ( is_null( $this->log ) ) { + $this->log = wc_get_logger(); + } + + $this->log->log( $level, $message, array( 'source' => 'geoip' ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-geolocation.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-geolocation.php new file mode 100644 index 0000000..97d9184 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-geolocation.php @@ -0,0 +1,356 @@ + 'http://api.ipify.org/', + 'ipecho' => 'http://ipecho.net/plain', + 'ident' => 'http://ident.me', + 'whatismyipaddress' => 'http://bot.whatismyipaddress.com', + ); + + /** + * API endpoints for geolocating an IP address + * + * @var array + */ + private static $geoip_apis = array( + 'ipinfo.io' => 'https://ipinfo.io/%s/json', + 'ip-api.com' => 'http://ip-api.com/json/%s', + ); + + /** + * Check if geolocation is enabled. + * + * @since 3.4.0 + * @param string $current_settings Current geolocation settings. + * @return bool + */ + private static function is_geolocation_enabled( $current_settings ) { + return in_array( $current_settings, array( 'geolocation', 'geolocation_ajax' ), true ); + } + + /** + * Get current user IP Address. + * + * @return string + */ + public static function get_ip_address() { + if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) { + return sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) ); + } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { + // Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2 + // Make sure we always only send through the first IP in the list which should always be the client IP. + return (string) rest_is_ip_address( trim( current( preg_split( '/,/', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) ) ) ); + } elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) { + return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); + } + return ''; + } + + /** + * Get user IP Address using an external service. + * This can be used as a fallback for users on localhost where + * get_ip_address() will be a local IP and non-geolocatable. + * + * @return string + */ + public static function get_external_ip_address() { + $external_ip_address = '0.0.0.0'; + + if ( '' !== self::get_ip_address() ) { + $transient_name = 'external_ip_address_' . self::get_ip_address(); + $external_ip_address = get_transient( $transient_name ); + } + + if ( false === $external_ip_address ) { + $external_ip_address = '0.0.0.0'; + $ip_lookup_services = apply_filters( 'woocommerce_geolocation_ip_lookup_apis', self::$ip_lookup_apis ); + $ip_lookup_services_keys = array_keys( $ip_lookup_services ); + shuffle( $ip_lookup_services_keys ); + + foreach ( $ip_lookup_services_keys as $service_name ) { + $service_endpoint = $ip_lookup_services[ $service_name ]; + $response = wp_safe_remote_get( $service_endpoint, array( 'timeout' => 2 ) ); + + if ( ! is_wp_error( $response ) && rest_is_ip_address( $response['body'] ) ) { + $external_ip_address = apply_filters( 'woocommerce_geolocation_ip_lookup_api_response', wc_clean( $response['body'] ), $service_name ); + break; + } + } + + set_transient( $transient_name, $external_ip_address, WEEK_IN_SECONDS ); + } + + return $external_ip_address; + } + + /** + * Geolocate an IP address. + * + * @param string $ip_address IP Address. + * @param bool $fallback If true, fallbacks to alternative IP detection (can be slower). + * @param bool $api_fallback If true, uses geolocation APIs if the database file doesn't exist (can be slower). + * @return array + */ + public static function geolocate_ip( $ip_address = '', $fallback = false, $api_fallback = true ) { + // Filter to allow custom geolocation of the IP address. + $country_code = apply_filters( 'woocommerce_geolocate_ip', false, $ip_address, $fallback, $api_fallback ); + + if ( false !== $country_code ) { + return array( + 'country' => $country_code, + 'state' => '', + 'city' => '', + 'postcode' => '', + ); + } + + if ( empty( $ip_address ) ) { + $ip_address = self::get_ip_address(); + } + + $country_code = self::get_country_code_from_headers(); + + /** + * Get geolocation filter. + * + * @since 3.9.0 + * @param array $geolocation Geolocation data, including country, state, city, and postcode. + * @param string $ip_address IP Address. + */ + $geolocation = apply_filters( + 'woocommerce_get_geolocation', + array( + 'country' => $country_code, + 'state' => '', + 'city' => '', + 'postcode' => '', + ), + $ip_address + ); + + // If we still haven't found a country code, let's consider doing an API lookup. + if ( '' === $geolocation['country'] && $api_fallback ) { + $geolocation['country'] = self::geolocate_via_api( $ip_address ); + } + + // It's possible that we're in a local environment, in which case the geolocation needs to be done from the + // external address. + if ( '' === $geolocation['country'] && $fallback ) { + $external_ip_address = self::get_external_ip_address(); + + // Only bother with this if the external IP differs. + if ( '0.0.0.0' !== $external_ip_address && $external_ip_address !== $ip_address ) { + return self::geolocate_ip( $external_ip_address, false, $api_fallback ); + } + } + + return array( + 'country' => $geolocation['country'], + 'state' => $geolocation['state'], + 'city' => $geolocation['city'], + 'postcode' => $geolocation['postcode'], + ); + } + + /** + * Path to our local db. + * + * @deprecated 3.9.0 + * @param string $deprecated Deprecated since 3.4.0. + * @return string + */ + public static function get_local_database_path( $deprecated = '2' ) { + wc_deprecated_function( 'WC_Geolocation::get_local_database_path', '3.9.0' ); + $integration = wc()->integrations->get_integration( 'maxmind_geolocation' ); + return $integration->get_database_service()->get_database_path(); + } + + /** + * Update geoip database. + * + * @deprecated 3.9.0 + * Extract files with PharData. Tool built into PHP since 5.3. + */ + public static function update_database() { + wc_deprecated_function( 'WC_Geolocation::update_database', '3.9.0' ); + $integration = wc()->integrations->get_integration( 'maxmind_geolocation' ); + $integration->update_database(); + } + + /** + * Fetches the country code from the request headers, if one is available. + * + * @since 3.9.0 + * @return string The country code pulled from the headers, or empty string if one was not found. + */ + private static function get_country_code_from_headers() { + $country_code = ''; + + $headers = array( + 'MM_COUNTRY_CODE', + 'GEOIP_COUNTRY_CODE', + 'HTTP_CF_IPCOUNTRY', + 'HTTP_X_COUNTRY_CODE', + ); + + foreach ( $headers as $header ) { + if ( empty( $_SERVER[ $header ] ) ) { + continue; + } + + $country_code = strtoupper( sanitize_text_field( wp_unslash( $_SERVER[ $header ] ) ) ); + break; + } + + return $country_code; + } + + /** + * Use APIs to Geolocate the user. + * + * Geolocation APIs can be added through the use of the woocommerce_geolocation_geoip_apis filter. + * Provide a name=>value pair for service-slug=>endpoint. + * + * If APIs are defined, one will be chosen at random to fulfil the request. After completing, the result + * will be cached in a transient. + * + * @param string $ip_address IP address. + * @return string + */ + private static function geolocate_via_api( $ip_address ) { + $country_code = get_transient( 'geoip_' . $ip_address ); + + if ( false === $country_code ) { + $geoip_services = apply_filters( 'woocommerce_geolocation_geoip_apis', self::$geoip_apis ); + + if ( empty( $geoip_services ) ) { + return ''; + } + + $geoip_services_keys = array_keys( $geoip_services ); + + shuffle( $geoip_services_keys ); + + foreach ( $geoip_services_keys as $service_name ) { + $service_endpoint = $geoip_services[ $service_name ]; + $response = wp_safe_remote_get( sprintf( $service_endpoint, $ip_address ), array( 'timeout' => 2 ) ); + + if ( ! is_wp_error( $response ) && $response['body'] ) { + switch ( $service_name ) { + case 'ipinfo.io': + $data = json_decode( $response['body'] ); + $country_code = isset( $data->country ) ? $data->country : ''; + break; + case 'ip-api.com': + $data = json_decode( $response['body'] ); + $country_code = isset( $data->countryCode ) ? $data->countryCode : ''; // @codingStandardsIgnoreLine + break; + default: + $country_code = apply_filters( 'woocommerce_geolocation_geoip_response_' . $service_name, '', $response['body'] ); + break; + } + + $country_code = sanitize_text_field( strtoupper( $country_code ) ); + + if ( $country_code ) { + break; + } + } + } + + set_transient( 'geoip_' . $ip_address, $country_code, WEEK_IN_SECONDS ); + } + + return $country_code; + } + + /** + * Hook in geolocation functionality. + * + * @deprecated 3.9.0 + * @return null + */ + public static function init() { + wc_deprecated_function( 'WC_Geolocation::init', '3.9.0' ); + return null; + } + + /** + * Prevent geolocation via MaxMind when using legacy versions of php. + * + * @deprecated 3.9.0 + * @since 3.4.0 + * @param string $default_customer_address current value. + * @return string + */ + public static function disable_geolocation_on_legacy_php( $default_customer_address ) { + wc_deprecated_function( 'WC_Geolocation::disable_geolocation_on_legacy_php', '3.9.0' ); + + if ( self::is_geolocation_enabled( $default_customer_address ) ) { + $default_customer_address = 'base'; + } + + return $default_customer_address; + } + + /** + * Maybe trigger a DB update for the first time. + * + * @deprecated 3.9.0 + * @param string $new_value New value. + * @param string $old_value Old value. + * @return string + */ + public static function maybe_update_database( $new_value, $old_value ) { + wc_deprecated_function( 'WC_Geolocation::maybe_update_database', '3.9.0' ); + if ( $new_value !== $old_value && self::is_geolocation_enabled( $new_value ) ) { + self::update_database(); + } + + return $new_value; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-https.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-https.php new file mode 100644 index 0000000..84e3aed --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-https.php @@ -0,0 +1,138 @@ + array( + 'wc_update_200_file_paths', + 'wc_update_200_permalinks', + 'wc_update_200_subcat_display', + 'wc_update_200_taxrates', + 'wc_update_200_line_items', + 'wc_update_200_images', + 'wc_update_200_db_version', + ), + '2.0.9' => array( + 'wc_update_209_brazillian_state', + 'wc_update_209_db_version', + ), + '2.1.0' => array( + 'wc_update_210_remove_pages', + 'wc_update_210_file_paths', + 'wc_update_210_db_version', + ), + '2.2.0' => array( + 'wc_update_220_shipping', + 'wc_update_220_order_status', + 'wc_update_220_variations', + 'wc_update_220_attributes', + 'wc_update_220_db_version', + ), + '2.3.0' => array( + 'wc_update_230_options', + 'wc_update_230_db_version', + ), + '2.4.0' => array( + 'wc_update_240_options', + 'wc_update_240_shipping_methods', + 'wc_update_240_api_keys', + 'wc_update_240_refunds', + 'wc_update_240_db_version', + ), + '2.4.1' => array( + 'wc_update_241_variations', + 'wc_update_241_db_version', + ), + '2.5.0' => array( + 'wc_update_250_currency', + 'wc_update_250_db_version', + ), + '2.6.0' => array( + 'wc_update_260_options', + 'wc_update_260_termmeta', + 'wc_update_260_zones', + 'wc_update_260_zone_methods', + 'wc_update_260_refunds', + 'wc_update_260_db_version', + ), + '3.0.0' => array( + 'wc_update_300_grouped_products', + 'wc_update_300_settings', + 'wc_update_300_product_visibility', + 'wc_update_300_db_version', + ), + '3.1.0' => array( + 'wc_update_310_downloadable_products', + 'wc_update_310_old_comments', + 'wc_update_310_db_version', + ), + '3.1.2' => array( + 'wc_update_312_shop_manager_capabilities', + 'wc_update_312_db_version', + ), + '3.2.0' => array( + 'wc_update_320_mexican_states', + 'wc_update_320_db_version', + ), + '3.3.0' => array( + 'wc_update_330_image_options', + 'wc_update_330_webhooks', + 'wc_update_330_product_stock_status', + 'wc_update_330_set_default_product_cat', + 'wc_update_330_clear_transients', + 'wc_update_330_set_paypal_sandbox_credentials', + 'wc_update_330_db_version', + ), + '3.4.0' => array( + 'wc_update_340_states', + 'wc_update_340_state', + 'wc_update_340_last_active', + 'wc_update_340_db_version', + ), + '3.4.3' => array( + 'wc_update_343_cleanup_foreign_keys', + 'wc_update_343_db_version', + ), + '3.4.4' => array( + 'wc_update_344_recreate_roles', + 'wc_update_344_db_version', + ), + '3.5.0' => array( + 'wc_update_350_reviews_comment_type', + 'wc_update_350_db_version', + ), + '3.5.2' => array( + 'wc_update_352_drop_download_log_fk', + ), + '3.5.4' => array( + 'wc_update_354_modify_shop_manager_caps', + 'wc_update_354_db_version', + ), + '3.6.0' => array( + 'wc_update_360_product_lookup_tables', + 'wc_update_360_term_meta', + 'wc_update_360_downloadable_product_permissions_index', + 'wc_update_360_db_version', + ), + '3.7.0' => array( + 'wc_update_370_tax_rate_classes', + 'wc_update_370_mro_std_currency', + 'wc_update_370_db_version', + ), + '3.9.0' => array( + 'wc_update_390_move_maxmind_database', + 'wc_update_390_change_geolocation_database_update_cron', + 'wc_update_390_db_version', + ), + '4.0.0' => array( + 'wc_update_product_lookup_tables', + 'wc_update_400_increase_size_of_column', + 'wc_update_400_reset_action_scheduler_migration_status', + 'wc_update_400_db_version', + ), + '4.4.0' => array( + 'wc_update_440_insert_attribute_terms_for_variable_products', + 'wc_update_440_db_version', + ), + '4.5.0' => array( + 'wc_update_450_sanitize_coupons_code', + 'wc_update_450_db_version', + ), + ); + + /** + * Hook in tabs. + */ + public static function init() { + add_action( 'init', array( __CLASS__, 'check_version' ), 5 ); + add_action( 'init', array( __CLASS__, 'manual_database_update' ), 20 ); + add_action( 'admin_init', array( __CLASS__, 'wc_admin_db_update_notice' ) ); + add_action( 'woocommerce_run_update_callback', array( __CLASS__, 'run_update_callback' ) ); + add_action( 'admin_init', array( __CLASS__, 'install_actions' ) ); + add_filter( 'plugin_action_links_' . WC_PLUGIN_BASENAME, array( __CLASS__, 'plugin_action_links' ) ); + add_filter( 'plugin_row_meta', array( __CLASS__, 'plugin_row_meta' ), 10, 2 ); + add_filter( 'wpmu_drop_tables', array( __CLASS__, 'wpmu_drop_tables' ) ); + add_filter( 'cron_schedules', array( __CLASS__, 'cron_schedules' ) ); + } + + /** + * Check WooCommerce version and run the updater is required. + * + * This check is done on all requests and runs if the versions do not match. + */ + public static function check_version() { + if ( ! Constants::is_defined( 'IFRAME_REQUEST' ) && version_compare( get_option( 'woocommerce_version' ), WC()->version, '<' ) ) { + self::install(); + do_action( 'woocommerce_updated' ); + } + } + + /** + * Performan manual database update when triggered by WooCommerce System Tools. + * + * @since 3.6.5 + */ + public static function manual_database_update() { + $blog_id = get_current_blog_id(); + + add_action( 'wp_' . $blog_id . '_wc_updater_cron', array( __CLASS__, 'run_manual_database_update' ) ); + } + + /** + * Add WC Admin based db update notice. + * + * @since 4.0.0 + */ + public static function wc_admin_db_update_notice() { + if ( + WC()->is_wc_admin_active() && + false !== get_option( 'woocommerce_admin_install_timestamp' ) + ) { + new WC_Notes_Run_Db_Update(); + } + } + + /** + * Run manual database update. + */ + public static function run_manual_database_update() { + self::update(); + } + + /** + * Run an update callback when triggered by ActionScheduler. + * + * @since 3.6.0 + * @param string $callback Callback name. + */ + public static function run_update_callback( $callback ) { + include_once dirname( __FILE__ ) . '/wc-update-functions.php'; + + if ( is_callable( $callback ) ) { + self::run_update_callback_start( $callback ); + $result = (bool) call_user_func( $callback ); + self::run_update_callback_end( $callback, $result ); + } + } + + /** + * Triggered when a callback will run. + * + * @since 3.6.0 + * @param string $callback Callback name. + */ + protected static function run_update_callback_start( $callback ) { + wc_maybe_define_constant( 'WC_UPDATING', true ); + } + + /** + * Triggered when a callback has ran. + * + * @since 3.6.0 + * @param string $callback Callback name. + * @param bool $result Return value from callback. Non-false need to run again. + */ + protected static function run_update_callback_end( $callback, $result ) { + if ( $result ) { + WC()->queue()->add( + 'woocommerce_run_update_callback', + array( + 'update_callback' => $callback, + ), + 'woocommerce-db-updates' + ); + } + } + + /** + * Install actions when a update button is clicked within the admin area. + * + * This function is hooked into admin_init to affect admin only. + */ + public static function install_actions() { + if ( ! empty( $_GET['do_update_woocommerce'] ) ) { // WPCS: input var ok. + check_admin_referer( 'wc_db_update', 'wc_db_update_nonce' ); + self::update(); + WC_Admin_Notices::add_notice( 'update', true ); + } + } + + /** + * Install WC. + */ + public static function install() { + if ( ! is_blog_installed() ) { + return; + } + + // Check if we are not already running this routine. + if ( 'yes' === get_transient( 'wc_installing' ) ) { + return; + } + + // If we made it till here nothing is running yet, lets set the transient now. + set_transient( 'wc_installing', 'yes', MINUTE_IN_SECONDS * 10 ); + wc_maybe_define_constant( 'WC_INSTALLING', true ); + + WC()->wpdb_table_fix(); + self::remove_admin_notices(); + self::create_tables(); + self::verify_base_tables(); + self::create_options(); + self::create_roles(); + self::setup_environment(); + self::create_terms(); + self::create_cron_jobs(); + self::create_files(); + self::maybe_create_pages(); + self::maybe_set_activation_transients(); + self::update_wc_version(); + self::maybe_update_db_version(); + + delete_transient( 'wc_installing' ); + + do_action( 'woocommerce_flush_rewrite_rules' ); + do_action( 'woocommerce_installed' ); + } + + /** + * Check if all the base tables are present. + * + * @param bool $modify_notice Whether to modify notice based on if all tables are present. + * @param bool $execute Whether to execute get_schema queries as well. + * + * @return array List of querues. + */ + public static function verify_base_tables( $modify_notice = true, $execute = false ) { + require_once ABSPATH . 'wp-admin/includes/upgrade.php'; + + if ( $execute ) { + self::create_tables(); + } + $queries = dbDelta( self::get_schema(), false ); + $missing_tables = array(); + foreach ( $queries as $table_name => $result ) { + if ( "Created table $table_name" === $result ) { + $missing_tables[] = $table_name; + } + } + + if ( 0 < count( $missing_tables ) ) { + if ( $modify_notice ) { + WC_Admin_Notices::add_notice( 'base_tables_missing' ); + } + update_option( 'woocommerce_schema_missing_tables', $missing_tables ); + } else { + if ( $modify_notice ) { + WC_Admin_Notices::remove_notice( 'base_tables_missing' ); + } + update_option( 'woocommerce_schema_version', WC()->db_version ); + delete_option( 'woocommerce_schema_missing_tables' ); + } + return $missing_tables; + } + + /** + * Reset any notices added to admin. + * + * @since 3.2.0 + */ + private static function remove_admin_notices() { + include_once dirname( __FILE__ ) . '/admin/class-wc-admin-notices.php'; + WC_Admin_Notices::remove_all_notices(); + } + + /** + * Setup WC environment - post types, taxonomies, endpoints. + * + * @since 3.2.0 + */ + private static function setup_environment() { + WC_Post_types::register_post_types(); + WC_Post_types::register_taxonomies(); + WC()->query->init_query_vars(); + WC()->query->add_endpoints(); + WC_API::add_endpoint(); + WC_Auth::add_endpoint(); + } + + /** + * Is this a brand new WC install? + * + * A brand new install has no version yet. Also treat empty installs as 'new'. + * + * @since 3.2.0 + * @return boolean + */ + public static function is_new_install() { + $product_count = array_sum( (array) wp_count_posts( 'product' ) ); + + return is_null( get_option( 'woocommerce_version', null ) ) || ( 0 === $product_count && -1 === wc_get_page_id( 'shop' ) ); + } + + /** + * Is a DB update needed? + * + * @since 3.2.0 + * @return boolean + */ + public static function needs_db_update() { + $current_db_version = get_option( 'woocommerce_db_version', null ); + $updates = self::get_db_update_callbacks(); + $update_versions = array_keys( $updates ); + usort( $update_versions, 'version_compare' ); + + return ! is_null( $current_db_version ) && version_compare( $current_db_version, end( $update_versions ), '<' ); + } + + /** + * See if we need to set redirect transients for activation or not. + * + * @since 4.6.0 + */ + private static function maybe_set_activation_transients() { + if ( self::is_new_install() ) { + set_transient( '_wc_activation_redirect', 1, 30 ); + } + } + + /** + * See if we need to show or run database updates during install. + * + * @since 3.2.0 + */ + private static function maybe_update_db_version() { + if ( self::needs_db_update() ) { + if ( apply_filters( 'woocommerce_enable_auto_update_db', false ) ) { + self::update(); + } else { + WC_Admin_Notices::add_notice( 'update', true ); + } + } else { + self::update_db_version(); + } + } + + /** + * Update WC version to current. + */ + private static function update_wc_version() { + update_option( 'woocommerce_version', WC()->version ); + } + + /** + * Get list of DB update callbacks. + * + * @since 3.0.0 + * @return array + */ + public static function get_db_update_callbacks() { + return self::$db_updates; + } + + /** + * Push all needed DB updates to the queue for processing. + */ + private static function update() { + $current_db_version = get_option( 'woocommerce_db_version' ); + $loop = 0; + + foreach ( self::get_db_update_callbacks() as $version => $update_callbacks ) { + if ( version_compare( $current_db_version, $version, '<' ) ) { + foreach ( $update_callbacks as $update_callback ) { + WC()->queue()->schedule_single( + time() + $loop, + 'woocommerce_run_update_callback', + array( + 'update_callback' => $update_callback, + ), + 'woocommerce-db-updates' + ); + $loop++; + } + } + } + } + + /** + * Update DB version to current. + * + * @param string|null $version New WooCommerce DB version or null. + */ + public static function update_db_version( $version = null ) { + update_option( 'woocommerce_db_version', is_null( $version ) ? WC()->version : $version ); + } + + /** + * Add more cron schedules. + * + * @param array $schedules List of WP scheduled cron jobs. + * + * @return array + */ + public static function cron_schedules( $schedules ) { + $schedules['monthly'] = array( + 'interval' => 2635200, + 'display' => __( 'Monthly', 'woocommerce' ), + ); + $schedules['fifteendays'] = array( + 'interval' => 1296000, + 'display' => __( 'Every 15 Days', 'woocommerce' ), + ); + return $schedules; + } + + /** + * Create cron jobs (clear them first). + */ + private static function create_cron_jobs() { + wp_clear_scheduled_hook( 'woocommerce_scheduled_sales' ); + wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' ); + wp_clear_scheduled_hook( 'woocommerce_cleanup_sessions' ); + wp_clear_scheduled_hook( 'woocommerce_cleanup_personal_data' ); + wp_clear_scheduled_hook( 'woocommerce_cleanup_logs' ); + wp_clear_scheduled_hook( 'woocommerce_geoip_updater' ); + wp_clear_scheduled_hook( 'woocommerce_tracker_send_event' ); + + $ve = get_option( 'gmt_offset' ) > 0 ? '-' : '+'; + + wp_schedule_event( strtotime( '00:00 tomorrow ' . $ve . absint( get_option( 'gmt_offset' ) ) . ' HOURS' ), 'daily', 'woocommerce_scheduled_sales' ); + + $held_duration = get_option( 'woocommerce_hold_stock_minutes', '60' ); + + if ( '' !== $held_duration ) { + wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' ); + } + + // Delay the first run of `woocommerce_cleanup_personal_data` by 10 seconds + // so it doesn't occur in the same request. WooCommerce Admin also schedules + // a daily cron that gets lost due to a race condition. WC_Privacy's background + // processing instance updates the cron schedule from within a cron job. + wp_schedule_event( time() + 10, 'daily', 'woocommerce_cleanup_personal_data' ); + wp_schedule_event( time() + ( 3 * HOUR_IN_SECONDS ), 'daily', 'woocommerce_cleanup_logs' ); + wp_schedule_event( time() + ( 6 * HOUR_IN_SECONDS ), 'twicedaily', 'woocommerce_cleanup_sessions' ); + wp_schedule_event( time() + MINUTE_IN_SECONDS, 'fifteendays', 'woocommerce_geoip_updater' ); + wp_schedule_event( time() + 10, apply_filters( 'woocommerce_tracker_event_recurrence', 'daily' ), 'woocommerce_tracker_send_event' ); + } + + /** + * Create pages on installation. + */ + public static function maybe_create_pages() { + if ( empty( get_option( 'woocommerce_db_version' ) ) ) { + self::create_pages(); + } + } + + /** + * Create pages that the plugin relies on, storing page IDs in variables. + */ + public static function create_pages() { + include_once dirname( __FILE__ ) . '/admin/wc-admin-functions.php'; + + $pages = apply_filters( + 'woocommerce_create_pages', + array( + 'shop' => array( + 'name' => _x( 'shop', 'Page slug', 'woocommerce' ), + 'title' => _x( 'Shop', 'Page title', 'woocommerce' ), + 'content' => '', + ), + 'cart' => array( + 'name' => _x( 'cart', 'Page slug', 'woocommerce' ), + 'title' => _x( 'Cart', 'Page title', 'woocommerce' ), + 'content' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', + ), + 'checkout' => array( + 'name' => _x( 'checkout', 'Page slug', 'woocommerce' ), + 'title' => _x( 'Checkout', 'Page title', 'woocommerce' ), + 'content' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', + ), + 'myaccount' => array( + 'name' => _x( 'my-account', 'Page slug', 'woocommerce' ), + 'title' => _x( 'My account', 'Page title', 'woocommerce' ), + 'content' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', + ), + ) + ); + + foreach ( $pages as $key => $page ) { + wc_create_page( esc_sql( $page['name'] ), 'woocommerce_' . $key . '_page_id', $page['title'], $page['content'], ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '' ); + } + } + + /** + * Default options. + * + * Sets up the default options used on the settings page. + */ + private static function create_options() { + // Include settings so that we can run through defaults. + include_once dirname( __FILE__ ) . '/admin/class-wc-admin-settings.php'; + + $settings = WC_Admin_Settings::get_settings_pages(); + + foreach ( $settings as $section ) { + if ( ! method_exists( $section, 'get_settings' ) ) { + continue; + } + $subsections = array_unique( array_merge( array( '' ), array_keys( $section->get_sections() ) ) ); + + foreach ( $subsections as $subsection ) { + foreach ( $section->get_settings( $subsection ) as $value ) { + if ( isset( $value['default'] ) && isset( $value['id'] ) ) { + $autoload = isset( $value['autoload'] ) ? (bool) $value['autoload'] : true; + add_option( $value['id'], $value['default'], '', ( $autoload ? 'yes' : 'no' ) ); + } + } + } + } + + // Define other defaults if not in setting screens. + add_option( 'woocommerce_single_image_width', '600', '', 'yes' ); + add_option( 'woocommerce_thumbnail_image_width', '300', '', 'yes' ); + add_option( 'woocommerce_checkout_highlight_required_fields', 'yes', '', 'yes' ); + add_option( 'woocommerce_demo_store', 'no', '', 'no' ); + + // Define initial tax classes. + WC_Tax::create_tax_class( __( 'Reduced rate', 'woocommerce' ) ); + WC_Tax::create_tax_class( __( 'Zero rate', 'woocommerce' ) ); + } + + /** + * Add the default terms for WC taxonomies - product types and order statuses. Modify this at your own risk. + */ + public static function create_terms() { + $taxonomies = array( + 'product_type' => array( + 'simple', + 'grouped', + 'variable', + 'external', + ), + 'product_visibility' => array( + 'exclude-from-search', + 'exclude-from-catalog', + 'featured', + 'outofstock', + 'rated-1', + 'rated-2', + 'rated-3', + 'rated-4', + 'rated-5', + ), + ); + + foreach ( $taxonomies as $taxonomy => $terms ) { + foreach ( $terms as $term ) { + if ( ! get_term_by( 'name', $term, $taxonomy ) ) { // @codingStandardsIgnoreLine. + wp_insert_term( $term, $taxonomy ); + } + } + } + + $woocommerce_default_category = (int) get_option( 'default_product_cat', 0 ); + + if ( ! $woocommerce_default_category || ! term_exists( $woocommerce_default_category, 'product_cat' ) ) { + $default_product_cat_id = 0; + $default_product_cat_slug = sanitize_title( _x( 'Uncategorized', 'Default category slug', 'woocommerce' ) ); + $default_product_cat = get_term_by( 'slug', $default_product_cat_slug, 'product_cat' ); // @codingStandardsIgnoreLine. + + if ( $default_product_cat ) { + $default_product_cat_id = absint( $default_product_cat->term_taxonomy_id ); + } else { + $result = wp_insert_term( _x( 'Uncategorized', 'Default category slug', 'woocommerce' ), 'product_cat', array( 'slug' => $default_product_cat_slug ) ); + + if ( ! is_wp_error( $result ) && ! empty( $result['term_taxonomy_id'] ) ) { + $default_product_cat_id = absint( $result['term_taxonomy_id'] ); + } + } + + if ( $default_product_cat_id ) { + update_option( 'default_product_cat', $default_product_cat_id ); + } + } + } + + /** + * Set up the database tables which the plugin needs to function. + * WARNING: If you are modifying this method, make sure that its safe to call regardless of the state of database. + * + * This is called from `install` method and is executed in-sync when WC is installed or updated. This can also be called optionally from `verify_base_tables`. + * + * TODO: Add all crucial tables that we have created from workers in the past. + * + * Tables: + * woocommerce_attribute_taxonomies - Table for storing attribute taxonomies - these are user defined + * woocommerce_downloadable_product_permissions - Table for storing user and guest download permissions. + * KEY(order_id, product_id, download_id) used for organizing downloads on the My Account page + * woocommerce_order_items - Order line items are stored in a table to make them easily queryable for reports + * woocommerce_order_itemmeta - Order line item meta is stored in a table for storing extra data. + * woocommerce_tax_rates - Tax Rates are stored inside 2 tables making tax queries simple and efficient. + * woocommerce_tax_rate_locations - Each rate can be applied to more than one postcode/city hence the second table. + */ + private static function create_tables() { + global $wpdb; + + $wpdb->hide_errors(); + + require_once ABSPATH . 'wp-admin/includes/upgrade.php'; + + /** + * Before updating with DBDELTA, remove any primary keys which could be + * modified due to schema updates. + */ + if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_downloadable_product_permissions';" ) ) { + if ( ! $wpdb->get_var( "SHOW COLUMNS FROM `{$wpdb->prefix}woocommerce_downloadable_product_permissions` LIKE 'permission_id';" ) ) { + $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions DROP PRIMARY KEY, ADD `permission_id` BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT;" ); + } + } + + /** + * Change wp_woocommerce_sessions schema to use a bigint auto increment field instead of char(32) field as + * the primary key as it is not a good practice to use a char(32) field as the primary key of a table and as + * there were reports of issues with this table (see https://github.com/woocommerce/woocommerce/issues/20912). + * + * This query needs to run before dbDelta() as this WP function is not able to handle primary key changes + * (see https://github.com/woocommerce/woocommerce/issues/21534 and https://core.trac.wordpress.org/ticket/40357). + */ + if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_sessions'" ) ) { + if ( ! $wpdb->get_var( "SHOW KEYS FROM {$wpdb->prefix}woocommerce_sessions WHERE Key_name = 'PRIMARY' AND Column_name = 'session_id'" ) ) { + $wpdb->query( + "ALTER TABLE `{$wpdb->prefix}woocommerce_sessions` DROP PRIMARY KEY, DROP KEY `session_id`, ADD PRIMARY KEY(`session_id`), ADD UNIQUE KEY(`session_key`)" + ); + } + } + + dbDelta( self::get_schema() ); + + $index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->comments} WHERE column_name = 'comment_type' and key_name = 'woo_idx_comment_type'" ); + + if ( is_null( $index_exists ) ) { + // Add an index to the field comment_type to improve the response time of the query + // used by WC_Comments::wp_count_comments() to get the number of comments by type. + $wpdb->query( "ALTER TABLE {$wpdb->comments} ADD INDEX woo_idx_comment_type (comment_type)" ); + } + + // Get tables data types and check it matches before adding constraint. + $download_log_columns = $wpdb->get_results( "SHOW COLUMNS FROM {$wpdb->prefix}wc_download_log WHERE Field = 'permission_id'", ARRAY_A ); + $download_log_column_type = ''; + if ( isset( $download_log_columns[0]['Type'] ) ) { + $download_log_column_type = $download_log_columns[0]['Type']; + } + + $download_permissions_columns = $wpdb->get_results( "SHOW COLUMNS FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE Field = 'permission_id'", ARRAY_A ); + $download_permissions_column_type = ''; + if ( isset( $download_permissions_columns[0]['Type'] ) ) { + $download_permissions_column_type = $download_permissions_columns[0]['Type']; + } + + // Add constraint to download logs if the columns matches. + if ( ! empty( $download_permissions_column_type ) && ! empty( $download_log_column_type ) && $download_permissions_column_type === $download_log_column_type ) { + $fk_result = $wpdb->get_row( "SHOW CREATE TABLE {$wpdb->prefix}wc_download_log" ); + if ( false === strpos( $fk_result->{'Create Table'}, "fk_{$wpdb->prefix}wc_download_log_permission_id" ) ) { + $wpdb->query( + "ALTER TABLE `{$wpdb->prefix}wc_download_log` + ADD CONSTRAINT `fk_{$wpdb->prefix}wc_download_log_permission_id` + FOREIGN KEY (`permission_id`) + REFERENCES `{$wpdb->prefix}woocommerce_downloadable_product_permissions` (`permission_id`) ON DELETE CASCADE;" + ); + } + } + + // Clear table caches. + delete_transient( 'wc_attribute_taxonomies' ); + } + + /** + * Get Table schema. + * + * See https://github.com/woocommerce/woocommerce/wiki/Database-Description/ + * + * A note on indexes; Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that. + * As of WordPress 4.2, however, we moved to utf8mb4, which uses 4 bytes per character. This means that an index which + * used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters. + * + * Changing indexes may cause duplicate index notices in logs due to https://core.trac.wordpress.org/ticket/34870 but dropping + * indexes first causes too much load on some servers/larger DB. + * + * When adding or removing a table, make sure to update the list of tables in WC_Install::get_tables(). + * + * @return string + */ + private static function get_schema() { + global $wpdb; + + $collate = ''; + + if ( $wpdb->has_cap( 'collation' ) ) { + $collate = $wpdb->get_charset_collate(); + } + + /* + * Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that. + * As of WP 4.2, however, they moved to utf8mb4, which uses 4 bytes per character. This means that an index which + * used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters. + */ + $max_index_length = 191; + + $tables = " +CREATE TABLE {$wpdb->prefix}woocommerce_sessions ( + session_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + session_key char(32) NOT NULL, + session_value longtext NOT NULL, + session_expiry BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (session_id), + UNIQUE KEY session_key (session_key) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_api_keys ( + key_id BIGINT UNSIGNED NOT NULL auto_increment, + user_id BIGINT UNSIGNED NOT NULL, + description varchar(200) NULL, + permissions varchar(10) NOT NULL, + consumer_key char(64) NOT NULL, + consumer_secret char(43) NOT NULL, + nonces longtext NULL, + truncated_key char(7) NOT NULL, + last_access datetime NULL default null, + PRIMARY KEY (key_id), + KEY consumer_key (consumer_key), + KEY consumer_secret (consumer_secret) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_attribute_taxonomies ( + attribute_id BIGINT UNSIGNED NOT NULL auto_increment, + attribute_name varchar(200) NOT NULL, + attribute_label varchar(200) NULL, + attribute_type varchar(20) NOT NULL, + attribute_orderby varchar(20) NOT NULL, + attribute_public int(1) NOT NULL DEFAULT 1, + PRIMARY KEY (attribute_id), + KEY attribute_name (attribute_name(20)) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions ( + permission_id BIGINT UNSIGNED NOT NULL auto_increment, + download_id varchar(36) NOT NULL, + product_id BIGINT UNSIGNED NOT NULL, + order_id BIGINT UNSIGNED NOT NULL DEFAULT 0, + order_key varchar(200) NOT NULL, + user_email varchar(200) NOT NULL, + user_id BIGINT UNSIGNED NULL, + downloads_remaining varchar(9) NULL, + access_granted datetime NOT NULL default '0000-00-00 00:00:00', + access_expires datetime NULL default null, + download_count BIGINT UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (permission_id), + KEY download_order_key_product (product_id,order_id,order_key(16),download_id), + KEY download_order_product (download_id,order_id,product_id), + KEY order_id (order_id), + KEY user_order_remaining_expires (user_id,order_id,downloads_remaining,access_expires) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_order_items ( + order_item_id BIGINT UNSIGNED NOT NULL auto_increment, + order_item_name TEXT NOT NULL, + order_item_type varchar(200) NOT NULL DEFAULT '', + order_id BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (order_item_id), + KEY order_id (order_id) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_order_itemmeta ( + meta_id BIGINT UNSIGNED NOT NULL auto_increment, + order_item_id BIGINT UNSIGNED NOT NULL, + meta_key varchar(255) default NULL, + meta_value longtext NULL, + PRIMARY KEY (meta_id), + KEY order_item_id (order_item_id), + KEY meta_key (meta_key(32)) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_tax_rates ( + tax_rate_id BIGINT UNSIGNED NOT NULL auto_increment, + tax_rate_country varchar(2) NOT NULL DEFAULT '', + tax_rate_state varchar(200) NOT NULL DEFAULT '', + tax_rate varchar(8) NOT NULL DEFAULT '', + tax_rate_name varchar(200) NOT NULL DEFAULT '', + tax_rate_priority BIGINT UNSIGNED NOT NULL, + tax_rate_compound int(1) NOT NULL DEFAULT 0, + tax_rate_shipping int(1) NOT NULL DEFAULT 1, + tax_rate_order BIGINT UNSIGNED NOT NULL, + tax_rate_class varchar(200) NOT NULL DEFAULT '', + PRIMARY KEY (tax_rate_id), + KEY tax_rate_country (tax_rate_country), + KEY tax_rate_state (tax_rate_state(2)), + KEY tax_rate_class (tax_rate_class(10)), + KEY tax_rate_priority (tax_rate_priority) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations ( + location_id BIGINT UNSIGNED NOT NULL auto_increment, + location_code varchar(200) NOT NULL, + tax_rate_id BIGINT UNSIGNED NOT NULL, + location_type varchar(40) NOT NULL, + PRIMARY KEY (location_id), + KEY tax_rate_id (tax_rate_id), + KEY location_type_code (location_type(10),location_code(20)) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_shipping_zones ( + zone_id BIGINT UNSIGNED NOT NULL auto_increment, + zone_name varchar(200) NOT NULL, + zone_order BIGINT UNSIGNED NOT NULL, + PRIMARY KEY (zone_id) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_shipping_zone_locations ( + location_id BIGINT UNSIGNED NOT NULL auto_increment, + zone_id BIGINT UNSIGNED NOT NULL, + location_code varchar(200) NOT NULL, + location_type varchar(40) NOT NULL, + PRIMARY KEY (location_id), + KEY location_id (location_id), + KEY location_type_code (location_type(10),location_code(20)) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_shipping_zone_methods ( + zone_id BIGINT UNSIGNED NOT NULL, + instance_id BIGINT UNSIGNED NOT NULL auto_increment, + method_id varchar(200) NOT NULL, + method_order BIGINT UNSIGNED NOT NULL, + is_enabled tinyint(1) NOT NULL DEFAULT '1', + PRIMARY KEY (instance_id) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_payment_tokens ( + token_id BIGINT UNSIGNED NOT NULL auto_increment, + gateway_id varchar(200) NOT NULL, + token text NOT NULL, + user_id BIGINT UNSIGNED NOT NULL DEFAULT '0', + type varchar(200) NOT NULL, + is_default tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (token_id), + KEY user_id (user_id) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_payment_tokenmeta ( + meta_id BIGINT UNSIGNED NOT NULL auto_increment, + payment_token_id BIGINT UNSIGNED NOT NULL, + meta_key varchar(255) NULL, + meta_value longtext NULL, + PRIMARY KEY (meta_id), + KEY payment_token_id (payment_token_id), + KEY meta_key (meta_key(32)) +) $collate; +CREATE TABLE {$wpdb->prefix}woocommerce_log ( + log_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + timestamp datetime NOT NULL, + level smallint(4) NOT NULL, + source varchar(200) NOT NULL, + message longtext NOT NULL, + context longtext NULL, + PRIMARY KEY (log_id), + KEY level (level) +) $collate; +CREATE TABLE {$wpdb->prefix}wc_webhooks ( + webhook_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + status varchar(200) NOT NULL, + name text NOT NULL, + user_id BIGINT UNSIGNED NOT NULL, + delivery_url text NOT NULL, + secret text NOT NULL, + topic varchar(200) NOT NULL, + date_created datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + date_created_gmt datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + date_modified datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + date_modified_gmt datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + api_version smallint(4) NOT NULL, + failure_count smallint(10) NOT NULL DEFAULT '0', + pending_delivery tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (webhook_id), + KEY user_id (user_id) +) $collate; +CREATE TABLE {$wpdb->prefix}wc_download_log ( + download_log_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + timestamp datetime NOT NULL, + permission_id BIGINT UNSIGNED NOT NULL, + user_id BIGINT UNSIGNED NULL, + user_ip_address VARCHAR(100) NULL DEFAULT '', + PRIMARY KEY (download_log_id), + KEY permission_id (permission_id), + KEY timestamp (timestamp) +) $collate; +CREATE TABLE {$wpdb->prefix}wc_product_meta_lookup ( + `product_id` bigint(20) NOT NULL, + `sku` varchar(100) NULL default '', + `virtual` tinyint(1) NULL default 0, + `downloadable` tinyint(1) NULL default 0, + `min_price` decimal(19,4) NULL default NULL, + `max_price` decimal(19,4) NULL default NULL, + `onsale` tinyint(1) NULL default 0, + `stock_quantity` double NULL default NULL, + `stock_status` varchar(100) NULL default 'instock', + `rating_count` bigint(20) NULL default 0, + `average_rating` decimal(3,2) NULL default 0.00, + `total_sales` bigint(20) NULL default 0, + `tax_status` varchar(100) NULL default 'taxable', + `tax_class` varchar(100) NULL default '', + PRIMARY KEY (`product_id`), + KEY `virtual` (`virtual`), + KEY `downloadable` (`downloadable`), + KEY `stock_status` (`stock_status`), + KEY `stock_quantity` (`stock_quantity`), + KEY `onsale` (`onsale`), + KEY min_max_price (`min_price`, `max_price`) +) $collate; +CREATE TABLE {$wpdb->prefix}wc_tax_rate_classes ( + tax_rate_class_id BIGINT UNSIGNED NOT NULL auto_increment, + name varchar(200) NOT NULL DEFAULT '', + slug varchar(200) NOT NULL DEFAULT '', + PRIMARY KEY (tax_rate_class_id), + UNIQUE KEY slug (slug($max_index_length)) +) $collate; +CREATE TABLE {$wpdb->prefix}wc_reserved_stock ( + `order_id` bigint(20) NOT NULL, + `product_id` bigint(20) NOT NULL, + `stock_quantity` double NOT NULL DEFAULT 0, + `timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`order_id`, `product_id`) +) $collate; + "; + + return $tables; + } + + /** + * Return a list of WooCommerce tables. Used to make sure all WC tables are dropped when uninstalling the plugin + * in a single site or multi site environment. + * + * @return array WC tables. + */ + public static function get_tables() { + global $wpdb; + + $tables = array( + "{$wpdb->prefix}wc_download_log", + "{$wpdb->prefix}wc_product_meta_lookup", + "{$wpdb->prefix}wc_tax_rate_classes", + "{$wpdb->prefix}wc_webhooks", + "{$wpdb->prefix}woocommerce_api_keys", + "{$wpdb->prefix}woocommerce_attribute_taxonomies", + "{$wpdb->prefix}woocommerce_downloadable_product_permissions", + "{$wpdb->prefix}woocommerce_log", + "{$wpdb->prefix}woocommerce_order_itemmeta", + "{$wpdb->prefix}woocommerce_order_items", + "{$wpdb->prefix}woocommerce_payment_tokenmeta", + "{$wpdb->prefix}woocommerce_payment_tokens", + "{$wpdb->prefix}woocommerce_sessions", + "{$wpdb->prefix}woocommerce_shipping_zone_locations", + "{$wpdb->prefix}woocommerce_shipping_zone_methods", + "{$wpdb->prefix}woocommerce_shipping_zones", + "{$wpdb->prefix}woocommerce_tax_rate_locations", + "{$wpdb->prefix}woocommerce_tax_rates", + "{$wpdb->prefix}wc_reserved_stock", + ); + + /** + * Filter the list of known WooCommerce tables. + * + * If WooCommerce plugins need to add new tables, they can inject them here. + * + * @param array $tables An array of WooCommerce-specific database table names. + */ + $tables = apply_filters( 'woocommerce_install_get_tables', $tables ); + + return $tables; + } + + /** + * Drop WooCommerce tables. + * + * @return void + */ + public static function drop_tables() { + global $wpdb; + + $tables = self::get_tables(); + + foreach ( $tables as $table ) { + $wpdb->query( "DROP TABLE IF EXISTS {$table}" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + } + + /** + * Uninstall tables when MU blog is deleted. + * + * @param array $tables List of tables that will be deleted by WP. + * + * @return string[] + */ + public static function wpmu_drop_tables( $tables ) { + return array_merge( $tables, self::get_tables() ); + } + + /** + * Create roles and capabilities. + */ + public static function create_roles() { + global $wp_roles; + + if ( ! class_exists( 'WP_Roles' ) ) { + return; + } + + if ( ! isset( $wp_roles ) ) { + $wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine + } + + // Dummy gettext calls to get strings in the catalog. + /* translators: user role */ + _x( 'Customer', 'User role', 'woocommerce' ); + /* translators: user role */ + _x( 'Shop manager', 'User role', 'woocommerce' ); + + // Customer role. + add_role( + 'customer', + 'Customer', + array( + 'read' => true, + ) + ); + + // Shop manager role. + add_role( + 'shop_manager', + 'Shop manager', + array( + 'level_9' => true, + 'level_8' => true, + 'level_7' => true, + 'level_6' => true, + 'level_5' => true, + 'level_4' => true, + 'level_3' => true, + 'level_2' => true, + 'level_1' => true, + 'level_0' => true, + 'read' => true, + 'read_private_pages' => true, + 'read_private_posts' => true, + 'edit_posts' => true, + 'edit_pages' => true, + 'edit_published_posts' => true, + 'edit_published_pages' => true, + 'edit_private_pages' => true, + 'edit_private_posts' => true, + 'edit_others_posts' => true, + 'edit_others_pages' => true, + 'publish_posts' => true, + 'publish_pages' => true, + 'delete_posts' => true, + 'delete_pages' => true, + 'delete_private_pages' => true, + 'delete_private_posts' => true, + 'delete_published_pages' => true, + 'delete_published_posts' => true, + 'delete_others_posts' => true, + 'delete_others_pages' => true, + 'manage_categories' => true, + 'manage_links' => true, + 'moderate_comments' => true, + 'upload_files' => true, + 'export' => true, + 'import' => true, + 'list_users' => true, + 'edit_theme_options' => true, + ) + ); + + $capabilities = self::get_core_capabilities(); + + foreach ( $capabilities as $cap_group ) { + foreach ( $cap_group as $cap ) { + $wp_roles->add_cap( 'shop_manager', $cap ); + $wp_roles->add_cap( 'administrator', $cap ); + } + } + } + + /** + * Get capabilities for WooCommerce - these are assigned to admin/shop manager during installation or reset. + * + * @return array + */ + public static function get_core_capabilities() { + $capabilities = array(); + + $capabilities['core'] = array( + 'manage_woocommerce', + 'view_woocommerce_reports', + ); + + $capability_types = array( 'product', 'shop_order', 'shop_coupon' ); + + foreach ( $capability_types as $capability_type ) { + + $capabilities[ $capability_type ] = array( + // Post type. + "edit_{$capability_type}", + "read_{$capability_type}", + "delete_{$capability_type}", + "edit_{$capability_type}s", + "edit_others_{$capability_type}s", + "publish_{$capability_type}s", + "read_private_{$capability_type}s", + "delete_{$capability_type}s", + "delete_private_{$capability_type}s", + "delete_published_{$capability_type}s", + "delete_others_{$capability_type}s", + "edit_private_{$capability_type}s", + "edit_published_{$capability_type}s", + + // Terms. + "manage_{$capability_type}_terms", + "edit_{$capability_type}_terms", + "delete_{$capability_type}_terms", + "assign_{$capability_type}_terms", + ); + } + + return $capabilities; + } + + /** + * Remove WooCommerce roles. + */ + public static function remove_roles() { + global $wp_roles; + + if ( ! class_exists( 'WP_Roles' ) ) { + return; + } + + if ( ! isset( $wp_roles ) ) { + $wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine + } + + $capabilities = self::get_core_capabilities(); + + foreach ( $capabilities as $cap_group ) { + foreach ( $cap_group as $cap ) { + $wp_roles->remove_cap( 'shop_manager', $cap ); + $wp_roles->remove_cap( 'administrator', $cap ); + } + } + + remove_role( 'customer' ); + remove_role( 'shop_manager' ); + } + + /** + * Create files/directories. + */ + private static function create_files() { + // Bypass if filesystem is read-only and/or non-standard upload system is used. + if ( apply_filters( 'woocommerce_install_skip_create_files', false ) ) { + return; + } + + // Install files and folders for uploading files and prevent hotlinking. + $upload_dir = wp_get_upload_dir(); + $download_method = get_option( 'woocommerce_file_download_method', 'force' ); + + $files = array( + array( + 'base' => $upload_dir['basedir'] . '/woocommerce_uploads', + 'file' => 'index.html', + 'content' => '', + ), + array( + 'base' => WC_LOG_DIR, + 'file' => '.htaccess', + 'content' => 'deny from all', + ), + array( + 'base' => WC_LOG_DIR, + 'file' => 'index.html', + 'content' => '', + ), + array( + 'base' => $upload_dir['basedir'] . '/woocommerce_uploads', + 'file' => '.htaccess', + 'content' => 'redirect' === $download_method ? 'Options -Indexes' : 'deny from all', + ), + ); + + foreach ( $files as $file ) { + if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) { + $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'wb' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen + if ( $file_handle ) { + fwrite( $file_handle, $file['content'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite + fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose + } + } + } + + // Create attachment for placeholders. + self::create_placeholder_image(); + } + + /** + * Create a placeholder image in the media library. + * + * @since 3.5.0 + */ + private static function create_placeholder_image() { + $placeholder_image = get_option( 'woocommerce_placeholder_image', 0 ); + + // Validate current setting if set. If set, return. + if ( ! empty( $placeholder_image ) ) { + if ( ! is_numeric( $placeholder_image ) ) { + return; + } elseif ( $placeholder_image && wp_attachment_is_image( $placeholder_image ) ) { + return; + } + } + + $upload_dir = wp_upload_dir(); + $source = WC()->plugin_path() . '/assets/images/placeholder-attachment.png'; + $filename = $upload_dir['basedir'] . '/woocommerce-placeholder.png'; + + if ( ! file_exists( $filename ) ) { + copy( $source, $filename ); // @codingStandardsIgnoreLine. + } + + if ( ! file_exists( $filename ) ) { + update_option( 'woocommerce_placeholder_image', 0 ); + return; + } + + $filetype = wp_check_filetype( basename( $filename ), null ); + $attachment = array( + 'guid' => $upload_dir['url'] . '/' . basename( $filename ), + 'post_mime_type' => $filetype['type'], + 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ), + 'post_content' => '', + 'post_status' => 'inherit', + ); + $attach_id = wp_insert_attachment( $attachment, $filename ); + + update_option( 'woocommerce_placeholder_image', $attach_id ); + + // Make sure that this file is included, as wp_generate_attachment_metadata() depends on it. + require_once ABSPATH . 'wp-admin/includes/image.php'; + + // Generate the metadata for the attachment, and update the database record. + $attach_data = wp_generate_attachment_metadata( $attach_id, $filename ); + wp_update_attachment_metadata( $attach_id, $attach_data ); + } + + /** + * Show action links on the plugin screen. + * + * @param mixed $links Plugin Action links. + * + * @return array + */ + public static function plugin_action_links( $links ) { + $action_links = array( + 'settings' => '' . esc_html__( 'Settings', 'woocommerce' ) . '', + ); + + return array_merge( $action_links, $links ); + } + + /** + * Show row meta on the plugin screen. + * + * @param mixed $links Plugin Row Meta. + * @param mixed $file Plugin Base file. + * + * @return array + */ + public static function plugin_row_meta( $links, $file ) { + if ( WC_PLUGIN_BASENAME !== $file ) { + return $links; + } + + $row_meta = array( + 'docs' => '' . esc_html__( 'Docs', 'woocommerce' ) . '', + 'apidocs' => '' . esc_html__( 'API docs', 'woocommerce' ) . '', + 'support' => '' . esc_html__( 'Community support', 'woocommerce' ) . '', + ); + + if ( WCConnectionHelper::is_connected() ) { + $row_meta['premium_support'] = '' . esc_html__( 'Premium support', 'woocommerce' ) . ''; + } + + return array_merge( $links, $row_meta ); + } + + /** + * Get slug from path and associate it with the path. + * + * @param array $plugins Associative array of plugin files to paths. + * @param string $key Plugin relative path. Example: woocommerce/woocommerce.php. + */ + private static function associate_plugin_file( $plugins, $key ) { + $path = explode( '/', $key ); + $filename = end( $path ); + $plugins[ $filename ] = $key; + return $plugins; + } + + /** + * Install a plugin from .org in the background via a cron job (used by + * installer - opt in). + * + * @param string $plugin_to_install_id Plugin ID. + * @param array $plugin_to_install Plugin information. + * + * @throws Exception If unable to proceed with plugin installation. + * @since 2.6.0 + */ + public static function background_installer( $plugin_to_install_id, $plugin_to_install ) { + // Explicitly clear the event. + $args = func_get_args(); + + if ( ! empty( $plugin_to_install['repo-slug'] ) ) { + require_once ABSPATH . 'wp-admin/includes/file.php'; + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + WP_Filesystem(); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new WP_Upgrader( $skin ); + $installed_plugins = array_reduce( array_keys( get_plugins() ), array( __CLASS__, 'associate_plugin_file' ) ); + if ( empty( $installed_plugins ) ) { + $installed_plugins = array(); + } + $plugin_slug = $plugin_to_install['repo-slug']; + $plugin_file = isset( $plugin_to_install['file'] ) ? $plugin_to_install['file'] : $plugin_slug . '.php'; + $installed = false; + $activate = false; + + // See if the plugin is installed already. + if ( isset( $installed_plugins[ $plugin_file ] ) ) { + $installed = true; + $activate = ! is_plugin_active( $installed_plugins[ $plugin_file ] ); + } + + // Install this thing! + if ( ! $installed ) { + // Suppress feedback. + ob_start(); + + try { + $plugin_information = plugins_api( + 'plugin_information', + array( + 'slug' => $plugin_slug, + 'fields' => array( + 'short_description' => false, + 'sections' => false, + 'requires' => false, + 'rating' => false, + 'ratings' => false, + 'downloaded' => false, + 'last_updated' => false, + 'added' => false, + 'tags' => false, + 'homepage' => false, + 'donate_link' => false, + 'author_profile' => false, + 'author' => false, + ), + ) + ); + + if ( is_wp_error( $plugin_information ) ) { + throw new Exception( $plugin_information->get_error_message() ); + } + + $package = $plugin_information->download_link; + $download = $upgrader->download_package( $package ); + + if ( is_wp_error( $download ) ) { + throw new Exception( $download->get_error_message() ); + } + + $working_dir = $upgrader->unpack_package( $download, true ); + + if ( is_wp_error( $working_dir ) ) { + throw new Exception( $working_dir->get_error_message() ); + } + + $result = $upgrader->install_package( + array( + 'source' => $working_dir, + 'destination' => WP_PLUGIN_DIR, + 'clear_destination' => false, + 'abort_if_destination_exists' => false, + 'clear_working' => true, + 'hook_extra' => array( + 'type' => 'plugin', + 'action' => 'install', + ), + ) + ); + + if ( is_wp_error( $result ) ) { + throw new Exception( $result->get_error_message() ); + } + + $activate = true; + + } catch ( Exception $e ) { + WC_Admin_Notices::add_custom_notice( + $plugin_to_install_id . '_install_error', + sprintf( + // translators: 1: plugin name, 2: error message, 3: URL to install plugin manually. + __( '%1$s could not be installed (%2$s). Please install it manually by clicking here.', 'woocommerce' ), + $plugin_to_install['name'], + $e->getMessage(), + esc_url( admin_url( 'index.php?wc-install-plugin-redirect=' . $plugin_slug ) ) + ) + ); + } + + // Discard feedback. + ob_end_clean(); + } + + wp_clean_plugins_cache(); + + // Activate this thing. + if ( $activate ) { + try { + add_action( 'add_option_mailchimp_woocommerce_plugin_do_activation_redirect', array( __CLASS__, 'remove_mailchimps_redirect' ), 10, 2 ); + $result = activate_plugin( $installed ? $installed_plugins[ $plugin_file ] : $plugin_slug . '/' . $plugin_file ); + + if ( is_wp_error( $result ) ) { + throw new Exception( $result->get_error_message() ); + } + } catch ( Exception $e ) { + WC_Admin_Notices::add_custom_notice( + $plugin_to_install_id . '_install_error', + sprintf( + // translators: 1: plugin name, 2: URL to WP plugin page. + __( '%1$s was installed but could not be activated. Please activate it manually by clicking here.', 'woocommerce' ), + $plugin_to_install['name'], + admin_url( 'plugins.php' ) + ) + ); + } + } + } + } + + /** + * Removes redirect added during MailChimp plugin's activation. + * + * @param string $option Option name. + * @param string $value Option value. + */ + public static function remove_mailchimps_redirect( $option, $value ) { + // Remove this action to prevent infinite looping. + remove_action( 'add_option_mailchimp_woocommerce_plugin_do_activation_redirect', array( __CLASS__, 'remove_mailchimps_redirect' ) ); + + // Update redirect back to false. + update_option( 'mailchimp_woocommerce_plugin_do_activation_redirect', false ); + } + + /** + * Install a theme from .org in the background via a cron job (used by installer - opt in). + * + * @param string $theme_slug Theme slug. + * + * @throws Exception If unable to proceed with theme installation. + * @since 3.1.0 + */ + public static function theme_background_installer( $theme_slug ) { + // Explicitly clear the event. + $args = func_get_args(); + + if ( ! empty( $theme_slug ) ) { + // Suppress feedback. + ob_start(); + + try { + $theme = wp_get_theme( $theme_slug ); + + if ( ! $theme->exists() ) { + require_once ABSPATH . 'wp-admin/includes/file.php'; + include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + include_once ABSPATH . 'wp-admin/includes/theme.php'; + + WP_Filesystem(); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new Theme_Upgrader( $skin ); + $api = themes_api( + 'theme_information', + array( + 'slug' => $theme_slug, + 'fields' => array( 'sections' => false ), + ) + ); + $result = $upgrader->install( $api->download_link ); + + if ( is_wp_error( $result ) ) { + throw new Exception( $result->get_error_message() ); + } elseif ( is_wp_error( $skin->result ) ) { + throw new Exception( $skin->result->get_error_message() ); + } elseif ( is_null( $result ) ) { + throw new Exception( 'Unable to connect to the filesystem. Please confirm your credentials.' ); + } + } + + switch_theme( $theme_slug ); + } catch ( Exception $e ) { + WC_Admin_Notices::add_custom_notice( + $theme_slug . '_install_error', + sprintf( + // translators: 1: theme slug, 2: error message, 3: URL to install theme manually. + __( '%1$s could not be installed (%2$s). Please install it manually by clicking here.', 'woocommerce' ), + $theme_slug, + $e->getMessage(), + esc_url( admin_url( 'update.php?action=install-theme&theme=' . $theme_slug . '&_wpnonce=' . wp_create_nonce( 'install-theme_' . $theme_slug ) ) ) + ) + ); + } + + // Discard feedback. + ob_end_clean(); + } + } +} + +WC_Install::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-integrations.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-integrations.php new file mode 100644 index 0000000..f29360b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-integrations.php @@ -0,0 +1,70 @@ +integrations[ $load_integration->id ] = $load_integration; + } + } + + /** + * Return loaded integrations. + * + * @return array + */ + public function get_integrations() { + return $this->integrations; + } + + /** + * Return a desired integration. + * + * @since 3.9.0 + * @param string $id The id of the integration to get. + * @return mixed|null The integration if one is found, otherwise null. + */ + public function get_integration( $id ) { + if ( isset( $this->integrations[ $id ] ) ) { + return $this->integrations[ $id ]; + } + + return null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-log-levels.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-log-levels.php new file mode 100644 index 0000000..f577b55 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-log-levels.php @@ -0,0 +1,108 @@ + 800, + self::ALERT => 700, + self::CRITICAL => 600, + self::ERROR => 500, + self::WARNING => 400, + self::NOTICE => 300, + self::INFO => 200, + self::DEBUG => 100, + ); + + /** + * Severity integers mapped to level strings. + * + * This is the inverse of $level_severity. + * + * @var array + */ + protected static $severity_to_level = array( + 800 => self::EMERGENCY, + 700 => self::ALERT, + 600 => self::CRITICAL, + 500 => self::ERROR, + 400 => self::WARNING, + 300 => self::NOTICE, + 200 => self::INFO, + 100 => self::DEBUG, + ); + + + /** + * Validate a level string. + * + * @param string $level Log level. + * @return bool True if $level is a valid level. + */ + public static function is_valid_level( $level ) { + return array_key_exists( strtolower( $level ), self::$level_to_severity ); + } + + /** + * Translate level string to integer. + * + * @param string $level Log level, options: emergency|alert|critical|error|warning|notice|info|debug. + * @return int 100 (debug) - 800 (emergency) or 0 if not recognized + */ + public static function get_level_severity( $level ) { + return self::is_valid_level( $level ) ? self::$level_to_severity[ strtolower( $level ) ] : 0; + } + + /** + * Translate severity integer to level string. + * + * @param int $severity Severity level. + * @return bool|string False if not recognized. Otherwise string representation of level. + */ + public static function get_severity_level( $severity ) { + if ( ! array_key_exists( $severity, self::$severity_to_level ) ) { + return false; + } + return self::$severity_to_level[ $severity ]; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-logger.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-logger.php new file mode 100644 index 0000000..040dd58 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-logger.php @@ -0,0 +1,303 @@ +' . esc_html( is_object( $handler ) ? get_class( $handler ) : $handler ) . '', + 'WC_Log_Handler_Interface' + ), + '3.0' + ); + } + } + } + + // Support the constant as long as a valid log level has been set for it. + if ( null === $threshold ) { + $threshold = Constants::get_constant( 'WC_LOG_THRESHOLD' ); + if ( null !== $threshold && ! WC_Log_Levels::is_valid_level( $threshold ) ) { + $threshold = null; + } + } + + if ( null !== $threshold ) { + $threshold = WC_Log_Levels::get_level_severity( $threshold ); + } + + $this->handlers = $register_handlers; + $this->threshold = $threshold; + } + + /** + * Determine whether to handle or ignore log. + * + * @param string $level emergency|alert|critical|error|warning|notice|info|debug. + * @return bool True if the log should be handled. + */ + protected function should_handle( $level ) { + if ( null === $this->threshold ) { + return true; + } + return $this->threshold <= WC_Log_Levels::get_level_severity( $level ); + } + + /** + * Add a log entry. + * + * This is not the preferred method for adding log messages. Please use log() or any one of + * the level methods (debug(), info(), etc.). This method may be deprecated in the future. + * + * @param string $handle File handle. + * @param string $message Message to log. + * @param string $level Logging level. + * @return bool + */ + public function add( $handle, $message, $level = WC_Log_Levels::NOTICE ) { + $message = apply_filters( 'woocommerce_logger_add_message', $message, $handle ); + $this->log( + $level, + $message, + array( + 'source' => $handle, + '_legacy' => true, + ) + ); + wc_do_deprecated_action( 'woocommerce_log_add', array( $handle, $message ), '3.0', 'This action has been deprecated with no alternative.' ); + return true; + } + + /** + * Add a log entry. + * + * @param string $level One of the following: + * 'emergency': System is unusable. + * 'alert': Action must be taken immediately. + * 'critical': Critical conditions. + * 'error': Error conditions. + * 'warning': Warning conditions. + * 'notice': Normal but significant condition. + * 'info': Informational messages. + * 'debug': Debug-level messages. + * @param string $message Log message. + * @param array $context Optional. Additional information for log handlers. + */ + public function log( $level, $message, $context = array() ) { + if ( ! WC_Log_Levels::is_valid_level( $level ) ) { + /* translators: 1: WC_Logger::log 2: level */ + wc_doing_it_wrong( __METHOD__, sprintf( __( '%1$s was called with an invalid level "%2$s".', 'woocommerce' ), 'WC_Logger::log', $level ), '3.0' ); + } + + if ( $this->should_handle( $level ) ) { + $timestamp = current_time( 'timestamp', 1 ); + $message = apply_filters( 'woocommerce_logger_log_message', $message, $level, $context ); + + foreach ( $this->handlers as $handler ) { + $handler->handle( $timestamp, $level, $message, $context ); + } + } + } + + /** + * Adds an emergency level message. + * + * System is unusable. + * + * @see WC_Logger::log + * + * @param string $message Message to log. + * @param array $context Log context. + */ + public function emergency( $message, $context = array() ) { + $this->log( WC_Log_Levels::EMERGENCY, $message, $context ); + } + + /** + * Adds an alert level message. + * + * Action must be taken immediately. + * Example: Entire website down, database unavailable, etc. + * + * @see WC_Logger::log + * + * @param string $message Message to log. + * @param array $context Log context. + */ + public function alert( $message, $context = array() ) { + $this->log( WC_Log_Levels::ALERT, $message, $context ); + } + + /** + * Adds a critical level message. + * + * Critical conditions. + * Example: Application component unavailable, unexpected exception. + * + * @see WC_Logger::log + * + * @param string $message Message to log. + * @param array $context Log context. + */ + public function critical( $message, $context = array() ) { + $this->log( WC_Log_Levels::CRITICAL, $message, $context ); + } + + /** + * Adds an error level message. + * + * Runtime errors that do not require immediate action but should typically be logged + * and monitored. + * + * @see WC_Logger::log + * + * @param string $message Message to log. + * @param array $context Log context. + */ + public function error( $message, $context = array() ) { + $this->log( WC_Log_Levels::ERROR, $message, $context ); + } + + /** + * Adds a warning level message. + * + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things that are not + * necessarily wrong. + * + * @see WC_Logger::log + * + * @param string $message Message to log. + * @param array $context Log context. + */ + public function warning( $message, $context = array() ) { + $this->log( WC_Log_Levels::WARNING, $message, $context ); + } + + /** + * Adds a notice level message. + * + * Normal but significant events. + * + * @see WC_Logger::log + * + * @param string $message Message to log. + * @param array $context Log context. + */ + public function notice( $message, $context = array() ) { + $this->log( WC_Log_Levels::NOTICE, $message, $context ); + } + + /** + * Adds a info level message. + * + * Interesting events. + * Example: User logs in, SQL logs. + * + * @see WC_Logger::log + * + * @param string $message Message to log. + * @param array $context Log context. + */ + public function info( $message, $context = array() ) { + $this->log( WC_Log_Levels::INFO, $message, $context ); + } + + /** + * Adds a debug level message. + * + * Detailed debug information. + * + * @see WC_Logger::log + * + * @param string $message Message to log. + * @param array $context Log context. + */ + public function debug( $message, $context = array() ) { + $this->log( WC_Log_Levels::DEBUG, $message, $context ); + } + + /** + * Clear entries for a chosen file/source. + * + * @param string $source Source/handle to clear. + * @return bool + */ + public function clear( $source = '' ) { + if ( ! $source ) { + return false; + } + foreach ( $this->handlers as $handler ) { + if ( is_callable( array( $handler, 'clear' ) ) ) { + $handler->clear( $source ); + } + } + return true; + } + + /** + * Clear all logs older than a defined number of days. Defaults to 30 days. + * + * @since 3.4.0 + */ + public function clear_expired_logs() { + $days = absint( apply_filters( 'woocommerce_logger_days_to_retain_logs', 30 ) ); + $timestamp = strtotime( "-{$days} days" ); + + foreach ( $this->handlers as $handler ) { + if ( is_callable( array( $handler, 'delete_logs_before_timestamp' ) ) ) { + $handler->delete_logs_before_timestamp( $timestamp ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-meta-data.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-meta-data.php new file mode 100644 index 0000000..c21d98d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-meta-data.php @@ -0,0 +1,119 @@ +current_data = $meta; + $this->apply_changes(); + } + + /** + * When converted to JSON. + * + * @return object|array + */ + public function jsonSerialize() { + return $this->get_data(); + } + + /** + * Merge changes with data and clear. + */ + public function apply_changes() { + $this->data = $this->current_data; + } + + /** + * Creates or updates a property in the metadata object. + * + * @param string $key Key to set. + * @param mixed $value Value to set. + */ + public function __set( $key, $value ) { + $this->current_data[ $key ] = $value; + } + + /** + * Checks if a given key exists in our data. This is called internally + * by `empty` and `isset`. + * + * @param string $key Key to check if set. + * + * @return bool + */ + public function __isset( $key ) { + return array_key_exists( $key, $this->current_data ); + } + + /** + * Returns the value of any property. + * + * @param string $key Key to get. + * @return mixed Property value or NULL if it does not exists + */ + public function __get( $key ) { + if ( array_key_exists( $key, $this->current_data ) ) { + return $this->current_data[ $key ]; + } + return null; + } + + /** + * Return data changes only. + * + * @return array + */ + public function get_changes() { + $changes = array(); + foreach ( $this->current_data as $id => $value ) { + if ( ! array_key_exists( $id, $this->data ) || $value !== $this->data[ $id ] ) { + $changes[ $id ] = $value; + } + } + return $changes; + } + + /** + * Return all data as an array. + * + * @return array + */ + public function get_data() { + return $this->data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-factory.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-factory.php new file mode 100644 index 0000000..a307787 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-factory.php @@ -0,0 +1,131 @@ +get_order_type( $order_id ); + $order_type_data = wc_get_order_type( $order_type ); + if ( $order_type_data ) { + $classname = $order_type_data['class_name']; + } else { + $classname = false; + } + + // Filter classname so that the class can be overridden if extended. + $classname = apply_filters( 'woocommerce_order_class', $classname, $order_type, $order_id ); + + if ( ! class_exists( $classname ) ) { + return false; + } + + try { + return new $classname( $order_id ); + } catch ( Exception $e ) { + wc_caught_exception( $e, __FUNCTION__, array( $order_id ) ); + return false; + } + } + + /** + * Get order item. + * + * @param int $item_id Order item ID to get. + * @return WC_Order_Item|false if not found + */ + public static function get_order_item( $item_id = 0 ) { + if ( is_numeric( $item_id ) ) { + $item_type = WC_Data_Store::load( 'order-item' )->get_order_item_type( $item_id ); + $id = $item_id; + } elseif ( $item_id instanceof WC_Order_Item ) { + $item_type = $item_id->get_type(); + $id = $item_id->get_id(); + } elseif ( is_object( $item_id ) && ! empty( $item_id->order_item_type ) ) { + $id = $item_id->order_item_id; + $item_type = $item_id->order_item_type; + } else { + $item_type = false; + $id = false; + } + + if ( $id && $item_type ) { + $classname = false; + switch ( $item_type ) { + case 'line_item': + case 'product': + $classname = 'WC_Order_Item_Product'; + break; + case 'coupon': + $classname = 'WC_Order_Item_Coupon'; + break; + case 'fee': + $classname = 'WC_Order_Item_Fee'; + break; + case 'shipping': + $classname = 'WC_Order_Item_Shipping'; + break; + case 'tax': + $classname = 'WC_Order_Item_Tax'; + break; + } + + $classname = apply_filters( 'woocommerce_get_order_item_classname', $classname, $item_type, $id ); + + if ( $classname && class_exists( $classname ) ) { + try { + return new $classname( $id ); + } catch ( Exception $e ) { + return false; + } + } + } + return false; + } + + /** + * Get the order ID depending on what was passed. + * + * @since 3.0.0 + * @param mixed $order Order data to convert to an ID. + * @return int|bool false on failure + */ + public static function get_order_id( $order ) { + global $post; + + if ( false === $order && is_a( $post, 'WP_Post' ) && 'shop_order' === get_post_type( $post ) ) { + return absint( $post->ID ); + } elseif ( is_numeric( $order ) ) { + return $order; + } elseif ( $order instanceof WC_Abstract_Order ) { + return $order->get_id(); + } elseif ( ! empty( $order->ID ) ) { + return $order->ID; + } else { + return false; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-coupon.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-coupon.php new file mode 100644 index 0000000..1a8aa50 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-coupon.php @@ -0,0 +1,182 @@ + '', + 'discount' => 0, + 'discount_tax' => 0, + ); + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set order item name. + * + * @param string $value Coupon code. + */ + public function set_name( $value ) { + return $this->set_code( $value ); + } + + /** + * Set code. + * + * @param string $value Coupon code. + */ + public function set_code( $value ) { + $this->set_prop( 'code', wc_format_coupon_code( $value ) ); + } + + /** + * Set discount amount. + * + * @param string $value Discount. + */ + public function set_discount( $value ) { + $this->set_prop( 'discount', wc_format_decimal( $value ) ); + } + + /** + * Set discounted tax amount. + * + * @param string $value Discount tax. + */ + public function set_discount_tax( $value ) { + $this->set_prop( 'discount_tax', wc_format_decimal( $value ) ); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item type. + * + * @return string + */ + public function get_type() { + return 'coupon'; + } + + /** + * Get order item name. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_name( $context = 'view' ) { + return $this->get_code( $context ); + } + + /** + * Get coupon code. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_code( $context = 'view' ) { + return $this->get_prop( 'code', $context ); + } + + /** + * Get discount amount. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_discount( $context = 'view' ) { + return $this->get_prop( 'discount', $context ); + } + + /** + * Get discounted tax amount. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * + * @return string + */ + public function get_discount_tax( $context = 'view' ) { + return $this->get_prop( 'discount_tax', $context ); + } + + /* + |-------------------------------------------------------------------------- + | Array Access Methods + |-------------------------------------------------------------------------- + | + | For backwards compatibility with legacy arrays. + | + */ + + /** + * OffsetGet for ArrayAccess/Backwards compatibility. + * + * @deprecated 4.4.0 + * @param string $offset Offset. + * @return mixed + */ + public function offsetGet( $offset ) { + wc_deprecated_function( 'WC_Order_Item_Coupon::offsetGet', '4.4.0', '' ); + if ( 'discount_amount' === $offset ) { + $offset = 'discount'; + } elseif ( 'discount_amount_tax' === $offset ) { + $offset = 'discount_tax'; + } + return parent::offsetGet( $offset ); + } + + /** + * OffsetSet for ArrayAccess/Backwards compatibility. + * + * @deprecated 4.4.0 + * @param string $offset Offset. + * @param mixed $value Value. + */ + public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Coupon::offsetSet', '4.4.0', '' ); + if ( 'discount_amount' === $offset ) { + $offset = 'discount'; + } elseif ( 'discount_amount_tax' === $offset ) { + $offset = 'discount_tax'; + } + parent::offsetSet( $offset, $value ); + } + + /** + * OffsetExists for ArrayAccess. + * + * @param string $offset Offset. + * @return bool + */ + public function offsetExists( $offset ) { + if ( in_array( $offset, array( 'discount_amount', 'discount_amount_tax' ), true ) ) { + return true; + } + return parent::offsetExists( $offset ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-fee.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-fee.php new file mode 100644 index 0000000..44e1ee1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-fee.php @@ -0,0 +1,338 @@ + '', + 'tax_status' => 'taxable', + 'amount' => '', + 'total' => '', + 'total_tax' => '', + 'taxes' => array( + 'total' => array(), + ), + ); + + /** + * Get item costs grouped by tax class. + * + * @since 3.2.0 + * @param WC_Order $order Order object. + * @return array + */ + protected function get_tax_class_costs( $order ) { + $order_item_tax_classes = $order->get_items_tax_classes(); + $costs = array_fill_keys( $order_item_tax_classes, 0 ); + $costs['non-taxable'] = 0; + + foreach ( $order->get_items( array( 'line_item', 'fee', 'shipping' ) ) as $item ) { + if ( 0 > $item->get_total() ) { + continue; + } + if ( 'taxable' !== $item->get_tax_status() ) { + $costs['non-taxable'] += $item->get_total(); + } elseif ( 'inherit' === $item->get_tax_class() ) { + $inherit_class = reset( $order_item_tax_classes ); + $costs[ $inherit_class ] += $item->get_total(); + } else { + $costs[ $item->get_tax_class() ] += $item->get_total(); + } + } + + return array_filter( $costs ); + } + /** + * Calculate item taxes. + * + * @since 3.2.0 + * @param array $calculate_tax_for Location data to get taxes for. Required. + * @return bool True if taxes were calculated. + */ + public function calculate_taxes( $calculate_tax_for = array() ) { + if ( ! isset( $calculate_tax_for['country'], $calculate_tax_for['state'], $calculate_tax_for['postcode'], $calculate_tax_for['city'] ) ) { + return false; + } + // Use regular calculation unless the fee is negative. + if ( 0 <= $this->get_total() ) { + return parent::calculate_taxes( $calculate_tax_for ); + } + + if ( wc_tax_enabled() && $this->get_order() ) { + // Apportion taxes to order items, shipping, and fees. + $order = $this->get_order(); + $tax_class_costs = $this->get_tax_class_costs( $order ); + $total_costs = array_sum( $tax_class_costs ); + $discount_taxes = array(); + if ( $total_costs ) { + foreach ( $tax_class_costs as $tax_class => $tax_class_cost ) { + if ( 'non-taxable' === $tax_class ) { + continue; + } + $proportion = $tax_class_cost / $total_costs; + $cart_discount_proportion = $this->get_total() * $proportion; + $calculate_tax_for['tax_class'] = $tax_class; + $tax_rates = WC_Tax::find_rates( $calculate_tax_for ); + $discount_taxes = wc_array_merge_recursive_numeric( $discount_taxes, WC_Tax::calc_tax( $cart_discount_proportion, $tax_rates ) ); + } + } + $this->set_taxes( array( 'total' => $discount_taxes ) ); + } else { + $this->set_taxes( false ); + } + + do_action( 'woocommerce_order_item_fee_after_calculate_taxes', $this, $calculate_tax_for ); + + return true; + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set fee amount. + * + * @param string $value Amount. + */ + public function set_amount( $value ) { + $this->set_prop( 'amount', wc_format_decimal( $value ) ); + } + + /** + * Set tax class. + * + * @param string $value Tax class. + */ + public function set_tax_class( $value ) { + if ( $value && ! in_array( $value, WC_Tax::get_tax_class_slugs(), true ) ) { + $this->error( 'order_item_fee_invalid_tax_class', __( 'Invalid tax class', 'woocommerce' ) ); + } + $this->set_prop( 'tax_class', $value ); + } + + /** + * Set tax_status. + * + * @param string $value Tax status. + */ + public function set_tax_status( $value ) { + if ( in_array( $value, array( 'taxable', 'none' ), true ) ) { + $this->set_prop( 'tax_status', $value ); + } else { + $this->set_prop( 'tax_status', 'taxable' ); + } + } + + /** + * Set total. + * + * @param string $amount Fee amount (do not enter negative amounts). + */ + public function set_total( $amount ) { + $this->set_prop( 'total', wc_format_decimal( $amount ) ); + } + + /** + * Set total tax. + * + * @param string $amount Amount. + */ + public function set_total_tax( $amount ) { + $this->set_prop( 'total_tax', wc_format_decimal( $amount ) ); + } + + /** + * Set taxes. + * + * This is an array of tax ID keys with total amount values. + * + * @param array $raw_tax_data Raw tax data. + */ + public function set_taxes( $raw_tax_data ) { + $raw_tax_data = maybe_unserialize( $raw_tax_data ); + $tax_data = array( + 'total' => array(), + ); + if ( ! empty( $raw_tax_data['total'] ) ) { + $tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data['total'] ); + } + $this->set_prop( 'taxes', $tax_data ); + + if ( 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' ) ) { + $this->set_total_tax( array_sum( $tax_data['total'] ) ); + } else { + $this->set_total_tax( array_sum( array_map( 'wc_round_tax_total', $tax_data['total'] ) ) ); + } + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get fee amount. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_amount( $context = 'view' ) { + return $this->get_prop( 'amount', $context ); + } + + /** + * Get order item name. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_name( $context = 'view' ) { + $name = $this->get_prop( 'name', $context ); + if ( 'view' === $context ) { + return $name ? $name : __( 'Fee', 'woocommerce' ); + } else { + return $name; + } + } + + /** + * Get order item type. + * + * @return string + */ + public function get_type() { + return 'fee'; + } + + /** + * Get tax class. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_tax_class( $context = 'view' ) { + return $this->get_prop( 'tax_class', $context ); + } + + /** + * Get tax status. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_tax_status( $context = 'view' ) { + return $this->get_prop( 'tax_status', $context ); + } + + /** + * Get total fee. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_total( $context = 'view' ) { + return $this->get_prop( 'total', $context ); + } + + /** + * Get total tax. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_total_tax( $context = 'view' ) { + return $this->get_prop( 'total_tax', $context ); + } + + /** + * Get fee taxes. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_taxes( $context = 'view' ) { + return $this->get_prop( 'taxes', $context ); + } + + /* + |-------------------------------------------------------------------------- + | Array Access Methods + |-------------------------------------------------------------------------- + | + | For backwards compatibility with legacy arrays. + | + */ + + /** + * OffsetGet for ArrayAccess/Backwards compatibility. + * + * @param string $offset Offset. + * @return mixed + */ + public function offsetGet( $offset ) { + if ( 'line_total' === $offset ) { + $offset = 'total'; + } elseif ( 'line_tax' === $offset ) { + $offset = 'total_tax'; + } elseif ( 'line_tax_data' === $offset ) { + $offset = 'taxes'; + } + return parent::offsetGet( $offset ); + } + + /** + * OffsetSet for ArrayAccess/Backwards compatibility. + * + * @deprecated 4.4.0 + * @param string $offset Offset. + * @param mixed $value Value. + */ + public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Fee::offsetSet', '4.4.0', '' ); + if ( 'line_total' === $offset ) { + $offset = 'total'; + } elseif ( 'line_tax' === $offset ) { + $offset = 'total_tax'; + } elseif ( 'line_tax_data' === $offset ) { + $offset = 'taxes'; + } + parent::offsetSet( $offset, $value ); + } + + /** + * OffsetExists for ArrayAccess + * + * @param string $offset Offset. + * @return bool + */ + public function offsetExists( $offset ) { + if ( in_array( $offset, array( 'line_total', 'line_tax', 'line_tax_data' ), true ) ) { + return true; + } + return parent::offsetExists( $offset ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-meta.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-meta.php new file mode 100644 index 0000000..693be23 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-meta.php @@ -0,0 +1,215 @@ +legacy = true; + $this->meta = array_filter( (array) $item ); + return; + } + $this->item = $item; + $this->meta = array_filter( (array) $item['item_meta'] ); + $this->product = $product; + } + + /** + * Display meta in a formatted list. + * + * @param bool $flat Flat (default: false). + * @param bool $return Return (default: false). + * @param string $hideprefix Hide prefix (default: _). + * @param string $delimiter Delimiter used to separate items when $flat is true. + * @return string|void + */ + public function display( $flat = false, $return = false, $hideprefix = '_', $delimiter = ", \n" ) { + $output = ''; + $formatted_meta = $this->get_formatted( $hideprefix ); + + if ( ! empty( $formatted_meta ) ) { + $meta_list = array(); + + foreach ( $formatted_meta as $meta ) { + if ( $flat ) { + $meta_list[] = wp_kses_post( $meta['label'] . ': ' . $meta['value'] ); + } else { + $meta_list[] = ' +
    ' . wp_kses_post( $meta['label'] ) . ':
    +
    ' . wp_kses_post( wpautop( make_clickable( $meta['value'] ) ) ) . '
    + '; + } + } + + if ( ! empty( $meta_list ) ) { + if ( $flat ) { + $output .= implode( $delimiter, $meta_list ); + } else { + $output .= '
    ' . implode( '', $meta_list ) . '
    '; + } + } + } + + $output = apply_filters( 'woocommerce_order_items_meta_display', $output, $this, $flat ); + + if ( $return ) { + return $output; + } else { + echo $output; // WPCS: XSS ok. + } + } + + /** + * Return an array of formatted item meta in format e.g. + * + * Returns: array( + * 'pa_size' => array( + * 'label' => 'Size', + * 'value' => 'Medium', + * ) + * ) + * + * @since 2.4 + * @param string $hideprefix exclude meta when key is prefixed with this, defaults to '_'. + * @return array + */ + public function get_formatted( $hideprefix = '_' ) { + if ( $this->legacy ) { + return $this->get_formatted_legacy( $hideprefix ); + } + + $formatted_meta = array(); + + if ( ! empty( $this->item['item_meta_array'] ) ) { + foreach ( $this->item['item_meta_array'] as $meta_id => $meta ) { + if ( '' === $meta->value || is_serialized( $meta->value ) || ( ! empty( $hideprefix ) && substr( $meta->key, 0, 1 ) === $hideprefix ) ) { + continue; + } + + $attribute_key = urldecode( str_replace( 'attribute_', '', $meta->key ) ); + $meta_value = $meta->value; + + // If this is a term slug, get the term's nice name. + if ( taxonomy_exists( $attribute_key ) ) { + $term = get_term_by( 'slug', $meta_value, $attribute_key ); + + if ( ! is_wp_error( $term ) && is_object( $term ) && $term->name ) { + $meta_value = $term->name; + } + } + + $formatted_meta[ $meta_id ] = array( + 'key' => $meta->key, + 'label' => wc_attribute_label( $attribute_key, $this->product ), + 'value' => apply_filters( 'woocommerce_order_item_display_meta_value', $meta_value, $meta, $this->item ), + ); + } + } + + return apply_filters( 'woocommerce_order_items_meta_get_formatted', $formatted_meta, $this ); + } + + /** + * Return an array of formatted item meta in format e.g. + * Handles @deprecated args. + * + * @param string $hideprefix Hide prefix. + * + * @return array + */ + public function get_formatted_legacy( $hideprefix = '_' ) { + if ( ! is_ajax() ) { + wc_deprecated_argument( 'WC_Order_Item_Meta::get_formatted', '2.4', 'Item Meta Data is being called with legacy arguments' ); + } + + $formatted_meta = array(); + + foreach ( $this->meta as $meta_key => $meta_values ) { + if ( empty( $meta_values ) || ( ! empty( $hideprefix ) && substr( $meta_key, 0, 1 ) === $hideprefix ) ) { + continue; + } + foreach ( (array) $meta_values as $meta_value ) { + // Skip serialised meta. + if ( is_serialized( $meta_value ) ) { + continue; + } + + $attribute_key = urldecode( str_replace( 'attribute_', '', $meta_key ) ); + + // If this is a term slug, get the term's nice name. + if ( taxonomy_exists( $attribute_key ) ) { + $term = get_term_by( 'slug', $meta_value, $attribute_key ); + if ( ! is_wp_error( $term ) && is_object( $term ) && $term->name ) { + $meta_value = $term->name; + } + } + + // Unique key required. + $formatted_meta_key = $meta_key; + $loop = 0; + while ( isset( $formatted_meta[ $formatted_meta_key ] ) ) { + $loop ++; + $formatted_meta_key = $meta_key . '-' . $loop; + } + + $formatted_meta[ $formatted_meta_key ] = array( + 'key' => $meta_key, + 'label' => wc_attribute_label( $attribute_key, $this->product ), + 'value' => apply_filters( 'woocommerce_order_item_display_meta_value', $meta_value, $this->meta, $this->item ), + ); + } + } + + return $formatted_meta; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-product.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-product.php new file mode 100644 index 0000000..a32a626 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-product.php @@ -0,0 +1,485 @@ + 0, + 'variation_id' => 0, + 'quantity' => 1, + 'tax_class' => '', + 'subtotal' => 0, + 'subtotal_tax' => 0, + 'total' => 0, + 'total_tax' => 0, + 'taxes' => array( + 'subtotal' => array(), + 'total' => array(), + ), + ); + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set quantity. + * + * @param int $value Quantity. + */ + public function set_quantity( $value ) { + $this->set_prop( 'quantity', wc_stock_amount( $value ) ); + } + + /** + * Set tax class. + * + * @param string $value Tax class. + */ + public function set_tax_class( $value ) { + if ( $value && ! in_array( $value, WC_Tax::get_tax_class_slugs(), true ) ) { + $this->error( 'order_item_product_invalid_tax_class', __( 'Invalid tax class', 'woocommerce' ) ); + } + $this->set_prop( 'tax_class', $value ); + } + + /** + * Set Product ID + * + * @param int $value Product ID. + */ + public function set_product_id( $value ) { + if ( $value > 0 && 'product' !== get_post_type( absint( $value ) ) ) { + $this->error( 'order_item_product_invalid_product_id', __( 'Invalid product ID', 'woocommerce' ) ); + } + $this->set_prop( 'product_id', absint( $value ) ); + } + + /** + * Set variation ID. + * + * @param int $value Variation ID. + */ + public function set_variation_id( $value ) { + if ( $value > 0 && 'product_variation' !== get_post_type( $value ) ) { + $this->error( 'order_item_product_invalid_variation_id', __( 'Invalid variation ID', 'woocommerce' ) ); + } + $this->set_prop( 'variation_id', absint( $value ) ); + } + + /** + * Line subtotal (before discounts). + * + * @param string $value Subtotal. + */ + public function set_subtotal( $value ) { + $value = wc_format_decimal( $value ); + + if ( ! is_numeric( $value ) ) { + $value = 0; + } + + $this->set_prop( 'subtotal', $value ); + } + + /** + * Line total (after discounts). + * + * @param string $value Total. + */ + public function set_total( $value ) { + $value = wc_format_decimal( $value ); + + if ( ! is_numeric( $value ) ) { + $value = 0; + } + + $this->set_prop( 'total', $value ); + + // Subtotal cannot be less than total. + if ( '' === $this->get_subtotal() || $this->get_subtotal() < $this->get_total() ) { + $this->set_subtotal( $value ); + } + } + + /** + * Line subtotal tax (before discounts). + * + * @param string $value Subtotal tax. + */ + public function set_subtotal_tax( $value ) { + $this->set_prop( 'subtotal_tax', wc_format_decimal( $value ) ); + } + + /** + * Line total tax (after discounts). + * + * @param string $value Total tax. + */ + public function set_total_tax( $value ) { + $this->set_prop( 'total_tax', wc_format_decimal( $value ) ); + } + + /** + * Set line taxes and totals for passed in taxes. + * + * @param array $raw_tax_data Raw tax data. + */ + public function set_taxes( $raw_tax_data ) { + $raw_tax_data = maybe_unserialize( $raw_tax_data ); + $tax_data = array( + 'total' => array(), + 'subtotal' => array(), + ); + if ( ! empty( $raw_tax_data['total'] ) && ! empty( $raw_tax_data['subtotal'] ) ) { + $tax_data['subtotal'] = array_map( 'wc_format_decimal', $raw_tax_data['subtotal'] ); + $tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data['total'] ); + + // Subtotal cannot be less than total! + if ( array_sum( $tax_data['subtotal'] ) < array_sum( $tax_data['total'] ) ) { + $tax_data['subtotal'] = $tax_data['total']; + } + } + $this->set_prop( 'taxes', $tax_data ); + + if ( 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' ) ) { + $this->set_total_tax( array_sum( $tax_data['total'] ) ); + $this->set_subtotal_tax( array_sum( $tax_data['subtotal'] ) ); + } else { + $this->set_total_tax( array_sum( array_map( 'wc_round_tax_total', $tax_data['total'] ) ) ); + $this->set_subtotal_tax( array_sum( array_map( 'wc_round_tax_total', $tax_data['subtotal'] ) ) ); + } + } + + /** + * Set variation data (stored as meta data - write only). + * + * @param array $data Key/Value pairs. + */ + public function set_variation( $data = array() ) { + if ( is_array( $data ) ) { + foreach ( $data as $key => $value ) { + $this->add_meta_data( str_replace( 'attribute_', '', $key ), $value, true ); + } + } + } + + /** + * Set properties based on passed in product object. + * + * @param WC_Product $product Product instance. + */ + public function set_product( $product ) { + if ( ! is_a( $product, 'WC_Product' ) ) { + $this->error( 'order_item_product_invalid_product', __( 'Invalid product', 'woocommerce' ) ); + } + if ( $product->is_type( 'variation' ) ) { + $this->set_product_id( $product->get_parent_id() ); + $this->set_variation_id( $product->get_id() ); + $this->set_variation( is_callable( array( $product, 'get_variation_attributes' ) ) ? $product->get_variation_attributes() : array() ); + } else { + $this->set_product_id( $product->get_id() ); + } + $this->set_name( $product->get_name() ); + $this->set_tax_class( $product->get_tax_class() ); + } + + /** + * Set meta data for backordered products. + */ + public function set_backorder_meta() { + $product = $this->get_product(); + if ( $product && $product->backorders_require_notification() && $product->is_on_backorder( $this->get_quantity() ) ) { + $this->add_meta_data( apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ), $this ), $this->get_quantity() - max( 0, $product->get_stock_quantity() ), true ); + } + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item type. + * + * @return string + */ + public function get_type() { + return 'line_item'; + } + + /** + * Get product ID. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return int + */ + public function get_product_id( $context = 'view' ) { + return $this->get_prop( 'product_id', $context ); + } + + /** + * Get variation ID. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return int + */ + public function get_variation_id( $context = 'view' ) { + return $this->get_prop( 'variation_id', $context ); + } + + /** + * Get quantity. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return int + */ + public function get_quantity( $context = 'view' ) { + return $this->get_prop( 'quantity', $context ); + } + + /** + * Get tax class. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_tax_class( $context = 'view' ) { + return $this->get_prop( 'tax_class', $context ); + } + + /** + * Get subtotal. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_subtotal( $context = 'view' ) { + return $this->get_prop( 'subtotal', $context ); + } + + /** + * Get subtotal tax. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_subtotal_tax( $context = 'view' ) { + return $this->get_prop( 'subtotal_tax', $context ); + } + + /** + * Get total. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_total( $context = 'view' ) { + return $this->get_prop( 'total', $context ); + } + + /** + * Get total tax. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_total_tax( $context = 'view' ) { + return $this->get_prop( 'total_tax', $context ); + } + + /** + * Get taxes. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return array + */ + public function get_taxes( $context = 'view' ) { + return $this->get_prop( 'taxes', $context ); + } + + /** + * Get the associated product. + * + * @return WC_Product|bool + */ + public function get_product() { + if ( $this->get_variation_id() ) { + $product = wc_get_product( $this->get_variation_id() ); + } else { + $product = wc_get_product( $this->get_product_id() ); + } + + // Backwards compatible filter from WC_Order::get_product_from_item(). + if ( has_filter( 'woocommerce_get_product_from_item' ) ) { + $product = apply_filters( 'woocommerce_get_product_from_item', $product, $this, $this->get_order() ); + } + + return apply_filters( 'woocommerce_order_item_product', $product, $this ); + } + + /** + * Get the Download URL. + * + * @param int $download_id Download ID. + * @return string + */ + public function get_item_download_url( $download_id ) { + $order = $this->get_order(); + + return $order ? add_query_arg( + array( + 'download_file' => $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id(), + 'order' => $order->get_order_key(), + 'email' => rawurlencode( $order->get_billing_email() ), + 'key' => $download_id, + ), + trailingslashit( home_url() ) + ) : ''; + } + + /** + * Get any associated downloadable files. + * + * @return array + */ + public function get_item_downloads() { + $files = array(); + $product = $this->get_product(); + $order = $this->get_order(); + $product_id = $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id(); + + if ( $product && $order && $product->is_downloadable() && $order->is_download_permitted() ) { + $email_hash = function_exists( 'hash' ) ? hash( 'sha256', $order->get_billing_email() ) : sha1( $order->get_billing_email() ); + $data_store = WC_Data_Store::load( 'customer-download' ); + $customer_downloads = $data_store->get_downloads( + array( + 'user_email' => $order->get_billing_email(), + 'order_id' => $order->get_id(), + 'product_id' => $product_id, + ) + ); + foreach ( $customer_downloads as $customer_download ) { + $download_id = $customer_download->get_download_id(); + + if ( $product->has_file( $download_id ) ) { + $file = $product->get_file( $download_id ); + $files[ $download_id ] = $file->get_data(); + $files[ $download_id ]['downloads_remaining'] = $customer_download->get_downloads_remaining(); + $files[ $download_id ]['access_expires'] = $customer_download->get_access_expires(); + $files[ $download_id ]['download_url'] = add_query_arg( + array( + 'download_file' => $product_id, + 'order' => $order->get_order_key(), + 'uid' => $email_hash, + 'key' => $download_id, + ), + trailingslashit( home_url() ) + ); + } + } + } + + return apply_filters( 'woocommerce_get_item_downloads', $files, $this, $order ); + } + + /** + * Get tax status. + * + * @return string + */ + public function get_tax_status() { + $product = $this->get_product(); + return $product ? $product->get_tax_status() : 'taxable'; + } + + /* + |-------------------------------------------------------------------------- + | Array Access Methods + |-------------------------------------------------------------------------- + | + | For backwards compatibility with legacy arrays. + | + */ + + /** + * OffsetGet for ArrayAccess/Backwards compatibility. + * + * @param string $offset Offset. + * @return mixed + */ + public function offsetGet( $offset ) { + if ( 'line_subtotal' === $offset ) { + $offset = 'subtotal'; + } elseif ( 'line_subtotal_tax' === $offset ) { + $offset = 'subtotal_tax'; + } elseif ( 'line_total' === $offset ) { + $offset = 'total'; + } elseif ( 'line_tax' === $offset ) { + $offset = 'total_tax'; + } elseif ( 'line_tax_data' === $offset ) { + $offset = 'taxes'; + } elseif ( 'qty' === $offset ) { + $offset = 'quantity'; + } + return parent::offsetGet( $offset ); + } + + /** + * OffsetSet for ArrayAccess/Backwards compatibility. + * + * @deprecated 4.4.0 + * @param string $offset Offset. + * @param mixed $value Value. + */ + public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Product::offsetSet', '4.4.0', '' ); + if ( 'line_subtotal' === $offset ) { + $offset = 'subtotal'; + } elseif ( 'line_subtotal_tax' === $offset ) { + $offset = 'subtotal_tax'; + } elseif ( 'line_total' === $offset ) { + $offset = 'total'; + } elseif ( 'line_tax' === $offset ) { + $offset = 'total_tax'; + } elseif ( 'line_tax_data' === $offset ) { + $offset = 'taxes'; + } elseif ( 'qty' === $offset ) { + $offset = 'quantity'; + } + parent::offsetSet( $offset, $value ); + } + + /** + * OffsetExists for ArrayAccess. + * + * @param string $offset Offset. + * @return bool + */ + public function offsetExists( $offset ) { + if ( in_array( $offset, array( 'line_subtotal', 'line_subtotal_tax', 'line_total', 'line_tax', 'line_tax_data', 'item_meta_array', 'item_meta', 'qty' ), true ) ) { + return true; + } + return parent::offsetExists( $offset ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-shipping.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-shipping.php new file mode 100644 index 0000000..6602e87 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-shipping.php @@ -0,0 +1,316 @@ + '', + 'method_id' => '', + 'instance_id' => '', + 'total' => 0, + 'total_tax' => 0, + 'taxes' => array( + 'total' => array(), + ), + ); + + /** + * Calculate item taxes. + * + * @since 3.2.0 + * @param array $calculate_tax_for Location data to get taxes for. Required. + * @return bool True if taxes were calculated. + */ + public function calculate_taxes( $calculate_tax_for = array() ) { + if ( ! isset( $calculate_tax_for['country'], $calculate_tax_for['state'], $calculate_tax_for['postcode'], $calculate_tax_for['city'], $calculate_tax_for['tax_class'] ) ) { + return false; + } + if ( wc_tax_enabled() ) { + $tax_rates = WC_Tax::find_shipping_rates( $calculate_tax_for ); + $taxes = WC_Tax::calc_tax( $this->get_total(), $tax_rates, false ); + $this->set_taxes( array( 'total' => $taxes ) ); + } else { + $this->set_taxes( false ); + } + + do_action( 'woocommerce_order_item_shipping_after_calculate_taxes', $this, $calculate_tax_for ); + + return true; + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set order item name. + * + * @param string $value Value to set. + * @throws WC_Data_Exception May throw exception if data is invalid. + */ + public function set_name( $value ) { + $this->set_method_title( $value ); + } + + /** + * Set method title. + * + * @param string $value Value to set. + * @throws WC_Data_Exception May throw exception if data is invalid. + */ + public function set_method_title( $value ) { + $this->set_prop( 'name', wc_clean( $value ) ); + $this->set_prop( 'method_title', wc_clean( $value ) ); + } + + /** + * Set shipping method id. + * + * @param string $value Value to set. + * @throws WC_Data_Exception May throw exception if data is invalid. + */ + public function set_method_id( $value ) { + $this->set_prop( 'method_id', wc_clean( $value ) ); + } + + /** + * Set shipping instance id. + * + * @param string $value Value to set. + * @throws WC_Data_Exception May throw exception if data is invalid. + */ + public function set_instance_id( $value ) { + $this->set_prop( 'instance_id', wc_clean( $value ) ); + } + + /** + * Set total. + * + * @param string $value Value to set. + * @throws WC_Data_Exception May throw exception if data is invalid. + */ + public function set_total( $value ) { + $this->set_prop( 'total', wc_format_decimal( $value ) ); + } + + /** + * Set total tax. + * + * @param string $value Value to set. + * @throws WC_Data_Exception May throw exception if data is invalid. + */ + protected function set_total_tax( $value ) { + $this->set_prop( 'total_tax', wc_format_decimal( $value ) ); + } + + /** + * Set taxes. + * + * This is an array of tax ID keys with total amount values. + * + * @param array $raw_tax_data Value to set. + * @throws WC_Data_Exception May throw exception if data is invalid. + */ + public function set_taxes( $raw_tax_data ) { + $raw_tax_data = maybe_unserialize( $raw_tax_data ); + $tax_data = array( + 'total' => array(), + ); + if ( isset( $raw_tax_data['total'] ) ) { + $tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data['total'] ); + } elseif ( ! empty( $raw_tax_data ) && is_array( $raw_tax_data ) ) { + // Older versions just used an array. + $tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data ); + } + $this->set_prop( 'taxes', $tax_data ); + + if ( 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' ) ) { + $this->set_total_tax( array_sum( $tax_data['total'] ) ); + } else { + $this->set_total_tax( array_sum( array_map( 'wc_round_tax_total', $tax_data['total'] ) ) ); + } + } + + /** + * Set properties based on passed in shipping rate object. + * + * @param WC_Shipping_Rate $shipping_rate Shipping rate to set. + */ + public function set_shipping_rate( $shipping_rate ) { + $this->set_method_title( $shipping_rate->get_label() ); + $this->set_method_id( $shipping_rate->get_method_id() ); + $this->set_instance_id( $shipping_rate->get_instance_id() ); + $this->set_total( $shipping_rate->get_cost() ); + $this->set_taxes( $shipping_rate->get_taxes() ); + $this->set_meta_data( $shipping_rate->get_meta_data() ); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item type. + * + * @return string + */ + public function get_type() { + return 'shipping'; + } + + /** + * Get order item name. + * + * @param string $context View or edit context. + * @return string + */ + public function get_name( $context = 'view' ) { + return $this->get_method_title( $context ); + } + + /** + * Get title. + * + * @param string $context View or edit context. + * @return string + */ + public function get_method_title( $context = 'view' ) { + $method_title = $this->get_prop( 'method_title', $context ); + if ( 'view' === $context ) { + return $method_title ? $method_title : __( 'Shipping', 'woocommerce' ); + } else { + return $method_title; + } + } + + /** + * Get method ID. + * + * @param string $context View or edit context. + * @return string + */ + public function get_method_id( $context = 'view' ) { + return $this->get_prop( 'method_id', $context ); + } + + /** + * Get instance ID. + * + * @param string $context View or edit context. + * @return string + */ + public function get_instance_id( $context = 'view' ) { + return $this->get_prop( 'instance_id', $context ); + } + + /** + * Get total cost. + * + * @param string $context View or edit context. + * @return string + */ + public function get_total( $context = 'view' ) { + return $this->get_prop( 'total', $context ); + } + + /** + * Get total tax. + * + * @param string $context View or edit context. + * @return string + */ + public function get_total_tax( $context = 'view' ) { + return $this->get_prop( 'total_tax', $context ); + } + + /** + * Get taxes. + * + * @param string $context View or edit context. + * @return array + */ + public function get_taxes( $context = 'view' ) { + return $this->get_prop( 'taxes', $context ); + } + + /** + * Get tax class. + * + * @param string $context View or edit context. + * @return string + */ + public function get_tax_class( $context = 'view' ) { + return get_option( 'woocommerce_shipping_tax_class' ); + } + + /* + |-------------------------------------------------------------------------- + | Array Access Methods + |-------------------------------------------------------------------------- + | + | For backwards compatibility with legacy arrays. + | + */ + + /** + * Offset get: for ArrayAccess/Backwards compatibility. + * + * @param string $offset Key. + * @return mixed + */ + public function offsetGet( $offset ) { + if ( 'cost' === $offset ) { + $offset = 'total'; + } + return parent::offsetGet( $offset ); + } + + /** + * Offset set: for ArrayAccess/Backwards compatibility. + * + * @deprecated 4.4.0 + * @param string $offset Key. + * @param mixed $value Value to set. + */ + public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Shipping::offsetSet', '4.4.0', '' ); + if ( 'cost' === $offset ) { + $offset = 'total'; + } + parent::offsetSet( $offset, $value ); + } + + /** + * Offset exists: for ArrayAccess. + * + * @param string $offset Key. + * @return bool + */ + public function offsetExists( $offset ) { + if ( in_array( $offset, array( 'cost' ), true ) ) { + return true; + } + return parent::offsetExists( $offset ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-tax.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-tax.php new file mode 100644 index 0000000..c41e388 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item-tax.php @@ -0,0 +1,288 @@ + '', + 'rate_id' => 0, + 'label' => '', + 'compound' => false, + 'tax_total' => 0, + 'shipping_tax_total' => 0, + 'rate_percent' => null, + ); + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set order item name. + * + * @param string $value Name. + */ + public function set_name( $value ) { + $this->set_rate_code( $value ); + } + + /** + * Set item name. + * + * @param string $value Rate code. + */ + public function set_rate_code( $value ) { + $this->set_prop( 'rate_code', wc_clean( $value ) ); + } + + /** + * Set item name. + * + * @param string $value Label. + */ + public function set_label( $value ) { + $this->set_prop( 'label', wc_clean( $value ) ); + } + + /** + * Set tax rate id. + * + * @param int $value Rate ID. + */ + public function set_rate_id( $value ) { + $this->set_prop( 'rate_id', absint( $value ) ); + } + + /** + * Set tax total. + * + * @param string $value Tax total. + */ + public function set_tax_total( $value ) { + $this->set_prop( 'tax_total', $value ? wc_format_decimal( $value ) : 0 ); + } + + /** + * Set shipping tax total. + * + * @param string $value Shipping tax total. + */ + public function set_shipping_tax_total( $value ) { + $this->set_prop( 'shipping_tax_total', $value ? wc_format_decimal( $value ) : 0 ); + } + + /** + * Set compound. + * + * @param bool $value If tax is compound. + */ + public function set_compound( $value ) { + $this->set_prop( 'compound', (bool) $value ); + } + + /** + * Set rate value. + * + * @param float $value tax rate value. + */ + public function set_rate_percent( $value ) { + $this->set_prop( 'rate_percent', (float) $value ); + } + + /** + * Set properties based on passed in tax rate by ID. + * + * @param int $tax_rate_id Tax rate ID. + */ + public function set_rate( $tax_rate_id ) { + $tax_rate = WC_Tax::_get_tax_rate( $tax_rate_id, OBJECT ); + + $this->set_rate_id( $tax_rate_id ); + $this->set_rate_code( WC_Tax::get_rate_code( $tax_rate ) ); + $this->set_label( WC_Tax::get_rate_label( $tax_rate ) ); + $this->set_compound( WC_Tax::is_compound( $tax_rate ) ); + $this->set_rate_percent( WC_Tax::get_rate_percent_value( $tax_rate ) ); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item type. + * + * @return string + */ + public function get_type() { + return 'tax'; + } + + /** + * Get rate code/name. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_name( $context = 'view' ) { + return $this->get_rate_code( $context ); + } + + /** + * Get rate code/name. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_rate_code( $context = 'view' ) { + return $this->get_prop( 'rate_code', $context ); + } + + /** + * Get label. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_label( $context = 'view' ) { + $label = $this->get_prop( 'label', $context ); + if ( 'view' === $context ) { + return $label ? $label : __( 'Tax', 'woocommerce' ); + } else { + return $label; + } + } + + /** + * Get tax rate ID. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return int + */ + public function get_rate_id( $context = 'view' ) { + return $this->get_prop( 'rate_id', $context ); + } + + /** + * Get tax_total + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_tax_total( $context = 'view' ) { + return $this->get_prop( 'tax_total', $context ); + } + + /** + * Get shipping_tax_total + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_shipping_tax_total( $context = 'view' ) { + return $this->get_prop( 'shipping_tax_total', $context ); + } + + /** + * Get compound. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return bool + */ + public function get_compound( $context = 'view' ) { + return $this->get_prop( 'compound', $context ); + } + + /** + * Is this a compound tax rate? + * + * @return boolean + */ + public function is_compound() { + return $this->get_compound(); + } + + /** + * Get rate value + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return float + */ + public function get_rate_percent( $context = 'view' ) { + return $this->get_prop( 'rate_percent', $context ); + } + + /* + |-------------------------------------------------------------------------- + | Array Access Methods + |-------------------------------------------------------------------------- + | + | For backwards compatibility with legacy arrays. + | + */ + + /** + * O for ArrayAccess/Backwards compatibility. + * + * @param string $offset Offset. + * @return mixed + */ + public function offsetGet( $offset ) { + if ( 'tax_amount' === $offset ) { + $offset = 'tax_total'; + } elseif ( 'shipping_tax_amount' === $offset ) { + $offset = 'shipping_tax_total'; + } + return parent::offsetGet( $offset ); + } + + /** + * OffsetSet for ArrayAccess/Backwards compatibility. + * + * @deprecated 4.4.0 + * @param string $offset Offset. + * @param mixed $value Value. + */ + public function offsetSet( $offset, $value ) { + wc_deprecated_function( 'WC_Order_Item_Tax::offsetSet', '4.4.0', '' ); + if ( 'tax_amount' === $offset ) { + $offset = 'tax_total'; + } elseif ( 'shipping_tax_amount' === $offset ) { + $offset = 'shipping_tax_total'; + } + parent::offsetSet( $offset, $value ); + } + + /** + * OffsetExists for ArrayAccess. + * + * @param string $offset Offset. + * @return bool + */ + public function offsetExists( $offset ) { + if ( in_array( $offset, array( 'tax_amount', 'shipping_tax_amount' ), true ) ) { + return true; + } + return parent::offsetExists( $offset ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item.php new file mode 100644 index 0000000..e7c9161 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-item.php @@ -0,0 +1,409 @@ + 0, + 'name' => '', + ); + + /** + * Stores meta in cache for future reads. + * A group must be set to to enable caching. + * + * @var string + */ + protected $cache_group = 'order-items'; + + /** + * Meta type. This should match up with + * the types available at https://developer.wordpress.org/reference/functions/add_metadata/. + * WP defines 'post', 'user', 'comment', and 'term'. + * + * @var string + */ + protected $meta_type = 'order_item'; + + /** + * This is the name of this object type. + * + * @var string + */ + protected $object_type = 'order_item'; + + /** + * Constructor. + * + * @param int|object|array $item ID to load from the DB, or WC_Order_Item object. + */ + public function __construct( $item = 0 ) { + parent::__construct( $item ); + + if ( $item instanceof WC_Order_Item ) { + $this->set_id( $item->get_id() ); + } elseif ( is_numeric( $item ) && $item > 0 ) { + $this->set_id( $item ); + } else { + $this->set_object_read( true ); + } + + $type = 'line_item' === $this->get_type() ? 'product' : $this->get_type(); + $this->data_store = WC_Data_Store::load( 'order-item-' . $type ); + if ( $this->get_id() > 0 ) { + $this->data_store->read( $this ); + } + } + + /** + * Merge changes with data and clear. + * Overrides WC_Data::apply_changes. + * array_replace_recursive does not work well for order items because it merges taxes instead + * of replacing them. + * + * @since 3.2.0 + */ + public function apply_changes() { + if ( function_exists( 'array_replace' ) ) { + $this->data = array_replace( $this->data, $this->changes ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.array_replaceFound + } else { // PHP 5.2 compatibility. + foreach ( $this->changes as $key => $change ) { + $this->data[ $key ] = $change; + } + } + $this->changes = array(); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order ID this meta belongs to. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return int + */ + public function get_order_id( $context = 'view' ) { + return $this->get_prop( 'order_id', $context ); + } + + /** + * Get order item name. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_name( $context = 'view' ) { + return $this->get_prop( 'name', $context ); + } + + /** + * Get order item type. Overridden by child classes. + * + * @return string + */ + public function get_type() { + return ''; + } + + /** + * Get quantity. + * + * @return int + */ + public function get_quantity() { + return 1; + } + + /** + * Get tax status. + * + * @return string + */ + public function get_tax_status() { + return 'taxable'; + } + + /** + * Get tax class. + * + * @return string + */ + public function get_tax_class() { + return ''; + } + + /** + * Get parent order object. + * + * @return WC_Order + */ + public function get_order() { + return wc_get_order( $this->get_order_id() ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set order ID. + * + * @param int $value Order ID. + */ + public function set_order_id( $value ) { + $this->set_prop( 'order_id', absint( $value ) ); + } + + /** + * Set order item name. + * + * @param string $value Item name. + */ + public function set_name( $value ) { + $this->set_prop( 'name', wp_check_invalid_utf8( $value ) ); + } + + /* + |-------------------------------------------------------------------------- + | Other Methods + |-------------------------------------------------------------------------- + */ + + /** + * Type checking. + * + * @param string|array $type Type. + * @return boolean + */ + public function is_type( $type ) { + return is_array( $type ) ? in_array( $this->get_type(), $type, true ) : $type === $this->get_type(); + } + + /** + * Calculate item taxes. + * + * @since 3.2.0 + * @param array $calculate_tax_for Location data to get taxes for. Required. + * @return bool True if taxes were calculated. + */ + public function calculate_taxes( $calculate_tax_for = array() ) { + if ( ! isset( $calculate_tax_for['country'], $calculate_tax_for['state'], $calculate_tax_for['postcode'], $calculate_tax_for['city'] ) ) { + return false; + } + if ( '0' !== $this->get_tax_class() && 'taxable' === $this->get_tax_status() && wc_tax_enabled() ) { + $calculate_tax_for['tax_class'] = $this->get_tax_class(); + $tax_rates = WC_Tax::find_rates( $calculate_tax_for ); + $taxes = WC_Tax::calc_tax( $this->get_total(), $tax_rates, false ); + + if ( method_exists( $this, 'get_subtotal' ) ) { + $subtotal_taxes = WC_Tax::calc_tax( $this->get_subtotal(), $tax_rates, false ); + $this->set_taxes( + array( + 'total' => $taxes, + 'subtotal' => $subtotal_taxes, + ) + ); + } else { + $this->set_taxes( array( 'total' => $taxes ) ); + } + } else { + $this->set_taxes( false ); + } + + do_action( 'woocommerce_order_item_after_calculate_taxes', $this, $calculate_tax_for ); + + return true; + } + + /* + |-------------------------------------------------------------------------- + | Meta Data Handling + |-------------------------------------------------------------------------- + */ + + /** + * Expands things like term slugs before return. + * + * @param string $hideprefix Meta data prefix, (default: _). + * @param bool $include_all Include all meta data, this stop skip items with values already in the product name. + * @return array + */ + public function get_formatted_meta_data( $hideprefix = '_', $include_all = false ) { + $formatted_meta = array(); + $meta_data = $this->get_meta_data(); + $hideprefix_length = ! empty( $hideprefix ) ? strlen( $hideprefix ) : 0; + $product = is_callable( array( $this, 'get_product' ) ) ? $this->get_product() : false; + $order_item_name = $this->get_name(); + + foreach ( $meta_data as $meta ) { + if ( empty( $meta->id ) || '' === $meta->value || ! is_scalar( $meta->value ) || ( $hideprefix_length && substr( $meta->key, 0, $hideprefix_length ) === $hideprefix ) ) { + continue; + } + + $meta->key = rawurldecode( (string) $meta->key ); + $meta->value = rawurldecode( (string) $meta->value ); + $attribute_key = str_replace( 'attribute_', '', $meta->key ); + $display_key = wc_attribute_label( $attribute_key, $product ); + $display_value = wp_kses_post( $meta->value ); + + if ( taxonomy_exists( $attribute_key ) ) { + $term = get_term_by( 'slug', $meta->value, $attribute_key ); + if ( ! is_wp_error( $term ) && is_object( $term ) && $term->name ) { + $display_value = $term->name; + } + } + + // Skip items with values already in the product details area of the product name. + if ( ! $include_all && $product && $product->is_type( 'variation' ) && wc_is_attribute_in_product_name( $display_value, $order_item_name ) ) { + continue; + } + + $formatted_meta[ $meta->id ] = (object) array( + 'key' => $meta->key, + 'value' => $meta->value, + 'display_key' => apply_filters( 'woocommerce_order_item_display_meta_key', $display_key, $meta, $this ), + 'display_value' => wpautop( make_clickable( apply_filters( 'woocommerce_order_item_display_meta_value', $display_value, $meta, $this ) ) ), + ); + } + + return apply_filters( 'woocommerce_order_item_get_formatted_meta_data', $formatted_meta, $this ); + } + + /* + |-------------------------------------------------------------------------- + | Array Access Methods + |-------------------------------------------------------------------------- + | + | For backwards compatibility with legacy arrays. + | + */ + + /** + * OffsetSet for ArrayAccess. + * + * @param string $offset Offset. + * @param mixed $value Value. + */ + public function offsetSet( $offset, $value ) { + if ( 'item_meta_array' === $offset ) { + foreach ( $value as $meta_id => $meta ) { + $this->update_meta_data( $meta->key, $meta->value, $meta_id ); + } + return; + } + + if ( array_key_exists( $offset, $this->data ) ) { + $setter = "set_$offset"; + if ( is_callable( array( $this, $setter ) ) ) { + $this->$setter( $value ); + } + return; + } + + $this->update_meta_data( $offset, $value ); + } + + /** + * OffsetUnset for ArrayAccess. + * + * @param string $offset Offset. + */ + public function offsetUnset( $offset ) { + $this->maybe_read_meta_data(); + + if ( 'item_meta_array' === $offset || 'item_meta' === $offset ) { + $this->meta_data = array(); + return; + } + + if ( array_key_exists( $offset, $this->data ) ) { + unset( $this->data[ $offset ] ); + } + + if ( array_key_exists( $offset, $this->changes ) ) { + unset( $this->changes[ $offset ] ); + } + + $this->delete_meta_data( $offset ); + } + + /** + * OffsetExists for ArrayAccess. + * + * @param string $offset Offset. + * @return bool + */ + public function offsetExists( $offset ) { + $this->maybe_read_meta_data(); + if ( 'item_meta_array' === $offset || 'item_meta' === $offset || array_key_exists( $offset, $this->data ) ) { + return true; + } + return array_key_exists( $offset, wp_list_pluck( $this->meta_data, 'value', 'key' ) ) || array_key_exists( '_' . $offset, wp_list_pluck( $this->meta_data, 'value', 'key' ) ); + } + + /** + * OffsetGet for ArrayAccess. + * + * @param string $offset Offset. + * @return mixed + */ + public function offsetGet( $offset ) { + $this->maybe_read_meta_data(); + + if ( 'item_meta_array' === $offset ) { + $return = array(); + + foreach ( $this->meta_data as $meta ) { + $return[ $meta->id ] = $meta; + } + + return $return; + } + + $meta_values = wp_list_pluck( $this->meta_data, 'value', 'key' ); + + if ( 'item_meta' === $offset ) { + return $meta_values; + } elseif ( 'type' === $offset ) { + return $this->get_type(); + } elseif ( array_key_exists( $offset, $this->data ) ) { + $getter = "get_$offset"; + if ( is_callable( array( $this, $getter ) ) ) { + return $this->$getter(); + } + } elseif ( array_key_exists( '_' . $offset, $meta_values ) ) { + // Item meta was expanded in previous versions, with prefixes removed. This maintains support. + return $meta_values[ '_' . $offset ]; + } elseif ( array_key_exists( $offset, $meta_values ) ) { + return $meta_values[ $offset ]; + } + + return null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-query.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-query.php new file mode 100644 index 0000000..4f481c8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-query.php @@ -0,0 +1,89 @@ + array_keys( wc_get_order_statuses() ), + 'type' => wc_get_order_types( 'view-orders' ), + 'currency' => '', + 'version' => '', + 'prices_include_tax' => '', + 'date_created' => '', + 'date_modified' => '', + 'date_completed' => '', + 'date_paid' => '', + 'discount_total' => '', + 'discount_tax' => '', + 'shipping_total' => '', + 'shipping_tax' => '', + 'cart_tax' => '', + 'total' => '', + 'total_tax' => '', + 'customer' => '', + 'customer_id' => '', + 'order_key' => '', + 'billing_first_name' => '', + 'billing_last_name' => '', + 'billing_company' => '', + 'billing_address_1' => '', + 'billing_address_2' => '', + 'billing_city' => '', + 'billing_state' => '', + 'billing_postcode' => '', + 'billing_country' => '', + 'billing_email' => '', + 'billing_phone' => '', + 'shipping_first_name' => '', + 'shipping_last_name' => '', + 'shipping_company' => '', + 'shipping_address_1' => '', + 'shipping_address_2' => '', + 'shipping_city' => '', + 'shipping_state' => '', + 'shipping_postcode' => '', + 'shipping_country' => '', + 'payment_method' => '', + 'payment_method_title' => '', + 'transaction_id' => '', + 'customer_ip_address' => '', + 'customer_user_agent' => '', + 'created_via' => '', + 'customer_note' => '', + ) + ); + } + + /** + * Get orders matching the current query vars. + * + * @return array|object of WC_Order objects + * + * @throws Exception When WC_Data_Store validation fails. + */ + public function get_orders() { + $args = apply_filters( 'woocommerce_order_query_args', $this->get_query_vars() ); + $results = WC_Data_Store::load( 'order' )->query( $args ); + return apply_filters( 'woocommerce_order_query', $results, $args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-refund.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-refund.php new file mode 100644 index 0000000..c384d04 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order-refund.php @@ -0,0 +1,228 @@ + '', + 'reason' => '', + 'refunded_by' => 0, + 'refunded_payment' => false, + ); + + /** + * Get internal type (post type.) + * + * @return string + */ + public function get_type() { + return 'shop_order_refund'; + } + + /** + * Get status - always completed for refunds. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_status( $context = 'view' ) { + return 'completed'; + } + + /** + * Get a title for the new post type. + */ + public function get_post_title() { + // @codingStandardsIgnoreStart + return sprintf( __( 'Refund – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) ); + // @codingStandardsIgnoreEnd + } + + /** + * Get refunded amount. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int|float + */ + public function get_amount( $context = 'view' ) { + return $this->get_prop( 'amount', $context ); + } + + /** + * Get refund reason. + * + * @since 2.2 + * @param string $context What the value is for. Valid values are view and edit. + * @return int|float + */ + public function get_reason( $context = 'view' ) { + return $this->get_prop( 'reason', $context ); + } + + /** + * Get ID of user who did the refund. + * + * @since 3.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ + public function get_refunded_by( $context = 'view' ) { + return $this->get_prop( 'refunded_by', $context ); + } + + /** + * Return if the payment was refunded via API. + * + * @since 3.3 + * @param string $context What the value is for. Valid values are view and edit. + * @return bool + */ + public function get_refunded_payment( $context = 'view' ) { + return $this->get_prop( 'refunded_payment', $context ); + } + + /** + * Get formatted refunded amount. + * + * @since 2.4 + * @return string + */ + public function get_formatted_refund_amount() { + return apply_filters( 'woocommerce_formatted_refund_amount', wc_price( $this->get_amount(), array( 'currency' => $this->get_currency() ) ), $this ); + } + + /** + * Set refunded amount. + * + * @param string $value Value to set. + * @throws WC_Data_Exception Exception if the amount is invalid. + */ + public function set_amount( $value ) { + $this->set_prop( 'amount', wc_format_decimal( $value ) ); + } + + /** + * Set refund reason. + * + * @param string $value Value to set. + * @throws WC_Data_Exception Exception if the amount is invalid. + */ + public function set_reason( $value ) { + $this->set_prop( 'reason', $value ); + } + + /** + * Set refunded by. + * + * @param int $value Value to set. + * @throws WC_Data_Exception Exception if the amount is invalid. + */ + public function set_refunded_by( $value ) { + $this->set_prop( 'refunded_by', absint( $value ) ); + } + + /** + * Set if the payment was refunded via API. + * + * @since 3.3 + * @param bool $value Value to set. + */ + public function set_refunded_payment( $value ) { + $this->set_prop( 'refunded_payment', (bool) $value ); + } + + /** + * Magic __get method for backwards compatibility. + * + * @param string $key Value to get. + * @return mixed + */ + public function __get( $key ) { + wc_doing_it_wrong( $key, 'Refund properties should not be accessed directly.', '3.0' ); + /** + * Maps legacy vars to new getters. + */ + if ( 'reason' === $key ) { + return $this->get_reason(); + } elseif ( 'refund_amount' === $key ) { + return $this->get_amount(); + } + return parent::__get( $key ); + } + + /** + * Gets an refund from the database. + * + * @deprecated 3.0 + * @param int $id (default: 0). + * @return bool + */ + public function get_refund( $id = 0 ) { + wc_deprecated_function( 'get_refund', '3.0', 'read' ); + + if ( ! $id ) { + return false; + } + + $result = get_post( $id ); + + if ( $result ) { + $this->populate( $result ); + return true; + } + + return false; + } + + /** + * Get refund amount. + * + * @deprecated 3.0 + * @return int|float + */ + public function get_refund_amount() { + wc_deprecated_function( 'get_refund_amount', '3.0', 'get_amount' ); + return $this->get_amount(); + } + + /** + * Get refund reason. + * + * @deprecated 3.0 + * @return int|float + */ + public function get_refund_reason() { + wc_deprecated_function( 'get_refund_reason', '3.0', 'get_reason' ); + return $this->get_reason(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order.php new file mode 100644 index 0000000..f33c5db --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-order.php @@ -0,0 +1,2091 @@ + 0, + 'status' => '', + 'currency' => '', + 'version' => '', + 'prices_include_tax' => false, + 'date_created' => null, + 'date_modified' => null, + 'discount_total' => 0, + 'discount_tax' => 0, + 'shipping_total' => 0, + 'shipping_tax' => 0, + 'cart_tax' => 0, + 'total' => 0, + 'total_tax' => 0, + + // Order props. + 'customer_id' => 0, + 'order_key' => '', + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + ), + 'payment_method' => '', + 'payment_method_title' => '', + 'transaction_id' => '', + 'customer_ip_address' => '', + 'customer_user_agent' => '', + 'created_via' => '', + 'customer_note' => '', + 'date_completed' => null, + 'date_paid' => null, + 'cart_hash' => '', + ); + + /** + * When a payment is complete this function is called. + * + * Most of the time this should mark an order as 'processing' so that admin can process/post the items. + * If the cart contains only downloadable items then the order is 'completed' since the admin needs to take no action. + * Stock levels are reduced at this point. + * Sales are also recorded for products. + * Finally, record the date of payment. + * + * @param string $transaction_id Optional transaction id to store in post meta. + * @return bool success + */ + public function payment_complete( $transaction_id = '' ) { + if ( ! $this->get_id() ) { // Order must exist. + return false; + } + + try { + do_action( 'woocommerce_pre_payment_complete', $this->get_id() ); + + if ( WC()->session ) { + WC()->session->set( 'order_awaiting_payment', false ); + } + + if ( $this->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_payment_complete', array( 'on-hold', 'pending', 'failed', 'cancelled' ), $this ) ) ) { + if ( ! empty( $transaction_id ) ) { + $this->set_transaction_id( $transaction_id ); + } + if ( ! $this->get_date_paid( 'edit' ) ) { + $this->set_date_paid( time() ); + } + $this->set_status( apply_filters( 'woocommerce_payment_complete_order_status', $this->needs_processing() ? 'processing' : 'completed', $this->get_id(), $this ) ); + $this->save(); + + do_action( 'woocommerce_payment_complete', $this->get_id() ); + } else { + do_action( 'woocommerce_payment_complete_order_status_' . $this->get_status(), $this->get_id() ); + } + } catch ( Exception $e ) { + /** + * If there was an error completing the payment, log to a file and add an order note so the admin can take action. + */ + $logger = wc_get_logger(); + $logger->error( + sprintf( + 'Error completing payment for order #%d', + $this->get_id() + ), + array( + 'order' => $this, + 'error' => $e, + ) + ); + $this->add_order_note( __( 'Payment complete event failed.', 'woocommerce' ) . ' ' . $e->getMessage() ); + return false; + } + return true; + } + + /** + * Gets order total - formatted for display. + * + * @param string $tax_display Type of tax display. + * @param bool $display_refunded If should include refunded value. + * + * @return string + */ + public function get_formatted_order_total( $tax_display = '', $display_refunded = true ) { + $formatted_total = wc_price( $this->get_total(), array( 'currency' => $this->get_currency() ) ); + $order_total = $this->get_total(); + $total_refunded = $this->get_total_refunded(); + $tax_string = ''; + + // Tax for inclusive prices. + if ( wc_tax_enabled() && 'incl' === $tax_display ) { + $tax_string_array = array(); + $tax_totals = $this->get_tax_totals(); + + if ( 'itemized' === get_option( 'woocommerce_tax_total_display' ) ) { + foreach ( $tax_totals as $code => $tax ) { + $tax_amount = ( $total_refunded && $display_refunded ) ? wc_price( WC_Tax::round( $tax->amount - $this->get_total_tax_refunded_by_rate_id( $tax->rate_id ) ), array( 'currency' => $this->get_currency() ) ) : $tax->formatted_amount; + $tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label ); + } + } elseif ( ! empty( $tax_totals ) ) { + $tax_amount = ( $total_refunded && $display_refunded ) ? $this->get_total_tax() - $this->get_total_tax_refunded() : $this->get_total_tax(); + $tax_string_array[] = sprintf( '%s %s', wc_price( $tax_amount, array( 'currency' => $this->get_currency() ) ), WC()->countries->tax_or_vat() ); + } + + if ( ! empty( $tax_string_array ) ) { + /* translators: %s: taxes */ + $tax_string = ' ' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ) . ''; + } + } + + if ( $total_refunded && $display_refunded ) { + $formatted_total = '' . wp_strip_all_tags( $formatted_total ) . ' ' . wc_price( $order_total - $total_refunded, array( 'currency' => $this->get_currency() ) ) . $tax_string . ''; + } else { + $formatted_total .= $tax_string; + } + + /** + * Filter WooCommerce formatted order total. + * + * @param string $formatted_total Total to display. + * @param WC_Order $order Order data. + * @param string $tax_display Type of tax display. + * @param bool $display_refunded If should include refunded value. + */ + return apply_filters( 'woocommerce_get_formatted_order_total', $formatted_total, $this, $tax_display, $display_refunded ); + } + + /* + |-------------------------------------------------------------------------- + | CRUD methods + |-------------------------------------------------------------------------- + | + | Methods which create, read, update and delete orders from the database. + | Written in abstract fashion so that the way orders are stored can be + | changed more easily in the future. + | + | A save method is included for convenience (chooses update or create based + | on if the order exists yet). + | + */ + + /** + * Save data to the database. + * + * @since 3.0.0 + * @return int order ID + */ + public function save() { + $this->maybe_set_user_billing_email(); + parent::save(); + $this->status_transition(); + + return $this->get_id(); + } + + /** + * Log an error about this order is exception is encountered. + * + * @param Exception $e Exception object. + * @param string $message Message regarding exception thrown. + * @since 3.7.0 + */ + protected function handle_exception( $e, $message = 'Error' ) { + wc_get_logger()->error( + $message, + array( + 'order' => $this, + 'error' => $e, + ) + ); + $this->add_order_note( $message . ' ' . $e->getMessage() ); + } + + /** + * Set order status. + * + * @since 3.0.0 + * @param string $new_status Status to change the order to. No internal wc- prefix is required. + * @param string $note Optional note to add. + * @param bool $manual_update Is this a manual order status change?. + * @return array + */ + public function set_status( $new_status, $note = '', $manual_update = false ) { + $result = parent::set_status( $new_status ); + + if ( true === $this->object_read && ! empty( $result['from'] ) && $result['from'] !== $result['to'] ) { + $this->status_transition = array( + 'from' => ! empty( $this->status_transition['from'] ) ? $this->status_transition['from'] : $result['from'], + 'to' => $result['to'], + 'note' => $note, + 'manual' => (bool) $manual_update, + ); + + if ( $manual_update ) { + do_action( 'woocommerce_order_edit_status', $this->get_id(), $result['to'] ); + } + + $this->maybe_set_date_paid(); + $this->maybe_set_date_completed(); + } + + return $result; + } + + /** + * Maybe set date paid. + * + * Sets the date paid variable when transitioning to the payment complete + * order status. This is either processing or completed. This is not filtered + * to avoid infinite loops e.g. if loading an order via the filter. + * + * Date paid is set once in this manner - only when it is not already set. + * This ensures the data exists even if a gateway does not use the + * `payment_complete` method. + * + * @since 3.0.0 + */ + public function maybe_set_date_paid() { + // This logic only runs if the date_paid prop has not been set yet. + if ( ! $this->get_date_paid( 'edit' ) ) { + $payment_completed_status = apply_filters( 'woocommerce_payment_complete_order_status', $this->needs_processing() ? 'processing' : 'completed', $this->get_id(), $this ); + + if ( $this->has_status( $payment_completed_status ) ) { + // If payment complete status is reached, set paid now. + $this->set_date_paid( time() ); + + } elseif ( 'processing' === $payment_completed_status && $this->has_status( 'completed' ) ) { + // If payment complete status was processing, but we've passed that and still have no date, set it now. + $this->set_date_paid( time() ); + } + } + } + + /** + * Maybe set date completed. + * + * Sets the date completed variable when transitioning to completed status. + * + * @since 3.0.0 + */ + protected function maybe_set_date_completed() { + if ( $this->has_status( 'completed' ) ) { + $this->set_date_completed( time() ); + } + } + + /** + * Updates status of order immediately. + * + * @uses WC_Order::set_status() + * @param string $new_status Status to change the order to. No internal wc- prefix is required. + * @param string $note Optional note to add. + * @param bool $manual Is this a manual order status change?. + * @return bool + */ + public function update_status( $new_status, $note = '', $manual = false ) { + if ( ! $this->get_id() ) { // Order must exist. + return false; + } + + try { + $this->set_status( $new_status, $note, $manual ); + $this->save(); + } catch ( Exception $e ) { + $logger = wc_get_logger(); + $logger->error( + sprintf( + 'Error updating status for order #%d', + $this->get_id() + ), + array( + 'order' => $this, + 'error' => $e, + ) + ); + $this->add_order_note( __( 'Update status event failed.', 'woocommerce' ) . ' ' . $e->getMessage() ); + return false; + } + return true; + } + + /** + * Handle the status transition. + */ + protected function status_transition() { + $status_transition = $this->status_transition; + + // Reset status transition variable. + $this->status_transition = false; + + if ( $status_transition ) { + try { + do_action( 'woocommerce_order_status_' . $status_transition['to'], $this->get_id(), $this ); + + if ( ! empty( $status_transition['from'] ) ) { + /* translators: 1: old order status 2: new order status */ + $transition_note = sprintf( __( 'Order status changed from %1$s to %2$s.', 'woocommerce' ), wc_get_order_status_name( $status_transition['from'] ), wc_get_order_status_name( $status_transition['to'] ) ); + + // Note the transition occurred. + $this->add_status_transition_note( $transition_note, $status_transition ); + + do_action( 'woocommerce_order_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->get_id(), $this ); + do_action( 'woocommerce_order_status_changed', $this->get_id(), $status_transition['from'], $status_transition['to'], $this ); + + // Work out if this was for a payment, and trigger a payment_status hook instead. + if ( + in_array( $status_transition['from'], apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ), $this ), true ) + && in_array( $status_transition['to'], wc_get_is_paid_statuses(), true ) + ) { + /** + * Fires when the order progresses from a pending payment status to a paid one. + * + * @since 3.9.0 + * @param int Order ID + * @param WC_Order Order object + */ + do_action( 'woocommerce_order_payment_status_changed', $this->get_id(), $this ); + } + } else { + /* translators: %s: new order status */ + $transition_note = sprintf( __( 'Order status set to %s.', 'woocommerce' ), wc_get_order_status_name( $status_transition['to'] ) ); + + // Note the transition occurred. + $this->add_status_transition_note( $transition_note, $status_transition ); + } + } catch ( Exception $e ) { + $logger = wc_get_logger(); + $logger->error( + sprintf( + 'Status transition of order #%d errored!', + $this->get_id() + ), + array( + 'order' => $this, + 'error' => $e, + ) + ); + $this->add_order_note( __( 'Error during status transition.', 'woocommerce' ) . ' ' . $e->getMessage() ); + } + } + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + | + | Methods for getting data from the order object. + | + */ + + /** + * Get basic order data in array format. + * + * @return array + */ + public function get_base_data() { + return array_merge( + array( 'id' => $this->get_id() ), + $this->data, + array( 'number' => $this->get_order_number() ) + ); + } + + /** + * Get all class data in array format. + * + * @since 3.0.0 + * @return array + */ + public function get_data() { + return array_merge( + $this->get_base_data(), + array( + 'meta_data' => $this->get_meta_data(), + 'line_items' => $this->get_items( 'line_item' ), + 'tax_lines' => $this->get_items( 'tax' ), + 'shipping_lines' => $this->get_items( 'shipping' ), + 'fee_lines' => $this->get_items( 'fee' ), + 'coupon_lines' => $this->get_items( 'coupon' ), + ) + ); + } + + /** + * Expands the shipping and billing information in the changes array. + */ + public function get_changes() { + $changed_props = parent::get_changes(); + $subs = array( 'shipping', 'billing' ); + foreach ( $subs as $sub ) { + if ( ! empty( $changed_props[ $sub ] ) ) { + foreach ( $changed_props[ $sub ] as $sub_prop => $value ) { + $changed_props[ $sub . '_' . $sub_prop ] = $value; + } + } + } + if ( isset( $changed_props['customer_note'] ) ) { + $changed_props['post_excerpt'] = $changed_props['customer_note']; + } + return $changed_props; + } + + /** + * Gets the order number for display (by default, order ID). + * + * @return string + */ + public function get_order_number() { + return (string) apply_filters( 'woocommerce_order_number', $this->get_id(), $this ); + } + + /** + * Get order key. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_order_key( $context = 'view' ) { + return $this->get_prop( 'order_key', $context ); + } + + /** + * Get customer_id. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ + public function get_customer_id( $context = 'view' ) { + return $this->get_prop( 'customer_id', $context ); + } + + /** + * Alias for get_customer_id(). + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ + public function get_user_id( $context = 'view' ) { + return $this->get_customer_id( $context ); + } + + /** + * Get the user associated with the order. False for guests. + * + * @return WP_User|false + */ + public function get_user() { + return $this->get_user_id() ? get_user_by( 'id', $this->get_user_id() ) : false; + } + + /** + * Gets a prop for a getter method. + * + * @since 3.0.0 + * @param string $prop Name of prop to get. + * @param string $address billing or shipping. + * @param string $context What the value is for. Valid values are view and edit. + * @return mixed + */ + protected function get_address_prop( $prop, $address = 'billing', $context = 'view' ) { + $value = null; + + if ( array_key_exists( $prop, $this->data[ $address ] ) ) { + $value = isset( $this->changes[ $address ][ $prop ] ) ? $this->changes[ $address ][ $prop ] : $this->data[ $address ][ $prop ]; + + if ( 'view' === $context ) { + $value = apply_filters( $this->get_hook_prefix() . $address . '_' . $prop, $value, $this ); + } + } + return $value; + } + + /** + * Get billing first name. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_first_name( $context = 'view' ) { + return $this->get_address_prop( 'first_name', 'billing', $context ); + } + + /** + * Get billing last name. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_last_name( $context = 'view' ) { + return $this->get_address_prop( 'last_name', 'billing', $context ); + } + + /** + * Get billing company. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_company( $context = 'view' ) { + return $this->get_address_prop( 'company', 'billing', $context ); + } + + /** + * Get billing address line 1. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_address_1( $context = 'view' ) { + return $this->get_address_prop( 'address_1', 'billing', $context ); + } + + /** + * Get billing address line 2. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_address_2( $context = 'view' ) { + return $this->get_address_prop( 'address_2', 'billing', $context ); + } + + /** + * Get billing city. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_city( $context = 'view' ) { + return $this->get_address_prop( 'city', 'billing', $context ); + } + + /** + * Get billing state. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_state( $context = 'view' ) { + return $this->get_address_prop( 'state', 'billing', $context ); + } + + /** + * Get billing postcode. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_postcode( $context = 'view' ) { + return $this->get_address_prop( 'postcode', 'billing', $context ); + } + + /** + * Get billing country. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_country( $context = 'view' ) { + return $this->get_address_prop( 'country', 'billing', $context ); + } + + /** + * Get billing email. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_email( $context = 'view' ) { + return $this->get_address_prop( 'email', 'billing', $context ); + } + + /** + * Get billing phone. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_billing_phone( $context = 'view' ) { + return $this->get_address_prop( 'phone', 'billing', $context ); + } + + /** + * Get shipping first name. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_shipping_first_name( $context = 'view' ) { + return $this->get_address_prop( 'first_name', 'shipping', $context ); + } + + /** + * Get shipping_last_name. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_shipping_last_name( $context = 'view' ) { + return $this->get_address_prop( 'last_name', 'shipping', $context ); + } + + /** + * Get shipping company. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_shipping_company( $context = 'view' ) { + return $this->get_address_prop( 'company', 'shipping', $context ); + } + + /** + * Get shipping address line 1. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_shipping_address_1( $context = 'view' ) { + return $this->get_address_prop( 'address_1', 'shipping', $context ); + } + + /** + * Get shipping address line 2. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_shipping_address_2( $context = 'view' ) { + return $this->get_address_prop( 'address_2', 'shipping', $context ); + } + + /** + * Get shipping city. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_shipping_city( $context = 'view' ) { + return $this->get_address_prop( 'city', 'shipping', $context ); + } + + /** + * Get shipping state. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_shipping_state( $context = 'view' ) { + return $this->get_address_prop( 'state', 'shipping', $context ); + } + + /** + * Get shipping postcode. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_shipping_postcode( $context = 'view' ) { + return $this->get_address_prop( 'postcode', 'shipping', $context ); + } + + /** + * Get shipping country. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_shipping_country( $context = 'view' ) { + return $this->get_address_prop( 'country', 'shipping', $context ); + } + + /** + * Get the payment method. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_payment_method( $context = 'view' ) { + return $this->get_prop( 'payment_method', $context ); + } + + /** + * Get payment method title. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_payment_method_title( $context = 'view' ) { + return $this->get_prop( 'payment_method_title', $context ); + } + + /** + * Get transaction d. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_transaction_id( $context = 'view' ) { + return $this->get_prop( 'transaction_id', $context ); + } + + /** + * Get customer ip address. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_customer_ip_address( $context = 'view' ) { + return $this->get_prop( 'customer_ip_address', $context ); + } + + /** + * Get customer user agent. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_customer_user_agent( $context = 'view' ) { + return $this->get_prop( 'customer_user_agent', $context ); + } + + /** + * Get created via. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_created_via( $context = 'view' ) { + return $this->get_prop( 'created_via', $context ); + } + + /** + * Get customer note. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_customer_note( $context = 'view' ) { + return $this->get_prop( 'customer_note', $context ); + } + + /** + * Get date completed. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return WC_DateTime|NULL object if the date is set or null if there is no date. + */ + public function get_date_completed( $context = 'view' ) { + return $this->get_prop( 'date_completed', $context ); + } + + /** + * Get date paid. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return WC_DateTime|NULL object if the date is set or null if there is no date. + */ + public function get_date_paid( $context = 'view' ) { + $date_paid = $this->get_prop( 'date_paid', $context ); + + if ( 'view' === $context && ! $date_paid && version_compare( $this->get_version( 'edit' ), '3.0', '<' ) && $this->has_status( apply_filters( 'woocommerce_payment_complete_order_status', $this->needs_processing() ? 'processing' : 'completed', $this->get_id(), $this ) ) ) { + // In view context, return a date if missing. + $date_paid = $this->get_date_created( 'edit' ); + } + return $date_paid; + } + + /** + * Get cart hash. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_cart_hash( $context = 'view' ) { + return $this->get_prop( 'cart_hash', $context ); + } + + /** + * Returns the requested address in raw, non-formatted way. + * Note: Merges raw data with get_prop data so changes are returned too. + * + * @since 2.4.0 + * @param string $type Billing or shipping. Anything else besides 'billing' will return shipping address. + * @return array The stored address after filter. + */ + public function get_address( $type = 'billing' ) { + return apply_filters( 'woocommerce_get_order_address', array_merge( $this->data[ $type ], $this->get_prop( $type, 'view' ) ), $type, $this ); + } + + /** + * Get a formatted shipping address for the order. + * + * @return string + */ + public function get_shipping_address_map_url() { + $address = $this->get_address( 'shipping' ); + + // Remove name and company before generate the Google Maps URL. + unset( $address['first_name'], $address['last_name'], $address['company'] ); + + $address = apply_filters( 'woocommerce_shipping_address_map_url_parts', $address, $this ); + + return apply_filters( 'woocommerce_shipping_address_map_url', 'https://maps.google.com/maps?&q=' . rawurlencode( implode( ', ', $address ) ) . '&z=16', $this ); + } + + /** + * Get a formatted billing full name. + * + * @return string + */ + public function get_formatted_billing_full_name() { + /* translators: 1: first name 2: last name */ + return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->get_billing_first_name(), $this->get_billing_last_name() ); + } + + /** + * Get a formatted shipping full name. + * + * @return string + */ + public function get_formatted_shipping_full_name() { + /* translators: 1: first name 2: last name */ + return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->get_shipping_first_name(), $this->get_shipping_last_name() ); + } + + /** + * Get a formatted billing address for the order. + * + * @param string $empty_content Content to show if no address is present. @since 3.3.0. + * @return string + */ + public function get_formatted_billing_address( $empty_content = '' ) { + $raw_address = apply_filters( 'woocommerce_order_formatted_billing_address', $this->get_address( 'billing' ), $this ); + $address = WC()->countries->get_formatted_address( $raw_address ); + + /** + * Filter orders formatterd billing address. + * + * @since 3.8.0 + * @param string $address Formatted billing address string. + * @param array $raw_address Raw billing address. + * @param WC_Order $order Order data. @since 3.9.0 + */ + return apply_filters( 'woocommerce_order_get_formatted_billing_address', $address ? $address : $empty_content, $raw_address, $this ); + } + + /** + * Get a formatted shipping address for the order. + * + * @param string $empty_content Content to show if no address is present. @since 3.3.0. + * @return string + */ + public function get_formatted_shipping_address( $empty_content = '' ) { + $address = ''; + $raw_address = $this->get_address( 'shipping' ); + + if ( $this->has_shipping_address() ) { + $raw_address = apply_filters( 'woocommerce_order_formatted_shipping_address', $raw_address, $this ); + $address = WC()->countries->get_formatted_address( $raw_address ); + } + + /** + * Filter orders formatterd shipping address. + * + * @since 3.8.0 + * @param string $address Formatted billing address string. + * @param array $raw_address Raw billing address. + * @param WC_Order $order Order data. @since 3.9.0 + */ + return apply_filters( 'woocommerce_order_get_formatted_shipping_address', $address ? $address : $empty_content, $raw_address, $this ); + } + + /** + * Returns true if the order has a billing address. + * + * @since 3.0.4 + * @return boolean + */ + public function has_billing_address() { + return $this->get_billing_address_1() || $this->get_billing_address_2(); + } + + /** + * Returns true if the order has a shipping address. + * + * @since 3.0.4 + * @return boolean + */ + public function has_shipping_address() { + return $this->get_shipping_address_1() || $this->get_shipping_address_2(); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + | + | Functions for setting order data. These should not update anything in the + | database itself and should only change what is stored in the class + | object. However, for backwards compatibility pre 3.0.0 some of these + | setters may handle both. + | + */ + + /** + * Sets a prop for a setter method. + * + * @since 3.0.0 + * @param string $prop Name of prop to set. + * @param string $address Name of address to set. billing or shipping. + * @param mixed $value Value of the prop. + */ + protected function set_address_prop( $prop, $address, $value ) { + if ( array_key_exists( $prop, $this->data[ $address ] ) ) { + if ( true === $this->object_read ) { + if ( $value !== $this->data[ $address ][ $prop ] || ( isset( $this->changes[ $address ] ) && array_key_exists( $prop, $this->changes[ $address ] ) ) ) { + $this->changes[ $address ][ $prop ] = $value; + } + } else { + $this->data[ $address ][ $prop ] = $value; + } + } + } + + /** + * Set order key. + * + * @param string $value Max length 22 chars. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_order_key( $value ) { + $this->set_prop( 'order_key', substr( $value, 0, 22 ) ); + } + + /** + * Set customer id. + * + * @param int $value Customer ID. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_customer_id( $value ) { + $this->set_prop( 'customer_id', absint( $value ) ); + } + + /** + * Set billing first name. + * + * @param string $value Billing first name. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_first_name( $value ) { + $this->set_address_prop( 'first_name', 'billing', $value ); + } + + /** + * Set billing last name. + * + * @param string $value Billing last name. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_last_name( $value ) { + $this->set_address_prop( 'last_name', 'billing', $value ); + } + + /** + * Set billing company. + * + * @param string $value Billing company. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_company( $value ) { + $this->set_address_prop( 'company', 'billing', $value ); + } + + /** + * Set billing address line 1. + * + * @param string $value Billing address line 1. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_address_1( $value ) { + $this->set_address_prop( 'address_1', 'billing', $value ); + } + + /** + * Set billing address line 2. + * + * @param string $value Billing address line 2. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_address_2( $value ) { + $this->set_address_prop( 'address_2', 'billing', $value ); + } + + /** + * Set billing city. + * + * @param string $value Billing city. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_city( $value ) { + $this->set_address_prop( 'city', 'billing', $value ); + } + + /** + * Set billing state. + * + * @param string $value Billing state. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_state( $value ) { + $this->set_address_prop( 'state', 'billing', $value ); + } + + /** + * Set billing postcode. + * + * @param string $value Billing postcode. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_postcode( $value ) { + $this->set_address_prop( 'postcode', 'billing', $value ); + } + + /** + * Set billing country. + * + * @param string $value Billing country. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_country( $value ) { + $this->set_address_prop( 'country', 'billing', $value ); + } + + /** + * Maybe set empty billing email to that of the user who owns the order. + */ + protected function maybe_set_user_billing_email() { + $user = $this->get_user(); + if ( ! $this->get_billing_email() && $user ) { + try { + $this->set_billing_email( $user->user_email ); + } catch ( WC_Data_Exception $e ) { + unset( $e ); + } + } + } + + /** + * Set billing email. + * + * @param string $value Billing email. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_email( $value ) { + if ( $value && ! is_email( $value ) ) { + $this->error( 'order_invalid_billing_email', __( 'Invalid billing email address', 'woocommerce' ) ); + } + $this->set_address_prop( 'email', 'billing', sanitize_email( $value ) ); + } + + /** + * Set billing phone. + * + * @param string $value Billing phone. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_billing_phone( $value ) { + $this->set_address_prop( 'phone', 'billing', $value ); + } + + /** + * Set shipping first name. + * + * @param string $value Shipping first name. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_shipping_first_name( $value ) { + $this->set_address_prop( 'first_name', 'shipping', $value ); + } + + /** + * Set shipping last name. + * + * @param string $value Shipping last name. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_shipping_last_name( $value ) { + $this->set_address_prop( 'last_name', 'shipping', $value ); + } + + /** + * Set shipping company. + * + * @param string $value Shipping company. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_shipping_company( $value ) { + $this->set_address_prop( 'company', 'shipping', $value ); + } + + /** + * Set shipping address line 1. + * + * @param string $value Shipping address line 1. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_shipping_address_1( $value ) { + $this->set_address_prop( 'address_1', 'shipping', $value ); + } + + /** + * Set shipping address line 2. + * + * @param string $value Shipping address line 2. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_shipping_address_2( $value ) { + $this->set_address_prop( 'address_2', 'shipping', $value ); + } + + /** + * Set shipping city. + * + * @param string $value Shipping city. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_shipping_city( $value ) { + $this->set_address_prop( 'city', 'shipping', $value ); + } + + /** + * Set shipping state. + * + * @param string $value Shipping state. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_shipping_state( $value ) { + $this->set_address_prop( 'state', 'shipping', $value ); + } + + /** + * Set shipping postcode. + * + * @param string $value Shipping postcode. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_shipping_postcode( $value ) { + $this->set_address_prop( 'postcode', 'shipping', $value ); + } + + /** + * Set shipping country. + * + * @param string $value Shipping country. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_shipping_country( $value ) { + $this->set_address_prop( 'country', 'shipping', $value ); + } + + /** + * Set the payment method. + * + * @param string $payment_method Supports WC_Payment_Gateway for bw compatibility with < 3.0. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_payment_method( $payment_method = '' ) { + if ( is_object( $payment_method ) ) { + $this->set_payment_method( $payment_method->id ); + $this->set_payment_method_title( $payment_method->get_title() ); + } elseif ( '' === $payment_method ) { + $this->set_prop( 'payment_method', '' ); + $this->set_prop( 'payment_method_title', '' ); + } else { + $this->set_prop( 'payment_method', $payment_method ); + } + } + + /** + * Set payment method title. + * + * @param string $value Payment method title. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_payment_method_title( $value ) { + $this->set_prop( 'payment_method_title', $value ); + } + + /** + * Set transaction id. + * + * @param string $value Transaction id. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_transaction_id( $value ) { + $this->set_prop( 'transaction_id', $value ); + } + + /** + * Set customer ip address. + * + * @param string $value Customer ip address. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_customer_ip_address( $value ) { + $this->set_prop( 'customer_ip_address', $value ); + } + + /** + * Set customer user agent. + * + * @param string $value Customer user agent. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_customer_user_agent( $value ) { + $this->set_prop( 'customer_user_agent', $value ); + } + + /** + * Set created via. + * + * @param string $value Created via. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_created_via( $value ) { + $this->set_prop( 'created_via', $value ); + } + + /** + * Set customer note. + * + * @param string $value Customer note. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_customer_note( $value ) { + $this->set_prop( 'customer_note', $value ); + } + + /** + * Set date completed. + * + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_date_completed( $date = null ) { + $this->set_date_prop( 'date_completed', $date ); + } + + /** + * Set date paid. + * + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_date_paid( $date = null ) { + $this->set_date_prop( 'date_paid', $date ); + } + + /** + * Set cart hash. + * + * @param string $value Cart hash. + * @throws WC_Data_Exception Throws exception when invalid data is found. + */ + public function set_cart_hash( $value ) { + $this->set_prop( 'cart_hash', $value ); + } + + /* + |-------------------------------------------------------------------------- + | Conditionals + |-------------------------------------------------------------------------- + | + | Checks if a condition is true or false. + | + */ + + /** + * Check if an order key is valid. + * + * @param string $key Order key. + * @return bool + */ + public function key_is_valid( $key ) { + return hash_equals( $this->get_order_key(), $key ); + } + + /** + * See if order matches cart_hash. + * + * @param string $cart_hash Cart hash. + * @return bool + */ + public function has_cart_hash( $cart_hash = '' ) { + return hash_equals( $this->get_cart_hash(), $cart_hash ); // @codingStandardsIgnoreLine + } + + /** + * Checks if an order can be edited, specifically for use on the Edit Order screen. + * + * @return bool + */ + public function is_editable() { + return apply_filters( 'wc_order_is_editable', in_array( $this->get_status(), array( 'pending', 'on-hold', 'auto-draft' ), true ), $this ); + } + + /** + * Returns if an order has been paid for based on the order status. + * + * @since 2.5.0 + * @return bool + */ + public function is_paid() { + return apply_filters( 'woocommerce_order_is_paid', $this->has_status( wc_get_is_paid_statuses() ), $this ); + } + + /** + * Checks if product download is permitted. + * + * @return bool + */ + public function is_download_permitted() { + return apply_filters( 'woocommerce_order_is_download_permitted', $this->has_status( 'completed' ) || ( 'yes' === get_option( 'woocommerce_downloads_grant_access_after_payment' ) && $this->has_status( 'processing' ) ), $this ); + } + + /** + * Checks if an order needs display the shipping address, based on shipping method. + * + * @return bool + */ + public function needs_shipping_address() { + if ( 'no' === get_option( 'woocommerce_calc_shipping' ) ) { + return false; + } + + $hide = apply_filters( 'woocommerce_order_hide_shipping_address', array( 'local_pickup' ), $this ); + $needs_address = false; + + foreach ( $this->get_shipping_methods() as $shipping_method ) { + $shipping_method_id = $shipping_method->get_method_id(); + + if ( ! in_array( $shipping_method_id, $hide, true ) ) { + $needs_address = true; + break; + } + } + + return apply_filters( 'woocommerce_order_needs_shipping_address', $needs_address, $hide, $this ); + } + + /** + * Returns true if the order contains a downloadable product. + * + * @return bool + */ + public function has_downloadable_item() { + foreach ( $this->get_items() as $item ) { + if ( $item->is_type( 'line_item' ) ) { + $product = $item->get_product(); + + if ( $product && $product->has_file() ) { + return true; + } + } + } + return false; + } + + /** + * Get downloads from all line items for this order. + * + * @since 3.2.0 + * @return array + */ + public function get_downloadable_items() { + $downloads = array(); + + foreach ( $this->get_items() as $item ) { + if ( ! is_object( $item ) ) { + continue; + } + + // Check item refunds. + $refunded_qty = abs( $this->get_qty_refunded_for_item( $item->get_id() ) ); + if ( $refunded_qty && $item->get_quantity() === $refunded_qty ) { + continue; + } + + if ( $item->is_type( 'line_item' ) ) { + $item_downloads = $item->get_item_downloads(); + $product = $item->get_product(); + if ( $product && $item_downloads ) { + foreach ( $item_downloads as $file ) { + $downloads[] = array( + 'download_url' => $file['download_url'], + 'download_id' => $file['id'], + 'product_id' => $product->get_id(), + 'product_name' => $product->get_name(), + 'product_url' => $product->is_visible() ? $product->get_permalink() : '', // Since 3.3.0. + 'download_name' => $file['name'], + 'order_id' => $this->get_id(), + 'order_key' => $this->get_order_key(), + 'downloads_remaining' => $file['downloads_remaining'], + 'access_expires' => $file['access_expires'], + 'file' => array( + 'name' => $file['name'], + 'file' => $file['file'], + ), + ); + } + } + } + } + + return apply_filters( 'woocommerce_order_get_downloadable_items', $downloads, $this ); + } + + /** + * Checks if an order needs payment, based on status and order total. + * + * @return bool + */ + public function needs_payment() { + $valid_order_statuses = apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ), $this ); + return apply_filters( 'woocommerce_order_needs_payment', ( $this->has_status( $valid_order_statuses ) && $this->get_total() > 0 ), $this, $valid_order_statuses ); + } + + /** + * See if the order needs processing before it can be completed. + * + * Orders which only contain virtual, downloadable items do not need admin + * intervention. + * + * Uses a transient so these calls are not repeated multiple times, and because + * once the order is processed this code/transient does not need to persist. + * + * @since 3.0.0 + * @return bool + */ + public function needs_processing() { + $transient_name = 'wc_order_' . $this->get_id() . '_needs_processing'; + $needs_processing = get_transient( $transient_name ); + + if ( false === $needs_processing ) { + $needs_processing = 0; + + if ( count( $this->get_items() ) > 0 ) { + foreach ( $this->get_items() as $item ) { + if ( $item->is_type( 'line_item' ) ) { + $product = $item->get_product(); + + if ( ! $product ) { + continue; + } + + $virtual_downloadable_item = $product->is_downloadable() && $product->is_virtual(); + + if ( apply_filters( 'woocommerce_order_item_needs_processing', ! $virtual_downloadable_item, $product, $this->get_id() ) ) { + $needs_processing = 1; + break; + } + } + } + } + + set_transient( $transient_name, $needs_processing, DAY_IN_SECONDS ); + } + + return 1 === absint( $needs_processing ); + } + + /* + |-------------------------------------------------------------------------- + | URLs and Endpoints + |-------------------------------------------------------------------------- + */ + + /** + * Generates a URL so that a customer can pay for their (unpaid - pending) order. Pass 'true' for the checkout version which doesn't offer gateway choices. + * + * @param bool $on_checkout If on checkout. + * @return string + */ + public function get_checkout_payment_url( $on_checkout = false ) { + $pay_url = wc_get_endpoint_url( 'order-pay', $this->get_id(), wc_get_checkout_url() ); + + if ( $on_checkout ) { + $pay_url = add_query_arg( 'key', $this->get_order_key(), $pay_url ); + } else { + $pay_url = add_query_arg( + array( + 'pay_for_order' => 'true', + 'key' => $this->get_order_key(), + ), + $pay_url + ); + } + + return apply_filters( 'woocommerce_get_checkout_payment_url', $pay_url, $this ); + } + + /** + * Generates a URL for the thanks page (order received). + * + * @return string + */ + public function get_checkout_order_received_url() { + $order_received_url = wc_get_endpoint_url( 'order-received', $this->get_id(), wc_get_checkout_url() ); + $order_received_url = add_query_arg( 'key', $this->get_order_key(), $order_received_url ); + + return apply_filters( 'woocommerce_get_checkout_order_received_url', $order_received_url, $this ); + } + + /** + * Generates a URL so that a customer can cancel their (unpaid - pending) order. + * + * @param string $redirect Redirect URL. + * @return string + */ + public function get_cancel_order_url( $redirect = '' ) { + return apply_filters( + 'woocommerce_get_cancel_order_url', + wp_nonce_url( + add_query_arg( + array( + 'cancel_order' => 'true', + 'order' => $this->get_order_key(), + 'order_id' => $this->get_id(), + 'redirect' => $redirect, + ), + $this->get_cancel_endpoint() + ), + 'woocommerce-cancel_order' + ) + ); + } + + /** + * Generates a raw (unescaped) cancel-order URL for use by payment gateways. + * + * @param string $redirect Redirect URL. + * @return string The unescaped cancel-order URL. + */ + public function get_cancel_order_url_raw( $redirect = '' ) { + return apply_filters( + 'woocommerce_get_cancel_order_url_raw', + add_query_arg( + array( + 'cancel_order' => 'true', + 'order' => $this->get_order_key(), + 'order_id' => $this->get_id(), + 'redirect' => $redirect, + '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ), + ), + $this->get_cancel_endpoint() + ) + ); + } + + /** + * Helper method to return the cancel endpoint. + * + * @return string the cancel endpoint; either the cart page or the home page. + */ + public function get_cancel_endpoint() { + $cancel_endpoint = wc_get_cart_url(); + if ( ! $cancel_endpoint ) { + $cancel_endpoint = home_url(); + } + + if ( false === strpos( $cancel_endpoint, '?' ) ) { + $cancel_endpoint = trailingslashit( $cancel_endpoint ); + } + + return $cancel_endpoint; + } + + /** + * Generates a URL to view an order from the my account page. + * + * @return string + */ + public function get_view_order_url() { + return apply_filters( 'woocommerce_get_view_order_url', wc_get_endpoint_url( 'view-order', $this->get_id(), wc_get_page_permalink( 'myaccount' ) ), $this ); + } + + /** + * Get's the URL to edit the order in the backend. + * + * @since 3.3.0 + * @return string + */ + public function get_edit_order_url() { + return apply_filters( 'woocommerce_get_edit_order_url', get_admin_url( null, 'post.php?post=' . $this->get_id() . '&action=edit' ), $this ); + } + + /* + |-------------------------------------------------------------------------- + | Order notes. + |-------------------------------------------------------------------------- + */ + + /** + * Adds a note (comment) to the order. Order must exist. + * + * @param string $note Note to add. + * @param int $is_customer_note Is this a note for the customer?. + * @param bool $added_by_user Was the note added by a user?. + * @return int Comment ID. + */ + public function add_order_note( $note, $is_customer_note = 0, $added_by_user = false ) { + if ( ! $this->get_id() ) { + return 0; + } + + if ( is_user_logged_in() && current_user_can( 'edit_shop_orders', $this->get_id() ) && $added_by_user ) { + $user = get_user_by( 'id', get_current_user_id() ); + $comment_author = $user->display_name; + $comment_author_email = $user->user_email; + } else { + $comment_author = __( 'WooCommerce', 'woocommerce' ); + $comment_author_email = strtolower( __( 'WooCommerce', 'woocommerce' ) ) . '@'; + $comment_author_email .= isset( $_SERVER['HTTP_HOST'] ) ? str_replace( 'www.', '', sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) ) : 'noreply.com'; // WPCS: input var ok. + $comment_author_email = sanitize_email( $comment_author_email ); + } + $commentdata = apply_filters( + 'woocommerce_new_order_note_data', + array( + 'comment_post_ID' => $this->get_id(), + 'comment_author' => $comment_author, + 'comment_author_email' => $comment_author_email, + 'comment_author_url' => '', + 'comment_content' => $note, + 'comment_agent' => 'WooCommerce', + 'comment_type' => 'order_note', + 'comment_parent' => 0, + 'comment_approved' => 1, + ), + array( + 'order_id' => $this->get_id(), + 'is_customer_note' => $is_customer_note, + ) + ); + + $comment_id = wp_insert_comment( $commentdata ); + + if ( $is_customer_note ) { + add_comment_meta( $comment_id, 'is_customer_note', 1 ); + + do_action( + 'woocommerce_new_customer_note', + array( + 'order_id' => $this->get_id(), + 'customer_note' => $commentdata['comment_content'], + ) + ); + } + + /** + * Action hook fired after an order note is added. + * + * @param int $order_note_id Order note ID. + * @param WC_Order $order Order data. + * + * @since 4.4.0 + */ + do_action( 'woocommerce_order_note_added', $comment_id, $this ); + + return $comment_id; + } + + /** + * Add an order note for status transition + * + * @since 3.9.0 + * @uses WC_Order::add_order_note() + * @param string $note Note to be added giving status transition from and to details. + * @param bool $transition Details of the status transition. + * @return int Comment ID. + */ + private function add_status_transition_note( $note, $transition ) { + return $this->add_order_note( trim( $transition['note'] . ' ' . $note ), 0, $transition['manual'] ); + } + + /** + * List order notes (public) for the customer. + * + * @return array + */ + public function get_customer_order_notes() { + $notes = array(); + $args = array( + 'post_id' => $this->get_id(), + 'approve' => 'approve', + 'type' => '', + ); + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) ); + + $comments = get_comments( $args ); + + foreach ( $comments as $comment ) { + if ( ! get_comment_meta( $comment->comment_ID, 'is_customer_note', true ) ) { + continue; + } + $comment->comment_content = make_clickable( $comment->comment_content ); + $notes[] = $comment; + } + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) ); + + return $notes; + } + + /* + |-------------------------------------------------------------------------- + | Refunds + |-------------------------------------------------------------------------- + */ + + /** + * Get order refunds. + * + * @since 2.2 + * @return array of WC_Order_Refund objects + */ + public function get_refunds() { + $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'refunds' . $this->get_id(); + $cached_data = wp_cache_get( $cache_key, $this->cache_group ); + + if ( false !== $cached_data ) { + return $cached_data; + } + + $this->refunds = wc_get_orders( + array( + 'type' => 'shop_order_refund', + 'parent' => $this->get_id(), + 'limit' => -1, + ) + ); + + wp_cache_set( $cache_key, $this->refunds, $this->cache_group ); + + return $this->refunds; + } + + /** + * Get amount already refunded. + * + * @since 2.2 + * @return string + */ + public function get_total_refunded() { + $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'total_refunded' . $this->get_id(); + $cached_data = wp_cache_get( $cache_key, $this->cache_group ); + + if ( false !== $cached_data ) { + return $cached_data; + } + + $total_refunded = $this->data_store->get_total_refunded( $this ); + + wp_cache_set( $cache_key, $total_refunded, $this->cache_group ); + + return $total_refunded; + } + + /** + * Get the total tax refunded. + * + * @since 2.3 + * @return float + */ + public function get_total_tax_refunded() { + $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'total_tax_refunded' . $this->get_id(); + $cached_data = wp_cache_get( $cache_key, $this->cache_group ); + + if ( false !== $cached_data ) { + return $cached_data; + } + + $total_refunded = $this->data_store->get_total_tax_refunded( $this ); + + wp_cache_set( $cache_key, $total_refunded, $this->cache_group ); + + return $total_refunded; + } + + /** + * Get the total shipping refunded. + * + * @since 2.4 + * @return float + */ + public function get_total_shipping_refunded() { + $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'total_shipping_refunded' . $this->get_id(); + $cached_data = wp_cache_get( $cache_key, $this->cache_group ); + + if ( false !== $cached_data ) { + return $cached_data; + } + + $total_refunded = $this->data_store->get_total_shipping_refunded( $this ); + + wp_cache_set( $cache_key, $total_refunded, $this->cache_group ); + + return $total_refunded; + } + + /** + * Gets the count of order items of a certain type that have been refunded. + * + * @since 2.4.0 + * @param string $item_type Item type. + * @return string + */ + public function get_item_count_refunded( $item_type = '' ) { + if ( empty( $item_type ) ) { + $item_type = array( 'line_item' ); + } + if ( ! is_array( $item_type ) ) { + $item_type = array( $item_type ); + } + $count = 0; + + foreach ( $this->get_refunds() as $refund ) { + foreach ( $refund->get_items( $item_type ) as $refunded_item ) { + $count += abs( $refunded_item->get_quantity() ); + } + } + + return apply_filters( 'woocommerce_get_item_count_refunded', $count, $item_type, $this ); + } + + /** + * Get the total number of items refunded. + * + * @since 2.4.0 + * + * @param string $item_type Type of the item we're checking, if not a line_item. + * @return int + */ + public function get_total_qty_refunded( $item_type = 'line_item' ) { + $qty = 0; + foreach ( $this->get_refunds() as $refund ) { + foreach ( $refund->get_items( $item_type ) as $refunded_item ) { + $qty += $refunded_item->get_quantity(); + } + } + return $qty; + } + + /** + * Get the refunded amount for a line item. + * + * @param int $item_id ID of the item we're checking. + * @param string $item_type Type of the item we're checking, if not a line_item. + * @return int + */ + public function get_qty_refunded_for_item( $item_id, $item_type = 'line_item' ) { + $qty = 0; + foreach ( $this->get_refunds() as $refund ) { + foreach ( $refund->get_items( $item_type ) as $refunded_item ) { + if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) { + $qty += $refunded_item->get_quantity(); + } + } + } + return $qty; + } + + /** + * Get the refunded amount for a line item. + * + * @param int $item_id ID of the item we're checking. + * @param string $item_type Type of the item we're checking, if not a line_item. + * @return int + */ + public function get_total_refunded_for_item( $item_id, $item_type = 'line_item' ) { + $total = 0; + foreach ( $this->get_refunds() as $refund ) { + foreach ( $refund->get_items( $item_type ) as $refunded_item ) { + if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) { + $total += $refunded_item->get_total(); + } + } + } + return $total * -1; + } + + /** + * Get the refunded tax amount for a line item. + * + * @param int $item_id ID of the item we're checking. + * @param int $tax_id ID of the tax we're checking. + * @param string $item_type Type of the item we're checking, if not a line_item. + * @return double + */ + public function get_tax_refunded_for_item( $item_id, $tax_id, $item_type = 'line_item' ) { + $total = 0; + foreach ( $this->get_refunds() as $refund ) { + foreach ( $refund->get_items( $item_type ) as $refunded_item ) { + $refunded_item_id = (int) $refunded_item->get_meta( '_refunded_item_id' ); + if ( $refunded_item_id === $item_id ) { + $taxes = $refunded_item->get_taxes(); + $total += isset( $taxes['total'][ $tax_id ] ) ? (float) $taxes['total'][ $tax_id ] : 0; + break; + } + } + } + return wc_round_tax_total( $total ) * -1; + } + + /** + * Get total tax refunded by rate ID. + * + * @param int $rate_id Rate ID. + * @return float + */ + public function get_total_tax_refunded_by_rate_id( $rate_id ) { + $total = 0; + foreach ( $this->get_refunds() as $refund ) { + foreach ( $refund->get_items( 'tax' ) as $refunded_item ) { + if ( absint( $refunded_item->get_rate_id() ) === $rate_id ) { + $total += abs( $refunded_item->get_tax_total() ) + abs( $refunded_item->get_shipping_tax_total() ); + } + } + } + + return $total; + } + + /** + * How much money is left to refund? + * + * @return string + */ + public function get_remaining_refund_amount() { + return wc_format_decimal( $this->get_total() - $this->get_total_refunded(), wc_get_price_decimals() ); + } + + /** + * How many items are left to refund? + * + * @return int + */ + public function get_remaining_refund_items() { + return absint( $this->get_item_count() - $this->get_item_count_refunded() ); + } + + /** + * Add total row for the payment method. + * + * @param array $total_rows Total rows. + * @param string $tax_display Tax to display. + */ + protected function add_order_item_totals_payment_method_row( &$total_rows, $tax_display ) { + if ( $this->get_total() > 0 && $this->get_payment_method_title() && 'other' !== $this->get_payment_method_title() ) { + $total_rows['payment_method'] = array( + 'label' => __( 'Payment method:', 'woocommerce' ), + 'value' => $this->get_payment_method_title(), + ); + } + } + + /** + * Add total row for refunds. + * + * @param array $total_rows Total rows. + * @param string $tax_display Tax to display. + */ + protected function add_order_item_totals_refund_rows( &$total_rows, $tax_display ) { + $refunds = $this->get_refunds(); + if ( $refunds ) { + foreach ( $refunds as $id => $refund ) { + $total_rows[ 'refund_' . $id ] = array( + 'label' => $refund->get_reason() ? $refund->get_reason() : __( 'Refund', 'woocommerce' ) . ':', + 'value' => wc_price( '-' . $refund->get_amount(), array( 'currency' => $this->get_currency() ) ), + ); + } + } + } + + /** + * Get totals for display on pages and in emails. + * + * @param string $tax_display Tax to display. + * @return array + */ + public function get_order_item_totals( $tax_display = '' ) { + $tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); + $total_rows = array(); + + $this->add_order_item_totals_subtotal_row( $total_rows, $tax_display ); + $this->add_order_item_totals_discount_row( $total_rows, $tax_display ); + $this->add_order_item_totals_shipping_row( $total_rows, $tax_display ); + $this->add_order_item_totals_fee_rows( $total_rows, $tax_display ); + $this->add_order_item_totals_tax_rows( $total_rows, $tax_display ); + $this->add_order_item_totals_payment_method_row( $total_rows, $tax_display ); + $this->add_order_item_totals_refund_rows( $total_rows, $tax_display ); + $this->add_order_item_totals_total_row( $total_rows, $tax_display ); + + return apply_filters( 'woocommerce_get_order_item_totals', $total_rows, $this, $tax_display ); + } + + /** + * Check if order has been created via admin, checkout, or in another way. + * + * @since 4.0.0 + * @param string $modus Way of creating the order to test for. + * @return bool + */ + public function is_created_via( $modus ) { + return apply_filters( 'woocommerce_order_is_created_via', $modus === $this->get_created_via(), $this, $modus ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-payment-gateways.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-payment-gateways.php new file mode 100644 index 0000000..c6114ef --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -0,0 +1,222 @@ +init(); + } + + /** + * Load gateways and hook in functions. + */ + public function init() { + $load_gateways = array( + 'WC_Gateway_BACS', + 'WC_Gateway_Cheque', + 'WC_Gateway_COD', + 'WC_Gateway_Paypal', + ); + + // Filter. + $load_gateways = apply_filters( 'woocommerce_payment_gateways', $load_gateways ); + + // Get sort order option. + $ordering = (array) get_option( 'woocommerce_gateway_order' ); + $order_end = 999; + + // Load gateways in order. + foreach ( $load_gateways as $gateway ) { + if ( is_string( $gateway ) && class_exists( $gateway ) ) { + $gateway = new $gateway(); + } + + // Gateways need to be valid and extend WC_Payment_Gateway. + if ( ! is_a( $gateway, 'WC_Payment_Gateway' ) ) { + continue; + } + + if ( isset( $ordering[ $gateway->id ] ) && is_numeric( $ordering[ $gateway->id ] ) ) { + // Add in position. + $this->payment_gateways[ $ordering[ $gateway->id ] ] = $gateway; + } else { + // Add to end of the array. + $this->payment_gateways[ $order_end ] = $gateway; + $order_end++; + } + } + + ksort( $this->payment_gateways ); + } + + /** + * Get gateways. + * + * @return array + */ + public function payment_gateways() { + $_available_gateways = array(); + + if ( count( $this->payment_gateways ) > 0 ) { + foreach ( $this->payment_gateways as $gateway ) { + $_available_gateways[ $gateway->id ] = $gateway; + } + } + + return $_available_gateways; + } + + /** + * Get array of registered gateway ids + * + * @since 2.6.0 + * @return array of strings + */ + public function get_payment_gateway_ids() { + return wp_list_pluck( $this->payment_gateways, 'id' ); + } + + /** + * Get available gateways. + * + * @return array + */ + public function get_available_payment_gateways() { + $_available_gateways = array(); + + foreach ( $this->payment_gateways as $gateway ) { + if ( $gateway->is_available() ) { + if ( ! is_add_payment_method_page() ) { + $_available_gateways[ $gateway->id ] = $gateway; + } elseif ( $gateway->supports( 'add_payment_method' ) || $gateway->supports( 'tokenization' ) ) { + $_available_gateways[ $gateway->id ] = $gateway; + } + } + } + + return array_filter( (array) apply_filters( 'woocommerce_available_payment_gateways', $_available_gateways ), array( $this, 'filter_valid_gateway_class' ) ); + } + + /** + * Callback for array filter. Returns true if gateway is of correct type. + * + * @since 3.6.0 + * @param object $gateway Gateway to check. + * @return bool + */ + protected function filter_valid_gateway_class( $gateway ) { + return $gateway && is_a( $gateway, 'WC_Payment_Gateway' ); + } + + /** + * Set the current, active gateway. + * + * @param array $gateways Available payment gateways. + */ + public function set_current_gateway( $gateways ) { + // Be on the defensive. + if ( ! is_array( $gateways ) || empty( $gateways ) ) { + return; + } + + $current_gateway = false; + + if ( WC()->session ) { + $current = WC()->session->get( 'chosen_payment_method' ); + + if ( $current && isset( $gateways[ $current ] ) ) { + $current_gateway = $gateways[ $current ]; + } + } + + if ( ! $current_gateway ) { + $current_gateway = current( $gateways ); + } + + // Ensure we can make a call to set_current() without triggering an error. + if ( $current_gateway && is_callable( array( $current_gateway, 'set_current' ) ) ) { + $current_gateway->set_current(); + } + } + + /** + * Save options in admin. + */ + public function process_admin_options() { + $gateway_order = isset( $_POST['gateway_order'] ) ? wc_clean( wp_unslash( $_POST['gateway_order'] ) ) : ''; // WPCS: input var ok, CSRF ok. + $order = array(); + + if ( is_array( $gateway_order ) && count( $gateway_order ) > 0 ) { + $loop = 0; + foreach ( $gateway_order as $gateway_id ) { + $order[ esc_attr( $gateway_id ) ] = $loop; + $loop++; + } + } + + update_option( 'woocommerce_gateway_order', $order ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-payment-tokens.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-payment-tokens.php new file mode 100644 index 0000000..85625d0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-payment-tokens.php @@ -0,0 +1,234 @@ + '', + 'user_id' => '', + 'gateway_id' => '', + 'type' => '', + ) + ); + + $data_store = WC_Data_Store::load( 'payment-token' ); + $token_results = $data_store->get_tokens( $args ); + $tokens = array(); + + if ( ! empty( $token_results ) ) { + foreach ( $token_results as $token_result ) { + $_token = self::get( $token_result->token_id, $token_result ); + if ( ! empty( $_token ) ) { + $tokens[ $token_result->token_id ] = $_token; + } + } + } + + return $tokens; + } + + /** + * Returns an array of payment token objects associated with the passed customer ID. + * + * @since 2.6.0 + * @param int $customer_id Customer ID. + * @param string $gateway_id Optional Gateway ID for getting tokens for a specific gateway. + * @return WC_Payment_Token[] Array of token objects. + */ + public static function get_customer_tokens( $customer_id, $gateway_id = '' ) { + if ( $customer_id < 1 ) { + return array(); + } + + $tokens = self::get_tokens( + array( + 'user_id' => $customer_id, + 'gateway_id' => $gateway_id, + ) + ); + + return apply_filters( 'woocommerce_get_customer_payment_tokens', $tokens, $customer_id, $gateway_id ); + } + + /** + * Returns a customers default token or NULL if there is no default token. + * + * @since 2.6.0 + * @param int $customer_id Customer ID. + * @return WC_Payment_Token|null + */ + public static function get_customer_default_token( $customer_id ) { + if ( $customer_id < 1 ) { + return null; + } + + $data_store = WC_Data_Store::load( 'payment-token' ); + $token = $data_store->get_users_default_token( $customer_id ); + + if ( $token ) { + return self::get( $token->token_id, $token ); + } else { + return null; + } + } + + /** + * Returns an array of payment token objects associated with the passed order ID. + * + * @since 2.6.0 + * @param int $order_id Order ID. + * @return WC_Payment_Token[] Array of token objects. + */ + public static function get_order_tokens( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( ! $order ) { + return array(); + } + + $token_ids = $order->get_payment_tokens(); + + if ( empty( $token_ids ) ) { + return array(); + } + + $tokens = self::get_tokens( + array( + 'token_id' => $token_ids, + ) + ); + + return apply_filters( 'woocommerce_get_order_payment_tokens', $tokens, $order_id ); + } + + /** + * Get a token object by ID. + * + * @since 2.6.0 + * + * @param int $token_id Token ID. + * @param object $token_result Token result. + * @return null|WC_Payment_Token Returns a valid payment token or null if no token can be found. + */ + public static function get( $token_id, $token_result = null ) { + $data_store = WC_Data_Store::load( 'payment-token' ); + + if ( is_null( $token_result ) ) { + $token_result = $data_store->get_token_by_id( $token_id ); + // Still empty? Token doesn't exist? Don't continue. + if ( empty( $token_result ) ) { + return null; + } + } + + $token_class = self::get_token_classname( $token_result->type ); + + if ( class_exists( $token_class ) ) { + $meta = $data_store->get_metadata( $token_id ); + $passed_meta = array(); + if ( ! empty( $meta ) ) { + foreach ( $meta as $meta_key => $meta_value ) { + $passed_meta[ $meta_key ] = $meta_value[0]; + } + } + return new $token_class( $token_id, (array) $token_result, $passed_meta ); + } + + return null; + } + + /** + * Remove a payment token from the database by ID. + * + * @since 2.6.0 + * @param int $token_id Token ID. + */ + public static function delete( $token_id ) { + $type = self::get_token_type_by_id( $token_id ); + if ( ! empty( $type ) ) { + $class = self::get_token_classname( $type ); + $token = new $class( $token_id ); + $token->delete(); + } + } + + /** + * Loops through all of a users payment tokens and sets is_default to false for all but a specific token. + * + * @since 2.6.0 + * @param int $user_id User to set a default for. + * @param int $token_id The ID of the token that should be default. + */ + public static function set_users_default( $user_id, $token_id ) { + $data_store = WC_Data_Store::load( 'payment-token' ); + $users_tokens = self::get_customer_tokens( $user_id ); + foreach ( $users_tokens as $token ) { + if ( $token_id === $token->get_id() ) { + $data_store->set_default_status( $token->get_id(), true ); + do_action( 'woocommerce_payment_token_set_default', $token_id, $token ); + } else { + $data_store->set_default_status( $token->get_id(), false ); + } + } + } + + /** + * Returns what type (credit card, echeck, etc) of token a token is by ID. + * + * @since 2.6.0 + * @param int $token_id Token ID. + * @return string Type. + */ + public static function get_token_type_by_id( $token_id ) { + $data_store = WC_Data_Store::load( 'payment-token' ); + return $data_store->get_token_type_by_id( $token_id ); + } + + /** + * Get classname based on token type. + * + * @since 3.8.0 + * @param string $type Token type. + * @return string + */ + protected static function get_token_classname( $type ) { + /** + * Filter payment token class per type. + * + * @since 3.8.0 + * @param string $class Payment token class. + * @param string $type Token type. + */ + return apply_filters( 'woocommerce_payment_token_class', 'WC_Payment_Token_' . $type, $type ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-post-data.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-post-data.php new file mode 100644 index 0000000..39b89ba --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-post-data.php @@ -0,0 +1,533 @@ +ID, $post->post_type ) && 'product_variation' === $post->post_type ) { + $variation = wc_get_product( $post->ID ); + + if ( $variation && $variation->get_parent_id() ) { + return $variation->get_permalink(); + } + } + return $permalink; + } + + /** + * Sync products queued to sync. + */ + public static function do_deferred_product_sync() { + global $wc_deferred_product_sync; + + if ( ! empty( $wc_deferred_product_sync ) ) { + $wc_deferred_product_sync = wp_parse_id_list( $wc_deferred_product_sync ); + array_walk( $wc_deferred_product_sync, array( __CLASS__, 'deferred_product_sync' ) ); + } + } + + /** + * Sync a product. + * + * @param int $product_id Product ID. + */ + public static function deferred_product_sync( $product_id ) { + $product = wc_get_product( $product_id ); + + if ( is_callable( array( $product, 'sync' ) ) ) { + $product->sync( $product ); + } + } + + /** + * When a post status changes. + * + * @param string $new_status New status. + * @param string $old_status Old status. + * @param WP_Post $post Post data. + */ + public static function transition_post_status( $new_status, $old_status, $post ) { + if ( ( 'publish' === $new_status || 'publish' === $old_status ) && in_array( $post->post_type, array( 'product', 'product_variation' ), true ) ) { + self::delete_product_query_transients(); + } + } + + /** + * Delete product view transients when needed e.g. when post status changes, or visibility/stock status is modified. + */ + public static function delete_product_query_transients() { + WC_Cache_Helper::get_transient_version( 'product_query', true ); + } + + /** + * Handle type changes. + * + * @since 3.0.0 + * @param WC_Product $product Product data. + * @param string $from Origin type. + * @param string $to New type. + */ + public static function product_type_changed( $product, $from, $to ) { + if ( 'variable' === $from && 'variable' !== $to ) { + // If the product is no longer variable, we should ensure all variations are removed. + $data_store = WC_Data_Store::load( 'product-variable' ); + $data_store->delete_variations( $product->get_id(), true ); + } + } + + /** + * When editing a term, check for product attributes. + * + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param string $taxonomy Taxonomy slug. + */ + public static function edit_term( $term_id, $tt_id, $taxonomy ) { + if ( strpos( $taxonomy, 'pa_' ) === 0 ) { + self::$editing_term = get_term_by( 'id', $term_id, $taxonomy ); + } else { + self::$editing_term = null; + } + } + + /** + * When a term is edited, check for product attributes and update variations. + * + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param string $taxonomy Taxonomy slug. + */ + public static function edited_term( $term_id, $tt_id, $taxonomy ) { + if ( ! is_null( self::$editing_term ) && strpos( $taxonomy, 'pa_' ) === 0 ) { + $edited_term = get_term_by( 'id', $term_id, $taxonomy ); + + if ( $edited_term->slug !== self::$editing_term->slug ) { + global $wpdb; + + $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND meta_value = %s;", $edited_term->slug, 'attribute_' . sanitize_title( $taxonomy ), self::$editing_term->slug ) ); + + $wpdb->query( + $wpdb->prepare( + "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE( meta_value, %s, %s ) WHERE meta_key = '_default_attributes'", + serialize( self::$editing_term->taxonomy ) . serialize( self::$editing_term->slug ), + serialize( $edited_term->taxonomy ) . serialize( $edited_term->slug ) + ) + ); + } + } else { + self::$editing_term = null; + } + } + + /** + * Ensure floats are correctly converted to strings based on PHP locale. + * + * @param null $check Whether to allow updating metadata for the given type. + * @param int $object_id Object ID. + * @param string $meta_key Meta key. + * @param mixed $meta_value Meta value. Must be serializable if non-scalar. + * @param mixed $prev_value If specified, only update existing metadata entries with the specified value. Otherwise, update all entries. + * @return null|bool + */ + public static function update_order_item_metadata( $check, $object_id, $meta_key, $meta_value, $prev_value ) { + if ( ! empty( $meta_value ) && is_float( $meta_value ) ) { + + // Convert float to string. + $meta_value = wc_float_to_string( $meta_value ); + + // Update meta value with new string. + update_metadata( 'order_item', $object_id, $meta_key, $meta_value, $prev_value ); + + return true; + } + return $check; + } + + /** + * Ensure floats are correctly converted to strings based on PHP locale. + * + * @param null $check Whether to allow updating metadata for the given type. + * @param int $object_id Object ID. + * @param string $meta_key Meta key. + * @param mixed $meta_value Meta value. Must be serializable if non-scalar. + * @param mixed $prev_value If specified, only update existing metadata entries with the specified value. Otherwise, update all entries. + * @return null|bool + */ + public static function update_post_metadata( $check, $object_id, $meta_key, $meta_value, $prev_value ) { + // Delete product cache if someone uses meta directly. + if ( in_array( get_post_type( $object_id ), array( 'product', 'product_variation' ), true ) ) { + wp_cache_delete( 'product-' . $object_id, 'products' ); + } + + if ( ! empty( $meta_value ) && is_float( $meta_value ) && ! registered_meta_key_exists( 'post', $meta_key ) && in_array( get_post_type( $object_id ), array_merge( wc_get_order_types(), array( 'shop_coupon', 'product', 'product_variation' ) ), true ) ) { + + // Convert float to string. + $meta_value = wc_float_to_string( $meta_value ); + + // Update meta value with new string. + update_metadata( 'post', $object_id, $meta_key, $meta_value, $prev_value ); + + return true; + } + return $check; + } + + /** + * Forces the order posts to have a title in a certain format (containing the date). + * Forces certain product data based on the product's type, e.g. grouped products cannot have a parent. + * + * @param array $data An array of slashed post data. + * @return array + */ + public static function wp_insert_post_data( $data ) { + if ( 'shop_order' === $data['post_type'] && isset( $data['post_date'] ) ) { + $order_title = 'Order'; + if ( $data['post_date'] ) { + $order_title .= ' – ' . date_i18n( 'F j, Y @ h:i A', strtotime( $data['post_date'] ) ); + } + $data['post_title'] = $order_title; + } elseif ( 'product' === $data['post_type'] && isset( $_POST['product-type'] ) ) { // WPCS: input var ok, CSRF ok. + $product_type = wc_clean( wp_unslash( $_POST['product-type'] ) ); // WPCS: input var ok, CSRF ok. + switch ( $product_type ) { + case 'grouped': + case 'variable': + $data['post_parent'] = 0; + break; + } + } elseif ( 'product' === $data['post_type'] && 'auto-draft' === $data['post_status'] ) { + $data['post_title'] = 'AUTO-DRAFT'; + } elseif ( 'shop_coupon' === $data['post_type'] ) { + // Coupons should never allow unfiltered HTML. + $data['post_title'] = wp_filter_kses( $data['post_title'] ); + } + + return $data; + } + + /** + * Change embed data for certain post types. + * + * @since 3.2.0 + * @param array $data The response data. + * @param WP_Post $post The post object. + * @return array + */ + public static function filter_oembed_response_data( $data, $post ) { + if ( in_array( $post->post_type, array( 'shop_order', 'shop_coupon' ), true ) ) { + return array(); + } + return $data; + } + + /** + * Removes variations etc belonging to a deleted post, and clears transients. + * + * @param mixed $id ID of post being deleted. + */ + public static function delete_post( $id ) { + if ( ! current_user_can( 'delete_posts' ) || ! $id ) { + return; + } + + $post_type = get_post_type( $id ); + + switch ( $post_type ) { + case 'product': + $data_store = WC_Data_Store::load( 'product-variable' ); + $data_store->delete_variations( $id, true ); + $data_store->delete_from_lookup_table( $id, 'wc_product_meta_lookup' ); + $parent_id = wp_get_post_parent_id( $id ); + + if ( $parent_id ) { + wc_delete_product_transients( $parent_id ); + } + break; + case 'product_variation': + $data_store = WC_Data_Store::load( 'product' ); + $data_store->delete_from_lookup_table( $id, 'wc_product_meta_lookup' ); + wc_delete_product_transients( wp_get_post_parent_id( $id ) ); + break; + case 'shop_order': + global $wpdb; + + $refunds = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type = 'shop_order_refund' AND post_parent = %d", $id ) ); + + if ( ! is_null( $refunds ) ) { + foreach ( $refunds as $refund ) { + wp_delete_post( $refund->ID, true ); + } + } + break; + } + } + + /** + * Trash post. + * + * @param mixed $id Post ID. + */ + public static function trash_post( $id ) { + if ( ! $id ) { + return; + } + + $post_type = get_post_type( $id ); + + // If this is an order, trash any refunds too. + if ( in_array( $post_type, wc_get_order_types( 'order-count' ), true ) ) { + global $wpdb; + + $refunds = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type = 'shop_order_refund' AND post_parent = %d", $id ) ); + + foreach ( $refunds as $refund ) { + $wpdb->update( $wpdb->posts, array( 'post_status' => 'trash' ), array( 'ID' => $refund->ID ) ); + } + + wc_delete_shop_order_transients( $id ); + + // If this is a product, trash children variations. + } elseif ( 'product' === $post_type ) { + $data_store = WC_Data_Store::load( 'product-variable' ); + $data_store->delete_variations( $id, false ); + } + } + + /** + * Untrash post. + * + * @param mixed $id Post ID. + */ + public static function untrash_post( $id ) { + if ( ! $id ) { + return; + } + + $post_type = get_post_type( $id ); + + if ( in_array( $post_type, wc_get_order_types( 'order-count' ), true ) ) { + global $wpdb; + + $refunds = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type = 'shop_order_refund' AND post_parent = %d", $id ) ); + + foreach ( $refunds as $refund ) { + $wpdb->update( $wpdb->posts, array( 'post_status' => 'wc-completed' ), array( 'ID' => $refund->ID ) ); + } + + wc_delete_shop_order_transients( $id ); + + } elseif ( 'product' === $post_type ) { + $data_store = WC_Data_Store::load( 'product-variable' ); + $data_store->untrash_variations( $id ); + + wc_product_force_unique_sku( $id ); + } + } + + /** + * Before deleting an order, do some cleanup. + * + * @since 3.2.0 + * @param int $order_id Order ID. + */ + public static function before_delete_order( $order_id ) { + if ( in_array( get_post_type( $order_id ), wc_get_order_types(), true ) ) { + // Clean up user. + $order = wc_get_order( $order_id ); + + // Check for `get_customer_id`, since this may be e.g. a refund order (which doesn't implement it). + $customer_id = is_callable( array( $order, 'get_customer_id' ) ) ? $order->get_customer_id() : 0; + + if ( $customer_id > 0 && 'shop_order' === $order->get_type() ) { + $customer = new WC_Customer( $customer_id ); + $order_count = $customer->get_order_count(); + $order_count --; + + if ( 0 === $order_count ) { + $customer->set_is_paying_customer( false ); + $customer->save(); + } + + // Delete order count meta. + delete_user_meta( $customer_id, '_order_count' ); + } + + // Clean up items. + self::delete_order_items( $order_id ); + self::delete_order_downloadable_permissions( $order_id ); + } + } + + /** + * Remove item meta on permanent deletion. + * + * @param int $postid Post ID. + */ + public static function delete_order_items( $postid ) { + global $wpdb; + + if ( in_array( get_post_type( $postid ), wc_get_order_types(), true ) ) { + do_action( 'woocommerce_delete_order_items', $postid ); + + $wpdb->query( + " + DELETE {$wpdb->prefix}woocommerce_order_items, {$wpdb->prefix}woocommerce_order_itemmeta + FROM {$wpdb->prefix}woocommerce_order_items + JOIN {$wpdb->prefix}woocommerce_order_itemmeta ON {$wpdb->prefix}woocommerce_order_items.order_item_id = {$wpdb->prefix}woocommerce_order_itemmeta.order_item_id + WHERE {$wpdb->prefix}woocommerce_order_items.order_id = '{$postid}'; + " + ); // WPCS: unprepared SQL ok. + + do_action( 'woocommerce_deleted_order_items', $postid ); + } + } + + /** + * Remove downloadable permissions on permanent order deletion. + * + * @param int $postid Post ID. + */ + public static function delete_order_downloadable_permissions( $postid ) { + if ( in_array( get_post_type( $postid ), wc_get_order_types(), true ) ) { + do_action( 'woocommerce_delete_order_downloadable_permissions', $postid ); + + $data_store = WC_Data_Store::load( 'customer-download' ); + $data_store->delete_by_order_id( $postid ); + + do_action( 'woocommerce_deleted_order_downloadable_permissions', $postid ); + } + } + + /** + * Flush meta cache for CRUD objects on direct update. + * + * @param int $meta_id Meta ID. + * @param int $object_id Object ID. + * @param string $meta_key Meta key. + * @param string $meta_value Meta value. + */ + public static function flush_object_meta_cache( $meta_id, $object_id, $meta_key, $meta_value ) { + WC_Cache_Helper::invalidate_cache_group( 'object_' . $object_id ); + } + + /** + * Ensure default category gets set. + * + * @since 3.3.0 + * @param int $object_id Product ID. + * @param array $terms Terms array. + * @param array $tt_ids Term ids array. + * @param string $taxonomy Taxonomy name. + * @param bool $append Are we appending or setting terms. + */ + public static function force_default_term( $object_id, $terms, $tt_ids, $taxonomy, $append ) { + if ( ! $append && 'product_cat' === $taxonomy && empty( $tt_ids ) && 'product' === get_post_type( $object_id ) ) { + $default_term = absint( get_option( 'default_product_cat', 0 ) ); + $tt_ids = array_map( 'absint', $tt_ids ); + + if ( $default_term && ! in_array( $default_term, $tt_ids, true ) ) { + wp_set_post_terms( $object_id, array( $default_term ), 'product_cat', true ); + } + } + } + + /** + * When setting stock level, ensure the stock status is kept in sync. + * + * @param int $meta_id Meta ID. + * @param int $object_id Object ID. + * @param string $meta_key Meta key. + * @param mixed $meta_value Meta value. + * @deprecated 3.3 + */ + public static function sync_product_stock_status( $meta_id, $object_id, $meta_key, $meta_value ) {} + + /** + * Update changed downloads. + * + * @deprecated 3.3.0 No action is necessary on changes to download paths since download_id is no longer based on file hash. + * @param int $product_id Product ID. + * @param int $variation_id Variation ID. Optional product variation identifier. + * @param array $downloads Newly set files. + */ + public static function process_product_file_download_paths( $product_id, $variation_id, $downloads ) { + wc_deprecated_function( __FUNCTION__, '3.3' ); + } + + /** + * Delete transients when terms are set. + * + * @deprecated 3.6 + * @param int $object_id Object ID. + * @param mixed $terms An array of object terms. + * @param array $tt_ids An array of term taxonomy IDs. + * @param string $taxonomy Taxonomy slug. + * @param mixed $append Whether to append new terms to the old terms. + * @param array $old_tt_ids Old array of term taxonomy IDs. + */ + public static function set_object_terms( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) { + if ( in_array( get_post_type( $object_id ), array( 'product', 'product_variation' ), true ) ) { + self::delete_product_query_transients(); + } + } +} + +WC_Post_Data::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-post-types.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-post-types.php new file mode 100644 index 0000000..2a2255b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-post-types.php @@ -0,0 +1,676 @@ + false, + 'show_ui' => false, + 'show_in_nav_menus' => false, + 'query_var' => is_admin(), + 'rewrite' => false, + 'public' => false, + 'label' => _x( 'Product type', 'Taxonomy name', 'woocommerce' ), + ) + ) + ); + + register_taxonomy( + 'product_visibility', + apply_filters( 'woocommerce_taxonomy_objects_product_visibility', array( 'product', 'product_variation' ) ), + apply_filters( + 'woocommerce_taxonomy_args_product_visibility', + array( + 'hierarchical' => false, + 'show_ui' => false, + 'show_in_nav_menus' => false, + 'query_var' => is_admin(), + 'rewrite' => false, + 'public' => false, + 'label' => _x( 'Product visibility', 'Taxonomy name', 'woocommerce' ), + ) + ) + ); + + register_taxonomy( + 'product_cat', + apply_filters( 'woocommerce_taxonomy_objects_product_cat', array( 'product' ) ), + apply_filters( + 'woocommerce_taxonomy_args_product_cat', + array( + 'hierarchical' => true, + 'update_count_callback' => '_wc_term_recount', + 'label' => __( 'Categories', 'woocommerce' ), + 'labels' => array( + 'name' => __( 'Product categories', 'woocommerce' ), + 'singular_name' => __( 'Category', 'woocommerce' ), + 'menu_name' => _x( 'Categories', 'Admin menu name', 'woocommerce' ), + 'search_items' => __( 'Search categories', 'woocommerce' ), + 'all_items' => __( 'All categories', 'woocommerce' ), + 'parent_item' => __( 'Parent category', 'woocommerce' ), + 'parent_item_colon' => __( 'Parent category:', 'woocommerce' ), + 'edit_item' => __( 'Edit category', 'woocommerce' ), + 'update_item' => __( 'Update category', 'woocommerce' ), + 'add_new_item' => __( 'Add new category', 'woocommerce' ), + 'new_item_name' => __( 'New category name', 'woocommerce' ), + 'not_found' => __( 'No categories found', 'woocommerce' ), + ), + 'show_ui' => true, + 'query_var' => true, + 'capabilities' => array( + 'manage_terms' => 'manage_product_terms', + 'edit_terms' => 'edit_product_terms', + 'delete_terms' => 'delete_product_terms', + 'assign_terms' => 'assign_product_terms', + ), + 'rewrite' => array( + 'slug' => $permalinks['category_rewrite_slug'], + 'with_front' => false, + 'hierarchical' => true, + ), + ) + ) + ); + + register_taxonomy( + 'product_tag', + apply_filters( 'woocommerce_taxonomy_objects_product_tag', array( 'product' ) ), + apply_filters( + 'woocommerce_taxonomy_args_product_tag', + array( + 'hierarchical' => false, + 'update_count_callback' => '_wc_term_recount', + 'label' => __( 'Product tags', 'woocommerce' ), + 'labels' => array( + 'name' => __( 'Product tags', 'woocommerce' ), + 'singular_name' => __( 'Tag', 'woocommerce' ), + 'menu_name' => _x( 'Tags', 'Admin menu name', 'woocommerce' ), + 'search_items' => __( 'Search tags', 'woocommerce' ), + 'all_items' => __( 'All tags', 'woocommerce' ), + 'edit_item' => __( 'Edit tag', 'woocommerce' ), + 'update_item' => __( 'Update tag', 'woocommerce' ), + 'add_new_item' => __( 'Add new tag', 'woocommerce' ), + 'new_item_name' => __( 'New tag name', 'woocommerce' ), + 'popular_items' => __( 'Popular tags', 'woocommerce' ), + 'separate_items_with_commas' => __( 'Separate tags with commas', 'woocommerce' ), + 'add_or_remove_items' => __( 'Add or remove tags', 'woocommerce' ), + 'choose_from_most_used' => __( 'Choose from the most used tags', 'woocommerce' ), + 'not_found' => __( 'No tags found', 'woocommerce' ), + ), + 'show_ui' => true, + 'query_var' => true, + 'capabilities' => array( + 'manage_terms' => 'manage_product_terms', + 'edit_terms' => 'edit_product_terms', + 'delete_terms' => 'delete_product_terms', + 'assign_terms' => 'assign_product_terms', + ), + 'rewrite' => array( + 'slug' => $permalinks['tag_rewrite_slug'], + 'with_front' => false, + ), + ) + ) + ); + + register_taxonomy( + 'product_shipping_class', + apply_filters( 'woocommerce_taxonomy_objects_product_shipping_class', array( 'product', 'product_variation' ) ), + apply_filters( + 'woocommerce_taxonomy_args_product_shipping_class', + array( + 'hierarchical' => false, + 'update_count_callback' => '_update_post_term_count', + 'label' => __( 'Shipping classes', 'woocommerce' ), + 'labels' => array( + 'name' => __( 'Product shipping classes', 'woocommerce' ), + 'singular_name' => __( 'Shipping class', 'woocommerce' ), + 'menu_name' => _x( 'Shipping classes', 'Admin menu name', 'woocommerce' ), + 'search_items' => __( 'Search shipping classes', 'woocommerce' ), + 'all_items' => __( 'All shipping classes', 'woocommerce' ), + 'parent_item' => __( 'Parent shipping class', 'woocommerce' ), + 'parent_item_colon' => __( 'Parent shipping class:', 'woocommerce' ), + 'edit_item' => __( 'Edit shipping class', 'woocommerce' ), + 'update_item' => __( 'Update shipping class', 'woocommerce' ), + 'add_new_item' => __( 'Add new shipping class', 'woocommerce' ), + 'new_item_name' => __( 'New shipping class Name', 'woocommerce' ), + ), + 'show_ui' => false, + 'show_in_quick_edit' => false, + 'show_in_nav_menus' => false, + 'query_var' => is_admin(), + 'capabilities' => array( + 'manage_terms' => 'manage_product_terms', + 'edit_terms' => 'edit_product_terms', + 'delete_terms' => 'delete_product_terms', + 'assign_terms' => 'assign_product_terms', + ), + 'rewrite' => false, + ) + ) + ); + + global $wc_product_attributes; + + $wc_product_attributes = array(); + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + if ( $attribute_taxonomies ) { + foreach ( $attribute_taxonomies as $tax ) { + $name = wc_attribute_taxonomy_name( $tax->attribute_name ); + + if ( $name ) { + $tax->attribute_public = absint( isset( $tax->attribute_public ) ? $tax->attribute_public : 1 ); + $label = ! empty( $tax->attribute_label ) ? $tax->attribute_label : $tax->attribute_name; + $wc_product_attributes[ $name ] = $tax; + $taxonomy_data = array( + 'hierarchical' => false, + 'update_count_callback' => '_update_post_term_count', + 'labels' => array( + /* translators: %s: attribute name */ + 'name' => sprintf( _x( 'Product %s', 'Product Attribute', 'woocommerce' ), $label ), + 'singular_name' => $label, + /* translators: %s: attribute name */ + 'search_items' => sprintf( __( 'Search %s', 'woocommerce' ), $label ), + /* translators: %s: attribute name */ + 'all_items' => sprintf( __( 'All %s', 'woocommerce' ), $label ), + /* translators: %s: attribute name */ + 'parent_item' => sprintf( __( 'Parent %s', 'woocommerce' ), $label ), + /* translators: %s: attribute name */ + 'parent_item_colon' => sprintf( __( 'Parent %s:', 'woocommerce' ), $label ), + /* translators: %s: attribute name */ + 'edit_item' => sprintf( __( 'Edit %s', 'woocommerce' ), $label ), + /* translators: %s: attribute name */ + 'update_item' => sprintf( __( 'Update %s', 'woocommerce' ), $label ), + /* translators: %s: attribute name */ + 'add_new_item' => sprintf( __( 'Add new %s', 'woocommerce' ), $label ), + /* translators: %s: attribute name */ + 'new_item_name' => sprintf( __( 'New %s', 'woocommerce' ), $label ), + /* translators: %s: attribute name */ + 'not_found' => sprintf( __( 'No "%s" found', 'woocommerce' ), $label ), + /* translators: %s: attribute name */ + 'back_to_items' => sprintf( __( '← Back to "%s" attributes', 'woocommerce' ), $label ), + ), + 'show_ui' => true, + 'show_in_quick_edit' => false, + 'show_in_menu' => false, + 'meta_box_cb' => false, + 'query_var' => 1 === $tax->attribute_public, + 'rewrite' => false, + 'sort' => false, + 'public' => 1 === $tax->attribute_public, + 'show_in_nav_menus' => 1 === $tax->attribute_public && apply_filters( 'woocommerce_attribute_show_in_nav_menus', false, $name ), + 'capabilities' => array( + 'manage_terms' => 'manage_product_terms', + 'edit_terms' => 'edit_product_terms', + 'delete_terms' => 'delete_product_terms', + 'assign_terms' => 'assign_product_terms', + ), + ); + + if ( 1 === $tax->attribute_public && sanitize_title( $tax->attribute_name ) ) { + $taxonomy_data['rewrite'] = array( + 'slug' => trailingslashit( $permalinks['attribute_rewrite_slug'] ) . sanitize_title( $tax->attribute_name ), + 'with_front' => false, + 'hierarchical' => true, + ); + } + + register_taxonomy( $name, apply_filters( "woocommerce_taxonomy_objects_{$name}", array( 'product' ) ), apply_filters( "woocommerce_taxonomy_args_{$name}", $taxonomy_data ) ); + } + } + } + + do_action( 'woocommerce_after_register_taxonomy' ); + } + + /** + * Register core post types. + */ + public static function register_post_types() { + if ( ! is_blog_installed() || post_type_exists( 'product' ) ) { + return; + } + + do_action( 'woocommerce_register_post_type' ); + + $permalinks = wc_get_permalink_structure(); + $supports = array( 'title', 'editor', 'excerpt', 'thumbnail', 'custom-fields', 'publicize', 'wpcom-markdown' ); + + if ( 'yes' === get_option( 'woocommerce_enable_reviews', 'yes' ) ) { + $supports[] = 'comments'; + } + + $shop_page_id = wc_get_page_id( 'shop' ); + + if ( current_theme_supports( 'woocommerce' ) ) { + $has_archive = $shop_page_id && get_post( $shop_page_id ) ? urldecode( get_page_uri( $shop_page_id ) ) : 'shop'; + } else { + $has_archive = false; + } + + // If theme support changes, we may need to flush permalinks since some are changed based on this flag. + $theme_support = current_theme_supports( 'woocommerce' ) ? 'yes' : 'no'; + if ( get_option( 'current_theme_supports_woocommerce' ) !== $theme_support && update_option( 'current_theme_supports_woocommerce', $theme_support ) ) { + update_option( 'woocommerce_queue_flush_rewrite_rules', 'yes' ); + } + + register_post_type( + 'product', + apply_filters( + 'woocommerce_register_post_type_product', + array( + 'labels' => array( + 'name' => __( 'Products', 'woocommerce' ), + 'singular_name' => __( 'Product', 'woocommerce' ), + 'all_items' => __( 'All Products', 'woocommerce' ), + 'menu_name' => _x( 'Products', 'Admin menu name', 'woocommerce' ), + 'add_new' => __( 'Add New', 'woocommerce' ), + 'add_new_item' => __( 'Add new product', 'woocommerce' ), + 'edit' => __( 'Edit', 'woocommerce' ), + 'edit_item' => __( 'Edit product', 'woocommerce' ), + 'new_item' => __( 'New product', 'woocommerce' ), + 'view_item' => __( 'View product', 'woocommerce' ), + 'view_items' => __( 'View products', 'woocommerce' ), + 'search_items' => __( 'Search products', 'woocommerce' ), + 'not_found' => __( 'No products found', 'woocommerce' ), + 'not_found_in_trash' => __( 'No products found in trash', 'woocommerce' ), + 'parent' => __( 'Parent product', 'woocommerce' ), + 'featured_image' => __( 'Product image', 'woocommerce' ), + 'set_featured_image' => __( 'Set product image', 'woocommerce' ), + 'remove_featured_image' => __( 'Remove product image', 'woocommerce' ), + 'use_featured_image' => __( 'Use as product image', 'woocommerce' ), + 'insert_into_item' => __( 'Insert into product', 'woocommerce' ), + 'uploaded_to_this_item' => __( 'Uploaded to this product', 'woocommerce' ), + 'filter_items_list' => __( 'Filter products', 'woocommerce' ), + 'items_list_navigation' => __( 'Products navigation', 'woocommerce' ), + 'items_list' => __( 'Products list', 'woocommerce' ), + ), + 'description' => __( 'This is where you can add new products to your store.', 'woocommerce' ), + 'public' => true, + 'show_ui' => true, + 'capability_type' => 'product', + 'map_meta_cap' => true, + 'publicly_queryable' => true, + 'exclude_from_search' => false, + 'hierarchical' => false, // Hierarchical causes memory issues - WP loads all records! + 'rewrite' => $permalinks['product_rewrite_slug'] ? array( + 'slug' => $permalinks['product_rewrite_slug'], + 'with_front' => false, + 'feeds' => true, + ) : false, + 'query_var' => true, + 'supports' => $supports, + 'has_archive' => $has_archive, + 'show_in_nav_menus' => true, + 'show_in_rest' => true, + ) + ) + ); + + register_post_type( + 'product_variation', + apply_filters( + 'woocommerce_register_post_type_product_variation', + array( + 'label' => __( 'Variations', 'woocommerce' ), + 'public' => false, + 'hierarchical' => false, + 'supports' => false, + 'capability_type' => 'product', + 'rewrite' => false, + ) + ) + ); + + wc_register_order_type( + 'shop_order', + apply_filters( + 'woocommerce_register_post_type_shop_order', + array( + 'labels' => array( + 'name' => __( 'Orders', 'woocommerce' ), + 'singular_name' => _x( 'Order', 'shop_order post type singular name', 'woocommerce' ), + 'add_new' => __( 'Add order', 'woocommerce' ), + 'add_new_item' => __( 'Add new order', 'woocommerce' ), + 'edit' => __( 'Edit', 'woocommerce' ), + 'edit_item' => __( 'Edit order', 'woocommerce' ), + 'new_item' => __( 'New order', 'woocommerce' ), + 'view_item' => __( 'View order', 'woocommerce' ), + 'search_items' => __( 'Search orders', 'woocommerce' ), + 'not_found' => __( 'No orders found', 'woocommerce' ), + 'not_found_in_trash' => __( 'No orders found in trash', 'woocommerce' ), + 'parent' => __( 'Parent orders', 'woocommerce' ), + 'menu_name' => _x( 'Orders', 'Admin menu name', 'woocommerce' ), + 'filter_items_list' => __( 'Filter orders', 'woocommerce' ), + 'items_list_navigation' => __( 'Orders navigation', 'woocommerce' ), + 'items_list' => __( 'Orders list', 'woocommerce' ), + ), + 'description' => __( 'This is where store orders are stored.', 'woocommerce' ), + 'public' => false, + 'show_ui' => true, + 'capability_type' => 'shop_order', + 'map_meta_cap' => true, + 'publicly_queryable' => false, + 'exclude_from_search' => true, + 'show_in_menu' => current_user_can( 'edit_others_shop_orders' ) ? 'woocommerce' : true, + 'hierarchical' => false, + 'show_in_nav_menus' => false, + 'rewrite' => false, + 'query_var' => false, + 'supports' => array( 'title', 'comments', 'custom-fields' ), + 'has_archive' => false, + ) + ) + ); + + wc_register_order_type( + 'shop_order_refund', + apply_filters( + 'woocommerce_register_post_type_shop_order_refund', + array( + 'label' => __( 'Refunds', 'woocommerce' ), + 'capability_type' => 'shop_order', + 'public' => false, + 'hierarchical' => false, + 'supports' => false, + 'exclude_from_orders_screen' => false, + 'add_order_meta_boxes' => false, + 'exclude_from_order_count' => true, + 'exclude_from_order_views' => false, + 'exclude_from_order_reports' => false, + 'exclude_from_order_sales_reports' => true, + 'class_name' => 'WC_Order_Refund', + 'rewrite' => false, + ) + ) + ); + + if ( 'yes' === get_option( 'woocommerce_enable_coupons' ) ) { + register_post_type( + 'shop_coupon', + apply_filters( + 'woocommerce_register_post_type_shop_coupon', + array( + 'labels' => array( + 'name' => __( 'Coupons', 'woocommerce' ), + 'singular_name' => __( 'Coupon', 'woocommerce' ), + 'menu_name' => _x( 'Coupons', 'Admin menu name', 'woocommerce' ), + 'add_new' => __( 'Add coupon', 'woocommerce' ), + 'add_new_item' => __( 'Add new coupon', 'woocommerce' ), + 'edit' => __( 'Edit', 'woocommerce' ), + 'edit_item' => __( 'Edit coupon', 'woocommerce' ), + 'new_item' => __( 'New coupon', 'woocommerce' ), + 'view_item' => __( 'View coupon', 'woocommerce' ), + 'search_items' => __( 'Search coupons', 'woocommerce' ), + 'not_found' => __( 'No coupons found', 'woocommerce' ), + 'not_found_in_trash' => __( 'No coupons found in trash', 'woocommerce' ), + 'parent' => __( 'Parent coupon', 'woocommerce' ), + 'filter_items_list' => __( 'Filter coupons', 'woocommerce' ), + 'items_list_navigation' => __( 'Coupons navigation', 'woocommerce' ), + 'items_list' => __( 'Coupons list', 'woocommerce' ), + ), + 'description' => __( 'This is where you can add new coupons that customers can use in your store.', 'woocommerce' ), + 'public' => false, + 'show_ui' => true, + 'capability_type' => 'shop_coupon', + 'map_meta_cap' => true, + 'publicly_queryable' => false, + 'exclude_from_search' => true, + 'show_in_menu' => current_user_can( 'edit_others_shop_orders' ) ? 'woocommerce' : true, + 'hierarchical' => false, + 'rewrite' => false, + 'query_var' => false, + 'supports' => array( 'title' ), + 'show_in_nav_menus' => false, + 'show_in_admin_bar' => true, + ) + ) + ); + } + + do_action( 'woocommerce_after_register_post_type' ); + } + + /** + * Customize taxonomies update messages. + * + * @param array $messages The list of available messages. + * @since 4.4.0 + * @return bool + */ + public static function updated_term_messages( $messages ) { + $messages['product_cat'] = array( + 0 => '', + 1 => __( 'Category added.', 'woocommerce' ), + 2 => __( 'Category deleted.', 'woocommerce' ), + 3 => __( 'Category updated.', 'woocommerce' ), + 4 => __( 'Category not added.', 'woocommerce' ), + 5 => __( 'Category not updated.', 'woocommerce' ), + 6 => __( 'Categories deleted.', 'woocommerce' ), + ); + + $messages['product_tag'] = array( + 0 => '', + 1 => __( 'Tag added.', 'woocommerce' ), + 2 => __( 'Tag deleted.', 'woocommerce' ), + 3 => __( 'Tag updated.', 'woocommerce' ), + 4 => __( 'Tag not added.', 'woocommerce' ), + 5 => __( 'Tag not updated.', 'woocommerce' ), + 6 => __( 'Tags deleted.', 'woocommerce' ), + ); + + $wc_product_attributes = array(); + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + if ( $attribute_taxonomies ) { + foreach ( $attribute_taxonomies as $tax ) { + $name = wc_attribute_taxonomy_name( $tax->attribute_name ); + + if ( $name ) { + $label = ! empty( $tax->attribute_label ) ? $tax->attribute_label : $tax->attribute_name; + + $messages[ $name ] = array( + 0 => '', + /* translators: %s: taxonomy label */ + 1 => sprintf( _x( '%s added', 'taxonomy term messages', 'woocommerce' ), $label ), + /* translators: %s: taxonomy label */ + 2 => sprintf( _x( '%s deleted', 'taxonomy term messages', 'woocommerce' ), $label ), + /* translators: %s: taxonomy label */ + 3 => sprintf( _x( '%s updated', 'taxonomy term messages', 'woocommerce' ), $label ), + /* translators: %s: taxonomy label */ + 4 => sprintf( _x( '%s not added', 'taxonomy term messages', 'woocommerce' ), $label ), + /* translators: %s: taxonomy label */ + 5 => sprintf( _x( '%s not updated', 'taxonomy term messages', 'woocommerce' ), $label ), + /* translators: %s: taxonomy label */ + 6 => sprintf( _x( '%s deleted', 'taxonomy term messages', 'woocommerce' ), $label ), + ); + } + } + } + + return $messages; + } + + /** + * Register our custom post statuses, used for order status. + */ + public static function register_post_status() { + + $order_statuses = apply_filters( + 'woocommerce_register_shop_order_post_statuses', + array( + 'wc-pending' => array( + 'label' => _x( 'Pending payment', 'Order status', 'woocommerce' ), + 'public' => false, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => true, + 'show_in_admin_status_list' => true, + /* translators: %s: number of orders */ + 'label_count' => _n_noop( 'Pending payment (%s)', 'Pending payment (%s)', 'woocommerce' ), + ), + 'wc-processing' => array( + 'label' => _x( 'Processing', 'Order status', 'woocommerce' ), + 'public' => false, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => true, + 'show_in_admin_status_list' => true, + /* translators: %s: number of orders */ + 'label_count' => _n_noop( 'Processing (%s)', 'Processing (%s)', 'woocommerce' ), + ), + 'wc-on-hold' => array( + 'label' => _x( 'On hold', 'Order status', 'woocommerce' ), + 'public' => false, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => true, + 'show_in_admin_status_list' => true, + /* translators: %s: number of orders */ + 'label_count' => _n_noop( 'On hold (%s)', 'On hold (%s)', 'woocommerce' ), + ), + 'wc-completed' => array( + 'label' => _x( 'Completed', 'Order status', 'woocommerce' ), + 'public' => false, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => true, + 'show_in_admin_status_list' => true, + /* translators: %s: number of orders */ + 'label_count' => _n_noop( 'Completed (%s)', 'Completed (%s)', 'woocommerce' ), + ), + 'wc-cancelled' => array( + 'label' => _x( 'Cancelled', 'Order status', 'woocommerce' ), + 'public' => false, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => true, + 'show_in_admin_status_list' => true, + /* translators: %s: number of orders */ + 'label_count' => _n_noop( 'Cancelled (%s)', 'Cancelled (%s)', 'woocommerce' ), + ), + 'wc-refunded' => array( + 'label' => _x( 'Refunded', 'Order status', 'woocommerce' ), + 'public' => false, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => true, + 'show_in_admin_status_list' => true, + /* translators: %s: number of orders */ + 'label_count' => _n_noop( 'Refunded (%s)', 'Refunded (%s)', 'woocommerce' ), + ), + 'wc-failed' => array( + 'label' => _x( 'Failed', 'Order status', 'woocommerce' ), + 'public' => false, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => true, + 'show_in_admin_status_list' => true, + /* translators: %s: number of orders */ + 'label_count' => _n_noop( 'Failed (%s)', 'Failed (%s)', 'woocommerce' ), + ), + ) + ); + + foreach ( $order_statuses as $order_status => $values ) { + register_post_status( $order_status, $values ); + } + } + + /** + * Flush rules if the event is queued. + * + * @since 3.3.0 + */ + public static function maybe_flush_rewrite_rules() { + if ( 'yes' === get_option( 'woocommerce_queue_flush_rewrite_rules' ) ) { + update_option( 'woocommerce_queue_flush_rewrite_rules', 'no' ); + self::flush_rewrite_rules(); + } + } + + /** + * Flush rewrite rules. + */ + public static function flush_rewrite_rules() { + flush_rewrite_rules(); + } + + /** + * Disable Gutenberg for products. + * + * @param bool $can_edit Whether the post type can be edited or not. + * @param string $post_type The post type being checked. + * @return bool + */ + public static function gutenberg_can_edit_post_type( $can_edit, $post_type ) { + return 'product' === $post_type ? false : $can_edit; + } + + /** + * Add Product Support to Jetpack Omnisearch. + */ + public static function support_jetpack_omnisearch() { + if ( class_exists( 'Jetpack_Omnisearch_Posts' ) ) { + new Jetpack_Omnisearch_Posts( 'product' ); + } + } + + /** + * Added product for Jetpack related posts. + * + * @param array $post_types Post types. + * @return array + */ + public static function rest_api_allowed_post_types( $post_types ) { + $post_types[] = 'product'; + + return $post_types; + } +} + +WC_Post_types::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy-background-process.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy-background-process.php new file mode 100644 index 0000000..f75fa42 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy-background-process.php @@ -0,0 +1,70 @@ +prefix = 'wp_' . get_current_blog_id(); + $this->action = 'wc_privacy_cleanup'; + parent::__construct(); + } + + /** + * Code to execute for each item in the queue + * + * @param string $item Queue item to iterate over. + * @return bool + */ + protected function task( $item ) { + if ( ! $item || empty( $item['task'] ) ) { + return false; + } + + $process_count = 0; + $process_limit = 20; + + switch ( $item['task'] ) { + case 'trash_pending_orders': + $process_count = WC_Privacy::trash_pending_orders( $process_limit ); + break; + case 'trash_failed_orders': + $process_count = WC_Privacy::trash_failed_orders( $process_limit ); + break; + case 'trash_cancelled_orders': + $process_count = WC_Privacy::trash_cancelled_orders( $process_limit ); + break; + case 'anonymize_completed_orders': + $process_count = WC_Privacy::anonymize_completed_orders( $process_limit ); + break; + case 'delete_inactive_accounts': + $process_count = WC_Privacy::delete_inactive_accounts( $process_limit ); + break; + } + + if ( $process_limit === $process_count ) { + // Needs to run again. + return $item; + } + + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy-erasers.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy-erasers.php new file mode 100644 index 0000000..463e236 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy-erasers.php @@ -0,0 +1,412 @@ + false, + 'items_retained' => false, + 'messages' => array(), + 'done' => true, + ); + + $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. + + if ( ! $user instanceof WP_User ) { + return $response; + } + + $customer = new WC_Customer( $user->ID ); + + if ( ! $customer ) { + return $response; + } + + $props_to_erase = apply_filters( + 'woocommerce_privacy_erase_customer_personal_data_props', + array( + 'billing_first_name' => __( 'Billing First Name', 'woocommerce' ), + 'billing_last_name' => __( 'Billing Last Name', 'woocommerce' ), + 'billing_company' => __( 'Billing Company', 'woocommerce' ), + 'billing_address_1' => __( 'Billing Address 1', 'woocommerce' ), + 'billing_address_2' => __( 'Billing Address 2', 'woocommerce' ), + 'billing_city' => __( 'Billing City', 'woocommerce' ), + 'billing_postcode' => __( 'Billing Postal/Zip Code', 'woocommerce' ), + 'billing_state' => __( 'Billing State', 'woocommerce' ), + 'billing_country' => __( 'Billing Country / Region', 'woocommerce' ), + 'billing_phone' => __( 'Phone Number', 'woocommerce' ), + 'billing_email' => __( 'Email Address', 'woocommerce' ), + 'shipping_first_name' => __( 'Shipping First Name', 'woocommerce' ), + 'shipping_last_name' => __( 'Shipping Last Name', 'woocommerce' ), + 'shipping_company' => __( 'Shipping Company', 'woocommerce' ), + 'shipping_address_1' => __( 'Shipping Address 1', 'woocommerce' ), + 'shipping_address_2' => __( 'Shipping Address 2', 'woocommerce' ), + 'shipping_city' => __( 'Shipping City', 'woocommerce' ), + 'shipping_postcode' => __( 'Shipping Postal/Zip Code', 'woocommerce' ), + 'shipping_state' => __( 'Shipping State', 'woocommerce' ), + 'shipping_country' => __( 'Shipping Country / Region', 'woocommerce' ), + ), + $customer + ); + + foreach ( $props_to_erase as $prop => $label ) { + $erased = false; + + if ( is_callable( array( $customer, 'get_' . $prop ) ) && is_callable( array( $customer, 'set_' . $prop ) ) ) { + $value = $customer->{"get_$prop"}( 'edit' ); + + if ( $value ) { + $customer->{"set_$prop"}( '' ); + $erased = true; + } + } + + $erased = apply_filters( 'woocommerce_privacy_erase_customer_personal_data_prop', $erased, $prop, $customer ); + + if ( $erased ) { + /* Translators: %s Prop name. */ + $response['messages'][] = sprintf( __( 'Removed customer "%s"', 'woocommerce' ), $label ); + $response['items_removed'] = true; + } + } + + $customer->save(); + + /** + * Allow extensions to remove data for this customer and adjust the response. + * + * @since 3.4.0 + * @param array $response Array resonse data. Must include messages, num_items_removed, num_items_retained, done. + * @param WC_Order $order A customer object. + */ + return apply_filters( 'woocommerce_privacy_erase_personal_data_customer', $response, $customer ); + } + + /** + * Finds and erases data which could be used to identify a person from WooCommerce data assocated with an email address. + * + * Orders are erased in blocks of 10 to avoid timeouts. + * + * @since 3.4.0 + * @param string $email_address The user email address. + * @param int $page Page. + * @return array An array of personal data in name value pairs + */ + public static function order_data_eraser( $email_address, $page ) { + $page = (int) $page; + $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. + $erasure_enabled = wc_string_to_bool( get_option( 'woocommerce_erasure_request_removes_order_data', 'no' ) ); + $response = array( + 'items_removed' => false, + 'items_retained' => false, + 'messages' => array(), + 'done' => true, + ); + + $order_query = array( + 'limit' => 10, + 'page' => $page, + 'customer' => array( $email_address ), + ); + + if ( $user instanceof WP_User ) { + $order_query['customer'][] = (int) $user->ID; + } + + $orders = wc_get_orders( $order_query ); + + if ( 0 < count( $orders ) ) { + foreach ( $orders as $order ) { + if ( apply_filters( 'woocommerce_privacy_erase_order_personal_data', $erasure_enabled, $order ) ) { + self::remove_order_personal_data( $order ); + + /* Translators: %s Order number. */ + $response['messages'][] = sprintf( __( 'Removed personal data from order %s.', 'woocommerce' ), $order->get_order_number() ); + $response['items_removed'] = true; + } else { + /* Translators: %s Order number. */ + $response['messages'][] = sprintf( __( 'Personal data within order %s has been retained.', 'woocommerce' ), $order->get_order_number() ); + $response['items_retained'] = true; + } + } + $response['done'] = 10 > count( $orders ); + } else { + $response['done'] = true; + } + + return $response; + } + + /** + * Finds and removes customer download logs by email address. + * + * @since 3.4.0 + * @param string $email_address The user email address. + * @param int $page Page. + * @return array An array of personal data in name value pairs + */ + public static function download_data_eraser( $email_address, $page ) { + $page = (int) $page; + $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. + $erasure_enabled = wc_string_to_bool( get_option( 'woocommerce_erasure_request_removes_download_data', 'no' ) ); + $response = array( + 'items_removed' => false, + 'items_retained' => false, + 'messages' => array(), + 'done' => true, + ); + + $downloads_query = array( + 'limit' => -1, + 'page' => $page, + 'return' => 'ids', + ); + + if ( $user instanceof WP_User ) { + $downloads_query['user_id'] = (int) $user->ID; + } else { + $downloads_query['user_email'] = $email_address; + } + + $customer_download_data_store = WC_Data_Store::load( 'customer-download' ); + + // Revoke download permissions. + if ( apply_filters( 'woocommerce_privacy_erase_download_personal_data', $erasure_enabled, $email_address ) ) { + if ( $user instanceof WP_User ) { + $result = $customer_download_data_store->delete_by_user_id( (int) $user->ID ); + } else { + $result = $customer_download_data_store->delete_by_user_email( $email_address ); + } + if ( $result ) { + $response['messages'][] = __( 'Removed access to downloadable files.', 'woocommerce' ); + $response['items_removed'] = true; + } + } else { + $response['messages'][] = __( 'Customer download permissions have been retained.', 'woocommerce' ); + $response['items_retained'] = true; + } + + return $response; + } + + /** + * Remove personal data specific to WooCommerce from an order object. + * + * Note; this will hinder order processing for obvious reasons! + * + * @param WC_Order $order Order object. + */ + public static function remove_order_personal_data( $order ) { + $anonymized_data = array(); + + /** + * Allow extensions to remove their own personal data for this order first, so order data is still available. + * + * @since 3.4.0 + * @param WC_Order $order A customer object. + */ + do_action( 'woocommerce_privacy_before_remove_order_personal_data', $order ); + + /** + * Expose props and data types we'll be anonymizing. + * + * @since 3.4.0 + * @param array $props Keys are the prop names, values are the data type we'll be passing to wp_privacy_anonymize_data(). + * @param WC_Order $order A customer object. + */ + $props_to_remove = apply_filters( + 'woocommerce_privacy_remove_order_personal_data_props', + array( + 'customer_ip_address' => 'ip', + 'customer_user_agent' => 'text', + 'billing_first_name' => 'text', + 'billing_last_name' => 'text', + 'billing_company' => 'text', + 'billing_address_1' => 'text', + 'billing_address_2' => 'text', + 'billing_city' => 'text', + 'billing_postcode' => 'text', + 'billing_state' => 'address_state', + 'billing_country' => 'address_country', + 'billing_phone' => 'phone', + 'billing_email' => 'email', + 'shipping_first_name' => 'text', + 'shipping_last_name' => 'text', + 'shipping_company' => 'text', + 'shipping_address_1' => 'text', + 'shipping_address_2' => 'text', + 'shipping_city' => 'text', + 'shipping_postcode' => 'text', + 'shipping_state' => 'address_state', + 'shipping_country' => 'address_country', + 'customer_id' => 'numeric_id', + 'transaction_id' => 'numeric_id', + ), + $order + ); + + if ( ! empty( $props_to_remove ) && is_array( $props_to_remove ) ) { + foreach ( $props_to_remove as $prop => $data_type ) { + // Get the current value in edit context. + $value = $order->{"get_$prop"}( 'edit' ); + + // If the value is empty, it does not need to be anonymized. + if ( empty( $value ) || empty( $data_type ) ) { + continue; + } + + $anon_value = function_exists( 'wp_privacy_anonymize_data' ) ? wp_privacy_anonymize_data( $data_type, $value ) : ''; + + /** + * Expose a way to control the anonymized value of a prop via 3rd party code. + * + * @since 3.4.0 + * @param string $anon_value Value of this prop after anonymization. + * @param string $prop Name of the prop being removed. + * @param string $value Current value of the data. + * @param string $data_type Type of data. + * @param WC_Order $order An order object. + */ + $anonymized_data[ $prop ] = apply_filters( 'woocommerce_privacy_remove_order_personal_data_prop_value', $anon_value, $prop, $value, $data_type, $order ); + } + } + + // Set all new props and persist the new data to the database. + $order->set_props( $anonymized_data ); + + // Remove meta data. + $meta_to_remove = apply_filters( + 'woocommerce_privacy_remove_order_personal_data_meta', + array( + 'Payer first name' => 'text', + 'Payer last name' => 'text', + 'Payer PayPal address' => 'email', + 'Transaction ID' => 'numeric_id', + ) + ); + + if ( ! empty( $meta_to_remove ) && is_array( $meta_to_remove ) ) { + foreach ( $meta_to_remove as $meta_key => $data_type ) { + $value = $order->get_meta( $meta_key ); + + // If the value is empty, it does not need to be anonymized. + if ( empty( $value ) || empty( $data_type ) ) { + continue; + } + + $anon_value = function_exists( 'wp_privacy_anonymize_data' ) ? wp_privacy_anonymize_data( $data_type, $value ) : ''; + + /** + * Expose a way to control the anonymized value of a value via 3rd party code. + * + * @since 3.4.0 + * @param string $anon_value Value of this data after anonymization. + * @param string $prop meta_key key being removed. + * @param string $value Current value of the data. + * @param string $data_type Type of data. + * @param WC_Order $order An order object. + */ + $anon_value = apply_filters( 'woocommerce_privacy_remove_order_personal_data_meta_value', $anon_value, $meta_key, $value, $data_type, $order ); + + if ( $anon_value ) { + $order->update_meta_data( $meta_key, $anon_value ); + } else { + $order->delete_meta_data( $meta_key ); + } + } + } + + $order->update_meta_data( '_anonymized', 'yes' ); + $order->save(); + + // Delete order notes which can contain PII. + $notes = wc_get_order_notes( + array( + 'order_id' => $order->get_id(), + ) + ); + + foreach ( $notes as $note ) { + wc_delete_order_note( $note->id ); + } + + // Add note that this event occured. + $order->add_order_note( __( 'Personal data removed.', 'woocommerce' ) ); + + /** + * Allow extensions to remove their own personal data for this order. + * + * @since 3.4.0 + * @param WC_Order $order A customer object. + */ + do_action( 'woocommerce_privacy_remove_order_personal_data', $order ); + } + + /** + * Finds and erases customer tokens by email address. + * + * @since 3.4.0 + * @param string $email_address The user email address. + * @param int $page Page. + * @return array An array of personal data in name value pairs + */ + public static function customer_tokens_eraser( $email_address, $page ) { + $response = array( + 'items_removed' => false, + 'items_retained' => false, + 'messages' => array(), + 'done' => true, + ); + + $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. + + if ( ! $user instanceof WP_User ) { + return $response; + } + + $tokens = WC_Payment_Tokens::get_tokens( + array( + 'user_id' => $user->ID, + ) + ); + + if ( empty( $tokens ) ) { + return $response; + } + + foreach ( $tokens as $token ) { + WC_Payment_Tokens::delete( $token->get_id() ); + + /* Translators: %s Prop name. */ + $response['messages'][] = sprintf( __( 'Removed payment token "%d"', 'woocommerce' ), $token->get_id() ); + $response['items_removed'] = true; + } + + /** + * Allow extensions to remove data for tokens and adjust the response. + * + * @since 3.4.0 + * @param array $response Array resonse data. Must include messages, num_items_removed, num_items_retained, done. + * @param array $tokens Array of tokens. + */ + return apply_filters( 'woocommerce_privacy_erase_personal_data_tokens', $response, $tokens ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy-exporters.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy-exporters.php new file mode 100644 index 0000000..b248de8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy-exporters.php @@ -0,0 +1,442 @@ + 'woocommerce_customer', + 'group_label' => __( 'Customer Data', 'woocommerce' ), + 'group_description' => __( 'User’s WooCommerce customer data.', 'woocommerce' ), + 'item_id' => 'user', + 'data' => $customer_personal_data, + ); + } + } + + return array( + 'data' => $data_to_export, + 'done' => true, + ); + } + + /** + * Finds and exports data which could be used to identify a person from WooCommerce data associated with an email address. + * + * Orders are exported in blocks of 10 to avoid timeouts. + * + * @since 3.4.0 + * @param string $email_address The user email address. + * @param int $page Page. + * @return array An array of personal data in name value pairs + */ + public static function order_data_exporter( $email_address, $page ) { + $done = true; + $page = (int) $page; + $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. + $data_to_export = array(); + $order_query = array( + 'limit' => 10, + 'page' => $page, + 'customer' => array( $email_address ), + ); + + if ( $user instanceof WP_User ) { + $order_query['customer'][] = (int) $user->ID; + } + + $orders = wc_get_orders( $order_query ); + + if ( 0 < count( $orders ) ) { + foreach ( $orders as $order ) { + $data_to_export[] = array( + 'group_id' => 'woocommerce_orders', + 'group_label' => __( 'Orders', 'woocommerce' ), + 'group_description' => __( 'User’s WooCommerce orders data.', 'woocommerce' ), + 'item_id' => 'order-' . $order->get_id(), + 'data' => self::get_order_personal_data( $order ), + ); + } + $done = 10 > count( $orders ); + } + + return array( + 'data' => $data_to_export, + 'done' => $done, + ); + } + + /** + * Finds and exports customer download logs by email address. + * + * @since 3.4.0 + * @param string $email_address The user email address. + * @param int $page Page. + * @throws Exception When WC_Data_Store validation fails. + * @return array An array of personal data in name value pairs + */ + public static function download_data_exporter( $email_address, $page ) { + $done = true; + $page = (int) $page; + $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. + $data_to_export = array(); + $downloads_query = array( + 'limit' => 10, + 'page' => $page, + ); + + if ( $user instanceof WP_User ) { + $downloads_query['user_id'] = (int) $user->ID; + } else { + $downloads_query['user_email'] = $email_address; + } + + $customer_download_data_store = WC_Data_Store::load( 'customer-download' ); + $customer_download_log_data_store = WC_Data_Store::load( 'customer-download-log' ); + $downloads = $customer_download_data_store->get_downloads( $downloads_query ); + + if ( 0 < count( $downloads ) ) { + foreach ( $downloads as $download ) { + $data_to_export[] = array( + 'group_id' => 'woocommerce_downloads', + /* translators: This is the headline for a list of downloads purchased from the store for a given user. */ + 'group_label' => __( 'Purchased Downloads', 'woocommerce' ), + 'group_description' => __( 'User’s WooCommerce purchased downloads data.', 'woocommerce' ), + 'item_id' => 'download-' . $download->get_id(), + 'data' => self::get_download_personal_data( $download ), + ); + + $download_logs = $customer_download_log_data_store->get_download_logs_for_permission( $download->get_id() ); + + foreach ( $download_logs as $download_log ) { + $data_to_export[] = array( + 'group_id' => 'woocommerce_download_logs', + /* translators: This is the headline for a list of access logs for downloads purchased from the store for a given user. */ + 'group_label' => __( 'Access to Purchased Downloads', 'woocommerce' ), + 'group_description' => __( 'User’s WooCommerce access to purchased downloads data.', 'woocommerce' ), + 'item_id' => 'download-log-' . $download_log->get_id(), + 'data' => array( + array( + 'name' => __( 'Download ID', 'woocommerce' ), + 'value' => $download_log->get_permission_id(), + ), + array( + 'name' => __( 'Timestamp', 'woocommerce' ), + 'value' => $download_log->get_timestamp(), + ), + array( + 'name' => __( 'IP Address', 'woocommerce' ), + 'value' => $download_log->get_user_ip_address(), + ), + ), + ); + } + } + $done = 10 > count( $downloads ); + } + + return array( + 'data' => $data_to_export, + 'done' => $done, + ); + } + + /** + * Get personal data (key/value pairs) for a user object. + * + * @since 3.4.0 + * @param WP_User $user user object. + * @throws Exception If customer cannot be read/found and $data is set to WC_Customer class. + * @return array + */ + protected static function get_customer_personal_data( $user ) { + $personal_data = array(); + $customer = new WC_Customer( $user->ID ); + + if ( ! $customer ) { + return array(); + } + + $props_to_export = apply_filters( + 'woocommerce_privacy_export_customer_personal_data_props', + array( + 'billing_first_name' => __( 'Billing First Name', 'woocommerce' ), + 'billing_last_name' => __( 'Billing Last Name', 'woocommerce' ), + 'billing_company' => __( 'Billing Company', 'woocommerce' ), + 'billing_address_1' => __( 'Billing Address 1', 'woocommerce' ), + 'billing_address_2' => __( 'Billing Address 2', 'woocommerce' ), + 'billing_city' => __( 'Billing City', 'woocommerce' ), + 'billing_postcode' => __( 'Billing Postal/Zip Code', 'woocommerce' ), + 'billing_state' => __( 'Billing State', 'woocommerce' ), + 'billing_country' => __( 'Billing Country / Region', 'woocommerce' ), + 'billing_phone' => __( 'Phone Number', 'woocommerce' ), + 'billing_email' => __( 'Email Address', 'woocommerce' ), + 'shipping_first_name' => __( 'Shipping First Name', 'woocommerce' ), + 'shipping_last_name' => __( 'Shipping Last Name', 'woocommerce' ), + 'shipping_company' => __( 'Shipping Company', 'woocommerce' ), + 'shipping_address_1' => __( 'Shipping Address 1', 'woocommerce' ), + 'shipping_address_2' => __( 'Shipping Address 2', 'woocommerce' ), + 'shipping_city' => __( 'Shipping City', 'woocommerce' ), + 'shipping_postcode' => __( 'Shipping Postal/Zip Code', 'woocommerce' ), + 'shipping_state' => __( 'Shipping State', 'woocommerce' ), + 'shipping_country' => __( 'Shipping Country / Region', 'woocommerce' ), + ), + $customer + ); + + foreach ( $props_to_export as $prop => $description ) { + $value = ''; + + if ( is_callable( array( $customer, 'get_' . $prop ) ) ) { + $value = $customer->{"get_$prop"}( 'edit' ); + } + + $value = apply_filters( 'woocommerce_privacy_export_customer_personal_data_prop_value', $value, $prop, $customer ); + + if ( $value ) { + $personal_data[] = array( + 'name' => $description, + 'value' => $value, + ); + } + } + + /** + * Allow extensions to register their own personal data for this customer for the export. + * + * @since 3.4.0 + * @param array $personal_data Array of name value pairs. + * @param WC_Order $order A customer object. + */ + $personal_data = apply_filters( 'woocommerce_privacy_export_customer_personal_data', $personal_data, $customer ); + + return $personal_data; + } + + /** + * Get personal data (key/value pairs) for an order object. + * + * @since 3.4.0 + * @param WC_Order $order Order object. + * @return array + */ + protected static function get_order_personal_data( $order ) { + $personal_data = array(); + $props_to_export = apply_filters( + 'woocommerce_privacy_export_order_personal_data_props', + array( + 'order_number' => __( 'Order Number', 'woocommerce' ), + 'date_created' => __( 'Order Date', 'woocommerce' ), + 'total' => __( 'Order Total', 'woocommerce' ), + 'items' => __( 'Items Purchased', 'woocommerce' ), + 'customer_ip_address' => __( 'IP Address', 'woocommerce' ), + 'customer_user_agent' => __( 'Browser User Agent', 'woocommerce' ), + 'formatted_billing_address' => __( 'Billing Address', 'woocommerce' ), + 'formatted_shipping_address' => __( 'Shipping Address', 'woocommerce' ), + 'billing_phone' => __( 'Phone Number', 'woocommerce' ), + 'billing_email' => __( 'Email Address', 'woocommerce' ), + ), + $order + ); + + foreach ( $props_to_export as $prop => $name ) { + $value = ''; + + switch ( $prop ) { + case 'items': + $item_names = array(); + foreach ( $order->get_items() as $item ) { + $item_names[] = $item->get_name() . ' x ' . $item->get_quantity(); + } + $value = implode( ', ', $item_names ); + break; + case 'date_created': + $value = wc_format_datetime( $order->get_date_created(), get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) ); + break; + case 'formatted_billing_address': + case 'formatted_shipping_address': + $value = preg_replace( '##i', ', ', $order->{"get_$prop"}() ); + break; + default: + if ( is_callable( array( $order, 'get_' . $prop ) ) ) { + $value = $order->{"get_$prop"}(); + } + break; + } + + $value = apply_filters( 'woocommerce_privacy_export_order_personal_data_prop', $value, $prop, $order ); + + if ( $value ) { + $personal_data[] = array( + 'name' => $name, + 'value' => $value, + ); + } + } + + // Export meta data. + $meta_to_export = apply_filters( + 'woocommerce_privacy_export_order_personal_data_meta', + array( + 'Payer first name' => __( 'Payer first name', 'woocommerce' ), + 'Payer last name' => __( 'Payer last name', 'woocommerce' ), + 'Payer PayPal address' => __( 'Payer PayPal address', 'woocommerce' ), + 'Transaction ID' => __( 'Transaction ID', 'woocommerce' ), + ) + ); + + if ( ! empty( $meta_to_export ) && is_array( $meta_to_export ) ) { + foreach ( $meta_to_export as $meta_key => $name ) { + $value = apply_filters( 'woocommerce_privacy_export_order_personal_data_meta_value', $order->get_meta( $meta_key ), $meta_key, $order ); + + if ( $value ) { + $personal_data[] = array( + 'name' => $name, + 'value' => $value, + ); + } + } + } + + /** + * Allow extensions to register their own personal data for this order for the export. + * + * @since 3.4.0 + * @param array $personal_data Array of name value pairs to expose in the export. + * @param WC_Order $order An order object. + */ + $personal_data = apply_filters( 'woocommerce_privacy_export_order_personal_data', $personal_data, $order ); + + return $personal_data; + } + + /** + * Get personal data (key/value pairs) for a download object. + * + * @since 3.4.0 + * @param WC_Order $download Download object. + * @return array + */ + protected static function get_download_personal_data( $download ) { + $personal_data = array( + array( + 'name' => __( 'Download ID', 'woocommerce' ), + 'value' => $download->get_id(), + ), + array( + 'name' => __( 'Order ID', 'woocommerce' ), + 'value' => $download->get_order_id(), + ), + array( + 'name' => __( 'Product', 'woocommerce' ), + 'value' => get_the_title( $download->get_product_id() ), + ), + array( + 'name' => __( 'User email', 'woocommerce' ), + 'value' => $download->get_user_email(), + ), + array( + 'name' => __( 'Downloads remaining', 'woocommerce' ), + 'value' => $download->get_downloads_remaining(), + ), + array( + 'name' => __( 'Download count', 'woocommerce' ), + 'value' => $download->get_download_count(), + ), + array( + 'name' => __( 'Access granted', 'woocommerce' ), + 'value' => date( 'Y-m-d', $download->get_access_granted( 'edit' )->getTimestamp() ), + ), + array( + 'name' => __( 'Access expires', 'woocommerce' ), + 'value' => ! is_null( $download->get_access_expires( 'edit' ) ) ? date( 'Y-m-d', $download->get_access_expires( 'edit' )->getTimestamp() ) : null, + ), + ); + + /** + * Allow extensions to register their own personal data for this download for the export. + * + * @since 3.4.0 + * @param array $personal_data Array of name value pairs to expose in the export. + * @param WC_Order $order An order object. + */ + $personal_data = apply_filters( 'woocommerce_privacy_export_download_personal_data', $personal_data, $download ); + + return $personal_data; + } + + /** + * Finds and exports payment tokens by email address for a customer. + * + * @since 3.4.0 + * @param string $email_address The user email address. + * @param int $page Page. + * @return array An array of personal data in name value pairs + */ + public static function customer_tokens_exporter( $email_address, $page ) { + $user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. + $data_to_export = array(); + + if ( ! $user instanceof WP_User ) { + return array( + 'data' => $data_to_export, + 'done' => true, + ); + } + + $tokens = WC_Payment_Tokens::get_tokens( + array( + 'user_id' => $user->ID, + 'limit' => 10, + 'page' => $page, + ) + ); + + if ( 0 < count( $tokens ) ) { + foreach ( $tokens as $token ) { + $data_to_export[] = array( + 'group_id' => 'woocommerce_tokens', + 'group_label' => __( 'Payment Tokens', 'woocommerce' ), + 'group_description' => __( 'User’s WooCommerce payment tokens data.', 'woocommerce' ), + 'item_id' => 'token-' . $token->get_id(), + 'data' => array( + array( + 'name' => __( 'Token', 'woocommerce' ), + 'value' => $token->get_display_name(), + ), + ), + ); + } + $done = 10 > count( $tokens ); + } else { + $done = true; + } + + return array( + 'data' => $data_to_export, + 'done' => $done, + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy.php new file mode 100644 index 0000000..f9e3dbf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-privacy.php @@ -0,0 +1,381 @@ +add_exporter( 'woocommerce-customer-data', __( 'WooCommerce Customer Data', 'woocommerce' ), array( 'WC_Privacy_Exporters', 'customer_data_exporter' ) ); + $this->add_exporter( 'woocommerce-customer-orders', __( 'WooCommerce Customer Orders', 'woocommerce' ), array( 'WC_Privacy_Exporters', 'order_data_exporter' ) ); + $this->add_exporter( 'woocommerce-customer-downloads', __( 'WooCommerce Customer Downloads', 'woocommerce' ), array( 'WC_Privacy_Exporters', 'download_data_exporter' ) ); + $this->add_exporter( 'woocommerce-customer-tokens', __( 'WooCommerce Customer Payment Tokens', 'woocommerce' ), array( 'WC_Privacy_Exporters', 'customer_tokens_exporter' ) ); + + // This hook registers WooCommerce data erasers. + $this->add_eraser( 'woocommerce-customer-data', __( 'WooCommerce Customer Data', 'woocommerce' ), array( 'WC_Privacy_Erasers', 'customer_data_eraser' ) ); + $this->add_eraser( 'woocommerce-customer-orders', __( 'WooCommerce Customer Orders', 'woocommerce' ), array( 'WC_Privacy_Erasers', 'order_data_eraser' ) ); + $this->add_eraser( 'woocommerce-customer-downloads', __( 'WooCommerce Customer Downloads', 'woocommerce' ), array( 'WC_Privacy_Erasers', 'download_data_eraser' ) ); + $this->add_eraser( 'woocommerce-customer-tokens', __( 'WooCommerce Customer Payment Tokens', 'woocommerce' ), array( 'WC_Privacy_Erasers', 'customer_tokens_eraser' ) ); + + // Cleanup orders daily - this is a callback on a daily cron event. + add_action( 'woocommerce_cleanup_personal_data', array( $this, 'queue_cleanup_personal_data' ) ); + + // Handles custom anonomization types not included in core. + add_filter( 'wp_privacy_anonymize_data', array( $this, 'anonymize_custom_data_types' ), 10, 3 ); + + // When this is fired, data is removed in a given order. Called from bulk actions. + add_action( 'woocommerce_remove_order_personal_data', array( 'WC_Privacy_Erasers', 'remove_order_personal_data' ) ); + } + + /** + * Add privacy policy content for the privacy policy page. + * + * @since 3.4.0 + */ + public function get_privacy_message() { + $content = '
    ' . + '

    ' . + __( 'This sample language includes the basics around what personal data your store may be collecting, storing and sharing, as well as who may have access to that data. Depending on what settings are enabled and which additional plugins are used, the specific information shared by your store will vary. We recommend consulting with a lawyer when deciding what information to disclose on your privacy policy.', 'woocommerce' ) . + '

    ' . + '

    ' . __( 'We collect information about you during the checkout process on our store.', 'woocommerce' ) . '

    ' . + '

    ' . __( 'What we collect and store', 'woocommerce' ) . '

    ' . + '

    ' . __( 'While you visit our site, we’ll track:', 'woocommerce' ) . '

    ' . + '
      ' . + '
    • ' . __( 'Products you’ve viewed: we’ll use this to, for example, show you products you’ve recently viewed', 'woocommerce' ) . '
    • ' . + '
    • ' . __( 'Location, IP address and browser type: we’ll use this for purposes like estimating taxes and shipping', 'woocommerce' ) . '
    • ' . + '
    • ' . __( 'Shipping address: we’ll ask you to enter this so we can, for instance, estimate shipping before you place an order, and send you the order!', 'woocommerce' ) . '
    • ' . + '
    ' . + '

    ' . __( 'We’ll also use cookies to keep track of cart contents while you’re browsing our site.', 'woocommerce' ) . '

    ' . + '

    ' . + __( 'Note: you may want to further detail your cookie policy, and link to that section from here.', 'woocommerce' ) . + '

    ' . + '

    ' . __( 'When you purchase from us, we’ll ask you to provide information including your name, billing address, shipping address, email address, phone number, credit card/payment details and optional account information like username and password. We’ll use this information for purposes, such as, to:', 'woocommerce' ) . '

    ' . + '
      ' . + '
    • ' . __( 'Send you information about your account and order', 'woocommerce' ) . '
    • ' . + '
    • ' . __( 'Respond to your requests, including refunds and complaints', 'woocommerce' ) . '
    • ' . + '
    • ' . __( 'Process payments and prevent fraud', 'woocommerce' ) . '
    • ' . + '
    • ' . __( 'Set up your account for our store', 'woocommerce' ) . '
    • ' . + '
    • ' . __( 'Comply with any legal obligations we have, such as calculating taxes', 'woocommerce' ) . '
    • ' . + '
    • ' . __( 'Improve our store offerings', 'woocommerce' ) . '
    • ' . + '
    • ' . __( 'Send you marketing messages, if you choose to receive them', 'woocommerce' ) . '
    • ' . + '
    ' . + '

    ' . __( 'If you create an account, we will store your name, address, email and phone number, which will be used to populate the checkout for future orders.', 'woocommerce' ) . '

    ' . + '

    ' . __( 'We generally store information about you for as long as we need the information for the purposes for which we collect and use it, and we are not legally required to continue to keep it. For example, we will store order information for XXX years for tax and accounting purposes. This includes your name, email address and billing and shipping addresses.', 'woocommerce' ) . '

    ' . + '

    ' . __( 'We will also store comments or reviews, if you choose to leave them.', 'woocommerce' ) . '

    ' . + '

    ' . __( 'Who on our team has access', 'woocommerce' ) . '

    ' . + '

    ' . __( 'Members of our team have access to the information you provide us. For example, both Administrators and Shop Managers can access:', 'woocommerce' ) . '

    ' . + '
      ' . + '
    • ' . __( 'Order information like what was purchased, when it was purchased and where it should be sent, and', 'woocommerce' ) . '
    • ' . + '
    • ' . __( 'Customer information like your name, email address, and billing and shipping information.', 'woocommerce' ) . '
    • ' . + '
    ' . + '

    ' . __( 'Our team members have access to this information to help fulfill orders, process refunds and support you.', 'woocommerce' ) . '

    ' . + '

    ' . __( 'What we share with others', 'woocommerce' ) . '

    ' . + '

    ' . + __( 'In this section you should list who you’re sharing data with, and for what purpose. This could include, but may not be limited to, analytics, marketing, payment gateways, shipping providers, and third party embeds.', 'woocommerce' ) . + '

    ' . + '

    ' . __( 'We share information with third parties who help us provide our orders and store services to you; for example --', 'woocommerce' ) . '

    ' . + '

    ' . __( 'Payments', 'woocommerce' ) . '

    ' . + '

    ' . + __( 'In this subsection you should list which third party payment processors you’re using to take payments on your store since these may handle customer data. We’ve included PayPal as an example, but you should remove this if you’re not using PayPal.', 'woocommerce' ) . + '

    ' . + '

    ' . __( 'We accept payments through PayPal. When processing payments, some of your data will be passed to PayPal, including information required to process or support the payment, such as the purchase total and billing information.', 'woocommerce' ) . '

    ' . + '

    ' . __( 'Please see the PayPal Privacy Policy for more details.', 'woocommerce' ) . '

    ' . + '
    '; + + return apply_filters( 'wc_privacy_policy_content', $content ); + } + + /** + * Spawn events for order cleanup. + */ + public function queue_cleanup_personal_data() { + self::$background_process->push_to_queue( array( 'task' => 'trash_pending_orders' ) ); + self::$background_process->push_to_queue( array( 'task' => 'trash_failed_orders' ) ); + self::$background_process->push_to_queue( array( 'task' => 'trash_cancelled_orders' ) ); + self::$background_process->push_to_queue( array( 'task' => 'anonymize_completed_orders' ) ); + self::$background_process->push_to_queue( array( 'task' => 'delete_inactive_accounts' ) ); + self::$background_process->save()->dispatch(); + } + + /** + * Handle some custom types of data and anonymize them. + * + * @param string $anonymous Anonymized string. + * @param string $type Type of data. + * @param string $data The data being anonymized. + * @return string Anonymized string. + */ + public function anonymize_custom_data_types( $anonymous, $type, $data ) { + switch ( $type ) { + case 'address_state': + case 'address_country': + $anonymous = ''; // Empty string - we don't want to store anything after removal. + break; + case 'phone': + $anonymous = preg_replace( '/\d/u', '0', $data ); + break; + case 'numeric_id': + $anonymous = 0; + break; + } + return $anonymous; + } + + /** + * Find and trash old orders. + * + * @since 3.4.0 + * @param int $limit Limit orders to process per batch. + * @return int Number of orders processed. + */ + public static function trash_pending_orders( $limit = 20 ) { + $option = wc_parse_relative_date_option( get_option( 'woocommerce_trash_pending_orders' ) ); + + if ( empty( $option['number'] ) ) { + return 0; + } + + return self::trash_orders_query( + apply_filters( + 'woocommerce_trash_pending_orders_query_args', + array( + 'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ), + 'limit' => $limit, // Batches of 20. + 'status' => 'wc-pending', + 'type' => 'shop_order', + ) + ) + ); + } + + /** + * Find and trash old orders. + * + * @since 3.4.0 + * @param int $limit Limit orders to process per batch. + * @return int Number of orders processed. + */ + public static function trash_failed_orders( $limit = 20 ) { + $option = wc_parse_relative_date_option( get_option( 'woocommerce_trash_failed_orders' ) ); + + if ( empty( $option['number'] ) ) { + return 0; + } + + return self::trash_orders_query( + apply_filters( + 'woocommerce_trash_failed_orders_query_args', + array( + 'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ), + 'limit' => $limit, // Batches of 20. + 'status' => 'wc-failed', + 'type' => 'shop_order', + ) + ) + ); + } + + /** + * Find and trash old orders. + * + * @since 3.4.0 + * @param int $limit Limit orders to process per batch. + * @return int Number of orders processed. + */ + public static function trash_cancelled_orders( $limit = 20 ) { + $option = wc_parse_relative_date_option( get_option( 'woocommerce_trash_cancelled_orders' ) ); + + if ( empty( $option['number'] ) ) { + return 0; + } + + return self::trash_orders_query( + apply_filters( + 'woocommerce_trash_cancelled_orders_query_args', + array( + 'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ), + 'limit' => $limit, // Batches of 20. + 'status' => 'wc-cancelled', + 'type' => 'shop_order', + ) + ) + ); + } + + /** + * For a given query trash all matches. + * + * @since 3.4.0 + * @param array $query Query array to pass to wc_get_orders(). + * @return int Count of orders that were trashed. + */ + protected static function trash_orders_query( $query ) { + $orders = wc_get_orders( $query ); + $count = 0; + + if ( $orders ) { + foreach ( $orders as $order ) { + $order->delete( false ); + $count ++; + } + } + + return $count; + } + + /** + * Anonymize old completed orders. + * + * @since 3.4.0 + * @param int $limit Limit orders to process per batch. + * @return int Number of orders processed. + */ + public static function anonymize_completed_orders( $limit = 20 ) { + $option = wc_parse_relative_date_option( get_option( 'woocommerce_anonymize_completed_orders' ) ); + + if ( empty( $option['number'] ) ) { + return 0; + } + + return self::anonymize_orders_query( + apply_filters( + 'woocommerce_anonymize_completed_orders_query_args', + array( + 'date_created' => '<' . strtotime( '-' . $option['number'] . ' ' . $option['unit'] ), + 'limit' => $limit, // Batches of 20. + 'status' => 'wc-completed', + 'anonymized' => false, + 'type' => 'shop_order', + ) + ) + ); + } + + /** + * For a given query, anonymize all matches. + * + * @since 3.4.0 + * @param array $query Query array to pass to wc_get_orders(). + * @return int Count of orders that were anonymized. + */ + protected static function anonymize_orders_query( $query ) { + $orders = wc_get_orders( $query ); + $count = 0; + + if ( $orders ) { + foreach ( $orders as $order ) { + WC_Privacy_Erasers::remove_order_personal_data( $order ); + $count ++; + } + } + + return $count; + } + + /** + * Delete inactive accounts. + * + * @since 3.4.0 + * @param int $limit Limit users to process per batch. + * @return int Number of users processed. + */ + public static function delete_inactive_accounts( $limit = 20 ) { + $option = wc_parse_relative_date_option( get_option( 'woocommerce_delete_inactive_accounts' ) ); + + if ( empty( $option['number'] ) ) { + return 0; + } + + return self::delete_inactive_accounts_query( strtotime( '-' . $option['number'] . ' ' . $option['unit'] ), $limit ); + } + + /** + * Delete inactive accounts. + * + * @since 3.4.0 + * @param int $timestamp Timestamp to delete customers before. + * @param int $limit Limit number of users to delete per run. + * @return int Count of customers that were deleted. + */ + protected static function delete_inactive_accounts_query( $timestamp, $limit = 20 ) { + $count = 0; + $user_query = new WP_User_Query( + array( + 'fields' => 'ID', + 'number' => $limit, + 'role__in' => apply_filters( + 'woocommerce_delete_inactive_account_roles', + array( + 'Customer', + 'Subscriber', + ) + ), + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + 'relation' => 'AND', + array( + 'key' => 'wc_last_active', + 'value' => (string) $timestamp, + 'compare' => '<', + 'type' => 'NUMERIC', + ), + array( + 'key' => 'wc_last_active', + 'value' => '0', + 'compare' => '>', + 'type' => 'NUMERIC', + ), + ), + ) + ); + + $user_ids = $user_query->get_results(); + + if ( $user_ids ) { + if ( ! function_exists( 'wp_delete_user' ) ) { + require_once ABSPATH . 'wp-admin/includes/user.php'; + } + + foreach ( $user_ids as $user_id ) { + wp_delete_user( $user_id ); + $count ++; + } + } + + return $count; + } +} + +new WC_Privacy(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-attribute.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-attribute.php new file mode 100644 index 0000000..14f1901 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-attribute.php @@ -0,0 +1,329 @@ + 0, + 'name' => '', + 'options' => array(), + 'position' => 0, + 'visible' => false, + 'variation' => false, + ); + + /** + * Return if this attribute is a taxonomy. + * + * @return boolean + */ + public function is_taxonomy() { + return 0 < $this->get_id(); + } + + /** + * Get taxonomy name if applicable. + * + * @return string + */ + public function get_taxonomy() { + return $this->is_taxonomy() ? $this->get_name() : ''; + } + + /** + * Get taxonomy object. + * + * @return array|null + */ + public function get_taxonomy_object() { + global $wc_product_attributes; + return $this->is_taxonomy() ? $wc_product_attributes[ $this->get_name() ] : null; + } + + /** + * Gets terms from the stored options. + * + * @return array|null + */ + public function get_terms() { + if ( ! $this->is_taxonomy() || ! taxonomy_exists( $this->get_name() ) ) { + return null; + } + $terms = array(); + foreach ( $this->get_options() as $option ) { + if ( is_int( $option ) ) { + $term = get_term_by( 'id', $option, $this->get_name() ); + } else { + // Term names get escaped in WP. See sanitize_term_field. + $term = get_term_by( 'name', $option, $this->get_name() ); + + if ( ! $term || is_wp_error( $term ) ) { + $new_term = wp_insert_term( $option, $this->get_name() ); + $term = is_wp_error( $new_term ) ? false : get_term_by( 'id', $new_term['term_id'], $this->get_name() ); + } + } + if ( $term && ! is_wp_error( $term ) ) { + $terms[] = $term; + } + } + return $terms; + } + + /** + * Gets slugs from the stored options, or just the string if text based. + * + * @return array + */ + public function get_slugs() { + if ( ! $this->is_taxonomy() || ! taxonomy_exists( $this->get_name() ) ) { + return $this->get_options(); + } + $terms = array(); + foreach ( $this->get_options() as $option ) { + if ( is_int( $option ) ) { + $term = get_term_by( 'id', $option, $this->get_name() ); + } else { + $term = get_term_by( 'name', $option, $this->get_name() ); + + if ( ! $term || is_wp_error( $term ) ) { + $new_term = wp_insert_term( $option, $this->get_name() ); + $term = is_wp_error( $new_term ) ? false : get_term_by( 'id', $new_term['term_id'], $this->get_name() ); + } + } + if ( $term && ! is_wp_error( $term ) ) { + $terms[] = $term->slug; + } + } + return $terms; + } + + /** + * Returns all data for this object. + * + * @return array + */ + public function get_data() { + return array_merge( + $this->data, + array( + 'is_visible' => $this->get_visible() ? 1 : 0, + 'is_variation' => $this->get_variation() ? 1 : 0, + 'is_taxonomy' => $this->is_taxonomy() ? 1 : 0, + 'value' => $this->is_taxonomy() ? '' : wc_implode_text_attributes( $this->get_options() ), + ) + ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set ID (this is the attribute ID). + * + * @param int $value Attribute ID. + */ + public function set_id( $value ) { + $this->data['id'] = absint( $value ); + } + + /** + * Set name (this is the attribute name or taxonomy). + * + * @param int $value Attribute name. + */ + public function set_name( $value ) { + $this->data['name'] = $value; + } + + /** + * Set options. + * + * @param array $value Attribute options. + */ + public function set_options( $value ) { + $this->data['options'] = $value; + } + + /** + * Set position. + * + * @param int $value Attribute position. + */ + public function set_position( $value ) { + $this->data['position'] = absint( $value ); + } + + /** + * Set if visible. + * + * @param bool $value If is visible on Product's additional info tab. + */ + public function set_visible( $value ) { + $this->data['visible'] = wc_string_to_bool( $value ); + } + + /** + * Set if variation. + * + * @param bool $value If is used for variations. + */ + public function set_variation( $value ) { + $this->data['variation'] = wc_string_to_bool( $value ); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get the ID. + * + * @return int + */ + public function get_id() { + return $this->data['id']; + } + + /** + * Get name. + * + * @return string + */ + public function get_name() { + return $this->data['name']; + } + + /** + * Get options. + * + * @return array + */ + public function get_options() { + return $this->data['options']; + } + + /** + * Get position. + * + * @return int + */ + public function get_position() { + return $this->data['position']; + } + + /** + * Get if visible. + * + * @return bool + */ + public function get_visible() { + return $this->data['visible']; + } + + /** + * Get if variation. + * + * @return bool + */ + public function get_variation() { + return $this->data['variation']; + } + + /* + |-------------------------------------------------------------------------- + | ArrayAccess/Backwards compatibility. + |-------------------------------------------------------------------------- + */ + + /** + * OffsetGet. + * + * @param string $offset Offset. + * @return mixed + */ + public function offsetGet( $offset ) { + switch ( $offset ) { + case 'is_variation': + return $this->get_variation() ? 1 : 0; + case 'is_visible': + return $this->get_visible() ? 1 : 0; + case 'is_taxonomy': + return $this->is_taxonomy() ? 1 : 0; + case 'value': + return $this->is_taxonomy() ? '' : wc_implode_text_attributes( $this->get_options() ); + default: + if ( is_callable( array( $this, "get_$offset" ) ) ) { + return $this->{"get_$offset"}(); + } + break; + } + return ''; + } + + /** + * OffsetSet. + * + * @param string $offset Offset. + * @param mixed $value Value. + */ + public function offsetSet( $offset, $value ) { + switch ( $offset ) { + case 'is_variation': + $this->set_variation( $value ); + break; + case 'is_visible': + $this->set_visible( $value ); + break; + case 'value': + $this->set_options( $value ); + break; + default: + if ( is_callable( array( $this, "set_$offset" ) ) ) { + return $this->{"set_$offset"}( $value ); + } + break; + } + } + + /** + * OffsetUnset. + * + * @param string $offset Offset. + */ + public function offsetUnset( $offset ) {} + + /** + * OffsetExists. + * + * @param string $offset Offset. + * @return bool + */ + public function offsetExists( $offset ) { + return in_array( $offset, array_merge( array( 'is_variation', 'is_visible', 'is_taxonomy', 'value' ), array_keys( $this->data ) ), true ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-download.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-download.php new file mode 100644 index 0000000..1c13bf1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-download.php @@ -0,0 +1,276 @@ + '', + 'name' => '', + 'file' => '', + ); + + /** + * Returns all data for this object. + * + * @return array + */ + public function get_data() { + return $this->data; + } + + /** + * Get allowed mime types. + * + * @return array + */ + public function get_allowed_mime_types() { + return apply_filters( 'woocommerce_downloadable_file_allowed_mime_types', get_allowed_mime_types() ); + } + + /** + * Get type of file path set. + * + * @param string $file_path optional. + * @return string absolute, relative, or shortcode. + */ + public function get_type_of_file_path( $file_path = '' ) { + $file_path = $file_path ? $file_path : $this->get_file(); + if ( 0 === strpos( $file_path, 'http' ) || 0 === strpos( $file_path, '//' ) ) { + return 'absolute'; + } elseif ( '[' === substr( $file_path, 0, 1 ) && ']' === substr( $file_path, -1 ) ) { + return 'shortcode'; + } else { + return 'relative'; + } + } + + /** + * Get file type. + * + * @return string + */ + public function get_file_type() { + $type = wp_check_filetype( strtok( $this->get_file(), '?' ), $this->get_allowed_mime_types() ); + return $type['type']; + } + + /** + * Get file extension. + * + * @return string + */ + public function get_file_extension() { + $parsed_url = wp_parse_url( $this->get_file(), PHP_URL_PATH ); + return pathinfo( $parsed_url, PATHINFO_EXTENSION ); + } + + /** + * Check if file is allowed. + * + * @return boolean + */ + public function is_allowed_filetype() { + $file_path = $this->get_file(); + + // File types for URL-based files located on the server should get validated. + $is_file_on_server = false; + if ( false !== stripos( $file_path, network_site_url( '/', 'https' ) ) || + false !== stripos( $file_path, network_site_url( '/', 'http' ) ) || + false !== stripos( $file_path, site_url( '/', 'https' ) ) || + false !== stripos( $file_path, site_url( '/', 'http' ) ) + ) { + $is_file_on_server = true; + } + + if ( ! $is_file_on_server && 'relative' !== $this->get_type_of_file_path() ) { + return true; + } + return ! $this->get_file_extension() || in_array( $this->get_file_type(), $this->get_allowed_mime_types(), true ); + } + + /** + * Validate file exists. + * + * @return boolean + */ + public function file_exists() { + if ( 'relative' !== $this->get_type_of_file_path() ) { + return true; + } + $file_url = $this->get_file(); + if ( '..' === substr( $file_url, 0, 2 ) || '/' !== substr( $file_url, 0, 1 ) ) { + $file_url = realpath( ABSPATH . $file_url ); + } elseif ( substr( WP_CONTENT_DIR, strlen( untrailingslashit( ABSPATH ) ) ) === substr( $file_url, 0, strlen( substr( WP_CONTENT_DIR, strlen( untrailingslashit( ABSPATH ) ) ) ) ) ) { + $file_url = realpath( WP_CONTENT_DIR . substr( $file_url, 11 ) ); + } + return apply_filters( 'woocommerce_downloadable_file_exists', file_exists( $file_url ), $this->get_file() ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set ID. + * + * @param string $value Download ID. + */ + public function set_id( $value ) { + $this->data['id'] = wc_clean( $value ); + } + + /** + * Set name. + * + * @param string $value Download name. + */ + public function set_name( $value ) { + $this->data['name'] = wc_clean( $value ); + } + + /** + * Set previous_hash. + * + * @deprecated 3.3.0 No longer using filename based hashing to keep track of files. + * @param string $value Previous hash. + */ + public function set_previous_hash( $value ) { + wc_deprecated_function( __FUNCTION__, '3.3' ); + $this->data['previous_hash'] = wc_clean( $value ); + } + + /** + * Set file. + * + * @param string $value File URL/Path. + */ + public function set_file( $value ) { + switch ( $this->get_type_of_file_path( $value ) ) { + case 'absolute': + $this->data['file'] = esc_url_raw( $value ); + break; + default: + $this->data['file'] = wc_clean( $value ); + break; + } + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get id. + * + * @return string + */ + public function get_id() { + return $this->data['id']; + } + + /** + * Get name. + * + * @return string + */ + public function get_name() { + return $this->data['name']; + } + + /** + * Get previous_hash. + * + * @deprecated 3.3.0 No longer using filename based hashing to keep track of files. + * @return string + */ + public function get_previous_hash() { + wc_deprecated_function( __FUNCTION__, '3.3' ); + return $this->data['previous_hash']; + } + + /** + * Get file. + * + * @return string + */ + public function get_file() { + return $this->data['file']; + } + + /* + |-------------------------------------------------------------------------- + | ArrayAccess/Backwards compatibility. + |-------------------------------------------------------------------------- + */ + + /** + * OffsetGet. + * + * @param string $offset Offset. + * @return mixed + */ + public function offsetGet( $offset ) { + switch ( $offset ) { + default: + if ( is_callable( array( $this, "get_$offset" ) ) ) { + return $this->{"get_$offset"}(); + } + break; + } + return ''; + } + + /** + * OffsetSet. + * + * @param string $offset Offset. + * @param mixed $value Offset value. + */ + public function offsetSet( $offset, $value ) { + switch ( $offset ) { + default: + if ( is_callable( array( $this, "set_$offset" ) ) ) { + return $this->{"set_$offset"}( $value ); + } + break; + } + } + + /** + * OffsetUnset. + * + * @param string $offset Offset. + */ + public function offsetUnset( $offset ) {} + + /** + * OffsetExists. + * + * @param string $offset Offset. + * @return bool + */ + public function offsetExists( $offset ) { + return in_array( $offset, array_keys( $this->data ), true ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-external.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-external.php new file mode 100644 index 0000000..f88d45f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-external.php @@ -0,0 +1,194 @@ + '', + 'button_text' => '', + ); + + /** + * Get internal type. + * + * @return string + */ + public function get_type() { + return 'external'; + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + | + | Methods for getting data from the product object. + */ + + /** + * Get product url. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_product_url( $context = 'view' ) { + return esc_url_raw( $this->get_prop( 'product_url', $context ) ); + } + + /** + * Get button text. + * + * @param string $context What the value is for. Valid values are 'view' and 'edit'. + * @return string + */ + public function get_button_text( $context = 'view' ) { + return $this->get_prop( 'button_text', $context ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + | + | Functions for setting product data. These should not update anything in the + | database itself and should only change what is stored in the class + | object. + */ + + /** + * Set product URL. + * + * @since 3.0.0 + * @param string $product_url Product URL. + */ + public function set_product_url( $product_url ) { + $this->set_prop( 'product_url', htmlspecialchars_decode( $product_url ) ); + } + + /** + * Set button text. + * + * @since 3.0.0 + * @param string $button_text Button text. + */ + public function set_button_text( $button_text ) { + $this->set_prop( 'button_text', $button_text ); + } + + /** + * External products cannot be stock managed. + * + * @since 3.0.0 + * @param bool $manage_stock If manage stock. + */ + public function set_manage_stock( $manage_stock ) { + $this->set_prop( 'manage_stock', false ); + + if ( true === $manage_stock ) { + $this->error( 'product_external_invalid_manage_stock', __( 'External products cannot be stock managed.', 'woocommerce' ) ); + } + } + + /** + * External products cannot be stock managed. + * + * @since 3.0.0 + * + * @param string $stock_status Stock status. + */ + public function set_stock_status( $stock_status = '' ) { + $this->set_prop( 'stock_status', 'instock' ); + + if ( 'instock' !== $stock_status ) { + $this->error( 'product_external_invalid_stock_status', __( 'External products cannot be stock managed.', 'woocommerce' ) ); + } + } + + /** + * External products cannot be backordered. + * + * @since 3.0.0 + * @param string $backorders Options: 'yes', 'no' or 'notify'. + */ + public function set_backorders( $backorders ) { + $this->set_prop( 'backorders', 'no' ); + + if ( 'no' !== $backorders ) { + $this->error( 'product_external_invalid_backorders', __( 'External products cannot be backordered.', 'woocommerce' ) ); + } + } + + /* + |-------------------------------------------------------------------------- + | Other Actions + |-------------------------------------------------------------------------- + */ + + /** + * Returns false if the product cannot be bought. + * + * @access public + * @return bool + */ + public function is_purchasable() { + return apply_filters( 'woocommerce_is_purchasable', false, $this ); + } + + /** + * Get the add to url used mainly in loops. + * + * @access public + * @return string + */ + public function add_to_cart_url() { + return apply_filters( 'woocommerce_product_add_to_cart_url', $this->get_product_url(), $this ); + } + + /** + * Get the add to cart button text for the single page. + * + * @access public + * @return string + */ + public function single_add_to_cart_text() { + return apply_filters( 'woocommerce_product_single_add_to_cart_text', $this->get_button_text() ? $this->get_button_text() : _x( 'Buy product', 'placeholder', 'woocommerce' ), $this ); + } + + /** + * Get the add to cart button text. + * + * @access public + * @return string + */ + public function add_to_cart_text() { + return apply_filters( 'woocommerce_product_add_to_cart_text', $this->get_button_text() ? $this->get_button_text() : _x( 'Buy product', 'placeholder', 'woocommerce' ), $this ); + } + + /** + * Get the add to cart button text description - used in aria tags. + * + * @since 3.3.0 + * @return string + */ + public function add_to_cart_description() { + /* translators: %s: Product title */ + return apply_filters( 'woocommerce_product_add_to_cart_description', $this->get_button_text() ? $this->get_button_text() : sprintf( __( 'Buy “%s”', 'woocommerce' ), $this->get_name() ), $this ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-factory.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-factory.php new file mode 100644 index 0000000..9344f67 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-factory.php @@ -0,0 +1,119 @@ +get_product_id( $product_id ); + + if ( ! $product_id ) { + return false; + } + + $product_type = $this->get_product_type( $product_id ); + + // Backwards compatibility. + if ( ! empty( $deprecated ) ) { + wc_deprecated_argument( 'args', '3.0', 'Passing args to the product factory is deprecated. If you need to force a type, construct the product class directly.' ); + + if ( isset( $deprecated['product_type'] ) ) { + $product_type = $this->get_classname_from_product_type( $deprecated['product_type'] ); + } + } + + $classname = $this->get_product_classname( $product_id, $product_type ); + + try { + return new $classname( $product_id, $deprecated ); + } catch ( Exception $e ) { + return false; + } + } + + /** + * Gets a product classname and allows filtering. Returns WC_Product_Simple if the class does not exist. + * + * @since 3.0.0 + * @param int $product_id Product ID. + * @param string $product_type Product type. + * @return string + */ + public static function get_product_classname( $product_id, $product_type ) { + $classname = apply_filters( 'woocommerce_product_class', self::get_classname_from_product_type( $product_type ), $product_type, 'variation' === $product_type ? 'product_variation' : 'product', $product_id ); + + if ( ! $classname || ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + + return $classname; + } + + /** + * Get the product type for a product. + * + * @since 3.0.0 + * @param int $product_id Product ID. + * @return string|false + */ + public static function get_product_type( $product_id ) { + // Allow the overriding of the lookup in this function. Return the product type here. + $override = apply_filters( 'woocommerce_product_type_query', false, $product_id ); + if ( ! $override ) { + return WC_Data_Store::load( 'product' )->get_product_type( $product_id ); + } else { + return $override; + } + } + + /** + * Create a WC coding standards compliant class name e.g. WC_Product_Type_Class instead of WC_Product_type-class. + * + * @param string $product_type Product type. + * @return string|false + */ + public static function get_classname_from_product_type( $product_type ) { + return $product_type ? 'WC_Product_' . implode( '_', array_map( 'ucfirst', explode( '-', $product_type ) ) ) : false; + } + + /** + * Get the product ID depending on what was passed. + * + * @since 3.0.0 + * @param WC_Product|WP_Post|int|bool $product Product instance, post instance, numeric or false to use global $post. + * @return int|bool false on failure + */ + private function get_product_id( $product ) { + global $post; + + if ( false === $product && isset( $post, $post->ID ) && 'product' === get_post_type( $post->ID ) ) { + return absint( $post->ID ); + } elseif ( is_numeric( $product ) ) { + return $product; + } elseif ( $product instanceof WC_Product ) { + return $product->get_id(); + } elseif ( ! empty( $product->ID ) ) { + return $product->ID; + } else { + return false; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-grouped.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-grouped.php new file mode 100644 index 0000000..e2b19d0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-grouped.php @@ -0,0 +1,193 @@ + array(), + ); + + /** + * Get internal type. + * + * @return string + */ + public function get_type() { + return 'grouped'; + } + + /** + * Get the add to cart button text. + * + * @return string + */ + public function add_to_cart_text() { + return apply_filters( 'woocommerce_product_add_to_cart_text', __( 'View products', 'woocommerce' ), $this ); + } + + /** + * Get the add to cart button text description - used in aria tags. + * + * @since 3.3.0 + * @return string + */ + public function add_to_cart_description() { + /* translators: %s: Product title */ + return apply_filters( 'woocommerce_product_add_to_cart_description', sprintf( __( 'View products in the “%s” group', 'woocommerce' ), $this->get_name() ), $this ); + } + + /** + * Returns whether or not the product is on sale. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return bool + */ + public function is_on_sale( $context = 'view' ) { + $children = array_filter( array_map( 'wc_get_product', $this->get_children( $context ) ), 'wc_products_array_filter_visible_grouped' ); + $on_sale = false; + + foreach ( $children as $child ) { + if ( $child->is_purchasable() && ! $child->has_child() && $child->is_on_sale() ) { + $on_sale = true; + break; + } + } + + return 'view' === $context ? apply_filters( 'woocommerce_product_is_on_sale', $on_sale, $this ) : $on_sale; + } + + /** + * Returns false if the product cannot be bought. + * + * @return bool + */ + public function is_purchasable() { + return apply_filters( 'woocommerce_is_purchasable', false, $this ); + } + + /** + * Returns the price in html format. + * + * @param string $price (default: ''). + * @return string + */ + public function get_price_html( $price = '' ) { + $tax_display_mode = get_option( 'woocommerce_tax_display_shop' ); + $child_prices = array(); + $children = array_filter( array_map( 'wc_get_product', $this->get_children() ), 'wc_products_array_filter_visible_grouped' ); + + foreach ( $children as $child ) { + if ( '' !== $child->get_price() ) { + $child_prices[] = 'incl' === $tax_display_mode ? wc_get_price_including_tax( $child ) : wc_get_price_excluding_tax( $child ); + } + } + + if ( ! empty( $child_prices ) ) { + $min_price = min( $child_prices ); + $max_price = max( $child_prices ); + } else { + $min_price = ''; + $max_price = ''; + } + + if ( '' !== $min_price ) { + if ( $min_price !== $max_price ) { + $price = wc_format_price_range( $min_price, $max_price ); + } else { + $price = wc_price( $min_price ); + } + + $is_free = 0 === $min_price && 0 === $max_price; + + if ( $is_free ) { + $price = apply_filters( 'woocommerce_grouped_free_price_html', __( 'Free!', 'woocommerce' ), $this ); + } else { + $price = apply_filters( 'woocommerce_grouped_price_html', $price . $this->get_price_suffix(), $this, $child_prices ); + } + } else { + $price = apply_filters( 'woocommerce_grouped_empty_price_html', '', $this ); + } + + return apply_filters( 'woocommerce_get_price_html', $price, $this ); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + | + | Methods for getting data from the product object. + */ + + /** + * Return the children of this product. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return array + */ + public function get_children( $context = 'view' ) { + return $this->get_prop( 'children', $context ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + | + | Methods for getting data from the product object. + */ + + /** + * Return the children of this product. + * + * @param array $children List of product children. + */ + public function set_children( $children ) { + $this->set_prop( 'children', array_filter( wp_parse_id_list( (array) $children ) ) ); + } + + /* + |-------------------------------------------------------------------------- + | Sync with children. + |-------------------------------------------------------------------------- + */ + + /** + * Sync a grouped product with it's children. These sync functions sync + * upwards (from child to parent) when the variation is saved. + * + * @param WC_Product|int $product Product object or ID for which you wish to sync. + * @param bool $save If true, the product object will be saved to the DB before returning it. + * @return WC_Product Synced product object. + */ + public static function sync( $product, $save = true ) { + if ( ! is_a( $product, 'WC_Product' ) ) { + $product = wc_get_product( $product ); + } + if ( is_a( $product, 'WC_Product_Grouped' ) ) { + $data_store = WC_Data_Store::load( 'product-' . $product->get_type() ); + $data_store->sync_price( $product ); + if ( $save ) { + $product->save(); + } + } + return $product; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-query.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-query.php new file mode 100644 index 0000000..8562a1f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-query.php @@ -0,0 +1,79 @@ + array( 'draft', 'pending', 'private', 'publish' ), + 'type' => array_merge( array_keys( wc_get_product_types() ) ), + 'limit' => get_option( 'posts_per_page' ), + 'include' => array(), + 'date_created' => '', + 'date_modified' => '', + 'featured' => '', + 'visibility' => '', + 'sku' => '', + 'price' => '', + 'regular_price' => '', + 'sale_price' => '', + 'date_on_sale_from' => '', + 'date_on_sale_to' => '', + 'total_sales' => '', + 'tax_status' => '', + 'tax_class' => '', + 'manage_stock' => '', + 'stock_quantity' => '', + 'stock_status' => '', + 'backorders' => '', + 'low_stock_amount' => '', + 'sold_individually' => '', + 'weight' => '', + 'length' => '', + 'width' => '', + 'height' => '', + 'reviews_allowed' => '', + 'virtual' => '', + 'downloadable' => '', + 'category' => array(), + 'tag' => array(), + 'shipping_class' => array(), + 'download_limit' => '', + 'download_expiry' => '', + 'average_rating' => '', + 'review_count' => '', + ) + ); + } + + /** + * Get products matching the current query vars. + * + * @return array|object of WC_Product objects + */ + public function get_products() { + $args = apply_filters( 'woocommerce_product_object_query_args', $this->get_query_vars() ); + $results = WC_Data_Store::load( 'product' )->query( $args ); + return apply_filters( 'woocommerce_product_object_query', $results, $args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-simple.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-simple.php new file mode 100644 index 0000000..6dfebfc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-simple.php @@ -0,0 +1,77 @@ +supports[] = 'ajax_add_to_cart'; + parent::__construct( $product ); + } + + /** + * Get internal type. + * + * @return string + */ + public function get_type() { + return 'simple'; + } + + /** + * Get the add to url used mainly in loops. + * + * @return string + */ + public function add_to_cart_url() { + $url = $this->is_purchasable() && $this->is_in_stock() ? remove_query_arg( + 'added-to-cart', + add_query_arg( + array( + 'add-to-cart' => $this->get_id(), + ), + ( function_exists( 'is_feed' ) && is_feed() ) || ( function_exists( 'is_404' ) && is_404() ) ? $this->get_permalink() : '' + ) + ) : $this->get_permalink(); + return apply_filters( 'woocommerce_product_add_to_cart_url', $url, $this ); + } + + /** + * Get the add to cart button text. + * + * @return string + */ + public function add_to_cart_text() { + $text = $this->is_purchasable() && $this->is_in_stock() ? __( 'Add to cart', 'woocommerce' ) : __( 'Read more', 'woocommerce' ); + + return apply_filters( 'woocommerce_product_add_to_cart_text', $text, $this ); + } + + /** + * Get the add to cart button text description - used in aria tags. + * + * @since 3.3.0 + * @return string + */ + public function add_to_cart_description() { + /* translators: %s: Product title */ + $text = $this->is_purchasable() && $this->is_in_stock() ? __( 'Add “%s” to your cart', 'woocommerce' ) : __( 'Read more about “%s”', 'woocommerce' ); + + return apply_filters( 'woocommerce_product_add_to_cart_description', sprintf( $text, $this->get_name() ), $this ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-variable.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-variable.php new file mode 100644 index 0000000..78900dd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-variable.php @@ -0,0 +1,675 @@ +is_purchasable() ? __( 'Select options', 'woocommerce' ) : __( 'Read more', 'woocommerce' ), $this ); + } + + /** + * Get the add to cart button text description - used in aria tags. + * + * @since 3.3.0 + * @return string + */ + public function add_to_cart_description() { + /* translators: %s: Product title */ + return apply_filters( 'woocommerce_product_add_to_cart_description', sprintf( __( 'Select options for “%s”', 'woocommerce' ), $this->get_name() ), $this ); + } + + /** + * Get an array of all sale and regular prices from all variations. This is used for example when displaying the price range at variable product level or seeing if the variable product is on sale. + * + * @param bool $for_display If true, prices will be adapted for display based on the `woocommerce_tax_display_shop` setting (including or excluding taxes). + * @return array Array of RAW prices, regular prices, and sale prices with keys set to variation ID. + */ + public function get_variation_prices( $for_display = false ) { + $prices = $this->data_store->read_price_data( $this, $for_display ); + + foreach ( $prices as $price_key => $variation_prices ) { + $prices[ $price_key ] = $this->sort_variation_prices( $variation_prices ); + } + + return $prices; + } + + /** + * Get the min or max variation regular price. + * + * @param string $min_or_max Min or max price. + * @param boolean $for_display If true, prices will be adapted for display based on the `woocommerce_tax_display_shop` setting (including or excluding taxes). + * @return string + */ + public function get_variation_regular_price( $min_or_max = 'min', $for_display = false ) { + $prices = $this->get_variation_prices( $for_display ); + $price = 'min' === $min_or_max ? current( $prices['regular_price'] ) : end( $prices['regular_price'] ); + + return apply_filters( 'woocommerce_get_variation_regular_price', $price, $this, $min_or_max, $for_display ); + } + + /** + * Get the min or max variation sale price. + * + * @param string $min_or_max Min or max price. + * @param boolean $for_display If true, prices will be adapted for display based on the `woocommerce_tax_display_shop` setting (including or excluding taxes). + * @return string + */ + public function get_variation_sale_price( $min_or_max = 'min', $for_display = false ) { + $prices = $this->get_variation_prices( $for_display ); + $price = 'min' === $min_or_max ? current( $prices['sale_price'] ) : end( $prices['sale_price'] ); + + return apply_filters( 'woocommerce_get_variation_sale_price', $price, $this, $min_or_max, $for_display ); + } + + /** + * Get the min or max variation (active) price. + * + * @param string $min_or_max Min or max price. + * @param boolean $for_display If true, prices will be adapted for display based on the `woocommerce_tax_display_shop` setting (including or excluding taxes). + * @return string + */ + public function get_variation_price( $min_or_max = 'min', $for_display = false ) { + $prices = $this->get_variation_prices( $for_display ); + $price = 'min' === $min_or_max ? current( $prices['price'] ) : end( $prices['price'] ); + + return apply_filters( 'woocommerce_get_variation_price', $price, $this, $min_or_max, $for_display ); + } + + /** + * Returns the price in html format. + * + * Note: Variable prices do not show suffixes like other product types. This + * is due to some things like tax classes being set at variation level which + * could differ from the parent price. The only way to show accurate prices + * would be to load the variation and get it's price, which adds extra + * overhead and still has edge cases where the values would be inaccurate. + * + * Additionally, ranges of prices no longer show 'striked out' sale prices + * due to the strings being very long and unclear/confusing. A single range + * is shown instead. + * + * @param string $price Price (default: ''). + * @return string + */ + public function get_price_html( $price = '' ) { + $prices = $this->get_variation_prices( true ); + + if ( empty( $prices['price'] ) ) { + $price = apply_filters( 'woocommerce_variable_empty_price_html', '', $this ); + } else { + $min_price = current( $prices['price'] ); + $max_price = end( $prices['price'] ); + $min_reg_price = current( $prices['regular_price'] ); + $max_reg_price = end( $prices['regular_price'] ); + + if ( $min_price !== $max_price ) { + $price = wc_format_price_range( $min_price, $max_price ); + } elseif ( $this->is_on_sale() && $min_reg_price === $max_reg_price ) { + $price = wc_format_sale_price( wc_price( $max_reg_price ), wc_price( $min_price ) ); + } else { + $price = wc_price( $min_price ); + } + + $price = apply_filters( 'woocommerce_variable_price_html', $price . $this->get_price_suffix(), $this ); + } + + return apply_filters( 'woocommerce_get_price_html', $price, $this ); + } + + /** + * Get the suffix to display after prices > 0. + * + * This is skipped if the suffix + * has dynamic values such as {price_excluding_tax} for variable products. + * + * @see get_price_html for an explanation as to why. + * @param string $price Price to calculate, left blank to just use get_price(). + * @param integer $qty Quantity passed on to get_price_including_tax() or get_price_excluding_tax(). + * @return string + */ + public function get_price_suffix( $price = '', $qty = 1 ) { + $suffix = get_option( 'woocommerce_price_display_suffix' ); + + if ( strstr( $suffix, '{' ) ) { + return apply_filters( 'woocommerce_get_price_suffix', '', $this, $price, $qty ); + } else { + return parent::get_price_suffix( $price, $qty ); + } + } + + /** + * Return a products child ids. + * + * This is lazy loaded as it's not used often and does require several queries. + * + * @param bool|string $visible_only Visible only. + * @return array Children ids + */ + public function get_children( $visible_only = '' ) { + if ( is_bool( $visible_only ) ) { + wc_deprecated_argument( 'visible_only', '3.0', 'WC_Product_Variable::get_visible_children' ); + + return $visible_only ? $this->get_visible_children() : $this->get_children(); + } + + if ( null === $this->children ) { + $children = $this->data_store->read_children( $this ); + $this->set_children( $children['all'] ); + $this->set_visible_children( $children['visible'] ); + } + + return apply_filters( 'woocommerce_get_children', $this->children, $this, false ); + } + + /** + * Return a products child ids - visible only. + * + * This is lazy loaded as it's not used often and does require several queries. + * + * @since 3.0.0 + * @return array Children ids + */ + public function get_visible_children() { + if ( null === $this->visible_children ) { + $children = $this->data_store->read_children( $this ); + $this->set_children( $children['all'] ); + $this->set_visible_children( $children['visible'] ); + } + return apply_filters( 'woocommerce_get_children', $this->visible_children, $this, true ); + } + + /** + * Return an array of attributes used for variations, as well as their possible values. + * + * This is lazy loaded as it's not used often and does require several queries. + * + * @return array Attributes and their available values + */ + public function get_variation_attributes() { + if ( null === $this->variation_attributes ) { + $this->variation_attributes = $this->data_store->read_variation_attributes( $this ); + } + return $this->variation_attributes; + } + + /** + * If set, get the default attributes for a variable product. + * + * @param string $attribute_name Attribute name. + * @return string + */ + public function get_variation_default_attribute( $attribute_name ) { + $defaults = $this->get_default_attributes(); + $attribute_name = sanitize_title( $attribute_name ); + + return isset( $defaults[ $attribute_name ] ) ? $defaults[ $attribute_name ] : ''; + } + + /** + * Variable products themselves cannot be downloadable. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return bool + */ + public function get_downloadable( $context = 'view' ) { + return false; + } + + /** + * Variable products themselves cannot be virtual. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return bool + */ + public function get_virtual( $context = 'view' ) { + return false; + } + + /** + * Get an array of available variations for the current product. + * + * @param string $return Optional. The format to return the results in. Can be 'array' to return an array of variation data or 'objects' for the product objects. Default 'array'. + * + * @return array[]|WC_Product_Variation[] + */ + public function get_available_variations( $return = 'array' ) { + $variation_ids = $this->get_children(); + $available_variations = array(); + + if ( is_callable( '_prime_post_caches' ) ) { + _prime_post_caches( $variation_ids ); + } + + foreach ( $variation_ids as $variation_id ) { + + $variation = wc_get_product( $variation_id ); + + // Hide out of stock variations if 'Hide out of stock items from the catalog' is checked. + if ( ! $variation || ! $variation->exists() || ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && ! $variation->is_in_stock() ) ) { + continue; + } + + // Filter 'woocommerce_hide_invisible_variations' to optionally hide invisible variations (disabled variations and variations with empty price). + if ( apply_filters( 'woocommerce_hide_invisible_variations', true, $this->get_id(), $variation ) && ! $variation->variation_is_visible() ) { + continue; + } + + if ( 'array' === $return ) { + $available_variations[] = $this->get_available_variation( $variation ); + } else { + $available_variations[] = $variation; + } + } + + if ( 'array' === $return ) { + $available_variations = array_values( array_filter( $available_variations ) ); + } + + return $available_variations; + } + + /** + * Check if a given variation is currently available. + * + * @param WC_Product_Variation $variation Variation to check. + * + * @return bool True if the variation is available, false otherwise. + */ + private function variation_is_available( WC_Product_Variation $variation ) { + // Hide out of stock variations if 'Hide out of stock items from the catalog' is checked. + if ( ! $variation || ! $variation->exists() || ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && ! $variation->is_in_stock() ) ) { + return false; + } + + // Filter 'woocommerce_hide_invisible_variations' to optionally hide invisible variations (disabled variations and variations with empty price). + if ( apply_filters( 'woocommerce_hide_invisible_variations', true, $this->get_id(), $variation ) && ! $variation->variation_is_visible() ) { + return false; + } + + return true; + } + + /** + * Returns an array of data for a variation. Used in the add to cart form. + * + * @since 2.4.0 + * @param WC_Product $variation Variation product object or ID. + * @return array|bool + */ + public function get_available_variation( $variation ) { + if ( is_numeric( $variation ) ) { + $variation = wc_get_product( $variation ); + } + if ( ! $variation instanceof WC_Product_Variation ) { + return false; + } + // See if prices should be shown for each variation after selection. + $show_variation_price = apply_filters( 'woocommerce_show_variation_price', $variation->get_price() === '' || $this->get_variation_sale_price( 'min' ) !== $this->get_variation_sale_price( 'max' ) || $this->get_variation_regular_price( 'min' ) !== $this->get_variation_regular_price( 'max' ), $this, $variation ); + + return apply_filters( + 'woocommerce_available_variation', + array( + 'attributes' => $variation->get_variation_attributes(), + 'availability_html' => wc_get_stock_html( $variation ), + 'backorders_allowed' => $variation->backorders_allowed(), + 'dimensions' => $variation->get_dimensions( false ), + 'dimensions_html' => wc_format_dimensions( $variation->get_dimensions( false ) ), + 'display_price' => wc_get_price_to_display( $variation ), + 'display_regular_price' => wc_get_price_to_display( $variation, array( 'price' => $variation->get_regular_price() ) ), + 'image' => wc_get_product_attachment_props( $variation->get_image_id() ), + 'image_id' => $variation->get_image_id(), + 'is_downloadable' => $variation->is_downloadable(), + 'is_in_stock' => $variation->is_in_stock(), + 'is_purchasable' => $variation->is_purchasable(), + 'is_sold_individually' => $variation->is_sold_individually() ? 'yes' : 'no', + 'is_virtual' => $variation->is_virtual(), + 'max_qty' => 0 < $variation->get_max_purchase_quantity() ? $variation->get_max_purchase_quantity() : '', + 'min_qty' => $variation->get_min_purchase_quantity(), + 'price_html' => $show_variation_price ? '' . $variation->get_price_html() . '' : '', + 'sku' => $variation->get_sku(), + 'variation_description' => wc_format_content( $variation->get_description() ), + 'variation_id' => $variation->get_id(), + 'variation_is_active' => $variation->variation_is_active(), + 'variation_is_visible' => $variation->variation_is_visible(), + 'weight' => $variation->get_weight(), + 'weight_html' => wc_format_weight( $variation->get_weight() ), + ), + $this, + $variation + ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Sets an array of variation attributes. + * + * @since 3.0.0 + * @param array $variation_attributes Attributes list. + */ + public function set_variation_attributes( $variation_attributes ) { + $this->variation_attributes = $variation_attributes; + } + + /** + * Sets an array of children for the product. + * + * @since 3.0.0 + * @param array $children Children products. + */ + public function set_children( $children ) { + $this->children = array_filter( wp_parse_id_list( (array) $children ) ); + } + + /** + * Sets an array of visible children only. + * + * @since 3.0.0 + * @param array $visible_children List of visible children products. + */ + public function set_visible_children( $visible_children ) { + $this->visible_children = array_filter( wp_parse_id_list( (array) $visible_children ) ); + } + + /* + |-------------------------------------------------------------------------- + | CRUD methods + |-------------------------------------------------------------------------- + */ + + /** + * Ensure properties are set correctly before save. + * + * @since 3.0.0 + */ + public function validate_props() { + parent::validate_props(); + + if ( ! $this->get_manage_stock() ) { + $this->data_store->sync_stock_status( $this ); + } + } + + /** + * Save data (either create or update depending on if we are working on an existing product). + * + * @since 3.0.0 + */ + public function save() { + $this->validate_props(); + + if ( ! $this->data_store ) { + return $this->get_id(); + } + + /** + * Trigger action before saving to the DB. Allows you to adjust object props before save. + * + * @param WC_Data $this The object being saved. + * @param WC_Data_Store_WP $data_store The data store persisting the data. + */ + do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store ); + + // Get names before save. + $previous_name = $this->data['name']; + $new_name = $this->get_name( 'edit' ); + + if ( $this->get_id() ) { + $this->data_store->update( $this ); + } else { + $this->data_store->create( $this ); + } + + $this->data_store->sync_variation_names( $this, $previous_name, $new_name ); + $this->data_store->sync_managed_variation_stock_status( $this ); + + /** + * Trigger action after saving to the DB. + * + * @param WC_Data $this The object being saved. + * @param WC_Data_Store_WP $data_store The data store persisting the data. + */ + do_action( 'woocommerce_after_' . $this->object_type . '_object_save', $this, $this->data_store ); + + return $this->get_id(); + } + + /* + |-------------------------------------------------------------------------- + | Conditionals + |-------------------------------------------------------------------------- + */ + + /** + * Returns whether or not the product is on sale. + * + * @param string $context What the value is for. Valid values are view and edit. What the value is for. Valid values are view and edit. + * @return bool + */ + public function is_on_sale( $context = 'view' ) { + $prices = $this->get_variation_prices(); + $on_sale = $prices['regular_price'] !== $prices['sale_price'] && $prices['sale_price'] === $prices['price']; + + return 'view' === $context ? apply_filters( 'woocommerce_product_is_on_sale', $on_sale, $this ) : $on_sale; + } + + /** + * Is a child in stock? + * + * @return boolean + */ + public function child_is_in_stock() { + return $this->data_store->child_is_in_stock( $this ); + } + + /** + * Is a child on backorder? + * + * @since 3.3.0 + * @return boolean + */ + public function child_is_on_backorder() { + return $this->data_store->child_has_stock_status( $this, 'onbackorder' ); + } + + /** + * Does a child have a weight set? + * + * @return boolean + */ + public function child_has_weight() { + $transient_name = 'wc_child_has_weight_' . $this->get_id(); + $has_weight = get_transient( $transient_name ); + + if ( false === $has_weight ) { + $has_weight = $this->data_store->child_has_weight( $this ); + set_transient( $transient_name, (int) $has_weight, DAY_IN_SECONDS * 30 ); + } + + return (bool) $has_weight; + } + + /** + * Does a child have dimensions set? + * + * @return boolean + */ + public function child_has_dimensions() { + $transient_name = 'wc_child_has_dimensions_' . $this->get_id(); + $has_dimension = get_transient( $transient_name ); + + if ( false === $has_dimension ) { + $has_dimension = $this->data_store->child_has_dimensions( $this ); + set_transient( $transient_name, (int) $has_dimension, DAY_IN_SECONDS * 30 ); + } + + return (bool) $has_dimension; + } + + /** + * Returns whether or not the product has dimensions set. + * + * @return bool + */ + public function has_dimensions() { + return parent::has_dimensions() || $this->child_has_dimensions(); + } + + /** + * Returns whether or not the product has weight set. + * + * @return bool + */ + public function has_weight() { + return parent::has_weight() || $this->child_has_weight(); + } + + /** + * Returns whether or not the product has additional options that need + * selecting before adding to cart. + * + * @since 3.0.0 + * @return boolean + */ + public function has_options() { + return apply_filters( 'woocommerce_product_has_options', true, $this ); + } + + + /* + |-------------------------------------------------------------------------- + | Sync with child variations. + |-------------------------------------------------------------------------- + */ + + /** + * Sync a variable product with it's children. These sync functions sync + * upwards (from child to parent) when the variation is saved. + * + * @param WC_Product|int $product Product object or ID for which you wish to sync. + * @param bool $save If true, the product object will be saved to the DB before returning it. + * @return WC_Product Synced product object. + */ + public static function sync( $product, $save = true ) { + if ( ! is_a( $product, 'WC_Product' ) ) { + $product = wc_get_product( $product ); + } + if ( is_a( $product, 'WC_Product_Variable' ) ) { + $data_store = WC_Data_Store::load( 'product-' . $product->get_type() ); + $data_store->sync_price( $product ); + $data_store->sync_stock_status( $product ); + self::sync_attributes( $product ); // Legacy update of attributes. + + do_action( 'woocommerce_variable_product_sync_data', $product ); + + if ( $save ) { + $product->save(); + } + + wc_do_deprecated_action( + 'woocommerce_variable_product_sync', + array( + $product->get_id(), + $product->get_visible_children(), + ), + '3.0', + 'woocommerce_variable_product_sync_data, woocommerce_new_product or woocommerce_update_product' + ); + } + + return $product; + } + + /** + * Sync parent stock status with the status of all children and save. + * + * @param WC_Product|int $product Product object or ID for which you wish to sync. + * @param bool $save If true, the product object will be saved to the DB before returning it. + * @return WC_Product Synced product object. + */ + public static function sync_stock_status( $product, $save = true ) { + if ( ! is_a( $product, 'WC_Product' ) ) { + $product = wc_get_product( $product ); + } + if ( is_a( $product, 'WC_Product_Variable' ) ) { + $data_store = WC_Data_Store::load( 'product-' . $product->get_type() ); + $data_store->sync_stock_status( $product ); + + if ( $save ) { + $product->save(); + } + } + + return $product; + } + + /** + * Sort an associative array of $variation_id => $price pairs in order of min and max prices. + * + * @param array $prices associative array of $variation_id => $price pairs. + * @return array + */ + protected function sort_variation_prices( $prices ) { + asort( $prices ); + + return $prices; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-variation.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-variation.php new file mode 100644 index 0000000..ebd2838 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-product-variation.php @@ -0,0 +1,603 @@ + '', + 'sku' => '', + 'manage_stock' => '', + 'backorders' => '', + 'stock_quantity' => '', + 'weight' => '', + 'length' => '', + 'width' => '', + 'height' => '', + 'tax_class' => '', + 'shipping_class_id' => '', + 'image_id' => '', + 'purchase_note' => '', + ); + + /** + * Override the default constructor to set custom defaults. + * + * @param int|WC_Product|object $product Product to init. + */ + public function __construct( $product = 0 ) { + $this->data['tax_class'] = 'parent'; + $this->data['attribute_summary'] = ''; + parent::__construct( $product ); + } + + /** + * Prefix for action and filter hooks on data. + * + * @since 3.0.0 + * @return string + */ + protected function get_hook_prefix() { + return 'woocommerce_product_variation_get_'; + } + + /** + * Get internal type. + * + * @return string + */ + public function get_type() { + return 'variation'; + } + + /** + * If the stock level comes from another product ID. + * + * @since 3.0.0 + * @return int + */ + public function get_stock_managed_by_id() { + return 'parent' === $this->get_manage_stock() ? $this->get_parent_id() : $this->get_id(); + } + + /** + * Get the product's title. For variations this is the parent product name. + * + * @return string + */ + public function get_title() { + return apply_filters( 'woocommerce_product_title', $this->parent_data['title'], $this ); + } + + /** + * Get product name with SKU or ID. Used within admin. + * + * @return string Formatted product name + */ + public function get_formatted_name() { + if ( $this->get_sku() ) { + $identifier = $this->get_sku(); + } else { + $identifier = '#' . $this->get_id(); + } + + $formatted_variation_list = wc_get_formatted_variation( $this, true, true, true ); + + return sprintf( '%2$s (%1$s)', $identifier, $this->get_name() ) . '' . $formatted_variation_list . ''; + } + + /** + * Get variation attribute values. Keys are prefixed with attribute_, as stored, unless $with_prefix is false. + * + * @param bool $with_prefix Whether keys should be prepended with attribute_ or not, default is true. + * @return array of attributes and their values for this variation. + */ + public function get_variation_attributes( $with_prefix = true ) { + $attributes = $this->get_attributes(); + $variation_attributes = array(); + $prefix = $with_prefix ? 'attribute_' : ''; + + foreach ( $attributes as $key => $value ) { + $variation_attributes[ $prefix . $key ] = $value; + } + return $variation_attributes; + } + + /** + * Returns a single product attribute as a string. + * + * @param string $attribute to get. + * @return string + */ + public function get_attribute( $attribute ) { + $attributes = $this->get_attributes(); + $attribute = sanitize_title( $attribute ); + + if ( isset( $attributes[ $attribute ] ) ) { + $value = $attributes[ $attribute ]; + $term = taxonomy_exists( $attribute ) ? get_term_by( 'slug', $value, $attribute ) : false; + return ! is_wp_error( $term ) && $term ? $term->name : $value; + } + + $att_str = 'pa_' . $attribute; + if ( isset( $attributes[ $att_str ] ) ) { + $value = $attributes[ $att_str ]; + $term = taxonomy_exists( $att_str ) ? get_term_by( 'slug', $value, $att_str ) : false; + return ! is_wp_error( $term ) && $term ? $term->name : $value; + } + + return ''; + } + + /** + * Wrapper for get_permalink. Adds this variations attributes to the URL. + * + * @param array|null $item_object item array If a cart or order item is passed, we can get a link containing the exact attributes selected for the variation, rather than the default attributes. + * @return string + */ + public function get_permalink( $item_object = null ) { + $url = get_permalink( $this->get_parent_id() ); + + if ( ! empty( $item_object['variation'] ) ) { + $data = $item_object['variation']; + } elseif ( ! empty( $item_object['item_meta_array'] ) ) { + $data_keys = array_map( 'wc_variation_attribute_name', wp_list_pluck( $item_object['item_meta_array'], 'key' ) ); + $data_values = wp_list_pluck( $item_object['item_meta_array'], 'value' ); + $data = array_intersect_key( array_combine( $data_keys, $data_values ), $this->get_variation_attributes() ); + } else { + $data = $this->get_variation_attributes(); + } + + $data = array_filter( $data, 'wc_array_filter_default_attributes' ); + + if ( empty( $data ) ) { + return $url; + } + + // Filter and encode keys and values so this is not broken by add_query_arg. + $data = array_map( 'urlencode', $data ); + $keys = array_map( 'urlencode', array_keys( $data ) ); + + return add_query_arg( array_combine( $keys, $data ), $url ); + } + + /** + * Get the add to url used mainly in loops. + * + * @return string + */ + public function add_to_cart_url() { + $url = $this->is_purchasable() ? remove_query_arg( + 'added-to-cart', + add_query_arg( + array( + 'variation_id' => $this->get_id(), + 'add-to-cart' => $this->get_parent_id(), + ), + $this->get_permalink() + ) + ) : $this->get_permalink(); + return apply_filters( 'woocommerce_product_add_to_cart_url', $url, $this ); + } + + /** + * Get SKU (Stock-keeping unit) - product unique ID. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_sku( $context = 'view' ) { + $value = $this->get_prop( 'sku', $context ); + + // Inherit value from parent. + if ( 'view' === $context && empty( $value ) ) { + $value = apply_filters( $this->get_hook_prefix() . 'sku', $this->parent_data['sku'], $this ); + } + return $value; + } + + /** + * Returns the product's weight. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_weight( $context = 'view' ) { + $value = $this->get_prop( 'weight', $context ); + + // Inherit value from parent. + if ( 'view' === $context && empty( $value ) ) { + $value = apply_filters( $this->get_hook_prefix() . 'weight', $this->parent_data['weight'], $this ); + } + return $value; + } + + /** + * Returns the product length. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_length( $context = 'view' ) { + $value = $this->get_prop( 'length', $context ); + + // Inherit value from parent. + if ( 'view' === $context && empty( $value ) ) { + $value = apply_filters( $this->get_hook_prefix() . 'length', $this->parent_data['length'], $this ); + } + return $value; + } + + /** + * Returns the product width. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_width( $context = 'view' ) { + $value = $this->get_prop( 'width', $context ); + + // Inherit value from parent. + if ( 'view' === $context && empty( $value ) ) { + $value = apply_filters( $this->get_hook_prefix() . 'width', $this->parent_data['width'], $this ); + } + return $value; + } + + /** + * Returns the product height. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_height( $context = 'view' ) { + $value = $this->get_prop( 'height', $context ); + + // Inherit value from parent. + if ( 'view' === $context && empty( $value ) ) { + $value = apply_filters( $this->get_hook_prefix() . 'height', $this->parent_data['height'], $this ); + } + return $value; + } + + /** + * Returns the tax class. + * + * Does not use get_prop so it can handle 'parent' inheritance correctly. + * + * @param string $context view, edit, or unfiltered. + * @return string + */ + public function get_tax_class( $context = 'view' ) { + $value = null; + + if ( array_key_exists( 'tax_class', $this->data ) ) { + $value = array_key_exists( 'tax_class', $this->changes ) ? $this->changes['tax_class'] : $this->data['tax_class']; + + if ( 'edit' !== $context && 'parent' === $value ) { + $value = $this->parent_data['tax_class']; + } + + if ( 'view' === $context ) { + $value = apply_filters( $this->get_hook_prefix() . 'tax_class', $value, $this ); + } + } + return $value; + } + + /** + * Return if product manage stock. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return boolean|string true, false, or parent. + */ + public function get_manage_stock( $context = 'view' ) { + $value = $this->get_prop( 'manage_stock', $context ); + + // Inherit value from parent. + if ( 'view' === $context && false === $value && true === wc_string_to_bool( $this->parent_data['manage_stock'] ) ) { + $value = 'parent'; + } + return $value; + } + + /** + * Returns number of items available for sale. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int|null + */ + public function get_stock_quantity( $context = 'view' ) { + $value = $this->get_prop( 'stock_quantity', $context ); + + // Inherit value from parent. + if ( 'view' === $context && 'parent' === $this->get_manage_stock() ) { + $value = apply_filters( $this->get_hook_prefix() . 'stock_quantity', $this->parent_data['stock_quantity'], $this ); + } + return $value; + } + + /** + * Get backorders. + * + * @param string $context What the value is for. Valid values are view and edit. + * @since 3.0.0 + * @return string yes no or notify + */ + public function get_backorders( $context = 'view' ) { + $value = $this->get_prop( 'backorders', $context ); + + // Inherit value from parent. + if ( 'view' === $context && 'parent' === $this->get_manage_stock() ) { + $value = apply_filters( $this->get_hook_prefix() . 'backorders', $this->parent_data['backorders'], $this ); + } + return $value; + } + + /** + * Get main image ID. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_image_id( $context = 'view' ) { + $image_id = $this->get_prop( 'image_id', $context ); + + if ( 'view' === $context && ! $image_id ) { + $image_id = apply_filters( $this->get_hook_prefix() . 'image_id', $this->parent_data['image_id'], $this ); + } + + return $image_id; + } + + /** + * Get purchase note. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_purchase_note( $context = 'view' ) { + $value = $this->get_prop( 'purchase_note', $context ); + + // Inherit value from parent. + if ( 'view' === $context && empty( $value ) ) { + $value = apply_filters( $this->get_hook_prefix() . 'purchase_note', $this->parent_data['purchase_note'], $this ); + } + return $value; + } + + /** + * Get shipping class ID. + * + * @since 3.0.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ + public function get_shipping_class_id( $context = 'view' ) { + $shipping_class_id = $this->get_prop( 'shipping_class_id', $context ); + + if ( 'view' === $context && ! $shipping_class_id ) { + $shipping_class_id = apply_filters( $this->get_hook_prefix() . 'shipping_class_id', $this->parent_data['shipping_class_id'], $this ); + } + + return $shipping_class_id; + } + + /** + * Get catalog visibility. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return string + */ + public function get_catalog_visibility( $context = 'view' ) { + return apply_filters( $this->get_hook_prefix() . 'catalog_visibility', $this->parent_data['catalog_visibility'], $this ); + } + + /** + * Get attribute summary. + * + * By default, attribute summary contains comma-delimited 'attribute_name: attribute_value' pairs for all attributes. + * + * @param string $context What the value is for. Valid values are view and edit. + * + * @since 3.6.0 + * @return string + */ + public function get_attribute_summary( $context = 'view' ) { + return $this->get_prop( 'attribute_summary', $context ); + } + + + /** + * Set attribute summary. + * + * By default, attribute summary contains comma-delimited 'attribute_name: attribute_value' pairs for all attributes. + * + * @since 3.6.0 + * @param string $attribute_summary Summary of attribute names and values assigned to the variation. + */ + public function set_attribute_summary( $attribute_summary ) { + $this->set_prop( 'attribute_summary', $attribute_summary ); + } + + /* + |-------------------------------------------------------------------------- + | CRUD methods + |-------------------------------------------------------------------------- + */ + + /** + * Set the parent data array for this variation. + * + * @since 3.0.0 + * @param array $parent_data parent data array for this variation. + */ + public function set_parent_data( $parent_data ) { + $parent_data = wp_parse_args( + $parent_data, + array( + 'title' => '', + 'status' => '', + 'sku' => '', + 'manage_stock' => 'no', + 'backorders' => 'no', + 'stock_quantity' => '', + 'weight' => '', + 'length' => '', + 'width' => '', + 'height' => '', + 'tax_class' => '', + 'shipping_class_id' => 0, + 'image_id' => 0, + 'purchase_note' => '', + 'catalog_visibility' => 'visible', + ) + ); + + // Normalize tax class. + $parent_data['tax_class'] = sanitize_title( $parent_data['tax_class'] ); + $parent_data['tax_class'] = 'standard' === $parent_data['tax_class'] ? '' : $parent_data['tax_class']; + $valid_classes = $this->get_valid_tax_classes(); + + if ( ! in_array( $parent_data['tax_class'], $valid_classes, true ) ) { + $parent_data['tax_class'] = ''; + } + + $this->parent_data = $parent_data; + } + + /** + * Get the parent data array for this variation. + * + * @since 3.0.0 + * @return array + */ + public function get_parent_data() { + return $this->parent_data; + } + + /** + * Set attributes. Unlike the parent product which uses terms, variations are assigned + * specific attributes using name value pairs. + * + * @param array $raw_attributes array of raw attributes. + */ + public function set_attributes( $raw_attributes ) { + $raw_attributes = (array) $raw_attributes; + $attributes = array(); + + foreach ( $raw_attributes as $key => $value ) { + // Remove attribute prefix which meta gets stored with. + if ( 0 === strpos( $key, 'attribute_' ) ) { + $key = substr( $key, 10 ); + } + $attributes[ $key ] = $value; + } + $this->set_prop( 'attributes', $attributes ); + } + + /** + * Returns whether or not the product has any visible attributes. + * + * Variations are mapped to specific attributes unlike products, and the return + * value of ->get_attributes differs. Therefore this returns false. + * + * @return boolean + */ + public function has_attributes() { + return false; + } + + /* + |-------------------------------------------------------------------------- + | Conditionals + |-------------------------------------------------------------------------- + */ + + /** + * Returns false if the product cannot be bought. + * Override abstract method so that: i) Disabled variations are not be purchasable by admins. ii) Enabled variations are not purchasable if the parent product is not purchasable. + * + * @return bool + */ + public function is_purchasable() { + return apply_filters( 'woocommerce_variation_is_purchasable', $this->variation_is_visible() && parent::is_purchasable() && ( 'publish' === $this->parent_data['status'] || current_user_can( 'edit_post', $this->get_parent_id() ) ), $this ); + } + + /** + * Controls whether this particular variation will appear greyed-out (inactive) or not (active). + * Used by extensions to make incompatible variations appear greyed-out, etc. + * Other possible uses: prevent out-of-stock variations from being selected. + * + * @return bool + */ + public function variation_is_active() { + return apply_filters( 'woocommerce_variation_is_active', true, $this ); + } + + /** + * Checks if this particular variation is visible. Invisible variations are enabled and can be selected, but no price / stock info is displayed. + * Instead, a suitable 'unavailable' message is displayed. + * Invisible by default: Disabled variations and variations with an empty price. + * + * @return bool + */ + public function variation_is_visible() { + return apply_filters( 'woocommerce_variation_is_visible', 'publish' === get_post_status( $this->get_id() ) && '' !== $this->get_price(), $this->get_id(), $this->get_parent_id(), $this ); + } + + /** + * Return valid tax classes. Adds 'parent' to the default list of valid tax classes. + * + * @return array valid tax classes + */ + protected function get_valid_tax_classes() { + $valid_classes = WC_Tax::get_tax_class_slugs(); + $valid_classes[] = 'parent'; + + return $valid_classes; + } + + /** + * Delete variation, set the ID to 0, and return result. + * + * @since 4.4.0 + * @param bool $force_delete Should the variation be deleted permanently. + * @return bool result + */ + public function delete( $force_delete = false ) { + $variation_id = $this->get_id(); + + if ( ! parent::delete( $force_delete ) ) { + return false; + } + + return true; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-query.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-query.php new file mode 100644 index 0000000..1f2e331 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-query.php @@ -0,0 +1,971 @@ +init_query_vars(); + } + + /** + * Get any errors from querystring. + */ + public function get_errors() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $error = ! empty( $_GET['wc_error'] ) ? sanitize_text_field( wp_unslash( $_GET['wc_error'] ) ) : ''; + + if ( $error && ! wc_has_notice( $error, 'error' ) ) { + wc_add_notice( $error, 'error' ); + } + } + + /** + * Init query vars by loading options. + */ + public function init_query_vars() { + // Query vars to add to WP. + $this->query_vars = array( + // Checkout actions. + 'order-pay' => get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' ), + 'order-received' => get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' ), + // My account actions. + 'orders' => get_option( 'woocommerce_myaccount_orders_endpoint', 'orders' ), + 'view-order' => get_option( 'woocommerce_myaccount_view_order_endpoint', 'view-order' ), + 'downloads' => get_option( 'woocommerce_myaccount_downloads_endpoint', 'downloads' ), + 'edit-account' => get_option( 'woocommerce_myaccount_edit_account_endpoint', 'edit-account' ), + 'edit-address' => get_option( 'woocommerce_myaccount_edit_address_endpoint', 'edit-address' ), + 'payment-methods' => get_option( 'woocommerce_myaccount_payment_methods_endpoint', 'payment-methods' ), + 'lost-password' => get_option( 'woocommerce_myaccount_lost_password_endpoint', 'lost-password' ), + 'customer-logout' => get_option( 'woocommerce_logout_endpoint', 'customer-logout' ), + 'add-payment-method' => get_option( 'woocommerce_myaccount_add_payment_method_endpoint', 'add-payment-method' ), + 'delete-payment-method' => get_option( 'woocommerce_myaccount_delete_payment_method_endpoint', 'delete-payment-method' ), + 'set-default-payment-method' => get_option( 'woocommerce_myaccount_set_default_payment_method_endpoint', 'set-default-payment-method' ), + ); + } + + /** + * Get page title for an endpoint. + * + * @param string $endpoint Endpoint key. + * @param string $action Optional action or variation within the endpoint. + * + * @since 2.3.0 + * @since 4.6.0 Added $action parameter. + * @return string The page title. + */ + public function get_endpoint_title( $endpoint, $action = '' ) { + global $wp; + + switch ( $endpoint ) { + case 'order-pay': + $title = __( 'Pay for order', 'woocommerce' ); + break; + case 'order-received': + $title = __( 'Order received', 'woocommerce' ); + break; + case 'orders': + if ( ! empty( $wp->query_vars['orders'] ) ) { + /* translators: %s: page */ + $title = sprintf( __( 'Orders (page %d)', 'woocommerce' ), intval( $wp->query_vars['orders'] ) ); + } else { + $title = __( 'Orders', 'woocommerce' ); + } + break; + case 'view-order': + $order = wc_get_order( $wp->query_vars['view-order'] ); + /* translators: %s: order number */ + $title = ( $order ) ? sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ) : ''; + break; + case 'downloads': + $title = __( 'Downloads', 'woocommerce' ); + break; + case 'edit-account': + $title = __( 'Account details', 'woocommerce' ); + break; + case 'edit-address': + $title = __( 'Addresses', 'woocommerce' ); + break; + case 'payment-methods': + $title = __( 'Payment methods', 'woocommerce' ); + break; + case 'add-payment-method': + $title = __( 'Add payment method', 'woocommerce' ); + break; + case 'lost-password': + if ( in_array( $action, array( 'rp', 'resetpass', 'newaccount' ) ) ) { + $title = __( 'Set password', 'woocommerce' ); + } else { + $title = __( 'Lost password', 'woocommerce' ); + } + break; + default: + $title = ''; + break; + } + + /** + * Filters the page title used for my-account endpoints. + * + * @since 2.6.0 + * @since 4.6.0 Added $action parameter. + * + * @see get_endpoint_title() + * + * @param string $title Default title. + * @param string $endpoint Endpoint key. + * @param string $action Optional action or variation within the endpoint. + */ + return apply_filters( 'woocommerce_endpoint_' . $endpoint . '_title', $title, $endpoint, $action ); + } + + /** + * Endpoint mask describing the places the endpoint should be added. + * + * @since 2.6.2 + * @return int + */ + public function get_endpoints_mask() { + if ( 'page' === get_option( 'show_on_front' ) ) { + $page_on_front = get_option( 'page_on_front' ); + $myaccount_page_id = get_option( 'woocommerce_myaccount_page_id' ); + $checkout_page_id = get_option( 'woocommerce_checkout_page_id' ); + + if ( in_array( $page_on_front, array( $myaccount_page_id, $checkout_page_id ), true ) ) { + return EP_ROOT | EP_PAGES; + } + } + + return EP_PAGES; + } + + /** + * Add endpoints for query vars. + */ + public function add_endpoints() { + $mask = $this->get_endpoints_mask(); + + foreach ( $this->get_query_vars() as $key => $var ) { + if ( ! empty( $var ) ) { + add_rewrite_endpoint( $var, $mask ); + } + } + } + + /** + * Add query vars. + * + * @param array $vars Query vars. + * @return array + */ + public function add_query_vars( $vars ) { + foreach ( $this->get_query_vars() as $key => $var ) { + $vars[] = $key; + } + return $vars; + } + + /** + * Get query vars. + * + * @return array + */ + public function get_query_vars() { + return apply_filters( 'woocommerce_get_query_vars', $this->query_vars ); + } + + /** + * Get query current active query var. + * + * @return string + */ + public function get_current_endpoint() { + global $wp; + + foreach ( $this->get_query_vars() as $key => $value ) { + if ( isset( $wp->query_vars[ $key ] ) ) { + return $key; + } + } + return ''; + } + + /** + * Parse the request and look for query vars - endpoints may not be supported. + */ + public function parse_request() { + global $wp; + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + // Map query vars to their keys, or get them if endpoints are not supported. + foreach ( $this->get_query_vars() as $key => $var ) { + if ( isset( $_GET[ $var ] ) ) { + $wp->query_vars[ $key ] = sanitize_text_field( wp_unslash( $_GET[ $var ] ) ); + } elseif ( isset( $wp->query_vars[ $var ] ) ) { + $wp->query_vars[ $key ] = $wp->query_vars[ $var ]; + } + } + // phpcs:enable WordPress.Security.NonceVerification.Recommended + } + + /** + * Are we currently on the front page? + * + * @param WP_Query $q Query instance. + * @return bool + */ + private function is_showing_page_on_front( $q ) { + return ( $q->is_home() && ! $q->is_posts_page ) && 'page' === get_option( 'show_on_front' ); + } + + /** + * Is the front page a page we define? + * + * @param int $page_id Page ID. + * @return bool + */ + private function page_on_front_is( $page_id ) { + return absint( get_option( 'page_on_front' ) ) === absint( $page_id ); + } + + /** + * Hook into pre_get_posts to do the main product query. + * + * @param WP_Query $q Query instance. + */ + public function pre_get_posts( $q ) { + // We only want to affect the main query. + if ( ! $q->is_main_query() ) { + return; + } + + // Fixes for queries on static homepages. + if ( $this->is_showing_page_on_front( $q ) ) { + + // Fix for endpoints on the homepage. + if ( ! $this->page_on_front_is( $q->get( 'page_id' ) ) ) { + $_query = wp_parse_args( $q->query ); + if ( ! empty( $_query ) && array_intersect( array_keys( $_query ), array_keys( $this->get_query_vars() ) ) ) { + $q->is_page = true; + $q->is_home = false; + $q->is_singular = true; + $q->set( 'page_id', (int) get_option( 'page_on_front' ) ); + add_filter( 'redirect_canonical', '__return_false' ); + } + } + + // When orderby is set, WordPress shows posts on the front-page. Get around that here. + if ( $this->page_on_front_is( wc_get_page_id( 'shop' ) ) ) { + $_query = wp_parse_args( $q->query ); + if ( empty( $_query ) || ! array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage', 'orderby' ) ) ) { + $q->set( 'page_id', (int) get_option( 'page_on_front' ) ); + $q->is_page = true; + $q->is_home = false; + + // WP supporting themes show post type archive. + if ( current_theme_supports( 'woocommerce' ) ) { + $q->set( 'post_type', 'product' ); + } else { + $q->is_singular = true; + } + } + } elseif ( ! empty( $_GET['orderby'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $q->set( 'page_id', (int) get_option( 'page_on_front' ) ); + $q->is_page = true; + $q->is_home = false; + $q->is_singular = true; + } + } + + // Fix product feeds. + if ( $q->is_feed() && $q->is_post_type_archive( 'product' ) ) { + $q->is_comment_feed = false; + } + + // Special check for shops with the PRODUCT POST TYPE ARCHIVE on front. + if ( current_theme_supports( 'woocommerce' ) && $q->is_page() && 'page' === get_option( 'show_on_front' ) && absint( $q->get( 'page_id' ) ) === wc_get_page_id( 'shop' ) ) { + // This is a front-page shop. + $q->set( 'post_type', 'product' ); + $q->set( 'page_id', '' ); + + if ( isset( $q->query['paged'] ) ) { + $q->set( 'paged', $q->query['paged'] ); + } + + // Define a variable so we know this is the front page shop later on. + wc_maybe_define_constant( 'SHOP_IS_ON_FRONT', true ); + + // Get the actual WP page to avoid errors and let us use is_front_page(). + // This is hacky but works. Awaiting https://core.trac.wordpress.org/ticket/21096. + global $wp_post_types; + + $shop_page = get_post( wc_get_page_id( 'shop' ) ); + + $wp_post_types['product']->ID = $shop_page->ID; + $wp_post_types['product']->post_title = $shop_page->post_title; + $wp_post_types['product']->post_name = $shop_page->post_name; + $wp_post_types['product']->post_type = $shop_page->post_type; + $wp_post_types['product']->ancestors = get_ancestors( $shop_page->ID, $shop_page->post_type ); + + // Fix conditional Functions like is_front_page. + $q->is_singular = false; + $q->is_post_type_archive = true; + $q->is_archive = true; + $q->is_page = true; + + // Remove post type archive name from front page title tag. + add_filter( 'post_type_archive_title', '__return_empty_string', 5 ); + + // Fix WP SEO. + if ( class_exists( 'WPSEO_Meta' ) ) { + add_filter( 'wpseo_metadesc', array( $this, 'wpseo_metadesc' ) ); + add_filter( 'wpseo_metakey', array( $this, 'wpseo_metakey' ) ); + } + } elseif ( ! $q->is_post_type_archive( 'product' ) && ! $q->is_tax( get_object_taxonomies( 'product' ) ) ) { + // Only apply to product categories, the product post archive, the shop page, product tags, and product attribute taxonomies. + return; + } + + $this->product_query( $q ); + } + + /** + * Handler for the 'the_posts' WP filter. + * + * @param array $posts Posts from WP Query. + * @param WP_Query $query Current query. + * + * @return array + */ + public function handle_get_posts( $posts, $query ) { + if ( 'product_query' !== $query->get( 'wc_query' ) ) { + return $posts; + } + $this->remove_product_query_filters( $posts ); + return $posts; + } + + + /** + * Pre_get_posts above may adjust the main query to add WooCommerce logic. When this query is done, we need to ensure + * all custom filters are removed. + * + * This is done here during the_posts filter. The input is not changed. + * + * @param array $posts Posts from WP Query. + * @return array + */ + public function remove_product_query_filters( $posts ) { + $this->remove_ordering_args(); + remove_filter( 'posts_clauses', array( $this, 'price_filter_post_clauses' ), 10, 2 ); + return $posts; + } + + /** + * This function used to be hooked to found_posts and adjust the posts count when the filtering by attribute + * widget was used and variable products were present. Now it isn't hooked anymore and does nothing but return + * the input unchanged, since the pull request in which it was introduced has been reverted. + * + * @since 4.4.0 + * @param int $count Original posts count, as supplied by the found_posts filter. + * @param WP_Query $query The current WP_Query object. + * + * @return int Adjusted posts count. + */ + public function adjust_posts_count( $count, $query ) { + return $count; + } + + /** + * Instance version of get_layered_nav_chosen_attributes, needed for unit tests. + * + * @return array + */ + protected function get_layered_nav_chosen_attributes_inst() { + return self::get_layered_nav_chosen_attributes(); + } + + /** + * Get the posts (or the ids of the posts) found in the current WP loop. + * + * @return array Array of posts or post ids. + */ + protected function get_current_posts() { + return $GLOBALS['wp_query']->posts; + } + + /** + * WP SEO meta description. + * + * Hooked into wpseo_ hook already, so no need for function_exist. + * + * @return string + */ + public function wpseo_metadesc() { + return WPSEO_Meta::get_value( 'metadesc', wc_get_page_id( 'shop' ) ); + } + + /** + * WP SEO meta key. + * + * Hooked into wpseo_ hook already, so no need for function_exist. + * + * @return string + */ + public function wpseo_metakey() { + return WPSEO_Meta::get_value( 'metakey', wc_get_page_id( 'shop' ) ); + } + + /** + * Query the products, applying sorting/ordering etc. + * This applies to the main WordPress loop. + * + * @param WP_Query $q Query instance. + */ + public function product_query( $q ) { + if ( ! is_feed() ) { + $ordering = $this->get_catalog_ordering_args(); + $q->set( 'orderby', $ordering['orderby'] ); + $q->set( 'order', $ordering['order'] ); + + if ( isset( $ordering['meta_key'] ) ) { + $q->set( 'meta_key', $ordering['meta_key'] ); + } + } + + // Query vars that affect posts shown. + $q->set( 'meta_query', $this->get_meta_query( $q->get( 'meta_query' ), true ) ); + $q->set( 'tax_query', $this->get_tax_query( $q->get( 'tax_query' ), true ) ); + $q->set( 'wc_query', 'product_query' ); + $q->set( 'post__in', array_unique( (array) apply_filters( 'loop_shop_post_in', array() ) ) ); + + // Work out how many products to query. + $q->set( 'posts_per_page', $q->get( 'posts_per_page' ) ? $q->get( 'posts_per_page' ) : apply_filters( 'loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page() ) ); + + // Store reference to this query. + self::$product_query = $q; + + // Additonal hooks to change WP Query. + add_filter( 'posts_clauses', array( $this, 'price_filter_post_clauses' ), 10, 2 ); + add_filter( 'the_posts', array( $this, 'handle_get_posts' ), 10, 2 ); + + do_action( 'woocommerce_product_query', $q, $this ); + } + + /** + * Remove the query. + */ + public function remove_product_query() { + remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); + } + + /** + * Remove ordering queries. + */ + public function remove_ordering_args() { + remove_filter( 'posts_clauses', array( $this, 'order_by_price_asc_post_clauses' ) ); + remove_filter( 'posts_clauses', array( $this, 'order_by_price_desc_post_clauses' ) ); + remove_filter( 'posts_clauses', array( $this, 'order_by_popularity_post_clauses' ) ); + remove_filter( 'posts_clauses', array( $this, 'order_by_rating_post_clauses' ) ); + } + + /** + * Returns an array of arguments for ordering products based on the selected values. + * + * @param string $orderby Order by param. + * @param string $order Order param. + * @return array + */ + public function get_catalog_ordering_args( $orderby = '', $order = '' ) { + // Get ordering from query string unless defined. + if ( ! $orderby ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( (string) wp_unslash( $_GET['orderby'] ) ) : wc_clean( get_query_var( 'orderby' ) ); + + if ( ! $orderby_value ) { + if ( is_search() ) { + $orderby_value = 'relevance'; + } else { + $orderby_value = apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby', 'menu_order' ) ); + } + } + + // Get order + orderby args from string. + $orderby_value = is_array( $orderby_value ) ? $orderby_value : explode( '-', $orderby_value ); + $orderby = esc_attr( $orderby_value[0] ); + $order = ! empty( $orderby_value[1] ) ? $orderby_value[1] : $order; + } + + // Convert to correct format. + $orderby = strtolower( is_array( $orderby ) ? (string) current( $orderby ) : (string) $orderby ); + $order = strtoupper( is_array( $order ) ? (string) current( $order ) : (string) $order ); + $args = array( + 'orderby' => $orderby, + 'order' => ( 'DESC' === $order ) ? 'DESC' : 'ASC', + 'meta_key' => '', // @codingStandardsIgnoreLine + ); + + switch ( $orderby ) { + case 'id': + $args['orderby'] = 'ID'; + break; + case 'menu_order': + $args['orderby'] = 'menu_order title'; + break; + case 'title': + $args['orderby'] = 'title'; + $args['order'] = ( 'DESC' === $order ) ? 'DESC' : 'ASC'; + break; + case 'relevance': + $args['orderby'] = 'relevance'; + $args['order'] = 'DESC'; + break; + case 'rand': + $args['orderby'] = 'rand'; // @codingStandardsIgnoreLine + break; + case 'date': + $args['orderby'] = 'date ID'; + $args['order'] = ( 'ASC' === $order ) ? 'ASC' : 'DESC'; + break; + case 'price': + $callback = 'DESC' === $order ? 'order_by_price_desc_post_clauses' : 'order_by_price_asc_post_clauses'; + add_filter( 'posts_clauses', array( $this, $callback ) ); + break; + case 'popularity': + add_filter( 'posts_clauses', array( $this, 'order_by_popularity_post_clauses' ) ); + break; + case 'rating': + add_filter( 'posts_clauses', array( $this, 'order_by_rating_post_clauses' ) ); + break; + } + + return apply_filters( 'woocommerce_get_catalog_ordering_args', $args, $orderby, $order ); + } + + /** + * Custom query used to filter products by price. + * + * @since 3.6.0 + * + * @param array $args Query args. + * @param WP_Query $wp_query WP_Query object. + * + * @return array + */ + public function price_filter_post_clauses( $args, $wp_query ) { + global $wpdb; + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + if ( ! $wp_query->is_main_query() || ( ! isset( $_GET['max_price'] ) && ! isset( $_GET['min_price'] ) ) ) { + return $args; + } + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + $current_min_price = isset( $_GET['min_price'] ) ? floatval( wp_unslash( $_GET['min_price'] ) ) : 0; + $current_max_price = isset( $_GET['max_price'] ) ? floatval( wp_unslash( $_GET['max_price'] ) ) : PHP_INT_MAX; + // phpcs:enable WordPress.Security.NonceVerification.Recommended + + /** + * Adjust if the store taxes are not displayed how they are stored. + * Kicks in when prices excluding tax are displayed including tax. + */ + if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) { + $tax_class = apply_filters( 'woocommerce_price_filter_widget_tax_class', '' ); // Uses standard tax class. + $tax_rates = WC_Tax::get_rates( $tax_class ); + + if ( $tax_rates ) { + $current_min_price -= WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $current_min_price, $tax_rates ) ); + $current_max_price -= WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $current_max_price, $tax_rates ) ); + } + } + + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= $wpdb->prepare( + ' AND wc_product_meta_lookup.min_price >= %f AND wc_product_meta_lookup.max_price <= %f ', + $current_min_price, + $current_max_price + ); + return $args; + } + + /** + * Handle numeric price sorting. + * + * @param array $args Query args. + * @return array + */ + public function order_by_price_asc_post_clauses( $args ) { + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['orderby'] = ' wc_product_meta_lookup.min_price ASC, wc_product_meta_lookup.product_id ASC '; + return $args; + } + + /** + * Handle numeric price sorting. + * + * @param array $args Query args. + * @return array + */ + public function order_by_price_desc_post_clauses( $args ) { + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['orderby'] = ' wc_product_meta_lookup.max_price DESC, wc_product_meta_lookup.product_id DESC '; + return $args; + } + + /** + * WP Core does not let us change the sort direction for individual orderby params - https://core.trac.wordpress.org/ticket/17065. + * + * This lets us sort by meta value desc, and have a second orderby param. + * + * @param array $args Query args. + * @return array + */ + public function order_by_popularity_post_clauses( $args ) { + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['orderby'] = ' wc_product_meta_lookup.total_sales DESC, wc_product_meta_lookup.product_id DESC '; + return $args; + } + + /** + * Order by rating post clauses. + * + * @param array $args Query args. + * @return array + */ + public function order_by_rating_post_clauses( $args ) { + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['orderby'] = ' wc_product_meta_lookup.average_rating DESC, wc_product_meta_lookup.rating_count DESC, wc_product_meta_lookup.product_id DESC '; + return $args; + } + + /** + * Join wc_product_meta_lookup to posts if not already joined. + * + * @param string $sql SQL join. + * @return string + */ + private function append_product_sorting_table_join( $sql ) { + global $wpdb; + + if ( ! strstr( $sql, 'wc_product_meta_lookup' ) ) { + $sql .= " LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON $wpdb->posts.ID = wc_product_meta_lookup.product_id "; + } + return $sql; + } + + /** + * Appends meta queries to an array. + * + * @param array $meta_query Meta query. + * @param bool $main_query If is main query. + * @return array + */ + public function get_meta_query( $meta_query = array(), $main_query = false ) { + if ( ! is_array( $meta_query ) ) { + $meta_query = array(); + } + return array_filter( apply_filters( 'woocommerce_product_query_meta_query', $meta_query, $this ) ); + } + + /** + * Appends tax queries to an array. + * + * @param array $tax_query Tax query. + * @param bool $main_query If is main query. + * @return array + */ + public function get_tax_query( $tax_query = array(), $main_query = false ) { + if ( ! is_array( $tax_query ) ) { + $tax_query = array( + 'relation' => 'AND', + ); + } + + // Layered nav filters on terms. + if ( $main_query ) { + foreach ( $this->get_layered_nav_chosen_attributes() as $taxonomy => $data ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'slug', + 'terms' => $data['terms'], + 'operator' => 'and' === $data['query_type'] ? 'AND' : 'IN', + 'include_children' => false, + ); + } + } + + $product_visibility_terms = wc_get_product_visibility_term_ids(); + $product_visibility_not_in = array( is_search() && $main_query ? $product_visibility_terms['exclude-from-search'] : $product_visibility_terms['exclude-from-catalog'] ); + + // Hide out of stock products. + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) { + $product_visibility_not_in[] = $product_visibility_terms['outofstock']; + } + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + // Filter by rating. + if ( isset( $_GET['rating_filter'] ) ) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $rating_filter = array_filter( array_map( 'absint', explode( ',', wp_unslash( $_GET['rating_filter'] ) ) ) ); + $rating_terms = array(); + for ( $i = 1; $i <= 5; $i ++ ) { + if ( in_array( $i, $rating_filter, true ) && isset( $product_visibility_terms[ 'rated-' . $i ] ) ) { + $rating_terms[] = $product_visibility_terms[ 'rated-' . $i ]; + } + } + if ( ! empty( $rating_terms ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => $rating_terms, + 'operator' => 'IN', + 'rating_filter' => true, + ); + } + } + // phpcs:enable WordPress.Security.NonceVerification.Recommended + + if ( ! empty( $product_visibility_not_in ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => $product_visibility_not_in, + 'operator' => 'NOT IN', + ); + } + + return array_filter( apply_filters( 'woocommerce_product_query_tax_query', $tax_query, $this ) ); + } + + /** + * Get the main query which product queries ran against. + * + * @return WP_Query + */ + public static function get_main_query() { + return self::$product_query; + } + + /** + * Get the tax query which was used by the main query. + * + * @return array + */ + public static function get_main_tax_query() { + $tax_query = isset( self::$product_query->tax_query, self::$product_query->tax_query->queries ) ? self::$product_query->tax_query->queries : array(); + + return $tax_query; + } + + /** + * Get the meta query which was used by the main query. + * + * @return array + */ + public static function get_main_meta_query() { + $args = self::$product_query->query_vars; + $meta_query = isset( $args['meta_query'] ) ? $args['meta_query'] : array(); + + return $meta_query; + } + + /** + * Based on WP_Query::parse_search + */ + public static function get_main_search_query_sql() { + global $wpdb; + + $args = self::$product_query->query_vars; + $search_terms = isset( $args['search_terms'] ) ? $args['search_terms'] : array(); + $sql = array(); + + foreach ( $search_terms as $term ) { + // Terms prefixed with '-' should be excluded. + $include = '-' !== substr( $term, 0, 1 ); + + if ( $include ) { + $like_op = 'LIKE'; + $andor_op = 'OR'; + } else { + $like_op = 'NOT LIKE'; + $andor_op = 'AND'; + $term = substr( $term, 1 ); + } + + $like = '%' . $wpdb->esc_like( $term ) . '%'; + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $sql[] = $wpdb->prepare( "(($wpdb->posts.post_title $like_op %s) $andor_op ($wpdb->posts.post_excerpt $like_op %s) $andor_op ($wpdb->posts.post_content $like_op %s))", $like, $like, $like ); + } + + if ( ! empty( $sql ) && ! is_user_logged_in() ) { + $sql[] = "($wpdb->posts.post_password = '')"; + } + + return implode( ' AND ', $sql ); + } + + /** + * Get an array of attributes and terms selected with the layered nav widget. + * + * @return array + */ + public static function get_layered_nav_chosen_attributes() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended + if ( ! is_array( self::$chosen_attributes ) ) { + self::$chosen_attributes = array(); + + if ( ! empty( $_GET ) ) { + foreach ( $_GET as $key => $value ) { + if ( 0 === strpos( $key, 'filter_' ) ) { + $attribute = wc_sanitize_taxonomy_name( str_replace( 'filter_', '', $key ) ); + $taxonomy = wc_attribute_taxonomy_name( $attribute ); + $filter_terms = ! empty( $value ) ? explode( ',', wc_clean( wp_unslash( $value ) ) ) : array(); + + if ( empty( $filter_terms ) || ! taxonomy_exists( $taxonomy ) || ! wc_attribute_taxonomy_id_by_name( $attribute ) ) { + continue; + } + + $query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ), true ) ? wc_clean( wp_unslash( $_GET[ 'query_type_' . $attribute ] ) ) : ''; + self::$chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding. + self::$chosen_attributes[ $taxonomy ]['query_type'] = $query_type ? $query_type : apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' ); + } + } + } + } + return self::$chosen_attributes; + // phpcs:disable WordPress.Security.NonceVerification.Recommended + } + + /** + * Remove the add-to-cart param from pagination urls. + * + * @param string $url URL. + * @return string + */ + public function remove_add_to_cart_pagination( $url ) { + return remove_query_arg( 'add-to-cart', $url ); + } + + /** + * Return a meta query for filtering by rating. + * + * @deprecated 3.0.0 Replaced with taxonomy. + * @return array + */ + public function rating_filter_meta_query() { + return array(); + } + + /** + * Returns a meta query to handle product visibility. + * + * @deprecated 3.0.0 Replaced with taxonomy. + * @param string $compare (default: 'IN'). + * @return array + */ + public function visibility_meta_query( $compare = 'IN' ) { + return array(); + } + + /** + * Returns a meta query to handle product stock status. + * + * @deprecated 3.0.0 Replaced with taxonomy. + * @param string $status (default: 'instock'). + * @return array + */ + public function stock_status_meta_query( $status = 'instock' ) { + return array(); + } + + /** + * Layered nav init. + * + * @deprecated 2.6.0 + */ + public function layered_nav_init() { + wc_deprecated_function( 'layered_nav_init', '2.6' ); + } + + /** + * Get an unpaginated list all product IDs (both filtered and unfiltered). Makes use of transients. + * + * @deprecated 2.6.0 due to performance concerns + */ + public function get_products_in_view() { + wc_deprecated_function( 'get_products_in_view', '2.6' ); + } + + /** + * Layered Nav post filter. + * + * @deprecated 2.6.0 due to performance concerns + * + * @param mixed $deprecated Deprecated. + */ + public function layered_nav_query( $deprecated ) { + wc_deprecated_function( 'layered_nav_query', '2.6' ); + } + + /** + * Search post excerpt. + * + * @param string $where Where clause. + * + * @deprecated 3.2.0 - Not needed anymore since WordPress 4.5. + */ + public function search_post_excerpt( $where = '' ) { + wc_deprecated_function( 'WC_Query::search_post_excerpt', '3.2.0', 'Excerpt added to search query by default since WordPress 4.5.' ); + return $where; + } + + /** + * Remove the posts_where filter. + * + * @deprecated 3.2.0 - Nothing to remove anymore because search_post_excerpt() is deprecated. + */ + public function remove_posts_where() { + wc_deprecated_function( 'WC_Query::remove_posts_where', '3.2.0', 'Nothing to remove anymore because search_post_excerpt() is deprecated.' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-rate-limiter.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-rate-limiter.php new file mode 100644 index 0000000..aba4fb0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-rate-limiter.php @@ -0,0 +1,79 @@ +prefix = 'wp_' . get_current_blog_id(); + $this->action = 'wc_regenerate_images'; + + // This is needed to prevent timeouts due to threading. See https://core.trac.wordpress.org/ticket/36534. + @putenv( 'MAGICK_THREAD_LIMIT=1' ); // @codingStandardsIgnoreLine. + + parent::__construct(); + } + + /** + * Is job running? + * + * @return boolean + */ + public function is_running() { + return $this->is_queue_empty(); + } + + /** + * Limit each task ran per batch to 1 for image regen. + * + * @return bool + */ + protected function batch_limit_exceeded() { + return true; + } + + /** + * Determines whether an attachment can have its thumbnails regenerated. + * + * Adapted from Regenerate Thumbnails by Alex Mills. + * + * @param WP_Post $attachment An attachment's post object. + * @return bool Whether the given attachment can have its thumbnails regenerated. + */ + protected function is_regeneratable( $attachment ) { + if ( 'site-icon' === get_post_meta( $attachment->ID, '_wp_attachment_context', true ) ) { + return false; + } + + if ( wp_attachment_is_image( $attachment ) ) { + return true; + } + + return false; + } + + /** + * Code to execute for each item in the queue + * + * @param mixed $item Queue item to iterate over. + * @return bool + */ + protected function task( $item ) { + if ( ! is_array( $item ) && ! isset( $item['attachment_id'] ) ) { + return false; + } + + $this->attachment_id = absint( $item['attachment_id'] ); + $attachment = get_post( $this->attachment_id ); + + if ( ! $attachment || 'attachment' !== $attachment->post_type || ! $this->is_regeneratable( $attachment ) ) { + return false; + } + + if ( ! function_exists( 'wp_crop_image' ) ) { + include ABSPATH . 'wp-admin/includes/image.php'; + } + + $log = wc_get_logger(); + + $log->info( + sprintf( + // translators: %s: ID of the attachment. + __( 'Regenerating images for attachment ID: %s', 'woocommerce' ), + $this->attachment_id + ), + array( + 'source' => 'wc-image-regeneration', + ) + ); + + $fullsizepath = get_attached_file( $this->attachment_id ); + + // Check if the file exists, if not just remove item from queue. + if ( false === $fullsizepath || is_wp_error( $fullsizepath ) || ! file_exists( $fullsizepath ) ) { + return false; + } + + $old_metadata = wp_get_attachment_metadata( $this->attachment_id ); + + // We only want to regen WC images. + add_filter( 'intermediate_image_sizes', array( $this, 'adjust_intermediate_image_sizes' ) ); + + // We only want to resize images if they do not already exist. + add_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_image_sizes_to_only_missing_thumbnails' ), 10, 3 ); + + // This function will generate the new image sizes. + $new_metadata = wp_generate_attachment_metadata( $this->attachment_id, $fullsizepath ); + + // Remove custom filters. + remove_filter( 'intermediate_image_sizes', array( $this, 'adjust_intermediate_image_sizes' ) ); + remove_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_image_sizes_to_only_missing_thumbnails' ), 10, 3 ); + + // If something went wrong lets just remove the item from the queue. + if ( is_wp_error( $new_metadata ) || empty( $new_metadata ) ) { + return false; + } + + if ( ! empty( $old_metadata ) && ! empty( $old_metadata['sizes'] ) && is_array( $old_metadata['sizes'] ) ) { + foreach ( $old_metadata['sizes'] as $old_size => $old_size_data ) { + if ( empty( $new_metadata['sizes'][ $old_size ] ) ) { + $new_metadata['sizes'][ $old_size ] = $old_metadata['sizes'][ $old_size ]; + } + } + // Handle legacy sizes. + if ( isset( $new_metadata['sizes']['shop_thumbnail'], $new_metadata['sizes']['woocommerce_gallery_thumbnail'] ) ) { + $new_metadata['sizes']['shop_thumbnail'] = $new_metadata['sizes']['woocommerce_gallery_thumbnail']; + } + if ( isset( $new_metadata['sizes']['shop_catalog'], $new_metadata['sizes']['woocommerce_thumbnail'] ) ) { + $new_metadata['sizes']['shop_catalog'] = $new_metadata['sizes']['woocommerce_thumbnail']; + } + if ( isset( $new_metadata['sizes']['shop_single'], $new_metadata['sizes']['woocommerce_single'] ) ) { + $new_metadata['sizes']['shop_single'] = $new_metadata['sizes']['woocommerce_single']; + } + } + + // Update the meta data with the new size values. + wp_update_attachment_metadata( $this->attachment_id, $new_metadata ); + + // We made it till the end, now lets remove the item from the queue. + return false; + } + + /** + * Filters the list of thumbnail sizes to only include those which have missing files. + * + * @param array $sizes An associative array of registered thumbnail image sizes. + * @param array $metadata An associative array of fullsize image metadata: width, height, file. + * @param int $attachment_id Attachment ID. Only passed from WP 5.0+. + * @return array An associative array of image sizes. + */ + public function filter_image_sizes_to_only_missing_thumbnails( $sizes, $metadata, $attachment_id = null ) { + $attachment_id = is_null( $attachment_id ) ? $this->attachment_id : $attachment_id; + + if ( ! $sizes || ! $attachment_id ) { + return $sizes; + } + + $fullsizepath = get_attached_file( $attachment_id ); + $editor = wp_get_image_editor( $fullsizepath ); + + if ( is_wp_error( $editor ) ) { + return $sizes; + } + + $metadata = wp_get_attachment_metadata( $attachment_id ); + + // This is based on WP_Image_Editor_GD::multi_resize() and others. + foreach ( $sizes as $size => $size_data ) { + if ( empty( $metadata['sizes'][ $size ] ) ) { + continue; + } + if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { + continue; + } + if ( ! isset( $size_data['width'] ) ) { + $size_data['width'] = null; + } + if ( ! isset( $size_data['height'] ) ) { + $size_data['height'] = null; + } + if ( ! isset( $size_data['crop'] ) ) { + $size_data['crop'] = false; + } + + $image_sizes = getimagesize( $fullsizepath ); + if ( false === $image_sizes ) { + continue; + } + list( $orig_w, $orig_h ) = $image_sizes; + + $dimensions = image_resize_dimensions( $orig_w, $orig_h, $size_data['width'], $size_data['height'], $size_data['crop'] ); + + if ( ! $dimensions || ! is_array( $dimensions ) ) { + continue; + } + + $info = pathinfo( $fullsizepath ); + $ext = $info['extension']; + $dst_w = $dimensions[4]; + $dst_h = $dimensions[5]; + $suffix = "{$dst_w}x{$dst_h}"; + $dst_rel_path = str_replace( '.' . $ext, '', $fullsizepath ); + $thumbnail = "{$dst_rel_path}-{$suffix}.{$ext}"; + + if ( $dst_w === $metadata['sizes'][ $size ]['width'] && $dst_h === $metadata['sizes'][ $size ]['height'] && file_exists( $thumbnail ) ) { + unset( $sizes[ $size ] ); + } + } + + return $sizes; + } + + /** + * Returns the sizes we want to regenerate. + * + * @param array $sizes Sizes to generate. + * @return array + */ + public function adjust_intermediate_image_sizes( $sizes ) { + // Prevent a filter loop. + $unfiltered_sizes = array( 'woocommerce_thumbnail', 'woocommerce_gallery_thumbnail', 'woocommerce_single' ); + static $in_filter = false; + if ( $in_filter ) { + return $unfiltered_sizes; + } + $in_filter = true; + $filtered_sizes = apply_filters( 'woocommerce_regenerate_images_intermediate_image_sizes', $unfiltered_sizes ); + $in_filter = false; + return $filtered_sizes; + } + + /** + * This runs once the job has completed all items on the queue. + * + * @return void + */ + protected function complete() { + parent::complete(); + $log = wc_get_logger(); + $log->info( + __( 'Completed product image regeneration job.', 'woocommerce' ), + array( + 'source' => 'wc-image-regeneration', + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-regenerate-images.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-regenerate-images.php new file mode 100644 index 0000000..6e6ed20 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-regenerate-images.php @@ -0,0 +1,471 @@ +is_running() ) { + WC_Admin_Notices::add_notice( 'regenerating_thumbnails' ); + } else { + WC_Admin_Notices::remove_notice( 'regenerating_thumbnails' ); + } + } + + /** + * Dismiss notice and cancel jobs. + */ + public static function dismiss_regenerating_notice() { + if ( self::$background_process ) { + self::$background_process->kill_process(); + + $log = wc_get_logger(); + $log->info( + __( 'Cancelled product image regeneration job.', 'woocommerce' ), + array( + 'source' => 'wc-image-regeneration', + ) + ); + } + WC_Admin_Notices::remove_notice( 'regenerating_thumbnails' ); + } + + /** + * Regenerate images if the settings have changed since last re-generation. + * + * @return void + */ + public static function maybe_regenerate_images() { + $size_hash = md5( + wp_json_encode( + array( + wc_get_image_size( 'thumbnail' ), + wc_get_image_size( 'single' ), + wc_get_image_size( 'gallery_thumbnail' ), + ) + ) + ); + + if ( update_option( 'woocommerce_maybe_regenerate_images_hash', $size_hash ) ) { + // Size settings have changed. Trigger regen. + self::queue_image_regeneration(); + } + } + + /** + * Check if we should maybe generate a new image size if not already there. + * + * @param array $image Properties of the image. + * @param int $attachment_id Attachment ID. + * @param string|array $size Image size. + * @param bool $icon If icon or not. + * @return array + */ + public static function maybe_resize_image( $image, $attachment_id, $size, $icon ) { + if ( ! apply_filters( 'woocommerce_resize_images', true ) ) { + return $image; + } + + // List of sizes we want to resize. Ignore others. + if ( ! $image || ! in_array( $size, apply_filters( 'woocommerce_image_sizes_to_resize', array( 'woocommerce_thumbnail', 'woocommerce_gallery_thumbnail', 'woocommerce_single', 'shop_thumbnail', 'shop_catalog', 'shop_single' ) ), true ) ) { + return $image; + } + + $target_size = wc_get_image_size( $size ); + $image_width = $image[1]; + $image_height = $image[2]; + $ratio_match = false; + $target_uncropped = '' === $target_size['width'] || '' === $target_size['height'] || ! $target_size['crop']; + + // If '' is passed to either size, we test ratios against the original file. It's uncropped. + if ( $target_uncropped ) { + $full_size = self::get_full_size_image_dimensions( $attachment_id ); + + if ( ! $full_size || ! $full_size['width'] || ! $full_size['height'] ) { + return $image; + } + + $ratio_match = wp_image_matches_ratio( $image_width, $image_height, $full_size['width'], $full_size['height'] ); + } else { + $ratio_match = wp_image_matches_ratio( $image_width, $image_height, $target_size['width'], $target_size['height'] ); + } + + if ( ! $ratio_match ) { + $full_size = self::get_full_size_image_dimensions( $attachment_id ); + + if ( ! $full_size ) { + return $image; + } + + // Check if the actual image has a larger dimension than the requested image size. Smaller images are not zoom-cropped. + if ( $image_width === $target_size['width'] && $full_size['height'] < $target_size['height'] ) { + return $image; + } + + if ( $image_height === $target_size['height'] && $full_size['width'] < $target_size['width'] ) { + return $image; + } + + // If the full size image is smaller both ways, don't scale it up. + if ( $full_size['height'] < $target_size['height'] && $full_size['width'] < $target_size['width'] ) { + return $image; + } + + return self::resize_and_return_image( $attachment_id, $image, $size, $icon ); + } + + return $image; + } + + /** + * Get full size image dimensions. + * + * @param int $attachment_id Attachment ID of image. + * @return array Width and height. Empty array if the dimensions cannot be found. + */ + private static function get_full_size_image_dimensions( $attachment_id ) { + $imagedata = wp_get_attachment_metadata( $attachment_id ); + + if ( ! $imagedata ) { + return array(); + } + + if ( ! isset( $imagedata['file'] ) && isset( $imagedata['sizes']['full'] ) ) { + $imagedata['height'] = $imagedata['sizes']['full']['height']; + $imagedata['width'] = $imagedata['sizes']['full']['width']; + } + + return array( + 'width' => $imagedata['width'], + 'height' => $imagedata['height'], + ); + } + + /** + * Ensure we are dealing with the correct image attachment + * + * @param int|WP_Post $attachment Attachment object or ID. + * @return boolean + */ + public static function is_regeneratable( $attachment ) { + if ( 'site-icon' === get_post_meta( is_object( $attachment ) ? $attachment->ID : $attachment, '_wp_attachment_context', true ) ) { + return false; + } + + if ( wp_attachment_is_image( $attachment ) ) { + return true; + } + + return false; + } + + /** + * Only regenerate images for the requested size. + * + * @param array $sizes Array of image sizes. + * @return array + */ + public static function adjust_intermediate_image_sizes( $sizes ) { + return array( self::$regenerate_size ); + } + + /** + * Generate the thumbnail filename and dimensions for a given file. + * + * @param string $fullsizepath Path to full size image. + * @param int $thumbnail_width The width of the thumbnail. + * @param int $thumbnail_height The height of the thumbnail. + * @param bool $crop Whether to crop or not. + * @return array|false An array of the filename, thumbnail width, and thumbnail height, or false on failure to resize such as the thumbnail being larger than the fullsize image. + */ + private static function get_image( $fullsizepath, $thumbnail_width, $thumbnail_height, $crop ) { + list( $fullsize_width, $fullsize_height ) = getimagesize( $fullsizepath ); + + $dimensions = image_resize_dimensions( $fullsize_width, $fullsize_height, $thumbnail_width, $thumbnail_height, $crop ); + $editor = wp_get_image_editor( $fullsizepath ); + + if ( is_wp_error( $editor ) ) { + return false; + } + + if ( ! $dimensions || ! is_array( $dimensions ) ) { + return false; + } + + list( , , , , $dst_w, $dst_h ) = $dimensions; + $suffix = "{$dst_w}x{$dst_h}"; + $file_ext = strtolower( pathinfo( $fullsizepath, PATHINFO_EXTENSION ) ); + + return array( + 'filename' => $editor->generate_filename( $suffix, null, $file_ext ), + 'width' => $dst_w, + 'height' => $dst_h, + ); + } + + /** + * Regenerate the image according to the required size + * + * @param int $attachment_id Attachment ID. + * @param array $image Original Image. + * @param string $size Size to return for new URL. + * @param bool $icon If icon or not. + * @return string + */ + private static function resize_and_return_image( $attachment_id, $image, $size, $icon ) { + if ( ! self::is_regeneratable( $attachment_id ) ) { + return $image; + } + + $fullsizepath = get_attached_file( $attachment_id ); + + if ( false === $fullsizepath || is_wp_error( $fullsizepath ) || ! file_exists( $fullsizepath ) ) { + return $image; + } + + if ( ! function_exists( 'wp_crop_image' ) ) { + include ABSPATH . 'wp-admin/includes/image.php'; + } + + self::$regenerate_size = is_customize_preview() ? $size . '_preview' : $size; + + if ( is_customize_preview() ) { + $image_size = wc_get_image_size( $size ); + + // Make sure registered image size matches the size we're requesting. + add_image_size( self::$regenerate_size, absint( $image_size['width'] ), absint( $image_size['height'] ), $image_size['crop'] ); + + $thumbnail = self::get_image( $fullsizepath, absint( $image_size['width'] ), absint( $image_size['height'] ), $image_size['crop'] ); + + // If the file is already there perhaps just load it if we're using the customizer. No need to store in meta data. + if ( $thumbnail && file_exists( $thumbnail['filename'] ) ) { + $wp_uploads = wp_upload_dir( null, false ); + $wp_uploads_dir = $wp_uploads['basedir']; + $wp_uploads_url = $wp_uploads['baseurl']; + + return array( + 0 => str_replace( $wp_uploads_dir, $wp_uploads_url, $thumbnail['filename'] ), + 1 => $thumbnail['width'], + 2 => $thumbnail['height'], + ); + } + } + + $metadata = wp_get_attachment_metadata( $attachment_id ); + + // Fix for images with no metadata. + if ( ! is_array( $metadata ) ) { + $metadata = array(); + } + + // We only want to regen a specific image size. + add_filter( 'intermediate_image_sizes', array( __CLASS__, 'adjust_intermediate_image_sizes' ) ); + + // This function will generate the new image sizes. + $new_metadata = wp_generate_attachment_metadata( $attachment_id, $fullsizepath ); + + // Remove custom filter. + remove_filter( 'intermediate_image_sizes', array( __CLASS__, 'adjust_intermediate_image_sizes' ) ); + + // If something went wrong lets just return the original image. + if ( is_wp_error( $new_metadata ) || empty( $new_metadata ) ) { + return $image; + } + + if ( isset( $new_metadata['sizes'][ self::$regenerate_size ] ) ) { + $metadata['sizes'][ self::$regenerate_size ] = $new_metadata['sizes'][ self::$regenerate_size ]; + wp_update_attachment_metadata( $attachment_id, $metadata ); + } + + // Now we've done our regen, attempt to return the new size. + $new_image = self::unfiltered_image_downsize( $attachment_id, self::$regenerate_size ); + + return $new_image ? $new_image : $image; + } + + /** + * Image downsize, without this classes filtering on the results. + * + * @param int $attachment_id Attachment ID. + * @param string $size Size to downsize to. + * @return string New image URL. + */ + private static function unfiltered_image_downsize( $attachment_id, $size ) { + remove_action( 'image_get_intermediate_size', array( __CLASS__, 'filter_image_get_intermediate_size' ), 10, 3 ); + + $return = image_downsize( $attachment_id, $size ); + + add_action( 'image_get_intermediate_size', array( __CLASS__, 'filter_image_get_intermediate_size' ), 10, 3 ); + + return $return; + } + + /** + * Get list of images and queue them for regeneration + * + * @return void + */ + public static function queue_image_regeneration() { + global $wpdb; + // First lets cancel existing running queue to avoid running it more than once. + self::$background_process->kill_process(); + + // Now lets find all product image attachments IDs and pop them onto the queue. + $images = $wpdb->get_results( // @codingStandardsIgnoreLine + "SELECT ID + FROM $wpdb->posts + WHERE post_type = 'attachment' + AND post_mime_type LIKE 'image/%' + ORDER BY ID DESC" + ); + foreach ( $images as $image ) { + self::$background_process->push_to_queue( + array( + 'attachment_id' => $image->ID, + ) + ); + } + + // Lets dispatch the queue to start processing. + self::$background_process->save()->dispatch(); + } +} + +add_action( 'init', array( 'WC_Regenerate_Images', 'init' ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-register-wp-admin-settings.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-register-wp-admin-settings.php new file mode 100644 index 0000000..9dbefe8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-register-wp-admin-settings.php @@ -0,0 +1,180 @@ +object = $object; + + if ( 'page' === $type ) { + add_filter( 'woocommerce_settings_groups', array( $this, 'register_page_group' ) ); + add_filter( 'woocommerce_settings-' . $this->object->get_id(), array( $this, 'register_page_settings' ) ); + } elseif ( 'email' === $type ) { + add_filter( 'woocommerce_settings_groups', array( $this, 'register_email_group' ) ); + add_filter( 'woocommerce_settings-email_' . $this->object->id, array( $this, 'register_email_settings' ) ); + } + } + + /** + * Register's all of our different notification emails as sub groups + * of email settings. + * + * @since 3.0.0 + * @param array $groups Existing registered groups. + * @return array + */ + public function register_email_group( $groups ) { + $groups[] = array( + 'id' => 'email_' . $this->object->id, + 'label' => $this->object->title, + 'description' => $this->object->description, + 'parent_id' => 'email', + ); + return $groups; + } + + /** + * Registers all of the setting form fields for emails to each email type's group. + * + * @since 3.0.0 + * @param array $settings Existing registered settings. + * @return array + */ + public function register_email_settings( $settings ) { + foreach ( $this->object->form_fields as $id => $setting ) { + $setting['id'] = $id; + $setting['option_key'] = array( $this->object->get_option_key(), $id ); + $new_setting = $this->register_setting( $setting ); + if ( $new_setting ) { + $settings[] = $new_setting; + } + } + return $settings; + } + + /** + * Registers a setting group, based on admin page ID & label as parent group. + * + * @since 3.0.0 + * @param array $groups Array of previously registered groups. + * @return array + */ + public function register_page_group( $groups ) { + $groups[] = array( + 'id' => $this->object->get_id(), + 'label' => $this->object->get_label(), + ); + return $groups; + } + + /** + * Registers settings to a specific group. + * + * @since 3.0.0 + * @param array $settings Existing registered settings. + * @return array + */ + public function register_page_settings( $settings ) { + /** + * WP admin settings can be broken down into separate sections from + * a UI standpoint. This will grab all the sections associated with + * a particular setting group (like 'products') and register them + * to the REST API. + */ + $sections = $this->object->get_sections(); + if ( empty( $sections ) ) { + // Default section is just an empty string, per admin page classes. + $sections = array( '' ); + } + + foreach ( $sections as $section => $section_label ) { + $settings_from_section = $this->object->get_settings( $section ); + foreach ( $settings_from_section as $setting ) { + if ( ! isset( $setting['id'] ) ) { + continue; + } + $setting['option_key'] = $setting['id']; + $new_setting = $this->register_setting( $setting ); + if ( $new_setting ) { + $settings[] = $new_setting; + } + } + } + return $settings; + } + + /** + * Register a setting into the format expected for the Settings REST API. + * + * @since 3.0.0 + * @param array $setting Setting data. + * @return array|bool + */ + public function register_setting( $setting ) { + if ( ! isset( $setting['id'] ) ) { + return false; + } + + $description = ''; + if ( ! empty( $setting['desc'] ) ) { + $description = $setting['desc']; + } elseif ( ! empty( $setting['description'] ) ) { + $description = $setting['description']; + } + + $new_setting = array( + 'id' => $setting['id'], + 'label' => ( ! empty( $setting['title'] ) ? $setting['title'] : '' ), + 'description' => $description, + 'type' => $setting['type'], + 'option_key' => $setting['option_key'], + ); + + if ( isset( $setting['default'] ) ) { + $new_setting['default'] = $setting['default']; + } + if ( isset( $setting['options'] ) ) { + $new_setting['options'] = $setting['options']; + } + if ( isset( $setting['desc_tip'] ) ) { + if ( true === $setting['desc_tip'] ) { + $new_setting['tip'] = $description; + } elseif ( ! empty( $setting['desc_tip'] ) ) { + $new_setting['tip'] = $setting['desc_tip']; + } + } + + return $new_setting; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-rest-authentication.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-rest-authentication.php new file mode 100644 index 0000000..d31cad0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-rest-authentication.php @@ -0,0 +1,640 @@ +is_request_to_rest_api() ) { + return $user_id; + } + + if ( is_ssl() ) { + $user_id = $this->perform_basic_authentication(); + } + + if ( $user_id ) { + return $user_id; + } + + return $this->perform_oauth_authentication(); + } + + /** + * Authenticate the user if authentication wasn't performed during the + * determine_current_user action. + * + * Necessary in cases where wp_get_current_user() is called before WooCommerce is loaded. + * + * @see https://github.com/woocommerce/woocommerce/issues/26847 + * + * @param WP_Error|null|bool $error Error data. + * @return WP_Error|null|bool + */ + public function authentication_fallback( $error ) { + if ( ! empty( $error ) ) { + // Another plugin has already declared a failure. + return $error; + } + if ( empty( $this->error ) && empty( $this->auth_method ) && empty( $this->user ) && 0 === get_current_user_id() ) { + // Authentication hasn't occurred during `determine_current_user`, so check auth. + $user_id = $this->authenticate( false ); + if ( $user_id ) { + wp_set_current_user( $user_id ); + return true; + } + } + return $error; + } + + /** + * Check for authentication error. + * + * @param WP_Error|null|bool $error Error data. + * @return WP_Error|null|bool + */ + public function check_authentication_error( $error ) { + // Pass through other errors. + if ( ! empty( $error ) ) { + return $error; + } + + return $this->get_error(); + } + + /** + * Set authentication error. + * + * @param WP_Error $error Authentication error data. + */ + protected function set_error( $error ) { + // Reset user. + $this->user = null; + + $this->error = $error; + } + + /** + * Get authentication error. + * + * @return WP_Error|null. + */ + protected function get_error() { + return $this->error; + } + + /** + * Basic Authentication. + * + * SSL-encrypted requests are not subject to sniffing or man-in-the-middle + * attacks, so the request can be authenticated by simply looking up the user + * associated with the given consumer key and confirming the consumer secret + * provided is valid. + * + * @return int|bool + */ + private function perform_basic_authentication() { + $this->auth_method = 'basic_auth'; + $consumer_key = ''; + $consumer_secret = ''; + + // If the $_GET parameters are present, use those first. + if ( ! empty( $_GET['consumer_key'] ) && ! empty( $_GET['consumer_secret'] ) ) { // WPCS: CSRF ok. + $consumer_key = $_GET['consumer_key']; // WPCS: CSRF ok, sanitization ok. + $consumer_secret = $_GET['consumer_secret']; // WPCS: CSRF ok, sanitization ok. + } + + // If the above is not present, we will do full basic auth. + if ( ! $consumer_key && ! empty( $_SERVER['PHP_AUTH_USER'] ) && ! empty( $_SERVER['PHP_AUTH_PW'] ) ) { + $consumer_key = $_SERVER['PHP_AUTH_USER']; // WPCS: CSRF ok, sanitization ok. + $consumer_secret = $_SERVER['PHP_AUTH_PW']; // WPCS: CSRF ok, sanitization ok. + } + + // Stop if don't have any key. + if ( ! $consumer_key || ! $consumer_secret ) { + return false; + } + + // Get user data. + $this->user = $this->get_user_data_by_consumer_key( $consumer_key ); + if ( empty( $this->user ) ) { + return false; + } + + // Validate user secret. + if ( ! hash_equals( $this->user->consumer_secret, $consumer_secret ) ) { // @codingStandardsIgnoreLine + $this->set_error( new WP_Error( 'woocommerce_rest_authentication_error', __( 'Consumer secret is invalid.', 'woocommerce' ), array( 'status' => 401 ) ) ); + + return false; + } + + return $this->user->user_id; + } + + /** + * Parse the Authorization header into parameters. + * + * @since 3.0.0 + * + * @param string $header Authorization header value (not including "Authorization: " prefix). + * + * @return array Map of parameter values. + */ + public function parse_header( $header ) { + if ( 'OAuth ' !== substr( $header, 0, 6 ) ) { + return array(); + } + + // From OAuth PHP library, used under MIT license. + $params = array(); + if ( preg_match_all( '/(oauth_[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches ) ) { + foreach ( $matches[1] as $i => $h ) { + $params[ $h ] = urldecode( empty( $matches[3][ $i ] ) ? $matches[4][ $i ] : $matches[3][ $i ] ); + } + if ( isset( $params['realm'] ) ) { + unset( $params['realm'] ); + } + } + + return $params; + } + + /** + * Get the authorization header. + * + * On certain systems and configurations, the Authorization header will be + * stripped out by the server or PHP. Typically this is then used to + * generate `PHP_AUTH_USER`/`PHP_AUTH_PASS` but not passed on. We use + * `getallheaders` here to try and grab it out instead. + * + * @since 3.0.0 + * + * @return string Authorization header if set. + */ + public function get_authorization_header() { + if ( ! empty( $_SERVER['HTTP_AUTHORIZATION'] ) ) { + return wp_unslash( $_SERVER['HTTP_AUTHORIZATION'] ); // WPCS: sanitization ok. + } + + if ( function_exists( 'getallheaders' ) ) { + $headers = getallheaders(); + // Check for the authoization header case-insensitively. + foreach ( $headers as $key => $value ) { + if ( 'authorization' === strtolower( $key ) ) { + return $value; + } + } + } + + return ''; + } + + /** + * Get oAuth parameters from $_GET, $_POST or request header. + * + * @since 3.0.0 + * + * @return array|WP_Error + */ + public function get_oauth_parameters() { + $params = array_merge( $_GET, $_POST ); // WPCS: CSRF ok. + $params = wp_unslash( $params ); + $header = $this->get_authorization_header(); + + if ( ! empty( $header ) ) { + // Trim leading spaces. + $header = trim( $header ); + $header_params = $this->parse_header( $header ); + + if ( ! empty( $header_params ) ) { + $params = array_merge( $params, $header_params ); + } + } + + $param_names = array( + 'oauth_consumer_key', + 'oauth_timestamp', + 'oauth_nonce', + 'oauth_signature', + 'oauth_signature_method', + ); + + $errors = array(); + $have_one = false; + + // Check for required OAuth parameters. + foreach ( $param_names as $param_name ) { + if ( empty( $params[ $param_name ] ) ) { + $errors[] = $param_name; + } else { + $have_one = true; + } + } + + // All keys are missing, so we're probably not even trying to use OAuth. + if ( ! $have_one ) { + return array(); + } + + // If we have at least one supplied piece of data, and we have an error, + // then it's a failed authentication. + if ( ! empty( $errors ) ) { + $message = sprintf( + /* translators: %s: amount of errors */ + _n( 'Missing OAuth parameter %s', 'Missing OAuth parameters %s', count( $errors ), 'woocommerce' ), + implode( ', ', $errors ) + ); + + $this->set_error( new WP_Error( 'woocommerce_rest_authentication_missing_parameter', $message, array( 'status' => 401 ) ) ); + + return array(); + } + + return $params; + } + + /** + * Perform OAuth 1.0a "one-legged" (http://oauthbible.com/#oauth-10a-one-legged) authentication for non-SSL requests. + * + * This is required so API credentials cannot be sniffed or intercepted when making API requests over plain HTTP. + * + * This follows the spec for simple OAuth 1.0a authentication (RFC 5849) as closely as possible, with two exceptions: + * + * 1) There is no token associated with request/responses, only consumer keys/secrets are used. + * + * 2) The OAuth parameters are included as part of the request query string instead of part of the Authorization header, + * This is because there is no cross-OS function within PHP to get the raw Authorization header. + * + * @link http://tools.ietf.org/html/rfc5849 for the full spec. + * + * @return int|bool + */ + private function perform_oauth_authentication() { + $this->auth_method = 'oauth1'; + + $params = $this->get_oauth_parameters(); + if ( empty( $params ) ) { + return false; + } + + // Fetch WP user by consumer key. + $this->user = $this->get_user_data_by_consumer_key( $params['oauth_consumer_key'] ); + + if ( empty( $this->user ) ) { + $this->set_error( new WP_Error( 'woocommerce_rest_authentication_error', __( 'Consumer key is invalid.', 'woocommerce' ), array( 'status' => 401 ) ) ); + + return false; + } + + // Perform OAuth validation. + $signature = $this->check_oauth_signature( $this->user, $params ); + if ( is_wp_error( $signature ) ) { + $this->set_error( $signature ); + return false; + } + + $timestamp_and_nonce = $this->check_oauth_timestamp_and_nonce( $this->user, $params['oauth_timestamp'], $params['oauth_nonce'] ); + if ( is_wp_error( $timestamp_and_nonce ) ) { + $this->set_error( $timestamp_and_nonce ); + return false; + } + + return $this->user->user_id; + } + + /** + * Verify that the consumer-provided request signature matches our generated signature, + * this ensures the consumer has a valid key/secret. + * + * @param stdClass $user User data. + * @param array $params The request parameters. + * @return true|WP_Error + */ + private function check_oauth_signature( $user, $params ) { + $http_method = isset( $_SERVER['REQUEST_METHOD'] ) ? strtoupper( $_SERVER['REQUEST_METHOD'] ) : ''; // WPCS: sanitization ok. + $request_path = isset( $_SERVER['REQUEST_URI'] ) ? wp_parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ) : ''; // WPCS: sanitization ok. + $wp_base = get_home_url( null, '/', 'relative' ); + if ( substr( $request_path, 0, strlen( $wp_base ) ) === $wp_base ) { + $request_path = substr( $request_path, strlen( $wp_base ) ); + } + $base_request_uri = rawurlencode( get_home_url( null, $request_path, is_ssl() ? 'https' : 'http' ) ); + + // Get the signature provided by the consumer and remove it from the parameters prior to checking the signature. + $consumer_signature = rawurldecode( str_replace( ' ', '+', $params['oauth_signature'] ) ); + unset( $params['oauth_signature'] ); + + // Sort parameters. + if ( ! uksort( $params, 'strcmp' ) ) { + return new WP_Error( 'woocommerce_rest_authentication_error', __( 'Invalid signature - failed to sort parameters.', 'woocommerce' ), array( 'status' => 401 ) ); + } + + // Normalize parameter key/values. + $params = $this->normalize_parameters( $params ); + $query_string = implode( '%26', $this->join_with_equals_sign( $params ) ); // Join with ampersand. + $string_to_sign = $http_method . '&' . $base_request_uri . '&' . $query_string; + + if ( 'HMAC-SHA1' !== $params['oauth_signature_method'] && 'HMAC-SHA256' !== $params['oauth_signature_method'] ) { + return new WP_Error( 'woocommerce_rest_authentication_error', __( 'Invalid signature - signature method is invalid.', 'woocommerce' ), array( 'status' => 401 ) ); + } + + $hash_algorithm = strtolower( str_replace( 'HMAC-', '', $params['oauth_signature_method'] ) ); + $secret = $user->consumer_secret . '&'; + $signature = base64_encode( hash_hmac( $hash_algorithm, $string_to_sign, $secret, true ) ); + + if ( ! hash_equals( $signature, $consumer_signature ) ) { // @codingStandardsIgnoreLine + return new WP_Error( 'woocommerce_rest_authentication_error', __( 'Invalid signature - provided signature does not match.', 'woocommerce' ), array( 'status' => 401 ) ); + } + + return true; + } + + /** + * Creates an array of urlencoded strings out of each array key/value pairs. + * + * @param array $params Array of parameters to convert. + * @param array $query_params Array to extend. + * @param string $key Optional Array key to append. + * @return string Array of urlencoded strings. + */ + private function join_with_equals_sign( $params, $query_params = array(), $key = '' ) { + foreach ( $params as $param_key => $param_value ) { + if ( $key ) { + $param_key = $key . '%5B' . $param_key . '%5D'; // Handle multi-dimensional array. + } + + if ( is_array( $param_value ) ) { + $query_params = $this->join_with_equals_sign( $param_value, $query_params, $param_key ); + } else { + $string = $param_key . '=' . $param_value; // Join with equals sign. + $query_params[] = wc_rest_urlencode_rfc3986( $string ); + } + } + + return $query_params; + } + + /** + * Normalize each parameter by assuming each parameter may have already been + * encoded, so attempt to decode, and then re-encode according to RFC 3986. + * + * Note both the key and value is normalized so a filter param like: + * + * 'filter[period]' => 'week' + * + * is encoded to: + * + * 'filter%255Bperiod%255D' => 'week' + * + * This conforms to the OAuth 1.0a spec which indicates the entire query string + * should be URL encoded. + * + * @see rawurlencode() + * @param array $parameters Un-normalized parameters. + * @return array Normalized parameters. + */ + private function normalize_parameters( $parameters ) { + $keys = wc_rest_urlencode_rfc3986( array_keys( $parameters ) ); + $values = wc_rest_urlencode_rfc3986( array_values( $parameters ) ); + $parameters = array_combine( $keys, $values ); + + return $parameters; + } + + /** + * Verify that the timestamp and nonce provided with the request are valid. This prevents replay attacks where + * an attacker could attempt to re-send an intercepted request at a later time. + * + * - A timestamp is valid if it is within 15 minutes of now. + * - A nonce is valid if it has not been used within the last 15 minutes. + * + * @param stdClass $user User data. + * @param int $timestamp The unix timestamp for when the request was made. + * @param string $nonce A unique (for the given user) 32 alphanumeric string, consumer-generated. + * @return bool|WP_Error + */ + private function check_oauth_timestamp_and_nonce( $user, $timestamp, $nonce ) { + global $wpdb; + + $valid_window = 15 * 60; // 15 minute window. + + if ( ( $timestamp < time() - $valid_window ) || ( $timestamp > time() + $valid_window ) ) { + return new WP_Error( 'woocommerce_rest_authentication_error', __( 'Invalid timestamp.', 'woocommerce' ), array( 'status' => 401 ) ); + } + + $used_nonces = maybe_unserialize( $user->nonces ); + + if ( empty( $used_nonces ) ) { + $used_nonces = array(); + } + + if ( in_array( $nonce, $used_nonces, true ) ) { + return new WP_Error( 'woocommerce_rest_authentication_error', __( 'Invalid nonce - nonce has already been used.', 'woocommerce' ), array( 'status' => 401 ) ); + } + + $used_nonces[ $timestamp ] = $nonce; + + // Remove expired nonces. + foreach ( $used_nonces as $nonce_timestamp => $nonce ) { + if ( $nonce_timestamp < ( time() - $valid_window ) ) { + unset( $used_nonces[ $nonce_timestamp ] ); + } + } + + $used_nonces = maybe_serialize( $used_nonces ); + + $wpdb->update( + $wpdb->prefix . 'woocommerce_api_keys', + array( 'nonces' => $used_nonces ), + array( 'key_id' => $user->key_id ), + array( '%s' ), + array( '%d' ) + ); + + return true; + } + + /** + * Return the user data for the given consumer_key. + * + * @param string $consumer_key Consumer key. + * @return array + */ + private function get_user_data_by_consumer_key( $consumer_key ) { + global $wpdb; + + $consumer_key = wc_api_hash( sanitize_text_field( $consumer_key ) ); + $user = $wpdb->get_row( + $wpdb->prepare( + " + SELECT key_id, user_id, permissions, consumer_key, consumer_secret, nonces + FROM {$wpdb->prefix}woocommerce_api_keys + WHERE consumer_key = %s + ", + $consumer_key + ) + ); + + return $user; + } + + /** + * Check that the API keys provided have the proper key-specific permissions to either read or write API resources. + * + * @param string $method Request method. + * @return bool|WP_Error + */ + private function check_permissions( $method ) { + $permissions = $this->user->permissions; + + switch ( $method ) { + case 'HEAD': + case 'GET': + if ( 'read' !== $permissions && 'read_write' !== $permissions ) { + return new WP_Error( 'woocommerce_rest_authentication_error', __( 'The API key provided does not have read permissions.', 'woocommerce' ), array( 'status' => 401 ) ); + } + break; + case 'POST': + case 'PUT': + case 'PATCH': + case 'DELETE': + if ( 'write' !== $permissions && 'read_write' !== $permissions ) { + return new WP_Error( 'woocommerce_rest_authentication_error', __( 'The API key provided does not have write permissions.', 'woocommerce' ), array( 'status' => 401 ) ); + } + break; + case 'OPTIONS': + return true; + + default: + return new WP_Error( 'woocommerce_rest_authentication_error', __( 'Unknown request method.', 'woocommerce' ), array( 'status' => 401 ) ); + } + + return true; + } + + /** + * Updated API Key last access datetime. + */ + private function update_last_access() { + global $wpdb; + + $wpdb->update( + $wpdb->prefix . 'woocommerce_api_keys', + array( 'last_access' => current_time( 'mysql' ) ), + array( 'key_id' => $this->user->key_id ), + array( '%s' ), + array( '%d' ) + ); + } + + /** + * If the consumer_key and consumer_secret $_GET parameters are NOT provided + * and the Basic auth headers are either not present or the consumer secret does not match the consumer + * key provided, then return the correct Basic headers and an error message. + * + * @param WP_REST_Response $response Current response being served. + * @return WP_REST_Response + */ + public function send_unauthorized_headers( $response ) { + if ( is_wp_error( $this->get_error() ) && 'basic_auth' === $this->auth_method ) { + $auth_message = __( 'WooCommerce API. Use a consumer key in the username field and a consumer secret in the password field.', 'woocommerce' ); + $response->header( 'WWW-Authenticate', 'Basic realm="' . $auth_message . '"', true ); + } + + return $response; + } + + /** + * Check for user permissions and register last access. + * + * @param mixed $result Response to replace the requested version with. + * @param WP_REST_Server $server Server instance. + * @param WP_REST_Request $request Request used to generate the response. + * @return mixed + */ + public function check_user_permissions( $result, $server, $request ) { + if ( $this->user ) { + // Check API Key permissions. + $allowed = $this->check_permissions( $request->get_method() ); + if ( is_wp_error( $allowed ) ) { + return $allowed; + } + + // Register last access. + $this->update_last_access(); + } + + return $result; + } +} + +new WC_REST_Authentication(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-rest-exception.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-rest-exception.php new file mode 100644 index 0000000..0545b53 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-rest-exception.php @@ -0,0 +1,16 @@ +_cookie = apply_filters( 'woocommerce_cookie', 'wp_woocommerce_session_' . COOKIEHASH ); + $this->_table = $GLOBALS['wpdb']->prefix . 'woocommerce_sessions'; + } + + /** + * Init hooks and session data. + * + * @since 3.3.0 + */ + public function init() { + $this->init_session_cookie(); + + add_action( 'woocommerce_set_cart_cookies', array( $this, 'set_customer_session_cookie' ), 10 ); + add_action( 'shutdown', array( $this, 'save_data' ), 20 ); + add_action( 'wp_logout', array( $this, 'destroy_session' ) ); + + if ( ! is_user_logged_in() ) { + add_filter( 'nonce_user_logged_out', array( $this, 'nonce_user_logged_out' ) ); + } + } + + /** + * Setup cookie and customer ID. + * + * @since 3.6.0 + */ + public function init_session_cookie() { + $cookie = $this->get_session_cookie(); + + if ( $cookie ) { + $this->_customer_id = $cookie[0]; + $this->_session_expiration = $cookie[1]; + $this->_session_expiring = $cookie[2]; + $this->_has_cookie = true; + $this->_data = $this->get_session_data(); + + // If the user logs in, update session. + if ( is_user_logged_in() && strval( get_current_user_id() ) !== $this->_customer_id ) { + $guest_session_id = $this->_customer_id; + $this->_customer_id = strval( get_current_user_id() ); + $this->_dirty = true; + $this->save_data( $guest_session_id ); + $this->set_customer_session_cookie( true ); + } + + // Update session if its close to expiring. + if ( time() > $this->_session_expiring ) { + $this->set_session_expiration(); + $this->update_session_timestamp( $this->_customer_id, $this->_session_expiration ); + } + } else { + $this->set_session_expiration(); + $this->_customer_id = $this->generate_customer_id(); + $this->_data = $this->get_session_data(); + } + } + + /** + * Sets the session cookie on-demand (usually after adding an item to the cart). + * + * Since the cookie name (as of 2.1) is prepended with wp, cache systems like batcache will not cache pages when set. + * + * Warning: Cookies will only be set if this is called before the headers are sent. + * + * @param bool $set Should the session cookie be set. + */ + public function set_customer_session_cookie( $set ) { + if ( $set ) { + $to_hash = $this->_customer_id . '|' . $this->_session_expiration; + $cookie_hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) ); + $cookie_value = $this->_customer_id . '||' . $this->_session_expiration . '||' . $this->_session_expiring . '||' . $cookie_hash; + $this->_has_cookie = true; + + if ( ! isset( $_COOKIE[ $this->_cookie ] ) || $_COOKIE[ $this->_cookie ] !== $cookie_value ) { + wc_setcookie( $this->_cookie, $cookie_value, $this->_session_expiration, $this->use_secure_cookie(), true ); + } + } + } + + /** + * Should the session cookie be secure? + * + * @since 3.6.0 + * @return bool + */ + protected function use_secure_cookie() { + return apply_filters( 'wc_session_use_secure_cookie', wc_site_is_https() && is_ssl() ); + } + + /** + * Return true if the current user has an active session, i.e. a cookie to retrieve values. + * + * @return bool + */ + public function has_session() { + return isset( $_COOKIE[ $this->_cookie ] ) || $this->_has_cookie || is_user_logged_in(); // @codingStandardsIgnoreLine. + } + + /** + * Set session expiration. + */ + public function set_session_expiration() { + $this->_session_expiring = time() + intval( apply_filters( 'wc_session_expiring', 60 * 60 * 47 ) ); // 47 Hours. + $this->_session_expiration = time() + intval( apply_filters( 'wc_session_expiration', 60 * 60 * 48 ) ); // 48 Hours. + } + + /** + * Generate a unique customer ID for guests, or return user ID if logged in. + * + * Uses Portable PHP password hashing framework to generate a unique cryptographically strong ID. + * + * @return string + */ + public function generate_customer_id() { + $customer_id = ''; + + if ( is_user_logged_in() ) { + $customer_id = strval( get_current_user_id() ); + } + + if ( empty( $customer_id ) ) { + require_once ABSPATH . 'wp-includes/class-phpass.php'; + $hasher = new PasswordHash( 8, false ); + $customer_id = md5( $hasher->get_random_bytes( 32 ) ); + } + + return $customer_id; + } + + /** + * Get the session cookie, if set. Otherwise return false. + * + * Session cookies without a customer ID are invalid. + * + * @return bool|array + */ + public function get_session_cookie() { + $cookie_value = isset( $_COOKIE[ $this->_cookie ] ) ? wp_unslash( $_COOKIE[ $this->_cookie ] ) : false; // @codingStandardsIgnoreLine. + + if ( empty( $cookie_value ) || ! is_string( $cookie_value ) ) { + return false; + } + + list( $customer_id, $session_expiration, $session_expiring, $cookie_hash ) = explode( '||', $cookie_value ); + + if ( empty( $customer_id ) ) { + return false; + } + + // Validate hash. + $to_hash = $customer_id . '|' . $session_expiration; + $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) ); + + if ( empty( $cookie_hash ) || ! hash_equals( $hash, $cookie_hash ) ) { + return false; + } + + return array( $customer_id, $session_expiration, $session_expiring, $cookie_hash ); + } + + /** + * Get session data. + * + * @return array + */ + public function get_session_data() { + return $this->has_session() ? (array) $this->get_session( $this->_customer_id, array() ) : array(); + } + + /** + * Gets a cache prefix. This is used in session names so the entire cache can be invalidated with 1 function call. + * + * @return string + */ + private function get_cache_prefix() { + return WC_Cache_Helper::get_cache_prefix( WC_SESSION_CACHE_GROUP ); + } + + /** + * Save data and delete guest session. + * + * @param int $old_session_key session ID before user logs in. + */ + public function save_data( $old_session_key = 0 ) { + // Dirty if something changed - prevents saving nothing new. + if ( $this->_dirty && $this->has_session() ) { + global $wpdb; + + $wpdb->query( + $wpdb->prepare( + "INSERT INTO {$wpdb->prefix}woocommerce_sessions (`session_key`, `session_value`, `session_expiry`) VALUES (%s, %s, %d) + ON DUPLICATE KEY UPDATE `session_value` = VALUES(`session_value`), `session_expiry` = VALUES(`session_expiry`)", + $this->_customer_id, + maybe_serialize( $this->_data ), + $this->_session_expiration + ) + ); + + wp_cache_set( $this->get_cache_prefix() . $this->_customer_id, $this->_data, WC_SESSION_CACHE_GROUP, $this->_session_expiration - time() ); + $this->_dirty = false; + if ( get_current_user_id() != $old_session_key && ! is_object( get_user_by( 'id', $old_session_key ) ) ) { + $this->delete_session( $old_session_key ); + } + } + } + + /** + * Destroy all session data. + */ + public function destroy_session() { + $this->delete_session( $this->_customer_id ); + $this->forget_session(); + } + + /** + * Forget all session data without destroying it. + */ + public function forget_session() { + wc_setcookie( $this->_cookie, '', time() - YEAR_IN_SECONDS, $this->use_secure_cookie(), true ); + + wc_empty_cart(); + + $this->_data = array(); + $this->_dirty = false; + $this->_customer_id = $this->generate_customer_id(); + } + + /** + * When a user is logged out, ensure they have a unique nonce by using the customer/session ID. + * + * @param int $uid User ID. + * @return string + */ + public function nonce_user_logged_out( $uid ) { + return $this->has_session() && $this->_customer_id ? $this->_customer_id : $uid; + } + + /** + * Cleanup session data from the database and clear caches. + */ + public function cleanup_sessions() { + global $wpdb; + + $wpdb->query( $wpdb->prepare( "DELETE FROM $this->_table WHERE session_expiry < %d", time() ) ); // @codingStandardsIgnoreLine. + + if ( class_exists( 'WC_Cache_Helper' ) ) { + WC_Cache_Helper::invalidate_cache_group( WC_SESSION_CACHE_GROUP ); + } + } + + /** + * Returns the session. + * + * @param string $customer_id Custo ID. + * @param mixed $default Default session value. + * @return string|array + */ + public function get_session( $customer_id, $default = false ) { + global $wpdb; + + if ( Constants::is_defined( 'WP_SETUP_CONFIG' ) ) { + return false; + } + + // Try to get it from the cache, it will return false if not present or if object cache not in use. + $value = wp_cache_get( $this->get_cache_prefix() . $customer_id, WC_SESSION_CACHE_GROUP ); + + if ( false === $value ) { + $value = $wpdb->get_var( $wpdb->prepare( "SELECT session_value FROM $this->_table WHERE session_key = %s", $customer_id ) ); // @codingStandardsIgnoreLine. + + if ( is_null( $value ) ) { + $value = $default; + } + + $cache_duration = $this->_session_expiration - time(); + if ( 0 < $cache_duration ) { + wp_cache_add( $this->get_cache_prefix() . $customer_id, $value, WC_SESSION_CACHE_GROUP, $cache_duration ); + } + } + + return maybe_unserialize( $value ); + } + + /** + * Delete the session from the cache and database. + * + * @param int $customer_id Customer ID. + */ + public function delete_session( $customer_id ) { + global $wpdb; + + wp_cache_delete( $this->get_cache_prefix() . $customer_id, WC_SESSION_CACHE_GROUP ); + + $wpdb->delete( + $this->_table, + array( + 'session_key' => $customer_id, + ) + ); + } + + /** + * Update the session expiry timestamp. + * + * @param string $customer_id Customer ID. + * @param int $timestamp Timestamp to expire the cookie. + */ + public function update_session_timestamp( $customer_id, $timestamp ) { + global $wpdb; + + $wpdb->update( + $this->_table, + array( + 'session_expiry' => $timestamp, + ), + array( + 'session_key' => $customer_id, + ), + array( + '%d', + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping-rate.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping-rate.php new file mode 100644 index 0000000..1248a70 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping-rate.php @@ -0,0 +1,252 @@ + '', + 'method_id' => '', + 'instance_id' => 0, + 'label' => '', + 'cost' => 0, + 'taxes' => array(), + ); + + /** + * Stores meta data for this rate. + * + * @since 2.6.0 + * @var array + */ + protected $meta_data = array(); + + /** + * Constructor. + * + * @param string $id Shipping rate ID. + * @param string $label Shipping rate label. + * @param integer $cost Cost. + * @param array $taxes Taxes applied to shipping rate. + * @param string $method_id Shipping method ID. + * @param int $instance_id Shipping instance ID. + */ + public function __construct( $id = '', $label = '', $cost = 0, $taxes = array(), $method_id = '', $instance_id = 0 ) { + $this->set_id( $id ); + $this->set_label( $label ); + $this->set_cost( $cost ); + $this->set_taxes( $taxes ); + $this->set_method_id( $method_id ); + $this->set_instance_id( $instance_id ); + } + + /** + * Magic methods to support direct access to props. + * + * @since 3.2.0 + * @param string $key Key. + * @return bool + */ + public function __isset( $key ) { + return isset( $this->data[ $key ] ); + } + + /** + * Magic methods to support direct access to props. + * + * @since 3.2.0 + * @param string $key Key. + * @return mixed + */ + public function __get( $key ) { + if ( is_callable( array( $this, "get_{$key}" ) ) ) { + return $this->{"get_{$key}"}(); + } elseif ( isset( $this->data[ $key ] ) ) { + return $this->data[ $key ]; + } else { + return ''; + } + } + + /** + * Magic methods to support direct access to props. + * + * @since 3.2.0 + * @param string $key Key. + * @param mixed $value Value. + */ + public function __set( $key, $value ) { + if ( is_callable( array( $this, "set_{$key}" ) ) ) { + $this->{"set_{$key}"}( $value ); + } else { + $this->data[ $key ] = $value; + } + } + + /** + * Set ID for the rate. This is usually a combination of the method and instance IDs. + * + * @since 3.2.0 + * @param string $id Shipping rate ID. + */ + public function set_id( $id ) { + $this->data['id'] = (string) $id; + } + + /** + * Set shipping method ID the rate belongs to. + * + * @since 3.2.0 + * @param string $method_id Shipping method ID. + */ + public function set_method_id( $method_id ) { + $this->data['method_id'] = (string) $method_id; + } + + /** + * Set instance ID the rate belongs to. + * + * @since 3.2.0 + * @param int $instance_id Instance ID. + */ + public function set_instance_id( $instance_id ) { + $this->data['instance_id'] = absint( $instance_id ); + } + + /** + * Set rate label. + * + * @since 3.2.0 + * @param string $label Shipping rate label. + */ + public function set_label( $label ) { + $this->data['label'] = (string) $label; + } + + /** + * Set rate cost. + * + * @todo 4.0 Prevent negative value being set. #19293 + * @since 3.2.0 + * @param string $cost Shipping rate cost. + */ + public function set_cost( $cost ) { + $this->data['cost'] = $cost; + } + + /** + * Set rate taxes. + * + * @since 3.2.0 + * @param array $taxes List of taxes applied to shipping rate. + */ + public function set_taxes( $taxes ) { + $this->data['taxes'] = ! empty( $taxes ) && is_array( $taxes ) ? $taxes : array(); + } + + /** + * Set ID for the rate. This is usually a combination of the method and instance IDs. + * + * @since 3.2.0 + * @return string + */ + public function get_id() { + return apply_filters( 'woocommerce_shipping_rate_id', $this->data['id'], $this ); + } + + /** + * Set shipping method ID the rate belongs to. + * + * @since 3.2.0 + * @return string + */ + public function get_method_id() { + return apply_filters( 'woocommerce_shipping_rate_method_id', $this->data['method_id'], $this ); + } + + /** + * Set instance ID the rate belongs to. + * + * @since 3.2.0 + * @return int + */ + public function get_instance_id() { + return apply_filters( 'woocommerce_shipping_rate_instance_id', $this->data['instance_id'], $this ); + } + + /** + * Set rate label. + * + * @return string + */ + public function get_label() { + return apply_filters( 'woocommerce_shipping_rate_label', $this->data['label'], $this ); + } + + /** + * Set rate cost. + * + * @since 3.2.0 + * @return string + */ + public function get_cost() { + return apply_filters( 'woocommerce_shipping_rate_cost', $this->data['cost'], $this ); + } + + /** + * Set rate taxes. + * + * @since 3.2.0 + * @return array + */ + public function get_taxes() { + return apply_filters( 'woocommerce_shipping_rate_taxes', $this->data['taxes'], $this ); + } + + /** + * Get shipping tax. + * + * @return array + */ + public function get_shipping_tax() { + return apply_filters( 'woocommerce_get_shipping_tax', count( $this->taxes ) > 0 && ! WC()->customer->get_is_vat_exempt() ? array_sum( $this->taxes ) : 0, $this ); + } + + /** + * Add some meta data for this rate. + * + * @since 2.6.0 + * @param string $key Key. + * @param string $value Value. + */ + public function add_meta_data( $key, $value ) { + $this->meta_data[ wc_clean( $key ) ] = wc_clean( $value ); + } + + /** + * Get all meta data for this rate. + * + * @since 2.6.0 + * @return array + */ + public function get_meta_data() { + return $this->meta_data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping-zone.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping-zone.php new file mode 100644 index 0000000..f092789 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping-zone.php @@ -0,0 +1,462 @@ + '', + 'zone_order' => 0, + 'zone_locations' => array(), + ); + + /** + * Constructor for zones. + * + * @param int|object $zone Zone ID to load from the DB or zone object. + */ + public function __construct( $zone = null ) { + if ( is_numeric( $zone ) && ! empty( $zone ) ) { + $this->set_id( $zone ); + } elseif ( is_object( $zone ) ) { + $this->set_id( $zone->zone_id ); + } elseif ( 0 === $zone || '0' === $zone ) { + $this->set_id( 0 ); + } else { + $this->set_object_read( true ); + } + + $this->data_store = WC_Data_Store::load( 'shipping-zone' ); + if ( false === $this->get_object_read() ) { + $this->data_store->read( $this ); + } + } + + /** + * -------------------------------------------------------------------------- + * Getters + * -------------------------------------------------------------------------- + */ + + /** + * Get zone name. + * + * @param string $context View or edit context. + * @return string + */ + public function get_zone_name( $context = 'view' ) { + return $this->get_prop( 'zone_name', $context ); + } + + /** + * Get zone order. + * + * @param string $context View or edit context. + * @return int + */ + public function get_zone_order( $context = 'view' ) { + return $this->get_prop( 'zone_order', $context ); + } + + /** + * Get zone locations. + * + * @param string $context View or edit context. + * @return array of zone objects + */ + public function get_zone_locations( $context = 'view' ) { + return $this->get_prop( 'zone_locations', $context ); + } + + /** + * Return a text string representing what this zone is for. + * + * @param int $max Max locations to return. + * @param string $context View or edit context. + * @return string + */ + public function get_formatted_location( $max = 10, $context = 'view' ) { + $location_parts = array(); + $all_continents = WC()->countries->get_continents(); + $all_countries = WC()->countries->get_countries(); + $all_states = WC()->countries->get_states(); + $locations = $this->get_zone_locations( $context ); + $continents = array_filter( $locations, array( $this, 'location_is_continent' ) ); + $countries = array_filter( $locations, array( $this, 'location_is_country' ) ); + $states = array_filter( $locations, array( $this, 'location_is_state' ) ); + $postcodes = array_filter( $locations, array( $this, 'location_is_postcode' ) ); + + foreach ( $continents as $location ) { + $location_parts[] = $all_continents[ $location->code ]['name']; + } + + foreach ( $countries as $location ) { + $location_parts[] = $all_countries[ $location->code ]; + } + + foreach ( $states as $location ) { + $location_codes = explode( ':', $location->code ); + $location_parts[] = $all_states[ $location_codes[0] ][ $location_codes[1] ]; + } + + foreach ( $postcodes as $location ) { + $location_parts[] = $location->code; + } + + // Fix display of encoded characters. + $location_parts = array_map( 'html_entity_decode', $location_parts ); + + if ( count( $location_parts ) > $max ) { + $remaining = count( $location_parts ) - $max; + // @codingStandardsIgnoreStart + return sprintf( _n( '%s and %d other region', '%s and %d other regions', $remaining, 'woocommerce' ), implode( ', ', array_splice( $location_parts, 0, $max ) ), $remaining ); + // @codingStandardsIgnoreEnd + } elseif ( ! empty( $location_parts ) ) { + return implode( ', ', $location_parts ); + } else { + return __( 'Everywhere', 'woocommerce' ); + } + } + + /** + * Get shipping methods linked to this zone. + * + * @param bool $enabled_only Only return enabled methods. + * @param string $context Getting shipping methods for what context. Valid values, admin, json. + * @return array of objects + */ + public function get_shipping_methods( $enabled_only = false, $context = 'admin' ) { + if ( null === $this->get_id() ) { + return array(); + } + + $raw_methods = $this->data_store->get_methods( $this->get_id(), $enabled_only ); + $wc_shipping = WC_Shipping::instance(); + $allowed_classes = $wc_shipping->get_shipping_method_class_names(); + $methods = array(); + + foreach ( $raw_methods as $raw_method ) { + if ( in_array( $raw_method->method_id, array_keys( $allowed_classes ), true ) ) { + $class_name = $allowed_classes[ $raw_method->method_id ]; + $instance_id = $raw_method->instance_id; + + // The returned array may contain instances of shipping methods, as well + // as classes. If the "class" is an instance, just use it. If not, + // create an instance. + if ( is_object( $class_name ) ) { + $class_name_of_instance = get_class( $class_name ); + $methods[ $instance_id ] = new $class_name_of_instance( $instance_id ); + } else { + // If the class is not an object, it should be a string. It's better + // to double check, to be sure (a class must be a string, anything) + // else would be useless. + if ( is_string( $class_name ) && class_exists( $class_name ) ) { + $methods[ $instance_id ] = new $class_name( $instance_id ); + } + } + + // Let's make sure that we have an instance before setting its attributes. + if ( is_object( $methods[ $instance_id ] ) ) { + $methods[ $instance_id ]->method_order = absint( $raw_method->method_order ); + $methods[ $instance_id ]->enabled = $raw_method->is_enabled ? 'yes' : 'no'; + $methods[ $instance_id ]->has_settings = $methods[ $instance_id ]->has_settings(); + $methods[ $instance_id ]->settings_html = $methods[ $instance_id ]->supports( 'instance-settings-modal' ) ? $methods[ $instance_id ]->get_admin_options_html() : false; + $methods[ $instance_id ]->method_description = wp_kses_post( wpautop( $methods[ $instance_id ]->method_description ) ); + } + + if ( 'json' === $context ) { + // We don't want the entire object in this context, just the public props. + $methods[ $instance_id ] = (object) get_object_vars( $methods[ $instance_id ] ); + unset( $methods[ $instance_id ]->instance_form_fields, $methods[ $instance_id ]->form_fields ); + } + } + } + + uasort( $methods, 'wc_shipping_zone_method_order_uasort_comparison' ); + + return apply_filters( 'woocommerce_shipping_zone_shipping_methods', $methods, $raw_methods, $allowed_classes, $this ); + } + + /** + * -------------------------------------------------------------------------- + * Setters + * -------------------------------------------------------------------------- + */ + + /** + * Set zone name. + * + * @param string $set Value to set. + */ + public function set_zone_name( $set ) { + $this->set_prop( 'zone_name', wc_clean( $set ) ); + } + + /** + * Set zone order. Value to set. + * + * @param int $set Value to set. + */ + public function set_zone_order( $set ) { + $this->set_prop( 'zone_order', absint( $set ) ); + } + + /** + * Set zone locations. + * + * @since 3.0.0 + * @param array $locations Value to set. + */ + public function set_zone_locations( $locations ) { + if ( 0 !== $this->get_id() ) { + $this->set_prop( 'zone_locations', $locations ); + } + } + + /** + * -------------------------------------------------------------------------- + * Other + * -------------------------------------------------------------------------- + */ + + /** + * Save zone data to the database. + * + * @return int + */ + public function save() { + if ( ! $this->get_zone_name() ) { + $this->set_zone_name( $this->generate_zone_name() ); + } + + if ( ! $this->data_store ) { + return $this->get_id(); + } + + /** + * Trigger action before saving to the DB. Allows you to adjust object props before save. + * + * @param WC_Data $this The object being saved. + * @param WC_Data_Store_WP $data_store THe data store persisting the data. + */ + do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store ); + + if ( null !== $this->get_id() ) { + $this->data_store->update( $this ); + } else { + $this->data_store->create( $this ); + } + + /** + * Trigger action after saving to the DB. + * + * @param WC_Data $this The object being saved. + * @param WC_Data_Store_WP $data_store THe data store persisting the data. + */ + do_action( 'woocommerce_after_' . $this->object_type . '_object_save', $this, $this->data_store ); + + return $this->get_id(); + } + + /** + * Generate a zone name based on location. + * + * @return string + */ + protected function generate_zone_name() { + $zone_name = $this->get_formatted_location(); + + if ( empty( $zone_name ) ) { + $zone_name = __( 'Zone', 'woocommerce' ); + } + + return $zone_name; + } + + /** + * Location type detection. + * + * @param object $location Location to check. + * @return boolean + */ + private function location_is_continent( $location ) { + return 'continent' === $location->type; + } + + /** + * Location type detection. + * + * @param object $location Location to check. + * @return boolean + */ + private function location_is_country( $location ) { + return 'country' === $location->type; + } + + /** + * Location type detection. + * + * @param object $location Location to check. + * @return boolean + */ + private function location_is_state( $location ) { + return 'state' === $location->type; + } + + /** + * Location type detection. + * + * @param object $location Location to check. + * @return boolean + */ + private function location_is_postcode( $location ) { + return 'postcode' === $location->type; + } + + /** + * Is passed location type valid? + * + * @param string $type Type to check. + * @return boolean + */ + public function is_valid_location_type( $type ) { + return in_array( $type, apply_filters( 'woocommerce_valid_location_types', array( 'postcode', 'state', 'country', 'continent' ) ), true ); + } + + /** + * Add location (state or postcode) to a zone. + * + * @param string $code Location code. + * @param string $type state or postcode. + */ + public function add_location( $code, $type ) { + if ( 0 !== $this->get_id() && $this->is_valid_location_type( $type ) ) { + if ( 'postcode' === $type ) { + $code = trim( strtoupper( str_replace( chr( 226 ) . chr( 128 ) . chr( 166 ), '...', $code ) ) ); // No normalization - postcodes are matched against both normal and formatted versions to support wildcards. + } + $location = array( + 'code' => wc_clean( $code ), + 'type' => wc_clean( $type ), + ); + $zone_locations = $this->get_prop( 'zone_locations', 'edit' ); + $zone_locations[] = (object) $location; + $this->set_prop( 'zone_locations', $zone_locations ); + } + } + + + /** + * Clear all locations for this zone. + * + * @param array|string $types of location to clear. + */ + public function clear_locations( $types = array( 'postcode', 'state', 'country', 'continent' ) ) { + if ( ! is_array( $types ) ) { + $types = array( $types ); + } + $zone_locations = $this->get_prop( 'zone_locations', 'edit' ); + foreach ( $zone_locations as $key => $values ) { + if ( in_array( $values->type, $types, true ) ) { + unset( $zone_locations[ $key ] ); + } + } + $zone_locations = array_values( $zone_locations ); // reindex. + $this->set_prop( 'zone_locations', $zone_locations ); + } + + /** + * Set locations. + * + * @param array $locations Array of locations. + */ + public function set_locations( $locations = array() ) { + $this->clear_locations(); + foreach ( $locations as $location ) { + $this->add_location( $location['code'], $location['type'] ); + } + } + + /** + * Add a shipping method to this zone. + * + * @param string $type shipping method type. + * @return int new instance_id, 0 on failure + */ + public function add_shipping_method( $type ) { + if ( null === $this->get_id() ) { + $this->save(); + } + + $instance_id = 0; + $wc_shipping = WC_Shipping::instance(); + $allowed_classes = $wc_shipping->get_shipping_method_class_names(); + $count = $this->data_store->get_method_count( $this->get_id() ); + + if ( in_array( $type, array_keys( $allowed_classes ), true ) ) { + $instance_id = $this->data_store->add_method( $this->get_id(), $type, $count + 1 ); + } + + if ( $instance_id ) { + do_action( 'woocommerce_shipping_zone_method_added', $instance_id, $type, $this->get_id() ); + } + + WC_Cache_Helper::get_transient_version( 'shipping', true ); + + return $instance_id; + } + + /** + * Delete a shipping method from a zone. + * + * @param int $instance_id Shipping method instance ID. + * @return True on success, false on failure + */ + public function delete_shipping_method( $instance_id ) { + if ( null === $this->get_id() ) { + return false; + } + + // Get method details. + $method = $this->data_store->get_method( $instance_id ); + + if ( $method ) { + $this->data_store->delete_method( $instance_id ); + do_action( 'woocommerce_shipping_zone_method_deleted', $instance_id, $method->method_id, $this->get_id() ); + } + + WC_Cache_Helper::get_transient_version( 'shipping', true ); + + return true; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping-zones.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping-zones.php new file mode 100644 index 0000000..4acff8b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping-zones.php @@ -0,0 +1,142 @@ +get_zones(); + $zones = array(); + + foreach ( $raw_zones as $raw_zone ) { + $zone = new WC_Shipping_Zone( $raw_zone ); + $zones[ $zone->get_id() ] = $zone->get_data(); + $zones[ $zone->get_id() ]['zone_id'] = $zone->get_id(); + $zones[ $zone->get_id() ]['formatted_zone_location'] = $zone->get_formatted_location(); + $zones[ $zone->get_id() ]['shipping_methods'] = $zone->get_shipping_methods( false, $context ); + } + + return $zones; + } + + /** + * Get shipping zone using it's ID + * + * @since 2.6.0 + * @param int $zone_id Zone ID. + * @return WC_Shipping_Zone|bool + */ + public static function get_zone( $zone_id ) { + return self::get_zone_by( 'zone_id', $zone_id ); + } + + /** + * Get shipping zone by an ID. + * + * @since 2.6.0 + * @param string $by Get by 'zone_id' or 'instance_id'. + * @param int $id ID. + * @return WC_Shipping_Zone|bool + */ + public static function get_zone_by( $by = 'zone_id', $id = 0 ) { + $zone_id = false; + + switch ( $by ) { + case 'zone_id': + $zone_id = $id; + break; + case 'instance_id': + $data_store = WC_Data_Store::load( 'shipping-zone' ); + $zone_id = $data_store->get_zone_id_by_instance_id( $id ); + break; + } + + if ( false !== $zone_id ) { + try { + return new WC_Shipping_Zone( $zone_id ); + } catch ( Exception $e ) { + return false; + } + } + + return false; + } + + /** + * Get shipping zone using it's ID. + * + * @since 2.6.0 + * @param int $instance_id Instance ID. + * @return bool|WC_Shipping_Method + */ + public static function get_shipping_method( $instance_id ) { + $data_store = WC_Data_Store::load( 'shipping-zone' ); + $raw_shipping_method = $data_store->get_method( $instance_id ); + $wc_shipping = WC_Shipping::instance(); + $allowed_classes = $wc_shipping->get_shipping_method_class_names(); + + if ( ! empty( $raw_shipping_method ) && in_array( $raw_shipping_method->method_id, array_keys( $allowed_classes ), true ) ) { + $class_name = $allowed_classes[ $raw_shipping_method->method_id ]; + if ( is_object( $class_name ) ) { + $class_name = get_class( $class_name ); + } + return new $class_name( $raw_shipping_method->instance_id ); + } + return false; + } + + /** + * Delete a zone using it's ID + * + * @param int $zone_id Zone ID. + * @since 2.6.0 + */ + public static function delete_zone( $zone_id ) { + $zone = new WC_Shipping_Zone( $zone_id ); + $zone->delete(); + } + + /** + * Find a matching zone for a given package. + * + * @since 2.6.0 + * @uses wc_make_numeric_postcode() + * @param array $package Shipping package. + * @return WC_Shipping_Zone + */ + public static function get_zone_matching_package( $package ) { + $country = strtoupper( wc_clean( $package['destination']['country'] ) ); + $state = strtoupper( wc_clean( $package['destination']['state'] ) ); + $postcode = wc_normalize_postcode( wc_clean( $package['destination']['postcode'] ) ); + $cache_key = WC_Cache_Helper::get_cache_prefix( 'shipping_zones' ) . 'wc_shipping_zone_' . md5( sprintf( '%s+%s+%s', $country, $state, $postcode ) ); + $matching_zone_id = wp_cache_get( $cache_key, 'shipping_zones' ); + + if ( false === $matching_zone_id ) { + $data_store = WC_Data_Store::load( 'shipping-zone' ); + $matching_zone_id = $data_store->get_zone_id_from_package( $package ); + wp_cache_set( $cache_key, $matching_zone_id, 'shipping_zones' ); + } + + return new WC_Shipping_Zone( $matching_zone_id ? $matching_zone_id : 0 ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping.php new file mode 100644 index 0000000..6dcc53a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shipping.php @@ -0,0 +1,404 @@ +cart->get_shipping_total(); + } + if ( 'shipping_taxes' === $name ) { + return WC()->cart->get_shipping_taxes(); + } + } + + /** + * Initialize shipping. + */ + public function __construct() { + $this->enabled = wc_shipping_enabled(); + + if ( $this->enabled ) { + $this->init(); + } + } + + /** + * Initialize shipping. + */ + public function init() { + do_action( 'woocommerce_shipping_init' ); + } + + /** + * Shipping methods register themselves by returning their main class name through the woocommerce_shipping_methods filter. + * + * @return array + */ + public function get_shipping_method_class_names() { + // Unique Method ID => Method Class name. + $shipping_methods = array( + 'flat_rate' => 'WC_Shipping_Flat_Rate', + 'free_shipping' => 'WC_Shipping_Free_Shipping', + 'local_pickup' => 'WC_Shipping_Local_Pickup', + ); + + // For backwards compatibility with 2.5.x we load any ENABLED legacy shipping methods here. + $maybe_load_legacy_methods = array( 'flat_rate', 'free_shipping', 'international_delivery', 'local_delivery', 'local_pickup' ); + + foreach ( $maybe_load_legacy_methods as $method ) { + $options = get_option( 'woocommerce_' . $method . '_settings' ); + if ( $options && isset( $options['enabled'] ) && 'yes' === $options['enabled'] ) { + $shipping_methods[ 'legacy_' . $method ] = 'WC_Shipping_Legacy_' . $method; + } + } + + return apply_filters( 'woocommerce_shipping_methods', $shipping_methods ); + } + + /** + * Loads all shipping methods which are hooked in. + * If a $package is passed, some methods may add themselves conditionally and zones will be used. + * + * @param array $package Package information. + * @return WC_Shipping_Method[] + */ + public function load_shipping_methods( $package = array() ) { + if ( ! empty( $package ) ) { + $debug_mode = 'yes' === get_option( 'woocommerce_shipping_debug_mode', 'no' ); + $shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package ); + $this->shipping_methods = $shipping_zone->get_shipping_methods( true ); + + // translators: %s: shipping zone name. + $matched_zone_notice = sprintf( __( 'Customer matched zone "%s"', 'woocommerce' ), $shipping_zone->get_zone_name() ); + + // Debug output. + if ( $debug_mode && ! Constants::is_defined( 'WOOCOMMERCE_CHECKOUT' ) && ! Constants::is_defined( 'WC_DOING_AJAX' ) && ! wc_has_notice( $matched_zone_notice ) ) { + wc_add_notice( $matched_zone_notice ); + } + } else { + $this->shipping_methods = array(); + } + + // For the settings in the backend, and for non-shipping zone methods, we still need to load any registered classes here. + foreach ( $this->get_shipping_method_class_names() as $method_id => $method_class ) { + $this->register_shipping_method( $method_class ); + } + + // Methods can register themselves manually through this hook if necessary. + do_action( 'woocommerce_load_shipping_methods', $package ); + + // Return loaded methods. + return $this->get_shipping_methods(); + } + + /** + * Register a shipping method. + * + * @param object|string $method Either the name of the method's class, or an instance of the method's class. + * + * @return bool|void + */ + public function register_shipping_method( $method ) { + if ( ! is_object( $method ) ) { + if ( ! class_exists( $method ) ) { + return false; + } + $method = new $method(); + } + if ( is_null( $this->shipping_methods ) ) { + $this->shipping_methods = array(); + } + $this->shipping_methods[ $method->id ] = $method; + } + + /** + * Unregister shipping methods. + */ + public function unregister_shipping_methods() { + $this->shipping_methods = null; + } + + /** + * Returns all registered shipping methods for usage. + * + * @return WC_Shipping_Method[] + */ + public function get_shipping_methods() { + if ( is_null( $this->shipping_methods ) ) { + $this->load_shipping_methods(); + } + return $this->shipping_methods; + } + + /** + * Get an array of shipping classes. + * + * @return array + */ + public function get_shipping_classes() { + if ( empty( $this->shipping_classes ) ) { + $classes = get_terms( + 'product_shipping_class', + array( + 'hide_empty' => '0', + 'orderby' => 'name', + ) + ); + $this->shipping_classes = ! is_wp_error( $classes ) ? $classes : array(); + } + return apply_filters( 'woocommerce_get_shipping_classes', $this->shipping_classes ); + } + + /** + * Calculate shipping for (multiple) packages of cart items. + * + * @param array $packages multi-dimensional array of cart items to calc shipping for. + * @return array Array of calculated packages. + */ + public function calculate_shipping( $packages = array() ) { + $this->packages = array(); + + if ( ! $this->enabled || empty( $packages ) ) { + return array(); + } + + // Calculate costs for passed packages. + foreach ( $packages as $package_key => $package ) { + $this->packages[ $package_key ] = $this->calculate_shipping_for_package( $package, $package_key ); + } + + /** + * Allow packages to be reorganized after calculating the shipping. + * + * This filter can be used to apply some extra manipulation after the shipping costs are calculated for the packages + * but before WooCommerce does anything with them. A good example of usage is to merge the shipping methods for multiple + * packages for marketplaces. + * + * @since 2.6.0 + * + * @param array $packages The array of packages after shipping costs are calculated. + */ + $this->packages = array_filter( (array) apply_filters( 'woocommerce_shipping_packages', $this->packages ) ); + + return $this->packages; + } + + /** + * See if package is shippable. + * + * Packages are shippable until proven otherwise e.g. after getting a shipping country. + * + * @param array $package Package of cart items. + * @return bool + */ + public function is_package_shippable( $package ) { + // Packages are shippable until proven otherwise. + if ( empty( $package['destination']['country'] ) ) { + return true; + } + + $allowed = array_keys( WC()->countries->get_shipping_countries() ); + return in_array( $package['destination']['country'], $allowed, true ); + } + + /** + * Calculate shipping rates for a package, + * + * Calculates each shipping methods cost. Rates are stored in the session based on the package hash to avoid re-calculation every page load. + * + * @param array $package Package of cart items. + * @param int $package_key Index of the package being calculated. Used to cache multiple package rates. + * + * @return array|bool + */ + public function calculate_shipping_for_package( $package = array(), $package_key = 0 ) { + // If shipping is disabled or the package is invalid, return false. + if ( ! $this->enabled || empty( $package ) ) { + return false; + } + + $package['rates'] = array(); + + // If the package is not shippable, e.g. trying to ship to an invalid country, do not calculate rates. + if ( $this->is_package_shippable( $package ) ) { + // Check if we need to recalculate shipping for this package. + $package_to_hash = $package; + + // Remove data objects so hashes are consistent. + foreach ( $package_to_hash['contents'] as $item_id => $item ) { + unset( $package_to_hash['contents'][ $item_id ]['data'] ); + } + + // Get rates stored in the WC session data for this package. + $wc_session_key = 'shipping_for_package_' . $package_key; + $stored_rates = WC()->session->get( $wc_session_key ); + + // Calculate the hash for this package so we can tell if it's changed since last calculation. + $package_hash = 'wc_ship_' . md5( wp_json_encode( $package_to_hash ) . WC_Cache_Helper::get_transient_version( 'shipping' ) ); + + if ( ! is_array( $stored_rates ) || $package_hash !== $stored_rates['package_hash'] || 'yes' === get_option( 'woocommerce_shipping_debug_mode', 'no' ) ) { + foreach ( $this->load_shipping_methods( $package ) as $shipping_method ) { + if ( ! $shipping_method->supports( 'shipping-zones' ) || $shipping_method->get_instance_id() ) { + /** + * Fires before getting shipping rates for a package. + * + * @since 4.3.0 + * @param array $package Package of cart items. + * @param WC_Shipping_Method $shipping_method Shipping method instance. + */ + do_action( 'woocommerce_before_get_rates_for_package', $package, $shipping_method ); + + // Use + instead of array_merge to maintain numeric keys. + $package['rates'] = $package['rates'] + $shipping_method->get_rates_for_package( $package ); + + /** + * Fires after getting shipping rates for a package. + * + * @since 4.3.0 + * @param array $package Package of cart items. + * @param WC_Shipping_Method $shipping_method Shipping method instance. + */ + do_action( 'woocommerce_after_get_rates_for_package', $package, $shipping_method ); + } + } + + // Filter the calculated rates. + $package['rates'] = apply_filters( 'woocommerce_package_rates', $package['rates'], $package ); + + // Store in session to avoid recalculation. + WC()->session->set( + $wc_session_key, + array( + 'package_hash' => $package_hash, + 'rates' => $package['rates'], + ) + ); + } else { + $package['rates'] = $stored_rates['rates']; + } + } + return $package; + } + + /** + * Get packages. + * + * @return array + */ + public function get_packages() { + return $this->packages; + } + + /** + * Reset shipping. + * + * Reset the totals for shipping as a whole. + */ + public function reset_shipping() { + unset( WC()->session->chosen_shipping_methods ); + $this->packages = array(); + } + + /** + * Deprecated + * + * @deprecated 2.6.0 Was previously used to determine sort order of methods, but this is now controlled by zones and thus unused. + */ + public function sort_shipping_methods() { + wc_deprecated_function( 'sort_shipping_methods', '2.6' ); + return $this->shipping_methods; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shortcodes.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shortcodes.php new file mode 100644 index 0000000..b8eaa08 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-shortcodes.php @@ -0,0 +1,699 @@ + __CLASS__ . '::product', + 'product_page' => __CLASS__ . '::product_page', + 'product_category' => __CLASS__ . '::product_category', + 'product_categories' => __CLASS__ . '::product_categories', + 'add_to_cart' => __CLASS__ . '::product_add_to_cart', + 'add_to_cart_url' => __CLASS__ . '::product_add_to_cart_url', + 'products' => __CLASS__ . '::products', + 'recent_products' => __CLASS__ . '::recent_products', + 'sale_products' => __CLASS__ . '::sale_products', + 'best_selling_products' => __CLASS__ . '::best_selling_products', + 'top_rated_products' => __CLASS__ . '::top_rated_products', + 'featured_products' => __CLASS__ . '::featured_products', + 'product_attribute' => __CLASS__ . '::product_attribute', + 'related_products' => __CLASS__ . '::related_products', + 'shop_messages' => __CLASS__ . '::shop_messages', + 'woocommerce_order_tracking' => __CLASS__ . '::order_tracking', + 'woocommerce_cart' => __CLASS__ . '::cart', + 'woocommerce_checkout' => __CLASS__ . '::checkout', + 'woocommerce_my_account' => __CLASS__ . '::my_account', + ); + + foreach ( $shortcodes as $shortcode => $function ) { + add_shortcode( apply_filters( "{$shortcode}_shortcode_tag", $shortcode ), $function ); + } + + // Alias for pre 2.1 compatibility. + add_shortcode( 'woocommerce_messages', __CLASS__ . '::shop_messages' ); + } + + /** + * Shortcode Wrapper. + * + * @param string[] $function Callback function. + * @param array $atts Attributes. Default to empty array. + * @param array $wrapper Customer wrapper data. + * + * @return string + */ + public static function shortcode_wrapper( + $function, + $atts = array(), + $wrapper = array( + 'class' => 'woocommerce', + 'before' => null, + 'after' => null, + ) + ) { + ob_start(); + + // @codingStandardsIgnoreStart + echo empty( $wrapper['before'] ) ? '
    ' : $wrapper['before']; + call_user_func( $function, $atts ); + echo empty( $wrapper['after'] ) ? '
    ' : $wrapper['after']; + // @codingStandardsIgnoreEnd + + return ob_get_clean(); + } + + /** + * Cart page shortcode. + * + * @return string + */ + public static function cart() { + return is_null( WC()->cart ) ? '' : self::shortcode_wrapper( array( 'WC_Shortcode_Cart', 'output' ) ); + } + + /** + * Checkout page shortcode. + * + * @param array $atts Attributes. + * @return string + */ + public static function checkout( $atts ) { + return self::shortcode_wrapper( array( 'WC_Shortcode_Checkout', 'output' ), $atts ); + } + + /** + * Order tracking page shortcode. + * + * @param array $atts Attributes. + * @return string + */ + public static function order_tracking( $atts ) { + return self::shortcode_wrapper( array( 'WC_Shortcode_Order_Tracking', 'output' ), $atts ); + } + + /** + * My account page shortcode. + * + * @param array $atts Attributes. + * @return string + */ + public static function my_account( $atts ) { + return self::shortcode_wrapper( array( 'WC_Shortcode_My_Account', 'output' ), $atts ); + } + + /** + * List products in a category shortcode. + * + * @param array $atts Attributes. + * @return string + */ + public static function product_category( $atts ) { + if ( empty( $atts['category'] ) ) { + return ''; + } + + $atts = array_merge( + array( + 'limit' => '12', + 'columns' => '4', + 'orderby' => 'menu_order title', + 'order' => 'ASC', + 'category' => '', + 'cat_operator' => 'IN', + ), + (array) $atts + ); + + $shortcode = new WC_Shortcode_Products( $atts, 'product_category' ); + + return $shortcode->get_content(); + } + + /** + * List all (or limited) product categories. + * + * @param array $atts Attributes. + * @return string + */ + public static function product_categories( $atts ) { + if ( isset( $atts['number'] ) ) { + $atts['limit'] = $atts['number']; + } + + $atts = shortcode_atts( + array( + 'limit' => '-1', + 'orderby' => 'name', + 'order' => 'ASC', + 'columns' => '4', + 'hide_empty' => 1, + 'parent' => '', + 'ids' => '', + ), + $atts, + 'product_categories' + ); + + $ids = array_filter( array_map( 'trim', explode( ',', $atts['ids'] ) ) ); + $hide_empty = ( true === $atts['hide_empty'] || 'true' === $atts['hide_empty'] || 1 === $atts['hide_empty'] || '1' === $atts['hide_empty'] ) ? 1 : 0; + + // Get terms and workaround WP bug with parents/pad counts. + $args = array( + 'orderby' => $atts['orderby'], + 'order' => $atts['order'], + 'hide_empty' => $hide_empty, + 'include' => $ids, + 'pad_counts' => true, + 'child_of' => $atts['parent'], + ); + + $product_categories = apply_filters( + 'woocommerce_product_categories', + get_terms( 'product_cat', $args ) + ); + + if ( '' !== $atts['parent'] ) { + $product_categories = wp_list_filter( + $product_categories, + array( + 'parent' => $atts['parent'], + ) + ); + } + + if ( $hide_empty ) { + foreach ( $product_categories as $key => $category ) { + if ( 0 === $category->count ) { + unset( $product_categories[ $key ] ); + } + } + } + + $atts['limit'] = '-1' === $atts['limit'] ? null : intval( $atts['limit'] ); + if ( $atts['limit'] ) { + $product_categories = array_slice( $product_categories, 0, $atts['limit'] ); + } + + $columns = absint( $atts['columns'] ); + + wc_set_loop_prop( 'columns', $columns ); + wc_set_loop_prop( 'is_shortcode', true ); + + ob_start(); + + if ( $product_categories ) { + woocommerce_product_loop_start(); + + foreach ( $product_categories as $category ) { + wc_get_template( + 'content-product_cat.php', + array( + 'category' => $category, + ) + ); + } + + woocommerce_product_loop_end(); + } + + wc_reset_loop(); + + return '
    ' . ob_get_clean() . '
    '; + } + + /** + * Recent Products shortcode. + * + * @param array $atts Attributes. + * @return string + */ + public static function recent_products( $atts ) { + $atts = array_merge( + array( + 'limit' => '12', + 'columns' => '4', + 'orderby' => 'date', + 'order' => 'DESC', + 'category' => '', + 'cat_operator' => 'IN', + ), + (array) $atts + ); + + $shortcode = new WC_Shortcode_Products( $atts, 'recent_products' ); + + return $shortcode->get_content(); + } + + /** + * List multiple products shortcode. + * + * @param array $atts Attributes. + * @return string + */ + public static function products( $atts ) { + $atts = (array) $atts; + $type = 'products'; + + // Allow list product based on specific cases. + if ( isset( $atts['on_sale'] ) && wc_string_to_bool( $atts['on_sale'] ) ) { + $type = 'sale_products'; + } elseif ( isset( $atts['best_selling'] ) && wc_string_to_bool( $atts['best_selling'] ) ) { + $type = 'best_selling_products'; + } elseif ( isset( $atts['top_rated'] ) && wc_string_to_bool( $atts['top_rated'] ) ) { + $type = 'top_rated_products'; + } + + $shortcode = new WC_Shortcode_Products( $atts, $type ); + + return $shortcode->get_content(); + } + + /** + * Display a single product. + * + * @param array $atts Attributes. + * @return string + */ + public static function product( $atts ) { + if ( empty( $atts ) ) { + return ''; + } + + $atts['skus'] = isset( $atts['sku'] ) ? $atts['sku'] : ''; + $atts['ids'] = isset( $atts['id'] ) ? $atts['id'] : ''; + $atts['limit'] = '1'; + $shortcode = new WC_Shortcode_Products( (array) $atts, 'product' ); + + return $shortcode->get_content(); + } + + /** + * Display a single product price + cart button. + * + * @param array $atts Attributes. + * @return string + */ + public static function product_add_to_cart( $atts ) { + global $post; + + if ( empty( $atts ) ) { + return ''; + } + + $atts = shortcode_atts( + array( + 'id' => '', + 'class' => '', + 'quantity' => '1', + 'sku' => '', + 'style' => 'border:4px solid #ccc; padding: 12px;', + 'show_price' => 'true', + ), + $atts, + 'product_add_to_cart' + ); + + if ( ! empty( $atts['id'] ) ) { + $product_data = get_post( $atts['id'] ); + } elseif ( ! empty( $atts['sku'] ) ) { + $product_id = wc_get_product_id_by_sku( $atts['sku'] ); + $product_data = get_post( $product_id ); + } else { + return ''; + } + + $product = is_object( $product_data ) && in_array( $product_data->post_type, array( 'product', 'product_variation' ), true ) ? wc_setup_product_data( $product_data ) : false; + + if ( ! $product ) { + return ''; + } + + ob_start(); + + echo '

    '; + + if ( wc_string_to_bool( $atts['show_price'] ) ) { + // @codingStandardsIgnoreStart + echo $product->get_price_html(); + // @codingStandardsIgnoreEnd + } + + woocommerce_template_loop_add_to_cart( + array( + 'quantity' => $atts['quantity'], + ) + ); + + echo '

    '; + + // Restore Product global in case this is shown inside a product post. + wc_setup_product_data( $post ); + + return ob_get_clean(); + } + + /** + * Get the add to cart URL for a product. + * + * @param array $atts Attributes. + * @return string + */ + public static function product_add_to_cart_url( $atts ) { + if ( empty( $atts ) ) { + return ''; + } + + if ( isset( $atts['id'] ) ) { + $product_data = get_post( $atts['id'] ); + } elseif ( isset( $atts['sku'] ) ) { + $product_id = wc_get_product_id_by_sku( $atts['sku'] ); + $product_data = get_post( $product_id ); + } else { + return ''; + } + + $product = is_object( $product_data ) && in_array( $product_data->post_type, array( 'product', 'product_variation' ), true ) ? wc_setup_product_data( $product_data ) : false; + + if ( ! $product ) { + return ''; + } + + $_product = wc_get_product( $product_data ); + + return esc_url( $_product->add_to_cart_url() ); + } + + /** + * List all products on sale. + * + * @param array $atts Attributes. + * @return string + */ + public static function sale_products( $atts ) { + $atts = array_merge( + array( + 'limit' => '12', + 'columns' => '4', + 'orderby' => 'title', + 'order' => 'ASC', + 'category' => '', + 'cat_operator' => 'IN', + ), + (array) $atts + ); + + $shortcode = new WC_Shortcode_Products( $atts, 'sale_products' ); + + return $shortcode->get_content(); + } + + /** + * List best selling products on sale. + * + * @param array $atts Attributes. + * @return string + */ + public static function best_selling_products( $atts ) { + $atts = array_merge( + array( + 'limit' => '12', + 'columns' => '4', + 'category' => '', + 'cat_operator' => 'IN', + ), + (array) $atts + ); + + $shortcode = new WC_Shortcode_Products( $atts, 'best_selling_products' ); + + return $shortcode->get_content(); + } + + /** + * List top rated products on sale. + * + * @param array $atts Attributes. + * @return string + */ + public static function top_rated_products( $atts ) { + $atts = array_merge( + array( + 'limit' => '12', + 'columns' => '4', + 'orderby' => 'title', + 'order' => 'ASC', + 'category' => '', + 'cat_operator' => 'IN', + ), + (array) $atts + ); + + $shortcode = new WC_Shortcode_Products( $atts, 'top_rated_products' ); + + return $shortcode->get_content(); + } + + /** + * Output featured products. + * + * @param array $atts Attributes. + * @return string + */ + public static function featured_products( $atts ) { + $atts = array_merge( + array( + 'limit' => '12', + 'columns' => '4', + 'orderby' => 'date', + 'order' => 'DESC', + 'category' => '', + 'cat_operator' => 'IN', + ), + (array) $atts + ); + + $atts['visibility'] = 'featured'; + + $shortcode = new WC_Shortcode_Products( $atts, 'featured_products' ); + + return $shortcode->get_content(); + } + + /** + * Show a single product page. + * + * @param array $atts Attributes. + * @return string + */ + public static function product_page( $atts ) { + if ( empty( $atts ) ) { + return ''; + } + + if ( ! isset( $atts['id'] ) && ! isset( $atts['sku'] ) ) { + return ''; + } + + $args = array( + 'posts_per_page' => 1, + 'post_type' => 'product', + 'post_status' => ( ! empty( $atts['status'] ) ) ? $atts['status'] : 'publish', + 'ignore_sticky_posts' => 1, + 'no_found_rows' => 1, + ); + + if ( isset( $atts['sku'] ) ) { + $args['meta_query'][] = array( + 'key' => '_sku', + 'value' => sanitize_text_field( $atts['sku'] ), + 'compare' => '=', + ); + + $args['post_type'] = array( 'product', 'product_variation' ); + } + + if ( isset( $atts['id'] ) ) { + $args['p'] = absint( $atts['id'] ); + } + + // Don't render titles if desired. + if ( isset( $atts['show_title'] ) && ! $atts['show_title'] ) { + remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_title', 5 ); + } + + // Change form action to avoid redirect. + add_filter( 'woocommerce_add_to_cart_form_action', '__return_empty_string' ); + + $single_product = new WP_Query( $args ); + + $preselected_id = '0'; + + // Check if sku is a variation. + if ( isset( $atts['sku'] ) && $single_product->have_posts() && 'product_variation' === $single_product->post->post_type ) { + + $variation = wc_get_product_object( 'variation', $single_product->post->ID ); + $attributes = $variation->get_attributes(); + + // Set preselected id to be used by JS to provide context. + $preselected_id = $single_product->post->ID; + + // Get the parent product object. + $args = array( + 'posts_per_page' => 1, + 'post_type' => 'product', + 'post_status' => 'publish', + 'ignore_sticky_posts' => 1, + 'no_found_rows' => 1, + 'p' => $single_product->post->post_parent, + ); + + $single_product = new WP_Query( $args ); + ?> + + is_single = true; + + ob_start(); + + global $wp_query; + + // Backup query object so following loops think this is a product page. + $previous_wp_query = $wp_query; + // @codingStandardsIgnoreStart + $wp_query = $single_product; + // @codingStandardsIgnoreEnd + + wp_enqueue_script( 'wc-single-product' ); + + while ( $single_product->have_posts() ) { + $single_product->the_post() + ?> +
    + +
    + ' . ob_get_clean() . ''; + } + + /** + * Show messages. + * + * @return string + */ + public static function shop_messages() { + if ( ! function_exists( 'wc_print_notices' ) ) { + return ''; + } + return '
    ' . wc_print_notices( true ) . '
    '; + } + + /** + * Order by rating. + * + * @deprecated 3.2.0 Use WC_Shortcode_Products::order_by_rating_post_clauses(). + * @param array $args Query args. + * @return array + */ + public static function order_by_rating_post_clauses( $args ) { + return WC_Shortcode_Products::order_by_rating_post_clauses( $args ); + } + + /** + * List products with an attribute shortcode. + * Example [product_attribute attribute="color" filter="black"]. + * + * @param array $atts Attributes. + * @return string + */ + public static function product_attribute( $atts ) { + $atts = array_merge( + array( + 'limit' => '12', + 'columns' => '4', + 'orderby' => 'title', + 'order' => 'ASC', + 'attribute' => '', + 'terms' => '', + ), + (array) $atts + ); + + if ( empty( $atts['attribute'] ) ) { + return ''; + } + + $shortcode = new WC_Shortcode_Products( $atts, 'product_attribute' ); + + return $shortcode->get_content(); + } + + /** + * List related products. + * + * @param array $atts Attributes. + * @return string + */ + public static function related_products( $atts ) { + if ( isset( $atts['per_page'] ) ) { + $atts['limit'] = $atts['per_page']; + } + + // @codingStandardsIgnoreStart + $atts = shortcode_atts( array( + 'limit' => '4', + 'columns' => '4', + 'orderby' => 'rand', + ), $atts, 'related_products' ); + // @codingStandardsIgnoreEnd + + ob_start(); + + // Rename arg. + $atts['posts_per_page'] = absint( $atts['limit'] ); + + woocommerce_related_products( $atts ); + + return ob_get_clean(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-structured-data.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-structured-data.php new file mode 100644 index 0000000..070bea6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-structured-data.php @@ -0,0 +1,538 @@ +_data ) ) { + unset( $this->_data ); + } + + $this->_data[] = $data; + + return true; + } + + /** + * Gets data. + * + * @return array + */ + public function get_data() { + return $this->_data; + } + + /** + * Structures and returns data. + * + * List of types available by default for specific request: + * + * 'product', + * 'review', + * 'breadcrumblist', + * 'website', + * 'order', + * + * @param array $types Structured data types. + * @return array + */ + public function get_structured_data( $types ) { + $data = array(); + + // Put together the values of same type of structured data. + foreach ( $this->get_data() as $value ) { + $data[ strtolower( $value['@type'] ) ][] = $value; + } + + // Wrap the multiple values of each type inside a graph... Then add context to each type. + foreach ( $data as $type => $value ) { + $data[ $type ] = count( $value ) > 1 ? array( '@graph' => $value ) : $value[0]; + $data[ $type ] = apply_filters( 'woocommerce_structured_data_context', array( '@context' => 'https://schema.org/' ), $data, $type, $value ) + $data[ $type ]; + } + + // If requested types, pick them up... Finally change the associative array to an indexed one. + $data = $types ? array_values( array_intersect_key( $data, array_flip( $types ) ) ) : array_values( $data ); + + if ( ! empty( $data ) ) { + if ( 1 < count( $data ) ) { + $data = apply_filters( 'woocommerce_structured_data_context', array( '@context' => 'https://schema.org/' ), $data, '', '' ) + array( '@graph' => $data ); + } else { + $data = $data[0]; + } + } + + return $data; + } + + /** + * Get data types for pages. + * + * @return array + */ + protected function get_data_type_for_page() { + $types = array(); + $types[] = is_shop() || is_product_category() || is_product() ? 'product' : ''; + $types[] = is_shop() && is_front_page() ? 'website' : ''; + $types[] = is_product() ? 'review' : ''; + $types[] = 'breadcrumblist'; + $types[] = 'order'; + + return array_filter( apply_filters( 'woocommerce_structured_data_type_for_page', $types ) ); + } + + /** + * Makes sure email structured data only outputs on non-plain text versions. + * + * @param WP_Order $order Order data. + * @param bool $sent_to_admin Send to admin (default: false). + * @param bool $plain_text Plain text email (default: false). + */ + public function output_email_structured_data( $order, $sent_to_admin = false, $plain_text = false ) { + if ( $plain_text ) { + return; + } + echo '
    '; + $this->output_structured_data(); + echo '
    '; + } + + /** + * Sanitizes, encodes and outputs structured data. + * + * Hooked into `wp_footer` action hook. + * Hooked into `woocommerce_email_order_details` action hook. + */ + public function output_structured_data() { + $types = $this->get_data_type_for_page(); + $data = $this->get_structured_data( $types ); + + if ( $data ) { + echo ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + } + + /* + |-------------------------------------------------------------------------- + | Generators + |-------------------------------------------------------------------------- + | + | Methods for generating specific structured data types: + | + | - Product + | - Review + | - BreadcrumbList + | - WebSite + | - Order + | + | The generated data is stored into `$this->_data`. + | See the methods above for handling `$this->_data`. + | + */ + + /** + * Generates Product structured data. + * + * Hooked into `woocommerce_single_product_summary` action hook. + * + * @param WC_Product $product Product data (default: null). + */ + public function generate_product_data( $product = null ) { + if ( ! is_object( $product ) ) { + global $product; + } + + if ( ! is_a( $product, 'WC_Product' ) ) { + return; + } + + $shop_name = get_bloginfo( 'name' ); + $shop_url = home_url(); + $currency = get_woocommerce_currency(); + $permalink = get_permalink( $product->get_id() ); + $image = wp_get_attachment_url( $product->get_image_id() ); + + $markup = array( + '@type' => 'Product', + '@id' => $permalink . '#product', // Append '#product' to differentiate between this @id and the @id generated for the Breadcrumblist. + 'name' => $product->get_name(), + 'url' => $permalink, + 'description' => wp_strip_all_tags( do_shortcode( $product->get_short_description() ? $product->get_short_description() : $product->get_description() ) ), + ); + + if ( $image ) { + $markup['image'] = $image; + } + + // Declare SKU or fallback to ID. + if ( $product->get_sku() ) { + $markup['sku'] = $product->get_sku(); + } else { + $markup['sku'] = $product->get_id(); + } + + if ( '' !== $product->get_price() ) { + // Assume prices will be valid until the end of next year, unless on sale and there is an end date. + $price_valid_until = gmdate( 'Y-12-31', time() + YEAR_IN_SECONDS ); + + if ( $product->is_type( 'variable' ) ) { + $lowest = $product->get_variation_price( 'min', false ); + $highest = $product->get_variation_price( 'max', false ); + + if ( $lowest === $highest ) { + $markup_offer = array( + '@type' => 'Offer', + 'price' => wc_format_decimal( $lowest, wc_get_price_decimals() ), + 'priceValidUntil' => $price_valid_until, + 'priceSpecification' => array( + 'price' => wc_format_decimal( $lowest, wc_get_price_decimals() ), + 'priceCurrency' => $currency, + 'valueAddedTaxIncluded' => wc_prices_include_tax() ? 'true' : 'false', + ), + ); + } else { + $markup_offer = array( + '@type' => 'AggregateOffer', + 'lowPrice' => wc_format_decimal( $lowest, wc_get_price_decimals() ), + 'highPrice' => wc_format_decimal( $highest, wc_get_price_decimals() ), + 'offerCount' => count( $product->get_children() ), + ); + } + } else { + if ( $product->is_on_sale() && $product->get_date_on_sale_to() ) { + $price_valid_until = gmdate( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ); + } + $markup_offer = array( + '@type' => 'Offer', + 'price' => wc_format_decimal( $product->get_price(), wc_get_price_decimals() ), + 'priceValidUntil' => $price_valid_until, + 'priceSpecification' => array( + 'price' => wc_format_decimal( $product->get_price(), wc_get_price_decimals() ), + 'priceCurrency' => $currency, + 'valueAddedTaxIncluded' => wc_prices_include_tax() ? 'true' : 'false', + ), + ); + } + + $markup_offer += array( + 'priceCurrency' => $currency, + 'availability' => 'http://schema.org/' . ( $product->is_in_stock() ? 'InStock' : 'OutOfStock' ), + 'url' => $permalink, + 'seller' => array( + '@type' => 'Organization', + 'name' => $shop_name, + 'url' => $shop_url, + ), + ); + + $markup['offers'] = array( apply_filters( 'woocommerce_structured_data_product_offer', $markup_offer, $product ) ); + } + + if ( $product->get_rating_count() && wc_review_ratings_enabled() ) { + $markup['aggregateRating'] = array( + '@type' => 'AggregateRating', + 'ratingValue' => $product->get_average_rating(), + 'reviewCount' => $product->get_review_count(), + ); + + // Markup 5 most recent rating/review. + $comments = get_comments( + array( + 'number' => 5, + 'post_id' => $product->get_id(), + 'status' => 'approve', + 'post_status' => 'publish', + 'post_type' => 'product', + 'parent' => 0, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + array( + 'key' => 'rating', + 'type' => 'NUMERIC', + 'compare' => '>', + 'value' => 0, + ), + ), + ) + ); + + if ( $comments ) { + $markup['review'] = array(); + foreach ( $comments as $comment ) { + $markup['review'][] = array( + '@type' => 'Review', + 'reviewRating' => array( + '@type' => 'Rating', + 'bestRating' => '5', + 'ratingValue' => get_comment_meta( $comment->comment_ID, 'rating', true ), + 'worstRating' => '1', + ), + 'author' => array( + '@type' => 'Person', + 'name' => get_comment_author( $comment ), + ), + 'reviewBody' => get_comment_text( $comment ), + 'datePublished' => get_comment_date( 'c', $comment ), + ); + } + } + } + + // Check we have required data. + if ( empty( $markup['aggregateRating'] ) && empty( $markup['offers'] ) && empty( $markup['review'] ) ) { + return; + } + + $this->set_data( apply_filters( 'woocommerce_structured_data_product', $markup, $product ) ); + } + + /** + * Generates Review structured data. + * + * Hooked into `woocommerce_review_meta` action hook. + * + * @param WP_Comment $comment Comment data. + */ + public function generate_review_data( $comment ) { + $markup = array(); + $markup['@type'] = 'Review'; + $markup['@id'] = get_comment_link( $comment->comment_ID ); + $markup['datePublished'] = get_comment_date( 'c', $comment->comment_ID ); + $markup['description'] = get_comment_text( $comment->comment_ID ); + $markup['itemReviewed'] = array( + '@type' => 'Product', + 'name' => get_the_title( $comment->comment_post_ID ), + ); + + // Skip replies unless they have a rating. + $rating = get_comment_meta( $comment->comment_ID, 'rating', true ); + + if ( $rating ) { + $markup['reviewRating'] = array( + '@type' => 'Rating', + 'bestRating' => '5', + 'ratingValue' => $rating, + 'worstRating' => '1', + ); + } elseif ( $comment->comment_parent ) { + return; + } + + $markup['author'] = array( + '@type' => 'Person', + 'name' => get_comment_author( $comment->comment_ID ), + ); + + $this->set_data( apply_filters( 'woocommerce_structured_data_review', $markup, $comment ) ); + } + + /** + * Generates BreadcrumbList structured data. + * + * Hooked into `woocommerce_breadcrumb` action hook. + * + * @param WC_Breadcrumb $breadcrumbs Breadcrumb data. + */ + public function generate_breadcrumblist_data( $breadcrumbs ) { + $crumbs = $breadcrumbs->get_breadcrumb(); + + if ( empty( $crumbs ) || ! is_array( $crumbs ) ) { + return; + } + + $markup = array(); + $markup['@type'] = 'BreadcrumbList'; + $markup['itemListElement'] = array(); + + foreach ( $crumbs as $key => $crumb ) { + $markup['itemListElement'][ $key ] = array( + '@type' => 'ListItem', + 'position' => $key + 1, + 'item' => array( + 'name' => $crumb[0], + ), + ); + + if ( ! empty( $crumb[1] ) ) { + $markup['itemListElement'][ $key ]['item'] += array( '@id' => $crumb[1] ); + } elseif ( isset( $_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'] ) ) { + $current_url = set_url_scheme( 'http://' . wp_unslash( $_SERVER['HTTP_HOST'] ) . wp_unslash( $_SERVER['REQUEST_URI'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + $markup['itemListElement'][ $key ]['item'] += array( '@id' => $current_url ); + } + } + + $this->set_data( apply_filters( 'woocommerce_structured_data_breadcrumblist', $markup, $breadcrumbs ) ); + } + + /** + * Generates WebSite structured data. + * + * Hooked into `woocommerce_before_main_content` action hook. + */ + public function generate_website_data() { + $markup = array(); + $markup['@type'] = 'WebSite'; + $markup['name'] = get_bloginfo( 'name' ); + $markup['url'] = home_url(); + $markup['potentialAction'] = array( + '@type' => 'SearchAction', + 'target' => home_url( '?s={search_term_string}&post_type=product' ), + 'query-input' => 'required name=search_term_string', + ); + + $this->set_data( apply_filters( 'woocommerce_structured_data_website', $markup ) ); + } + + /** + * Generates Order structured data. + * + * Hooked into `woocommerce_email_order_details` action hook. + * + * @param WP_Order $order Order data. + * @param bool $sent_to_admin Send to admin (default: false). + * @param bool $plain_text Plain text email (default: false). + */ + public function generate_order_data( $order, $sent_to_admin = false, $plain_text = false ) { + if ( $plain_text || ! is_a( $order, 'WC_Order' ) ) { + return; + } + + $shop_name = get_bloginfo( 'name' ); + $shop_url = home_url(); + $order_url = $sent_to_admin ? $order->get_edit_order_url() : $order->get_view_order_url(); + $order_statuses = array( + 'pending' => 'https://schema.org/OrderPaymentDue', + 'processing' => 'https://schema.org/OrderProcessing', + 'on-hold' => 'https://schema.org/OrderProblem', + 'completed' => 'https://schema.org/OrderDelivered', + 'cancelled' => 'https://schema.org/OrderCancelled', + 'refunded' => 'https://schema.org/OrderReturned', + 'failed' => 'https://schema.org/OrderProblem', + ); + + $markup_offers = array(); + foreach ( $order->get_items() as $item ) { + if ( ! apply_filters( 'woocommerce_order_item_visible', true, $item ) ) { + continue; + } + + $product = $item->get_product(); + $product_exists = is_object( $product ); + $is_visible = $product_exists && $product->is_visible(); + + $markup_offers[] = array( + '@type' => 'Offer', + 'price' => $order->get_line_subtotal( $item ), + 'priceCurrency' => $order->get_currency(), + 'priceSpecification' => array( + 'price' => $order->get_line_subtotal( $item ), + 'priceCurrency' => $order->get_currency(), + 'eligibleQuantity' => array( + '@type' => 'QuantitativeValue', + 'value' => apply_filters( 'woocommerce_email_order_item_quantity', $item->get_quantity(), $item ), + ), + ), + 'itemOffered' => array( + '@type' => 'Product', + 'name' => apply_filters( 'woocommerce_order_item_name', $item->get_name(), $item, $is_visible ), + 'sku' => $product_exists ? $product->get_sku() : '', + 'image' => $product_exists ? wp_get_attachment_image_url( $product->get_image_id() ) : '', + 'url' => $is_visible ? get_permalink( $product->get_id() ) : get_home_url(), + ), + 'seller' => array( + '@type' => 'Organization', + 'name' => $shop_name, + 'url' => $shop_url, + ), + ); + } + + $markup = array(); + $markup['@type'] = 'Order'; + $markup['url'] = $order_url; + $markup['orderStatus'] = isset( $order_statuses[ $order->get_status() ] ) ? $order_statuses[ $order->get_status() ] : ''; + $markup['orderNumber'] = $order->get_order_number(); + $markup['orderDate'] = $order->get_date_created()->format( 'c' ); + $markup['acceptedOffer'] = $markup_offers; + $markup['discount'] = $order->get_total_discount(); + $markup['discountCurrency'] = $order->get_currency(); + $markup['price'] = $order->get_total(); + $markup['priceCurrency'] = $order->get_currency(); + $markup['priceSpecification'] = array( + 'price' => $order->get_total(), + 'priceCurrency' => $order->get_currency(), + 'valueAddedTaxIncluded' => 'true', + ); + $markup['billingAddress'] = array( + '@type' => 'PostalAddress', + 'name' => $order->get_formatted_billing_full_name(), + 'streetAddress' => $order->get_billing_address_1(), + 'postalCode' => $order->get_billing_postcode(), + 'addressLocality' => $order->get_billing_city(), + 'addressRegion' => $order->get_billing_state(), + 'addressCountry' => $order->get_billing_country(), + 'email' => $order->get_billing_email(), + 'telephone' => $order->get_billing_phone(), + ); + $markup['customer'] = array( + '@type' => 'Person', + 'name' => $order->get_formatted_billing_full_name(), + ); + $markup['merchant'] = array( + '@type' => 'Organization', + 'name' => $shop_name, + 'url' => $shop_url, + ); + $markup['potentialAction'] = array( + '@type' => 'ViewAction', + 'name' => 'View Order', + 'url' => $order_url, + 'target' => $order_url, + ); + + $this->set_data( apply_filters( 'woocommerce_structured_data_order', $markup, $sent_to_admin, $order ), true ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-tax.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-tax.php new file mode 100644 index 0000000..f80a7d8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-tax.php @@ -0,0 +1,1226 @@ + $rate ) { + $taxes[ $key ] = 0; + + if ( 'yes' === $rate['compound'] ) { + $compound_rates[ $key ] = $rate['rate']; + } else { + $regular_rates[ $key ] = $rate['rate']; + } + } + + $compound_rates = array_reverse( $compound_rates, true ); // Working backwards. + + $non_compound_price = $price; + + foreach ( $compound_rates as $key => $compound_rate ) { + $tax_amount = apply_filters( 'woocommerce_price_inc_tax_amount', $non_compound_price - ( $non_compound_price / ( 1 + ( $compound_rate / 100 ) ) ), $key, $rates[ $key ], $price ); + $taxes[ $key ] += $tax_amount; + $non_compound_price = $non_compound_price - $tax_amount; + } + + // Regular taxes. + $regular_tax_rate = 1 + ( array_sum( $regular_rates ) / 100 ); + + foreach ( $regular_rates as $key => $regular_rate ) { + $the_rate = ( $regular_rate / 100 ) / $regular_tax_rate; + $net_price = $price - ( $the_rate * $non_compound_price ); + $tax_amount = apply_filters( 'woocommerce_price_inc_tax_amount', $price - $net_price, $key, $rates[ $key ], $price ); + $taxes[ $key ] += $tax_amount; + } + + /** + * Round all taxes to precision (4DP) before passing them back. Note, this is not the same rounding + * as in the cart calculation class which, depending on settings, will round to 2DP when calculating + * final totals. Also unlike that class, this rounds .5 up for all cases. + */ + $taxes = array_map( array( __CLASS__, 'round' ), $taxes ); + + return $taxes; + } + + /** + * Calc tax from exclusive price. + * + * @param float $price Price to calculate tax for. + * @param array $rates Array of tax rates. + * @return array + */ + public static function calc_exclusive_tax( $price, $rates ) { + $taxes = array(); + + if ( ! empty( $rates ) ) { + foreach ( $rates as $key => $rate ) { + if ( 'yes' === $rate['compound'] ) { + continue; + } + + $tax_amount = $price * ( $rate['rate'] / 100 ); + $tax_amount = apply_filters( 'woocommerce_price_ex_tax_amount', $tax_amount, $key, $rate, $price ); // ADVANCED: Allow third parties to modify this rate. + + if ( ! isset( $taxes[ $key ] ) ) { + $taxes[ $key ] = $tax_amount; + } else { + $taxes[ $key ] += $tax_amount; + } + } + + $pre_compound_total = array_sum( $taxes ); + + // Compound taxes. + foreach ( $rates as $key => $rate ) { + if ( 'no' === $rate['compound'] ) { + continue; + } + $the_price_inc_tax = $price + ( $pre_compound_total ); + $tax_amount = $the_price_inc_tax * ( $rate['rate'] / 100 ); + $tax_amount = apply_filters( 'woocommerce_price_ex_tax_amount', $tax_amount, $key, $rate, $price, $the_price_inc_tax, $pre_compound_total ); // ADVANCED: Allow third parties to modify this rate. + + if ( ! isset( $taxes[ $key ] ) ) { + $taxes[ $key ] = $tax_amount; + } else { + $taxes[ $key ] += $tax_amount; + } + + $pre_compound_total = array_sum( $taxes ); + } + } + + /** + * Round all taxes to precision (4DP) before passing them back. Note, this is not the same rounding + * as in the cart calculation class which, depending on settings, will round to 2DP when calculating + * final totals. Also unlike that class, this rounds .5 up for all cases. + */ + $taxes = array_map( array( __CLASS__, 'round' ), $taxes ); + + return $taxes; + } + + /** + * Searches for all matching country/state/postcode tax rates. + * + * @param array $args Args that determine the rate to find. + * @return array + */ + public static function find_rates( $args = array() ) { + $args = wp_parse_args( + $args, + array( + 'country' => '', + 'state' => '', + 'city' => '', + 'postcode' => '', + 'tax_class' => '', + ) + ); + + $country = $args['country']; + $state = $args['state']; + $city = $args['city']; + $postcode = wc_normalize_postcode( wc_clean( $args['postcode'] ) ); + $tax_class = $args['tax_class']; + + if ( ! $country ) { + return array(); + } + + $cache_key = WC_Cache_Helper::get_cache_prefix( 'taxes' ) . 'wc_tax_rates_' . md5( sprintf( '%s+%s+%s+%s+%s', $country, $state, $city, $postcode, $tax_class ) ); + $matched_tax_rates = wp_cache_get( $cache_key, 'taxes' ); + + if ( false === $matched_tax_rates ) { + $matched_tax_rates = self::get_matched_tax_rates( $country, $state, $postcode, $city, $tax_class ); + wp_cache_set( $cache_key, $matched_tax_rates, 'taxes' ); + } + + return apply_filters( 'woocommerce_find_rates', $matched_tax_rates, $args ); + } + + /** + * Searches for all matching country/state/postcode tax rates. + * + * @param array $args Args that determine the rate to find. + * @return array + */ + public static function find_shipping_rates( $args = array() ) { + $rates = self::find_rates( $args ); + $shipping_rates = array(); + + if ( is_array( $rates ) ) { + foreach ( $rates as $key => $rate ) { + if ( 'yes' === $rate['shipping'] ) { + $shipping_rates[ $key ] = $rate; + } + } + } + + return $shipping_rates; + } + + /** + * Does the sort comparison. Compares (in this order): + * - Priority + * - Country + * - State + * - Number of postcodes + * - Number of cities + * - ID + * + * @param object $rate1 First rate to compare. + * @param object $rate2 Second rate to compare. + * @return int + */ + private static function sort_rates_callback( $rate1, $rate2 ) { + if ( $rate1->tax_rate_priority !== $rate2->tax_rate_priority ) { + return $rate1->tax_rate_priority < $rate2->tax_rate_priority ? -1 : 1; // ASC. + } + + if ( $rate1->tax_rate_country !== $rate2->tax_rate_country ) { + if ( '' === $rate1->tax_rate_country ) { + return 1; + } + if ( '' === $rate2->tax_rate_country ) { + return -1; + } + return strcmp( $rate1->tax_rate_country, $rate2->tax_rate_country ) > 0 ? 1 : -1; + } + + if ( $rate1->tax_rate_state !== $rate2->tax_rate_state ) { + if ( '' === $rate1->tax_rate_state ) { + return 1; + } + if ( '' === $rate2->tax_rate_state ) { + return -1; + } + return strcmp( $rate1->tax_rate_state, $rate2->tax_rate_state ) > 0 ? 1 : -1; + } + + if ( isset( $rate1->postcode_count, $rate2->postcode_count ) && $rate1->postcode_count !== $rate2->postcode_count ) { + return $rate1->postcode_count < $rate2->postcode_count ? 1 : -1; + } + + if ( isset( $rate1->city_count, $rate2->city_count ) && $rate1->city_count !== $rate2->city_count ) { + return $rate1->city_count < $rate2->city_count ? 1 : -1; + } + + return $rate1->tax_rate_id < $rate2->tax_rate_id ? -1 : 1; + } + + /** + * Logical sort order for tax rates based on the following in order of priority. + * + * @param array $rates Rates to be sorted. + * @return array + */ + private static function sort_rates( $rates ) { + uasort( $rates, __CLASS__ . '::sort_rates_callback' ); + $i = 0; + foreach ( $rates as $key => $rate ) { + $rates[ $key ]->tax_rate_order = $i++; + } + return $rates; + } + + /** + * Loop through a set of tax rates and get the matching rates (1 per priority). + * + * @param string $country Country code to match against. + * @param string $state State code to match against. + * @param string $postcode Postcode to match against. + * @param string $city City to match against. + * @param string $tax_class Tax class to match against. + * @return array + */ + private static function get_matched_tax_rates( $country, $state, $postcode, $city, $tax_class ) { + global $wpdb; + + // Query criteria - these will be ANDed. + $criteria = array(); + $criteria[] = $wpdb->prepare( "tax_rate_country IN ( %s, '' )", strtoupper( $country ) ); + $criteria[] = $wpdb->prepare( "tax_rate_state IN ( %s, '' )", strtoupper( $state ) ); + $criteria[] = $wpdb->prepare( 'tax_rate_class = %s', sanitize_title( $tax_class ) ); + + // Pre-query postcode ranges for PHP based matching. + $postcode_search = wc_get_wildcard_postcodes( $postcode, $country ); + $postcode_ranges = $wpdb->get_results( "SELECT tax_rate_id, location_code FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE location_type = 'postcode' AND location_code LIKE '%...%';" ); + + if ( $postcode_ranges ) { + $matches = wc_postcode_location_matcher( $postcode, $postcode_ranges, 'tax_rate_id', 'location_code', $country ); + if ( ! empty( $matches ) ) { + foreach ( $matches as $matched_postcodes ) { + $postcode_search = array_merge( $postcode_search, $matched_postcodes ); + } + } + } + + $postcode_search = array_unique( $postcode_search ); + + /** + * Location matching criteria - ORed + * Needs to match: + * - rates with no postcodes and cities + * - rates with a matching postcode and city + * - rates with matching postcode, no city + * - rates with matching city, no postcode + */ + $locations_criteria = array(); + $locations_criteria[] = 'locations.location_type IS NULL'; + $locations_criteria[] = " + locations.location_type = 'postcode' AND locations.location_code IN ('" . implode( "','", array_map( 'esc_sql', $postcode_search ) ) . "') + AND ( + ( locations2.location_type = 'city' AND locations2.location_code = '" . esc_sql( strtoupper( $city ) ) . "' ) + OR NOT EXISTS ( + SELECT sub.tax_rate_id FROM {$wpdb->prefix}woocommerce_tax_rate_locations as sub + WHERE sub.location_type = 'city' + AND sub.tax_rate_id = tax_rates.tax_rate_id + ) + ) + "; + $locations_criteria[] = " + locations.location_type = 'city' AND locations.location_code = '" . esc_sql( strtoupper( $city ) ) . "' + AND NOT EXISTS ( + SELECT sub.tax_rate_id FROM {$wpdb->prefix}woocommerce_tax_rate_locations as sub + WHERE sub.location_type = 'postcode' + AND sub.tax_rate_id = tax_rates.tax_rate_id + ) + "; + + $criteria[] = '( ( ' . implode( ' ) OR ( ', $locations_criteria ) . ' ) )'; + + $criteria_string = implode( ' AND ', $criteria ); + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $found_rates = $wpdb->get_results( + " + SELECT tax_rates.*, COUNT( locations.location_id ) as postcode_count, COUNT( locations2.location_id ) as city_count + FROM {$wpdb->prefix}woocommerce_tax_rates as tax_rates + LEFT OUTER JOIN {$wpdb->prefix}woocommerce_tax_rate_locations as locations ON tax_rates.tax_rate_id = locations.tax_rate_id + LEFT OUTER JOIN {$wpdb->prefix}woocommerce_tax_rate_locations as locations2 ON tax_rates.tax_rate_id = locations2.tax_rate_id + WHERE 1=1 AND {$criteria_string} + GROUP BY tax_rates.tax_rate_id + ORDER BY tax_rates.tax_rate_priority + " + ); + // phpcs:enable + + $found_rates = self::sort_rates( $found_rates ); + $matched_tax_rates = array(); + $found_priority = array(); + + foreach ( $found_rates as $found_rate ) { + if ( in_array( $found_rate->tax_rate_priority, $found_priority, true ) ) { + continue; + } + + $matched_tax_rates[ $found_rate->tax_rate_id ] = array( + 'rate' => (float) $found_rate->tax_rate, + 'label' => $found_rate->tax_rate_name, + 'shipping' => $found_rate->tax_rate_shipping ? 'yes' : 'no', + 'compound' => $found_rate->tax_rate_compound ? 'yes' : 'no', + ); + + $found_priority[] = $found_rate->tax_rate_priority; + } + + return apply_filters( 'woocommerce_matched_tax_rates', $matched_tax_rates, $country, $state, $postcode, $city, $tax_class ); + } + + /** + * Get the customer tax location based on their status and the current page. + * + * Used by get_rates(), get_shipping_rates(). + * + * @param string $tax_class string Optional, passed to the filter for advanced tax setups. + * @param object $customer Override the customer object to get their location. + * @return array + */ + public static function get_tax_location( $tax_class = '', $customer = null ) { + $location = array(); + + if ( is_null( $customer ) && WC()->customer ) { + $customer = WC()->customer; + } + + if ( ! empty( $customer ) ) { + $location = $customer->get_taxable_address(); + } elseif ( wc_prices_include_tax() || 'base' === get_option( 'woocommerce_default_customer_address' ) || 'base' === get_option( 'woocommerce_tax_based_on' ) ) { + $location = array( + WC()->countries->get_base_country(), + WC()->countries->get_base_state(), + WC()->countries->get_base_postcode(), + WC()->countries->get_base_city(), + ); + } + + return apply_filters( 'woocommerce_get_tax_location', $location, $tax_class, $customer ); + } + + /** + * Get's an array of matching rates for a tax class. + * + * @param string $tax_class Tax class to get rates for. + * @param object $customer Override the customer object to get their location. + * @return array + */ + public static function get_rates( $tax_class = '', $customer = null ) { + $tax_class = sanitize_title( $tax_class ); + $location = self::get_tax_location( $tax_class, $customer ); + $matched_tax_rates = array(); + + if ( count( $location ) === 4 ) { + list( $country, $state, $postcode, $city ) = $location; + + $matched_tax_rates = self::find_rates( + array( + 'country' => $country, + 'state' => $state, + 'postcode' => $postcode, + 'city' => $city, + 'tax_class' => $tax_class, + ) + ); + } + + return apply_filters( 'woocommerce_matched_rates', $matched_tax_rates, $tax_class, $customer ); + } + + /** + * Get's an array of matching rates for the shop's base country. + * + * @param string $tax_class Tax Class. + * @return array + */ + public static function get_base_tax_rates( $tax_class = '' ) { + return apply_filters( + 'woocommerce_base_tax_rates', + self::find_rates( + array( + 'country' => WC()->countries->get_base_country(), + 'state' => WC()->countries->get_base_state(), + 'postcode' => WC()->countries->get_base_postcode(), + 'city' => WC()->countries->get_base_city(), + 'tax_class' => $tax_class, + ) + ), + $tax_class + ); + } + + /** + * Alias for get_base_tax_rates(). + * + * @deprecated 2.3 + * @param string $tax_class Tax Class. + * @return array + */ + public static function get_shop_base_rate( $tax_class = '' ) { + return self::get_base_tax_rates( $tax_class ); + } + + /** + * Gets an array of matching shipping tax rates for a given class. + * + * @param string $tax_class Tax class to get rates for. + * @param object $customer Override the customer object to get their location. + * @return mixed + */ + public static function get_shipping_tax_rates( $tax_class = null, $customer = null ) { + // See if we have an explicitly set shipping tax class. + $shipping_tax_class = get_option( 'woocommerce_shipping_tax_class' ); + + if ( 'inherit' !== $shipping_tax_class ) { + $tax_class = $shipping_tax_class; + } + + $location = self::get_tax_location( $tax_class, $customer ); + $matched_tax_rates = array(); + + if ( 4 === count( $location ) ) { + list( $country, $state, $postcode, $city ) = $location; + + if ( ! is_null( $tax_class ) ) { + // This will be per item shipping. + $matched_tax_rates = self::find_shipping_rates( + array( + 'country' => $country, + 'state' => $state, + 'postcode' => $postcode, + 'city' => $city, + 'tax_class' => $tax_class, + ) + ); + + } elseif ( WC()->cart->get_cart() ) { + + // This will be per order shipping - loop through the order and find the highest tax class rate. + $cart_tax_classes = WC()->cart->get_cart_item_tax_classes_for_shipping(); + + // No tax classes = no taxable items. + if ( empty( $cart_tax_classes ) ) { + return array(); + } + + // If multiple classes are found, use the first one found unless a standard rate item is found. This will be the first listed in the 'additional tax class' section. + if ( count( $cart_tax_classes ) > 1 && ! in_array( '', $cart_tax_classes, true ) ) { + $tax_classes = self::get_tax_class_slugs(); + + foreach ( $tax_classes as $tax_class ) { + if ( in_array( $tax_class, $cart_tax_classes, true ) ) { + $matched_tax_rates = self::find_shipping_rates( + array( + 'country' => $country, + 'state' => $state, + 'postcode' => $postcode, + 'city' => $city, + 'tax_class' => $tax_class, + ) + ); + break; + } + } + } elseif ( 1 === count( $cart_tax_classes ) ) { + // If a single tax class is found, use it. + $matched_tax_rates = self::find_shipping_rates( + array( + 'country' => $country, + 'state' => $state, + 'postcode' => $postcode, + 'city' => $city, + 'tax_class' => $cart_tax_classes[0], + ) + ); + } + } + + // Get standard rate if no taxes were found. + if ( ! count( $matched_tax_rates ) ) { + $matched_tax_rates = self::find_shipping_rates( + array( + 'country' => $country, + 'state' => $state, + 'postcode' => $postcode, + 'city' => $city, + ) + ); + } + } + + return $matched_tax_rates; + } + + /** + * Return true/false depending on if a rate is a compound rate. + * + * @param mixed $key_or_rate Tax rate ID, or the db row itself in object format. + * @return bool + */ + public static function is_compound( $key_or_rate ) { + global $wpdb; + + if ( is_object( $key_or_rate ) ) { + $key = $key_or_rate->tax_rate_id; + $compound = $key_or_rate->tax_rate_compound; + } else { + $key = $key_or_rate; + $compound = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT tax_rate_compound FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) ); + } + + return (bool) apply_filters( 'woocommerce_rate_compound', $compound, $key ); + } + + /** + * Return a given rates label. + * + * @param mixed $key_or_rate Tax rate ID, or the db row itself in object format. + * @return string + */ + public static function get_rate_label( $key_or_rate ) { + global $wpdb; + + if ( is_object( $key_or_rate ) ) { + $key = $key_or_rate->tax_rate_id; + $rate_name = $key_or_rate->tax_rate_name; + } else { + $key = $key_or_rate; + $rate_name = $wpdb->get_var( $wpdb->prepare( "SELECT tax_rate_name FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) ); + } + + if ( ! $rate_name ) { + $rate_name = WC()->countries->tax_or_vat(); + } + + return apply_filters( 'woocommerce_rate_label', $rate_name, $key ); + } + + /** + * Return a given rates percent. + * + * @param mixed $key_or_rate Tax rate ID, or the db row itself in object format. + * @return string + */ + public static function get_rate_percent( $key_or_rate ) { + $rate_percent_value = self::get_rate_percent_value( $key_or_rate ); + $tax_rate_id = is_object( $key_or_rate ) ? $key_or_rate->tax_rate_id : $key_or_rate; + return apply_filters( 'woocommerce_rate_percent', $rate_percent_value . '%', $tax_rate_id ); + } + + /** + * Return a given rates percent. + * + * @param mixed $key_or_rate Tax rate ID, or the db row itself in object format. + * @return float + */ + public static function get_rate_percent_value( $key_or_rate ) { + global $wpdb; + + if ( is_object( $key_or_rate ) ) { + $tax_rate = $key_or_rate->tax_rate; + } else { + $key = $key_or_rate; + $tax_rate = $wpdb->get_var( $wpdb->prepare( "SELECT tax_rate FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) ); + } + + return floatval( $tax_rate ); + } + + + /** + * Get a rates code. Code is made up of COUNTRY-STATE-NAME-Priority. E.g GB-VAT-1, US-AL-TAX-1. + * + * @param mixed $key_or_rate Tax rate ID, or the db row itself in object format. + * @return string + */ + public static function get_rate_code( $key_or_rate ) { + global $wpdb; + + if ( is_object( $key_or_rate ) ) { + $key = $key_or_rate->tax_rate_id; + $rate = $key_or_rate; + } else { + $key = $key_or_rate; + $rate = $wpdb->get_row( $wpdb->prepare( "SELECT tax_rate_country, tax_rate_state, tax_rate_name, tax_rate_priority FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) ); + } + + $code_string = ''; + + if ( null !== $rate ) { + $code = array(); + $code[] = $rate->tax_rate_country; + $code[] = $rate->tax_rate_state; + $code[] = $rate->tax_rate_name ? $rate->tax_rate_name : 'TAX'; + $code[] = absint( $rate->tax_rate_priority ); + $code_string = strtoupper( implode( '-', array_filter( $code ) ) ); + } + + return apply_filters( 'woocommerce_rate_code', $code_string, $key ); + } + + /** + * Sums a set of taxes to form a single total. Values are pre-rounded to precision from 3.6.0. + * + * @param array $taxes Array of taxes. + * @return float + */ + public static function get_tax_total( $taxes ) { + return array_sum( $taxes ); + } + + /** + * Gets all tax rate classes from the database. + * + * @since 3.7.0 + * @return array Array of tax class objects consisting of tax_rate_class_id, name, and slug. + */ + protected static function get_tax_rate_classes() { + global $wpdb; + + $cache_key = 'tax-rate-classes'; + $tax_rate_classes = wp_cache_get( $cache_key, 'taxes' ); + + if ( ! is_array( $tax_rate_classes ) ) { + $tax_rate_classes = $wpdb->get_results( + " + SELECT * FROM {$wpdb->wc_tax_rate_classes} ORDER BY name; + " + ); + wp_cache_set( $cache_key, $tax_rate_classes, 'taxes' ); + } + + return $tax_rate_classes; + } + + /** + * Get store tax class names. + * + * @return array Array of class names ("Reduced rate", "Zero rate", etc). + */ + public static function get_tax_classes() { + return wp_list_pluck( self::get_tax_rate_classes(), 'name' ); + } + + /** + * Get store tax classes as slugs. + * + * @since 3.0.0 + * @return array Array of class slugs ("reduced-rate", "zero-rate", etc). + */ + public static function get_tax_class_slugs() { + return wp_list_pluck( self::get_tax_rate_classes(), 'slug' ); + } + + /** + * Create a new tax class. + * + * @since 3.7.0 + * @param string $name Name of the tax class to add. + * @param string $slug (optional) Slug of the tax class to add. Defaults to sanitized name. + * @return WP_Error|array Returns name and slug (array) if the tax class is created, or WP_Error if something went wrong. + */ + public static function create_tax_class( $name, $slug = '' ) { + global $wpdb; + + if ( empty( $name ) ) { + return new WP_Error( 'tax_class_invalid_name', __( 'Tax class requires a valid name', 'woocommerce' ) ); + } + + $existing = self::get_tax_classes(); + $existing_slugs = self::get_tax_class_slugs(); + + if ( in_array( $name, $existing, true ) ) { + return new WP_Error( 'tax_class_exists', __( 'Tax class already exists', 'woocommerce' ) ); + } + + if ( ! $slug ) { + $slug = sanitize_title( $name ); + } + + if ( in_array( $slug, $existing_slugs, true ) ) { + return new WP_Error( 'tax_class_slug_exists', __( 'Tax class slug already exists', 'woocommerce' ) ); + } + + $insert = $wpdb->insert( + $wpdb->wc_tax_rate_classes, + array( + 'name' => $name, + 'slug' => $slug, + ) + ); + + if ( is_wp_error( $insert ) ) { + return new WP_Error( 'tax_class_insert_error', $insert->get_error_message() ); + } + + wp_cache_delete( 'tax-rate-classes', 'taxes' ); + + return array( + 'name' => $name, + 'slug' => $slug, + ); + } + + /** + * Get an existing tax class. + * + * @since 3.7.0 + * @param string $field Field to get by. Valid values are id, name, or slug. + * @param string|int $item Item to get. + * @return array|bool Returns the tax class as an array. False if not found. + */ + public static function get_tax_class_by( $field, $item ) { + if ( ! in_array( $field, array( 'id', 'name', 'slug' ), true ) ) { + return new WP_Error( 'invalid_field', __( 'Invalid field', 'woocommerce' ) ); + } + + if ( 'id' === $field ) { + $field = 'tax_rate_class_id'; + } + + $matches = wp_list_filter( + self::get_tax_rate_classes(), + array( + $field => $item, + ) + ); + + if ( ! $matches ) { + return false; + } + + $tax_class = current( $matches ); + + return array( + 'name' => $tax_class->name, + 'slug' => $tax_class->slug, + ); + } + + /** + * Delete an existing tax class. + * + * @since 3.7.0 + * @param string $field Field to delete by. Valid values are id, name, or slug. + * @param string|int $item Item to delete. + * @return WP_Error|bool Returns true if deleted successfully, false if nothing was deleted, or WP_Error if there is an invalid request. + */ + public static function delete_tax_class_by( $field, $item ) { + global $wpdb; + + if ( ! in_array( $field, array( 'id', 'name', 'slug' ), true ) ) { + return new WP_Error( 'invalid_field', __( 'Invalid field', 'woocommerce' ) ); + } + + $tax_class = self::get_tax_class_by( $field, $item ); + + if ( ! $tax_class ) { + return new WP_Error( 'invalid_tax_class', __( 'Invalid tax class', 'woocommerce' ) ); + } + + if ( 'id' === $field ) { + $field = 'tax_rate_class_id'; + } + + $delete = $wpdb->delete( + $wpdb->wc_tax_rate_classes, + array( + $field => $item, + ) + ); + + if ( $delete ) { + // Delete associated tax rates. + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_class = %s;", $tax_class['slug'] ) ); + $wpdb->query( "DELETE locations FROM {$wpdb->prefix}woocommerce_tax_rate_locations locations LEFT JOIN {$wpdb->prefix}woocommerce_tax_rates rates ON rates.tax_rate_id = locations.tax_rate_id WHERE rates.tax_rate_id IS NULL;" ); + } + + wp_cache_delete( 'tax-rate-classes', 'taxes' ); + WC_Cache_Helper::invalidate_cache_group( 'taxes' ); + + return (bool) $delete; + } + + /** + * Format the city. + * + * @param string $city Value to format. + * @return string + */ + private static function format_tax_rate_city( $city ) { + return strtoupper( trim( $city ) ); + } + + /** + * Format the state. + * + * @param string $state Value to format. + * @return string + */ + private static function format_tax_rate_state( $state ) { + $state = strtoupper( $state ); + return ( '*' === $state ) ? '' : $state; + } + + /** + * Format the country. + * + * @param string $country Value to format. + * @return string + */ + private static function format_tax_rate_country( $country ) { + $country = strtoupper( $country ); + return ( '*' === $country ) ? '' : $country; + } + + /** + * Format the tax rate name. + * + * @param string $name Value to format. + * @return string + */ + private static function format_tax_rate_name( $name ) { + return $name ? $name : __( 'Tax', 'woocommerce' ); + } + + /** + * Format the rate. + * + * @param float $rate Value to format. + * @return string + */ + private static function format_tax_rate( $rate ) { + return number_format( (float) $rate, 4, '.', '' ); + } + + /** + * Format the priority. + * + * @param string $priority Value to format. + * @return int + */ + private static function format_tax_rate_priority( $priority ) { + return absint( $priority ); + } + + /** + * Format the class. + * + * @param string $class Value to format. + * @return string + */ + public static function format_tax_rate_class( $class ) { + $class = sanitize_title( $class ); + $classes = self::get_tax_class_slugs(); + if ( ! in_array( $class, $classes, true ) ) { + $class = ''; + } + return ( 'standard' === $class ) ? '' : $class; + } + + /** + * Prepare and format tax rate for DB insertion. + * + * @param array $tax_rate Tax rate to format. + * @return array + */ + private static function prepare_tax_rate( $tax_rate ) { + foreach ( $tax_rate as $key => $value ) { + if ( method_exists( __CLASS__, 'format_' . $key ) ) { + if ( 'tax_rate_state' === $key ) { + $tax_rate[ $key ] = call_user_func( array( __CLASS__, 'format_' . $key ), sanitize_key( $value ) ); + } else { + $tax_rate[ $key ] = call_user_func( array( __CLASS__, 'format_' . $key ), $value ); + } + } + } + return $tax_rate; + } + + /** + * Insert a new tax rate. + * + * Internal use only. + * + * @since 2.3.0 + * + * @param array $tax_rate Tax rate to insert. + * @return int tax rate id + */ + public static function _insert_tax_rate( $tax_rate ) { + global $wpdb; + + $wpdb->insert( $wpdb->prefix . 'woocommerce_tax_rates', self::prepare_tax_rate( $tax_rate ) ); + + $tax_rate_id = $wpdb->insert_id; + + WC_Cache_Helper::invalidate_cache_group( 'taxes' ); + + do_action( 'woocommerce_tax_rate_added', $tax_rate_id, $tax_rate ); + + return $tax_rate_id; + } + + /** + * Get tax rate. + * + * Internal use only. + * + * @since 2.5.0 + * + * @param int $tax_rate_id Tax rate ID. + * @param string $output_type Type of output. + * @return array|object + */ + public static function _get_tax_rate( $tax_rate_id, $output_type = ARRAY_A ) { + global $wpdb; + + return $wpdb->get_row( + $wpdb->prepare( + " + SELECT * + FROM {$wpdb->prefix}woocommerce_tax_rates + WHERE tax_rate_id = %d + ", + $tax_rate_id + ), + $output_type + ); + } + + /** + * Update a tax rate. + * + * Internal use only. + * + * @since 2.3.0 + * + * @param int $tax_rate_id Tax rate to update. + * @param array $tax_rate Tax rate values. + */ + public static function _update_tax_rate( $tax_rate_id, $tax_rate ) { + global $wpdb; + + $tax_rate_id = absint( $tax_rate_id ); + + $wpdb->update( + $wpdb->prefix . 'woocommerce_tax_rates', + self::prepare_tax_rate( $tax_rate ), + array( + 'tax_rate_id' => $tax_rate_id, + ) + ); + + WC_Cache_Helper::invalidate_cache_group( 'taxes' ); + + do_action( 'woocommerce_tax_rate_updated', $tax_rate_id, $tax_rate ); + } + + /** + * Delete a tax rate from the database. + * + * Internal use only. + * + * @since 2.3.0 + * @param int $tax_rate_id Tax rate to delete. + */ + public static function _delete_tax_rate( $tax_rate_id ) { + global $wpdb; + + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE tax_rate_id = %d;", $tax_rate_id ) ); + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %d;", $tax_rate_id ) ); + + WC_Cache_Helper::invalidate_cache_group( 'taxes' ); + + do_action( 'woocommerce_tax_rate_deleted', $tax_rate_id ); + } + + /** + * Update postcodes for a tax rate in the DB. + * + * Internal use only. + * + * @since 2.3.0 + * + * @param int $tax_rate_id Tax rate to update. + * @param string $postcodes String of postcodes separated by ; characters. + */ + public static function _update_tax_rate_postcodes( $tax_rate_id, $postcodes ) { + if ( ! is_array( $postcodes ) ) { + $postcodes = explode( ';', $postcodes ); + } + // No normalization - postcodes are matched against both normal and formatted versions to support wildcards. + foreach ( $postcodes as $key => $postcode ) { + $postcodes[ $key ] = strtoupper( trim( str_replace( chr( 226 ) . chr( 128 ) . chr( 166 ), '...', $postcode ) ) ); + } + self::update_tax_rate_locations( $tax_rate_id, array_diff( array_filter( $postcodes ), array( '*' ) ), 'postcode' ); + } + + /** + * Update cities for a tax rate in the DB. + * + * Internal use only. + * + * @since 2.3.0 + * + * @param int $tax_rate_id Tax rate to update. + * @param string $cities Cities to set. + */ + public static function _update_tax_rate_cities( $tax_rate_id, $cities ) { + if ( ! is_array( $cities ) ) { + $cities = explode( ';', $cities ); + } + $cities = array_filter( array_diff( array_map( array( __CLASS__, 'format_tax_rate_city' ), $cities ), array( '*' ) ) ); + + self::update_tax_rate_locations( $tax_rate_id, $cities, 'city' ); + } + + /** + * Updates locations (postcode and city). + * + * Internal use only. + * + * @since 2.3.0 + * + * @param int $tax_rate_id Tax rate ID to update. + * @param array $values Values to set. + * @param string $type Location type. + */ + private static function update_tax_rate_locations( $tax_rate_id, $values, $type ) { + global $wpdb; + + $tax_rate_id = absint( $tax_rate_id ); + + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE tax_rate_id = %d AND location_type = %s;", + $tax_rate_id, + $type + ) + ); + + if ( count( $values ) > 0 ) { + $sql = "( '" . implode( "', $tax_rate_id, '" . esc_sql( $type ) . "' ),( '", array_map( 'esc_sql', $values ) ) . "', $tax_rate_id, '" . esc_sql( $type ) . "' )"; + + $wpdb->query( "INSERT INTO {$wpdb->prefix}woocommerce_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES $sql;" ); // @codingStandardsIgnoreLine. + } + + WC_Cache_Helper::invalidate_cache_group( 'taxes' ); + } + + /** + * Used by admin settings page. + * + * @param string $tax_class Tax class slug. + * + * @return array|null|object + */ + public static function get_rates_for_tax_class( $tax_class ) { + global $wpdb; + + // Get all the rates and locations. Snagging all at once should significantly cut down on the number of queries. + $rates = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rates` WHERE `tax_rate_class` = %s;", sanitize_title( $tax_class ) ) ); + $locations = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rate_locations`" ); + + if ( ! empty( $rates ) ) { + // Set the rates keys equal to their ids. + $rates = array_combine( wp_list_pluck( $rates, 'tax_rate_id' ), $rates ); + } + + // Drop the locations into the rates array. + foreach ( $locations as $location ) { + // Don't set them for unexistent rates. + if ( ! isset( $rates[ $location->tax_rate_id ] ) ) { + continue; + } + // If the rate exists, initialize the array before appending to it. + if ( ! isset( $rates[ $location->tax_rate_id ]->{$location->location_type} ) ) { + $rates[ $location->tax_rate_id ]->{$location->location_type} = array(); + } + $rates[ $location->tax_rate_id ]->{$location->location_type}[] = $location->location_code; + } + + foreach ( $rates as $rate_id => $rate ) { + $rates[ $rate_id ]->postcode_count = isset( $rates[ $rate_id ]->postcode ) ? count( $rates[ $rate_id ]->postcode ) : 0; + $rates[ $rate_id ]->city_count = isset( $rates[ $rate_id ]->city ) ? count( $rates[ $rate_id ]->city ) : 0; + } + + $rates = self::sort_rates( $rates ); + + return $rates; + } +} +WC_Tax::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-template-loader.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-template-loader.php new file mode 100644 index 0000000..5a32337 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-template-loader.php @@ -0,0 +1,586 @@ +plugin_path() . '/templates/' . $cs_template; + } else { + $template = WC()->plugin_path() . '/templates/' . $default_file; + } + } + } + + return $template; + } + + /** + * Get the default filename for a template. + * + * @since 3.0.0 + * @return string + */ + private static function get_template_loader_default_file() { + if ( is_singular( 'product' ) ) { + $default_file = 'single-product.php'; + } elseif ( is_product_taxonomy() ) { + $object = get_queried_object(); + + if ( is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) { + $default_file = 'taxonomy-' . $object->taxonomy . '.php'; + } else { + $default_file = 'archive-product.php'; + } + } elseif ( is_post_type_archive( 'product' ) || is_page( wc_get_page_id( 'shop' ) ) ) { + $default_file = self::$theme_support ? 'archive-product.php' : ''; + } else { + $default_file = ''; + } + return $default_file; + } + + /** + * Get an array of filenames to search for a given template. + * + * @since 3.0.0 + * @param string $default_file The default file name. + * @return string[] + */ + private static function get_template_loader_files( $default_file ) { + $templates = apply_filters( 'woocommerce_template_loader_files', array(), $default_file ); + $templates[] = 'woocommerce.php'; + + if ( is_page_template() ) { + $page_template = get_page_template_slug(); + + if ( $page_template ) { + $validated_file = validate_file( $page_template ); + if ( 0 === $validated_file ) { + $templates[] = $page_template; + } else { + error_log( "WooCommerce: Unable to validate template path: \"$page_template\". Error Code: $validated_file." ); + } + } + } + + if ( is_singular( 'product' ) ) { + $object = get_queried_object(); + $name_decoded = urldecode( $object->post_name ); + if ( $name_decoded !== $object->post_name ) { + $templates[] = "single-product-{$name_decoded}.php"; + } + $templates[] = "single-product-{$object->post_name}.php"; + } + + if ( is_product_taxonomy() ) { + $object = get_queried_object(); + + $templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php'; + $templates[] = WC()->template_path() . 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php'; + $templates[] = 'taxonomy-' . $object->taxonomy . '.php'; + $templates[] = WC()->template_path() . 'taxonomy-' . $object->taxonomy . '.php'; + + if ( is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) { + $cs_taxonomy = str_replace( '_', '-', $object->taxonomy ); + $cs_default = str_replace( '_', '-', $default_file ); + $templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php'; + $templates[] = WC()->template_path() . 'taxonomy-' . $cs_taxonomy . '-' . $object->slug . '.php'; + $templates[] = 'taxonomy-' . $object->taxonomy . '.php'; + $templates[] = WC()->template_path() . 'taxonomy-' . $cs_taxonomy . '.php'; + $templates[] = $cs_default; + } + } + + $templates[] = $default_file; + if ( isset( $cs_default ) ) { + $templates[] = WC()->template_path() . $cs_default; + } + $templates[] = WC()->template_path() . $default_file; + + return array_unique( $templates ); + } + + /** + * Load comments template. + * + * @param string $template template to load. + * @return string + */ + public static function comments_template_loader( $template ) { + if ( get_post_type() !== 'product' ) { + return $template; + } + + $check_dirs = array( + trailingslashit( get_stylesheet_directory() ) . WC()->template_path(), + trailingslashit( get_template_directory() ) . WC()->template_path(), + trailingslashit( get_stylesheet_directory() ), + trailingslashit( get_template_directory() ), + trailingslashit( WC()->plugin_path() ) . 'templates/', + ); + + if ( WC_TEMPLATE_DEBUG_MODE ) { + $check_dirs = array( array_pop( $check_dirs ) ); + } + + foreach ( $check_dirs as $dir ) { + if ( file_exists( trailingslashit( $dir ) . 'single-product-reviews.php' ) ) { + return trailingslashit( $dir ) . 'single-product-reviews.php'; + } + } + } + + /** + * Unsupported theme compatibility methods. + */ + + /** + * Hook in methods to enhance the unsupported theme experience on pages. + * + * @since 3.3.0 + */ + public static function unsupported_theme_init() { + if ( 0 < self::$shop_page_id ) { + if ( is_product_taxonomy() ) { + self::unsupported_theme_tax_archive_init(); + } elseif ( is_product() ) { + self::unsupported_theme_product_page_init(); + } else { + self::unsupported_theme_shop_page_init(); + } + } + } + + /** + * Hook in methods to enhance the unsupported theme experience on the Shop page. + * + * @since 3.3.0 + */ + private static function unsupported_theme_shop_page_init() { + add_filter( 'the_content', array( __CLASS__, 'unsupported_theme_shop_content_filter' ), 10 ); + add_filter( 'the_title', array( __CLASS__, 'unsupported_theme_title_filter' ), 10, 2 ); + add_filter( 'comments_number', array( __CLASS__, 'unsupported_theme_comments_number_filter' ) ); + } + + /** + * Hook in methods to enhance the unsupported theme experience on Product pages. + * + * @since 3.3.0 + */ + private static function unsupported_theme_product_page_init() { + add_filter( 'the_content', array( __CLASS__, 'unsupported_theme_product_content_filter' ), 10 ); + add_filter( 'post_thumbnail_html', array( __CLASS__, 'unsupported_theme_single_featured_image_filter' ) ); + add_filter( 'woocommerce_product_tabs', array( __CLASS__, 'unsupported_theme_remove_review_tab' ) ); + remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 ); + remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 ); + add_theme_support( 'wc-product-gallery-zoom' ); + add_theme_support( 'wc-product-gallery-lightbox' ); + add_theme_support( 'wc-product-gallery-slider' ); + } + + /** + * Enhance the unsupported theme experience on Product Category and Attribute pages by rendering + * those pages using the single template and shortcode-based content. To do this we make a dummy + * post and set a shortcode as the post content. This approach is adapted from bbPress. + * + * @since 3.3.0 + */ + private static function unsupported_theme_tax_archive_init() { + global $wp_query, $post; + + $queried_object = get_queried_object(); + $args = self::get_current_shop_view_args(); + $shortcode_args = array( + 'page' => $args->page, + 'columns' => $args->columns, + 'rows' => $args->rows, + 'orderby' => '', + 'order' => '', + 'paginate' => true, + 'cache' => false, + ); + + if ( is_product_category() ) { + $shortcode_args['category'] = sanitize_title( $queried_object->slug ); + } elseif ( taxonomy_is_product_attribute( $queried_object->taxonomy ) ) { + $shortcode_args['attribute'] = sanitize_title( $queried_object->taxonomy ); + $shortcode_args['terms'] = sanitize_title( $queried_object->slug ); + } elseif ( is_product_tag() ) { + $shortcode_args['tag'] = sanitize_title( $queried_object->slug ); + } else { + // Default theme archive for all other taxonomies. + return; + } + + // Description handling. + if ( ! empty( $queried_object->description ) && ( empty( $_GET['product-page'] ) || 1 === absint( $_GET['product-page'] ) ) ) { // WPCS: input var ok, CSRF ok. + $prefix = '
    ' . wc_format_content( $queried_object->description ) . '
    '; // WPCS: XSS ok. + } else { + $prefix = ''; + } + + add_filter( 'woocommerce_shortcode_products_query', array( __CLASS__, 'unsupported_archive_layered_nav_compatibility' ) ); + $shortcode = new WC_Shortcode_Products( $shortcode_args ); + remove_filter( 'woocommerce_shortcode_products_query', array( __CLASS__, 'unsupported_archive_layered_nav_compatibility' ) ); + $shop_page = get_post( self::$shop_page_id ); + + $dummy_post_properties = array( + 'ID' => 0, + 'post_status' => 'publish', + 'post_author' => $shop_page->post_author, + 'post_parent' => 0, + 'post_type' => 'page', + 'post_date' => $shop_page->post_date, + 'post_date_gmt' => $shop_page->post_date_gmt, + 'post_modified' => $shop_page->post_modified, + 'post_modified_gmt' => $shop_page->post_modified_gmt, + 'post_content' => $prefix . $shortcode->get_content(), + 'post_title' => wc_clean( $queried_object->name ), + 'post_excerpt' => '', + 'post_content_filtered' => '', + 'post_mime_type' => '', + 'post_password' => '', + 'post_name' => $queried_object->slug, + 'guid' => '', + 'menu_order' => 0, + 'pinged' => '', + 'to_ping' => '', + 'ping_status' => '', + 'comment_status' => 'closed', + 'comment_count' => 0, + 'filter' => 'raw', + ); + + // Set the $post global. + $post = new WP_Post( (object) $dummy_post_properties ); // @codingStandardsIgnoreLine. + + // Copy the new post global into the main $wp_query. + $wp_query->post = $post; + $wp_query->posts = array( $post ); + + // Prevent comments form from appearing. + $wp_query->post_count = 1; + $wp_query->is_404 = false; + $wp_query->is_page = true; + $wp_query->is_single = true; + $wp_query->is_archive = false; + $wp_query->is_tax = true; + $wp_query->max_num_pages = 0; + + // Prepare everything for rendering. + setup_postdata( $post ); + remove_all_filters( 'the_content' ); + remove_all_filters( 'the_excerpt' ); + add_filter( 'template_include', array( __CLASS__, 'force_single_template_filter' ) ); + } + + /** + * Add layered nav args to WP_Query args generated by the 'products' shortcode. + * + * @since 3.3.4 + * @param array $query WP_Query args. + * @return array + */ + public static function unsupported_archive_layered_nav_compatibility( $query ) { + foreach ( WC()->query->get_layered_nav_chosen_attributes() as $taxonomy => $data ) { + $query['tax_query'][] = array( + 'taxonomy' => $taxonomy, + 'field' => 'slug', + 'terms' => $data['terms'], + 'operator' => 'and' === $data['query_type'] ? 'AND' : 'IN', + 'include_children' => false, + ); + } + return $query; + } + + /** + * Force the loading of one of the single templates instead of whatever template was about to be loaded. + * + * @since 3.3.0 + * @param string $template Path to template. + * @return string + */ + public static function force_single_template_filter( $template ) { + $possible_templates = array( + 'page', + 'single', + 'singular', + 'index', + ); + + foreach ( $possible_templates as $possible_template ) { + $path = get_query_template( $possible_template ); + if ( $path ) { + return $path; + } + } + + return $template; + } + + /** + * Get information about the current shop page view. + * + * @since 3.3.0 + * @return array + */ + private static function get_current_shop_view_args() { + return (object) array( + 'page' => absint( max( 1, absint( get_query_var( 'paged' ) ) ) ), + 'columns' => wc_get_default_products_per_row(), + 'rows' => wc_get_default_product_rows_per_page(), + ); + } + + /** + * Filter the title and insert WooCommerce content on the shop page. + * + * For non-WC themes, this will setup the main shop page to be shortcode based to improve default appearance. + * + * @since 3.3.0 + * @param string $title Existing title. + * @param int $id ID of the post being filtered. + * @return string + */ + public static function unsupported_theme_title_filter( $title, $id ) { + if ( self::$theme_support || ! $id !== self::$shop_page_id ) { + return $title; + } + + if ( is_page( self::$shop_page_id ) || ( is_home() && 'page' === get_option( 'show_on_front' ) && absint( get_option( 'page_on_front' ) ) === self::$shop_page_id ) ) { + $args = self::get_current_shop_view_args(); + $title_suffix = array(); + + if ( $args->page > 1 ) { + /* translators: %d: Page number. */ + $title_suffix[] = sprintf( esc_html__( 'Page %d', 'woocommerce' ), $args->page ); + } + + if ( $title_suffix ) { + $title = $title . ' – ' . implode( ', ', $title_suffix ); + } + } + return $title; + } + + /** + * Filter the content and insert WooCommerce content on the shop page. + * + * For non-WC themes, this will setup the main shop page to be shortcode based to improve default appearance. + * + * @since 3.3.0 + * @param string $content Existing post content. + * @return string + */ + public static function unsupported_theme_shop_content_filter( $content ) { + global $wp_query; + + if ( self::$theme_support || ! is_main_query() || ! in_the_loop() ) { + return $content; + } + + self::$in_content_filter = true; + + // Remove the filter we're in to avoid nested calls. + remove_filter( 'the_content', array( __CLASS__, 'unsupported_theme_shop_content_filter' ) ); + + // Unsupported theme shop page. + if ( is_page( self::$shop_page_id ) ) { + $args = self::get_current_shop_view_args(); + $shortcode = new WC_Shortcode_Products( + array_merge( + WC()->query->get_catalog_ordering_args(), + array( + 'page' => $args->page, + 'columns' => $args->columns, + 'rows' => $args->rows, + 'orderby' => '', + 'order' => '', + 'paginate' => true, + 'cache' => false, + ) + ), + 'products' + ); + + // Allow queries to run e.g. layered nav. + add_action( 'pre_get_posts', array( WC()->query, 'product_query' ) ); + + $content = $content . $shortcode->get_content(); + + // Remove actions and self to avoid nested calls. + remove_action( 'pre_get_posts', array( WC()->query, 'product_query' ) ); + WC()->query->remove_ordering_args(); + } + + self::$in_content_filter = false; + + return $content; + } + + /** + * Filter the content and insert WooCommerce content on the shop page. + * + * For non-WC themes, this will setup the main shop page to be shortcode based to improve default appearance. + * + * @since 3.3.0 + * @param string $content Existing post content. + * @return string + */ + public static function unsupported_theme_product_content_filter( $content ) { + global $wp_query; + + if ( self::$theme_support || ! is_main_query() || ! in_the_loop() ) { + return $content; + } + + self::$in_content_filter = true; + + // Remove the filter we're in to avoid nested calls. + remove_filter( 'the_content', array( __CLASS__, 'unsupported_theme_product_content_filter' ) ); + + if ( is_product() ) { + $content = do_shortcode( '[product_page id="' . get_the_ID() . '" show_title=0 status="any"]' ); + } + + self::$in_content_filter = false; + + return $content; + } + + /** + * Suppress the comments number on the Shop page for unsupported themes since there is no commenting on the Shop page. + * + * @since 3.4.5 + * @param string $comments_number The comments number text. + * @return string + */ + public static function unsupported_theme_comments_number_filter( $comments_number ) { + if ( is_page( self::$shop_page_id ) ) { + return ''; + } + + return $comments_number; + } + + /** + * Are we filtering content for unsupported themes? + * + * @since 3.3.2 + * @return bool + */ + public static function in_content_filter() { + return (bool) self::$in_content_filter; + } + + /** + * Prevent the main featured image on product pages because there will be another featured image + * in the gallery. + * + * @since 3.3.0 + * @param string $html Img element HTML. + * @return string + */ + public static function unsupported_theme_single_featured_image_filter( $html ) { + if ( self::in_content_filter() || ! is_product() || ! is_main_query() ) { + return $html; + } + + return ''; + } + + /** + * Remove the Review tab and just use the regular comment form. + * + * @param array $tabs Tab info. + * @return array + */ + public static function unsupported_theme_remove_review_tab( $tabs ) { + unset( $tabs['reviews'] ); + return $tabs; + } +} + +add_action( 'init', array( 'WC_Template_Loader', 'init' ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-tracker.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-tracker.php new file mode 100644 index 0000000..27a3696 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-tracker.php @@ -0,0 +1,763 @@ + apply_filters( 'woocommerce_tracker_last_send_interval', strtotime( '-1 week' ) ) ) { + return; + } + } else { + // Make sure there is at least a 1 hour delay between override sends, we don't want duplicate calls due to double clicking links. + $last_send = self::get_last_send_time(); + if ( $last_send && $last_send > strtotime( '-1 hours' ) ) { + return; + } + } + + // Update time first before sending to ensure it is set. + update_option( 'woocommerce_tracker_last_send', time() ); + + $params = self::get_tracking_data(); + wp_safe_remote_post( + self::$api_url, + array( + 'method' => 'POST', + 'timeout' => 45, + 'redirection' => 5, + 'httpversion' => '1.0', + 'blocking' => false, + 'headers' => array( 'user-agent' => 'WooCommerceTracker/' . md5( esc_url_raw( home_url( '/' ) ) ) . ';' ), + 'body' => wp_json_encode( $params ), + 'cookies' => array(), + ) + ); + } + + /** + * Get the last time tracking data was sent. + * + * @return int|bool + */ + private static function get_last_send_time() { + return apply_filters( 'woocommerce_tracker_last_send_time', get_option( 'woocommerce_tracker_last_send', false ) ); + } + + /** + * Test whether this site is a staging site according to the Jetpack criteria. + * + * With Jetpack 8.1+, Jetpack::is_staging_site has been deprecated. + * \Automattic\Jetpack\Status::is_staging_site is the replacement. + * However, there are version of JP where \Automattic\Jetpack\Status exists, but does *not* contain is_staging_site method, + * so with those, code still needs to use the previous check as a fallback. + * + * @return bool + */ + private static function is_jetpack_staging_site() { + if ( class_exists( '\Automattic\Jetpack\Status' ) ) { + // Preferred way of checking with Jetpack 8.1+. + $jp_status = new \Automattic\Jetpack\Status(); + if ( is_callable( array( $jp_status, 'is_staging_site' ) ) ) { + return $jp_status->is_staging_site(); + } + } + + return ( class_exists( 'Jetpack' ) && is_callable( 'Jetpack::is_staging_site' ) && Jetpack::is_staging_site() ); + } + + /** + * Get all the tracking data. + * + * @return array + */ + private static function get_tracking_data() { + $data = array(); + + // General site info. + $data['url'] = home_url(); + $data['email'] = apply_filters( 'woocommerce_tracker_admin_email', get_option( 'admin_email' ) ); + $data['theme'] = self::get_theme_info(); + + // WordPress Info. + $data['wp'] = self::get_wordpress_info(); + + // Server Info. + $data['server'] = self::get_server_info(); + + // Plugin info. + $all_plugins = self::get_all_plugins(); + $data['active_plugins'] = $all_plugins['active_plugins']; + $data['inactive_plugins'] = $all_plugins['inactive_plugins']; + + // Jetpack & WooCommerce Connect. + + $data['jetpack_version'] = Constants::is_defined( 'JETPACK__VERSION' ) ? Constants::get_constant( 'JETPACK__VERSION' ) : 'none'; + $data['jetpack_connected'] = ( class_exists( 'Jetpack' ) && is_callable( 'Jetpack::is_active' ) && Jetpack::is_active() ) ? 'yes' : 'no'; + $data['jetpack_is_staging'] = self::is_jetpack_staging_site() ? 'yes' : 'no'; + $data['connect_installed'] = class_exists( 'WC_Connect_Loader' ) ? 'yes' : 'no'; + $data['connect_active'] = ( class_exists( 'WC_Connect_Loader' ) && wp_next_scheduled( 'wc_connect_fetch_service_schemas' ) ) ? 'yes' : 'no'; + $data['helper_connected'] = self::get_helper_connected(); + + // Store count info. + $data['users'] = self::get_user_counts(); + $data['products'] = self::get_product_counts(); + $data['orders'] = self::get_orders(); + $data['reviews'] = self::get_review_counts(); + $data['categories'] = self::get_category_counts(); + + // Payment gateway info. + $data['gateways'] = self::get_active_payment_gateways(); + + // Shipping method info. + $data['shipping_methods'] = self::get_active_shipping_methods(); + + // Get all WooCommerce options info. + $data['settings'] = self::get_all_woocommerce_options_values(); + + // Template overrides. + $data['template_overrides'] = self::get_all_template_overrides(); + + // Template overrides. + $data['admin_user_agents'] = self::get_admin_user_agents(); + + // Cart & checkout tech (blocks or shortcodes). + $data['cart_checkout'] = self::get_cart_checkout_info(); + + return apply_filters( 'woocommerce_tracker_data', $data ); + } + + /** + * Get the current theme info, theme name and version. + * + * @return array + */ + public static function get_theme_info() { + $theme_data = wp_get_theme(); + $theme_child_theme = wc_bool_to_string( is_child_theme() ); + $theme_wc_support = wc_bool_to_string( current_theme_supports( 'woocommerce' ) ); + + return array( + 'name' => $theme_data->Name, // @phpcs:ignore + 'version' => $theme_data->Version, // @phpcs:ignore + 'child_theme' => $theme_child_theme, + 'wc_support' => $theme_wc_support, + ); + } + + /** + * Get WordPress related data. + * + * @return array + */ + private static function get_wordpress_info() { + $wp_data = array(); + + $memory = wc_let_to_num( WP_MEMORY_LIMIT ); + + if ( function_exists( 'memory_get_usage' ) ) { + $system_memory = wc_let_to_num( @ini_get( 'memory_limit' ) ); + $memory = max( $memory, $system_memory ); + } + + // WordPress 5.5+ environment type specification. + // 'production' is the default in WP, thus using it as a default here, too. + $environment_type = 'production'; + if ( function_exists( 'wp_get_environment_type' ) ) { + $environment_type = wp_get_environment_type(); + } + + $wp_data['memory_limit'] = size_format( $memory ); + $wp_data['debug_mode'] = ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'Yes' : 'No'; + $wp_data['locale'] = get_locale(); + $wp_data['version'] = get_bloginfo( 'version' ); + $wp_data['multisite'] = is_multisite() ? 'Yes' : 'No'; + $wp_data['env_type'] = $environment_type; + + return $wp_data; + } + + /** + * Get server related info. + * + * @return array + */ + private static function get_server_info() { + $server_data = array(); + + if ( ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) { + $server_data['software'] = $_SERVER['SERVER_SOFTWARE']; // @phpcs:ignore + } + + if ( function_exists( 'phpversion' ) ) { + $server_data['php_version'] = phpversion(); + } + + if ( function_exists( 'ini_get' ) ) { + $server_data['php_post_max_size'] = size_format( wc_let_to_num( ini_get( 'post_max_size' ) ) ); + $server_data['php_time_limt'] = ini_get( 'max_execution_time' ); + $server_data['php_max_input_vars'] = ini_get( 'max_input_vars' ); + $server_data['php_suhosin'] = extension_loaded( 'suhosin' ) ? 'Yes' : 'No'; + } + + $database_version = wc_get_server_database_version(); + $server_data['mysql_version'] = $database_version['number']; + + $server_data['php_max_upload_size'] = size_format( wp_max_upload_size() ); + $server_data['php_default_timezone'] = date_default_timezone_get(); + $server_data['php_soap'] = class_exists( 'SoapClient' ) ? 'Yes' : 'No'; + $server_data['php_fsockopen'] = function_exists( 'fsockopen' ) ? 'Yes' : 'No'; + $server_data['php_curl'] = function_exists( 'curl_init' ) ? 'Yes' : 'No'; + + return $server_data; + } + + /** + * Get all plugins grouped into activated or not. + * + * @return array + */ + private static function get_all_plugins() { + // Ensure get_plugins function is loaded. + if ( ! function_exists( 'get_plugins' ) ) { + include ABSPATH . '/wp-admin/includes/plugin.php'; + } + + $plugins = get_plugins(); + $active_plugins_keys = get_option( 'active_plugins', array() ); + $active_plugins = array(); + + foreach ( $plugins as $k => $v ) { + // Take care of formatting the data how we want it. + $formatted = array(); + $formatted['name'] = strip_tags( $v['Name'] ); + if ( isset( $v['Version'] ) ) { + $formatted['version'] = strip_tags( $v['Version'] ); + } + if ( isset( $v['Author'] ) ) { + $formatted['author'] = strip_tags( $v['Author'] ); + } + if ( isset( $v['Network'] ) ) { + $formatted['network'] = strip_tags( $v['Network'] ); + } + if ( isset( $v['PluginURI'] ) ) { + $formatted['plugin_uri'] = strip_tags( $v['PluginURI'] ); + } + if ( in_array( $k, $active_plugins_keys ) ) { + // Remove active plugins from list so we can show active and inactive separately. + unset( $plugins[ $k ] ); + $active_plugins[ $k ] = $formatted; + } else { + $plugins[ $k ] = $formatted; + } + } + + return array( + 'active_plugins' => $active_plugins, + 'inactive_plugins' => $plugins, + ); + } + + /** + * Check to see if the helper is connected to woocommerce.com + * + * @return string + */ + private static function get_helper_connected() { + if ( class_exists( 'WC_Helper_Options' ) && is_callable( 'WC_Helper_Options::get' ) ) { + $authenticated = WC_Helper_Options::get( 'auth' ); + } else { + $authenticated = ''; + } + return ( ! empty( $authenticated ) ) ? 'yes' : 'no'; + } + + + /** + * Get user totals based on user role. + * + * @return array + */ + private static function get_user_counts() { + $user_count = array(); + $user_count_data = count_users(); + $user_count['total'] = $user_count_data['total_users']; + + // Get user count based on user role. + foreach ( $user_count_data['avail_roles'] as $role => $count ) { + $user_count[ $role ] = $count; + } + + return $user_count; + } + + /** + * Get product totals based on product type. + * + * @return array + */ + public static function get_product_counts() { + $product_count = array(); + $product_count_data = wp_count_posts( 'product' ); + $product_count['total'] = $product_count_data->publish; + + $product_statuses = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); + foreach ( $product_statuses as $product_status ) { + $product_count[ $product_status->name ] = $product_status->count; + } + + return $product_count; + } + + /** + * Get order counts + * + * @return array + */ + private static function get_order_counts() { + $order_count = array(); + $order_count_data = wp_count_posts( 'shop_order' ); + foreach ( wc_get_order_statuses() as $status_slug => $status_name ) { + $order_count[ $status_slug ] = $order_count_data->{ $status_slug }; + } + return $order_count; + } + + /** + * Combine all order data. + * + * @return array + */ + private static function get_orders() { + $order_dates = self::get_order_dates(); + $order_counts = self::get_order_counts(); + $order_totals = self::get_order_totals(); + + return array_merge( $order_dates, $order_counts, $order_totals ); + } + + /** + * Get review counts for different statuses. + * + * @return array + */ + private static function get_review_counts() { + global $wpdb; + $review_count = array( 'total' => 0 ); + $status_map = array( + '0' => 'pending', + '1' => 'approved', + 'trash' => 'trash', + 'spam' => 'spam', + ); + $counts = $wpdb->get_results( + " + SELECT comment_approved, COUNT(*) AS num_reviews + FROM {$wpdb->comments} + WHERE comment_type = 'review' + GROUP BY comment_approved + ", + ARRAY_A + ); + + if ( ! $counts ) { + return $review_count; + } + + foreach ( $counts as $count ) { + $status = $count['comment_approved']; + if ( array_key_exists( $status, $status_map ) ) { + $review_count[ $status_map[ $status ] ] = $count['num_reviews']; + } + $review_count['total'] += $count['num_reviews']; + } + + return $review_count; + } + + /** + * Get the number of product categories. + * + * @return int + */ + private static function get_category_counts() { + return wp_count_terms( 'product_cat' ); + } + + /** + * Get a list of all active payment gateways. + * + * @return array + */ + private static function get_active_payment_gateways() { + $active_gateways = array(); + $gateways = WC()->payment_gateways->payment_gateways(); + foreach ( $gateways as $id => $gateway ) { + if ( isset( $gateway->enabled ) && 'yes' === $gateway->enabled ) { + $active_gateways[ $id ] = array( + 'title' => $gateway->title, + 'supports' => $gateway->supports, + ); + } + } + + return $active_gateways; + } + + /** + * Get a list of all active shipping methods. + * + * @return array + */ + private static function get_active_shipping_methods() { + $active_methods = array(); + $shipping_methods = WC()->shipping()->get_shipping_methods(); + foreach ( $shipping_methods as $id => $shipping_method ) { + if ( isset( $shipping_method->enabled ) && 'yes' === $shipping_method->enabled ) { + $active_methods[ $id ] = array( + 'title' => $shipping_method->title, + 'tax_status' => $shipping_method->tax_status, + ); + } + } + + return $active_methods; + } + + /** + * Get all options starting with woocommerce_ prefix. + * + * @return array + */ + private static function get_all_woocommerce_options_values() { + return array( + 'version' => WC()->version, + 'currency' => get_woocommerce_currency(), + 'base_location' => WC()->countries->get_base_country(), + 'selling_locations' => WC()->countries->get_allowed_countries(), + 'api_enabled' => get_option( 'woocommerce_api_enabled' ), + 'weight_unit' => get_option( 'woocommerce_weight_unit' ), + 'dimension_unit' => get_option( 'woocommerce_dimension_unit' ), + 'download_method' => get_option( 'woocommerce_file_download_method' ), + 'download_require_login' => get_option( 'woocommerce_downloads_require_login' ), + 'calc_taxes' => get_option( 'woocommerce_calc_taxes' ), + 'coupons_enabled' => get_option( 'woocommerce_enable_coupons' ), + 'guest_checkout' => get_option( 'woocommerce_enable_guest_checkout' ), + 'secure_checkout' => get_option( 'woocommerce_force_ssl_checkout' ), + 'enable_signup_and_login_from_checkout' => get_option( 'woocommerce_enable_signup_and_login_from_checkout' ), + 'enable_myaccount_registration' => get_option( 'woocommerce_enable_myaccount_registration' ), + 'registration_generate_username' => get_option( 'woocommerce_registration_generate_username' ), + 'registration_generate_password' => get_option( 'woocommerce_registration_generate_password' ), + ); + } + + /** + * Look for any template override and return filenames. + * + * @return array + */ + private static function get_all_template_overrides() { + $override_data = array(); + $template_paths = apply_filters( 'woocommerce_template_overrides_scan_paths', array( 'WooCommerce' => WC()->plugin_path() . '/templates/' ) ); + $scanned_files = array(); + + require_once WC()->plugin_path() . '/includes/admin/class-wc-admin-status.php'; + + foreach ( $template_paths as $plugin_name => $template_path ) { + $scanned_files[ $plugin_name ] = WC_Admin_Status::scan_template_files( $template_path ); + } + + foreach ( $scanned_files as $plugin_name => $files ) { + foreach ( $files as $file ) { + if ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . $file; + } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file; + } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { + $theme_file = get_template_directory() . '/' . $file; + } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_template_directory() . '/' . WC()->template_path() . $file; + } else { + $theme_file = false; + } + + if ( false !== $theme_file ) { + $override_data[] = basename( $theme_file ); + } + } + } + return $override_data; + } + + /** + * When an admin user logs in, there user agent is tracked in user meta and collected here. + * + * @return array + */ + private static function get_admin_user_agents() { + return array_filter( (array) get_option( 'woocommerce_tracker_ua', array() ) ); + } + + /** + * Get order totals + * + * @return array + */ + public static function get_order_totals() { + global $wpdb; + + $gross_total = $wpdb->get_var( + " + SELECT + SUM( order_meta.meta_value ) AS 'gross_total' + FROM {$wpdb->prefix}posts AS orders + LEFT JOIN {$wpdb->prefix}postmeta AS order_meta ON order_meta.post_id = orders.ID + WHERE order_meta.meta_key = '_order_total' + AND orders.post_status in ( 'wc-completed', 'wc-refunded' ) + GROUP BY order_meta.meta_key + " + ); + + if ( is_null( $gross_total ) ) { + $gross_total = 0; + } + + $processing_gross_total = $wpdb->get_var( + " + SELECT + SUM( order_meta.meta_value ) AS 'gross_total' + FROM {$wpdb->prefix}posts AS orders + LEFT JOIN {$wpdb->prefix}postmeta AS order_meta ON order_meta.post_id = orders.ID + WHERE order_meta.meta_key = '_order_total' + AND orders.post_status = 'wc-processing' + GROUP BY order_meta.meta_key + " + ); + + if ( is_null( $processing_gross_total ) ) { + $processing_gross_total = 0; + } + + return array( + 'gross' => $gross_total, + 'processing_gross' => $processing_gross_total, + ); + } + + /** + * Get last order date + * + * @return string + */ + private static function get_order_dates() { + global $wpdb; + + $min_max = $wpdb->get_row( + " + SELECT + MIN( post_date_gmt ) as 'first', MAX( post_date_gmt ) as 'last' + FROM {$wpdb->prefix}posts + WHERE post_type = 'shop_order' + AND post_status = 'wc-completed' + ", + ARRAY_A + ); + + if ( is_null( $min_max ) ) { + $min_max = array( + 'first' => '-', + 'last' => '-', + ); + } + + $processing_min_max = $wpdb->get_row( + " + SELECT + MIN( post_date_gmt ) as 'processing_first', MAX( post_date_gmt ) as 'processing_last' + FROM {$wpdb->prefix}posts + WHERE post_type = 'shop_order' + AND post_status = 'wc-processing' + ", + ARRAY_A + ); + + if ( is_null( $processing_min_max ) ) { + $processing_min_max = array( + 'processing_first' => '-', + 'processing_last' => '-', + ); + } + + return array_merge( $min_max, $processing_min_max ); + } + + /** + * Search a specific post for text content. + * + * @param integer $post_id The id of the post to search. + * @param string $text The text to search for. + * @return string 'Yes' if post contains $text (otherwise 'No'). + */ + public static function post_contains_text( $post_id, $text ) { + global $wpdb; + + // Search for the text anywhere in the post. + $wildcarded = "%{$text}%"; + + $result = $wpdb->get_var( + $wpdb->prepare( + " + SELECT COUNT( * ) FROM {$wpdb->prefix}posts + WHERE ID=%d + AND {$wpdb->prefix}posts.post_content LIKE %s + ", + array( $post_id, $wildcarded ) + ) + ); + + return ( '0' !== $result ) ? 'Yes' : 'No'; + } + + /** + * Get blocks from a woocommerce page. + * + * @param string $woo_page_name A woocommerce page e.g. `checkout` or `cart`. + * @return array Array of blocks as returned by parse_blocks(). + */ + private static function get_all_blocks_from_page( $woo_page_name ) { + $page_id = wc_get_page_id( $woo_page_name ); + + $page = get_post( $page_id ); + if ( ! $page ) { + return array(); + } + + $blocks = parse_blocks( $page->post_content ); + if ( ! $blocks ) { + return array(); + } + + return $blocks; + } + + /** + * Get all instances of the specified block on a specific woo page + * (e.g. `cart` or `checkout` page). + * + * @param string $block_name The name (id) of a block, e.g. `woocommerce/cart`. + * @param string $woo_page_name The woo page to search, e.g. `cart`. + * @return array Array of blocks as returned by parse_blocks(). + */ + private static function get_blocks_from_page( $block_name, $woo_page_name ) { + $page_blocks = self::get_all_blocks_from_page( $woo_page_name ); + + // Get any instances of the specified block. + return array_values( + array_filter( + $page_blocks, + function ( $block ) use ( $block_name ) { + return ( $block_name === $block['blockName'] ); + } + ) + ); + } + + /** + * Get tracker data for a specific block type on a woocommerce page. + * + * @param string $block_name The name (id) of a block, e.g. `woocommerce/cart`. + * @param string $woo_page_name The woo page to search, e.g. `cart`. + * @return array Associative array of tracker data with keys: + * - page_contains_block + * - block_attributes + */ + public static function get_block_tracker_data( $block_name, $woo_page_name ) { + $blocks = self::get_blocks_from_page( $block_name, $woo_page_name ); + + $block_present = false; + $attributes = array(); + if ( $blocks && count( $blocks ) ) { + // Return any customised attributes from the first block. + $block_present = true; + $attributes = $blocks[0]['attrs']; + } + + return array( + 'page_contains_block' => $block_present ? 'Yes' : 'No', + 'block_attributes' => $attributes, + ); + } + + /** + * Get info about the cart & checkout pages. + * + * @return array + */ + public static function get_cart_checkout_info() { + $cart_page_id = wc_get_page_id( 'cart' ); + $checkout_page_id = wc_get_page_id( 'checkout' ); + + $cart_block_data = self::get_block_tracker_data( 'woocommerce/cart', 'cart' ); + $checkout_block_data = self::get_block_tracker_data( 'woocommerce/checkout', 'checkout' ); + + return array( + 'cart_page_contains_cart_shortcode' => self::post_contains_text( + $cart_page_id, + '[woocommerce_cart]' + ), + 'checkout_page_contains_checkout_shortcode' => self::post_contains_text( + $checkout_page_id, + '[woocommerce_checkout]' + ), + + 'cart_page_contains_cart_block' => $cart_block_data['page_contains_block'], + 'cart_block_attributes' => $cart_block_data['block_attributes'], + 'checkout_page_contains_checkout_block' => $checkout_block_data['page_contains_block'], + 'checkout_block_attributes' => $checkout_block_data['block_attributes'], + ); + } +} + +WC_Tracker::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-validation.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-validation.php new file mode 100644 index 0000000..c2380d4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-validation.php @@ -0,0 +1,201 @@ + 0 ) { + return false; + } + + switch ( $country ) { + case 'AT': + $valid = (bool) preg_match( '/^([0-9]{4})$/', $postcode ); + break; + case 'BA': + $valid = (bool) preg_match( '/^([7-8]{1})([0-9]{4})$/', $postcode ); + break; + case 'BE': + $valid = (bool) preg_match( '/^([0-9]{4})$/i', $postcode ); + break; + case 'BR': + $valid = (bool) preg_match( '/^([0-9]{5})([-])?([0-9]{3})$/', $postcode ); + break; + case 'CH': + $valid = (bool) preg_match( '/^([0-9]{4})$/i', $postcode ); + break; + case 'DE': + $valid = (bool) preg_match( '/^([0]{1}[1-9]{1}|[1-9]{1}[0-9]{1})[0-9]{3}$/', $postcode ); + break; + case 'ES': + case 'FR': + case 'IT': + $valid = (bool) preg_match( '/^([0-9]{5})$/i', $postcode ); + break; + case 'GB': + $valid = self::is_gb_postcode( $postcode ); + break; + case 'HU': + $valid = (bool) preg_match( '/^([0-9]{4})$/i', $postcode ); + break; + case 'IE': + $valid = (bool) preg_match( '/([AC-FHKNPRTV-Y]\d{2}|D6W)[0-9AC-FHKNPRTV-Y]{4}/', wc_normalize_postcode( $postcode ) ); + break; + case 'IN': + $valid = (bool) preg_match( '/^[1-9]{1}[0-9]{2}\s{0,1}[0-9]{3}$/', $postcode ); + break; + case 'JP': + $valid = (bool) preg_match( '/^([0-9]{3})([-]?)([0-9]{4})$/', $postcode ); + break; + case 'PT': + $valid = (bool) preg_match( '/^([0-9]{4})([-])([0-9]{3})$/', $postcode ); + break; + case 'PR': + case 'US': + $valid = (bool) preg_match( '/^([0-9]{5})(-[0-9]{4})?$/i', $postcode ); + break; + case 'CA': + // CA Postal codes cannot contain D,F,I,O,Q,U and cannot start with W or Z. https://en.wikipedia.org/wiki/Postal_codes_in_Canada#Number_of_possible_postal_codes. + $valid = (bool) preg_match( '/^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])([\ ])?(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$/i', $postcode ); + break; + case 'PL': + $valid = (bool) preg_match( '/^([0-9]{2})([-])([0-9]{3})$/', $postcode ); + break; + case 'CZ': + case 'SK': + $valid = (bool) preg_match( '/^([0-9]{3})(\s?)([0-9]{2})$/', $postcode ); + break; + case 'NL': + $valid = (bool) preg_match( '/^([1-9][0-9]{3})(\s?)(?!SA|SD|SS)[A-Z]{2}$/i', $postcode ); + break; + case 'SI': + $valid = (bool) preg_match( '/^([1-9][0-9]{3})$/', $postcode ); + break; + case 'LI': + $valid = (bool) preg_match( '/^(94[8-9][0-9])$/', $postcode ); + break; + default: + $valid = true; + break; + } + + return apply_filters( 'woocommerce_validate_postcode', $valid, $postcode, $country ); + } + + /** + * Check if is a GB postcode. + * + * @param string $to_check A postcode. + * @return bool + */ + public static function is_gb_postcode( $to_check ) { + + // Permitted letters depend upon their position in the postcode. + // https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation. + $alpha1 = '[abcdefghijklmnoprstuwyz]'; // Character 1. + $alpha2 = '[abcdefghklmnopqrstuvwxy]'; // Character 2. + $alpha3 = '[abcdefghjkpstuw]'; // Character 3 == ABCDEFGHJKPSTUW. + $alpha4 = '[abehmnprvwxy]'; // Character 4 == ABEHMNPRVWXY. + $alpha5 = '[abdefghjlnpqrstuwxyz]'; // Character 5 != CIKMOV. + + $pcexp = array(); + + // Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA. + $pcexp[0] = '/^(' . $alpha1 . '{1}' . $alpha2 . '{0,1}[0-9]{1,2})([0-9]{1}' . $alpha5 . '{2})$/'; + + // Expression for postcodes: ANA NAA. + $pcexp[1] = '/^(' . $alpha1 . '{1}[0-9]{1}' . $alpha3 . '{1})([0-9]{1}' . $alpha5 . '{2})$/'; + + // Expression for postcodes: AANA NAA. + $pcexp[2] = '/^(' . $alpha1 . '{1}' . $alpha2 . '[0-9]{1}' . $alpha4 . ')([0-9]{1}' . $alpha5 . '{2})$/'; + + // Exception for the special postcode GIR 0AA. + $pcexp[3] = '/^(gir)(0aa)$/'; + + // Standard BFPO numbers. + $pcexp[4] = '/^(bfpo)([0-9]{1,4})$/'; + + // c/o BFPO numbers. + $pcexp[5] = '/^(bfpo)(c\/o[0-9]{1,3})$/'; + + // Load up the string to check, converting into lowercase and removing spaces. + $postcode = strtolower( $to_check ); + $postcode = str_replace( ' ', '', $postcode ); + + // Assume we are not going to find a valid postcode. + $valid = false; + + // Check the string against the six types of postcodes. + foreach ( $pcexp as $regexp ) { + if ( preg_match( $regexp, $postcode, $matches ) ) { + // Remember that we have found that the code is valid and break from loop. + $valid = true; + break; + } + } + + return $valid; + } + + /** + * Format the postcode according to the country and length of the postcode. + * + * @param string $postcode Postcode to format. + * @param string $country Country to format the postcode for. + * @return string Formatted postcode. + */ + public static function format_postcode( $postcode, $country ) { + return wc_format_postcode( $postcode, $country ); + } + + /** + * Format a given phone number. + * + * @param mixed $tel Phone number to format. + * @return string + */ + public static function format_phone( $tel ) { + return wc_format_phone_number( $tel ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-webhook.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-webhook.php new file mode 100644 index 0000000..1d55682 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-wc-webhook.php @@ -0,0 +1,1073 @@ + null, + 'date_modified' => null, + 'status' => 'disabled', + 'delivery_url' => '', + 'secret' => '', + 'name' => '', + 'topic' => '', + 'hooks' => '', + 'resource' => '', + 'event' => '', + 'failure_count' => 0, + 'user_id' => 0, + 'api_version' => 3, + 'pending_delivery' => false, + ); + + /** + * Load webhook data based on how WC_Webhook is called. + * + * @param WC_Webhook|int $data Webhook ID or data. + * @throws Exception If webhook cannot be read/found and $data is set. + */ + public function __construct( $data = 0 ) { + parent::__construct( $data ); + + if ( $data instanceof WC_Webhook ) { + $this->set_id( absint( $data->get_id() ) ); + } elseif ( is_numeric( $data ) ) { + $this->set_id( $data ); + } + + $this->data_store = WC_Data_Store::load( 'webhook' ); + + // If we have an ID, load the webhook from the DB. + if ( $this->get_id() ) { + try { + $this->data_store->read( $this ); + } catch ( Exception $e ) { + $this->set_id( 0 ); + $this->set_object_read( true ); + } + } else { + $this->set_object_read( true ); + } + } + + /** + * Enqueue the hooks associated with the webhook. + * + * @since 2.2.0 + */ + public function enqueue() { + $hooks = $this->get_hooks(); + $url = $this->get_delivery_url(); + + if ( is_array( $hooks ) && ! empty( $url ) ) { + foreach ( $hooks as $hook ) { + add_action( $hook, array( $this, 'process' ) ); + } + } + } + + /** + * Process the webhook for delivery by verifying that it should be delivered. + * and scheduling the delivery (in the background by default, or immediately). + * + * @since 2.2.0 + * @param mixed $arg The first argument provided from the associated hooks. + * @return mixed $arg Returns the argument in case the webhook was hooked into a filter. + */ + public function process( $arg ) { + + // Verify that webhook should be processed for delivery. + if ( ! $this->should_deliver( $arg ) ) { + return; + } + + // Mark this $arg as processed to ensure it doesn't get processed again within the current request. + $this->processed[] = $arg; + + /** + * Process webhook delivery. + * + * @since 3.3.0 + * @hooked wc_webhook_process_delivery - 10 + */ + do_action( 'woocommerce_webhook_process_delivery', $this, $arg ); + + return $arg; + } + + /** + * Helper to check if the webhook should be delivered, as some hooks. + * (like `wp_trash_post`) will fire for every post type, not just ours. + * + * @since 2.2.0 + * @param mixed $arg First hook argument. + * @return bool True if webhook should be delivered, false otherwise. + */ + private function should_deliver( $arg ) { + $should_deliver = $this->is_active() && $this->is_valid_topic() && $this->is_valid_action( $arg ) && $this->is_valid_resource( $arg ) && ! $this->is_already_processed( $arg ); + + /** + * Let other plugins intercept deliver for some messages queue like rabbit/zeromq. + * + * @param bool $should_deliver True if the webhook should be sent, or false to not send it. + * @param WC_Webhook $this The current webhook class. + * @param mixed $arg First hook argument. + */ + return apply_filters( 'woocommerce_webhook_should_deliver', $should_deliver, $this, $arg ); + } + + /** + * Returns if webhook is active. + * + * @since 3.6.0 + * @return bool True if validation passes. + */ + private function is_active() { + return 'active' === $this->get_status(); + } + + /** + * Returns if topic is valid. + * + * @since 3.6.0 + * @return bool True if validation passes. + */ + private function is_valid_topic() { + return wc_is_webhook_valid_topic( $this->get_topic() ); + } + + /** + * Validates the criteria for certain actions. + * + * @since 3.6.0 + * @param mixed $arg First hook argument. + * @return bool True if validation passes. + */ + private function is_valid_action( $arg ) { + $current_action = current_action(); + $return = true; + + switch ( $current_action ) { + case 'delete_post': + case 'wp_trash_post': + case 'untrashed_post': + $return = $this->is_valid_post_action( $arg ); + break; + case 'delete_user': + $return = $this->is_valid_user_action( $arg ); + break; + } + + if ( 0 === strpos( $current_action, 'woocommerce_process_shop' ) || 0 === strpos( $current_action, 'woocommerce_process_product' ) ) { + $return = $this->is_valid_processing_action( $arg ); + } + + return $return; + } + + /** + * Validates post actions. + * + * @since 3.6.0 + * @param mixed $arg First hook argument. + * @return bool True if validation passes. + */ + private function is_valid_post_action( $arg ) { + // Only deliver deleted/restored event for coupons, orders, and products. + if ( isset( $GLOBALS['post_type'] ) && ! in_array( $GLOBALS['post_type'], array( 'shop_coupon', 'shop_order', 'product' ), true ) ) { + return false; + } + + // Check if is delivering for the correct resource. + if ( isset( $GLOBALS['post_type'] ) && str_replace( 'shop_', '', $GLOBALS['post_type'] ) !== $this->get_resource() ) { + return false; + } + return true; + } + + /** + * Validates user actions. + * + * @since 3.6.0 + * @param mixed $arg First hook argument. + * @return bool True if validation passes. + */ + private function is_valid_user_action( $arg ) { + $user = get_userdata( absint( $arg ) ); + + // Only deliver deleted customer event for users with customer role. + if ( ! $user || ! in_array( 'customer', (array) $user->roles, true ) ) { + return false; + } + + return true; + } + + /** + * Validates WC processing actions. + * + * @since 3.6.0 + * @param mixed $arg First hook argument. + * @return bool True if validation passes. + */ + private function is_valid_processing_action( $arg ) { + // The `woocommerce_process_shop_*` and `woocommerce_process_product_*` hooks + // fire for create and update of products and orders, so check the post + // creation date to determine the actual event. + $resource = get_post( absint( $arg ) ); + + // Drafts don't have post_date_gmt so calculate it here. + $gmt_date = get_gmt_from_date( $resource->post_date ); + + // A resource is considered created when the hook is executed within 10 seconds of the post creation date. + $resource_created = ( ( time() - 10 ) <= strtotime( $gmt_date ) ); + + if ( 'created' === $this->get_event() && ! $resource_created ) { + return false; + } elseif ( 'updated' === $this->get_event() && $resource_created ) { + return false; + } + return true; + } + + /** + * Checks the resource for this webhook is valid e.g. valid post status. + * + * @since 3.6.0 + * @param mixed $arg First hook argument. + * @return bool True if validation passes. + */ + private function is_valid_resource( $arg ) { + $resource = $this->get_resource(); + + if ( in_array( $resource, array( 'order', 'product', 'coupon' ), true ) ) { + $status = get_post_status( absint( $arg ) ); + + // Ignore auto drafts for all resources. + if ( in_array( $status, array( 'auto-draft', 'new' ), true ) ) { + return false; + } + + // Ignore standard drafts for orders. + if ( 'order' === $resource && 'draft' === $status ) { + return false; + } + + // Check registered order types for order types args. + if ( 'order' === $resource && ! in_array( get_post_type( absint( $arg ) ), wc_get_order_types( 'order-webhooks' ), true ) ) { + return false; + } + } + return true; + } + + /** + * Checks if the specified resource has already been queued for delivery within the current request. + * + * Helps avoid duplication of data being sent for topics that have more than one hook defined. + * + * @param mixed $arg First hook argument. + * + * @return bool + */ + protected function is_already_processed( $arg ) { + return false !== array_search( $arg, $this->processed, true ); + } + + /** + * Deliver the webhook payload using wp_safe_remote_request(). + * + * @since 2.2.0 + * @param mixed $arg First hook argument. + */ + public function deliver( $arg ) { + $start_time = microtime( true ); + $payload = $this->build_payload( $arg ); + + // Setup request args. + $http_args = array( + 'method' => 'POST', + 'timeout' => MINUTE_IN_SECONDS, + 'redirection' => 0, + 'httpversion' => '1.0', + 'blocking' => true, + 'user-agent' => sprintf( 'WooCommerce/%s Hookshot (WordPress/%s)', Constants::get_constant( 'WC_VERSION' ), $GLOBALS['wp_version'] ), + 'body' => trim( wp_json_encode( $payload ) ), + 'headers' => array( + 'Content-Type' => 'application/json', + ), + 'cookies' => array(), + ); + + $http_args = apply_filters( 'woocommerce_webhook_http_args', $http_args, $arg, $this->get_id() ); + + // Add custom headers. + $delivery_id = $this->get_new_delivery_id(); + $http_args['headers']['X-WC-Webhook-Source'] = home_url( '/' ); // Since 2.6.0. + $http_args['headers']['X-WC-Webhook-Topic'] = $this->get_topic(); + $http_args['headers']['X-WC-Webhook-Resource'] = $this->get_resource(); + $http_args['headers']['X-WC-Webhook-Event'] = $this->get_event(); + $http_args['headers']['X-WC-Webhook-Signature'] = $this->generate_signature( $http_args['body'] ); + $http_args['headers']['X-WC-Webhook-ID'] = $this->get_id(); + $http_args['headers']['X-WC-Webhook-Delivery-ID'] = $delivery_id; + + // Webhook away! + $response = wp_safe_remote_request( $this->get_delivery_url(), $http_args ); + + $duration = NumberUtil::round( microtime( true ) - $start_time, 5 ); + + $this->log_delivery( $delivery_id, $http_args, $response, $duration ); + + do_action( 'woocommerce_webhook_delivery', $http_args, $response, $duration, $arg, $this->get_id() ); + } + + /** + * Get Legacy API payload. + * + * @since 3.0.0 + * @param string $resource Resource type. + * @param int $resource_id Resource ID. + * @param string $event Event type. + * @return array + */ + private function get_legacy_api_payload( $resource, $resource_id, $event ) { + // Include & load API classes. + WC()->api->includes(); + WC()->api->register_resources( new WC_API_Server( '/' ) ); + + switch ( $resource ) { + case 'coupon': + $payload = WC()->api->WC_API_Coupons->get_coupon( $resource_id ); + break; + + case 'customer': + $payload = WC()->api->WC_API_Customers->get_customer( $resource_id ); + break; + + case 'order': + $payload = WC()->api->WC_API_Orders->get_order( $resource_id, null, apply_filters( 'woocommerce_webhook_order_payload_filters', array() ) ); + break; + + case 'product': + // Bulk and quick edit action hooks return a product object instead of an ID. + if ( 'updated' === $event && is_a( $resource_id, 'WC_Product' ) ) { + $resource_id = $resource_id->get_id(); + } + $payload = WC()->api->WC_API_Products->get_product( $resource_id ); + break; + + // Custom topics include the first hook argument. + case 'action': + $payload = array( + 'action' => current( $this->get_hooks() ), + 'arg' => $resource_id, + ); + break; + + default: + $payload = array(); + break; + } + + return $payload; + } + + /** + * Get WP API integration payload. + * + * @since 3.0.0 + * @param string $resource Resource type. + * @param int $resource_id Resource ID. + * @param string $event Event type. + * @return array + */ + private function get_wp_api_payload( $resource, $resource_id, $event ) { + switch ( $resource ) { + case 'coupon': + case 'customer': + case 'order': + case 'product': + // Bulk and quick edit action hooks return a product object instead of an ID. + if ( 'product' === $resource && 'updated' === $event && is_a( $resource_id, 'WC_Product' ) ) { + $resource_id = $resource_id->get_id(); + } + + $version = str_replace( 'wp_api_', '', $this->get_api_version() ); + $payload = wc()->api->get_endpoint_data( "/wc/{$version}/{$resource}s/{$resource_id}" ); + break; + + // Custom topics include the first hook argument. + case 'action': + $payload = array( + 'action' => current( $this->get_hooks() ), + 'arg' => $resource_id, + ); + break; + + default: + $payload = array(); + break; + } + + return $payload; + } + + /** + * Build the payload data for the webhook. + * + * @since 2.2.0 + * @param mixed $resource_id First hook argument, typically the resource ID. + * @return mixed Payload data. + */ + public function build_payload( $resource_id ) { + // Build the payload with the same user context as the user who created + // the webhook -- this avoids permission errors as background processing + // runs with no user context. + $current_user = get_current_user_id(); + wp_set_current_user( $this->get_user_id() ); + + $resource = $this->get_resource(); + $event = $this->get_event(); + + // If a resource has been deleted, just include the ID. + if ( 'deleted' === $event ) { + $payload = array( + 'id' => $resource_id, + ); + } else { + if ( in_array( $this->get_api_version(), wc_get_webhook_rest_api_versions(), true ) ) { + $payload = $this->get_wp_api_payload( $resource, $resource_id, $event ); + } else { + $payload = $this->get_legacy_api_payload( $resource, $resource_id, $event ); + } + } + + // Restore the current user. + wp_set_current_user( $current_user ); + + return apply_filters( 'woocommerce_webhook_payload', $payload, $resource, $resource_id, $this->get_id() ); + } + + /** + * Generate a base64-encoded HMAC-SHA256 signature of the payload body so the + * recipient can verify the authenticity of the webhook. Note that the signature + * is calculated after the body has already been encoded (JSON by default). + * + * @since 2.2.0 + * @param string $payload Payload data to hash. + * @return string + */ + public function generate_signature( $payload ) { + $hash_algo = apply_filters( 'woocommerce_webhook_hash_algorithm', 'sha256', $payload, $this->get_id() ); + + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode + return base64_encode( hash_hmac( $hash_algo, $payload, wp_specialchars_decode( $this->get_secret(), ENT_QUOTES ), true ) ); + } + + /** + * Generate a new unique hash as a delivery id based on current time and wehbook id. + * Return the hash for inclusion in the webhook request. + * + * @since 2.2.0 + * @return string + */ + public function get_new_delivery_id() { + // Since we no longer use comments to store delivery logs, we generate a unique hash instead based on current time and webhook ID. + return wp_hash( $this->get_id() . strtotime( 'now' ) ); + } + + /** + * Log the delivery request/response. + * + * @since 2.2.0 + * @param string $delivery_id Previously created hash. + * @param array $request Request data. + * @param array|WP_Error $response Response data. + * @param float $duration Request duration. + */ + public function log_delivery( $delivery_id, $request, $response, $duration ) { + $logger = wc_get_logger(); + $message = array( + 'Webhook Delivery' => array( + 'Delivery ID' => $delivery_id, + 'Date' => date_i18n( __( 'M j, Y @ G:i', 'woocommerce' ), strtotime( 'now' ), true ), + 'URL' => $this->get_delivery_url(), + 'Duration' => $duration, + 'Request' => array( + 'Method' => $request['method'], + 'Headers' => array_merge( + array( + 'User-Agent' => $request['user-agent'], + ), + $request['headers'] + ), + ), + 'Body' => wp_slash( $request['body'] ), + ), + ); + + // Parse response. + if ( is_wp_error( $response ) ) { + $response_code = $response->get_error_code(); + $response_message = $response->get_error_message(); + $response_headers = array(); + $response_body = ''; + } else { + $response_code = wp_remote_retrieve_response_code( $response ); + $response_message = wp_remote_retrieve_response_message( $response ); + $response_headers = wp_remote_retrieve_headers( $response ); + $response_body = wp_remote_retrieve_body( $response ); + } + + $message['Webhook Delivery']['Response'] = array( + 'Code' => $response_code, + 'Message' => $response_message, + 'Headers' => $response_headers, + 'Body' => $response_body, + ); + + if ( ! Constants::is_true( 'WP_DEBUG' ) ) { + $message['Webhook Delivery']['Body'] = 'Webhook body is not logged unless WP_DEBUG mode is turned on. This is to avoid the storing of personal data in the logs.'; + $message['Webhook Delivery']['Response']['Body'] = 'Webhook body is not logged unless WP_DEBUG mode is turned on. This is to avoid the storing of personal data in the logs.'; + } + + $logger->info( + wc_print_r( $message, true ), + array( + 'source' => 'webhooks-delivery', + ) + ); + + // Track failures. + // Check for a success, which is a 2xx, 301 or 302 Response Code. + if ( intval( $response_code ) >= 200 && intval( $response_code ) < 303 ) { + $this->set_failure_count( 0 ); + $this->save(); + } else { + $this->failed_delivery(); + } + } + + /** + * Track consecutive delivery failures and automatically disable the webhook. + * if more than 5 consecutive failures occur. A failure is defined as a. + * non-2xx response. + * + * @since 2.2.0 + */ + private function failed_delivery() { + $failures = $this->get_failure_count(); + + if ( $failures > apply_filters( 'woocommerce_max_webhook_delivery_failures', 5 ) ) { + $this->set_status( 'disabled' ); + + do_action( 'woocommerce_webhook_disabled_due_delivery_failures', $this->get_id() ); + } else { + $this->set_failure_count( ++$failures ); + } + + $this->save(); + } + + /** + * Get the delivery logs for this webhook. + * + * @since 3.3.0 + * @return string + */ + public function get_delivery_logs() { + return esc_url( add_query_arg( 'log_file', wc_get_log_file_name( 'webhooks-delivery' ), admin_url( 'admin.php?page=wc-status&tab=logs' ) ) ); + } + + /** + * Get the delivery log specified by the ID. The delivery log includes: + * + * + duration + * + summary + * + request method/url + * + request headers/body + * + response code/message/headers/body + * + * @since 2.2 + * @deprecated 3.3.0 + * @param int $delivery_id Delivery ID. + * @return void + */ + public function get_delivery_log( $delivery_id ) { + wc_deprecated_function( 'WC_Webhook::get_delivery_log', '3.3' ); + } + + /** + * Send a test ping to the delivery URL, sent when the webhook is first created. + * + * @since 2.2.0 + * @return bool|WP_Error + */ + public function deliver_ping() { + $args = array( + 'user-agent' => sprintf( 'WooCommerce/%s Hookshot (WordPress/%s)', Constants::get_constant( 'WC_VERSION' ), $GLOBALS['wp_version'] ), + 'body' => 'webhook_id=' . $this->get_id(), + ); + + $test = wp_safe_remote_post( $this->get_delivery_url(), $args ); + $response_code = wp_remote_retrieve_response_code( $test ); + + if ( is_wp_error( $test ) ) { + /* translators: error message */ + return new WP_Error( 'error', sprintf( __( 'Error: Delivery URL cannot be reached: %s', 'woocommerce' ), $test->get_error_message() ) ); + } + + if ( 200 !== $response_code ) { + /* translators: error message */ + return new WP_Error( 'error', sprintf( __( 'Error: Delivery URL returned response code: %s', 'woocommerce' ), absint( $response_code ) ) ); + } + + $this->set_pending_delivery( false ); + $this->save(); + + return true; + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get the friendly name for the webhook. + * + * @since 2.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return string + */ + public function get_name( $context = 'view' ) { + return apply_filters( 'woocommerce_webhook_name', $this->get_prop( 'name', $context ), $this->get_id() ); + } + + /** + * Get the webhook status. + * + * - 'active' - delivers payload. + * - 'paused' - does not deliver payload, paused by admin. + * - 'disabled' - does not delivery payload, paused automatically due to consecutive failures. + * + * @since 2.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return string status + */ + public function get_status( $context = 'view' ) { + return apply_filters( 'woocommerce_webhook_status', $this->get_prop( 'status', $context ), $this->get_id() ); + } + + /** + * Get webhook created date. + * + * @since 3.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return WC_DateTime|null Object if the date is set or null if there is no date. + */ + public function get_date_created( $context = 'view' ) { + return $this->get_prop( 'date_created', $context ); + } + + /** + * Get webhook modified date. + * + * @since 3.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return WC_DateTime|null Object if the date is set or null if there is no date. + */ + public function get_date_modified( $context = 'view' ) { + return $this->get_prop( 'date_modified', $context ); + } + + /** + * Get the secret used for generating the HMAC-SHA256 signature. + * + * @since 2.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return string + */ + public function get_secret( $context = 'view' ) { + return apply_filters( 'woocommerce_webhook_secret', $this->get_prop( 'secret', $context ), $this->get_id() ); + } + + /** + * Get the webhook topic, e.g. `order.created`. + * + * @since 2.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return string + */ + public function get_topic( $context = 'view' ) { + return apply_filters( 'woocommerce_webhook_topic', $this->get_prop( 'topic', $context ), $this->get_id() ); + } + + /** + * Get the delivery URL. + * + * @since 2.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return string + */ + public function get_delivery_url( $context = 'view' ) { + return apply_filters( 'woocommerce_webhook_delivery_url', $this->get_prop( 'delivery_url', $context ), $this->get_id() ); + } + + /** + * Get the user ID for this webhook. + * + * @since 2.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return int + */ + public function get_user_id( $context = 'view' ) { + return $this->get_prop( 'user_id', $context ); + } + + /** + * API version. + * + * @since 3.0.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return string + */ + public function get_api_version( $context = 'view' ) { + $version = $this->get_prop( 'api_version', $context ); + + return 0 < $version ? 'wp_api_v' . $version : 'legacy_v3'; + } + + /** + * Get the failure count. + * + * @since 2.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return int + */ + public function get_failure_count( $context = 'view' ) { + return $this->get_prop( 'failure_count', $context ); + } + + /** + * Get pending delivery. + * + * @since 3.2.0 + * @param string $context What the value is for. + * Valid values are 'view' and 'edit'. + * @return bool + */ + public function get_pending_delivery( $context = 'view' ) { + return $this->get_prop( 'pending_delivery', $context ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set webhook name. + * + * @since 3.2.0 + * @param string $name Webhook name. + */ + public function set_name( $name ) { + $this->set_prop( 'name', $name ); + } + + /** + * Set webhook created date. + * + * @since 3.2.0 + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. + * If the DateTime string has no timezone or offset, + * WordPress site timezone will be assumed. + * Null if their is no date. + */ + public function set_date_created( $date = null ) { + $this->set_date_prop( 'date_created', $date ); + } + + /** + * Set webhook modified date. + * + * @since 3.2.0 + * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. + * If the DateTime string has no timezone or offset, + * WordPress site timezone will be assumed. + * Null if their is no date. + */ + public function set_date_modified( $date = null ) { + $this->set_date_prop( 'date_modified', $date ); + } + + /** + * Set status. + * + * @since 3.2.0 + * @param string $status Status. + */ + public function set_status( $status ) { + if ( ! array_key_exists( $status, wc_get_webhook_statuses() ) ) { + $status = 'disabled'; + } + + $this->set_prop( 'status', $status ); + } + + /** + * Set the secret used for generating the HMAC-SHA256 signature. + * + * @since 2.2.0 + * @param string $secret Secret. + */ + public function set_secret( $secret ) { + $this->set_prop( 'secret', $secret ); + } + + /** + * Set the webhook topic and associated hooks. + * The topic resource & event are also saved separately. + * + * @since 2.2.0 + * @param string $topic Webhook topic. + */ + public function set_topic( $topic ) { + $topic = wc_clean( $topic ); + + if ( ! wc_is_webhook_valid_topic( $topic ) ) { + $topic = ''; + } + + $this->set_prop( 'topic', $topic ); + } + + /** + * Set the delivery URL. + * + * @since 2.2.0 + * @param string $url Delivery URL. + */ + public function set_delivery_url( $url ) { + $this->set_prop( 'delivery_url', esc_url_raw( $url, array( 'http', 'https' ) ) ); + } + + /** + * Set user ID. + * + * @since 3.2.0 + * @param int $user_id User ID. + */ + public function set_user_id( $user_id ) { + $this->set_prop( 'user_id', (int) $user_id ); + } + + /** + * Set API version. + * + * @since 3.0.0 + * @param int|string $version REST API version. + */ + public function set_api_version( $version ) { + if ( ! is_numeric( $version ) ) { + $version = $this->data_store->get_api_version_number( $version ); + } + + $this->set_prop( 'api_version', (int) $version ); + } + + /** + * Set pending delivery. + * + * @since 3.2.0 + * @param bool $pending_delivery Set true if is pending for delivery. + */ + public function set_pending_delivery( $pending_delivery ) { + $this->set_prop( 'pending_delivery', (bool) $pending_delivery ); + } + + /** + * Set failure count. + * + * @since 3.2.0 + * @param bool $failure_count Total of failures. + */ + public function set_failure_count( $failure_count ) { + $this->set_prop( 'failure_count', intval( $failure_count ) ); + } + + /* + |-------------------------------------------------------------------------- + | Non-CRUD Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get the associated hook names for a topic. + * + * @since 2.2.0 + * @param string $topic Topic name. + * @return array + */ + private function get_topic_hooks( $topic ) { + $topic_hooks = array( + 'coupon.created' => array( + 'woocommerce_process_shop_coupon_meta', + 'woocommerce_new_coupon', + ), + 'coupon.updated' => array( + 'woocommerce_process_shop_coupon_meta', + 'woocommerce_update_coupon', + ), + 'coupon.deleted' => array( + 'wp_trash_post', + ), + 'coupon.restored' => array( + 'untrashed_post', + ), + 'customer.created' => array( + 'user_register', + 'woocommerce_created_customer', + 'woocommerce_new_customer', + ), + 'customer.updated' => array( + 'profile_update', + 'woocommerce_update_customer', + ), + 'customer.deleted' => array( + 'delete_user', + ), + 'order.created' => array( + 'woocommerce_new_order', + ), + 'order.updated' => array( + 'woocommerce_update_order', + 'woocommerce_order_refunded', + ), + 'order.deleted' => array( + 'wp_trash_post', + ), + 'order.restored' => array( + 'untrashed_post', + ), + 'product.created' => array( + 'woocommerce_process_product_meta', + 'woocommerce_new_product', + 'woocommerce_new_product_variation', + ), + 'product.updated' => array( + 'woocommerce_process_product_meta', + 'woocommerce_update_product', + 'woocommerce_update_product_variation', + ), + 'product.deleted' => array( + 'wp_trash_post', + ), + 'product.restored' => array( + 'untrashed_post', + ), + ); + + $topic_hooks = apply_filters( 'woocommerce_webhook_topic_hooks', $topic_hooks, $this ); + + return isset( $topic_hooks[ $topic ] ) ? $topic_hooks[ $topic ] : array(); + } + + /** + * Get the hook names for the webhook. + * + * @since 2.2.0 + * @return array + */ + public function get_hooks() { + if ( 'action' === $this->get_resource() ) { + $hooks = array( $this->get_event() ); + } else { + $hooks = $this->get_topic_hooks( $this->get_topic() ); + } + + return apply_filters( 'woocommerce_webhook_hooks', $hooks, $this->get_id() ); + } + + /** + * Get the resource for the webhook, e.g. `order`. + * + * @since 2.2.0 + * @return string + */ + public function get_resource() { + $topic = explode( '.', $this->get_topic() ); + + return apply_filters( 'woocommerce_webhook_resource', $topic[0], $this->get_id() ); + } + + /** + * Get the event for the webhook, e.g. `created`. + * + * @since 2.2.0 + * @return string + */ + public function get_event() { + $topic = explode( '.', $this->get_topic() ); + + return apply_filters( 'woocommerce_webhook_event', isset( $topic[1] ) ? $topic[1] : '', $this->get_id() ); + } + + /** + * Get the webhook i18n status. + * + * @return string + */ + public function get_i18n_status() { + $status = $this->get_status(); + $statuses = wc_get_webhook_statuses(); + + return isset( $statuses[ $status ] ) ? $statuses[ $status ] : $status; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-woocommerce.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-woocommerce.php new file mode 100644 index 0000000..c5313fd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/class-woocommerce.php @@ -0,0 +1,974 @@ +$key(); + } + } + + /** + * WooCommerce Constructor. + */ + public function __construct() { + $this->define_constants(); + $this->define_tables(); + $this->includes(); + $this->init_hooks(); + } + + /** + * When WP has loaded all plugins, trigger the `woocommerce_loaded` hook. + * + * This ensures `woocommerce_loaded` is called only after all other plugins + * are loaded, to avoid issues caused by plugin directory naming changing + * the load order. See #21524 for details. + * + * @since 3.6.0 + */ + public function on_plugins_loaded() { + do_action( 'woocommerce_loaded' ); + } + + /** + * Hook into actions and filters. + * + * @since 2.3 + */ + private function init_hooks() { + register_activation_hook( WC_PLUGIN_FILE, array( 'WC_Install', 'install' ) ); + register_shutdown_function( array( $this, 'log_errors' ) ); + + add_action( 'plugins_loaded', array( $this, 'on_plugins_loaded' ), -1 ); + add_action( 'admin_notices', array( $this, 'build_dependencies_notice' ) ); + add_action( 'after_setup_theme', array( $this, 'setup_environment' ) ); + add_action( 'after_setup_theme', array( $this, 'include_template_functions' ), 11 ); + add_action( 'init', array( $this, 'init' ), 0 ); + add_action( 'init', array( 'WC_Shortcodes', 'init' ) ); + add_action( 'init', array( 'WC_Emails', 'init_transactional_emails' ) ); + add_action( 'init', array( $this, 'add_image_sizes' ) ); + add_action( 'init', array( $this, 'load_rest_api' ) ); + add_action( 'switch_blog', array( $this, 'wpdb_table_fix' ), 0 ); + add_action( 'activated_plugin', array( $this, 'activated_plugin' ) ); + add_action( 'deactivated_plugin', array( $this, 'deactivated_plugin' ) ); + } + + /** + * Ensures fatal errors are logged so they can be picked up in the status report. + * + * @since 3.2.0 + */ + public function log_errors() { + $error = error_get_last(); + if ( $error && in_array( $error['type'], array( E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ), true ) ) { + $logger = wc_get_logger(); + $logger->critical( + /* translators: 1: error message 2: file name and path 3: line number */ + sprintf( __( '%1$s in %2$s on line %3$s', 'woocommerce' ), $error['message'], $error['file'], $error['line'] ) . PHP_EOL, + array( + 'source' => 'fatal-errors', + ) + ); + do_action( 'woocommerce_shutdown_error', $error ); + } + } + + /** + * Define WC Constants. + */ + private function define_constants() { + $upload_dir = wp_upload_dir( null, false ); + + $this->define( 'WC_ABSPATH', dirname( WC_PLUGIN_FILE ) . '/' ); + $this->define( 'WC_PLUGIN_BASENAME', plugin_basename( WC_PLUGIN_FILE ) ); + $this->define( 'WC_VERSION', $this->version ); + $this->define( 'WOOCOMMERCE_VERSION', $this->version ); + $this->define( 'WC_ROUNDING_PRECISION', 6 ); + $this->define( 'WC_DISCOUNT_ROUNDING_MODE', 2 ); + $this->define( 'WC_TAX_ROUNDING_MODE', 'yes' === get_option( 'woocommerce_prices_include_tax', 'no' ) ? 2 : 1 ); + $this->define( 'WC_DELIMITER', '|' ); + $this->define( 'WC_LOG_DIR', $upload_dir['basedir'] . '/wc-logs/' ); + $this->define( 'WC_SESSION_CACHE_GROUP', 'wc_session_id' ); + $this->define( 'WC_TEMPLATE_DEBUG_MODE', false ); + $this->define( 'WC_NOTICE_MIN_PHP_VERSION', '7.2' ); + $this->define( 'WC_NOTICE_MIN_WP_VERSION', '5.2' ); + $this->define( 'WC_PHP_MIN_REQUIREMENTS_NOTICE', 'wp_php_min_requirements_' . WC_NOTICE_MIN_PHP_VERSION . '_' . WC_NOTICE_MIN_WP_VERSION ); + } + + /** + * Register custom tables within $wpdb object. + */ + private function define_tables() { + global $wpdb; + + // List of tables without prefixes. + $tables = array( + 'payment_tokenmeta' => 'woocommerce_payment_tokenmeta', + 'order_itemmeta' => 'woocommerce_order_itemmeta', + 'wc_product_meta_lookup' => 'wc_product_meta_lookup', + 'wc_tax_rate_classes' => 'wc_tax_rate_classes', + 'wc_reserved_stock' => 'wc_reserved_stock', + ); + + foreach ( $tables as $name => $table ) { + $wpdb->$name = $wpdb->prefix . $table; + $wpdb->tables[] = $table; + } + } + + /** + * Define constant if not already set. + * + * @param string $name Constant name. + * @param string|bool $value Constant value. + */ + private function define( $name, $value ) { + if ( ! defined( $name ) ) { + define( $name, $value ); + } + } + + /** + * Returns true if the request is a non-legacy REST API request. + * + * Legacy REST requests should still run some extra code for backwards compatibility. + * + * @todo: replace this function once core WP function is available: https://core.trac.wordpress.org/ticket/42061. + * + * @return bool + */ + public function is_rest_api_request() { + if ( empty( $_SERVER['REQUEST_URI'] ) ) { + return false; + } + + $rest_prefix = trailingslashit( rest_get_url_prefix() ); + $is_rest_api_request = ( false !== strpos( $_SERVER['REQUEST_URI'], $rest_prefix ) ); // phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + return apply_filters( 'woocommerce_is_rest_api_request', $is_rest_api_request ); + } + + /** + * Load REST API. + */ + public function load_rest_api() { + \Automattic\WooCommerce\RestApi\Server::instance()->init(); + } + + /** + * What type of request is this? + * + * @param string $type admin, ajax, cron or frontend. + * @return bool + */ + private function is_request( $type ) { + switch ( $type ) { + case 'admin': + return is_admin(); + case 'ajax': + return defined( 'DOING_AJAX' ); + case 'cron': + return defined( 'DOING_CRON' ); + case 'frontend': + return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' ) && ! $this->is_rest_api_request(); + } + } + + /** + * Include required core files used in admin and on the frontend. + */ + public function includes() { + /** + * Class autoloader. + */ + include_once WC_ABSPATH . 'includes/class-wc-autoloader.php'; + + /** + * Interfaces. + */ + include_once WC_ABSPATH . 'includes/interfaces/class-wc-abstract-order-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-coupon-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-customer-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-customer-download-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-customer-download-log-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-object-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-item-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-item-product-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-item-type-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-refund-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-payment-token-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-product-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-product-variable-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-shipping-zone-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-logger-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-log-handler-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-webhooks-data-store-interface.php'; + include_once WC_ABSPATH . 'includes/interfaces/class-wc-queue-interface.php'; + + /** + * Core traits. + */ + include_once WC_ABSPATH . 'includes/traits/trait-wc-item-totals.php'; + + /** + * Abstract classes. + */ + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-data.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-object-query.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-payment-token.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-product.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-order.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-settings-api.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-shipping-method.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-payment-gateway.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-integration.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-log-handler.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-deprecated-hooks.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-session.php'; + include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-privacy.php'; + + /** + * Core classes. + */ + include_once WC_ABSPATH . 'includes/wc-core-functions.php'; + include_once WC_ABSPATH . 'includes/class-wc-datetime.php'; + include_once WC_ABSPATH . 'includes/class-wc-post-types.php'; + include_once WC_ABSPATH . 'includes/class-wc-install.php'; + include_once WC_ABSPATH . 'includes/class-wc-geolocation.php'; + include_once WC_ABSPATH . 'includes/class-wc-download-handler.php'; + include_once WC_ABSPATH . 'includes/class-wc-comments.php'; + include_once WC_ABSPATH . 'includes/class-wc-post-data.php'; + include_once WC_ABSPATH . 'includes/class-wc-ajax.php'; + include_once WC_ABSPATH . 'includes/class-wc-emails.php'; + include_once WC_ABSPATH . 'includes/class-wc-data-exception.php'; + include_once WC_ABSPATH . 'includes/class-wc-query.php'; + include_once WC_ABSPATH . 'includes/class-wc-meta-data.php'; + include_once WC_ABSPATH . 'includes/class-wc-order-factory.php'; + include_once WC_ABSPATH . 'includes/class-wc-order-query.php'; + include_once WC_ABSPATH . 'includes/class-wc-product-factory.php'; + include_once WC_ABSPATH . 'includes/class-wc-product-query.php'; + include_once WC_ABSPATH . 'includes/class-wc-payment-tokens.php'; + include_once WC_ABSPATH . 'includes/class-wc-shipping-zone.php'; + include_once WC_ABSPATH . 'includes/gateways/class-wc-payment-gateway-cc.php'; + include_once WC_ABSPATH . 'includes/gateways/class-wc-payment-gateway-echeck.php'; + include_once WC_ABSPATH . 'includes/class-wc-countries.php'; + include_once WC_ABSPATH . 'includes/class-wc-integrations.php'; + include_once WC_ABSPATH . 'includes/class-wc-cache-helper.php'; + include_once WC_ABSPATH . 'includes/class-wc-https.php'; + include_once WC_ABSPATH . 'includes/class-wc-deprecated-action-hooks.php'; + include_once WC_ABSPATH . 'includes/class-wc-deprecated-filter-hooks.php'; + include_once WC_ABSPATH . 'includes/class-wc-background-emailer.php'; + include_once WC_ABSPATH . 'includes/class-wc-discounts.php'; + include_once WC_ABSPATH . 'includes/class-wc-cart-totals.php'; + include_once WC_ABSPATH . 'includes/customizer/class-wc-shop-customizer.php'; + include_once WC_ABSPATH . 'includes/class-wc-regenerate-images.php'; + include_once WC_ABSPATH . 'includes/class-wc-privacy.php'; + include_once WC_ABSPATH . 'includes/class-wc-structured-data.php'; + include_once WC_ABSPATH . 'includes/class-wc-shortcodes.php'; + include_once WC_ABSPATH . 'includes/class-wc-logger.php'; + include_once WC_ABSPATH . 'includes/queue/class-wc-action-queue.php'; + include_once WC_ABSPATH . 'includes/queue/class-wc-queue.php'; + include_once WC_ABSPATH . 'includes/admin/marketplace-suggestions/class-wc-marketplace-updater.php'; + + /** + * Data stores - used to store and retrieve CRUD object data from the database. + */ + include_once WC_ABSPATH . 'includes/class-wc-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-data-store-wp.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-coupon-data-store-cpt.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-product-data-store-cpt.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-product-grouped-data-store-cpt.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-product-variable-data-store-cpt.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-product-variation-data-store-cpt.php'; + include_once WC_ABSPATH . 'includes/data-stores/abstract-wc-order-item-type-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-coupon-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-fee-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-product-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-shipping-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-tax-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-payment-token-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store-session.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-customer-download-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-customer-download-log-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-shipping-zone-data-store.php'; + include_once WC_ABSPATH . 'includes/data-stores/abstract-wc-order-data-store-cpt.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-data-store-cpt.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-refund-data-store-cpt.php'; + include_once WC_ABSPATH . 'includes/data-stores/class-wc-webhook-data-store.php'; + + /** + * REST API. + */ + include_once WC_ABSPATH . 'includes/legacy/class-wc-legacy-api.php'; + include_once WC_ABSPATH . 'includes/class-wc-api.php'; + include_once WC_ABSPATH . 'includes/class-wc-rest-authentication.php'; + include_once WC_ABSPATH . 'includes/class-wc-rest-exception.php'; + include_once WC_ABSPATH . 'includes/class-wc-auth.php'; + include_once WC_ABSPATH . 'includes/class-wc-register-wp-admin-settings.php'; + + /** + * WCCOM Site. + */ + include_once WC_ABSPATH . 'includes/wccom-site/class-wc-wccom-site.php'; + + /** + * Libraries and packages. + */ + include_once WC_ABSPATH . 'packages/action-scheduler/action-scheduler.php'; + + if ( defined( 'WP_CLI' ) && WP_CLI ) { + include_once WC_ABSPATH . 'includes/class-wc-cli.php'; + } + + if ( $this->is_request( 'admin' ) ) { + include_once WC_ABSPATH . 'includes/admin/class-wc-admin.php'; + } + + if ( $this->is_request( 'frontend' ) ) { + $this->frontend_includes(); + } + + if ( $this->is_request( 'cron' ) && 'yes' === get_option( 'woocommerce_allow_tracking', 'no' ) ) { + include_once WC_ABSPATH . 'includes/class-wc-tracker.php'; + } + + $this->theme_support_includes(); + $this->query = new WC_Query(); + $this->api = new WC_API(); + $this->api->init(); + } + + /** + * Include classes for theme support. + * + * @since 3.3.0 + */ + private function theme_support_includes() { + if ( wc_is_wp_default_theme_active() ) { + switch ( get_template() ) { + case 'twentyten': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-ten.php'; + break; + case 'twentyeleven': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-eleven.php'; + break; + case 'twentytwelve': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twelve.php'; + break; + case 'twentythirteen': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-thirteen.php'; + break; + case 'twentyfourteen': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fourteen.php'; + break; + case 'twentyfifteen': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fifteen.php'; + break; + case 'twentysixteen': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-sixteen.php'; + break; + case 'twentyseventeen': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-seventeen.php'; + break; + case 'twentynineteen': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-nineteen.php'; + break; + case 'twentytwenty': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twenty.php'; + break; + case 'twentytwentyone': + include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twenty-one.php'; + break; + } + } + } + + /** + * Include required frontend files. + */ + public function frontend_includes() { + include_once WC_ABSPATH . 'includes/wc-cart-functions.php'; + include_once WC_ABSPATH . 'includes/wc-notice-functions.php'; + include_once WC_ABSPATH . 'includes/wc-template-hooks.php'; + include_once WC_ABSPATH . 'includes/class-wc-template-loader.php'; + include_once WC_ABSPATH . 'includes/class-wc-frontend-scripts.php'; + include_once WC_ABSPATH . 'includes/class-wc-form-handler.php'; + include_once WC_ABSPATH . 'includes/class-wc-cart.php'; + include_once WC_ABSPATH . 'includes/class-wc-tax.php'; + include_once WC_ABSPATH . 'includes/class-wc-shipping-zones.php'; + include_once WC_ABSPATH . 'includes/class-wc-customer.php'; + include_once WC_ABSPATH . 'includes/class-wc-embed.php'; + include_once WC_ABSPATH . 'includes/class-wc-session-handler.php'; + } + + /** + * Function used to Init WooCommerce Template Functions - This makes them pluggable by plugins and themes. + */ + public function include_template_functions() { + include_once WC_ABSPATH . 'includes/wc-template-functions.php'; + } + + /** + * Init WooCommerce when WordPress Initialises. + */ + public function init() { + // Before init action. + do_action( 'before_woocommerce_init' ); + + // Set up localisation. + $this->load_plugin_textdomain(); + + // Load class instances. + $this->product_factory = new WC_Product_Factory(); + $this->order_factory = new WC_Order_Factory(); + $this->countries = new WC_Countries(); + $this->integrations = new WC_Integrations(); + $this->structured_data = new WC_Structured_Data(); + $this->deprecated_hook_handlers['actions'] = new WC_Deprecated_Action_Hooks(); + $this->deprecated_hook_handlers['filters'] = new WC_Deprecated_Filter_Hooks(); + + // Classes/actions loaded for the frontend and for ajax requests. + if ( $this->is_request( 'frontend' ) ) { + wc_load_cart(); + } + + $this->load_webhooks(); + + // Init action. + do_action( 'woocommerce_init' ); + } + + /** + * Load Localisation files. + * + * Note: the first-loaded translation file overrides any following ones if the same translation is present. + * + * Locales found in: + * - WP_LANG_DIR/woocommerce/woocommerce-LOCALE.mo + * - WP_LANG_DIR/plugins/woocommerce-LOCALE.mo + */ + public function load_plugin_textdomain() { + if ( function_exists( 'determine_locale' ) ) { + $locale = determine_locale(); + } else { + // @todo Remove when start supporting WP 5.0 or later. + $locale = is_admin() ? get_user_locale() : get_locale(); + } + + $locale = apply_filters( 'plugin_locale', $locale, 'woocommerce' ); + + unload_textdomain( 'woocommerce' ); + load_textdomain( 'woocommerce', WP_LANG_DIR . '/woocommerce/woocommerce-' . $locale . '.mo' ); + load_plugin_textdomain( 'woocommerce', false, plugin_basename( dirname( WC_PLUGIN_FILE ) ) . '/i18n/languages' ); + } + + /** + * Ensure theme and server variable compatibility and setup image sizes. + */ + public function setup_environment() { + /** + * WC_TEMPLATE_PATH constant. + * + * @deprecated 2.2 Use WC()->template_path() instead. + */ + $this->define( 'WC_TEMPLATE_PATH', $this->template_path() ); + + $this->add_thumbnail_support(); + } + + /** + * Ensure post thumbnail support is turned on. + */ + private function add_thumbnail_support() { + if ( ! current_theme_supports( 'post-thumbnails' ) ) { + add_theme_support( 'post-thumbnails' ); + } + add_post_type_support( 'product', 'thumbnail' ); + } + + /** + * Add WC Image sizes to WP. + * + * As of 3.3, image sizes can be registered via themes using add_theme_support for woocommerce + * and defining an array of args. If these are not defined, we will use defaults. This is + * handled in wc_get_image_size function. + * + * 3.3 sizes: + * + * woocommerce_thumbnail - Used in product listings. We assume these work for a 3 column grid layout. + * woocommerce_single - Used on single product pages for the main image. + * + * @since 2.3 + */ + public function add_image_sizes() { + $thumbnail = wc_get_image_size( 'thumbnail' ); + $single = wc_get_image_size( 'single' ); + $gallery_thumbnail = wc_get_image_size( 'gallery_thumbnail' ); + + add_image_size( 'woocommerce_thumbnail', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] ); + add_image_size( 'woocommerce_single', $single['width'], $single['height'], $single['crop'] ); + add_image_size( 'woocommerce_gallery_thumbnail', $gallery_thumbnail['width'], $gallery_thumbnail['height'], $gallery_thumbnail['crop'] ); + + /** + * Legacy image sizes. + * + * @deprecated 3.3.0 These sizes will be removed in 4.6.0. + */ + add_image_size( 'shop_catalog', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] ); + add_image_size( 'shop_single', $single['width'], $single['height'], $single['crop'] ); + add_image_size( 'shop_thumbnail', $gallery_thumbnail['width'], $gallery_thumbnail['height'], $gallery_thumbnail['crop'] ); + } + + /** + * Get the plugin url. + * + * @return string + */ + public function plugin_url() { + return untrailingslashit( plugins_url( '/', WC_PLUGIN_FILE ) ); + } + + /** + * Get the plugin path. + * + * @return string + */ + public function plugin_path() { + return untrailingslashit( plugin_dir_path( WC_PLUGIN_FILE ) ); + } + + /** + * Get the template path. + * + * @return string + */ + public function template_path() { + return apply_filters( 'woocommerce_template_path', 'woocommerce/' ); + } + + /** + * Get Ajax URL. + * + * @return string + */ + public function ajax_url() { + return admin_url( 'admin-ajax.php', 'relative' ); + } + + /** + * Return the WC API URL for a given request. + * + * @param string $request Requested endpoint. + * @param bool|null $ssl If should use SSL, null if should auto detect. Default: null. + * @return string + */ + public function api_request_url( $request, $ssl = null ) { + if ( is_null( $ssl ) ) { + $scheme = wp_parse_url( home_url(), PHP_URL_SCHEME ); + } elseif ( $ssl ) { + $scheme = 'https'; + } else { + $scheme = 'http'; + } + + if ( strstr( get_option( 'permalink_structure' ), '/index.php/' ) ) { + $api_request_url = trailingslashit( home_url( '/index.php/wc-api/' . $request, $scheme ) ); + } elseif ( get_option( 'permalink_structure' ) ) { + $api_request_url = trailingslashit( home_url( '/wc-api/' . $request, $scheme ) ); + } else { + $api_request_url = add_query_arg( 'wc-api', $request, trailingslashit( home_url( '', $scheme ) ) ); + } + + return esc_url_raw( apply_filters( 'woocommerce_api_request_url', $api_request_url, $request, $ssl ) ); + } + + /** + * Load & enqueue active webhooks. + * + * @since 2.2 + */ + private function load_webhooks() { + + if ( ! is_blog_installed() ) { + return; + } + + /** + * Hook: woocommerce_load_webhooks_limit. + * + * @since 3.6.0 + * @param int $limit Used to limit how many webhooks are loaded. Default: no limit. + */ + $limit = apply_filters( 'woocommerce_load_webhooks_limit', null ); + + wc_load_webhooks( 'active', $limit ); + } + + /** + * Initialize the customer and cart objects and setup customer saving on shutdown. + * + * @since 3.6.4 + * @return void + */ + public function initialize_cart() { + // Cart needs customer info. + if ( is_null( $this->customer ) || ! $this->customer instanceof WC_Customer ) { + $this->customer = new WC_Customer( get_current_user_id(), true ); + // Customer should be saved during shutdown. + add_action( 'shutdown', array( $this->customer, 'save' ), 10 ); + } + if ( is_null( $this->cart ) || ! $this->cart instanceof WC_Cart ) { + $this->cart = new WC_Cart(); + } + } + + /** + * Initialize the session class. + * + * @since 3.6.4 + * @return void + */ + public function initialize_session() { + // Session class, handles session data for users - can be overwritten if custom handler is needed. + $session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' ); + if ( is_null( $this->session ) || ! $this->session instanceof $session_class ) { + $this->session = new $session_class(); + $this->session->init(); + } + } + + /** + * Set tablenames inside WPDB object. + */ + public function wpdb_table_fix() { + $this->define_tables(); + } + + /** + * Ran when any plugin is activated. + * + * @since 3.6.0 + * @param string $filename The filename of the activated plugin. + */ + public function activated_plugin( $filename ) { + include_once dirname( __FILE__ ) . '/admin/helper/class-wc-helper.php'; + + WC_Helper::activated_plugin( $filename ); + } + + /** + * Ran when any plugin is deactivated. + * + * @since 3.6.0 + * @param string $filename The filename of the deactivated plugin. + */ + public function deactivated_plugin( $filename ) { + include_once dirname( __FILE__ ) . '/admin/helper/class-wc-helper.php'; + + WC_Helper::deactivated_plugin( $filename ); + } + + /** + * Get queue instance. + * + * @return WC_Queue_Interface + */ + public function queue() { + return WC_Queue::instance(); + } + + /** + * Get Checkout Class. + * + * @return WC_Checkout + */ + public function checkout() { + return WC_Checkout::instance(); + } + + /** + * Get gateways class. + * + * @return WC_Payment_Gateways + */ + public function payment_gateways() { + return WC_Payment_Gateways::instance(); + } + + /** + * Get shipping class. + * + * @return WC_Shipping + */ + public function shipping() { + return WC_Shipping::instance(); + } + + /** + * Email Class. + * + * @return WC_Emails + */ + public function mailer() { + return WC_Emails::instance(); + } + + /** + * Check if plugin assets are built and minified + * + * @return bool + */ + public function build_dependencies_satisfied() { + // Check if we have compiled CSS. + if ( ! file_exists( WC()->plugin_path() . '/assets/css/admin.css' ) ) { + return false; + } + + // Check if we have minified JS. + if ( ! file_exists( WC()->plugin_path() . '/assets/js/admin/woocommerce_admin.min.js' ) ) { + return false; + } + + return true; + } + + /** + * Output a admin notice when build dependencies not met. + * + * @return void + */ + public function build_dependencies_notice() { + if ( $this->build_dependencies_satisfied() ) { + return; + } + + $message_one = __( 'You have installed a development version of WooCommerce which requires files to be built and minified. From the plugin directory, run grunt assets to build and minify assets.', 'woocommerce' ); + $message_two = sprintf( + /* translators: 1: URL of WordPress.org Repository 2: URL of the GitHub Repository release page */ + __( 'Or you can download a pre-built version of the plugin from the WordPress.org repository or by visiting the releases page in the GitHub repository.', 'woocommerce' ), + 'https://wordpress.org/plugins/woocommerce/', + 'https://github.com/woocommerce/woocommerce/releases' + ); + printf( '

    %s %s

    ', $message_one, $message_two ); /* WPCS: xss ok. */ + } + + /** + * Is the WooCommerce Admin actively included in the WooCommerce core? + * Based on presence of a basic WC Admin function. + * + * @return boolean + */ + public function is_wc_admin_active() { + return function_exists( 'wc_admin_url' ); + } + + /** + * Call a user function. This should be used to execute any non-idempotent function, especially + * those in the `includes` directory or provided by WordPress. + * + * This method can be useful for unit tests, since functions called using this method + * can be easily mocked by using WC_Unit_Test_Case::register_legacy_proxy_function_mocks. + * + * @param string $function_name The function to execute. + * @param mixed ...$parameters The parameters to pass to the function. + * + * @return mixed The result from the function. + * + * @since 4.4 + */ + public function call_function( $function_name, ...$parameters ) { + return wc_get_container()->get( LegacyProxy::class )->call_function( $function_name, ...$parameters ); + } + + /** + * Call a static method in a class. This should be used to execute any non-idempotent method in classes + * from the `includes` directory. + * + * This method can be useful for unit tests, since methods called using this method + * can be easily mocked by using WC_Unit_Test_Case::register_legacy_proxy_static_mocks. + * + * @param string $class_name The name of the class containing the method. + * @param string $method_name The name of the method. + * @param mixed ...$parameters The parameters to pass to the method. + * + * @return mixed The result from the method. + * + * @since 4.4 + */ + public function call_static( $class_name, $method_name, ...$parameters ) { + return wc_get_container()->get( LegacyProxy::class )->call_static( $class_name, $method_name, ...$parameters ); + } + + /** + * Gets an instance of a given legacy class. + * This must not be used to get instances of classes in the `src` directory. + * + * This method can be useful for unit tests, since objects obtained using this method + * can be easily mocked by using WC_Unit_Test_Case::register_legacy_proxy_class_mocks. + * + * @param string $class_name The name of the class to get an instance for. + * @param mixed ...$args Parameters to be passed to the class constructor or to the appropriate internal 'get_instance_of_' method. + * + * @return object The instance of the class. + * @throws \Exception The requested class belongs to the `src` directory, or there was an error creating an instance of the class. + * + * @since 4.4 + */ + public function get_instance_of( string $class_name, ...$args ) { + return wc_get_container()->get( LegacyProxy::class )->get_instance_of( $class_name, ...$args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-rest-command.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-rest-command.php new file mode 100644 index 0000000..f4e2239 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-rest-command.php @@ -0,0 +1,467 @@ + desc). + * + * @var array + */ + private $supported_ids = array(); + + /** + * Sets up REST Command. + * + * @param string $name Name of endpoint object (comes from schema). + * @param string $route Path to route of this endpoint. + * @param array $schema Schema object. + */ + public function __construct( $name, $route, $schema ) { + $this->name = $name; + + preg_match_all( '#\([^\)]+\)#', $route, $matches ); + $first_match = $matches[0]; + $resource_id = ! empty( $matches[0] ) ? array_pop( $matches[0] ) : null; + $this->route = rtrim( $route ); + $this->schema = $schema; + + $this->resource_identifier = $resource_id; + if ( in_array( $name, $this->routes_with_parent_id, true ) ) { + $is_singular = substr( $this->route, - strlen( $resource_id ) ) === $resource_id; + if ( ! $is_singular ) { + $this->resource_identifier = $first_match[0]; + } + } + } + + /** + * Passes supported ID arguments (things like product_id, order_id, etc) that we should look for in addition to id. + * + * @param array $supported_ids List of supported IDs. + */ + public function set_supported_ids( $supported_ids = array() ) { + $this->supported_ids = $supported_ids; + } + + /** + * Returns an ID of supported ID arguments (things like product_id, order_id, etc) that we should look for in addition to id. + * + * @return array + */ + public function get_supported_ids() { + return $this->supported_ids; + } + + /** + * Create a new item. + * + * @subcommand create + * + * @param array $args WP-CLI positional arguments. + * @param array $assoc_args WP-CLI associative arguments. + */ + public function create_item( $args, $assoc_args ) { + $assoc_args = self::decode_json( $assoc_args ); + list( $status, $body ) = $this->do_request( 'POST', $this->get_filled_route( $args ), $assoc_args ); + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { + WP_CLI::line( $body['id'] ); + } else { + WP_CLI::success( "Created {$this->name} {$body['id']}." ); + } + } + + /** + * Delete an existing item. + * + * @subcommand delete + * + * @param array $args WP-CLI positional arguments. + * @param array $assoc_args WP-CLI associative arguments. + */ + public function delete_item( $args, $assoc_args ) { + list( $status, $body ) = $this->do_request( 'DELETE', $this->get_filled_route( $args ), $assoc_args ); + $object_id = isset( $body['id'] ) ? $body['id'] : ''; + if ( ! $object_id && isset( $body['slug'] ) ) { + $object_id = $body['slug']; + } + + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { + WP_CLI::line( $object_id ); + } else { + if ( empty( $assoc_args['force'] ) ) { + WP_CLI::success( __( 'Trashed', 'woocommerce' ) . " {$this->name} {$object_id}" ); + } else { + WP_CLI::success( __( 'Deleted', 'woocommerce' ) . " {$this->name} {$object_id}." ); + } + } + } + + /** + * Get a single item. + * + * @subcommand get + * + * @param array $args WP-CLI positional arguments. + * @param array $assoc_args WP-CLI associative arguments. + */ + public function get_item( $args, $assoc_args ) { + $route = $this->get_filled_route( $args ); + list( $status, $body, $headers ) = $this->do_request( 'GET', $route, $assoc_args ); + + if ( ! empty( $assoc_args['fields'] ) ) { + $body = self::limit_item_to_fields( $body, $assoc_args['fields'] ); + } + + if ( empty( $assoc_args['format'] ) ) { + $assoc_args['format'] = 'table'; + } + + if ( 'headers' === $assoc_args['format'] ) { + echo wp_json_encode( $headers ); + } elseif ( 'body' === $assoc_args['format'] ) { + echo wp_json_encode( $body ); + } elseif ( 'envelope' === $assoc_args['format'] ) { + echo wp_json_encode( + array( + 'body' => $body, + 'headers' => $headers, + 'status' => $status, + ) + ); + } else { + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_item( $body ); + } + } + + /** + * List all items. + * + * @subcommand list + * + * @param array $args WP-CLI positional arguments. + * @param array $assoc_args WP-CLI associative arguments. + */ + public function list_items( $args, $assoc_args ) { + if ( ! empty( $assoc_args['format'] ) && 'count' === $assoc_args['format'] ) { + $method = 'HEAD'; + } else { + $method = 'GET'; + } + + if ( ! isset( $assoc_args['per_page'] ) || empty( $assoc_args['per_page'] ) ) { + $assoc_args['per_page'] = '100'; + } + + list( $status, $body, $headers ) = $this->do_request( $method, $this->get_filled_route( $args ), $assoc_args ); + if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) { + $items = array_column( $body, 'id' ); + } else { + $items = $body; + } + + if ( ! empty( $assoc_args['fields'] ) ) { + foreach ( $items as $key => $item ) { + $items[ $key ] = self::limit_item_to_fields( $item, $assoc_args['fields'] ); + } + } + + if ( empty( $assoc_args['format'] ) ) { + $assoc_args['format'] = 'table'; + } + + if ( ! empty( $assoc_args['format'] ) && 'count' === $assoc_args['format'] ) { + echo (int) $headers['X-WP-Total']; + } elseif ( 'headers' === $assoc_args['format'] ) { + echo wp_json_encode( $headers ); + } elseif ( 'body' === $assoc_args['format'] ) { + echo wp_json_encode( $body ); + } elseif ( 'envelope' === $assoc_args['format'] ) { + echo wp_json_encode( + array( + 'body' => $body, + 'headers' => $headers, + 'status' => $status, + 'api_url' => $this->api_url, + ) + ); + } else { + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_items( $items ); + } + } + + /** + * Update an existing item. + * + * @subcommand update + * + * @param array $args WP-CLI positional arguments. + * @param array $assoc_args WP-CLI associative arguments. + */ + public function update_item( $args, $assoc_args ) { + $assoc_args = self::decode_json( $assoc_args ); + list( $status, $body ) = $this->do_request( 'POST', $this->get_filled_route( $args ), $assoc_args ); + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { + WP_CLI::line( $body['id'] ); + } else { + WP_CLI::success( __( 'Updated', 'woocommerce' ) . " {$this->name} {$body['id']}." ); + } + } + + /** + * Do a REST Request + * + * @param string $method Request method. Examples: 'POST', 'PUT', 'DELETE' or 'GET'. + * @param string $route Resource route. + * @param array $assoc_args Associative arguments passed to the originating WP-CLI command. + * + * @return array + */ + private function do_request( $method, $route, $assoc_args ) { + wc_maybe_define_constant( 'REST_REQUEST', true ); + + $request = new WP_REST_Request( $method, $route ); + if ( in_array( $method, array( 'POST', 'PUT' ), true ) ) { + $request->set_body_params( $assoc_args ); + } else { + foreach ( $assoc_args as $key => $value ) { + $request->set_param( $key, $value ); + } + } + if ( Constants::is_true( 'SAVEQUERIES' ) ) { + $original_queries = is_array( $GLOBALS['wpdb']->queries ) ? array_keys( $GLOBALS['wpdb']->queries ) : array(); + } + $response = rest_do_request( $request ); + if ( Constants::is_true( 'SAVEQUERIES' ) ) { + $performed_queries = array(); + foreach ( (array) $GLOBALS['wpdb']->queries as $key => $query ) { + if ( in_array( $key, $original_queries, true ) ) { + continue; + } + $performed_queries[] = $query; + } + usort( + $performed_queries, + function( $a, $b ) { + if ( $a[1] === $b[1] ) { + return 0; + } + return ( $a[1] > $b[1] ) ? -1 : 1; + } + ); + + $query_count = count( $performed_queries ); + $query_total_time = 0; + foreach ( $performed_queries as $query ) { + $query_total_time += $query[1]; + } + $slow_query_message = ''; + if ( $performed_queries && 'wc' === WP_CLI::get_config( 'debug' ) ) { + $slow_query_message .= '. Ordered by slowness, the queries are:' . PHP_EOL; + foreach ( $performed_queries as $i => $query ) { + $i++; + $bits = explode( ', ', $query[2] ); + $backtrace = implode( ', ', array_slice( $bits, 13 ) ); + $seconds = NumberUtil::round( $query[1], 6 ); + $slow_query_message .= <<as_error(); + + if ( $error ) { + // For authentication errors (status 401), include a reminder to set the --user flag. + // WP_CLI::error will only return the first message from WP_Error, so we will pass a string containing both instead. + if ( 401 === $response->get_status() ) { + $errors = $error->get_error_messages(); + $errors[] = __( 'Make sure to include the --user flag with an account that has permissions for this action.', 'woocommerce' ) . ' {"status":401}'; + $error = implode( "\n", $errors ); + } + WP_CLI::error( $error ); + } + return array( $response->get_status(), $response->get_data(), $response->get_headers() ); + } + + /** + * Get Formatter object based on supplied parameters. + * + * @param array $assoc_args Parameters passed to command. Determines formatting. + * @return \WP_CLI\Formatter + */ + protected function get_formatter( &$assoc_args ) { + if ( ! empty( $assoc_args['fields'] ) ) { + if ( is_string( $assoc_args['fields'] ) ) { + $fields = explode( ',', $assoc_args['fields'] ); + } else { + $fields = $assoc_args['fields']; + } + } else { + if ( ! empty( $assoc_args['context'] ) ) { + $fields = $this->get_context_fields( $assoc_args['context'] ); + } else { + $fields = $this->get_context_fields( 'view' ); + } + } + return new \WP_CLI\Formatter( $assoc_args, $fields ); + } + + /** + * Get a list of fields present in a given context + * + * @param string $context Scope under which the request is made. Determines fields present in response. + * @return array + */ + private function get_context_fields( $context ) { + $fields = array(); + foreach ( $this->schema['properties'] as $key => $args ) { + if ( empty( $args['context'] ) || in_array( $context, $args['context'], true ) ) { + $fields[] = $key; + } + } + return $fields; + } + + /** + * Get the route for this resource + * + * @param array $args Positional arguments passed to the originating WP-CLI command. + * @return string + */ + private function get_filled_route( $args = array() ) { + $supported_id_matched = false; + $route = $this->route; + + foreach ( $this->get_supported_ids() as $id_name => $id_desc ) { + if ( 'id' !== $id_name && strpos( $route, '<' . $id_name . '>' ) !== false && ! empty( $args ) ) { + $route = str_replace( array( '(?P<' . $id_name . '>[\d]+)', '(?P<' . $id_name . '>\w[\w\s\-]*)' ), $args[0], $route ); + $supported_id_matched = true; + } + } + + if ( ! empty( $args ) ) { + $id_replacement = $supported_id_matched && ! empty( $args[1] ) ? $args[1] : $args[0]; + $route = str_replace( array( '(?P[\d]+)', '(?P[\w-]+)' ), $id_replacement, $route ); + } + + return rtrim( $route ); + } + + /** + * Reduce an item to specific fields. + * + * @param array $item Item to reduce. + * @param array $fields Fields to keep. + * @return array + */ + private static function limit_item_to_fields( $item, $fields ) { + if ( empty( $fields ) ) { + return $item; + } + if ( is_string( $fields ) ) { + $fields = explode( ',', $fields ); + } + foreach ( $item as $i => $field ) { + if ( ! in_array( $i, $fields, true ) ) { + unset( $item[ $i ] ); + } + } + return $item; + } + + /** + * JSON can be passed in some more complicated objects, like the payment gateway settings array. + * This function decodes the json (if present) and tries to get it's value. + * + * @param array $arr Array that will be scanned for JSON encoded values. + * + * @return array + */ + protected function decode_json( $arr ) { + foreach ( $arr as $key => $value ) { + if ( '[' === substr( $value, 0, 1 ) || '{' === substr( $value, 0, 1 ) ) { + $arr[ $key ] = json_decode( $value, true ); + } else { + continue; + } + } + return $arr; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-runner.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-runner.php new file mode 100644 index 0000000..0804fb9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-runner.php @@ -0,0 +1,254 @@ +[\w-]+)', + 'settings/(?P[\w-]+)/batch', + 'settings/(?P[\w-]+)/(?P[\w-]+)', + 'system_status', + 'system_status/tools', + 'system_status/tools/(?P[\w-]+)', + 'reports', + 'reports/sales', + 'reports/top_sellers', + ); + + /** + * The version of the REST API we should target to + * generate commands. + * + * @var string + */ + private static $target_rest_version = 'v2'; + + /** + * Register's all endpoints as commands once WP and WC have all loaded. + */ + public static function after_wp_load() { + global $wp_rest_server; + $wp_rest_server = new WP_REST_Server(); + do_action( 'rest_api_init', $wp_rest_server ); + + $request = new WP_REST_Request( 'GET', '/' ); + $request->set_param( 'context', 'help' ); + $response = $wp_rest_server->dispatch( $request ); + $response_data = $response->get_data(); + if ( empty( $response_data ) ) { + return; + } + + // Loop through all of our endpoints and register any valid WC endpoints. + foreach ( $response_data['routes'] as $route => $route_data ) { + // Only register endpoints for WC and our target version. + if ( substr( $route, 0, 4 + strlen( self::$target_rest_version ) ) !== '/wc/' . self::$target_rest_version ) { + continue; + } + + // Only register endpoints with schemas. + if ( empty( $route_data['schema']['title'] ) ) { + /* translators: %s: Route to a given WC-API endpoint */ + WP_CLI::debug( sprintf( __( 'No schema title found for %s, skipping REST command registration.', 'woocommerce' ), $route ), 'wc' ); + continue; + } + // Ignore batch endpoints. + if ( 'batch' === $route_data['schema']['title'] ) { + continue; + } + // Disable specific endpoints. + $route_pieces = explode( '/', $route ); + $endpoint_piece = str_replace( '/wc/' . $route_pieces[2] . '/', '', $route ); + if ( in_array( $endpoint_piece, self::$disabled_endpoints, true ) ) { + continue; + } + + self::register_route_commands( new WC_CLI_REST_Command( $route_data['schema']['title'], $route, $route_data['schema'] ), $route, $route_data ); + } + } + + /** + * Generates command information and tells WP CLI about all + * commands available from a route. + * + * @param string $rest_command WC-API command. + * @param string $route Path to route endpoint. + * @param array $route_data Command data. + * @param array $command_args WP-CLI command arguments. + */ + private static function register_route_commands( $rest_command, $route, $route_data, $command_args = array() ) { + // Define IDs that we are looking for in the routes (in addition to id) + // so that we can pass it to the rest command, and use it here to generate documentation. + $supported_ids = array( + 'product_id' => __( 'Product ID.', 'woocommerce' ), + 'customer_id' => __( 'Customer ID.', 'woocommerce' ), + 'order_id' => __( 'Order ID.', 'woocommerce' ), + 'refund_id' => __( 'Refund ID.', 'woocommerce' ), + 'attribute_id' => __( 'Attribute ID.', 'woocommerce' ), + 'zone_id' => __( 'Zone ID.', 'woocommerce' ), + 'instance_id' => __( 'Instance ID.', 'woocommerce' ), + 'id' => __( 'The ID for the resource.', 'woocommerce' ), + 'slug' => __( 'The slug for the resource.', 'woocommerce' ), + ); + $rest_command->set_supported_ids( $supported_ids ); + $positional_args = array_keys( $supported_ids ); + $parent = "wc {$route_data['schema']['title']}"; + $supported_commands = array(); + + // Get a list of supported commands for each route. + foreach ( $route_data['endpoints'] as $endpoint ) { + preg_match_all( '#\([^\)]+\)#', $route, $matches ); + $resource_id = ! empty( $matches[0] ) ? array_pop( $matches[0] ) : null; + $trimmed_route = rtrim( $route ); + $is_singular = substr( $trimmed_route, - strlen( $resource_id ) ) === $resource_id; + + // List a collection. + if ( array( 'GET' ) === $endpoint['methods'] && ! $is_singular ) { + $supported_commands['list'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array(); + } + // Create a specific resource. + if ( array( 'POST' ) === $endpoint['methods'] && ! $is_singular ) { + $supported_commands['create'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array(); + } + // Get a specific resource. + if ( array( 'GET' ) === $endpoint['methods'] && $is_singular ) { + $supported_commands['get'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array(); + } + // Update a specific resource. + if ( in_array( 'POST', $endpoint['methods'], true ) && $is_singular ) { + $supported_commands['update'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array(); + } + // Delete a specific resource. + if ( array( 'DELETE' ) === $endpoint['methods'] && $is_singular ) { + $supported_commands['delete'] = ! empty( $endpoint['args'] ) ? $endpoint['args'] : array(); + } + } + + foreach ( $supported_commands as $command => $endpoint_args ) { + $synopsis = array(); + $arg_regs = array(); + $ids = array(); + + foreach ( $supported_ids as $id_name => $id_desc ) { + if ( strpos( $route, '<' . $id_name . '>' ) !== false ) { + $synopsis[] = array( + 'name' => $id_name, + 'type' => 'positional', + 'description' => $id_desc, + 'optional' => false, + ); + $ids[] = $id_name; + } + } + + foreach ( $endpoint_args as $name => $args ) { + if ( ! in_array( $name, $positional_args, true ) || strpos( $route, '<' . $id_name . '>' ) === false ) { + $arg_regs[] = array( + 'name' => $name, + 'type' => 'assoc', + 'description' => ! empty( $args['description'] ) ? $args['description'] : '', + 'optional' => empty( $args['required'] ), + ); + } + } + + foreach ( $arg_regs as $arg_reg ) { + $synopsis[] = $arg_reg; + } + + if ( in_array( $command, array( 'list', 'get' ), true ) ) { + $synopsis[] = array( + 'name' => 'fields', + 'type' => 'assoc', + 'description' => __( 'Limit response to specific fields. Defaults to all fields.', 'woocommerce' ), + 'optional' => true, + ); + $synopsis[] = array( + 'name' => 'field', + 'type' => 'assoc', + 'description' => __( 'Get the value of an individual field.', 'woocommerce' ), + 'optional' => true, + ); + $synopsis[] = array( + 'name' => 'format', + 'type' => 'assoc', + 'description' => __( 'Render response in a particular format.', 'woocommerce' ), + 'optional' => true, + 'default' => 'table', + 'options' => array( + 'table', + 'json', + 'csv', + 'ids', + 'yaml', + 'count', + 'headers', + 'body', + 'envelope', + ), + ); + } + + if ( in_array( $command, array( 'create', 'update', 'delete' ), true ) ) { + $synopsis[] = array( + 'name' => 'porcelain', + 'type' => 'flag', + 'description' => __( 'Output just the id when the operation is successful.', 'woocommerce' ), + 'optional' => true, + ); + } + + $methods = array( + 'list' => 'list_items', + 'create' => 'create_item', + 'delete' => 'delete_item', + 'get' => 'get_item', + 'update' => 'update_item', + ); + + $before_invoke = null; + if ( empty( $command_args['when'] ) && \WP_CLI::get_config( 'debug' ) ) { + $before_invoke = function() { + wc_maybe_define_constant( 'SAVEQUERIES', true ); + }; + } + + WP_CLI::add_command( + "{$parent} {$command}", + array( $rest_command, $methods[ $command ] ), + array( + 'synopsis' => $synopsis, + 'when' => ! empty( $command_args['when'] ) ? $command_args['when'] : '', + 'before_invoke' => $before_invoke, + ) + ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-tool-command.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-tool-command.php new file mode 100644 index 0000000..d2d3bd1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-tool-command.php @@ -0,0 +1,107 @@ +dispatch( $request ); + $response_data = $response->get_data(); + if ( empty( $response_data ) ) { + return; + } + + $parent = 'wc tool'; + $supported_commands = array( 'list', 'run' ); + foreach ( $supported_commands as $command ) { + $synopsis = array(); + if ( 'run' === $command ) { + $synopsis[] = array( + 'name' => 'id', + 'type' => 'positional', + 'description' => __( 'The id for the resource.', 'woocommerce' ), + 'optional' => false, + ); + $method = 'update_item'; + $route = '/wc/v2/system_status/tools/(?P[\w-]+)'; + } elseif ( 'list' === $command ) { + $synopsis[] = array( + 'name' => 'fields', + 'type' => 'assoc', + 'description' => __( 'Limit response to specific fields. Defaults to all fields.', 'woocommerce' ), + 'optional' => true, + ); + $synopsis[] = array( + 'name' => 'field', + 'type' => 'assoc', + 'description' => __( 'Get the value of an individual field.', 'woocommerce' ), + 'optional' => true, + ); + $synopsis[] = array( + 'name' => 'format', + 'type' => 'assoc', + 'description' => __( 'Render response in a particular format.', 'woocommerce' ), + 'optional' => true, + 'default' => 'table', + 'options' => array( + 'table', + 'json', + 'csv', + 'ids', + 'yaml', + 'count', + 'headers', + 'body', + 'envelope', + ), + ); + $method = 'list_items'; + $route = '/wc/v2/system_status/tools'; + } + + $before_invoke = null; + if ( empty( $command_args['when'] ) && WP_CLI::get_config( 'debug' ) ) { + $before_invoke = function() { + wc_maybe_define_constant( 'SAVEQUERIES', true ); + }; + } + + $rest_command = new WC_CLI_REST_Command( 'system_status_tool', $route, $response_data['schema'] ); + + WP_CLI::add_command( + "{$parent} {$command}", + array( $rest_command, $method ), + array( + 'synopsis' => $synopsis, + 'when' => ! empty( $command_args['when'] ) ? $command_args['when'] : '', + 'before_invoke' => $before_invoke, + ) + ); + } + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-update-command.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-update-command.php new file mode 100644 index 0000000..25473b0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/cli/class-wc-cli-update-command.php @@ -0,0 +1,81 @@ +hide_errors(); + + include_once WC_ABSPATH . 'includes/class-wc-install.php'; + include_once WC_ABSPATH . 'includes/wc-update-functions.php'; + + $current_db_version = get_option( 'woocommerce_db_version' ); + $update_count = 0; + $callbacks = WC_Install::get_db_update_callbacks(); + $callbacks_to_run = array(); + + foreach ( $callbacks as $version => $update_callbacks ) { + if ( version_compare( $current_db_version, $version, '<' ) ) { + foreach ( $update_callbacks as $update_callback ) { + $callbacks_to_run[] = $update_callback; + } + } + } + + if ( empty( $callbacks_to_run ) ) { + // Ensure DB version is set to the current WC version to match WP-Admin update routine. + WC_Install::update_db_version(); + /* translators: %s Database version number */ + WP_CLI::success( sprintf( __( 'No updates required. Database version is %s', 'woocommerce' ), get_option( 'woocommerce_db_version' ) ) ); + return; + } + + /* translators: 1: Number of database updates 2: List of update callbacks */ + WP_CLI::log( sprintf( __( 'Found %1$d updates (%2$s)', 'woocommerce' ), count( $callbacks_to_run ), implode( ', ', $callbacks_to_run ) ) ); + + $progress = \WP_CLI\Utils\make_progress_bar( __( 'Updating database', 'woocommerce' ), count( $callbacks_to_run ) ); // phpcs:ignore PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound + + foreach ( $callbacks_to_run as $update_callback ) { + call_user_func( $update_callback ); + $result = false; + while ( $result ) { + $result = (bool) call_user_func( $update_callback ); + } + $update_count ++; + $progress->tick(); + } + + $progress->finish(); + + WC_Admin_Notices::remove_notice( 'update', true ); + + /* translators: 1: Number of database updates performed 2: Database version number */ + WP_CLI::success( sprintf( __( '%1$d update functions completed. Database version is %2$s', 'woocommerce' ), absint( $update_count ), get_option( 'woocommerce_db_version' ) ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/customizer/class-wc-customizer-control-cropping.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/customizer/class-wc-customizer-control-cropping.php new file mode 100644 index 0000000..675f698 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/customizer/class-wc-customizer-control-cropping.php @@ -0,0 +1,64 @@ +choices ) ) { + return; + } + + $value = $this->value( 'cropping' ); + $custom_width = $this->value( 'custom_width' ); + $custom_height = $this->value( 'custom_height' ); + ?> + + + label ); ?> + + + description ) ) : ?> + description ); ?> + + +
      + choices as $key => $radio ) : ?> +
    • + link( 'cropping' ); ?> /> + + + + + link( 'custom_width' ); ?> /> : link( 'custom_height' ); ?> /> + + +
    • + +
    + add_panel( + 'woocommerce', + array( + 'priority' => 200, + 'capability' => 'manage_woocommerce', + 'theme_supports' => '', + 'title' => __( 'WooCommerce', 'woocommerce' ), + ) + ); + + $this->add_store_notice_section( $wp_customize ); + $this->add_product_catalog_section( $wp_customize ); + $this->add_product_images_section( $wp_customize ); + $this->add_checkout_section( $wp_customize ); + } + + /** + * Frontend CSS styles. + */ + public function add_frontend_scripts() { + if ( ! is_customize_preview() || ! is_store_notice_showing() ) { + return; + } + + $css = '.woocommerce-store-notice, p.demo_store { display: block !important; }'; + wp_add_inline_style( 'customize-preview', $css ); + } + + /** + * CSS styles to improve our form. + */ + public function add_styles() { + ?> + + + + __( 'Default sorting (custom ordering + name)', 'woocommerce' ), + 'popularity' => __( 'Popularity (sales)', 'woocommerce' ), + 'rating' => __( 'Average rating', 'woocommerce' ), + 'date' => __( 'Sort by most recent', 'woocommerce' ), + 'price' => __( 'Sort by price (asc)', 'woocommerce' ), + 'price-desc' => __( 'Sort by price (desc)', 'woocommerce' ), + ) + ); + + return array_key_exists( $value, $options ) ? $value : 'menu_order'; + } + + /** + * Store notice section. + * + * @param WP_Customize_Manager $wp_customize Theme Customizer object. + */ + private function add_store_notice_section( $wp_customize ) { + $wp_customize->add_section( + 'woocommerce_store_notice', + array( + 'title' => __( 'Store Notice', 'woocommerce' ), + 'priority' => 10, + 'panel' => 'woocommerce', + ) + ); + + $wp_customize->add_setting( + 'woocommerce_demo_store', + array( + 'default' => 'no', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'wc_bool_to_string', + 'sanitize_js_callback' => 'wc_string_to_bool', + ) + ); + + $wp_customize->add_setting( + 'woocommerce_demo_store_notice', + array( + 'default' => __( 'This is a demo store for testing purposes — no orders shall be fulfilled.', 'woocommerce' ), + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'wp_kses_post', + 'transport' => 'postMessage', + ) + ); + + $wp_customize->add_control( + 'woocommerce_demo_store_notice', + array( + 'label' => __( 'Store notice', 'woocommerce' ), + 'description' => __( 'If enabled, this text will be shown site-wide. You can use it to show events or promotions to visitors!', 'woocommerce' ), + 'section' => 'woocommerce_store_notice', + 'settings' => 'woocommerce_demo_store_notice', + 'type' => 'textarea', + ) + ); + + $wp_customize->add_control( + 'woocommerce_demo_store', + array( + 'label' => __( 'Enable store notice', 'woocommerce' ), + 'section' => 'woocommerce_store_notice', + 'settings' => 'woocommerce_demo_store', + 'type' => 'checkbox', + ) + ); + + if ( isset( $wp_customize->selective_refresh ) ) { + $wp_customize->selective_refresh->add_partial( + 'woocommerce_demo_store_notice', + array( + 'selector' => '.woocommerce-store-notice', + 'container_inclusive' => true, + 'render_callback' => 'woocommerce_demo_store', + ) + ); + } + } + + /** + * Product catalog section. + * + * @param WP_Customize_Manager $wp_customize Theme Customizer object. + */ + public function add_product_catalog_section( $wp_customize ) { + $wp_customize->add_section( + 'woocommerce_product_catalog', + array( + 'title' => __( 'Product Catalog', 'woocommerce' ), + 'priority' => 10, + 'panel' => 'woocommerce', + ) + ); + + $wp_customize->add_setting( + 'woocommerce_shop_page_display', + array( + 'default' => '', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => array( $this, 'sanitize_archive_display' ), + ) + ); + + $wp_customize->add_control( + 'woocommerce_shop_page_display', + array( + 'label' => __( 'Shop page display', 'woocommerce' ), + 'description' => __( 'Choose what to display on the main shop page.', 'woocommerce' ), + 'section' => 'woocommerce_product_catalog', + 'settings' => 'woocommerce_shop_page_display', + 'type' => 'select', + 'choices' => array( + '' => __( 'Show products', 'woocommerce' ), + 'subcategories' => __( 'Show categories', 'woocommerce' ), + 'both' => __( 'Show categories & products', 'woocommerce' ), + ), + ) + ); + + $wp_customize->add_setting( + 'woocommerce_category_archive_display', + array( + 'default' => '', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => array( $this, 'sanitize_archive_display' ), + ) + ); + + $wp_customize->add_control( + 'woocommerce_category_archive_display', + array( + 'label' => __( 'Category display', 'woocommerce' ), + 'description' => __( 'Choose what to display on product category pages.', 'woocommerce' ), + 'section' => 'woocommerce_product_catalog', + 'settings' => 'woocommerce_category_archive_display', + 'type' => 'select', + 'choices' => array( + '' => __( 'Show products', 'woocommerce' ), + 'subcategories' => __( 'Show subcategories', 'woocommerce' ), + 'both' => __( 'Show subcategories & products', 'woocommerce' ), + ), + ) + ); + + $wp_customize->add_setting( + 'woocommerce_default_catalog_orderby', + array( + 'default' => 'menu_order', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => array( $this, 'sanitize_default_catalog_orderby' ), + ) + ); + + $wp_customize->add_control( + 'woocommerce_default_catalog_orderby', + array( + 'label' => __( 'Default product sorting', 'woocommerce' ), + 'description' => __( 'How should products be sorted in the catalog by default?', 'woocommerce' ), + 'section' => 'woocommerce_product_catalog', + 'settings' => 'woocommerce_default_catalog_orderby', + 'type' => 'select', + 'choices' => apply_filters( + 'woocommerce_default_catalog_orderby_options', + array( + 'menu_order' => __( 'Default sorting (custom ordering + name)', 'woocommerce' ), + 'popularity' => __( 'Popularity (sales)', 'woocommerce' ), + 'rating' => __( 'Average rating', 'woocommerce' ), + 'date' => __( 'Sort by most recent', 'woocommerce' ), + 'price' => __( 'Sort by price (asc)', 'woocommerce' ), + 'price-desc' => __( 'Sort by price (desc)', 'woocommerce' ), + ) + ), + ) + ); + + // The following settings should be hidden if the theme is declaring the values. + if ( has_filter( 'loop_shop_columns' ) ) { + return; + } + + $wp_customize->add_setting( + 'woocommerce_catalog_columns', + array( + 'default' => 4, + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'absint', + 'sanitize_js_callback' => 'absint', + ) + ); + + $wp_customize->add_control( + 'woocommerce_catalog_columns', + array( + 'label' => __( 'Products per row', 'woocommerce' ), + 'description' => __( 'How many products should be shown per row?', 'woocommerce' ), + 'section' => 'woocommerce_product_catalog', + 'settings' => 'woocommerce_catalog_columns', + 'type' => 'number', + 'input_attrs' => array( + 'min' => wc_get_theme_support( 'product_grid::min_columns', 1 ), + 'max' => wc_get_theme_support( 'product_grid::max_columns', '' ), + 'step' => 1, + ), + ) + ); + + // Only add this setting if something else isn't managing the number of products per page. + if ( ! has_filter( 'loop_shop_per_page' ) ) { + $wp_customize->add_setting( + 'woocommerce_catalog_rows', + array( + 'default' => 4, + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'absint', + 'sanitize_js_callback' => 'absint', + ) + ); + } + + $wp_customize->add_control( + 'woocommerce_catalog_rows', + array( + 'label' => __( 'Rows per page', 'woocommerce' ), + 'description' => __( 'How many rows of products should be shown per page?', 'woocommerce' ), + 'section' => 'woocommerce_product_catalog', + 'settings' => 'woocommerce_catalog_rows', + 'type' => 'number', + 'input_attrs' => array( + 'min' => wc_get_theme_support( 'product_grid::min_rows', 1 ), + 'max' => wc_get_theme_support( 'product_grid::max_rows', '' ), + 'step' => 1, + ), + ) + ); + } + + /** + * Product images section. + * + * @param WP_Customize_Manager $wp_customize Theme Customizer object. + */ + private function add_product_images_section( $wp_customize ) { + if ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) { + $regen_description = ''; // Nothing to report; Jetpack will handle magically. + } elseif ( apply_filters( 'woocommerce_background_image_regeneration', true ) && ! is_multisite() ) { + $regen_description = __( 'After publishing your changes, new image sizes will be generated automatically.', 'woocommerce' ); + } elseif ( apply_filters( 'woocommerce_background_image_regeneration', true ) && is_multisite() ) { + /* translators: 1: tools URL 2: regen thumbs url */ + $regen_description = sprintf( __( 'After publishing your changes, new image sizes may not be shown until you regenerate thumbnails. You can do this from the tools section in WooCommerce or by using a plugin such as Regenerate Thumbnails.', 'woocommerce' ), admin_url( 'admin.php?page=wc-status&tab=tools' ), 'https://en-gb.wordpress.org/plugins/regenerate-thumbnails/' ); + } else { + /* translators: %s: regen thumbs url */ + $regen_description = sprintf( __( 'After publishing your changes, new image sizes may not be shown until you Regenerate Thumbnails.', 'woocommerce' ), 'https://en-gb.wordpress.org/plugins/regenerate-thumbnails/' ); + } + + $wp_customize->add_section( + 'woocommerce_product_images', + array( + 'title' => __( 'Product Images', 'woocommerce' ), + 'description' => $regen_description, + 'priority' => 20, + 'panel' => 'woocommerce', + ) + ); + + if ( ! wc_get_theme_support( 'single_image_width' ) ) { + $wp_customize->add_setting( + 'woocommerce_single_image_width', + array( + 'default' => 600, + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'absint', + 'sanitize_js_callback' => 'absint', + ) + ); + + $wp_customize->add_control( + 'woocommerce_single_image_width', + array( + 'label' => __( 'Main image width', 'woocommerce' ), + 'description' => __( 'Image size used for the main image on single product pages. These images will remain uncropped.', 'woocommerce' ), + 'section' => 'woocommerce_product_images', + 'settings' => 'woocommerce_single_image_width', + 'type' => 'number', + 'input_attrs' => array( + 'min' => 0, + 'step' => 1, + ), + ) + ); + } + + if ( ! wc_get_theme_support( 'thumbnail_image_width' ) ) { + $wp_customize->add_setting( + 'woocommerce_thumbnail_image_width', + array( + 'default' => 300, + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'absint', + 'sanitize_js_callback' => 'absint', + ) + ); + + $wp_customize->add_control( + 'woocommerce_thumbnail_image_width', + array( + 'label' => __( 'Thumbnail width', 'woocommerce' ), + 'description' => __( 'Image size used for products in the catalog.', 'woocommerce' ), + 'section' => 'woocommerce_product_images', + 'settings' => 'woocommerce_thumbnail_image_width', + 'type' => 'number', + 'input_attrs' => array( + 'min' => 0, + 'step' => 1, + ), + ) + ); + } + + include_once WC_ABSPATH . 'includes/customizer/class-wc-customizer-control-cropping.php'; + + $wp_customize->add_setting( + 'woocommerce_thumbnail_cropping', + array( + 'default' => '1:1', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'wc_clean', + ) + ); + + $wp_customize->add_setting( + 'woocommerce_thumbnail_cropping_custom_width', + array( + 'default' => '4', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'absint', + 'sanitize_js_callback' => 'absint', + ) + ); + + $wp_customize->add_setting( + 'woocommerce_thumbnail_cropping_custom_height', + array( + 'default' => '3', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'absint', + 'sanitize_js_callback' => 'absint', + ) + ); + + $wp_customize->add_control( + new WC_Customizer_Control_Cropping( + $wp_customize, + 'woocommerce_thumbnail_cropping', + array( + 'section' => 'woocommerce_product_images', + 'settings' => array( + 'cropping' => 'woocommerce_thumbnail_cropping', + 'custom_width' => 'woocommerce_thumbnail_cropping_custom_width', + 'custom_height' => 'woocommerce_thumbnail_cropping_custom_height', + ), + 'label' => __( 'Thumbnail cropping', 'woocommerce' ), + 'choices' => array( + '1:1' => array( + 'label' => __( '1:1', 'woocommerce' ), + 'description' => __( 'Images will be cropped into a square', 'woocommerce' ), + ), + 'custom' => array( + 'label' => __( 'Custom', 'woocommerce' ), + 'description' => __( 'Images will be cropped to a custom aspect ratio', 'woocommerce' ), + ), + 'uncropped' => array( + 'label' => __( 'Uncropped', 'woocommerce' ), + 'description' => __( 'Images will display using the aspect ratio in which they were uploaded', 'woocommerce' ), + ), + ), + ) + ) + ); + } + + /** + * Checkout section. + * + * @param WP_Customize_Manager $wp_customize Theme Customizer object. + */ + public function add_checkout_section( $wp_customize ) { + $wp_customize->add_section( + 'woocommerce_checkout', + array( + 'title' => __( 'Checkout', 'woocommerce' ), + 'priority' => 20, + 'panel' => 'woocommerce', + 'description' => __( 'These options let you change the appearance of the WooCommerce checkout.', 'woocommerce' ), + ) + ); + + // Checkout field controls. + $fields = array( + 'company' => __( 'Company name', 'woocommerce' ), + 'address_2' => __( 'Address line 2', 'woocommerce' ), + 'phone' => __( 'Phone', 'woocommerce' ), + ); + foreach ( $fields as $field => $label ) { + $wp_customize->add_setting( + 'woocommerce_checkout_' . $field . '_field', + array( + 'default' => 'phone' === $field ? 'required' : 'optional', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => array( $this, 'sanitize_checkout_field_display' ), + ) + ); + $wp_customize->add_control( + 'woocommerce_checkout_' . $field . '_field', + array( + /* Translators: %s field name. */ + 'label' => sprintf( __( '%s field', 'woocommerce' ), $label ), + 'section' => 'woocommerce_checkout', + 'settings' => 'woocommerce_checkout_' . $field . '_field', + 'type' => 'select', + 'choices' => array( + 'hidden' => __( 'Hidden', 'woocommerce' ), + 'optional' => __( 'Optional', 'woocommerce' ), + 'required' => __( 'Required', 'woocommerce' ), + ), + ) + ); + } + + // Register settings. + $wp_customize->add_setting( + 'woocommerce_checkout_highlight_required_fields', + array( + 'default' => 'yes', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'wc_bool_to_string', + 'sanitize_js_callback' => 'wc_string_to_bool', + ) + ); + + $wp_customize->add_setting( + 'woocommerce_checkout_terms_and_conditions_checkbox_text', + array( + /* translators: %s terms and conditions page name and link */ + 'default' => sprintf( __( 'I have read and agree to the website %s', 'woocommerce' ), '[terms]' ), + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'wp_kses_post', + 'transport' => 'postMessage', + ) + ); + + $wp_customize->add_setting( + 'woocommerce_checkout_privacy_policy_text', + array( + /* translators: %s privacy policy page name and link */ + 'default' => sprintf( __( 'Your personal data will be used to process your order, support your experience throughout this website, and for other purposes described in our %s.', 'woocommerce' ), '[privacy_policy]' ), + 'type' => 'option', + 'capability' => 'manage_woocommerce', + 'sanitize_callback' => 'wp_kses_post', + 'transport' => 'postMessage', + ) + ); + + // Register controls. + $wp_customize->add_control( + 'woocommerce_checkout_highlight_required_fields', + array( + 'label' => __( 'Highlight required fields with an asterisk', 'woocommerce' ), + 'section' => 'woocommerce_checkout', + 'settings' => 'woocommerce_checkout_highlight_required_fields', + 'type' => 'checkbox', + ) + ); + + if ( current_user_can( 'manage_privacy_options' ) ) { + $choose_pages = array( + 'wp_page_for_privacy_policy' => __( 'Privacy policy', 'woocommerce' ), + 'woocommerce_terms_page_id' => __( 'Terms and conditions', 'woocommerce' ), + ); + } else { + $choose_pages = array( + 'woocommerce_terms_page_id' => __( 'Terms and conditions', 'woocommerce' ), + ); + } + $pages = get_pages( + array( + 'post_type' => 'page', + 'post_status' => 'publish,private,draft', + 'child_of' => 0, + 'parent' => -1, + 'exclude' => array( + wc_get_page_id( 'cart' ), + wc_get_page_id( 'checkout' ), + wc_get_page_id( 'myaccount' ), + ), + 'sort_order' => 'asc', + 'sort_column' => 'post_title', + ) + ); + $page_choices = array( '' => __( 'No page set', 'woocommerce' ) ) + array_combine( array_map( 'strval', wp_list_pluck( $pages, 'ID' ) ), wp_list_pluck( $pages, 'post_title' ) ); + + foreach ( $choose_pages as $id => $name ) { + $wp_customize->add_setting( + $id, + array( + 'default' => '', + 'type' => 'option', + 'capability' => 'manage_woocommerce', + ) + ); + $wp_customize->add_control( + $id, + array( + /* Translators: %s: page name. */ + 'label' => sprintf( __( '%s page', 'woocommerce' ), $name ), + 'section' => 'woocommerce_checkout', + 'settings' => $id, + 'type' => 'select', + 'choices' => $page_choices, + ) + ); + } + + $wp_customize->add_control( + 'woocommerce_checkout_privacy_policy_text', + array( + 'label' => __( 'Privacy policy', 'woocommerce' ), + 'description' => __( 'Optionally add some text about your store privacy policy to show during checkout.', 'woocommerce' ), + 'section' => 'woocommerce_checkout', + 'settings' => 'woocommerce_checkout_privacy_policy_text', + 'active_callback' => 'wc_privacy_policy_page_id', + 'type' => 'textarea', + ) + ); + + $wp_customize->add_control( + 'woocommerce_checkout_terms_and_conditions_checkbox_text', + array( + 'label' => __( 'Terms and conditions', 'woocommerce' ), + 'description' => __( 'Optionally add some text for the terms checkbox that customers must accept.', 'woocommerce' ), + 'section' => 'woocommerce_checkout', + 'settings' => 'woocommerce_checkout_terms_and_conditions_checkbox_text', + 'active_callback' => 'wc_terms_and_conditions_page_id', + 'type' => 'text', + ) + ); + + if ( isset( $wp_customize->selective_refresh ) ) { + $wp_customize->selective_refresh->add_partial( + 'woocommerce_checkout_privacy_policy_text', + array( + 'selector' => '.woocommerce-privacy-policy-text', + 'container_inclusive' => true, + 'render_callback' => 'wc_checkout_privacy_policy_text', + ) + ); + $wp_customize->selective_refresh->add_partial( + 'woocommerce_checkout_terms_and_conditions_checkbox_text', + array( + 'selector' => '.woocommerce-terms-and-conditions-checkbox-text', + 'container_inclusive' => false, + 'render_callback' => 'wc_terms_and_conditions_checkbox_text', + ) + ); + } + } + + /** + * Sanitize field display. + * + * @param string $value '', 'subcategories', or 'both'. + * @return string + */ + public function sanitize_checkout_field_display( $value ) { + $options = array( 'hidden', 'optional', 'required' ); + return in_array( $value, $options, true ) ? $value : ''; + } +} + +new WC_Shop_Customizer(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php new file mode 100644 index 0000000..4081bbe --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php @@ -0,0 +1,439 @@ +set_version( Constants::get_constant( 'WC_VERSION' ) ); + $order->set_currency( $order->get_currency() ? $order->get_currency() : get_woocommerce_currency() ); + if ( ! $order->get_date_created( 'edit' ) ) { + $order->set_date_created( time() ); + } + + $id = wp_insert_post( + apply_filters( + 'woocommerce_new_order_data', + array( + 'post_date' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getOffsetTimestamp() ), + 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getTimestamp() ), + 'post_type' => $order->get_type( 'edit' ), + 'post_status' => $this->get_post_status( $order ), + 'ping_status' => 'closed', + 'post_author' => 1, + 'post_title' => $this->get_post_title(), + 'post_password' => $this->get_order_key( $order ), + 'post_parent' => $order->get_parent_id( 'edit' ), + 'post_excerpt' => $this->get_post_excerpt( $order ), + ) + ), + true + ); + + if ( $id && ! is_wp_error( $id ) ) { + $order->set_id( $id ); + $this->update_post_meta( $order ); + $order->save_meta_data(); + $order->apply_changes(); + $this->clear_caches( $order ); + } + } + + /** + * Method to read an order from the database. + * + * @param WC_Data $order Order object. + * + * @throws Exception If passed order is invalid. + */ + public function read( &$order ) { + $order->set_defaults(); + $post_object = get_post( $order->get_id() ); + + if ( ! $order->get_id() || ! $post_object || ! in_array( $post_object->post_type, wc_get_order_types(), true ) ) { + throw new Exception( __( 'Invalid order.', 'woocommerce' ) ); + } + + $order->set_props( + array( + 'parent_id' => $post_object->post_parent, + 'date_created' => $this->string_to_timestamp( $post_object->post_date_gmt ), + 'date_modified' => $this->string_to_timestamp( $post_object->post_modified_gmt ), + 'status' => $post_object->post_status, + ) + ); + + $this->read_order_data( $order, $post_object ); + $order->read_meta_data(); + $order->set_object_read( true ); + + /** + * In older versions, discounts may have been stored differently. + * Update them now so if the object is saved, the correct values are + * stored. @todo When meta is flattened, handle this during migration. + */ + if ( version_compare( $order->get_version( 'edit' ), '2.3.7', '<' ) && $order->get_prices_include_tax( 'edit' ) ) { + $order->set_discount_total( (float) get_post_meta( $order->get_id(), '_cart_discount', true ) - (float) get_post_meta( $order->get_id(), '_cart_discount_tax', true ) ); + } + } + + /** + * Method to update an order in the database. + * + * @param WC_Order $order Order object. + */ + public function update( &$order ) { + $order->save_meta_data(); + $order->set_version( Constants::get_constant( 'WC_VERSION' ) ); + + if ( null === $order->get_date_created( 'edit' ) ) { + $order->set_date_created( time() ); + } + + $changes = $order->get_changes(); + + // Only update the post when the post data changes. + if ( array_intersect( array( 'date_created', 'date_modified', 'status', 'parent_id', 'post_excerpt' ), array_keys( $changes ) ) ) { + $post_data = array( + 'post_date' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getOffsetTimestamp() ), + 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getTimestamp() ), + 'post_status' => $this->get_post_status( $order ), + 'post_parent' => $order->get_parent_id(), + 'post_excerpt' => $this->get_post_excerpt( $order ), + 'post_modified' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $order->get_date_modified( 'edit' )->getOffsetTimestamp() ) : current_time( 'mysql' ), + 'post_modified_gmt' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $order->get_date_modified( 'edit' )->getTimestamp() ) : current_time( 'mysql', 1 ), + ); + + /** + * When updating this object, to prevent infinite loops, use $wpdb + * to update data, since wp_update_post spawns more calls to the + * save_post action. + * + * This ensures hooks are fired by either WP itself (admin screen save), + * or an update purely from CRUD. + */ + if ( doing_action( 'save_post' ) ) { + $GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $post_data, array( 'ID' => $order->get_id() ) ); + clean_post_cache( $order->get_id() ); + } else { + wp_update_post( array_merge( array( 'ID' => $order->get_id() ), $post_data ) ); + } + $order->read_meta_data( true ); // Refresh internal meta data, in case things were hooked into `save_post` or another WP hook. + } + $this->update_post_meta( $order ); + $order->apply_changes(); + $this->clear_caches( $order ); + } + + /** + * Method to delete an order from the database. + * + * @param WC_Order $order Order object. + * @param array $args Array of args to pass to the delete method. + * + * @return void + */ + public function delete( &$order, $args = array() ) { + $id = $order->get_id(); + $args = wp_parse_args( + $args, + array( + 'force_delete' => false, + ) + ); + + if ( ! $id ) { + return; + } + + if ( $args['force_delete'] ) { + wp_delete_post( $id ); + $order->set_id( 0 ); + do_action( 'woocommerce_delete_order', $id ); + } else { + wp_trash_post( $id ); + $order->set_status( 'trash' ); + do_action( 'woocommerce_trash_order', $id ); + } + } + + /* + |-------------------------------------------------------------------------- + | Additional Methods + |-------------------------------------------------------------------------- + */ + + /** + * Get the status to save to the post object. + * + * Plugins extending the order classes can override this to change the stored status/add prefixes etc. + * + * @since 3.6.0 + * @param WC_order $order Order object. + * @return string + */ + protected function get_post_status( $order ) { + $order_status = $order->get_status( 'edit' ); + + if ( ! $order_status ) { + $order_status = apply_filters( 'woocommerce_default_order_status', 'pending' ); + } + + $post_status = $order_status; + $valid_statuses = get_post_stati(); + + // Add a wc- prefix to the status, but exclude some core statuses which should not be prefixed. + // @todo In the future this should only happen based on `wc_is_order_status`, but in order to + // preserve back-compatibility this happens to all statuses except a select few. A doing_it_wrong + // Notice will be needed here, followed by future removal. + if ( ! in_array( $post_status, array( 'auto-draft', 'draft', 'trash' ), true ) && in_array( 'wc-' . $post_status, $valid_statuses, true ) ) { + $post_status = 'wc-' . $post_status; + } + + return $post_status; + } + + /** + * Excerpt for post. + * + * @param WC_order $order Order object. + * @return string + */ + protected function get_post_excerpt( $order ) { + return ''; + } + + /** + * Get a title for the new post type. + * + * @return string + */ + protected function get_post_title() { + // @codingStandardsIgnoreStart + /* translators: %s: Order date */ + return sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) ); + // @codingStandardsIgnoreEnd + } + + /** + * Get order key. + * + * @since 4.3.0 + * @param WC_order $order Order object. + * @return string + */ + protected function get_order_key( $order ) { + return wc_generate_order_key(); + } + + /** + * Read order data. Can be overridden by child classes to load other props. + * + * @param WC_Order $order Order object. + * @param object $post_object Post object. + * @since 3.0.0 + */ + protected function read_order_data( &$order, $post_object ) { + $id = $order->get_id(); + + $order->set_props( + array( + 'currency' => get_post_meta( $id, '_order_currency', true ), + 'discount_total' => get_post_meta( $id, '_cart_discount', true ), + 'discount_tax' => get_post_meta( $id, '_cart_discount_tax', true ), + 'shipping_total' => get_post_meta( $id, '_order_shipping', true ), + 'shipping_tax' => get_post_meta( $id, '_order_shipping_tax', true ), + 'cart_tax' => get_post_meta( $id, '_order_tax', true ), + 'total' => get_post_meta( $id, '_order_total', true ), + 'version' => get_post_meta( $id, '_order_version', true ), + 'prices_include_tax' => metadata_exists( 'post', $id, '_prices_include_tax' ) ? 'yes' === get_post_meta( $id, '_prices_include_tax', true ) : 'yes' === get_option( 'woocommerce_prices_include_tax' ), + ) + ); + + // Gets extra data associated with the order if needed. + foreach ( $order->get_extra_data_keys() as $key ) { + $function = 'set_' . $key; + if ( is_callable( array( $order, $function ) ) ) { + $order->{$function}( get_post_meta( $order->get_id(), '_' . $key, true ) ); + } + } + } + + /** + * Helper method that updates all the post meta for an order based on it's settings in the WC_Order class. + * + * @param WC_Order $order Order object. + * @since 3.0.0 + */ + protected function update_post_meta( &$order ) { + $updated_props = array(); + $meta_key_to_props = array( + '_order_currency' => 'currency', + '_cart_discount' => 'discount_total', + '_cart_discount_tax' => 'discount_tax', + '_order_shipping' => 'shipping_total', + '_order_shipping_tax' => 'shipping_tax', + '_order_tax' => 'cart_tax', + '_order_total' => 'total', + '_order_version' => 'version', + '_prices_include_tax' => 'prices_include_tax', + ); + + $props_to_update = $this->get_props_to_update( $order, $meta_key_to_props ); + + foreach ( $props_to_update as $meta_key => $prop ) { + $value = $order->{"get_$prop"}( 'edit' ); + $value = is_string( $value ) ? wp_slash( $value ) : $value; + + if ( 'prices_include_tax' === $prop ) { + $value = $value ? 'yes' : 'no'; + } + + $updated = $this->update_or_delete_post_meta( $order, $meta_key, $value ); + + if ( $updated ) { + $updated_props[] = $prop; + } + } + + do_action( 'woocommerce_order_object_updated_props', $order, $updated_props ); + } + + /** + * Clear any caches. + * + * @param WC_Order $order Order object. + * @since 3.0.0 + */ + protected function clear_caches( &$order ) { + clean_post_cache( $order->get_id() ); + wc_delete_shop_order_transients( $order ); + wp_cache_delete( 'order-items-' . $order->get_id(), 'orders' ); + } + + /** + * Read order items of a specific type from the database for this order. + * + * @param WC_Order $order Order object. + * @param string $type Order item type. + * @return array + */ + public function read_items( $order, $type ) { + global $wpdb; + + // Get from cache if available. + $items = 0 < $order->get_id() ? wp_cache_get( 'order-items-' . $order->get_id(), 'orders' ) : false; + + if ( false === $items ) { + $items = $wpdb->get_results( + $wpdb->prepare( "SELECT order_item_type, order_item_id, order_id, order_item_name FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d ORDER BY order_item_id;", $order->get_id() ) + ); + foreach ( $items as $item ) { + wp_cache_set( 'item-' . $item->order_item_id, $item, 'order-items' ); + } + if ( 0 < $order->get_id() ) { + wp_cache_set( 'order-items-' . $order->get_id(), $items, 'orders' ); + } + } + + $items = wp_list_filter( $items, array( 'order_item_type' => $type ) ); + + if ( ! empty( $items ) ) { + $items = array_map( array( 'WC_Order_Factory', 'get_order_item' ), array_combine( wp_list_pluck( $items, 'order_item_id' ), $items ) ); + } else { + $items = array(); + } + + return $items; + } + + /** + * Remove all line items (products, coupons, shipping, taxes) from the order. + * + * @param WC_Order $order Order object. + * @param string $type Order item type. Default null. + */ + public function delete_items( $order, $type = null ) { + global $wpdb; + if ( ! empty( $type ) ) { + $wpdb->query( $wpdb->prepare( "DELETE FROM itemmeta USING {$wpdb->prefix}woocommerce_order_itemmeta itemmeta INNER JOIN {$wpdb->prefix}woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id AND items.order_id = %d AND items.order_item_type = %s", $order->get_id(), $type ) ); + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = %s", $order->get_id(), $type ) ); + } else { + $wpdb->query( $wpdb->prepare( "DELETE FROM itemmeta USING {$wpdb->prefix}woocommerce_order_itemmeta itemmeta INNER JOIN {$wpdb->prefix}woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id and items.order_id = %d", $order->get_id() ) ); + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d", $order->get_id() ) ); + } + $this->clear_caches( $order ); + } + + /** + * Get token ids for an order. + * + * @param WC_Order $order Order object. + * @return array + */ + public function get_payment_token_ids( $order ) { + $token_ids = array_filter( (array) get_post_meta( $order->get_id(), '_payment_tokens', true ) ); + return $token_ids; + } + + /** + * Update token ids for an order. + * + * @param WC_Order $order Order object. + * @param array $token_ids Payment token ids. + */ + public function update_payment_token_ids( $order, $token_ids ) { + update_post_meta( $order->get_id(), '_payment_tokens', $token_ids ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/abstract-wc-order-item-type-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/abstract-wc-order-item-type-data-store.php new file mode 100644 index 0000000..0aa25a6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/abstract-wc-order-item-type-data-store.php @@ -0,0 +1,166 @@ +insert( + $wpdb->prefix . 'woocommerce_order_items', + array( + 'order_item_name' => $item->get_name(), + 'order_item_type' => $item->get_type(), + 'order_id' => $item->get_order_id(), + ) + ); + $item->set_id( $wpdb->insert_id ); + $this->save_item_data( $item ); + $item->save_meta_data(); + $item->apply_changes(); + $this->clear_cache( $item ); + + do_action( 'woocommerce_new_order_item', $item->get_id(), $item, $item->get_order_id() ); + } + + /** + * Update a order item in the database. + * + * @since 3.0.0 + * @param WC_Order_Item $item Order item object. + */ + public function update( &$item ) { + global $wpdb; + + $changes = $item->get_changes(); + + if ( array_intersect( array( 'name', 'order_id' ), array_keys( $changes ) ) ) { + $wpdb->update( + $wpdb->prefix . 'woocommerce_order_items', + array( + 'order_item_name' => $item->get_name(), + 'order_item_type' => $item->get_type(), + 'order_id' => $item->get_order_id(), + ), + array( 'order_item_id' => $item->get_id() ) + ); + } + + $this->save_item_data( $item ); + $item->save_meta_data(); + $item->apply_changes(); + $this->clear_cache( $item ); + + do_action( 'woocommerce_update_order_item', $item->get_id(), $item, $item->get_order_id() ); + } + + /** + * Remove an order item from the database. + * + * @since 3.0.0 + * @param WC_Order_Item $item Order item object. + * @param array $args Array of args to pass to the delete method. + */ + public function delete( &$item, $args = array() ) { + if ( $item->get_id() ) { + global $wpdb; + do_action( 'woocommerce_before_delete_order_item', $item->get_id() ); + $wpdb->delete( $wpdb->prefix . 'woocommerce_order_items', array( 'order_item_id' => $item->get_id() ) ); + $wpdb->delete( $wpdb->prefix . 'woocommerce_order_itemmeta', array( 'order_item_id' => $item->get_id() ) ); + do_action( 'woocommerce_delete_order_item', $item->get_id() ); + $this->clear_cache( $item ); + } + } + + /** + * Read a order item from the database. + * + * @since 3.0.0 + * + * @param WC_Order_Item $item Order item object. + * + * @throws Exception If invalid order item. + */ + public function read( &$item ) { + global $wpdb; + + $item->set_defaults(); + + // Get from cache if available. + $data = wp_cache_get( 'item-' . $item->get_id(), 'order-items' ); + + if ( false === $data ) { + $data = $wpdb->get_row( $wpdb->prepare( "SELECT order_id, order_item_name FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d LIMIT 1;", $item->get_id() ) ); + wp_cache_set( 'item-' . $item->get_id(), $data, 'order-items' ); + } + + if ( ! $data ) { + throw new Exception( __( 'Invalid order item.', 'woocommerce' ) ); + } + + $item->set_props( + array( + 'order_id' => $data->order_id, + 'name' => $data->order_item_name, + ) + ); + $item->read_meta_data(); + } + + /** + * Saves an item's data to the database / item meta. + * Ran after both create and update, so $item->get_id() will be set. + * + * @since 3.0.0 + * @param WC_Order_Item $item Order item object. + */ + public function save_item_data( &$item ) {} + + /** + * Clear meta cache. + * + * @param WC_Order_Item $item Order item object. + */ + public function clear_cache( &$item ) { + wp_cache_delete( 'item-' . $item->get_id(), 'order-items' ); + wp_cache_delete( 'order-items-' . $item->get_order_id(), 'orders' ); + wp_cache_delete( $item->get_id(), $this->meta_type . '_meta' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-coupon-data-store-cpt.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-coupon-data-store-cpt.php new file mode 100644 index 0000000..8f9b731 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-coupon-data-store-cpt.php @@ -0,0 +1,728 @@ +get_date_created( 'edit' ) ) { + $coupon->set_date_created( time() ); + } + + $coupon_id = wp_insert_post( + apply_filters( + 'woocommerce_new_coupon_data', + array( + 'post_type' => 'shop_coupon', + 'post_status' => 'publish', + 'post_author' => get_current_user_id(), + 'post_title' => $coupon->get_code( 'edit' ), + 'post_content' => '', + 'post_excerpt' => $coupon->get_description( 'edit' ), + 'post_date' => gmdate( 'Y-m-d H:i:s', $coupon->get_date_created()->getOffsetTimestamp() ), + 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $coupon->get_date_created()->getTimestamp() ), + ) + ), + true + ); + + if ( $coupon_id ) { + $coupon->set_id( $coupon_id ); + $this->update_post_meta( $coupon ); + $coupon->save_meta_data(); + $coupon->apply_changes(); + delete_transient( 'rest_api_coupons_type_count' ); + do_action( 'woocommerce_new_coupon', $coupon_id, $coupon ); + } + } + + /** + * Method to read a coupon. + * + * @since 3.0.0 + * + * @param WC_Coupon $coupon Coupon object. + * + * @throws Exception If invalid coupon. + */ + public function read( &$coupon ) { + $coupon->set_defaults(); + + $post_object = get_post( $coupon->get_id() ); + + if ( ! $coupon->get_id() || ! $post_object || 'shop_coupon' !== $post_object->post_type ) { + throw new Exception( __( 'Invalid coupon.', 'woocommerce' ) ); + } + + $coupon_id = $coupon->get_id(); + $coupon->set_props( + array( + 'code' => $post_object->post_title, + 'description' => $post_object->post_excerpt, + 'date_created' => $this->string_to_timestamp( $post_object->post_date_gmt ), + 'date_modified' => $this->string_to_timestamp( $post_object->post_modified_gmt ), + 'date_expires' => metadata_exists( 'post', $coupon_id, 'date_expires' ) ? get_post_meta( $coupon_id, 'date_expires', true ) : get_post_meta( $coupon_id, 'expiry_date', true ), // @todo: Migrate expiry_date meta to date_expires in upgrade routine. + 'discount_type' => get_post_meta( $coupon_id, 'discount_type', true ), + 'amount' => get_post_meta( $coupon_id, 'coupon_amount', true ), + 'usage_count' => get_post_meta( $coupon_id, 'usage_count', true ), + 'individual_use' => 'yes' === get_post_meta( $coupon_id, 'individual_use', true ), + 'product_ids' => array_filter( (array) explode( ',', get_post_meta( $coupon_id, 'product_ids', true ) ) ), + 'excluded_product_ids' => array_filter( (array) explode( ',', get_post_meta( $coupon_id, 'exclude_product_ids', true ) ) ), + 'usage_limit' => get_post_meta( $coupon_id, 'usage_limit', true ), + 'usage_limit_per_user' => get_post_meta( $coupon_id, 'usage_limit_per_user', true ), + 'limit_usage_to_x_items' => 0 < get_post_meta( $coupon_id, 'limit_usage_to_x_items', true ) ? get_post_meta( $coupon_id, 'limit_usage_to_x_items', true ) : null, + 'free_shipping' => 'yes' === get_post_meta( $coupon_id, 'free_shipping', true ), + 'product_categories' => array_filter( (array) get_post_meta( $coupon_id, 'product_categories', true ) ), + 'excluded_product_categories' => array_filter( (array) get_post_meta( $coupon_id, 'exclude_product_categories', true ) ), + 'exclude_sale_items' => 'yes' === get_post_meta( $coupon_id, 'exclude_sale_items', true ), + 'minimum_amount' => get_post_meta( $coupon_id, 'minimum_amount', true ), + 'maximum_amount' => get_post_meta( $coupon_id, 'maximum_amount', true ), + 'email_restrictions' => array_filter( (array) get_post_meta( $coupon_id, 'customer_email', true ) ), + 'used_by' => array_filter( (array) get_post_meta( $coupon_id, '_used_by' ) ), + ) + ); + $coupon->read_meta_data(); + $coupon->set_object_read( true ); + do_action( 'woocommerce_coupon_loaded', $coupon ); + } + + /** + * Updates a coupon in the database. + * + * @since 3.0.0 + * @param WC_Coupon $coupon Coupon object. + */ + public function update( &$coupon ) { + $coupon->save_meta_data(); + $changes = $coupon->get_changes(); + + if ( array_intersect( array( 'code', 'description', 'date_created', 'date_modified' ), array_keys( $changes ) ) ) { + $post_data = array( + 'post_title' => $coupon->get_code( 'edit' ), + 'post_excerpt' => $coupon->get_description( 'edit' ), + 'post_date' => gmdate( 'Y-m-d H:i:s', $coupon->get_date_created( 'edit' )->getOffsetTimestamp() ), + 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $coupon->get_date_created( 'edit' )->getTimestamp() ), + 'post_modified' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $coupon->get_date_modified( 'edit' )->getOffsetTimestamp() ) : current_time( 'mysql' ), + 'post_modified_gmt' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $coupon->get_date_modified( 'edit' )->getTimestamp() ) : current_time( 'mysql', 1 ), + ); + + /** + * When updating this object, to prevent infinite loops, use $wpdb + * to update data, since wp_update_post spawns more calls to the + * save_post action. + * + * This ensures hooks are fired by either WP itself (admin screen save), + * or an update purely from CRUD. + */ + if ( doing_action( 'save_post' ) ) { + $GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $post_data, array( 'ID' => $coupon->get_id() ) ); + clean_post_cache( $coupon->get_id() ); + } else { + wp_update_post( array_merge( array( 'ID' => $coupon->get_id() ), $post_data ) ); + } + $coupon->read_meta_data( true ); // Refresh internal meta data, in case things were hooked into `save_post` or another WP hook. + } + $this->update_post_meta( $coupon ); + $coupon->apply_changes(); + delete_transient( 'rest_api_coupons_type_count' ); + do_action( 'woocommerce_update_coupon', $coupon->get_id(), $coupon ); + } + + /** + * Deletes a coupon from the database. + * + * @since 3.0.0 + * + * @param WC_Coupon $coupon Coupon object. + * @param array $args Array of args to pass to the delete method. + */ + public function delete( &$coupon, $args = array() ) { + $args = wp_parse_args( + $args, + array( + 'force_delete' => false, + ) + ); + + $id = $coupon->get_id(); + + if ( ! $id ) { + return; + } + + if ( $args['force_delete'] ) { + wp_delete_post( $id ); + + wp_cache_delete( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $coupon->get_code(), 'coupons' ); + + $coupon->set_id( 0 ); + do_action( 'woocommerce_delete_coupon', $id ); + } else { + wp_trash_post( $id ); + do_action( 'woocommerce_trash_coupon', $id ); + } + } + + /** + * Helper method that updates all the post meta for a coupon based on it's settings in the WC_Coupon class. + * + * @param WC_Coupon $coupon Coupon object. + * @since 3.0.0 + */ + private function update_post_meta( &$coupon ) { + $meta_key_to_props = array( + 'discount_type' => 'discount_type', + 'coupon_amount' => 'amount', + 'individual_use' => 'individual_use', + 'product_ids' => 'product_ids', + 'exclude_product_ids' => 'excluded_product_ids', + 'usage_limit' => 'usage_limit', + 'usage_limit_per_user' => 'usage_limit_per_user', + 'limit_usage_to_x_items' => 'limit_usage_to_x_items', + 'usage_count' => 'usage_count', + 'date_expires' => 'date_expires', + 'free_shipping' => 'free_shipping', + 'product_categories' => 'product_categories', + 'exclude_product_categories' => 'excluded_product_categories', + 'exclude_sale_items' => 'exclude_sale_items', + 'minimum_amount' => 'minimum_amount', + 'maximum_amount' => 'maximum_amount', + 'customer_email' => 'email_restrictions', + ); + + $props_to_update = $this->get_props_to_update( $coupon, $meta_key_to_props ); + foreach ( $props_to_update as $meta_key => $prop ) { + $value = $coupon->{"get_$prop"}( 'edit' ); + $value = is_string( $value ) ? wp_slash( $value ) : $value; + switch ( $prop ) { + case 'individual_use': + case 'free_shipping': + case 'exclude_sale_items': + $value = wc_bool_to_string( $value ); + break; + case 'product_ids': + case 'excluded_product_ids': + $value = implode( ',', array_filter( array_map( 'intval', $value ) ) ); + break; + case 'product_categories': + case 'excluded_product_categories': + $value = array_filter( array_map( 'intval', $value ) ); + break; + case 'email_restrictions': + $value = array_filter( array_map( 'sanitize_email', $value ) ); + break; + case 'date_expires': + $value = $value ? $value->getTimestamp() : null; + break; + } + + $updated = $this->update_or_delete_post_meta( $coupon, $meta_key, $value ); + + if ( $updated ) { + $this->updated_props[] = $prop; + } + } + + do_action( 'woocommerce_coupon_object_updated_props', $coupon, $this->updated_props ); + } + + /** + * Increase usage count for current coupon. + * + * @since 3.0.0 + * @param WC_Coupon $coupon Coupon object. + * @param string $used_by Either user ID or billing email. + * @param WC_Order $order (Optional) If passed, clears the hold record associated with order. + + * @return int New usage count. + */ + public function increase_usage_count( &$coupon, $used_by = '', $order = null ) { + $coupon_held_key_for_user = ''; + if ( $order instanceof WC_Order ) { + $coupon_held_key_for_user = $order->get_data_store()->get_coupon_held_keys_for_users( $order, $coupon->get_id() ); + } + + $new_count = $this->update_usage_count_meta( $coupon, 'increase' ); + + if ( $used_by ) { + $this->add_coupon_used_by( $coupon, $used_by, $coupon_held_key_for_user ); + $coupon->set_used_by( (array) get_post_meta( $coupon->get_id(), '_used_by' ) ); + } + + do_action( 'woocommerce_increase_coupon_usage_count', $coupon, $new_count, $used_by ); + + return $new_count; + } + + /** + * Helper function to add a `_used_by` record to track coupons used by the user. + * + * @param WC_Coupon $coupon Coupon object. + * @param string $used_by Either user ID or billing email. + * @param string $coupon_held_key (Optional) Update meta key to `_used_by` instead of adding a new record. + */ + private function add_coupon_used_by( $coupon, $used_by, $coupon_held_key ) { + global $wpdb; + if ( $coupon_held_key && '' !== $coupon_held_key ) { + // Looks like we added a tentative record for this coupon getting used. + // Lets change the tentative record to a permanent one. + $result = $wpdb->query( + $wpdb->prepare( + " + UPDATE $wpdb->postmeta SET meta_key = %s, meta_value = %s WHERE meta_key = %s LIMIT 1", + '_used_by', + $used_by, + $coupon_held_key + ) + ); + if ( ! $result ) { + // If no rows were updated, then insert a `_used_by` row manually to maintain consistency. + add_post_meta( $coupon->get_id(), '_used_by', strtolower( $used_by ) ); + } + } else { + add_post_meta( $coupon->get_id(), '_used_by', strtolower( $used_by ) ); + } + } + + /** + * Decrease usage count for current coupon. + * + * @since 3.0.0 + * @param WC_Coupon $coupon Coupon object. + * @param string $used_by Either user ID or billing email. + * @return int New usage count. + */ + public function decrease_usage_count( &$coupon, $used_by = '' ) { + global $wpdb; + $new_count = $this->update_usage_count_meta( $coupon, 'decrease' ); + if ( $used_by ) { + /** + * We're doing this the long way because `delete_post_meta( $id, $key, $value )` deletes. + * all instances where the key and value match, and we only want to delete one. + */ + $meta_id = $wpdb->get_var( + $wpdb->prepare( + "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_used_by' AND meta_value = %s AND post_id = %d LIMIT 1;", + $used_by, + $coupon->get_id() + ) + ); + if ( $meta_id ) { + delete_metadata_by_mid( 'post', $meta_id ); + $coupon->set_used_by( (array) get_post_meta( $coupon->get_id(), '_used_by' ) ); + } + } + + do_action( 'woocommerce_decrease_coupon_usage_count', $coupon, $new_count, $used_by ); + + return $new_count; + } + + /** + * Increase or decrease the usage count for a coupon by 1. + * + * @since 3.0.0 + * @param WC_Coupon $coupon Coupon object. + * @param string $operation 'increase' or 'decrease'. + * @return int New usage count + */ + private function update_usage_count_meta( &$coupon, $operation = 'increase' ) { + global $wpdb; + $id = $coupon->get_id(); + $operator = ( 'increase' === $operation ) ? '+' : '-'; + + add_post_meta( $id, 'usage_count', $coupon->get_usage_count( 'edit' ), true ); + $wpdb->query( + $wpdb->prepare( + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared + "UPDATE $wpdb->postmeta SET meta_value = meta_value {$operator} 1 WHERE meta_key = 'usage_count' AND post_id = %d;", + $id + ) + ); + + // Get the latest value direct from the DB, instead of possibly the WP meta cache. + return (int) $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key = 'usage_count' AND post_id = %d;", $id ) ); + } + + /** + * Returns tentative usage count for coupon. + * + * @param int $coupon_id Coupon ID. + * + * @return int Tentative usage count. + */ + public function get_tentative_usage_count( $coupon_id ) { + global $wpdb; + return $wpdb->get_var( + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $this->get_tentative_usage_query( $coupon_id ) + ); + } + /** + * Get the number of uses for a coupon by user ID. + * + * @since 3.0.0 + * @param WC_Coupon $coupon Coupon object. + * @param id $user_id User ID. + * @return int + */ + public function get_usage_by_user_id( &$coupon, $user_id ) { + global $wpdb; + $usage_count = $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT( meta_id ) FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = '_used_by' AND meta_value = %d;", + $coupon->get_id(), + $user_id + ) + ); + $tentative_usage_count = $this->get_tentative_usages_for_user( $coupon->get_id(), array( $user_id ) ); + return $tentative_usage_count + $usage_count; + } + + /** + * Get the number of uses for a coupon by email address + * + * @since 3.6.4 + * @param WC_Coupon $coupon Coupon object. + * @param string $email Email address. + * @return int + */ + public function get_usage_by_email( &$coupon, $email ) { + global $wpdb; + $usage_count = $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT( meta_id ) FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = '_used_by' AND meta_value = %s;", + $coupon->get_id(), + $email + ) + ); + $tentative_usage_count = $this->get_tentative_usages_for_user( $coupon->get_id(), array( $email ) ); + return $tentative_usage_count + $usage_count; + } + + /** + * Get tentative coupon usages for user. + * + * @param int $coupon_id Coupon ID. + * @param array $user_aliases Array of user aliases to check tentative usages for. + * + * @return string|null + */ + public function get_tentative_usages_for_user( $coupon_id, $user_aliases ) { + global $wpdb; + return $wpdb->get_var( + $this->get_tentative_usage_query_for_user( $coupon_id, $user_aliases ) + ); // WPCS: unprepared SQL ok. + + } + + /** + * Get held time for resources before cancelling the order. Use 60 minutes as sane default. + * Note that the filter `woocommerce_coupon_hold_minutes` only support minutes because it's getting used elsewhere as well, however this function returns in seconds. + * + * @return int + */ + private function get_tentative_held_time() { + return apply_filters( 'woocommerce_coupon_hold_minutes', ( (int) get_option( 'woocommerce_hold_stock_minutes', 60 ) ) ) * 60; + } + + /** + * Check and records coupon usage tentatively for short period of time so that counts validation is correct. Returns early if there is no limit defined for the coupon. + * + * @param WC_Coupon $coupon Coupon object. + * + * @return bool|int|string|null Returns meta key if coupon was held, null if returned early. + */ + public function check_and_hold_coupon( $coupon ) { + global $wpdb; + + $usage_limit = $coupon->get_usage_limit(); + $held_time = $this->get_tentative_held_time(); + + if ( 0 >= $usage_limit || 0 >= $held_time ) { + return null; + } + + if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', true ) ) { + return null; + } + + // Make sure we have usage_count meta key for this coupon because its required for `$query_for_usages`. + // We are not directly modifying `$query_for_usages` to allow for `usage_count` not present only keep that query simple. + if ( ! metadata_exists( 'post', $coupon->get_id(), 'usage_count' ) ) { + $coupon->set_usage_count( $coupon->get_usage_count() ); // Use `get_usage_count` here to write default value, which may changed by a filter. + $coupon->save(); + } + + $query_for_usages = $wpdb->prepare( + " + SELECT meta_value from $wpdb->postmeta + WHERE {$wpdb->postmeta}.meta_key = 'usage_count' + AND {$wpdb->postmeta}.post_id = %d + LIMIT 1 + FOR UPDATE + ", + $coupon->get_id() + ); + + $query_for_tentative_usages = $this->get_tentative_usage_query( $coupon->get_id() ); + $db_timestamp = $wpdb->get_var( 'SELECT UNIX_TIMESTAMP() FROM DUAL' ); + + $coupon_usage_key = '_coupon_held_' . ( (int) $db_timestamp + $held_time ) . '_' . wp_generate_password( 6, false ); + + $insert_statement = $wpdb->prepare( + " + INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value ) + SELECT %d, %s, %s FROM DUAL + WHERE ( $query_for_usages ) + ( $query_for_tentative_usages ) < %d + ", + $coupon->get_id(), + $coupon_usage_key, + '', + $usage_limit + ); // WPCS: unprepared SQL ok. + + /** + * In some cases, specifically when there is a combined index on post_id,meta_key, the insert statement above could end up in a deadlock. + * We will try to insert 3 times before giving up to recover from deadlock. + */ + for ( $count = 0; $count < 3; $count++ ) { + $result = $wpdb->query( $insert_statement ); // WPCS: unprepared SQL ok. + if ( false !== $result ) { + break; + } + } + + return $result > 0 ? $coupon_usage_key : $result; + } + + /** + * Generate query to calculate tentative usages for the coupon. + * + * @param int $coupon_id Coupon ID to get tentative usage query for. + * + * @return string Query for tentative usages. + */ + private function get_tentative_usage_query( $coupon_id ) { + global $wpdb; + return $wpdb->prepare( + " + SELECT COUNT(meta_id) FROM $wpdb->postmeta + WHERE {$wpdb->postmeta}.meta_key like %s + AND {$wpdb->postmeta}.meta_key > %s + AND {$wpdb->postmeta}.post_id = %d + FOR UPDATE + ", + array( + '_coupon_held_%', + '_coupon_held_' . time(), + $coupon_id, + ) + ); // WPCS: unprepared SQL ok. + } + + /** + * Check and records coupon usage tentatively for passed user aliases for short period of time so that counts validation is correct. Returns early if there is no limit per user for the coupon. + * + * @param WC_Coupon $coupon Coupon object. + * @param array $user_aliases Emails or Ids to check for user. + * @param string $user_alias Email/ID to use as `used_by` value. + * + * @return null|false|int + */ + public function check_and_hold_coupon_for_user( $coupon, $user_aliases, $user_alias ) { + global $wpdb; + $limit_per_user = $coupon->get_usage_limit_per_user(); + $held_time = $this->get_tentative_held_time(); + + if ( 0 >= $limit_per_user || 0 >= $held_time ) { + // This coupon do not have any restriction for usage per customer. No need to check further, lets bail. + return null; + } + + if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', true ) ) { + return null; + } + + $format = implode( "','", array_fill( 0, count( $user_aliases ), '%s' ) ); + + $query_for_usages = $wpdb->prepare( + " + SELECT COUNT(*) FROM $wpdb->postmeta + WHERE {$wpdb->postmeta}.meta_key = '_used_by' + AND {$wpdb->postmeta}.meta_value IN ('$format') + AND {$wpdb->postmeta}.post_id = %d + FOR UPDATE + ", + array_merge( + $user_aliases, + array( $coupon->get_id() ) + ) + ); // WPCS: unprepared SQL ok. + + $query_for_tentative_usages = $this->get_tentative_usage_query_for_user( $coupon->get_id(), $user_aliases ); + $db_timestamp = $wpdb->get_var( 'SELECT UNIX_TIMESTAMP() FROM DUAL' ); + + $coupon_used_by_meta_key = '_maybe_used_by_' . ( (int) $db_timestamp + $held_time ) . '_' . wp_generate_password( 6, false ); + $insert_statement = $wpdb->prepare( + " + INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value ) + SELECT %d, %s, %s FROM DUAL + WHERE ( $query_for_usages ) + ( $query_for_tentative_usages ) < %d + ", + $coupon->get_id(), + $coupon_used_by_meta_key, + $user_alias, + $limit_per_user + ); // WPCS: unprepared SQL ok. + + // This query can potentially be deadlocked if a combined index on post_id and meta_key is present and there is + // high concurrency, in which case DB will abort the query which has done less work to resolve deadlock. + // We will try up to 3 times before giving up. + for ( $count = 0; $count < 3; $count++ ) { + $result = $wpdb->query( $insert_statement ); // WPCS: unprepared SQL ok. + if ( false !== $result ) { + break; + } + } + + return $result > 0 ? $coupon_used_by_meta_key : $result; + } + + /** + * Generate query to calculate tentative usages for the coupon by the user. + * + * @param int $coupon_id Coupon ID. + * @param array $user_aliases List of user aliases to check for usages. + * + * @return string Tentative usages query. + */ + private function get_tentative_usage_query_for_user( $coupon_id, $user_aliases ) { + global $wpdb; + + $format = implode( "','", array_fill( 0, count( $user_aliases ), '%s' ) ); + + // Note that if you are debugging, `_maybe_used_by_%` will be converted to `_maybe_used_by_{...very long str...}` to very long string. This is expected, and is automatically corrected while running the insert query. + return $wpdb->prepare( + " + SELECT COUNT( meta_id ) FROM $wpdb->postmeta + WHERE {$wpdb->postmeta}.meta_key like %s + AND {$wpdb->postmeta}.meta_key > %s + AND {$wpdb->postmeta}.post_id = %d + AND {$wpdb->postmeta}.meta_value IN ('$format') + FOR UPDATE + ", + array_merge( + array( + '_maybe_used_by_%', + '_maybe_used_by_' . time(), + $coupon_id, + ), + $user_aliases + ) + ); // WPCS: unprepared SQL ok. + } + + /** + * Return a coupon code for a specific ID. + * + * @since 3.0.0 + * @param int $id Coupon ID. + * @return string Coupon Code + */ + public function get_code_by_id( $id ) { + global $wpdb; + return $wpdb->get_var( + $wpdb->prepare( + "SELECT post_title + FROM $wpdb->posts + WHERE ID = %d + AND post_type = 'shop_coupon' + AND post_status = 'publish'", + $id + ) + ); + } + + /** + * Return an array of IDs for for a specific coupon code. + * Can return multiple to check for existence. + * + * @since 3.0.0 + * @param string $code Coupon code. + * @return array Array of IDs. + */ + public function get_ids_by_code( $code ) { + global $wpdb; + return $wpdb->get_col( + $wpdb->prepare( + "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' ORDER BY post_date DESC", + wc_sanitize_coupon_code( $code ) + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php new file mode 100644 index 0000000..4a2585d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php @@ -0,0 +1,197 @@ +save_to_session( $customer ); + } + + /** + * Simply update the session. + * + * @param WC_Customer $customer Customer object. + */ + public function update( &$customer ) { + $this->save_to_session( $customer ); + } + + /** + * Saves all customer data to the session. + * + * @param WC_Customer $customer Customer object. + */ + public function save_to_session( $customer ) { + $data = array(); + foreach ( $this->session_keys as $session_key ) { + $function_key = $session_key; + if ( 'billing_' === substr( $session_key, 0, 8 ) ) { + $session_key = str_replace( 'billing_', '', $session_key ); + } + $data[ $session_key ] = (string) $customer->{"get_$function_key"}( 'edit' ); + } + WC()->session->set( 'customer', $data ); + } + + /** + * Read customer data from the session unless the user has logged in, in + * which case the stored ID will differ from the actual ID. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + */ + public function read( &$customer ) { + $data = (array) WC()->session->get( 'customer' ); + + /** + * There is a valid session if $data is not empty, and the ID matches the logged in user ID. + * + * If the user object has been updated since the session was created (based on date_modified) we should not load the session - data should be reloaded. + */ + if ( isset( $data['id'], $data['date_modified'] ) && $data['id'] === (string) $customer->get_id() && $data['date_modified'] === (string) $customer->get_date_modified( 'edit' ) ) { + foreach ( $this->session_keys as $session_key ) { + if ( in_array( $session_key, array( 'id', 'date_modified' ), true ) ) { + continue; + } + $function_key = $session_key; + if ( 'billing_' === substr( $session_key, 0, 8 ) ) { + $session_key = str_replace( 'billing_', '', $session_key ); + } + if ( isset( $data[ $session_key ] ) && is_callable( array( $customer, "set_{$function_key}" ) ) ) { + $customer->{"set_{$function_key}"}( wp_unslash( $data[ $session_key ] ) ); + } + } + } + $this->set_defaults( $customer ); + $customer->set_object_read( true ); + } + + /** + * Load default values if props are unset. + * + * @param WC_Customer $customer Customer object. + */ + protected function set_defaults( &$customer ) { + try { + $default = wc_get_customer_default_location(); + + if ( ! $customer->get_billing_country() ) { + $customer->set_billing_country( $default['country'] ); + } + + if ( ! $customer->get_shipping_country() ) { + $customer->set_shipping_country( $customer->get_billing_country() ); + } + + if ( ! $customer->get_billing_state() ) { + $customer->set_billing_state( $default['state'] ); + } + + if ( ! $customer->get_shipping_state() ) { + $customer->set_shipping_state( $customer->get_billing_state() ); + } + + if ( ! $customer->get_billing_email() && is_user_logged_in() ) { + $current_user = wp_get_current_user(); + $customer->set_billing_email( $current_user->user_email ); + } + } catch ( WC_Data_Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch + } + } + + /** + * Deletes a customer from the database. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + * @param array $args Array of args to pass to the delete method. + */ + public function delete( &$customer, $args = array() ) { + WC()->session->set( 'customer', null ); + } + + /** + * Gets the customers last order. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + * @return WC_Order|false + */ + public function get_last_order( &$customer ) { + return false; + } + + /** + * Return the number of orders this customer has. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + * @return integer + */ + public function get_order_count( &$customer ) { + return 0; + } + + /** + * Return how much money this customer has spent. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + * @return float + */ + public function get_total_spent( &$customer ) { + return 0; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store.php new file mode 100644 index 0000000..a772e45 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store.php @@ -0,0 +1,512 @@ +prefix ? $wpdb->prefix : 'wp_'; + + return ! in_array( $meta->meta_key, $this->internal_meta_keys, true ) + && 0 !== strpos( $meta->meta_key, '_woocommerce_persistent_cart' ) + && 0 !== strpos( $meta->meta_key, 'closedpostboxes_' ) + && 0 !== strpos( $meta->meta_key, 'metaboxhidden_' ) + && 0 !== strpos( $meta->meta_key, 'manageedit-' ) + && ! strstr( $meta->meta_key, $table_prefix ) + && 0 !== stripos( $meta->meta_key, 'wp_' ); + } + + /** + * Method to create a new customer in the database. + * + * @since 3.0.0 + * + * @param WC_Customer $customer Customer object. + * + * @throws WC_Data_Exception If unable to create new customer. + */ + public function create( &$customer ) { + $id = wc_create_new_customer( $customer->get_email(), $customer->get_username(), $customer->get_password() ); + + if ( is_wp_error( $id ) ) { + throw new WC_Data_Exception( $id->get_error_code(), $id->get_error_message() ); + } + + $customer->set_id( $id ); + $this->update_user_meta( $customer ); + + // Prevent wp_update_user calls in the same request and customer trigger the 'Notice of Password Changed' email. + $customer->set_password( '' ); + + wp_update_user( + apply_filters( + 'woocommerce_update_customer_args', + array( + 'ID' => $customer->get_id(), + 'role' => $customer->get_role(), + 'display_name' => $customer->get_display_name(), + ), + $customer + ) + ); + $wp_user = new WP_User( $customer->get_id() ); + $customer->set_date_created( $wp_user->user_registered ); + $customer->set_date_modified( get_user_meta( $customer->get_id(), 'last_update', true ) ); + $customer->save_meta_data(); + $customer->apply_changes(); + do_action( 'woocommerce_new_customer', $customer->get_id(), $customer ); + } + + /** + * Method to read a customer object. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + * @throws Exception If invalid customer. + */ + public function read( &$customer ) { + $user_object = $customer->get_id() ? get_user_by( 'id', $customer->get_id() ) : false; + + // User object is required. + if ( ! $user_object || empty( $user_object->ID ) ) { + throw new Exception( __( 'Invalid customer.', 'woocommerce' ) ); + } + + $customer_id = $customer->get_id(); + + // Load meta but exclude deprecated props. + $user_meta = array_diff_key( + array_change_key_case( array_map( 'wc_flatten_meta_callback', get_user_meta( $customer_id ) ) ), + array_flip( array( 'country', 'state', 'postcode', 'city', 'address', 'address_2', 'default', 'location' ) ) + ); + + $customer->set_props( $user_meta ); + $customer->set_props( + array( + 'is_paying_customer' => get_user_meta( $customer_id, 'paying_customer', true ), + 'email' => $user_object->user_email, + 'username' => $user_object->user_login, + 'display_name' => $user_object->display_name, + 'date_created' => $user_object->user_registered, // Mysql string in local format. + 'date_modified' => get_user_meta( $customer_id, 'last_update', true ), + 'role' => ! empty( $user_object->roles[0] ) ? $user_object->roles[0] : 'customer', + ) + ); + $customer->read_meta_data(); + $customer->set_object_read( true ); + do_action( 'woocommerce_customer_loaded', $customer ); + } + + /** + * Updates a customer in the database. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + */ + public function update( &$customer ) { + wp_update_user( + apply_filters( + 'woocommerce_update_customer_args', + array( + 'ID' => $customer->get_id(), + 'user_email' => $customer->get_email(), + 'display_name' => $customer->get_display_name(), + ), + $customer + ) + ); + + // Only update password if a new one was set with set_password. + if ( $customer->get_password() ) { + wp_update_user( + array( + 'ID' => $customer->get_id(), + 'user_pass' => $customer->get_password(), + ) + ); + $customer->set_password( '' ); + } + + $this->update_user_meta( $customer ); + $customer->set_date_modified( get_user_meta( $customer->get_id(), 'last_update', true ) ); + $customer->save_meta_data(); + $customer->apply_changes(); + do_action( 'woocommerce_update_customer', $customer->get_id(), $customer ); + } + + /** + * Deletes a customer from the database. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + * @param array $args Array of args to pass to the delete method. + */ + public function delete( &$customer, $args = array() ) { + if ( ! $customer->get_id() ) { + return; + } + + $args = wp_parse_args( + $args, + array( + 'reassign' => 0, + ) + ); + + $id = $customer->get_id(); + wp_delete_user( $id, $args['reassign'] ); + + do_action( 'woocommerce_delete_customer', $id ); + } + + /** + * Helper method that updates all the meta for a customer. Used for update & create. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + */ + private function update_user_meta( $customer ) { + $updated_props = array(); + $changed_props = $customer->get_changes(); + + $meta_key_to_props = array( + 'paying_customer' => 'is_paying_customer', + 'first_name' => 'first_name', + 'last_name' => 'last_name', + ); + + foreach ( $meta_key_to_props as $meta_key => $prop ) { + if ( ! array_key_exists( $prop, $changed_props ) ) { + continue; + } + + if ( update_user_meta( $customer->get_id(), $meta_key, $customer->{"get_$prop"}( 'edit' ) ) ) { + $updated_props[] = $prop; + } + } + + $billing_address_props = array( + 'billing_first_name' => 'billing_first_name', + 'billing_last_name' => 'billing_last_name', + 'billing_company' => 'billing_company', + 'billing_address_1' => 'billing_address_1', + 'billing_address_2' => 'billing_address_2', + 'billing_city' => 'billing_city', + 'billing_state' => 'billing_state', + 'billing_postcode' => 'billing_postcode', + 'billing_country' => 'billing_country', + 'billing_email' => 'billing_email', + 'billing_phone' => 'billing_phone', + ); + + foreach ( $billing_address_props as $meta_key => $prop ) { + $prop_key = substr( $prop, 8 ); + + if ( ! isset( $changed_props['billing'] ) || ! array_key_exists( $prop_key, $changed_props['billing'] ) ) { + continue; + } + + if ( update_user_meta( $customer->get_id(), $meta_key, $customer->{"get_$prop"}( 'edit' ) ) ) { + $updated_props[] = $prop; + } + } + + $shipping_address_props = array( + 'shipping_first_name' => 'shipping_first_name', + 'shipping_last_name' => 'shipping_last_name', + 'shipping_company' => 'shipping_company', + 'shipping_address_1' => 'shipping_address_1', + 'shipping_address_2' => 'shipping_address_2', + 'shipping_city' => 'shipping_city', + 'shipping_state' => 'shipping_state', + 'shipping_postcode' => 'shipping_postcode', + 'shipping_country' => 'shipping_country', + ); + + foreach ( $shipping_address_props as $meta_key => $prop ) { + $prop_key = substr( $prop, 9 ); + + if ( ! isset( $changed_props['shipping'] ) || ! array_key_exists( $prop_key, $changed_props['shipping'] ) ) { + continue; + } + + if ( update_user_meta( $customer->get_id(), $meta_key, $customer->{"get_$prop"}( 'edit' ) ) ) { + $updated_props[] = $prop; + } + } + + do_action( 'woocommerce_customer_object_updated_props', $customer, $updated_props ); + } + + /** + * Gets the customers last order. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + * @return WC_Order|false + */ + public function get_last_order( &$customer ) { + global $wpdb; + + $last_order = $wpdb->get_var( + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared + "SELECT posts.ID + FROM $wpdb->posts AS posts + LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id + WHERE meta.meta_key = '_customer_user' + AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "' + AND posts.post_type = 'shop_order' + AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' ) + ORDER BY posts.ID DESC" + // phpcs:enable + ); + + if ( ! $last_order ) { + return false; + } + + return wc_get_order( absint( $last_order ) ); + } + + /** + * Return the number of orders this customer has. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + * @return integer + */ + public function get_order_count( &$customer ) { + $count = get_user_meta( $customer->get_id(), '_order_count', true ); + + if ( '' === $count ) { + global $wpdb; + + $count = $wpdb->get_var( + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared + "SELECT COUNT(*) + FROM $wpdb->posts as posts + LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id + WHERE meta.meta_key = '_customer_user' + AND posts.post_type = 'shop_order' + AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' ) + AND meta_value = '" . esc_sql( $customer->get_id() ) . "'" + // phpcs:enable + ); + update_user_meta( $customer->get_id(), '_order_count', $count ); + } + + return absint( $count ); + } + + /** + * Return how much money this customer has spent. + * + * @since 3.0.0 + * @param WC_Customer $customer Customer object. + * @return float + */ + public function get_total_spent( &$customer ) { + $spent = apply_filters( + 'woocommerce_customer_get_total_spent', + get_user_meta( $customer->get_id(), '_money_spent', true ), + $customer + ); + + if ( '' === $spent ) { + global $wpdb; + + $statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() ); + $spent = $wpdb->get_var( + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared + apply_filters( + 'woocommerce_customer_get_total_spent_query', + "SELECT SUM(meta2.meta_value) + FROM $wpdb->posts as posts + LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id + LEFT JOIN {$wpdb->postmeta} AS meta2 ON posts.ID = meta2.post_id + WHERE meta.meta_key = '_customer_user' + AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "' + AND posts.post_type = 'shop_order' + AND posts.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' ) + AND meta2.meta_key = '_order_total'", + $customer + ) + // phpcs:enable + ); + + if ( ! $spent ) { + $spent = 0; + } + update_user_meta( $customer->get_id(), '_money_spent', $spent ); + } + + return wc_format_decimal( $spent, 2 ); + } + + /** + * Search customers and return customer IDs. + * + * @param string $term Search term. + * @param int|string $limit Limit search results. + * @since 3.0.7 + * + * @return array + */ + public function search_customers( $term, $limit = '' ) { + $results = apply_filters( 'woocommerce_customer_pre_search_customers', false, $term, $limit ); + if ( is_array( $results ) ) { + return $results; + } + + $query = new WP_User_Query( + apply_filters( + 'woocommerce_customer_search_customers', + array( + 'search' => '*' . esc_attr( $term ) . '*', + 'search_columns' => array( 'user_login', 'user_url', 'user_email', 'user_nicename', 'display_name' ), + 'fields' => 'ID', + 'number' => $limit, + ), + $term, + $limit, + 'main_query' + ) + ); + + $query2 = new WP_User_Query( + apply_filters( + 'woocommerce_customer_search_customers', + array( + 'fields' => 'ID', + 'number' => $limit, + 'meta_query' => array( + 'relation' => 'OR', + array( + 'key' => 'first_name', + 'value' => $term, + 'compare' => 'LIKE', + ), + array( + 'key' => 'last_name', + 'value' => $term, + 'compare' => 'LIKE', + ), + ), + ), + $term, + $limit, + 'meta_query' + ) + ); + + $results = wp_parse_id_list( array_merge( (array) $query->get_results(), (array) $query2->get_results() ) ); + + if ( $limit && count( $results ) > $limit ) { + $results = array_slice( $results, 0, $limit ); + } + + return $results; + } + + /** + * Get all user ids who have `billing_email` set to any of the email passed in array. + * + * @param array $emails List of emails to check against. + * + * @return array + */ + public function get_user_ids_for_billing_email( $emails ) { + $emails = array_unique( array_map( 'strtolower', array_map( 'sanitize_email', $emails ) ) ); + $users_query = new WP_User_Query( + array( + 'fields' => 'ID', + 'meta_query' => array( + array( + 'key' => 'billing_email', + 'value' => $emails, + 'compare' => 'IN', + ), + ), + ) + ); + return array_unique( $users_query->get_results() ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-download-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-download-data-store.php new file mode 100644 index 0000000..379e5fa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-download-data-store.php @@ -0,0 +1,447 @@ +get_access_granted( 'edit' ) ) ) { + $download->set_access_granted( time() ); + } + + $data = array( + 'download_id' => $download->get_download_id( 'edit' ), + 'product_id' => $download->get_product_id( 'edit' ), + 'user_id' => $download->get_user_id( 'edit' ), + 'user_email' => $download->get_user_email( 'edit' ), + 'order_id' => $download->get_order_id( 'edit' ), + 'order_key' => $download->get_order_key( 'edit' ), + 'downloads_remaining' => $download->get_downloads_remaining( 'edit' ), + 'access_granted' => date( 'Y-m-d', $download->get_access_granted( 'edit' )->getTimestamp() ), + 'download_count' => $download->get_download_count( 'edit' ), + 'access_expires' => ! is_null( $download->get_access_expires( 'edit' ) ) ? date( 'Y-m-d', $download->get_access_expires( 'edit' )->getTimestamp() ) : null, + ); + + $format = array( + '%s', + '%s', + '%s', + '%s', + '%s', + '%s', + '%s', + '%s', + '%d', + '%s', + ); + + $result = $wpdb->insert( + $wpdb->prefix . 'woocommerce_downloadable_product_permissions', + apply_filters( 'woocommerce_downloadable_file_permission_data', $data ), + apply_filters( 'woocommerce_downloadable_file_permission_format', $format, $data ) + ); + + if ( $result ) { + $download->set_id( $wpdb->insert_id ); + $download->apply_changes(); + } + + do_action( 'woocommerce_grant_product_download_access', $data ); + } + + /** + * Method to read a download permission from the database. + * + * @param WC_Customer_Download $download WC_Customer_Download object. + * + * @throws Exception Throw exception if invalid download is passed. + */ + public function read( &$download ) { + global $wpdb; + + if ( ! $download->get_id() ) { + throw new Exception( __( 'Invalid download.', 'woocommerce' ) ); + } + + $download->set_defaults(); + $raw_download = $wpdb->get_row( + $wpdb->prepare( + "SELECT * FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE permission_id = %d", + $download->get_id() + ) + ); + + if ( ! $raw_download ) { + throw new Exception( __( 'Invalid download.', 'woocommerce' ) ); + } + + $download->set_props( + array( + 'download_id' => $raw_download->download_id, + 'product_id' => $raw_download->product_id, + 'user_id' => $raw_download->user_id, + 'user_email' => $raw_download->user_email, + 'order_id' => $raw_download->order_id, + 'order_key' => $raw_download->order_key, + 'downloads_remaining' => $raw_download->downloads_remaining, + 'access_granted' => strtotime( $raw_download->access_granted ), + 'download_count' => $raw_download->download_count, + 'access_expires' => is_null( $raw_download->access_expires ) ? null : strtotime( $raw_download->access_expires ), + ) + ); + $download->set_object_read( true ); + } + + /** + * Method to update a download in the database. + * + * @param WC_Customer_Download $download WC_Customer_Download object. + */ + public function update( &$download ) { + global $wpdb; + + $data = array( + 'download_id' => $download->get_download_id( 'edit' ), + 'product_id' => $download->get_product_id( 'edit' ), + 'user_id' => $download->get_user_id( 'edit' ), + 'user_email' => $download->get_user_email( 'edit' ), + 'order_id' => $download->get_order_id( 'edit' ), + 'order_key' => $download->get_order_key( 'edit' ), + 'downloads_remaining' => $download->get_downloads_remaining( 'edit' ), + 'access_granted' => date( 'Y-m-d', $download->get_access_granted( 'edit' )->getTimestamp() ), + 'download_count' => $download->get_download_count( 'edit' ), + 'access_expires' => ! is_null( $download->get_access_expires( 'edit' ) ) ? date( 'Y-m-d', $download->get_access_expires( 'edit' )->getTimestamp() ) : null, + ); + + $format = array( + '%s', + '%s', + '%s', + '%s', + '%s', + '%s', + '%s', + '%s', + '%d', + '%s', + ); + + $wpdb->update( + $wpdb->prefix . 'woocommerce_downloadable_product_permissions', + $data, + array( + 'permission_id' => $download->get_id(), + ), + $format + ); + $download->apply_changes(); + } + + /** + * Method to delete a download permission from the database. + * + * @param WC_Customer_Download $download WC_Customer_Download object. + * @param array $args Array of args to pass to the delete method. + */ + public function delete( &$download, $args = array() ) { + global $wpdb; + + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE permission_id = %d", + $download->get_id() + ) + ); + + $download->set_id( 0 ); + } + + /** + * Method to delete a download permission from the database by ID. + * + * @param int $id permission_id of the download to be deleted. + */ + public function delete_by_id( $id ) { + global $wpdb; + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE permission_id = %d", + $id + ) + ); + } + + /** + * Method to delete a download permission from the database by order ID. + * + * @param int $id Order ID of the downloads that will be deleted. + */ + public function delete_by_order_id( $id ) { + global $wpdb; + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE order_id = %d", + $id + ) + ); + } + + /** + * Method to delete a download permission from the database by download ID. + * + * @param int $id download_id of the downloads that will be deleted. + */ + public function delete_by_download_id( $id ) { + global $wpdb; + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE download_id = %s", + $id + ) + ); + } + + /** + * Method to delete a download permission from the database by user ID. + * + * @since 3.4.0 + * @param int $id user ID of the downloads that will be deleted. + * @return bool True if deleted rows. + */ + public function delete_by_user_id( $id ) { + global $wpdb; + return (bool) $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE user_id = %d", + $id + ) + ); + } + + /** + * Method to delete a download permission from the database by user email. + * + * @since 3.4.0 + * @param string $email email of the downloads that will be deleted. + * @return bool True if deleted rows. + */ + public function delete_by_user_email( $email ) { + global $wpdb; + return (bool) $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE user_email = %s", + $email + ) + ); + } + + /** + * Get a download object. + * + * @param array $data From the DB. + * @return WC_Customer_Download + */ + private function get_download( $data ) { + return new WC_Customer_Download( $data ); + } + + /** + * Get array of download ids by specified args. + * + * @param array $args Arguments to filter downloads. $args['return'] accepts the following values: 'objects' (default), 'ids' or a comma separeted list of fields (for example: 'order_id,user_id,user_email'). + * @return array Can be an array of permission_ids, an array of WC_Customer_Download objects or an array of arrays containing specified fields depending on the value of $args['return']. + */ + public function get_downloads( $args = array() ) { + global $wpdb; + + $args = wp_parse_args( + $args, + array( + 'user_email' => '', + 'user_id' => '', + 'order_id' => '', + 'order_key' => '', + 'product_id' => '', + 'download_id' => '', + 'orderby' => 'permission_id', + 'order' => 'ASC', + 'limit' => -1, + 'page' => 1, + 'return' => 'objects', + ) + ); + + $valid_fields = array( 'permission_id', 'download_id', 'product_id', 'order_id', 'order_key', 'user_email', 'user_id', 'downloads_remaining', 'access_granted', 'access_expires', 'download_count' ); + $get_results_output = ARRAY_A; + + if ( 'ids' === $args['return'] ) { + $fields = 'permission_id'; + } elseif ( 'objects' === $args['return'] ) { + $fields = '*'; + $get_results_output = OBJECT; + } else { + $fields = explode( ',', (string) $args['return'] ); + $fields = implode( ', ', array_intersect( $fields, $valid_fields ) ); + } + + $query = array(); + $query[] = "SELECT {$fields} FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE 1=1"; + + if ( $args['user_email'] ) { + $query[] = $wpdb->prepare( 'AND user_email = %s', sanitize_email( $args['user_email'] ) ); + } + + if ( $args['user_id'] ) { + $query[] = $wpdb->prepare( 'AND user_id = %d', absint( $args['user_id'] ) ); + } + + if ( $args['order_id'] ) { + $query[] = $wpdb->prepare( 'AND order_id = %d', $args['order_id'] ); + } + + if ( $args['order_key'] ) { + $query[] = $wpdb->prepare( 'AND order_key = %s', $args['order_key'] ); + } + + if ( $args['product_id'] ) { + $query[] = $wpdb->prepare( 'AND product_id = %d', $args['product_id'] ); + } + + if ( $args['download_id'] ) { + $query[] = $wpdb->prepare( 'AND download_id = %s', $args['download_id'] ); + } + + $orderby = in_array( $args['orderby'], $valid_fields, true ) ? $args['orderby'] : 'permission_id'; + $order = 'DESC' === strtoupper( $args['order'] ) ? 'DESC' : 'ASC'; + $orderby_sql = sanitize_sql_orderby( "{$orderby} {$order}" ); + $query[] = "ORDER BY {$orderby_sql}"; + + if ( 0 < $args['limit'] ) { + $query[] = $wpdb->prepare( 'LIMIT %d, %d', absint( $args['limit'] ) * absint( $args['page'] - 1 ), absint( $args['limit'] ) ); + } + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $results = $wpdb->get_results( implode( ' ', $query ), $get_results_output ); + + switch ( $args['return'] ) { + case 'ids': + return wp_list_pluck( $results, 'permission_id' ); + case 'objects': + return array_map( array( $this, 'get_download' ), $results ); + default: + return $results; + } + } + + /** + * Update download ids if the hash changes. + * + * @deprecated 3.3.0 Download id is now a static UUID and should not be changed based on file hash. + * + * @param int $product_id Product ID. + * @param string $old_id Old download_id. + * @param string $new_id New download_id. + */ + public function update_download_id( $product_id, $old_id, $new_id ) { + global $wpdb; + + wc_deprecated_function( __METHOD__, '3.3' ); + + $wpdb->update( + $wpdb->prefix . 'woocommerce_downloadable_product_permissions', + array( + 'download_id' => $new_id, + ), + array( + 'download_id' => $old_id, + 'product_id' => $product_id, + ) + ); + } + + /** + * Get a customers downloads. + * + * @param int $customer_id Customer ID. + * @return array + */ + public function get_downloads_for_customer( $customer_id ) { + global $wpdb; + + return $wpdb->get_results( + $wpdb->prepare( + "SELECT * FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions as permissions + WHERE user_id = %d + AND permissions.order_id > 0 + AND + ( + permissions.downloads_remaining > 0 + OR permissions.downloads_remaining = '' + ) + AND + ( + permissions.access_expires IS NULL + OR permissions.access_expires >= %s + OR permissions.access_expires = '0000-00-00 00:00:00' + ) + ORDER BY permissions.order_id, permissions.product_id, permissions.permission_id;", + $customer_id, + date( 'Y-m-d', current_time( 'timestamp' ) ) + ) + ); + } + + /** + * Update user prop for downloads based on order id. + * + * @param int $order_id Order ID. + * @param int $customer_id Customer ID. + * @param string $email Customer email address. + */ + public function update_user_by_order_id( $order_id, $customer_id, $email ) { + global $wpdb; + $wpdb->update( + $wpdb->prefix . 'woocommerce_downloadable_product_permissions', + array( + 'user_id' => $customer_id, + 'user_email' => $email, + ), + array( + 'order_id' => $order_id, + ), + array( + '%d', + '%s', + ), + array( + '%d', + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-download-log-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-download-log-data-store.php new file mode 100644 index 0000000..12b59a5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-customer-download-log-data-store.php @@ -0,0 +1,239 @@ +get_timestamp( 'edit' ) ) ) { + $download_log->set_timestamp( time() ); + } + + $data = array( + 'timestamp' => date( 'Y-m-d H:i:s', $download_log->get_timestamp( 'edit' )->getTimestamp() ), + 'permission_id' => $download_log->get_permission_id( 'edit' ), + 'user_id' => $download_log->get_user_id( 'edit' ), + 'user_ip_address' => $download_log->get_user_ip_address( 'edit' ), + ); + + $format = array( + '%s', + '%s', + '%s', + '%s', + ); + + $result = $wpdb->insert( + $wpdb->prefix . self::get_table_name(), + apply_filters( 'woocommerce_downloadable_product_download_log_insert_data', $data ), + apply_filters( 'woocommerce_downloadable_product_download_log_insert_format', $format, $data ) + ); + + do_action( 'woocommerce_downloadable_product_download_log_insert', $data ); + + if ( $result ) { + $download_log->set_id( $wpdb->insert_id ); + $download_log->apply_changes(); + } else { + wp_die( esc_html__( 'Unable to insert download log entry in database.', 'woocommerce' ) ); + } + } + + /** + * Method to read a download log from the database. + * + * @param WC_Customer_Download_Log $download_log Download log object. + * @throws Exception Exception when read is not possible. + */ + public function read( &$download_log ) { + global $wpdb; + + $download_log->set_defaults(); + + // Ensure we have an id to pull from the DB. + if ( ! $download_log->get_id() ) { + throw new Exception( __( 'Invalid download log: no ID.', 'woocommerce' ) ); + } + + $table = $wpdb->prefix . self::get_table_name(); + + // Query the DB for the download log. + $raw_download_log = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE download_log_id = %d", $download_log->get_id() ) ); // WPCS: unprepared SQL ok. + + if ( ! $raw_download_log ) { + throw new Exception( __( 'Invalid download log: not found.', 'woocommerce' ) ); + } + + $download_log->set_props( + array( + 'timestamp' => strtotime( $raw_download_log->timestamp ), + 'permission_id' => $raw_download_log->permission_id, + 'user_id' => $raw_download_log->user_id, + 'user_ip_address' => $raw_download_log->user_ip_address, + ) + ); + + $download_log->set_object_read( true ); + } + + /** + * Method to update a download log in the database. + * + * @param WC_Customer_Download_Log $download_log Download log object. + */ + public function update( &$download_log ) { + global $wpdb; + + $data = array( + 'timestamp' => date( 'Y-m-d H:i:s', $download_log->get_timestamp( 'edit' )->getTimestamp() ), + 'permission_id' => $download_log->get_permission_id( 'edit' ), + 'user_id' => $download_log->get_user_id( 'edit' ), + 'user_ip_address' => $download_log->get_user_ip_address( 'edit' ), + ); + + $format = array( + '%s', + '%s', + '%s', + '%s', + ); + + $wpdb->update( + $wpdb->prefix . self::get_table_name(), + $data, + array( + 'download_log_id' => $download_log->get_id(), + ), + $format + ); + $download_log->apply_changes(); + } + + /** + * Get a download log object. + * + * @param array $data From the DB. + * @return WC_Customer_Download_Log + */ + private function get_download_log( $data ) { + return new WC_Customer_Download_Log( $data ); + } + + /** + * Get array of download log ids by specified args. + * + * @param array $args Arguments to define download logs to retrieve. + * @return array + */ + public function get_download_logs( $args = array() ) { + global $wpdb; + + $args = wp_parse_args( + $args, + array( + 'permission_id' => '', + 'user_id' => '', + 'user_ip_address' => '', + 'orderby' => 'download_log_id', + 'order' => 'ASC', + 'limit' => -1, + 'page' => 1, + 'return' => 'objects', + ) + ); + + $query = array(); + $table = $wpdb->prefix . self::get_table_name(); + $query[] = "SELECT * FROM {$table} WHERE 1=1"; + + if ( $args['permission_id'] ) { + $query[] = $wpdb->prepare( 'AND permission_id = %d', $args['permission_id'] ); + } + + if ( $args['user_id'] ) { + $query[] = $wpdb->prepare( 'AND user_id = %d', $args['user_id'] ); + } + + if ( $args['user_ip_address'] ) { + $query[] = $wpdb->prepare( 'AND user_ip_address = %s', $args['user_ip_address'] ); + } + + $allowed_orders = array( 'download_log_id', 'timestamp', 'permission_id', 'user_id' ); + $orderby = in_array( $args['orderby'], $allowed_orders, true ) ? $args['orderby'] : 'download_log_id'; + $order = 'DESC' === strtoupper( $args['order'] ) ? 'DESC' : 'ASC'; + $orderby_sql = sanitize_sql_orderby( "{$orderby} {$order}" ); + $query[] = "ORDER BY {$orderby_sql}"; + + if ( 0 < $args['limit'] ) { + $query[] = $wpdb->prepare( 'LIMIT %d, %d', absint( $args['limit'] ) * absint( $args['page'] - 1 ), absint( $args['limit'] ) ); + } + + $raw_download_logs = $wpdb->get_results( implode( ' ', $query ) ); // WPCS: unprepared SQL ok. + + switch ( $args['return'] ) { + case 'ids': + return wp_list_pluck( $raw_download_logs, 'download_log_id' ); + default: + return array_map( array( $this, 'get_download_log' ), $raw_download_logs ); + } + } + + /** + * Get download logs for a given download permission. + * + * @param int $permission_id Permission to get logs for. + * @return array + */ + public function get_download_logs_for_permission( $permission_id ) { + // If no permission_id is passed, return an empty array. + if ( empty( $permission_id ) ) { + return array(); + } + + return $this->get_download_logs( + array( + 'permission_id' => $permission_id, + ) + ); + } + + /** + * Method to delete download logs for a given permission ID. + * + * @since 3.4.0 + * @param int $id download_id of the downloads that will be deleted. + */ + public function delete_by_permission_id( $id ) { + global $wpdb; + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE permission_id = %d", $id ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-data-store-wp.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-data-store-wp.php new file mode 100644 index 0000000..d8b5edf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-data-store-wp.php @@ -0,0 +1,645 @@ +get_id(); + } + $terms = get_the_terms( $object_id, $taxonomy ); + if ( false === $terms || is_wp_error( $terms ) ) { + return array(); + } + return wp_list_pluck( $terms, 'term_id' ); + } + + /** + * Returns an array of meta for an object. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data object. + * @return array + */ + public function read_meta( &$object ) { + global $wpdb; + $db_info = $this->get_db_info(); + $raw_meta_data = $wpdb->get_results( + $wpdb->prepare( + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + "SELECT {$db_info['meta_id_field']} as meta_id, meta_key, meta_value + FROM {$db_info['table']} + WHERE {$db_info['object_id_field']} = %d + ORDER BY {$db_info['meta_id_field']}", + // phpcs:enable + $object->get_id() + ) + ); + + $this->internal_meta_keys = array_merge( array_map( array( $this, 'prefix_key' ), $object->get_data_keys() ), $this->internal_meta_keys ); + $meta_data = array_filter( $raw_meta_data, array( $this, 'exclude_internal_meta_keys' ) ); + return apply_filters( "woocommerce_data_store_wp_{$this->meta_type}_read_meta", $meta_data, $object, $this ); + } + + /** + * Deletes meta based on meta ID. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data object. + * @param stdClass $meta (containing at least ->id). + */ + public function delete_meta( &$object, $meta ) { + delete_metadata_by_mid( $this->meta_type, $meta->id ); + } + + /** + * Add new piece of meta. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data object. + * @param stdClass $meta (containing ->key and ->value). + * @return int meta ID + */ + public function add_meta( &$object, $meta ) { + return add_metadata( $this->meta_type, $object->get_id(), wp_slash( $meta->key ), is_string( $meta->value ) ? wp_slash( $meta->value ) : $meta->value, false ); + } + + /** + * Update meta. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data object. + * @param stdClass $meta (containing ->id, ->key and ->value). + */ + public function update_meta( &$object, $meta ) { + update_metadata_by_mid( $this->meta_type, $meta->id, $meta->value, $meta->key ); + } + + /** + * Table structure is slightly different between meta types, this function will return what we need to know. + * + * @since 3.0.0 + * @return array Array elements: table, object_id_field, meta_id_field + */ + protected function get_db_info() { + global $wpdb; + + $meta_id_field = 'meta_id'; // for some reason users calls this umeta_id so we need to track this as well. + $table = $wpdb->prefix; + + // If we are dealing with a type of metadata that is not a core type, the table should be prefixed. + if ( ! in_array( $this->meta_type, array( 'post', 'user', 'comment', 'term' ), true ) ) { + $table .= 'woocommerce_'; + } + + $table .= $this->meta_type . 'meta'; + $object_id_field = $this->meta_type . '_id'; + + // Figure out our field names. + if ( 'user' === $this->meta_type ) { + $meta_id_field = 'umeta_id'; + $table = $wpdb->usermeta; + } + + if ( ! empty( $this->object_id_field_for_meta ) ) { + $object_id_field = $this->object_id_field_for_meta; + } + + return array( + 'table' => $table, + 'object_id_field' => $object_id_field, + 'meta_id_field' => $meta_id_field, + ); + } + + /** + * Internal meta keys we don't want exposed as part of meta_data. This is in + * addition to all data props with _ prefix. + * + * @since 2.6.0 + * + * @param string $key Prefix to be added to meta keys. + * @return string + */ + protected function prefix_key( $key ) { + return '_' === substr( $key, 0, 1 ) ? $key : '_' . $key; + } + + /** + * Callback to remove unwanted meta data. + * + * @param object $meta Meta object to check if it should be excluded or not. + * @return bool + */ + protected function exclude_internal_meta_keys( $meta ) { + return ! in_array( $meta->meta_key, $this->internal_meta_keys, true ) && 0 !== stripos( $meta->meta_key, 'wp_' ); + } + + /** + * Gets a list of props and meta keys that need updated based on change state + * or if they are present in the database or not. + * + * @param WC_Data $object The WP_Data object (WC_Coupon for coupons, etc). + * @param array $meta_key_to_props A mapping of meta keys => prop names. + * @param string $meta_type The internal WP meta type (post, user, etc). + * @return array A mapping of meta keys => prop names, filtered by ones that should be updated. + */ + protected function get_props_to_update( $object, $meta_key_to_props, $meta_type = 'post' ) { + $props_to_update = array(); + $changed_props = $object->get_changes(); + + // Props should be updated if they are a part of the $changed array or don't exist yet. + foreach ( $meta_key_to_props as $meta_key => $prop ) { + if ( array_key_exists( $prop, $changed_props ) || ! metadata_exists( $meta_type, $object->get_id(), $meta_key ) ) { + $props_to_update[ $meta_key ] = $prop; + } + } + + return $props_to_update; + } + + /** + * Update meta data in, or delete it from, the database. + * + * Avoids storing meta when it's either an empty string or empty array. + * Other empty values such as numeric 0 and null should still be stored. + * Data-stores can force meta to exist using `must_exist_meta_keys`. + * + * Note: WordPress `get_metadata` function returns an empty string when meta data does not exist. + * + * @param WC_Data $object The WP_Data object (WC_Coupon for coupons, etc). + * @param string $meta_key Meta key to update. + * @param mixed $meta_value Value to save. + * + * @since 3.6.0 Added to prevent empty meta being stored unless required. + * + * @return bool True if updated/deleted. + */ + protected function update_or_delete_post_meta( $object, $meta_key, $meta_value ) { + if ( in_array( $meta_value, array( array(), '' ), true ) && ! in_array( $meta_key, $this->must_exist_meta_keys, true ) ) { + $updated = delete_post_meta( $object->get_id(), $meta_key ); + } else { + $updated = update_post_meta( $object->get_id(), $meta_key, $meta_value ); + } + + return (bool) $updated; + } + + /** + * Get valid WP_Query args from a WC_Object_Query's query variables. + * + * @since 3.1.0 + * @param array $query_vars query vars from a WC_Object_Query. + * @return array + */ + protected function get_wp_query_args( $query_vars ) { + + $skipped_values = array( '', array(), null ); + $wp_query_args = array( + 'errors' => array(), + 'meta_query' => array(), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + ); + + foreach ( $query_vars as $key => $value ) { + if ( in_array( $value, $skipped_values, true ) || 'meta_query' === $key ) { + continue; + } + + // Build meta queries out of vars that are stored in internal meta keys. + if ( in_array( '_' . $key, $this->internal_meta_keys, true ) ) { + // Check for existing values if wildcard is used. + if ( '*' === $value ) { + $wp_query_args['meta_query'][] = array( + array( + 'key' => '_' . $key, + 'compare' => 'EXISTS', + ), + array( + 'key' => '_' . $key, + 'value' => '', + 'compare' => '!=', + ), + ); + } else { + $wp_query_args['meta_query'][] = array( + 'key' => '_' . $key, + 'value' => $value, + 'compare' => is_array( $value ) ? 'IN' : '=', + ); + } + } else { // Other vars get mapped to wp_query args or just left alone. + $key_mapping = array( + 'parent' => 'post_parent', + 'parent_exclude' => 'post_parent__not_in', + 'exclude' => 'post__not_in', + 'limit' => 'posts_per_page', + 'type' => 'post_type', + 'return' => 'fields', + ); + + if ( isset( $key_mapping[ $key ] ) ) { + $wp_query_args[ $key_mapping[ $key ] ] = $value; + } else { + $wp_query_args[ $key ] = $value; + } + } + } + + return apply_filters( 'woocommerce_get_wp_query_args', $wp_query_args, $query_vars ); + } + + /** + * Map a valid date query var to WP_Query arguments. + * Valid date formats: YYYY-MM-DD or timestamp, possibly combined with an operator from $valid_operators. + * Also accepts a WC_DateTime object. + * + * @since 3.2.0 + * @param mixed $query_var A valid date format. + * @param string $key meta or db column key. + * @param array $wp_query_args WP_Query args. + * @return array Modified $wp_query_args + */ + public function parse_date_for_wp_query( $query_var, $key, $wp_query_args = array() ) { + $query_parse_regex = '/([^.<>]*)(>=|<=|>|<|\.\.\.)([^.<>]+)/'; + $valid_operators = array( '>', '>=', '=', '<=', '<', '...' ); + + // YYYY-MM-DD queries have 'day' precision. Timestamp/WC_DateTime queries have 'second' precision. + $precision = 'second'; + + $dates = array(); + $operator = '='; + + try { + // Specific time query with a WC_DateTime. + if ( is_a( $query_var, 'WC_DateTime' ) ) { + $dates[] = $query_var; + } elseif ( is_numeric( $query_var ) ) { // Specific time query with a timestamp. + $dates[] = new WC_DateTime( "@{$query_var}", new DateTimeZone( 'UTC' ) ); + } elseif ( preg_match( $query_parse_regex, $query_var, $sections ) ) { // Query with operators and possible range of dates. + if ( ! empty( $sections[1] ) ) { + $dates[] = is_numeric( $sections[1] ) ? new WC_DateTime( "@{$sections[1]}", new DateTimeZone( 'UTC' ) ) : wc_string_to_datetime( $sections[1] ); + } + + $operator = in_array( $sections[2], $valid_operators, true ) ? $sections[2] : ''; + $dates[] = is_numeric( $sections[3] ) ? new WC_DateTime( "@{$sections[3]}", new DateTimeZone( 'UTC' ) ) : wc_string_to_datetime( $sections[3] ); + + if ( ! is_numeric( $sections[1] ) && ! is_numeric( $sections[3] ) ) { + $precision = 'day'; + } + } else { // Specific time query with a string. + $dates[] = wc_string_to_datetime( $query_var ); + $precision = 'day'; + } + } catch ( Exception $e ) { + return $wp_query_args; + } + + // Check for valid inputs. + if ( ! $operator || empty( $dates ) || ( '...' === $operator && count( $dates ) < 2 ) ) { + return $wp_query_args; + } + + // Build date query for 'post_date' or 'post_modified' keys. + if ( 'post_date' === $key || 'post_modified' === $key ) { + if ( ! isset( $wp_query_args['date_query'] ) ) { + $wp_query_args['date_query'] = array(); + } + + $query_arg = array( + 'column' => 'day' === $precision ? $key : $key . '_gmt', + 'inclusive' => '>' !== $operator && '<' !== $operator, + ); + + // Add 'before'/'after' query args. + $comparisons = array(); + if ( '>' === $operator || '>=' === $operator || '...' === $operator ) { + $comparisons[] = 'after'; + } + if ( '<' === $operator || '<=' === $operator || '...' === $operator ) { + $comparisons[] = 'before'; + } + + foreach ( $comparisons as $index => $comparison ) { + if ( 'day' === $precision ) { + /** + * WordPress doesn't generate the correct SQL for inclusive day queries with both a 'before' and + * 'after' string query, so we have to use the array format in 'day' precision. + * + * @see https://core.trac.wordpress.org/ticket/29908 + */ + $query_arg[ $comparison ]['year'] = $dates[ $index ]->date( 'Y' ); + $query_arg[ $comparison ]['month'] = $dates[ $index ]->date( 'n' ); + $query_arg[ $comparison ]['day'] = $dates[ $index ]->date( 'j' ); + } else { + /** + * WordPress doesn't support 'hour'/'second'/'minute' in array format 'before'/'after' queries, + * so we have to use a string query. + */ + $query_arg[ $comparison ] = gmdate( 'm/d/Y H:i:s', $dates[ $index ]->getTimestamp() ); + } + } + + if ( empty( $comparisons ) ) { + $query_arg['year'] = $dates[0]->date( 'Y' ); + $query_arg['month'] = $dates[0]->date( 'n' ); + $query_arg['day'] = $dates[0]->date( 'j' ); + if ( 'second' === $precision ) { + $query_arg['hour'] = $dates[0]->date( 'H' ); + $query_arg['minute'] = $dates[0]->date( 'i' ); + $query_arg['second'] = $dates[0]->date( 's' ); + } + } + $wp_query_args['date_query'][] = $query_arg; + return $wp_query_args; + } + + // Build meta query for unrecognized keys. + if ( ! isset( $wp_query_args['meta_query'] ) ) { + $wp_query_args['meta_query'] = array(); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + } + + // Meta dates are stored as timestamps in the db. + // Check against beginning/end-of-day timestamps when using 'day' precision. + if ( 'day' === $precision ) { + $start_timestamp = strtotime( gmdate( 'm/d/Y 00:00:00', $dates[0]->getTimestamp() ) ); + $end_timestamp = '...' !== $operator ? ( $start_timestamp + DAY_IN_SECONDS ) : strtotime( gmdate( 'm/d/Y 00:00:00', $dates[1]->getTimestamp() ) ); + switch ( $operator ) { + case '>': + case '<=': + $wp_query_args['meta_query'][] = array( + 'key' => $key, + 'value' => $end_timestamp, + 'compare' => $operator, + ); + break; + case '<': + case '>=': + $wp_query_args['meta_query'][] = array( + 'key' => $key, + 'value' => $start_timestamp, + 'compare' => $operator, + ); + break; + default: + $wp_query_args['meta_query'][] = array( + 'key' => $key, + 'value' => $start_timestamp, + 'compare' => '>=', + ); + $wp_query_args['meta_query'][] = array( + 'key' => $key, + 'value' => $end_timestamp, + 'compare' => '<=', + ); + } + } else { + if ( '...' !== $operator ) { + $wp_query_args['meta_query'][] = array( + 'key' => $key, + 'value' => $dates[0]->getTimestamp(), + 'compare' => $operator, + ); + } else { + $wp_query_args['meta_query'][] = array( + 'key' => $key, + 'value' => $dates[0]->getTimestamp(), + 'compare' => '>=', + ); + $wp_query_args['meta_query'][] = array( + 'key' => $key, + 'value' => $dates[1]->getTimestamp(), + 'compare' => '<=', + ); + } + } + + return $wp_query_args; + } + + /** + * Return list of internal meta keys. + * + * @since 3.2.0 + * @return array + */ + public function get_internal_meta_keys() { + return $this->internal_meta_keys; + } + + /** + * Check if the terms are suitable for searching. + * + * Uses an array of stopwords (terms) that are excluded from the separate + * term matching when searching for posts. The list of English stopwords is + * the approximate search engines list, and is translatable. + * + * @since 3.4.0 + * @param array $terms Terms to check. + * @return array Terms that are not stopwords. + */ + protected function get_valid_search_terms( $terms ) { + $valid_terms = array(); + $stopwords = $this->get_search_stopwords(); + + foreach ( $terms as $term ) { + // keep before/after spaces when term is for exact match, otherwise trim quotes and spaces. + if ( preg_match( '/^".+"$/', $term ) ) { + $term = trim( $term, "\"'" ); + } else { + $term = trim( $term, "\"' " ); + } + + // Avoid single A-Z and single dashes. + if ( empty( $term ) || ( 1 === strlen( $term ) && preg_match( '/^[a-z\-]$/i', $term ) ) ) { + continue; + } + + if ( in_array( wc_strtolower( $term ), $stopwords, true ) ) { + continue; + } + + $valid_terms[] = $term; + } + + return $valid_terms; + } + + /** + * Retrieve stopwords used when parsing search terms. + * + * @since 3.4.0 + * @return array Stopwords. + */ + protected function get_search_stopwords() { + // Translators: This is a comma-separated list of very common words that should be excluded from a search, like a, an, and the. These are usually called "stopwords". You should not simply translate these individual words into your language. Instead, look for and provide commonly accepted stopwords in your language. + $stopwords = array_map( + 'wc_strtolower', + array_map( + 'trim', + explode( + ',', + _x( + 'about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www', + 'Comma-separated list of search stopwords in your language', + 'woocommerce' + ) + ) + ) + ); + + return apply_filters( 'wp_search_stopwords', $stopwords ); + } + + /** + * Get data to save to a lookup table. + * + * @since 3.6.0 + * @param int $id ID of object to update. + * @param string $table Lookup table name. + * @return array + */ + protected function get_data_for_lookup_table( $id, $table ) { + return array(); + } + + /** + * Get primary key name for lookup table. + * + * @since 3.6.0 + * @param string $table Lookup table name. + * @return string + */ + protected function get_primary_key_for_lookup_table( $table ) { + return ''; + } + + /** + * Update a lookup table for an object. + * + * @since 3.6.0 + * @param int $id ID of object to update. + * @param string $table Lookup table name. + * + * @return NULL + */ + protected function update_lookup_table( $id, $table ) { + global $wpdb; + + $id = absint( $id ); + $table = sanitize_key( $table ); + + if ( empty( $id ) || empty( $table ) ) { + return false; + } + + $existing_data = wp_cache_get( 'lookup_table', 'object_' . $id ); + $update_data = $this->get_data_for_lookup_table( $id, $table ); + + if ( ! empty( $update_data ) && $update_data !== $existing_data ) { + $wpdb->replace( + $wpdb->$table, + $update_data + ); + wp_cache_set( 'lookup_table', $update_data, 'object_' . $id ); + } + } + + /** + * Delete lookup table data for an ID. + * + * @since 3.6.0 + * @param int $id ID of object to update. + * @param string $table Lookup table name. + */ + public function delete_from_lookup_table( $id, $table ) { + global $wpdb; + + $id = absint( $id ); + $table = sanitize_key( $table ); + + if ( empty( $id ) || empty( $table ) ) { + return false; + } + + $pk = $this->get_primary_key_for_lookup_table( $table ); + + $wpdb->delete( + $wpdb->$table, + array( + $pk => $id, + ) + ); + wp_cache_delete( 'lookup_table', 'object_' . $id ); + } + + /** + * Converts a WP post date string into a timestamp. + * + * @since 4.8.0 + * + * @param string $time_string The WP post date string. + * @return int|null The date string converted to a timestamp or null. + */ + protected function string_to_timestamp( $time_string ) { + return '0000-00-00 00:00:00' !== $time_string ? wc_string_to_timestamp( $time_string ) : null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php new file mode 100644 index 0000000..0e19ecd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php @@ -0,0 +1,893 @@ +get_order_key() ) { + $order->set_order_key( wc_generate_order_key() ); + } + parent::create( $order ); + do_action( 'woocommerce_new_order', $order->get_id(), $order ); + } + + /** + * Read order data. Can be overridden by child classes to load other props. + * + * @param WC_Order $order Order object. + * @param object $post_object Post object. + * @since 3.0.0 + */ + protected function read_order_data( &$order, $post_object ) { + parent::read_order_data( $order, $post_object ); + $id = $order->get_id(); + $date_completed = get_post_meta( $id, '_date_completed', true ); + $date_paid = get_post_meta( $id, '_date_paid', true ); + + if ( ! $date_completed ) { + $date_completed = get_post_meta( $id, '_completed_date', true ); + } + + if ( ! $date_paid ) { + $date_paid = get_post_meta( $id, '_paid_date', true ); + } + + $order->set_props( + array( + 'order_key' => get_post_meta( $id, '_order_key', true ), + 'customer_id' => get_post_meta( $id, '_customer_user', true ), + 'billing_first_name' => get_post_meta( $id, '_billing_first_name', true ), + 'billing_last_name' => get_post_meta( $id, '_billing_last_name', true ), + 'billing_company' => get_post_meta( $id, '_billing_company', true ), + 'billing_address_1' => get_post_meta( $id, '_billing_address_1', true ), + 'billing_address_2' => get_post_meta( $id, '_billing_address_2', true ), + 'billing_city' => get_post_meta( $id, '_billing_city', true ), + 'billing_state' => get_post_meta( $id, '_billing_state', true ), + 'billing_postcode' => get_post_meta( $id, '_billing_postcode', true ), + 'billing_country' => get_post_meta( $id, '_billing_country', true ), + 'billing_email' => get_post_meta( $id, '_billing_email', true ), + 'billing_phone' => get_post_meta( $id, '_billing_phone', true ), + 'shipping_first_name' => get_post_meta( $id, '_shipping_first_name', true ), + 'shipping_last_name' => get_post_meta( $id, '_shipping_last_name', true ), + 'shipping_company' => get_post_meta( $id, '_shipping_company', true ), + 'shipping_address_1' => get_post_meta( $id, '_shipping_address_1', true ), + 'shipping_address_2' => get_post_meta( $id, '_shipping_address_2', true ), + 'shipping_city' => get_post_meta( $id, '_shipping_city', true ), + 'shipping_state' => get_post_meta( $id, '_shipping_state', true ), + 'shipping_postcode' => get_post_meta( $id, '_shipping_postcode', true ), + 'shipping_country' => get_post_meta( $id, '_shipping_country', true ), + 'payment_method' => get_post_meta( $id, '_payment_method', true ), + 'payment_method_title' => get_post_meta( $id, '_payment_method_title', true ), + 'transaction_id' => get_post_meta( $id, '_transaction_id', true ), + 'customer_ip_address' => get_post_meta( $id, '_customer_ip_address', true ), + 'customer_user_agent' => get_post_meta( $id, '_customer_user_agent', true ), + 'created_via' => get_post_meta( $id, '_created_via', true ), + 'date_completed' => $date_completed, + 'date_paid' => $date_paid, + 'cart_hash' => get_post_meta( $id, '_cart_hash', true ), + 'customer_note' => $post_object->post_excerpt, + ) + ); + } + + /** + * Method to update an order in the database. + * + * @param WC_Order $order Order object. + */ + public function update( &$order ) { + // Before updating, ensure date paid is set if missing. + if ( ! $order->get_date_paid( 'edit' ) && version_compare( $order->get_version( 'edit' ), '3.0', '<' ) && $order->has_status( apply_filters( 'woocommerce_payment_complete_order_status', $order->needs_processing() ? 'processing' : 'completed', $order->get_id(), $order ) ) ) { + $order->set_date_paid( $order->get_date_created( 'edit' ) ); + } + + // Also grab the current status so we can compare. + $previous_status = get_post_status( $order->get_id() ); + + // Update the order. + parent::update( $order ); + + // Fire a hook depending on the status - this should be considered a creation if it was previously draft status. + $new_status = $order->get_status( 'edit' ); + + if ( $new_status !== $previous_status && in_array( $previous_status, array( 'new', 'auto-draft', 'draft' ), true ) ) { + do_action( 'woocommerce_new_order', $order->get_id(), $order ); + } else { + do_action( 'woocommerce_update_order', $order->get_id(), $order ); + } + } + + /** + * Helper method that updates all the post meta for an order based on it's settings in the WC_Order class. + * + * @param WC_Order $order Order object. + * @since 3.0.0 + */ + protected function update_post_meta( &$order ) { + $updated_props = array(); + $id = $order->get_id(); + $meta_key_to_props = array( + '_order_key' => 'order_key', + '_customer_user' => 'customer_id', + '_payment_method' => 'payment_method', + '_payment_method_title' => 'payment_method_title', + '_transaction_id' => 'transaction_id', + '_customer_ip_address' => 'customer_ip_address', + '_customer_user_agent' => 'customer_user_agent', + '_created_via' => 'created_via', + '_date_completed' => 'date_completed', + '_date_paid' => 'date_paid', + '_cart_hash' => 'cart_hash', + ); + + $props_to_update = $this->get_props_to_update( $order, $meta_key_to_props ); + + foreach ( $props_to_update as $meta_key => $prop ) { + $value = $order->{"get_$prop"}( 'edit' ); + $value = is_string( $value ) ? wp_slash( $value ) : $value; + switch ( $prop ) { + case 'date_paid': + case 'date_completed': + $value = ! is_null( $value ) ? $value->getTimestamp() : ''; + break; + } + + $updated = $this->update_or_delete_post_meta( $order, $meta_key, $value ); + + if ( $updated ) { + $updated_props[] = $prop; + } + } + + $address_props = array( + 'billing' => array( + '_billing_first_name' => 'billing_first_name', + '_billing_last_name' => 'billing_last_name', + '_billing_company' => 'billing_company', + '_billing_address_1' => 'billing_address_1', + '_billing_address_2' => 'billing_address_2', + '_billing_city' => 'billing_city', + '_billing_state' => 'billing_state', + '_billing_postcode' => 'billing_postcode', + '_billing_country' => 'billing_country', + '_billing_email' => 'billing_email', + '_billing_phone' => 'billing_phone', + ), + 'shipping' => array( + '_shipping_first_name' => 'shipping_first_name', + '_shipping_last_name' => 'shipping_last_name', + '_shipping_company' => 'shipping_company', + '_shipping_address_1' => 'shipping_address_1', + '_shipping_address_2' => 'shipping_address_2', + '_shipping_city' => 'shipping_city', + '_shipping_state' => 'shipping_state', + '_shipping_postcode' => 'shipping_postcode', + '_shipping_country' => 'shipping_country', + ), + ); + + foreach ( $address_props as $props_key => $props ) { + $props_to_update = $this->get_props_to_update( $order, $props ); + foreach ( $props_to_update as $meta_key => $prop ) { + $value = $order->{"get_$prop"}( 'edit' ); + $value = is_string( $value ) ? wp_slash( $value ) : $value; + $updated = $this->update_or_delete_post_meta( $order, $meta_key, $value ); + + if ( $updated ) { + $updated_props[] = $prop; + $updated_props[] = $props_key; + } + } + } + + parent::update_post_meta( $order ); + + // If address changed, store concatenated version to make searches faster. + if ( in_array( 'billing', $updated_props, true ) || ! metadata_exists( 'post', $id, '_billing_address_index' ) ) { + update_post_meta( $id, '_billing_address_index', implode( ' ', $order->get_address( 'billing' ) ) ); + } + if ( in_array( 'shipping', $updated_props, true ) || ! metadata_exists( 'post', $id, '_shipping_address_index' ) ) { + update_post_meta( $id, '_shipping_address_index', implode( ' ', $order->get_address( 'shipping' ) ) ); + } + + // Legacy date handling. @todo remove in 4.0. + if ( in_array( 'date_paid', $updated_props, true ) ) { + $value = $order->get_date_paid( 'edit' ); + // In 2.6.x date_paid was stored as _paid_date in local mysql format. + update_post_meta( $id, '_paid_date', ! is_null( $value ) ? $value->date( 'Y-m-d H:i:s' ) : '' ); + } + + if ( in_array( 'date_completed', $updated_props, true ) ) { + $value = $order->get_date_completed( 'edit' ); + // In 2.6.x date_completed was stored as _completed_date in local mysql format. + update_post_meta( $id, '_completed_date', ! is_null( $value ) ? $value->date( 'Y-m-d H:i:s' ) : '' ); + } + + // If customer changed, update any downloadable permissions. + if ( in_array( 'customer_id', $updated_props ) || in_array( 'billing_email', $updated_props ) ) { + $data_store = WC_Data_Store::load( 'customer-download' ); + $data_store->update_user_by_order_id( $id, $order->get_customer_id(), $order->get_billing_email() ); + } + + // Mark user account as active. + if ( in_array( 'customer_id', $updated_props, true ) ) { + wc_update_user_last_active( $order->get_customer_id() ); + } + + do_action( 'woocommerce_order_object_updated_props', $order, $updated_props ); + } + + /** + * Excerpt for post. + * + * @param WC_Order $order Order object. + * @return string + */ + protected function get_post_excerpt( $order ) { + return $order->get_customer_note(); + } + + /** + * Get order key. + * + * @since 4.3.0 + * @param WC_order $order Order object. + * @return string + */ + protected function get_order_key( $order ) { + if ( '' !== $order->get_order_key() ) { + return $order->get_order_key(); + } + + return parent::get_order_key( $order ); + } + + /** + * Get amount already refunded. + * + * @param WC_Order $order Order object. + * @return float + */ + public function get_total_refunded( $order ) { + global $wpdb; + + $total = $wpdb->get_var( + $wpdb->prepare( + "SELECT SUM( postmeta.meta_value ) + FROM $wpdb->postmeta AS postmeta + INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) + WHERE postmeta.meta_key = '_refund_amount' + AND postmeta.post_id = posts.ID", + $order->get_id() + ) + ); + + return floatval( $total ); + } + + /** + * Get the total tax refunded. + * + * @param WC_Order $order Order object. + * @return float + */ + public function get_total_tax_refunded( $order ) { + global $wpdb; + + $total = $wpdb->get_var( + $wpdb->prepare( + "SELECT SUM( order_itemmeta.meta_value ) + FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta + INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) + INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'tax' ) + WHERE order_itemmeta.order_item_id = order_items.order_item_id + AND order_itemmeta.meta_key IN ('tax_amount', 'shipping_tax_amount')", + $order->get_id() + ) + ); + + return abs( $total ); + } + + /** + * Get the total shipping refunded. + * + * @param WC_Order $order Order object. + * @return float + */ + public function get_total_shipping_refunded( $order ) { + global $wpdb; + + $total = $wpdb->get_var( + $wpdb->prepare( + "SELECT SUM( order_itemmeta.meta_value ) + FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta + INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) + INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'shipping' ) + WHERE order_itemmeta.order_item_id = order_items.order_item_id + AND order_itemmeta.meta_key IN ('cost')", + $order->get_id() + ) + ); + + return abs( $total ); + } + + /** + * Finds an Order ID based on an order key. + * + * @param string $order_key An order key has generated by. + * @return int The ID of an order, or 0 if the order could not be found + */ + public function get_order_id_by_order_key( $order_key ) { + global $wpdb; + return $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = '_order_key' AND meta_value = %s", $order_key ) ); + } + + /** + * Return count of orders with a specific status. + * + * @param string $status Order status. Function wc_get_order_statuses() returns a list of valid statuses. + * @return int + */ + public function get_order_count( $status ) { + global $wpdb; + return absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( * ) FROM {$wpdb->posts} WHERE post_type = 'shop_order' AND post_status = %s", $status ) ) ); + } + + /** + * Get all orders matching the passed in args. + * + * @deprecated 3.1.0 - Use wc_get_orders instead. + * @see wc_get_orders() + * + * @param array $args List of args passed to wc_get_orders(). + * + * @return array|object + */ + public function get_orders( $args = array() ) { + wc_deprecated_function( 'WC_Order_Data_Store_CPT::get_orders', '3.1.0', 'Use wc_get_orders instead.' ); + return wc_get_orders( $args ); + } + + /** + * Generate meta query for wc_get_orders. + * + * @param array $values List of customers ids or emails. + * @param string $relation 'or' or 'and' relation used to build the WP meta_query. + * @return array + */ + private function get_orders_generate_customer_meta_query( $values, $relation = 'or' ) { + $meta_query = array( + 'relation' => strtoupper( $relation ), + 'customer_emails' => array( + 'key' => '_billing_email', + 'value' => array(), + 'compare' => 'IN', + ), + 'customer_ids' => array( + 'key' => '_customer_user', + 'value' => array(), + 'compare' => 'IN', + ), + ); + foreach ( $values as $value ) { + if ( is_array( $value ) ) { + $query_part = $this->get_orders_generate_customer_meta_query( $value, 'and' ); + if ( is_wp_error( $query_part ) ) { + return $query_part; + } + $meta_query[] = $query_part; + } elseif ( is_email( $value ) ) { + $meta_query['customer_emails']['value'][] = sanitize_email( $value ); + } elseif ( is_numeric( $value ) ) { + $meta_query['customer_ids']['value'][] = strval( absint( $value ) ); + } else { + return new WP_Error( 'woocommerce_query_invalid', __( 'Invalid customer query.', 'woocommerce' ), $values ); + } + } + + if ( empty( $meta_query['customer_emails']['value'] ) ) { + unset( $meta_query['customer_emails'] ); + unset( $meta_query['relation'] ); + } + + if ( empty( $meta_query['customer_ids']['value'] ) ) { + unset( $meta_query['customer_ids'] ); + unset( $meta_query['relation'] ); + } + + return $meta_query; + } + + /** + * Get unpaid orders after a certain date, + * + * @param int $date Timestamp. + * @return array + */ + public function get_unpaid_orders( $date ) { + global $wpdb; + + $unpaid_orders = $wpdb->get_col( + $wpdb->prepare( + // @codingStandardsIgnoreStart + "SELECT posts.ID + FROM {$wpdb->posts} AS posts + WHERE posts.post_type IN ('" . implode( "','", wc_get_order_types() ) . "') + AND posts.post_status = 'wc-pending' + AND posts.post_modified < %s", + // @codingStandardsIgnoreEnd + gmdate( 'Y-m-d H:i:s', absint( $date ) ) + ) + ); + + return $unpaid_orders; + } + + /** + * Search order data for a term and return ids. + * + * @param string $term Searched term. + * @return array of ids + */ + public function search_orders( $term ) { + global $wpdb; + + /** + * Searches on meta data can be slow - this lets you choose what fields to search. + * 3.0.0 added _billing_address and _shipping_address meta which contains all address data to make this faster. + * This however won't work on older orders unless updated, so search a few others (expand this using the filter if needed). + * + * @var array + */ + $search_fields = array_map( + 'wc_clean', + apply_filters( + 'woocommerce_shop_order_search_fields', + array( + '_billing_address_index', + '_shipping_address_index', + '_billing_last_name', + '_billing_email', + ) + ) + ); + $order_ids = array(); + + if ( is_numeric( $term ) ) { + $order_ids[] = absint( $term ); + } + + if ( ! empty( $search_fields ) ) { + $order_ids = array_unique( + array_merge( + $order_ids, + $wpdb->get_col( + $wpdb->prepare( + "SELECT DISTINCT p1.post_id FROM {$wpdb->postmeta} p1 WHERE p1.meta_value LIKE %s AND p1.meta_key IN ('" . implode( "','", array_map( 'esc_sql', $search_fields ) ) . "')", // @codingStandardsIgnoreLine + '%' . $wpdb->esc_like( wc_clean( $term ) ) . '%' + ) + ), + $wpdb->get_col( + $wpdb->prepare( + "SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items as order_items + WHERE order_item_name LIKE %s", + '%' . $wpdb->esc_like( wc_clean( $term ) ) . '%' + ) + ) + ) + ); + } + + return apply_filters( 'woocommerce_shop_order_search_results', $order_ids, $term, $search_fields ); + } + + /** + * Gets information about whether permissions were generated yet. + * + * @param WC_Order|int $order Order ID or order object. + * @return bool + */ + public function get_download_permissions_granted( $order ) { + $order_id = WC_Order_Factory::get_order_id( $order ); + return wc_string_to_bool( get_post_meta( $order_id, '_download_permissions_granted', true ) ); + } + + /** + * Stores information about whether permissions were generated yet. + * + * @param WC_Order|int $order Order ID or order object. + * @param bool $set True or false. + */ + public function set_download_permissions_granted( $order, $set ) { + $order_id = WC_Order_Factory::get_order_id( $order ); + update_post_meta( $order_id, '_download_permissions_granted', wc_bool_to_string( $set ) ); + } + + /** + * Gets information about whether sales were recorded. + * + * @param WC_Order|int $order Order ID or order object. + * @return bool + */ + public function get_recorded_sales( $order ) { + $order_id = WC_Order_Factory::get_order_id( $order ); + return wc_string_to_bool( get_post_meta( $order_id, '_recorded_sales', true ) ); + } + + /** + * Stores information about whether sales were recorded. + * + * @param WC_Order|int $order Order ID or order object. + * @param bool $set True or false. + */ + public function set_recorded_sales( $order, $set ) { + $order_id = WC_Order_Factory::get_order_id( $order ); + update_post_meta( $order_id, '_recorded_sales', wc_bool_to_string( $set ) ); + } + + /** + * Gets information about whether coupon counts were updated. + * + * @param WC_Order|int $order Order ID or order object. + * @return bool + */ + public function get_recorded_coupon_usage_counts( $order ) { + $order_id = WC_Order_Factory::get_order_id( $order ); + return wc_string_to_bool( get_post_meta( $order_id, '_recorded_coupon_usage_counts', true ) ); + } + + /** + * Stores information about whether coupon counts were updated. + * + * @param WC_Order|int $order Order ID or order object. + * @param bool $set True or false. + */ + public function set_recorded_coupon_usage_counts( $order, $set ) { + $order_id = WC_Order_Factory::get_order_id( $order ); + update_post_meta( $order_id, '_recorded_coupon_usage_counts', wc_bool_to_string( $set ) ); + } + + /** + * Return array of coupon_code => meta_key for coupon which have usage limit and have tentative keys. + * Pass $coupon_id if key for only one of the coupon is needed. + * + * @param WC_Order $order Order object. + * @param int $coupon_id If passed, will return held key for that coupon. + * + * @return array|string Key value pair for coupon code and meta key name. If $coupon_id is passed, returns meta_key for only that coupon. + */ + public function get_coupon_held_keys( $order, $coupon_id = null ) { + $held_keys = $order->get_meta( '_coupon_held_keys' ); + if ( $coupon_id ) { + return isset( $held_keys[ $coupon_id ] ) ? $held_keys[ $coupon_id ] : null; + } + return $held_keys; + } + + /** + * Return array of coupon_code => meta_key for coupon which have usage limit per customer and have tentative keys. + * + * @param WC_Order $order Order object. + * @param int $coupon_id If passed, will return held key for that coupon. + * + * @return mixed + */ + public function get_coupon_held_keys_for_users( $order, $coupon_id = null ) { + $held_keys_for_user = $order->get_meta( '_coupon_held_keys_for_users' ); + if ( $coupon_id ) { + return isset( $held_keys_for_user[ $coupon_id ] ) ? $held_keys_for_user[ $coupon_id ] : null; + } + return $held_keys_for_user; + } + + /** + * Add/Update list of meta keys that are currently being used by this order to hold a coupon. + * This is used to figure out what all meta entries we should delete when order is cancelled/completed. + * + * @param WC_Order $order Order object. + * @param array $held_keys Array of coupon_code => meta_key. + * @param array $held_keys_for_user Array of coupon_code => meta_key for held coupon for user. + * + * @return mixed + */ + public function set_coupon_held_keys( $order, $held_keys, $held_keys_for_user ) { + if ( is_array( $held_keys ) && 0 < count( $held_keys ) ) { + $order->update_meta_data( '_coupon_held_keys', $held_keys ); + } + if ( is_array( $held_keys_for_user ) && 0 < count( $held_keys_for_user ) ) { + $order->update_meta_data( '_coupon_held_keys_for_users', $held_keys_for_user ); + } + } + + /** + * Release all coupons held by this order. + * + * @param WC_Order $order Current order object. + * @param bool $save Whether to delete keys from DB right away. Could be useful to pass `false` if you are building a bulk request. + */ + public function release_held_coupons( $order, $save = true ) { + $coupon_held_keys = $this->get_coupon_held_keys( $order ); + if ( is_array( $coupon_held_keys ) ) { + foreach ( $coupon_held_keys as $coupon_id => $meta_key ) { + delete_post_meta( $coupon_id, $meta_key ); + } + } + $order->delete_meta_data( '_coupon_held_keys' ); + + $coupon_held_keys_for_users = $this->get_coupon_held_keys_for_users( $order ); + if ( is_array( $coupon_held_keys_for_users ) ) { + foreach ( $coupon_held_keys_for_users as $coupon_id => $meta_key ) { + delete_post_meta( $coupon_id, $meta_key ); + } + } + $order->delete_meta_data( '_coupon_held_keys_for_users' ); + + if ( $save ) { + $order->save_meta_data(); + } + + } + + /** + * Gets information about whether stock was reduced. + * + * @param WC_Order|int $order Order ID or order object. + * @return bool + */ + public function get_stock_reduced( $order ) { + $order_id = WC_Order_Factory::get_order_id( $order ); + return wc_string_to_bool( get_post_meta( $order_id, '_order_stock_reduced', true ) ); + } + + /** + * Stores information about whether stock was reduced. + * + * @param WC_Order|int $order Order ID or order object. + * @param bool $set True or false. + */ + public function set_stock_reduced( $order, $set ) { + $order_id = WC_Order_Factory::get_order_id( $order ); + update_post_meta( $order_id, '_order_stock_reduced', wc_bool_to_string( $set ) ); + } + + /** + * Get the order type based on Order ID. + * + * @since 3.0.0 + * @param int $order_id Order ID. + * @return string + */ + public function get_order_type( $order_id ) { + return get_post_type( $order_id ); + } + + /** + * Get valid WP_Query args from a WC_Order_Query's query variables. + * + * @since 3.1.0 + * @param array $query_vars query vars from a WC_Order_Query. + * @return array + */ + protected function get_wp_query_args( $query_vars ) { + + // Map query vars to ones that get_wp_query_args or WP_Query recognize. + $key_mapping = array( + 'customer_id' => 'customer_user', + 'status' => 'post_status', + 'currency' => 'order_currency', + 'version' => 'order_version', + 'discount_total' => 'cart_discount', + 'discount_tax' => 'cart_discount_tax', + 'shipping_total' => 'order_shipping', + 'shipping_tax' => 'order_shipping_tax', + 'cart_tax' => 'order_tax', + 'total' => 'order_total', + 'page' => 'paged', + ); + + foreach ( $key_mapping as $query_key => $db_key ) { + if ( isset( $query_vars[ $query_key ] ) ) { + $query_vars[ $db_key ] = $query_vars[ $query_key ]; + unset( $query_vars[ $query_key ] ); + } + } + + // Add the 'wc-' prefix to status if needed. + if ( ! empty( $query_vars['post_status'] ) ) { + if ( is_array( $query_vars['post_status'] ) ) { + foreach ( $query_vars['post_status'] as &$status ) { + $status = wc_is_order_status( 'wc-' . $status ) ? 'wc-' . $status : $status; + } + } else { + $query_vars['post_status'] = wc_is_order_status( 'wc-' . $query_vars['post_status'] ) ? 'wc-' . $query_vars['post_status'] : $query_vars['post_status']; + } + } + + $wp_query_args = parent::get_wp_query_args( $query_vars ); + + if ( ! isset( $wp_query_args['date_query'] ) ) { + $wp_query_args['date_query'] = array(); + } + if ( ! isset( $wp_query_args['meta_query'] ) ) { + $wp_query_args['meta_query'] = array(); + } + + $date_queries = array( + 'date_created' => 'post_date', + 'date_modified' => 'post_modified', + 'date_completed' => '_date_completed', + 'date_paid' => '_date_paid', + ); + foreach ( $date_queries as $query_var_key => $db_key ) { + if ( isset( $query_vars[ $query_var_key ] ) && '' !== $query_vars[ $query_var_key ] ) { + + // Remove any existing meta queries for the same keys to prevent conflicts. + $existing_queries = wp_list_pluck( $wp_query_args['meta_query'], 'key', true ); + $meta_query_index = array_search( $db_key, $existing_queries, true ); + if ( false !== $meta_query_index ) { + unset( $wp_query_args['meta_query'][ $meta_query_index ] ); + } + + $wp_query_args = $this->parse_date_for_wp_query( $query_vars[ $query_var_key ], $db_key, $wp_query_args ); + } + } + + if ( isset( $query_vars['customer'] ) && '' !== $query_vars['customer'] && array() !== $query_vars['customer'] ) { + $values = is_array( $query_vars['customer'] ) ? $query_vars['customer'] : array( $query_vars['customer'] ); + $customer_query = $this->get_orders_generate_customer_meta_query( $values ); + if ( is_wp_error( $customer_query ) ) { + $wp_query_args['errors'][] = $customer_query; + } else { + $wp_query_args['meta_query'][] = $customer_query; + } + } + + if ( isset( $query_vars['anonymized'] ) ) { + if ( $query_vars['anonymized'] ) { + $wp_query_args['meta_query'][] = array( + 'key' => '_anonymized', + 'value' => 'yes', + ); + } else { + $wp_query_args['meta_query'][] = array( + 'key' => '_anonymized', + 'compare' => 'NOT EXISTS', + ); + } + } + + if ( ! isset( $query_vars['paginate'] ) || ! $query_vars['paginate'] ) { + $wp_query_args['no_found_rows'] = true; + } + + return apply_filters( 'woocommerce_order_data_store_cpt_get_orders_query', $wp_query_args, $query_vars, $this ); + } + + /** + * Query for Orders matching specific criteria. + * + * @since 3.1.0 + * + * @param array $query_vars query vars from a WC_Order_Query. + * + * @return array|object + */ + public function query( $query_vars ) { + $args = $this->get_wp_query_args( $query_vars ); + + if ( ! empty( $args['errors'] ) ) { + $query = (object) array( + 'posts' => array(), + 'found_posts' => 0, + 'max_num_pages' => 0, + ); + } else { + $query = new WP_Query( $args ); + } + + $orders = ( isset( $query_vars['return'] ) && 'ids' === $query_vars['return'] ) ? $query->posts : array_filter( array_map( 'wc_get_order', $query->posts ) ); + + if ( isset( $query_vars['paginate'] ) && $query_vars['paginate'] ) { + return (object) array( + 'orders' => $orders, + 'total' => $query->found_posts, + 'max_num_pages' => $query->max_num_pages, + ); + } + + return $orders; + } + + /** + * Return the order type of a given item which belongs to WC_Order. + * + * @since 3.2.0 + * @param WC_Order $order Order Object. + * @param int $order_item_id Order item id. + * @return string Order Item type + */ + public function get_order_item_type( $order, $order_item_id ) { + global $wpdb; + return $wpdb->get_var( $wpdb->prepare( "SELECT DISTINCT order_item_type FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d and order_item_id = %d;", $order->get_id(), $order_item_id ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-coupon-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-coupon-data-store.php new file mode 100644 index 0000000..01eeb9d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-coupon-data-store.php @@ -0,0 +1,62 @@ +get_id(); + $item->set_props( + array( + 'discount' => get_metadata( 'order_item', $id, 'discount_amount', true ), + 'discount_tax' => get_metadata( 'order_item', $id, 'discount_amount_tax', true ), + ) + ); + $item->set_object_read( true ); + } + + /** + * Saves an item's data to the database / item meta. + * Ran after both create and update, so $item->get_id() will be set. + * + * @since 3.0.0 + * @param WC_Order_Item_Coupon $item Coupon order item. + */ + public function save_item_data( &$item ) { + $id = $item->get_id(); + $save_values = array( + 'discount_amount' => $item->get_discount( 'edit' ), + 'discount_amount_tax' => $item->get_discount_tax( 'edit' ), + ); + foreach ( $save_values as $key => $value ) { + update_metadata( 'order_item', $id, $key, $value ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-data-store.php new file mode 100644 index 0000000..46600ac --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-data-store.php @@ -0,0 +1,189 @@ +insert( + $wpdb->prefix . 'woocommerce_order_items', + array( + 'order_item_name' => $item['order_item_name'], + 'order_item_type' => $item['order_item_type'], + 'order_id' => $order_id, + ), + array( + '%s', + '%s', + '%d', + ) + ); + + $item_id = absint( $wpdb->insert_id ); + + $this->clear_caches( $item_id, $order_id ); + + return $item_id; + } + + /** + * Update an order item. + * + * @since 3.0.0 + * @param int $item_id Item ID. + * @param array $item order_item_name or order_item_type. + * @return boolean + */ + public function update_order_item( $item_id, $item ) { + global $wpdb; + $updated = $wpdb->update( $wpdb->prefix . 'woocommerce_order_items', $item, array( 'order_item_id' => $item_id ) ); + $this->clear_caches( $item_id, null ); + return $updated; + } + + /** + * Delete an order item. + * + * @since 3.0.0 + * @param int $item_id Item ID. + */ + public function delete_order_item( $item_id ) { + // Load the order ID before the deletion, since after, it won't exist in the database. + $order_id = $this->get_order_id_by_order_item_id( $item_id ); + + global $wpdb; + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id ) ); + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id = %d", $item_id ) ); + + $this->clear_caches( $item_id, $order_id ); + } + + /** + * Update term meta. + * + * @since 3.0.0 + * @param int $item_id Item ID. + * @param string $meta_key Meta key. + * @param mixed $meta_value Meta value. + * @param string $prev_value (default: ''). + * @return bool + */ + public function update_metadata( $item_id, $meta_key, $meta_value, $prev_value = '' ) { + return update_metadata( 'order_item', $item_id, $meta_key, is_string( $meta_value ) ? wp_slash( $meta_value ) : $meta_value, $prev_value ); + } + + /** + * Add term meta. + * + * @since 3.0.0 + * @param int $item_id Item ID. + * @param string $meta_key Meta key. + * @param mixed $meta_value Meta value. + * @param bool $unique (default: false). + * @return int New row ID or 0 + */ + public function add_metadata( $item_id, $meta_key, $meta_value, $unique = false ) { + return add_metadata( 'order_item', $item_id, wp_slash( $meta_key ), is_string( $meta_value ) ? wp_slash( $meta_value ) : $meta_value, $unique ); + } + + /** + * Delete term meta. + * + * @since 3.0.0 + * @param int $item_id Item ID. + * @param string $meta_key Meta key. + * @param string $meta_value (default: ''). + * @param bool $delete_all (default: false). + * @return bool + */ + public function delete_metadata( $item_id, $meta_key, $meta_value = '', $delete_all = false ) { + return delete_metadata( 'order_item', $item_id, $meta_key, is_string( $meta_value ) ? wp_slash( $meta_value ) : $meta_value, $delete_all ); + } + + /** + * Get term meta. + * + * @since 3.0.0 + * @param int $item_id Item ID. + * @param string $key Meta key. + * @param bool $single (default: true). + * @return mixed + */ + public function get_metadata( $item_id, $key, $single = true ) { + return get_metadata( 'order_item', $item_id, $key, $single ); + } + + /** + * Get order ID by order item ID. + * + * @since 3.0.0 + * @param int $item_id Item ID. + * @return int + */ + public function get_order_id_by_order_item_id( $item_id ) { + global $wpdb; + return (int) $wpdb->get_var( + $wpdb->prepare( + "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", + $item_id + ) + ); + } + + /** + * Get the order item type based on Item ID. + * + * @since 3.0.0 + * @param int $item_id Item ID. + * @return string|null Order item type or null if no order item entry found. + */ + public function get_order_item_type( $item_id ) { + global $wpdb; + $order_item_type = $wpdb->get_var( + $wpdb->prepare( + "SELECT order_item_type FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d LIMIT 1;", + $item_id + ) + ); + + return $order_item_type; + } + + /** + * Clear meta cache. + * + * @param int $item_id Item ID. + * @param int|null $order_id Order ID. If not set, it will be loaded using the item ID. + */ + protected function clear_caches( $item_id, $order_id ) { + wp_cache_delete( 'item-' . $item_id, 'order-items' ); + + if ( ! $order_id ) { + $order_id = $this->get_order_id_by_order_item_id( $item_id ); + } + if ( $order_id ) { + wp_cache_delete( 'order-items-' . $order_id, 'orders' ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-fee-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-fee-data-store.php new file mode 100644 index 0000000..2222d06 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-fee-data-store.php @@ -0,0 +1,69 @@ +get_id(); + $item->set_props( + array( + 'amount' => get_metadata( 'order_item', $id, '_fee_amount', true ), + 'tax_class' => get_metadata( 'order_item', $id, '_tax_class', true ), + 'tax_status' => get_metadata( 'order_item', $id, '_tax_status', true ), + 'total' => get_metadata( 'order_item', $id, '_line_total', true ), + 'taxes' => get_metadata( 'order_item', $id, '_line_tax_data', true ), + ) + ); + $item->set_object_read( true ); + } + + /** + * Saves an item's data to the database / item meta. + * Ran after both create and update, so $id will be set. + * + * @since 3.0.0 + * @param WC_Order_Item_Fee $item Fee order item object. + */ + public function save_item_data( &$item ) { + $id = $item->get_id(); + $save_values = array( + '_fee_amount' => $item->get_amount( 'edit' ), + '_tax_class' => $item->get_tax_class( 'edit' ), + '_tax_status' => $item->get_tax_status( 'edit' ), + '_line_total' => $item->get_total( 'edit' ), + '_line_tax' => $item->get_total_tax( 'edit' ), + '_line_tax_data' => $item->get_taxes( 'edit' ), + ); + foreach ( $save_values as $key => $value ) { + update_metadata( 'order_item', $id, $key, $value ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-product-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-product-data-store.php new file mode 100644 index 0000000..2f78691 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-product-data-store.php @@ -0,0 +1,97 @@ +get_id(); + $item->set_props( + array( + 'product_id' => get_metadata( 'order_item', $id, '_product_id', true ), + 'variation_id' => get_metadata( 'order_item', $id, '_variation_id', true ), + 'quantity' => get_metadata( 'order_item', $id, '_qty', true ), + 'tax_class' => get_metadata( 'order_item', $id, '_tax_class', true ), + 'subtotal' => get_metadata( 'order_item', $id, '_line_subtotal', true ), + 'total' => get_metadata( 'order_item', $id, '_line_total', true ), + 'taxes' => get_metadata( 'order_item', $id, '_line_tax_data', true ), + ) + ); + $item->set_object_read( true ); + } + + /** + * Saves an item's data to the database / item meta. + * Ran after both create and update, so $id will be set. + * + * @since 3.0.0 + * @param WC_Order_Item_Product $item Product order item object. + */ + public function save_item_data( &$item ) { + $id = $item->get_id(); + $changes = $item->get_changes(); + $meta_key_to_props = array( + '_product_id' => 'product_id', + '_variation_id' => 'variation_id', + '_qty' => 'quantity', + '_tax_class' => 'tax_class', + '_line_subtotal' => 'subtotal', + '_line_subtotal_tax' => 'subtotal_tax', + '_line_total' => 'total', + '_line_tax' => 'total_tax', + '_line_tax_data' => 'taxes', + ); + $props_to_update = $this->get_props_to_update( $item, $meta_key_to_props, 'order_item' ); + + foreach ( $props_to_update as $meta_key => $prop ) { + update_metadata( 'order_item', $id, $meta_key, $item->{"get_$prop"}( 'edit' ) ); + } + } + + /** + * Get a list of download IDs for a specific item from an order. + * + * @since 3.0.0 + * @param WC_Order_Item_Product $item Product order item object. + * @param WC_Order $order Order object. + * @return array + */ + public function get_download_ids( $item, $order ) { + global $wpdb; + return $wpdb->get_col( + $wpdb->prepare( + "SELECT download_id FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE user_email = %s AND order_key = %s AND product_id = %d ORDER BY permission_id", + $order->get_billing_email(), + $order->get_order_key(), + $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id() + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-shipping-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-shipping-data-store.php new file mode 100644 index 0000000..0c4f343 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-shipping-data-store.php @@ -0,0 +1,78 @@ +get_id(); + $item->set_props( + array( + 'method_id' => get_metadata( 'order_item', $id, 'method_id', true ), + 'instance_id' => get_metadata( 'order_item', $id, 'instance_id', true ), + 'total' => get_metadata( 'order_item', $id, 'cost', true ), + 'taxes' => get_metadata( 'order_item', $id, 'taxes', true ), + ) + ); + + // BW compat. + if ( '' === $item->get_instance_id() && strstr( $item->get_method_id(), ':' ) ) { + $legacy_method_id = explode( ':', $item->get_method_id() ); + $item->set_method_id( $legacy_method_id[0] ); + $item->set_instance_id( $legacy_method_id[1] ); + } + + $item->set_object_read( true ); + } + + /** + * Saves an item's data to the database / item meta. + * Ran after both create and update, so $id will be set. + * + * @since 3.0.0 + * @param WC_Order_Item_Shipping $item Item to save. + */ + public function save_item_data( &$item ) { + $id = $item->get_id(); + $changes = $item->get_changes(); + $meta_key_to_props = array( + 'method_id' => 'method_id', + 'instance_id' => 'instance_id', + 'cost' => 'total', + 'total_tax' => 'total_tax', + 'taxes' => 'taxes', + ); + $props_to_update = $this->get_props_to_update( $item, $meta_key_to_props, 'order_item' ); + + foreach ( $props_to_update as $meta_key => $prop ) { + update_metadata( 'order_item', $id, $meta_key, $item->{"get_$prop"}( 'edit' ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-tax-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-tax-data-store.php new file mode 100644 index 0000000..ab5325a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-item-tax-data-store.php @@ -0,0 +1,74 @@ +get_id(); + $item->set_props( + array( + 'rate_id' => get_metadata( 'order_item', $id, 'rate_id', true ), + 'label' => get_metadata( 'order_item', $id, 'label', true ), + 'compound' => get_metadata( 'order_item', $id, 'compound', true ), + 'tax_total' => get_metadata( 'order_item', $id, 'tax_amount', true ), + 'shipping_tax_total' => get_metadata( 'order_item', $id, 'shipping_tax_amount', true ), + 'rate_percent' => get_metadata( 'order_item', $id, 'rate_percent', true ), + ) + ); + $item->set_object_read( true ); + } + + /** + * Saves an item's data to the database / item meta. + * Ran after both create and update, so $id will be set. + * + * @since 3.0.0 + * @param WC_Order_Item_Tax $item Tax order item object. + */ + public function save_item_data( &$item ) { + $id = $item->get_id(); + $changes = $item->get_changes(); + $meta_key_to_props = array( + 'rate_id' => 'rate_id', + 'label' => 'label', + 'compound' => 'compound', + 'tax_amount' => 'tax_total', + 'shipping_tax_amount' => 'shipping_tax_total', + 'rate_percent' => 'rate_percent', + ); + $props_to_update = $this->get_props_to_update( $item, $meta_key_to_props, 'order_item' ); + + foreach ( $props_to_update as $meta_key => $prop ) { + update_metadata( 'order_item', $id, $meta_key, $item->{"get_$prop"}( 'edit' ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-refund-data-store-cpt.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-refund-data-store-cpt.php new file mode 100644 index 0000000..1cee50a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-order-refund-data-store-cpt.php @@ -0,0 +1,119 @@ +get_id(); + + if ( ! $id ) { + return; + } + + wp_delete_post( $id ); + $order->set_id( 0 ); + do_action( 'woocommerce_delete_order_refund', $id ); + } + + /** + * Read refund data. Can be overridden by child classes to load other props. + * + * @param WC_Order_Refund $refund Refund object. + * @param object $post_object Post object. + * @since 3.0.0 + */ + protected function read_order_data( &$refund, $post_object ) { + parent::read_order_data( $refund, $post_object ); + $id = $refund->get_id(); + $refund->set_props( + array( + 'amount' => get_post_meta( $id, '_refund_amount', true ), + 'refunded_by' => metadata_exists( 'post', $id, '_refunded_by' ) ? get_post_meta( $id, '_refunded_by', true ) : absint( $post_object->post_author ), + 'refunded_payment' => wc_string_to_bool( get_post_meta( $id, '_refunded_payment', true ) ), + 'reason' => metadata_exists( 'post', $id, '_refund_reason' ) ? get_post_meta( $id, '_refund_reason', true ) : $post_object->post_excerpt, + ) + ); + } + + /** + * Helper method that updates all the post meta for an order based on it's settings in the WC_Order class. + * + * @param WC_Order_Refund $refund Refund object. + * @since 3.0.0 + */ + protected function update_post_meta( &$refund ) { + parent::update_post_meta( $refund ); + + $updated_props = array(); + $meta_key_to_props = array( + '_refund_amount' => 'amount', + '_refunded_by' => 'refunded_by', + '_refunded_payment' => 'refunded_payment', + '_refund_reason' => 'reason', + ); + + $props_to_update = $this->get_props_to_update( $refund, $meta_key_to_props ); + foreach ( $props_to_update as $meta_key => $prop ) { + $value = $refund->{"get_$prop"}( 'edit' ); + update_post_meta( $refund->get_id(), $meta_key, $value ); + $updated_props[] = $prop; + } + + do_action( 'woocommerce_order_refund_object_updated_props', $refund, $updated_props ); + } + + /** + * Get a title for the new post type. + * + * @return string + */ + protected function get_post_title() { + return sprintf( + /* translators: %s: Order date */ + __( 'Refund – %s', 'woocommerce' ), + strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment, WordPress.WP.I18n.UnorderedPlaceholdersText + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-payment-token-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-payment-token-data-store.php new file mode 100644 index 0000000..81e2211 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-payment-token-data-store.php @@ -0,0 +1,372 @@ +validate() ) { + throw new Exception( __( 'Invalid or missing payment token fields.', 'woocommerce' ) ); + } + + global $wpdb; + if ( ! $token->is_default() && $token->get_user_id() > 0 ) { + $default_token = WC_Payment_Tokens::get_customer_default_token( $token->get_user_id() ); + if ( is_null( $default_token ) ) { + $token->set_default( true ); + } + } + + $payment_token_data = array( + 'gateway_id' => $token->get_gateway_id( 'edit' ), + 'token' => $token->get_token( 'edit' ), + 'user_id' => $token->get_user_id( 'edit' ), + 'type' => $token->get_type( 'edit' ), + ); + + $wpdb->insert( $wpdb->prefix . 'woocommerce_payment_tokens', $payment_token_data ); + $token_id = $wpdb->insert_id; + $token->set_id( $token_id ); + $this->save_extra_data( $token, true ); + $token->save_meta_data(); + $token->apply_changes(); + + // Make sure all other tokens are not set to default. + if ( $token->is_default() && $token->get_user_id() > 0 ) { + WC_Payment_Tokens::set_users_default( $token->get_user_id(), $token_id ); + } + + do_action( 'woocommerce_new_payment_token', $token_id, $token ); + } + + /** + * Update a payment token. + * + * @since 3.0.0 + * + * @param WC_Payment_Token $token Payment token object. + * + * @throws Exception Throw exception if invalid or missing payment token fields. + */ + public function update( &$token ) { + if ( false === $token->validate() ) { + throw new Exception( __( 'Invalid or missing payment token fields.', 'woocommerce' ) ); + } + + global $wpdb; + + $updated_props = array(); + $core_props = array( 'gateway_id', 'token', 'user_id', 'type' ); + $changed_props = array_keys( $token->get_changes() ); + + foreach ( $changed_props as $prop ) { + if ( ! in_array( $prop, $core_props, true ) ) { + continue; + } + $updated_props[] = $prop; + $payment_token_data[ $prop ] = $token->{'get_' . $prop}( 'edit' ); + } + + if ( ! empty( $payment_token_data ) ) { + $wpdb->update( + $wpdb->prefix . 'woocommerce_payment_tokens', + $payment_token_data, + array( 'token_id' => $token->get_id() ) + ); + } + + $updated_extra_props = $this->save_extra_data( $token ); + $updated_props = array_merge( $updated_props, $updated_extra_props ); + $token->save_meta_data(); + $token->apply_changes(); + + // Make sure all other tokens are not set to default. + if ( $token->is_default() && $token->get_user_id() > 0 ) { + WC_Payment_Tokens::set_users_default( $token->get_user_id(), $token->get_id() ); + } + + do_action( 'woocommerce_payment_token_object_updated_props', $token, $updated_props ); + do_action( 'woocommerce_payment_token_updated', $token->get_id() ); + } + + /** + * Remove a payment token from the database. + * + * @since 3.0.0 + * @param WC_Payment_Token $token Payment token object. + * @param bool $force_delete Unused param. + */ + public function delete( &$token, $force_delete = false ) { + global $wpdb; + $wpdb->delete( $wpdb->prefix . 'woocommerce_payment_tokens', array( 'token_id' => $token->get_id() ), array( '%d' ) ); + $wpdb->delete( $wpdb->prefix . 'woocommerce_payment_tokenmeta', array( 'payment_token_id' => $token->get_id() ), array( '%d' ) ); + do_action( 'woocommerce_payment_token_deleted', $token->get_id(), $token ); + } + + /** + * Read a token from the database. + * + * @since 3.0.0 + * + * @param WC_Payment_Token $token Payment token object. + * + * @throws Exception Throw exception if invalid payment token. + */ + public function read( &$token ) { + global $wpdb; + + $data = $wpdb->get_row( + $wpdb->prepare( + "SELECT token, user_id, gateway_id, is_default FROM {$wpdb->prefix}woocommerce_payment_tokens WHERE token_id = %d LIMIT 1", + $token->get_id() + ) + ); + + if ( $data ) { + $token->set_props( + array( + 'token' => $data->token, + 'user_id' => $data->user_id, + 'gateway_id' => $data->gateway_id, + 'default' => $data->is_default, + ) + ); + $this->read_extra_data( $token ); + $token->read_meta_data(); + $token->set_object_read( true ); + do_action( 'woocommerce_payment_token_loaded', $token ); + } else { + throw new Exception( __( 'Invalid payment token.', 'woocommerce' ) ); + } + } + + /** + * Read extra data associated with the token (like last4 digits of a card for expiry dates). + * + * @param WC_Payment_Token $token Payment token object. + * @since 3.0.0 + */ + protected function read_extra_data( &$token ) { + foreach ( $token->get_extra_data_keys() as $key ) { + $function = 'set_' . $key; + if ( is_callable( array( $token, $function ) ) ) { + $token->{$function}( get_metadata( 'payment_token', $token->get_id(), $key, true ) ); + } + } + } + + /** + * Saves extra token data as meta. + * + * @since 3.0.0 + * @param WC_Payment_Token $token Payment token object. + * @param bool $force By default, only changed props are updated. When this param is true all props are updated. + * @return array List of updated props. + */ + protected function save_extra_data( &$token, $force = false ) { + if ( $this->extra_data_saved ) { + return array(); + } + + $updated_props = array(); + $extra_data_keys = $token->get_extra_data_keys(); + $meta_key_to_props = ! empty( $extra_data_keys ) ? array_combine( $extra_data_keys, $extra_data_keys ) : array(); + $props_to_update = $force ? $meta_key_to_props : $this->get_props_to_update( $token, $meta_key_to_props ); + + foreach ( $extra_data_keys as $key ) { + if ( ! array_key_exists( $key, $props_to_update ) ) { + continue; + } + $function = 'get_' . $key; + if ( is_callable( array( $token, $function ) ) ) { + if ( update_metadata( 'payment_token', $token->get_id(), $key, $token->{$function}( 'edit' ) ) ) { + $updated_props[] = $key; + } + } + } + + return $updated_props; + } + + /** + * Returns an array of objects (stdObject) matching specific token criteria. + * Accepts token_id, user_id, gateway_id, and type. + * Each object should contain the fields token_id, gateway_id, token, user_id, type, is_default. + * + * @since 3.0.0 + * @param array $args List of accepted args: token_id, gateway_id, user_id, type. + * @return array + */ + public function get_tokens( $args ) { + global $wpdb; + $args = wp_parse_args( + $args, + array( + 'token_id' => '', + 'user_id' => '', + 'gateway_id' => '', + 'type' => '', + ) + ); + + $sql = "SELECT * FROM {$wpdb->prefix}woocommerce_payment_tokens"; + $where = array( '1=1' ); + + if ( $args['token_id'] ) { + $token_ids = array_map( 'absint', is_array( $args['token_id'] ) ? $args['token_id'] : array( $args['token_id'] ) ); + $where[] = "token_id IN ('" . implode( "','", array_map( 'esc_sql', $token_ids ) ) . "')"; + } + + if ( $args['user_id'] ) { + $where[] = $wpdb->prepare( 'user_id = %d', absint( $args['user_id'] ) ); + } + + if ( $args['gateway_id'] ) { + $gateway_ids = array( $args['gateway_id'] ); + } else { + $gateways = WC_Payment_Gateways::instance(); + $gateway_ids = $gateways->get_payment_gateway_ids(); + } + + $page = isset( $args['page'] ) ? absint( $args['page'] ) : 1; + $posts_per_page = isset( $args['limit'] ) ? absint( $args['limit'] ) : get_option( 'posts_per_page' ); + + $pgstrt = absint( ( $page - 1 ) * $posts_per_page ) . ', '; + $limits = 'LIMIT ' . $pgstrt . $posts_per_page; + + $gateway_ids[] = ''; + $where[] = "gateway_id IN ('" . implode( "','", array_map( 'esc_sql', $gateway_ids ) ) . "')"; + + if ( $args['type'] ) { + $where[] = $wpdb->prepare( 'type = %s', $args['type'] ); + } + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $token_results = $wpdb->get_results( $sql . ' WHERE ' . implode( ' AND ', $where ) . ' ' . $limits ); + + return $token_results; + } + + /** + * Returns an stdObject of a token for a user's default token. + * Should contain the fields token_id, gateway_id, token, user_id, type, is_default. + * + * @since 3.0.0 + * @param int $user_id User ID. + * @return object + */ + public function get_users_default_token( $user_id ) { + global $wpdb; + return $wpdb->get_row( + $wpdb->prepare( + "SELECT * FROM {$wpdb->prefix}woocommerce_payment_tokens WHERE user_id = %d AND is_default = 1", + $user_id + ) + ); + } + + /** + * Returns an stdObject of a token. + * Should contain the fields token_id, gateway_id, token, user_id, type, is_default. + * + * @since 3.0.0 + * @param id $token_id Token ID. + * @return object + */ + public function get_token_by_id( $token_id ) { + global $wpdb; + return $wpdb->get_row( + $wpdb->prepare( + "SELECT * FROM {$wpdb->prefix}woocommerce_payment_tokens WHERE token_id = %d", + $token_id + ) + ); + } + + /** + * Returns metadata for a specific payment token. + * + * @since 3.0.0 + * @param id $token_id Token ID. + * @return array + */ + public function get_metadata( $token_id ) { + return get_metadata( 'payment_token', $token_id ); + } + + /** + * Get a token's type by ID. + * + * @since 3.0.0 + * @param id $token_id Token ID. + * @return string + */ + public function get_token_type_by_id( $token_id ) { + global $wpdb; + return $wpdb->get_var( + $wpdb->prepare( + "SELECT type FROM {$wpdb->prefix}woocommerce_payment_tokens WHERE token_id = %d", + $token_id + ) + ); + } + + /** + * Update's a tokens default status in the database. Used for quickly + * looping through tokens and setting their statuses instead of creating a bunch + * of objects. + * + * @since 3.0.0 + * + * @param id $token_id Token ID. + * @param bool $status Whether given payment token is the default payment token or not. + * + * @return void + */ + public function set_default_status( $token_id, $status = true ) { + global $wpdb; + $wpdb->update( + $wpdb->prefix . 'woocommerce_payment_tokens', + array( 'is_default' => $status ), + array( + 'token_id' => $token_id, + ) + ); + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php new file mode 100644 index 0000000..9e56908 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php @@ -0,0 +1,2101 @@ +get_date_created( 'edit' ) ) { + $product->set_date_created( time() ); + } + + $id = wp_insert_post( + apply_filters( + 'woocommerce_new_product_data', + array( + 'post_type' => 'product', + 'post_status' => $product->get_status() ? $product->get_status() : 'publish', + 'post_author' => get_current_user_id(), + 'post_title' => $product->get_name() ? $product->get_name() : __( 'Product', 'woocommerce' ), + 'post_content' => $product->get_description(), + 'post_excerpt' => $product->get_short_description(), + 'post_parent' => $product->get_parent_id(), + 'comment_status' => $product->get_reviews_allowed() ? 'open' : 'closed', + 'ping_status' => 'closed', + 'menu_order' => $product->get_menu_order(), + 'post_password' => $product->get_post_password( 'edit' ), + 'post_date' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getOffsetTimestamp() ), + 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getTimestamp() ), + 'post_name' => $product->get_slug( 'edit' ), + ) + ), + true + ); + + if ( $id && ! is_wp_error( $id ) ) { + $product->set_id( $id ); + + $this->update_post_meta( $product, true ); + $this->update_terms( $product, true ); + $this->update_visibility( $product, true ); + $this->update_attributes( $product, true ); + $this->update_version_and_type( $product ); + $this->handle_updated_props( $product ); + $this->clear_caches( $product ); + + $product->save_meta_data(); + $product->apply_changes(); + + do_action( 'woocommerce_new_product', $id, $product ); + } + } + + /** + * Method to read a product from the database. + * + * @param WC_Product $product Product object. + * @throws Exception If invalid product. + */ + public function read( &$product ) { + $product->set_defaults(); + $post_object = get_post( $product->get_id() ); + + if ( ! $product->get_id() || ! $post_object || 'product' !== $post_object->post_type ) { + throw new Exception( __( 'Invalid product.', 'woocommerce' ) ); + } + + $product->set_props( + array( + 'name' => $post_object->post_title, + 'slug' => $post_object->post_name, + 'date_created' => $this->string_to_timestamp( $post_object->post_date_gmt ), + 'date_modified' => $this->string_to_timestamp( $post_object->post_modified_gmt ), + 'status' => $post_object->post_status, + 'description' => $post_object->post_content, + 'short_description' => $post_object->post_excerpt, + 'parent_id' => $post_object->post_parent, + 'menu_order' => $post_object->menu_order, + 'post_password' => $post_object->post_password, + 'reviews_allowed' => 'open' === $post_object->comment_status, + ) + ); + + $this->read_attributes( $product ); + $this->read_downloads( $product ); + $this->read_visibility( $product ); + $this->read_product_data( $product ); + $this->read_extra_data( $product ); + $product->set_object_read( true ); + + do_action( 'woocommerce_product_read', $product->get_id() ); + } + + /** + * Method to update a product in the database. + * + * @param WC_Product $product Product object. + */ + public function update( &$product ) { + $product->save_meta_data(); + $changes = $product->get_changes(); + + // Only update the post when the post data changes. + if ( array_intersect( array( 'description', 'short_description', 'name', 'parent_id', 'reviews_allowed', 'status', 'menu_order', 'date_created', 'date_modified', 'slug' ), array_keys( $changes ) ) ) { + $post_data = array( + 'post_content' => $product->get_description( 'edit' ), + 'post_excerpt' => $product->get_short_description( 'edit' ), + 'post_title' => $product->get_name( 'edit' ), + 'post_parent' => $product->get_parent_id( 'edit' ), + 'comment_status' => $product->get_reviews_allowed( 'edit' ) ? 'open' : 'closed', + 'post_status' => $product->get_status( 'edit' ) ? $product->get_status( 'edit' ) : 'publish', + 'menu_order' => $product->get_menu_order( 'edit' ), + 'post_password' => $product->get_post_password( 'edit' ), + 'post_name' => $product->get_slug( 'edit' ), + 'post_type' => 'product', + ); + if ( $product->get_date_created( 'edit' ) ) { + $post_data['post_date'] = gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getOffsetTimestamp() ); + $post_data['post_date_gmt'] = gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getTimestamp() ); + } + if ( isset( $changes['date_modified'] ) && $product->get_date_modified( 'edit' ) ) { + $post_data['post_modified'] = gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getOffsetTimestamp() ); + $post_data['post_modified_gmt'] = gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getTimestamp() ); + } else { + $post_data['post_modified'] = current_time( 'mysql' ); + $post_data['post_modified_gmt'] = current_time( 'mysql', 1 ); + } + + /** + * When updating this object, to prevent infinite loops, use $wpdb + * to update data, since wp_update_post spawns more calls to the + * save_post action. + * + * This ensures hooks are fired by either WP itself (admin screen save), + * or an update purely from CRUD. + */ + if ( doing_action( 'save_post' ) ) { + $GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $post_data, array( 'ID' => $product->get_id() ) ); + clean_post_cache( $product->get_id() ); + } else { + wp_update_post( array_merge( array( 'ID' => $product->get_id() ), $post_data ) ); + } + $product->read_meta_data( true ); // Refresh internal meta data, in case things were hooked into `save_post` or another WP hook. + + } else { // Only update post modified time to record this save event. + $GLOBALS['wpdb']->update( + $GLOBALS['wpdb']->posts, + array( + 'post_modified' => current_time( 'mysql' ), + 'post_modified_gmt' => current_time( 'mysql', 1 ), + ), + array( + 'ID' => $product->get_id(), + ) + ); + clean_post_cache( $product->get_id() ); + } + + $this->update_post_meta( $product ); + $this->update_terms( $product ); + $this->update_visibility( $product ); + $this->update_attributes( $product ); + $this->update_version_and_type( $product ); + $this->handle_updated_props( $product ); + $this->clear_caches( $product ); + + $product->apply_changes(); + + do_action( 'woocommerce_update_product', $product->get_id(), $product ); + } + + /** + * Method to delete a product from the database. + * + * @param WC_Product $product Product object. + * @param array $args Array of args to pass to the delete method. + */ + public function delete( &$product, $args = array() ) { + $id = $product->get_id(); + $post_type = $product->is_type( 'variation' ) ? 'product_variation' : 'product'; + + $args = wp_parse_args( + $args, + array( + 'force_delete' => false, + ) + ); + + if ( ! $id ) { + return; + } + + if ( $args['force_delete'] ) { + do_action( 'woocommerce_before_delete_' . $post_type, $id ); + wp_delete_post( $id ); + $product->set_id( 0 ); + do_action( 'woocommerce_delete_' . $post_type, $id ); + } else { + wp_trash_post( $id ); + $product->set_status( 'trash' ); + do_action( 'woocommerce_trash_' . $post_type, $id ); + } + } + + /* + |-------------------------------------------------------------------------- + | Additional Methods + |-------------------------------------------------------------------------- + */ + + /** + * Read product data. Can be overridden by child classes to load other props. + * + * @param WC_Product $product Product object. + * @since 3.0.0 + */ + protected function read_product_data( &$product ) { + $id = $product->get_id(); + $post_meta_values = get_post_meta( $id ); + $meta_key_to_props = array( + '_sku' => 'sku', + '_regular_price' => 'regular_price', + '_sale_price' => 'sale_price', + '_price' => 'price', + '_sale_price_dates_from' => 'date_on_sale_from', + '_sale_price_dates_to' => 'date_on_sale_to', + 'total_sales' => 'total_sales', + '_tax_status' => 'tax_status', + '_tax_class' => 'tax_class', + '_manage_stock' => 'manage_stock', + '_backorders' => 'backorders', + '_low_stock_amount' => 'low_stock_amount', + '_sold_individually' => 'sold_individually', + '_weight' => 'weight', + '_length' => 'length', + '_width' => 'width', + '_height' => 'height', + '_upsell_ids' => 'upsell_ids', + '_crosssell_ids' => 'cross_sell_ids', + '_purchase_note' => 'purchase_note', + '_default_attributes' => 'default_attributes', + '_virtual' => 'virtual', + '_downloadable' => 'downloadable', + '_download_limit' => 'download_limit', + '_download_expiry' => 'download_expiry', + '_thumbnail_id' => 'image_id', + '_stock' => 'stock_quantity', + '_stock_status' => 'stock_status', + '_wc_average_rating' => 'average_rating', + '_wc_rating_count' => 'rating_counts', + '_wc_review_count' => 'review_count', + '_product_image_gallery' => 'gallery_image_ids', + ); + + $set_props = array(); + + foreach ( $meta_key_to_props as $meta_key => $prop ) { + $meta_value = isset( $post_meta_values[ $meta_key ][0] ) ? $post_meta_values[ $meta_key ][0] : null; + $set_props[ $prop ] = maybe_unserialize( $meta_value ); // get_post_meta only unserializes single values. + } + + $set_props['category_ids'] = $this->get_term_ids( $product, 'product_cat' ); + $set_props['tag_ids'] = $this->get_term_ids( $product, 'product_tag' ); + $set_props['shipping_class_id'] = current( $this->get_term_ids( $product, 'product_shipping_class' ) ); + $set_props['gallery_image_ids'] = array_filter( explode( ',', $set_props['gallery_image_ids'] ) ); + + $product->set_props( $set_props ); + } + + /** + * Re-reads stock from the DB ignoring changes. + * + * @param WC_Product $product Product object. + * @param int|float $new_stock New stock level if already read. + */ + public function read_stock_quantity( &$product, $new_stock = null ) { + $object_read = $product->get_object_read(); + $product->set_object_read( false ); // This makes update of qty go directly to data- instead of changes-array of the product object (which is needed as the data should hold status of the object as it was read from the db). + $product->set_stock_quantity( is_null( $new_stock ) ? get_post_meta( $product->get_id(), '_stock', true ) : $new_stock ); + $product->set_object_read( $object_read ); + } + + /** + * Read extra data associated with the product, like button text or product URL for external products. + * + * @param WC_Product $product Product object. + * @since 3.0.0 + */ + protected function read_extra_data( &$product ) { + foreach ( $product->get_extra_data_keys() as $key ) { + $function = 'set_' . $key; + if ( is_callable( array( $product, $function ) ) ) { + $product->{$function}( get_post_meta( $product->get_id(), '_' . $key, true ) ); + } + } + } + + /** + * Convert visibility terms to props. + * Catalog visibility valid values are 'visible', 'catalog', 'search', and 'hidden'. + * + * @param WC_Product $product Product object. + * @since 3.0.0 + */ + protected function read_visibility( &$product ) { + $terms = get_the_terms( $product->get_id(), 'product_visibility' ); + $term_names = is_array( $terms ) ? wp_list_pluck( $terms, 'name' ) : array(); + $featured = in_array( 'featured', $term_names, true ); + $exclude_search = in_array( 'exclude-from-search', $term_names, true ); + $exclude_catalog = in_array( 'exclude-from-catalog', $term_names, true ); + + if ( $exclude_search && $exclude_catalog ) { + $catalog_visibility = 'hidden'; + } elseif ( $exclude_search ) { + $catalog_visibility = 'catalog'; + } elseif ( $exclude_catalog ) { + $catalog_visibility = 'search'; + } else { + $catalog_visibility = 'visible'; + } + + $product->set_props( + array( + 'featured' => $featured, + 'catalog_visibility' => $catalog_visibility, + ) + ); + } + + /** + * Read attributes from post meta. + * + * @param WC_Product $product Product object. + */ + protected function read_attributes( &$product ) { + $meta_attributes = get_post_meta( $product->get_id(), '_product_attributes', true ); + + if ( ! empty( $meta_attributes ) && is_array( $meta_attributes ) ) { + $attributes = array(); + foreach ( $meta_attributes as $meta_attribute_key => $meta_attribute_value ) { + $meta_value = array_merge( + array( + 'name' => '', + 'value' => '', + 'position' => 0, + 'is_visible' => 0, + 'is_variation' => 0, + 'is_taxonomy' => 0, + ), + (array) $meta_attribute_value + ); + + // Check if is a taxonomy attribute. + if ( ! empty( $meta_value['is_taxonomy'] ) ) { + if ( ! taxonomy_exists( $meta_value['name'] ) ) { + continue; + } + $id = wc_attribute_taxonomy_id_by_name( $meta_value['name'] ); + $options = wc_get_object_terms( $product->get_id(), $meta_value['name'], 'term_id' ); + } else { + $id = 0; + $options = wc_get_text_attributes( $meta_value['value'] ); + } + + $attribute = new WC_Product_Attribute(); + $attribute->set_id( $id ); + $attribute->set_name( $meta_value['name'] ); + $attribute->set_options( $options ); + $attribute->set_position( $meta_value['position'] ); + $attribute->set_visible( $meta_value['is_visible'] ); + $attribute->set_variation( $meta_value['is_variation'] ); + $attributes[] = $attribute; + } + $product->set_attributes( $attributes ); + } + } + + /** + * Read downloads from post meta. + * + * @param WC_Product $product Product object. + * @since 3.0.0 + */ + protected function read_downloads( &$product ) { + $meta_values = array_filter( (array) get_post_meta( $product->get_id(), '_downloadable_files', true ) ); + + if ( $meta_values ) { + $downloads = array(); + foreach ( $meta_values as $key => $value ) { + if ( ! isset( $value['name'], $value['file'] ) ) { + continue; + } + $download = new WC_Product_Download(); + $download->set_id( $key ); + $download->set_name( $value['name'] ? $value['name'] : wc_get_filename_from_url( $value['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $value['file'], $product, $key ) ); + $downloads[] = $download; + } + $product->set_downloads( $downloads ); + } + } + + /** + * Helper method that updates all the post meta for a product based on it's settings in the WC_Product class. + * + * @param WC_Product $product Product object. + * @param bool $force Force update. Used during create. + * @since 3.0.0 + */ + protected function update_post_meta( &$product, $force = false ) { + $meta_key_to_props = array( + '_sku' => 'sku', + '_regular_price' => 'regular_price', + '_sale_price' => 'sale_price', + '_sale_price_dates_from' => 'date_on_sale_from', + '_sale_price_dates_to' => 'date_on_sale_to', + 'total_sales' => 'total_sales', + '_tax_status' => 'tax_status', + '_tax_class' => 'tax_class', + '_manage_stock' => 'manage_stock', + '_backorders' => 'backorders', + '_low_stock_amount' => 'low_stock_amount', + '_sold_individually' => 'sold_individually', + '_weight' => 'weight', + '_length' => 'length', + '_width' => 'width', + '_height' => 'height', + '_upsell_ids' => 'upsell_ids', + '_crosssell_ids' => 'cross_sell_ids', + '_purchase_note' => 'purchase_note', + '_default_attributes' => 'default_attributes', + '_virtual' => 'virtual', + '_downloadable' => 'downloadable', + '_product_image_gallery' => 'gallery_image_ids', + '_download_limit' => 'download_limit', + '_download_expiry' => 'download_expiry', + '_thumbnail_id' => 'image_id', + '_stock' => 'stock_quantity', + '_stock_status' => 'stock_status', + '_wc_average_rating' => 'average_rating', + '_wc_rating_count' => 'rating_counts', + '_wc_review_count' => 'review_count', + ); + + // Make sure to take extra data (like product url or text for external products) into account. + $extra_data_keys = $product->get_extra_data_keys(); + + foreach ( $extra_data_keys as $key ) { + $meta_key_to_props[ '_' . $key ] = $key; + } + + $props_to_update = $force ? $meta_key_to_props : $this->get_props_to_update( $product, $meta_key_to_props ); + + foreach ( $props_to_update as $meta_key => $prop ) { + $value = $product->{"get_$prop"}( 'edit' ); + $value = is_string( $value ) ? wp_slash( $value ) : $value; + switch ( $prop ) { + case 'virtual': + case 'downloadable': + case 'manage_stock': + case 'sold_individually': + $value = wc_bool_to_string( $value ); + break; + case 'gallery_image_ids': + $value = implode( ',', $value ); + break; + case 'date_on_sale_from': + case 'date_on_sale_to': + $value = $value ? $value->getTimestamp() : ''; + break; + } + + $updated = $this->update_or_delete_post_meta( $product, $meta_key, $value ); + + if ( $updated ) { + $this->updated_props[] = $prop; + } + } + + // Update extra data associated with the product like button text or product URL for external products. + if ( ! $this->extra_data_saved ) { + foreach ( $extra_data_keys as $key ) { + $meta_key = '_' . $key; + $function = 'get_' . $key; + if ( ! array_key_exists( $meta_key, $props_to_update ) ) { + continue; + } + if ( is_callable( array( $product, $function ) ) ) { + $value = $product->{$function}( 'edit' ); + $value = is_string( $value ) ? wp_slash( $value ) : $value; + $updated = $this->update_or_delete_post_meta( $product, $meta_key, $value ); + + if ( $updated ) { + $this->updated_props[] = $key; + } + } + } + } + + if ( $this->update_downloads( $product, $force ) ) { + $this->updated_props[] = 'downloads'; + } + } + + /** + * Handle updated meta props after updating meta data. + * + * @since 3.0.0 + * @param WC_Product $product Product Object. + */ + protected function handle_updated_props( &$product ) { + $price_is_synced = $product->is_type( array( 'variable', 'grouped' ) ); + + if ( ! $price_is_synced ) { + if ( in_array( 'regular_price', $this->updated_props, true ) || in_array( 'sale_price', $this->updated_props, true ) ) { + if ( $product->get_sale_price( 'edit' ) >= $product->get_regular_price( 'edit' ) ) { + update_post_meta( $product->get_id(), '_sale_price', '' ); + $product->set_sale_price( '' ); + } + } + + if ( in_array( 'date_on_sale_from', $this->updated_props, true ) || in_array( 'date_on_sale_to', $this->updated_props, true ) || in_array( 'regular_price', $this->updated_props, true ) || in_array( 'sale_price', $this->updated_props, true ) || in_array( 'product_type', $this->updated_props, true ) ) { + if ( $product->is_on_sale( 'edit' ) ) { + update_post_meta( $product->get_id(), '_price', $product->get_sale_price( 'edit' ) ); + $product->set_price( $product->get_sale_price( 'edit' ) ); + } else { + update_post_meta( $product->get_id(), '_price', $product->get_regular_price( 'edit' ) ); + $product->set_price( $product->get_regular_price( 'edit' ) ); + } + } + } + + if ( in_array( 'stock_quantity', $this->updated_props, true ) ) { + if ( $product->is_type( 'variation' ) ) { + do_action( 'woocommerce_variation_set_stock', $product ); + } else { + do_action( 'woocommerce_product_set_stock', $product ); + } + } + + if ( in_array( 'stock_status', $this->updated_props, true ) ) { + if ( $product->is_type( 'variation' ) ) { + do_action( 'woocommerce_variation_set_stock_status', $product->get_id(), $product->get_stock_status(), $product ); + } else { + do_action( 'woocommerce_product_set_stock_status', $product->get_id(), $product->get_stock_status(), $product ); + } + } + + if ( array_intersect( $this->updated_props, array( 'sku', 'regular_price', 'sale_price', 'date_on_sale_from', 'date_on_sale_to', 'total_sales', 'average_rating', 'stock_quantity', 'stock_status', 'manage_stock', 'downloadable', 'virtual', 'tax_status', 'tax_class' ) ) ) { + $this->update_lookup_table( $product->get_id(), 'wc_product_meta_lookup' ); + } + + // Trigger action so 3rd parties can deal with updated props. + do_action( 'woocommerce_product_object_updated_props', $product, $this->updated_props ); + + // After handling, we can reset the props array. + $this->updated_props = array(); + } + + /** + * For all stored terms in all taxonomies, save them to the DB. + * + * @param WC_Product $product Product object. + * @param bool $force Force update. Used during create. + * @since 3.0.0 + */ + protected function update_terms( &$product, $force = false ) { + $changes = $product->get_changes(); + + if ( $force || array_key_exists( 'category_ids', $changes ) ) { + $categories = $product->get_category_ids( 'edit' ); + + if ( empty( $categories ) && get_option( 'default_product_cat', 0 ) ) { + $categories = array( get_option( 'default_product_cat', 0 ) ); + } + + wp_set_post_terms( $product->get_id(), $categories, 'product_cat', false ); + } + if ( $force || array_key_exists( 'tag_ids', $changes ) ) { + wp_set_post_terms( $product->get_id(), $product->get_tag_ids( 'edit' ), 'product_tag', false ); + } + if ( $force || array_key_exists( 'shipping_class_id', $changes ) ) { + wp_set_post_terms( $product->get_id(), array( $product->get_shipping_class_id( 'edit' ) ), 'product_shipping_class', false ); + } + } + + /** + * Update visibility terms based on props. + * + * @since 3.0.0 + * + * @param WC_Product $product Product object. + * @param bool $force Force update. Used during create. + */ + protected function update_visibility( &$product, $force = false ) { + $changes = $product->get_changes(); + + if ( $force || array_intersect( array( 'featured', 'stock_status', 'average_rating', 'catalog_visibility' ), array_keys( $changes ) ) ) { + $terms = array(); + + if ( $product->get_featured() ) { + $terms[] = 'featured'; + } + + if ( 'outofstock' === $product->get_stock_status() ) { + $terms[] = 'outofstock'; + } + + $rating = min( 5, NumberUtil::round( $product->get_average_rating(), 0 ) ); + + if ( $rating > 0 ) { + $terms[] = 'rated-' . $rating; + } + + switch ( $product->get_catalog_visibility() ) { + case 'hidden': + $terms[] = 'exclude-from-search'; + $terms[] = 'exclude-from-catalog'; + break; + case 'catalog': + $terms[] = 'exclude-from-search'; + break; + case 'search': + $terms[] = 'exclude-from-catalog'; + break; + } + + if ( ! is_wp_error( wp_set_post_terms( $product->get_id(), $terms, 'product_visibility', false ) ) ) { + do_action( 'woocommerce_product_set_visibility', $product->get_id(), $product->get_catalog_visibility() ); + } + } + } + + /** + * Update attributes which are a mix of terms and meta data. + * + * @param WC_Product $product Product object. + * @param bool $force Force update. Used during create. + * @since 3.0.0 + */ + protected function update_attributes( &$product, $force = false ) { + $changes = $product->get_changes(); + + if ( $force || array_key_exists( 'attributes', $changes ) ) { + $attributes = $product->get_attributes(); + $meta_values = array(); + + if ( $attributes ) { + foreach ( $attributes as $attribute_key => $attribute ) { + $value = ''; + + if ( is_null( $attribute ) ) { + if ( taxonomy_exists( $attribute_key ) ) { + // Handle attributes that have been unset. + wp_set_object_terms( $product->get_id(), array(), $attribute_key ); + } elseif ( taxonomy_exists( urldecode( $attribute_key ) ) ) { + // Handle attributes that have been unset. + wp_set_object_terms( $product->get_id(), array(), urldecode( $attribute_key ) ); + } + continue; + + } elseif ( $attribute->is_taxonomy() ) { + wp_set_object_terms( $product->get_id(), wp_list_pluck( (array) $attribute->get_terms(), 'term_id' ), $attribute->get_name() ); + } else { + $value = wc_implode_text_attributes( $attribute->get_options() ); + } + + // Store in format WC uses in meta. + $meta_values[ $attribute_key ] = array( + 'name' => $attribute->get_name(), + 'value' => $value, + 'position' => $attribute->get_position(), + 'is_visible' => $attribute->get_visible() ? 1 : 0, + 'is_variation' => $attribute->get_variation() ? 1 : 0, + 'is_taxonomy' => $attribute->is_taxonomy() ? 1 : 0, + ); + } + } + // Note, we use wp_slash to add extra level of escaping. See https://codex.wordpress.org/Function_Reference/update_post_meta#Workaround. + $this->update_or_delete_post_meta( $product, '_product_attributes', wp_slash( $meta_values ) ); + } + } + + /** + * Update downloads. + * + * @since 3.0.0 + * @param WC_Product $product Product object. + * @param bool $force Force update. Used during create. + * @return bool If updated or not. + */ + protected function update_downloads( &$product, $force = false ) { + $changes = $product->get_changes(); + + if ( $force || array_key_exists( 'downloads', $changes ) ) { + $downloads = $product->get_downloads(); + $meta_values = array(); + + if ( $downloads ) { + foreach ( $downloads as $key => $download ) { + // Store in format WC uses in meta. + $meta_values[ $key ] = $download->get_data(); + } + } + + if ( $product->is_type( 'variation' ) ) { + do_action( 'woocommerce_process_product_file_download_paths', $product->get_parent_id(), $product->get_id(), $downloads ); + } else { + do_action( 'woocommerce_process_product_file_download_paths', $product->get_id(), 0, $downloads ); + } + + return $this->update_or_delete_post_meta( $product, '_downloadable_files', wp_slash( $meta_values ) ); + } + return false; + } + + /** + * Make sure we store the product type and version (to track data changes). + * + * @param WC_Product $product Product object. + * @since 3.0.0 + */ + protected function update_version_and_type( &$product ) { + $old_type = WC_Product_Factory::get_product_type( $product->get_id() ); + $new_type = $product->get_type(); + + wp_set_object_terms( $product->get_id(), $new_type, 'product_type' ); + update_post_meta( $product->get_id(), '_product_version', Constants::get_constant( 'WC_VERSION' ) ); + + // Action for the transition. + if ( $old_type !== $new_type ) { + $this->updated_props[] = 'product_type'; + do_action( 'woocommerce_product_type_changed', $product, $old_type, $new_type ); + } + } + + /** + * Clear any caches. + * + * @param WC_Product $product Product object. + * @since 3.0.0 + */ + protected function clear_caches( &$product ) { + wc_delete_product_transients( $product->get_id() ); + if ( $product->get_parent_id( 'edit' ) ) { + wc_delete_product_transients( $product->get_parent_id( 'edit' ) ); + WC_Cache_Helper::invalidate_cache_group( 'product_' . $product->get_parent_id( 'edit' ) ); + } + WC_Cache_Helper::invalidate_attribute_count( array_keys( $product->get_attributes() ) ); + WC_Cache_Helper::invalidate_cache_group( 'product_' . $product->get_id() ); + } + + /* + |-------------------------------------------------------------------------- + | wc-product-functions.php methods + |-------------------------------------------------------------------------- + */ + + /** + * Returns an array of on sale products, as an array of objects with an + * ID and parent_id present. Example: $return[0]->id, $return[0]->parent_id. + * + * @return array + * @since 3.0.0 + */ + public function get_on_sale_products() { + global $wpdb; + + $exclude_term_ids = array(); + $outofstock_join = ''; + $outofstock_where = ''; + $non_published_where = ''; + $product_visibility_term_ids = wc_get_product_visibility_term_ids(); + + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && $product_visibility_term_ids['outofstock'] ) { + $exclude_term_ids[] = $product_visibility_term_ids['outofstock']; + } + + if ( count( $exclude_term_ids ) ) { + $outofstock_join = " LEFT JOIN ( SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN ( " . implode( ',', array_map( 'absint', $exclude_term_ids ) ) . ' ) ) AS exclude_join ON exclude_join.object_id = id'; + $outofstock_where = ' AND exclude_join.object_id IS NULL'; + } + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + return $wpdb->get_results( + " + SELECT posts.ID as id, posts.post_parent as parent_id + FROM {$wpdb->posts} AS posts + INNER JOIN {$wpdb->wc_product_meta_lookup} AS lookup ON posts.ID = lookup.product_id + $outofstock_join + WHERE posts.post_type IN ( 'product', 'product_variation' ) + AND posts.post_status = 'publish' + AND lookup.onsale = 1 + $outofstock_where + AND posts.post_parent NOT IN ( + SELECT ID FROM `$wpdb->posts` as posts + WHERE posts.post_type = 'product' + AND posts.post_parent = 0 + AND posts.post_status != 'publish' + ) + GROUP BY posts.ID + " + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Returns a list of product IDs ( id as key => parent as value) that are + * featured. Uses get_posts instead of wc_get_products since we want + * some extra meta queries and ALL products (posts_per_page = -1). + * + * @return array + * @since 3.0.0 + */ + public function get_featured_product_ids() { + $product_visibility_term_ids = wc_get_product_visibility_term_ids(); + + return get_posts( + array( + 'post_type' => array( 'product', 'product_variation' ), + 'posts_per_page' => -1, + 'post_status' => 'publish', + 'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query + 'relation' => 'AND', + array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( $product_visibility_term_ids['featured'] ), + ), + array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( $product_visibility_term_ids['exclude-from-catalog'] ), + 'operator' => 'NOT IN', + ), + ), + 'fields' => 'id=>parent', + ) + ); + } + + /** + * Check if product sku is found for any other product IDs. + * + * @since 3.0.0 + * @param int $product_id Product ID. + * @param string $sku Will be slashed to work around https://core.trac.wordpress.org/ticket/27421. + * @return bool + */ + public function is_existing_sku( $product_id, $sku ) { + global $wpdb; + + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + return (bool) $wpdb->get_var( + $wpdb->prepare( + " + SELECT posts.ID + FROM {$wpdb->posts} as posts + INNER JOIN {$wpdb->wc_product_meta_lookup} AS lookup ON posts.ID = lookup.product_id + WHERE + posts.post_type IN ( 'product', 'product_variation' ) + AND posts.post_status != 'trash' + AND lookup.sku = %s + AND lookup.product_id <> %d + LIMIT 1 + ", + wp_slash( $sku ), + $product_id + ) + ); + } + + /** + * Return product ID based on SKU. + * + * @since 3.0.0 + * @param string $sku Product SKU. + * @return int + */ + public function get_product_id_by_sku( $sku ) { + global $wpdb; + + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + $id = $wpdb->get_var( + $wpdb->prepare( + " + SELECT posts.ID + FROM {$wpdb->posts} as posts + INNER JOIN {$wpdb->wc_product_meta_lookup} AS lookup ON posts.ID = lookup.product_id + WHERE + posts.post_type IN ( 'product', 'product_variation' ) + AND posts.post_status != 'trash' + AND lookup.sku = %s + LIMIT 1 + ", + $sku + ) + ); + + return (int) apply_filters( 'woocommerce_get_product_id_by_sku', $id, $sku ); + } + + /** + * Returns an array of IDs of products that have sales starting soon. + * + * @since 3.0.0 + * @return array + */ + public function get_starting_sales() { + global $wpdb; + + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + return $wpdb->get_col( + $wpdb->prepare( + "SELECT postmeta.post_id FROM {$wpdb->postmeta} as postmeta + LEFT JOIN {$wpdb->postmeta} as postmeta_2 ON postmeta.post_id = postmeta_2.post_id + LEFT JOIN {$wpdb->postmeta} as postmeta_3 ON postmeta.post_id = postmeta_3.post_id + WHERE postmeta.meta_key = '_sale_price_dates_from' + AND postmeta_2.meta_key = '_price' + AND postmeta_3.meta_key = '_sale_price' + AND postmeta.meta_value > 0 + AND postmeta.meta_value < %s + AND postmeta_2.meta_value != postmeta_3.meta_value", + time() + ) + ); + } + + /** + * Returns an array of IDs of products that have sales which are due to end. + * + * @since 3.0.0 + * @return array + */ + public function get_ending_sales() { + global $wpdb; + + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + return $wpdb->get_col( + $wpdb->prepare( + "SELECT postmeta.post_id FROM {$wpdb->postmeta} as postmeta + LEFT JOIN {$wpdb->postmeta} as postmeta_2 ON postmeta.post_id = postmeta_2.post_id + LEFT JOIN {$wpdb->postmeta} as postmeta_3 ON postmeta.post_id = postmeta_3.post_id + WHERE postmeta.meta_key = '_sale_price_dates_to' + AND postmeta_2.meta_key = '_price' + AND postmeta_3.meta_key = '_regular_price' + AND postmeta.meta_value > 0 + AND postmeta.meta_value < %s + AND postmeta_2.meta_value != postmeta_3.meta_value", + time() + ) + ); + } + + /** + * Find a matching (enabled) variation within a variable product. + * + * @since 3.0.0 + * @param WC_Product $product Variable product. + * @param array $match_attributes Array of attributes we want to try to match. + * @return int Matching variation ID or 0. + */ + public function find_matching_product_variation( $product, $match_attributes = array() ) { + global $wpdb; + + $meta_attribute_names = array(); + + // Get attributes to match in meta. + foreach ( $product->get_attributes() as $attribute ) { + if ( ! $attribute->get_variation() ) { + continue; + } + $meta_attribute_names[] = 'attribute_' . sanitize_title( $attribute->get_name() ); + } + + // Get the attributes of the variations. + $query = $wpdb->prepare( + " + SELECT postmeta.post_id, postmeta.meta_key, postmeta.meta_value, posts.menu_order FROM {$wpdb->postmeta} as postmeta + LEFT JOIN {$wpdb->posts} as posts ON postmeta.post_id=posts.ID + WHERE postmeta.post_id IN ( + SELECT ID FROM {$wpdb->posts} + WHERE {$wpdb->posts}.post_parent = %d + AND {$wpdb->posts}.post_status = 'publish' + AND {$wpdb->posts}.post_type = 'product_variation' + ) + ", + $product->get_id() + ); + + $query .= ' AND postmeta.meta_key IN ( "' . implode( '","', array_map( 'esc_sql', $meta_attribute_names ) ) . '" )'; + + $query .= ' ORDER BY posts.menu_order ASC, postmeta.post_id ASC;'; + + $attributes = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + + if ( ! $attributes ) { + return 0; + } + + $sorted_meta = array(); + + foreach ( $attributes as $m ) { + $sorted_meta[ $m->post_id ][ $m->meta_key ] = $m->meta_value; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + } + + /** + * Check each variation to find the one that matches the $match_attributes. + * + * Note: Not all meta fields will be set which is why we check existance. + */ + foreach ( $sorted_meta as $variation_id => $variation ) { + $match = true; + + // Loop over the variation meta keys and values i.e. what is saved to the products. Note: $attribute_value is empty when 'any' is in use. + foreach ( $variation as $attribute_key => $attribute_value ) { + $match_any_value = '' === $attribute_value; + + if ( ! $match_any_value && ! array_key_exists( $attribute_key, $match_attributes ) ) { + $match = false; // Requires a selection but no value was provide. + } + + if ( array_key_exists( $attribute_key, $match_attributes ) ) { // Value to match was provided. + if ( ! $match_any_value && $match_attributes[ $attribute_key ] !== $attribute_value ) { + $match = false; // Provided value does not match variation. + } + } + } + + if ( true === $match ) { + return $variation_id; + } + } + + if ( version_compare( get_post_meta( $product->get_id(), '_product_version', true ), '2.4.0', '<' ) ) { + /** + * Pre 2.4 handling where 'slugs' were saved instead of the full text attribute. + * Fallback is here because there are cases where data will be 'synced' but the product version will remain the same. + */ + return ( array_map( 'sanitize_title', $match_attributes ) === $match_attributes ) ? 0 : $this->find_matching_product_variation( $product, array_map( 'sanitize_title', $match_attributes ) ); + } + + return 0; + } + + /** + * Creates all possible combinations of variations from the attributes, without creating duplicates. + * + * @since 3.6.0 + * @todo Add to interface in 4.0. + * @param WC_Product $product Variable product. + * @param int $limit Limit the number of created variations. + * @return int Number of created variations. + */ + public function create_all_product_variations( $product, $limit = -1 ) { + $count = 0; + + if ( ! $product ) { + return $count; + } + + $attributes = wc_list_pluck( array_filter( $product->get_attributes(), 'wc_attributes_array_filter_variation' ), 'get_slugs' ); + + if ( empty( $attributes ) ) { + return $count; + } + + // Get existing variations so we don't create duplicates. + $existing_variations = array_map( 'wc_get_product', $product->get_children() ); + $existing_attributes = array(); + + foreach ( $existing_variations as $existing_variation ) { + $existing_attributes[] = $existing_variation->get_attributes(); + } + + $possible_attributes = array_reverse( wc_array_cartesian( $attributes ) ); + + foreach ( $possible_attributes as $possible_attribute ) { + // Allow any order if key/values -- do not use strict mode. + if ( in_array( $possible_attribute, $existing_attributes ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict + continue; + } + $variation = wc_get_product_object( 'variation' ); + $variation->set_parent_id( $product->get_id() ); + $variation->set_attributes( $possible_attribute ); + $variation_id = $variation->save(); + + do_action( 'product_variation_linked', $variation_id ); + + $count ++; + + if ( $limit > 0 && $count >= $limit ) { + break; + } + } + + return $count; + } + + /** + * Make sure all variations have a sort order set so they can be reordered correctly. + * + * @param int $parent_id Product ID. + */ + public function sort_all_product_variations( $parent_id ) { + global $wpdb; + + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + $ids = $wpdb->get_col( + $wpdb->prepare( + "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product_variation' AND post_parent = %d AND post_status = 'publish' ORDER BY menu_order ASC, ID ASC", + $parent_id + ) + ); + $index = 1; + + foreach ( $ids as $id ) { + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + $wpdb->update( $wpdb->posts, array( 'menu_order' => ( $index++ ) ), array( 'ID' => absint( $id ) ) ); + } + } + + /** + * Return a list of related products (using data like categories and IDs). + * + * @since 3.0.0 + * @param array $cats_array List of categories IDs. + * @param array $tags_array List of tags IDs. + * @param array $exclude_ids Excluded IDs. + * @param int $limit Limit of results. + * @param int $product_id Product ID. + * @return array + */ + public function get_related_products( $cats_array, $tags_array, $exclude_ids, $limit, $product_id ) { + global $wpdb; + + $args = array( + 'categories' => $cats_array, + 'tags' => $tags_array, + 'exclude_ids' => $exclude_ids, + 'limit' => $limit + 10, + ); + + $related_product_query = (array) apply_filters( 'woocommerce_product_related_posts_query', $this->get_related_products_query( $cats_array, $tags_array, $exclude_ids, $limit + 10 ), $product_id, $args ); + + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared + return $wpdb->get_col( implode( ' ', $related_product_query ) ); + } + + /** + * Builds the related posts query. + * + * @since 3.0.0 + * + * @param array $cats_array List of categories IDs. + * @param array $tags_array List of tags IDs. + * @param array $exclude_ids Excluded IDs. + * @param int $limit Limit of results. + * + * @return array + */ + public function get_related_products_query( $cats_array, $tags_array, $exclude_ids, $limit ) { + global $wpdb; + + $include_term_ids = array_merge( $cats_array, $tags_array ); + $exclude_term_ids = array(); + $product_visibility_term_ids = wc_get_product_visibility_term_ids(); + + if ( $product_visibility_term_ids['exclude-from-catalog'] ) { + $exclude_term_ids[] = $product_visibility_term_ids['exclude-from-catalog']; + } + + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && $product_visibility_term_ids['outofstock'] ) { + $exclude_term_ids[] = $product_visibility_term_ids['outofstock']; + } + + $query = array( + 'fields' => " + SELECT DISTINCT ID FROM {$wpdb->posts} p + ", + 'join' => '', + 'where' => " + WHERE 1=1 + AND p.post_status = 'publish' + AND p.post_type = 'product' + + ", + 'limits' => ' + LIMIT ' . absint( $limit ) . ' + ', + ); + + if ( count( $exclude_term_ids ) ) { + $query['join'] .= " LEFT JOIN ( SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN ( " . implode( ',', array_map( 'absint', $exclude_term_ids ) ) . ' ) ) AS exclude_join ON exclude_join.object_id = p.ID'; + $query['where'] .= ' AND exclude_join.object_id IS NULL'; + } + + if ( count( $include_term_ids ) ) { + $query['join'] .= " INNER JOIN ( SELECT object_id FROM {$wpdb->term_relationships} INNER JOIN {$wpdb->term_taxonomy} using( term_taxonomy_id ) WHERE term_id IN ( " . implode( ',', array_map( 'absint', $include_term_ids ) ) . ' ) ) AS include_join ON include_join.object_id = p.ID'; + } + + if ( count( $exclude_ids ) ) { + $query['where'] .= ' AND p.ID NOT IN ( ' . implode( ',', array_map( 'absint', $exclude_ids ) ) . ' )'; + } + + return $query; + } + + /** + * Update a product's stock amount directly in the database. + * + * Updates both post meta and lookup tables. Ignores manage stock setting on the product. + * + * @param int $product_id_with_stock Product ID. + * @param int|float|null $stock_quantity Stock quantity. + */ + protected function set_product_stock( $product_id_with_stock, $stock_quantity ) { + global $wpdb; + + // Generate SQL. + $sql = $wpdb->prepare( + "UPDATE {$wpdb->postmeta} SET meta_value = %f WHERE post_id = %d AND meta_key='_stock'", + $stock_quantity, + $product_id_with_stock + ); + + $sql = apply_filters( 'woocommerce_update_product_stock_query', $sql, $product_id_with_stock, $stock_quantity, 'set' ); + + $wpdb->query( $sql ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared + + // Cache delete is required (not only) to set correct data for lookup table (which reads from cache). + // Sometimes I wonder if it shouldn't be part of update_lookup_table. + wp_cache_delete( $product_id_with_stock, 'post_meta' ); + + $this->update_lookup_table( $product_id_with_stock, 'wc_product_meta_lookup' ); + } + + /** + * Update a product's stock amount directly. + * + * Uses queries rather than update_post_meta so we can do this in one query (to avoid stock issues). + * Ignores manage stock setting on the product and sets quantities directly in the db: post meta and lookup tables. + * Uses locking to update the quantity. If the lock is not acquired, change is lost. + * + * @since 3.0.0 this supports set, increase and decrease. + * @param int $product_id_with_stock Product ID. + * @param int|float|null $stock_quantity Stock quantity. + * @param string $operation Set, increase and decrease. + * @return int|float New stock level. + */ + public function update_product_stock( $product_id_with_stock, $stock_quantity = null, $operation = 'set' ) { + global $wpdb; + + // Ensures a row exists to update. + add_post_meta( $product_id_with_stock, '_stock', 0, true ); + + if ( 'set' === $operation ) { + $new_stock = wc_stock_amount( $stock_quantity ); + + // Generate SQL. + $sql = $wpdb->prepare( + "UPDATE {$wpdb->postmeta} SET meta_value = %f WHERE post_id = %d AND meta_key='_stock'", + $new_stock, + $product_id_with_stock + ); + } else { + $current_stock = wc_stock_amount( + $wpdb->get_var( + $wpdb->prepare( + "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key='_stock';", + $product_id_with_stock + ) + ) + ); + + // Calculate new value for filter below. Set multiplier to subtract or add the meta_value. + switch ( $operation ) { + case 'increase': + $new_stock = $current_stock + wc_stock_amount( $stock_quantity ); + $multiplier = 1; + break; + default: + $new_stock = $current_stock - wc_stock_amount( $stock_quantity ); + $multiplier = -1; + break; + } + + // Generate SQL. + $sql = $wpdb->prepare( + "UPDATE {$wpdb->postmeta} SET meta_value = meta_value %+f WHERE post_id = %d AND meta_key='_stock'", + wc_stock_amount( $stock_quantity ) * $multiplier, // This will either subtract or add depending on operation. + $product_id_with_stock + ); + } + + $sql = apply_filters( 'woocommerce_update_product_stock_query', $sql, $product_id_with_stock, $new_stock, $operation ); + + $wpdb->query( $sql ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared + + // Cache delete is required (not only) to set correct data for lookup table (which reads from cache). + // Sometimes I wonder if it shouldn't be part of update_lookup_table. + wp_cache_delete( $product_id_with_stock, 'post_meta' ); + + $this->update_lookup_table( $product_id_with_stock, 'wc_product_meta_lookup' ); + + /** + * Fire an action for this direct update so it can be detected by other code. + * + * @since 3.6 + * @param int $product_id_with_stock Product ID that was updated directly. + */ + do_action( 'woocommerce_updated_product_stock', $product_id_with_stock ); + + return $new_stock; + } + + /** + * Update a product's sale count directly. + * + * Uses queries rather than update_post_meta so we can do this in one query for performance. + * + * @since 3.0.0 this supports set, increase and decrease. + * @param int $product_id Product ID. + * @param int|null $quantity Quantity. + * @param string $operation set, increase and decrease. + */ + public function update_product_sales( $product_id, $quantity = null, $operation = 'set' ) { + global $wpdb; + add_post_meta( $product_id, 'total_sales', 0, true ); + + // Update stock in DB directly. + switch ( $operation ) { + case 'increase': + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + $wpdb->query( + $wpdb->prepare( + "UPDATE {$wpdb->postmeta} SET meta_value = meta_value + %f WHERE post_id = %d AND meta_key='total_sales'", + $quantity, + $product_id + ) + ); + break; + case 'decrease': + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + $wpdb->query( + $wpdb->prepare( + "UPDATE {$wpdb->postmeta} SET meta_value = meta_value - %f WHERE post_id = %d AND meta_key='total_sales'", + $quantity, + $product_id + ) + ); + break; + default: + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + $wpdb->query( + $wpdb->prepare( + "UPDATE {$wpdb->postmeta} SET meta_value = %f WHERE post_id = %d AND meta_key='total_sales'", + $quantity, + $product_id + ) + ); + break; + } + + wp_cache_delete( $product_id, 'post_meta' ); + + $this->update_lookup_table( $product_id, 'wc_product_meta_lookup' ); + + /** + * Fire an action for this direct update so it can be detected by other code. + * + * @since 3.6 + * @param int $product_id Product ID that was updated directly. + */ + do_action( 'woocommerce_updated_product_sales', $product_id ); + } + + /** + * Update a products average rating meta. + * + * @since 3.0.0 + * @todo Deprecate unused function? + * @param WC_Product $product Product object. + */ + public function update_average_rating( $product ) { + update_post_meta( $product->get_id(), '_wc_average_rating', $product->get_average_rating( 'edit' ) ); + self::update_visibility( $product, true ); + } + + /** + * Update a products review count meta. + * + * @since 3.0.0 + * @todo Deprecate unused function? + * @param WC_Product $product Product object. + */ + public function update_review_count( $product ) { + update_post_meta( $product->get_id(), '_wc_review_count', $product->get_review_count( 'edit' ) ); + } + + /** + * Update a products rating counts. + * + * @since 3.0.0 + * @todo Deprecate unused function? + * @param WC_Product $product Product object. + */ + public function update_rating_counts( $product ) { + update_post_meta( $product->get_id(), '_wc_rating_count', $product->get_rating_counts( 'edit' ) ); + } + + /** + * Get shipping class ID by slug. + * + * @since 3.0.0 + * @param string $slug Product shipping class slug. + * @return int|false + */ + public function get_shipping_class_id_by_slug( $slug ) { + $shipping_class_term = get_term_by( 'slug', $slug, 'product_shipping_class' ); + if ( $shipping_class_term ) { + return $shipping_class_term->term_id; + } else { + return false; + } + } + + /** + * Returns an array of products. + * + * @param array $args Args to pass to WC_Product_Query(). + * @return array|object + * @see wc_get_products + */ + public function get_products( $args = array() ) { + $query = new WC_Product_Query( $args ); + return $query->get_products(); + } + + /** + * Search product data for a term and return ids. + * + * @param string $term Search term. + * @param string $type Type of product. + * @param bool $include_variations Include variations in search or not. + * @param bool $all_statuses Should we search all statuses or limit to published. + * @param null|int $limit Limit returned results. @since 3.5.0. + * @param null|array $include Keep specific results. @since 3.6.0. + * @param null|array $exclude Discard specific results. @since 3.6.0. + * @return array of ids + */ + public function search_products( $term, $type = '', $include_variations = false, $all_statuses = false, $limit = null, $include = null, $exclude = null ) { + global $wpdb; + + $custom_results = apply_filters( 'woocommerce_product_pre_search_products', false, $term, $type, $include_variations, $all_statuses, $limit ); + + if ( is_array( $custom_results ) ) { + return $custom_results; + } + + $post_types = $include_variations ? array( 'product', 'product_variation' ) : array( 'product' ); + $join_query = ''; + $type_where = ''; + $status_where = ''; + $limit_query = ''; + + // When searching variations we should include the parent's meta table for use in searches. + if ( $include_variations ) { + $join_query = " LEFT JOIN {$wpdb->wc_product_meta_lookup} parent_wc_product_meta_lookup + ON posts.post_type = 'product_variation' AND parent_wc_product_meta_lookup.product_id = posts.post_parent "; + } + + /** + * Hook woocommerce_search_products_post_statuses. + * + * @since 3.7.0 + * @param array $post_statuses List of post statuses. + */ + $post_statuses = apply_filters( + 'woocommerce_search_products_post_statuses', + current_user_can( 'edit_private_products' ) ? array( 'private', 'publish' ) : array( 'publish' ) + ); + + // See if search term contains OR keywords. + if ( stristr( $term, ' or ' ) ) { + $term_groups = preg_split( '/\s+or\s+/i', $term ); + } else { + $term_groups = array( $term ); + } + + $search_where = ''; + $search_queries = array(); + + foreach ( $term_groups as $term_group ) { + // Parse search terms. + if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $term_group, $matches ) ) { + $search_terms = $this->get_valid_search_terms( $matches[0] ); + $count = count( $search_terms ); + + // if the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence. + if ( 9 < $count || 0 === $count ) { + $search_terms = array( $term_group ); + } + } else { + $search_terms = array( $term_group ); + } + + $term_group_query = ''; + $searchand = ''; + + foreach ( $search_terms as $search_term ) { + $like = '%' . $wpdb->esc_like( $search_term ) . '%'; + + // Variations should also search the parent's meta table for fallback fields. + if ( $include_variations ) { + $variation_query = $wpdb->prepare( ' OR ( wc_product_meta_lookup.sku = "" AND parent_wc_product_meta_lookup.sku LIKE %s ) ', $like ); + } else { + $variation_query = ''; + } + + $term_group_query .= $wpdb->prepare( " {$searchand} ( ( posts.post_title LIKE %s) OR ( posts.post_excerpt LIKE %s) OR ( posts.post_content LIKE %s ) OR ( wc_product_meta_lookup.sku LIKE %s ) $variation_query)", $like, $like, $like, $like ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $searchand = ' AND '; + } + + if ( $term_group_query ) { + $search_queries[] = $term_group_query; + } + } + + if ( ! empty( $search_queries ) ) { + $search_where = ' AND (' . implode( ') OR (', $search_queries ) . ') '; + } + + if ( ! empty( $include ) && is_array( $include ) ) { + $search_where .= ' AND posts.ID IN(' . implode( ',', array_map( 'absint', $include ) ) . ') '; + } + + if ( ! empty( $exclude ) && is_array( $exclude ) ) { + $search_where .= ' AND posts.ID NOT IN(' . implode( ',', array_map( 'absint', $exclude ) ) . ') '; + } + + if ( 'virtual' === $type ) { + $type_where = ' AND ( wc_product_meta_lookup.virtual = 1 ) '; + } elseif ( 'downloadable' === $type ) { + $type_where = ' AND ( wc_product_meta_lookup.downloadable = 1 ) '; + } + + if ( ! $all_statuses ) { + $status_where = " AND posts.post_status IN ('" . implode( "','", $post_statuses ) . "') "; + } + + if ( $limit ) { + $limit_query = $wpdb->prepare( ' LIMIT %d ', $limit ); + } + + // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery + $search_results = $wpdb->get_results( + // phpcs:disable + "SELECT DISTINCT posts.ID as product_id, posts.post_parent as parent_id FROM {$wpdb->posts} posts + LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON posts.ID = wc_product_meta_lookup.product_id + $join_query + WHERE posts.post_type IN ('" . implode( "','", $post_types ) . "') + $search_where + $status_where + $type_where + ORDER BY posts.post_parent ASC, posts.post_title ASC + $limit_query + " + // phpcs:enable + ); + + $product_ids = wp_parse_id_list( array_merge( wp_list_pluck( $search_results, 'product_id' ), wp_list_pluck( $search_results, 'parent_id' ) ) ); + + if ( is_numeric( $term ) ) { + $post_id = absint( $term ); + $post_type = get_post_type( $post_id ); + + if ( 'product_variation' === $post_type && $include_variations ) { + $product_ids[] = $post_id; + } elseif ( 'product' === $post_type ) { + $product_ids[] = $post_id; + } + + $product_ids[] = wp_get_post_parent_id( $post_id ); + } + + return wp_parse_id_list( $product_ids ); + } + + /** + * Get the product type based on product ID. + * + * @since 3.0.0 + * @param int $product_id Product ID. + * @return bool|string + */ + public function get_product_type( $product_id ) { + $cache_key = WC_Cache_Helper::get_cache_prefix( 'product_' . $product_id ) . '_type_' . $product_id; + $product_type = wp_cache_get( $cache_key, 'products' ); + + if ( $product_type ) { + return $product_type; + } + + $post_type = get_post_type( $product_id ); + + if ( 'product_variation' === $post_type ) { + $product_type = 'variation'; + } elseif ( 'product' === $post_type ) { + $terms = get_the_terms( $product_id, 'product_type' ); + $product_type = ! empty( $terms ) && ! is_wp_error( $terms ) ? sanitize_title( current( $terms )->name ) : 'simple'; + } else { + $product_type = false; + } + + wp_cache_set( $cache_key, $product_type, 'products' ); + + return $product_type; + } + + /** + * Add ability to get products by 'reviews_allowed' in WC_Product_Query. + * + * @since 3.2.0 + * @param string $where Where clause. + * @param WP_Query $wp_query WP_Query instance. + * @return string + */ + public function reviews_allowed_query_where( $where, $wp_query ) { + global $wpdb; + + if ( isset( $wp_query->query_vars['reviews_allowed'] ) && is_bool( $wp_query->query_vars['reviews_allowed'] ) ) { + if ( $wp_query->query_vars['reviews_allowed'] ) { + $where .= " AND $wpdb->posts.comment_status = 'open'"; + } else { + $where .= " AND $wpdb->posts.comment_status = 'closed'"; + } + } + + return $where; + } + + /** + * Get valid WP_Query args from a WC_Product_Query's query variables. + * + * @since 3.2.0 + * @param array $query_vars Query vars from a WC_Product_Query. + * @return array + */ + protected function get_wp_query_args( $query_vars ) { + + // Map query vars to ones that get_wp_query_args or WP_Query recognize. + $key_mapping = array( + 'status' => 'post_status', + 'page' => 'paged', + 'include' => 'post__in', + 'stock_quantity' => 'stock', + 'average_rating' => 'wc_average_rating', + 'review_count' => 'wc_review_count', + ); + foreach ( $key_mapping as $query_key => $db_key ) { + if ( isset( $query_vars[ $query_key ] ) ) { + $query_vars[ $db_key ] = $query_vars[ $query_key ]; + unset( $query_vars[ $query_key ] ); + } + } + + // Map boolean queries that are stored as 'yes'/'no' in the DB to 'yes' or 'no'. + $boolean_queries = array( + 'virtual', + 'downloadable', + 'sold_individually', + 'manage_stock', + ); + foreach ( $boolean_queries as $boolean_query ) { + if ( isset( $query_vars[ $boolean_query ] ) && '' !== $query_vars[ $boolean_query ] ) { + $query_vars[ $boolean_query ] = $query_vars[ $boolean_query ] ? 'yes' : 'no'; + } + } + + // These queries cannot be auto-generated so we have to remove them and build them manually. + $manual_queries = array( + 'sku' => '', + 'featured' => '', + 'visibility' => '', + ); + foreach ( $manual_queries as $key => $manual_query ) { + if ( isset( $query_vars[ $key ] ) ) { + $manual_queries[ $key ] = $query_vars[ $key ]; + unset( $query_vars[ $key ] ); + } + } + + $wp_query_args = parent::get_wp_query_args( $query_vars ); + + if ( ! isset( $wp_query_args['date_query'] ) ) { + $wp_query_args['date_query'] = array(); + } + if ( ! isset( $wp_query_args['meta_query'] ) ) { + $wp_query_args['meta_query'] = array(); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + } + + // Handle product types. + if ( 'variation' === $query_vars['type'] ) { + $wp_query_args['post_type'] = 'product_variation'; + } elseif ( is_array( $query_vars['type'] ) && in_array( 'variation', $query_vars['type'], true ) ) { + $wp_query_args['post_type'] = array( 'product_variation', 'product' ); + $wp_query_args['tax_query'][] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query + 'relation' => 'OR', + array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $query_vars['type'], + ), + array( + 'taxonomy' => 'product_type', + 'field' => 'id', + 'operator' => 'NOT EXISTS', + ), + ); + } else { + $wp_query_args['post_type'] = 'product'; + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $query_vars['type'], + ); + } + + // Handle product categories. + if ( ! empty( $query_vars['category'] ) ) { + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_cat', + 'field' => 'slug', + 'terms' => $query_vars['category'], + ); + } + + // Handle product tags. + if ( ! empty( $query_vars['tag'] ) ) { + unset( $wp_query_args['tag'] ); + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_tag', + 'field' => 'slug', + 'terms' => $query_vars['tag'], + ); + } + + // Handle shipping classes. + if ( ! empty( $query_vars['shipping_class'] ) ) { + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_shipping_class', + 'field' => 'slug', + 'terms' => $query_vars['shipping_class'], + ); + } + + // Handle total_sales. + // This query doesn't get auto-generated since the meta key doesn't have the underscore prefix. + if ( isset( $query_vars['total_sales'] ) && '' !== $query_vars['total_sales'] ) { + $wp_query_args['meta_query'][] = array( + 'key' => 'total_sales', + 'value' => absint( $query_vars['total_sales'] ), + 'compare' => '=', + ); + } + + // Handle SKU. + if ( $manual_queries['sku'] ) { + // Check for existing values if wildcard is used. + if ( '*' === $manual_queries['sku'] ) { + $wp_query_args['meta_query'][] = array( + array( + 'key' => '_sku', + 'compare' => 'EXISTS', + ), + array( + 'key' => '_sku', + 'value' => '', + 'compare' => '!=', + ), + ); + } else { + $wp_query_args['meta_query'][] = array( + 'key' => '_sku', + 'value' => $manual_queries['sku'], + 'compare' => 'LIKE', + ); + } + } + + // Handle featured. + if ( '' !== $manual_queries['featured'] ) { + $product_visibility_term_ids = wc_get_product_visibility_term_ids(); + if ( $manual_queries['featured'] ) { + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( $product_visibility_term_ids['featured'] ), + ); + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( $product_visibility_term_ids['exclude-from-catalog'] ), + 'operator' => 'NOT IN', + ); + } else { + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( $product_visibility_term_ids['featured'] ), + 'operator' => 'NOT IN', + ); + } + } + + // Handle visibility. + if ( $manual_queries['visibility'] ) { + switch ( $manual_queries['visibility'] ) { + case 'search': + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'slug', + 'terms' => array( 'exclude-from-search' ), + 'operator' => 'NOT IN', + ); + break; + case 'catalog': + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'slug', + 'terms' => array( 'exclude-from-catalog' ), + 'operator' => 'NOT IN', + ); + break; + case 'visible': + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'slug', + 'terms' => array( 'exclude-from-catalog', 'exclude-from-search' ), + 'operator' => 'NOT IN', + ); + break; + case 'hidden': + $wp_query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'slug', + 'terms' => array( 'exclude-from-catalog', 'exclude-from-search' ), + 'operator' => 'AND', + ); + break; + } + } + + // Handle date queries. + $date_queries = array( + 'date_created' => 'post_date', + 'date_modified' => 'post_modified', + 'date_on_sale_from' => '_sale_price_dates_from', + 'date_on_sale_to' => '_sale_price_dates_to', + ); + foreach ( $date_queries as $query_var_key => $db_key ) { + if ( isset( $query_vars[ $query_var_key ] ) && '' !== $query_vars[ $query_var_key ] ) { + + // Remove any existing meta queries for the same keys to prevent conflicts. + $existing_queries = wp_list_pluck( $wp_query_args['meta_query'], 'key', true ); + foreach ( $existing_queries as $query_index => $query_contents ) { + unset( $wp_query_args['meta_query'][ $query_index ] ); + } + + $wp_query_args = $this->parse_date_for_wp_query( $query_vars[ $query_var_key ], $db_key, $wp_query_args ); + } + } + + // Handle paginate. + if ( ! isset( $query_vars['paginate'] ) || ! $query_vars['paginate'] ) { + $wp_query_args['no_found_rows'] = true; + } + + // Handle reviews_allowed. + if ( isset( $query_vars['reviews_allowed'] ) && is_bool( $query_vars['reviews_allowed'] ) ) { + add_filter( 'posts_where', array( $this, 'reviews_allowed_query_where' ), 10, 2 ); + } + + // Handle orderby. + if ( isset( $query_vars['orderby'] ) && 'include' === $query_vars['orderby'] ) { + $wp_query_args['orderby'] = 'post__in'; + } + + return apply_filters( 'woocommerce_product_data_store_cpt_get_products_query', $wp_query_args, $query_vars, $this ); + } + + /** + * Query for Products matching specific criteria. + * + * @since 3.2.0 + * + * @param array $query_vars Query vars from a WC_Product_Query. + * + * @return array|object + */ + public function query( $query_vars ) { + $args = $this->get_wp_query_args( $query_vars ); + + if ( ! empty( $args['errors'] ) ) { + $query = (object) array( + 'posts' => array(), + 'found_posts' => 0, + 'max_num_pages' => 0, + ); + } else { + $query = new WP_Query( $args ); + } + + if ( isset( $query_vars['return'] ) && 'objects' === $query_vars['return'] && ! empty( $query->posts ) ) { + // Prime caches before grabbing objects. + update_post_caches( $query->posts, array( 'product', 'product_variation' ) ); + } + + $products = ( isset( $query_vars['return'] ) && 'ids' === $query_vars['return'] ) ? $query->posts : array_filter( array_map( 'wc_get_product', $query->posts ) ); + + if ( isset( $query_vars['paginate'] ) && $query_vars['paginate'] ) { + return (object) array( + 'products' => $products, + 'total' => $query->found_posts, + 'max_num_pages' => $query->max_num_pages, + ); + } + + return $products; + } + + /** + * Get data to save to a lookup table. + * + * @since 3.6.0 + * @param int $id ID of object to update. + * @param string $table Lookup table name. + * @return array + */ + protected function get_data_for_lookup_table( $id, $table ) { + if ( 'wc_product_meta_lookup' === $table ) { + $price_meta = (array) get_post_meta( $id, '_price', false ); + $manage_stock = get_post_meta( $id, '_manage_stock', true ); + $stock = 'yes' === $manage_stock ? wc_stock_amount( get_post_meta( $id, '_stock', true ) ) : null; + $price = wc_format_decimal( get_post_meta( $id, '_price', true ) ); + $sale_price = wc_format_decimal( get_post_meta( $id, '_sale_price', true ) ); + return array( + 'product_id' => absint( $id ), + 'sku' => get_post_meta( $id, '_sku', true ), + 'virtual' => 'yes' === get_post_meta( $id, '_virtual', true ) ? 1 : 0, + 'downloadable' => 'yes' === get_post_meta( $id, '_downloadable', true ) ? 1 : 0, + 'min_price' => reset( $price_meta ), + 'max_price' => end( $price_meta ), + 'onsale' => $sale_price && $price === $sale_price ? 1 : 0, + 'stock_quantity' => $stock, + 'stock_status' => get_post_meta( $id, '_stock_status', true ), + 'rating_count' => array_sum( (array) get_post_meta( $id, '_wc_rating_count', true ) ), + 'average_rating' => get_post_meta( $id, '_wc_average_rating', true ), + 'total_sales' => get_post_meta( $id, 'total_sales', true ), + 'tax_status' => get_post_meta( $id, '_tax_status', true ), + 'tax_class' => get_post_meta( $id, '_tax_class', true ), + ); + } + return array(); + } + + /** + * Get primary key name for lookup table. + * + * @since 3.6.0 + * @param string $table Lookup table name. + * @return string + */ + protected function get_primary_key_for_lookup_table( $table ) { + if ( 'wc_product_meta_lookup' === $table ) { + return 'product_id'; + } + return ''; + } + + /** + * Returns query statement for getting current `_stock` of a product. + * + * @internal MAX function below is used to make sure result is a scalar. + * @param int $product_id Product ID. + * @return string|void Query statement. + */ + public function get_query_for_stock( $product_id ) { + global $wpdb; + return $wpdb->prepare( + " + SELECT COALESCE ( MAX( meta_value ), 0 ) FROM $wpdb->postmeta as meta_table + WHERE meta_table.meta_key = '_stock' + AND meta_table.post_id = %d + ", + $product_id + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-grouped-data-store-cpt.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-grouped-data-store-cpt.php new file mode 100644 index 0000000..3f7ea7b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-grouped-data-store-cpt.php @@ -0,0 +1,100 @@ + 'children', + ); + + $props_to_update = $force ? $meta_key_to_props : $this->get_props_to_update( $product, $meta_key_to_props ); + + foreach ( $props_to_update as $meta_key => $prop ) { + $value = $product->{"get_$prop"}( 'edit' ); + $updated = update_post_meta( $product->get_id(), $meta_key, $value ); + if ( $updated ) { + $this->updated_props[] = $prop; + } + } + + parent::update_post_meta( $product, $force ); + } + + /** + * Handle updated meta props after updating meta data. + * + * @since 3.0.0 + * @param WC_Product $product Product object. + */ + protected function handle_updated_props( &$product ) { + if ( in_array( 'children', $this->updated_props, true ) ) { + $this->update_prices_from_children( $product ); + } + parent::handle_updated_props( $product ); + } + + /** + * Sync grouped product prices with children. + * + * @since 3.0.0 + * @param WC_Product|int $product Product object or product ID. + */ + public function sync_price( &$product ) { + $this->update_prices_from_children( $product ); + } + + /** + * Loop over child products and update the grouped product prices. + * + * @param WC_Product $product Product object. + */ + protected function update_prices_from_children( &$product ) { + $child_prices = array(); + foreach ( $product->get_children( 'edit' ) as $child_id ) { + $child = wc_get_product( $child_id ); + if ( $child ) { + $child_prices[] = $child->get_price( 'edit' ); + } + } + $child_prices = array_filter( $child_prices ); + delete_post_meta( $product->get_id(), '_price' ); + delete_post_meta( $product->get_id(), '_sale_price' ); + delete_post_meta( $product->get_id(), '_regular_price' ); + + if ( ! empty( $child_prices ) ) { + add_post_meta( $product->get_id(), '_price', min( $child_prices ) ); + add_post_meta( $product->get_id(), '_price', max( $child_prices ) ); + } + + $this->update_lookup_table( $product->get_id(), 'wc_product_meta_lookup' ); + + /** + * Fire an action for this direct update so it can be detected by other code. + * + * @since 3.6 + * @param int $product_id Product ID that was updated directly. + */ + do_action( 'woocommerce_updated_product_price', $product->get_id() ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php new file mode 100644 index 0000000..eeece0d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php @@ -0,0 +1,701 @@ +get_id(), '_product_attributes', true ); + + if ( ! empty( $meta_attributes ) && is_array( $meta_attributes ) ) { + $attributes = array(); + $force_update = false; + foreach ( $meta_attributes as $meta_attribute_key => $meta_attribute_value ) { + $meta_value = array_merge( + array( + 'name' => '', + 'value' => '', + 'position' => 0, + 'is_visible' => 0, + 'is_variation' => 0, + 'is_taxonomy' => 0, + ), + (array) $meta_attribute_value + ); + + // Maintain data integrity. 4.9 changed sanitization functions - update the values here so variations function correctly. + if ( $meta_value['is_variation'] && strstr( $meta_value['name'], '/' ) && sanitize_title( $meta_value['name'] ) !== $meta_attribute_key ) { + global $wpdb; + + $old_slug = 'attribute_' . $meta_attribute_key; + $new_slug = 'attribute_' . sanitize_title( $meta_value['name'] ); + $old_meta_rows = $wpdb->get_results( $wpdb->prepare( "SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s;", $old_slug ) ); // WPCS: db call ok, cache ok. + + if ( $old_meta_rows ) { + foreach ( $old_meta_rows as $old_meta_row ) { + update_post_meta( $old_meta_row->post_id, $new_slug, $old_meta_row->meta_value ); + } + } + + $force_update = true; + } + + // Check if is a taxonomy attribute. + if ( ! empty( $meta_value['is_taxonomy'] ) ) { + if ( ! taxonomy_exists( $meta_value['name'] ) ) { + continue; + } + $id = wc_attribute_taxonomy_id_by_name( $meta_value['name'] ); + $options = wc_get_object_terms( $product->get_id(), $meta_value['name'], 'term_id' ); + } else { + $id = 0; + $options = wc_get_text_attributes( $meta_value['value'] ); + } + + $attribute = new WC_Product_Attribute(); + $attribute->set_id( $id ); + $attribute->set_name( $meta_value['name'] ); + $attribute->set_options( $options ); + $attribute->set_position( $meta_value['position'] ); + $attribute->set_visible( $meta_value['is_visible'] ); + $attribute->set_variation( $meta_value['is_variation'] ); + $attributes[] = $attribute; + } + $product->set_attributes( $attributes ); + + if ( $force_update ) { + $this->update_attributes( $product, true ); + } + } + } + + /** + * Read product data. + * + * @param WC_Product $product Product object. + * + * @since 3.0.0 + */ + protected function read_product_data( &$product ) { + parent::read_product_data( $product ); + + // Make sure data which does not apply to variables is unset. + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + } + + /** + * Loads variation child IDs. + * + * @param WC_Product $product Product object. + * @param bool $force_read True to bypass the transient. + * + * @return array + */ + public function read_children( &$product, $force_read = false ) { + $children_transient_name = 'wc_product_children_' . $product->get_id(); + $children = get_transient( $children_transient_name ); + + if ( empty( $children ) || ! is_array( $children ) || ! isset( $children['all'] ) || ! isset( $children['visible'] ) || $force_read ) { + $all_args = array( + 'post_parent' => $product->get_id(), + 'post_type' => 'product_variation', + 'orderby' => array( + 'menu_order' => 'ASC', + 'ID' => 'ASC', + ), + 'fields' => 'ids', + 'post_status' => array( 'publish', 'private' ), + 'numberposts' => -1, // phpcs:ignore WordPress.VIP.PostsPerPage.posts_per_page_numberposts + ); + + $visible_only_args = $all_args; + $visible_only_args['post_status'] = 'publish'; + + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) { + $visible_only_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => 'outofstock', + 'operator' => 'NOT IN', + ); + } + $children['all'] = get_posts( apply_filters( 'woocommerce_variable_children_args', $all_args, $product, false ) ); + $children['visible'] = get_posts( apply_filters( 'woocommerce_variable_children_args', $visible_only_args, $product, true ) ); + + set_transient( $children_transient_name, $children, DAY_IN_SECONDS * 30 ); + } + + $children['all'] = wp_parse_id_list( (array) $children['all'] ); + $children['visible'] = wp_parse_id_list( (array) $children['visible'] ); + + return $children; + } + + /** + * Loads an array of attributes used for variations, as well as their possible values. + * + * @param WC_Product $product Product object. + * + * @return array + */ + public function read_variation_attributes( &$product ) { + global $wpdb; + + $variation_attributes = array(); + $attributes = $product->get_attributes(); + $child_ids = $product->get_children(); + $cache_key = WC_Cache_Helper::get_cache_prefix( 'product_' . $product->get_id() ) . 'product_variation_attributes_' . $product->get_id(); + $cache_group = 'products'; + $cached_data = wp_cache_get( $cache_key, $cache_group ); + + if ( false !== $cached_data ) { + return $cached_data; + } + + if ( ! empty( $attributes ) ) { + foreach ( $attributes as $attribute ) { + if ( empty( $attribute['is_variation'] ) ) { + continue; + } + + // Get possible values for this attribute, for only visible variations. + if ( ! empty( $child_ids ) ) { + $format = array_fill( 0, count( $child_ids ), '%d' ); + $query_in = '(' . implode( ',', $format ) . ')'; + $query_args = array( 'attribute_name' => wc_variation_attribute_name( $attribute['name'] ) ) + $child_ids; + $values = array_unique( + $wpdb->get_col( + $wpdb->prepare( + "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s AND post_id IN {$query_in}", // @codingStandardsIgnoreLine. + $query_args + ) + ) + ); + } else { + $values = array(); + } + + // Empty value indicates that all options for given attribute are available. + if ( in_array( null, $values, true ) || in_array( '', $values, true ) || empty( $values ) ) { + $values = $attribute['is_taxonomy'] ? wc_get_object_terms( $product->get_id(), $attribute['name'], 'slug' ) : wc_get_text_attributes( $attribute['value'] ); + // Get custom attributes (non taxonomy) as defined. + } elseif ( ! $attribute['is_taxonomy'] ) { + $text_attributes = wc_get_text_attributes( $attribute['value'] ); + $assigned_text_attributes = $values; + $values = array(); + + // Pre 2.4 handling where 'slugs' were saved instead of the full text attribute. + if ( version_compare( get_post_meta( $product->get_id(), '_product_version', true ), '2.4.0', '<' ) ) { + $assigned_text_attributes = array_map( 'sanitize_title', $assigned_text_attributes ); + foreach ( $text_attributes as $text_attribute ) { + if ( in_array( sanitize_title( $text_attribute ), $assigned_text_attributes, true ) ) { + $values[] = $text_attribute; + } + } + } else { + foreach ( $text_attributes as $text_attribute ) { + if ( in_array( $text_attribute, $assigned_text_attributes, true ) ) { + $values[] = $text_attribute; + } + } + } + } + $variation_attributes[ $attribute['name'] ] = array_unique( $values ); + } + } + + wp_cache_set( $cache_key, $variation_attributes, $cache_group ); + + return $variation_attributes; + } + + /** + * Get an array of all sale and regular prices from all variations. This is used for example when displaying the price range at variable product level or seeing if the variable product is on sale. + * + * Can be filtered by plugins which modify costs, but otherwise will include the raw meta costs unlike get_price() which runs costs through the woocommerce_get_price filter. + * This is to ensure modified prices are not cached, unless intended. + * + * @param WC_Product $product Product object. + * @param bool $for_display If true, prices will be adapted for display based on the `woocommerce_tax_display_shop` setting (including or excluding taxes). + * + * @return array of prices + * @since 3.0.0 + */ + public function read_price_data( &$product, $for_display = false ) { + + /** + * Transient name for storing prices for this product (note: Max transient length is 45) + * + * @since 2.5.0 a single transient is used per product for all prices, rather than many transients per product. + */ + $transient_name = 'wc_var_prices_' . $product->get_id(); + $transient_version = WC_Cache_Helper::get_transient_version( 'product' ); + $price_hash = $this->get_price_hash( $product, $for_display ); + + // Check if prices array is stale. + if ( ! isset( $this->prices_array['version'] ) || $this->prices_array['version'] !== $transient_version ) { + $this->prices_array = array( + 'version' => $transient_version, + ); + } + + /** + * $this->prices_array is an array of values which may have been modified from what is stored in transients - this may not match $transient_cached_prices_array. + * If the value has already been generated, we don't need to grab the values again so just return them. They are already filtered. + */ + if ( empty( $this->prices_array[ $price_hash ] ) ) { + $transient_cached_prices_array = array_filter( (array) json_decode( strval( get_transient( $transient_name ) ), true ) ); + + // If the product version has changed since the transient was last saved, reset the transient cache. + if ( ! isset( $transient_cached_prices_array['version'] ) || $transient_version !== $transient_cached_prices_array['version'] ) { + $transient_cached_prices_array = array( + 'version' => $transient_version, + ); + } + + // If the prices are not stored for this hash, generate them and add to the transient. + if ( empty( $transient_cached_prices_array[ $price_hash ] ) ) { + $prices_array = array( + 'price' => array(), + 'regular_price' => array(), + 'sale_price' => array(), + ); + + $variation_ids = $product->get_visible_children(); + + if ( is_callable( '_prime_post_caches' ) ) { + _prime_post_caches( $variation_ids ); + } + + foreach ( $variation_ids as $variation_id ) { + $variation = wc_get_product( $variation_id ); + + if ( $variation ) { + $price = apply_filters( 'woocommerce_variation_prices_price', $variation->get_price( 'edit' ), $variation, $product ); + $regular_price = apply_filters( 'woocommerce_variation_prices_regular_price', $variation->get_regular_price( 'edit' ), $variation, $product ); + $sale_price = apply_filters( 'woocommerce_variation_prices_sale_price', $variation->get_sale_price( 'edit' ), $variation, $product ); + + // Skip empty prices. + if ( '' === $price ) { + continue; + } + + // If sale price does not equal price, the product is not yet on sale. + if ( $sale_price === $regular_price || $sale_price !== $price ) { + $sale_price = $regular_price; + } + + // If we are getting prices for display, we need to account for taxes. + if ( $for_display ) { + if ( 'incl' === get_option( 'woocommerce_tax_display_shop' ) ) { + $price = '' === $price ? '' : wc_get_price_including_tax( + $variation, + array( + 'qty' => 1, + 'price' => $price, + ) + ); + $regular_price = '' === $regular_price ? '' : wc_get_price_including_tax( + $variation, + array( + 'qty' => 1, + 'price' => $regular_price, + ) + ); + $sale_price = '' === $sale_price ? '' : wc_get_price_including_tax( + $variation, + array( + 'qty' => 1, + 'price' => $sale_price, + ) + ); + } else { + $price = '' === $price ? '' : wc_get_price_excluding_tax( + $variation, + array( + 'qty' => 1, + 'price' => $price, + ) + ); + $regular_price = '' === $regular_price ? '' : wc_get_price_excluding_tax( + $variation, + array( + 'qty' => 1, + 'price' => $regular_price, + ) + ); + $sale_price = '' === $sale_price ? '' : wc_get_price_excluding_tax( + $variation, + array( + 'qty' => 1, + 'price' => $sale_price, + ) + ); + } + } + + $prices_array['price'][ $variation_id ] = wc_format_decimal( $price, wc_get_price_decimals() ); + $prices_array['regular_price'][ $variation_id ] = wc_format_decimal( $regular_price, wc_get_price_decimals() ); + $prices_array['sale_price'][ $variation_id ] = wc_format_decimal( $sale_price, wc_get_price_decimals() ); + + $prices_array = apply_filters( 'woocommerce_variation_prices_array', $prices_array, $variation, $for_display ); + } + } + + // Add all pricing data to the transient array. + foreach ( $prices_array as $key => $values ) { + $transient_cached_prices_array[ $price_hash ][ $key ] = $values; + } + + set_transient( $transient_name, wp_json_encode( $transient_cached_prices_array ), DAY_IN_SECONDS * 30 ); + } + + /** + * Give plugins one last chance to filter the variation prices array which has been generated and store locally to the class. + * This value may differ from the transient cache. It is filtered once before storing locally. + */ + $this->prices_array[ $price_hash ] = apply_filters( 'woocommerce_variation_prices', $transient_cached_prices_array[ $price_hash ], $product, $for_display ); + } + return $this->prices_array[ $price_hash ]; + } + + /** + * Create unique cache key based on the tax location (affects displayed/cached prices), product version and active price filters. + * DEVELOPERS should filter this hash if offering conditional pricing to keep it unique. + * + * @param WC_Product $product Product object. + * @param bool $for_display If taxes should be calculated or not. + * + * @since 3.0.0 + * @return string + */ + protected function get_price_hash( &$product, $for_display = false ) { + global $wp_filter; + + $price_hash = $for_display && wc_tax_enabled() ? array( get_option( 'woocommerce_tax_display_shop', 'excl' ), WC_Tax::get_rates() ) : array( false ); + $filter_names = array( 'woocommerce_variation_prices_price', 'woocommerce_variation_prices_regular_price', 'woocommerce_variation_prices_sale_price' ); + + foreach ( $filter_names as $filter_name ) { + if ( ! empty( $wp_filter[ $filter_name ] ) ) { + $price_hash[ $filter_name ] = array(); + + foreach ( $wp_filter[ $filter_name ] as $priority => $callbacks ) { + $price_hash[ $filter_name ][] = array_values( wp_list_pluck( $callbacks, 'function' ) ); + } + } + } + + return md5( wp_json_encode( apply_filters( 'woocommerce_get_variation_prices_hash', $price_hash, $product, $for_display ) ) ); + } + + /** + * Does a child have a weight set? + * + * @param WC_Product $product Product object. + * + * @since 3.0.0 + * @return boolean + */ + public function child_has_weight( $product ) { + global $wpdb; + $children = $product->get_visible_children(); + if ( ! $children ) { + return false; + } + + $format = array_fill( 0, count( $children ), '%d' ); + $query_in = '(' . implode( ',', $format ) . ')'; + + return null !== $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_weight' AND meta_value > 0 AND post_id IN {$query_in}", $children ) ); // @codingStandardsIgnoreLine. + } + + /** + * Does a child have dimensions set? + * + * @param WC_Product $product Product object. + * + * @since 3.0.0 + * @return boolean + */ + public function child_has_dimensions( $product ) { + global $wpdb; + $children = $product->get_visible_children(); + if ( ! $children ) { + return false; + } + + $format = array_fill( 0, count( $children ), '%d' ); + $query_in = '(' . implode( ',', $format ) . ')'; + + return null !== $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key IN ( '_length', '_width', '_height' ) AND meta_value > 0 AND post_id IN {$query_in}", $children ) ); // @codingStandardsIgnoreLine. + } + + /** + * Is a child in stock? + * + * @param WC_Product $product Product object. + * + * @since 3.0.0 + * @return boolean + */ + public function child_is_in_stock( $product ) { + return $this->child_has_stock_status( $product, 'instock' ); + } + + /** + * Does a child have a stock status? + * + * @param WC_Product $product Product object. + * @param string $status 'instock', 'outofstock', or 'onbackorder'. + * + * @since 3.3.0 + * @return boolean + */ + public function child_has_stock_status( $product, $status ) { + global $wpdb; + + $children = $product->get_children(); + + if ( $children ) { + $format = array_fill( 0, count( $children ), '%d' ); + $query_in = '(' . implode( ',', $format ) . ')'; + $query_args = array( 'stock_status' => $status ) + $children; + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared + if ( get_option( 'woocommerce_product_lookup_table_is_generating' ) ) { + $query = "SELECT COUNT( post_id ) FROM {$wpdb->postmeta} WHERE meta_key = '_stock_status' AND meta_value = %s AND post_id IN {$query_in}"; + } else { + $query = "SELECT COUNT( product_id ) FROM {$wpdb->wc_product_meta_lookup} WHERE stock_status = %s AND product_id IN {$query_in}"; + } + $children_with_status = $wpdb->get_var( + $wpdb->prepare( + $query, + $query_args + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared + } else { + $children_with_status = 0; + } + + return (bool) $children_with_status; + } + + /** + * Syncs all variation names if the parent name is changed. + * + * @param WC_Product $product Product object. + * @param string $previous_name Variation previous name. + * @param string $new_name Variation new name. + * + * @since 3.0.0 + */ + public function sync_variation_names( &$product, $previous_name = '', $new_name = '' ) { + if ( $new_name !== $previous_name ) { + global $wpdb; + + $wpdb->query( + $wpdb->prepare( + "UPDATE {$wpdb->posts} + SET post_title = REPLACE( post_title, %s, %s ) + WHERE post_type = 'product_variation' + AND post_parent = %d", + $previous_name ? $previous_name : 'AUTO-DRAFT', + $new_name, + $product->get_id() + ) + ); + } + } + + /** + * Stock managed at the parent level - update children being managed by this product. + * This sync function syncs downwards (from parent to child) when the variable product is saved. + * + * @param WC_Product $product Product object. + * + * @since 3.0.0 + */ + public function sync_managed_variation_stock_status( &$product ) { + global $wpdb; + + if ( $product->get_manage_stock() ) { + $children = $product->get_children(); + $changed = false; + + if ( $children ) { + $status = $product->get_stock_status(); + $format = array_fill( 0, count( $children ), '%d' ); + $query_in = '(' . implode( ',', $format ) . ')'; + $managed_children = array_unique( $wpdb->get_col( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_manage_stock' AND meta_value != 'yes' AND post_id IN {$query_in}", $children ) ) ); // @codingStandardsIgnoreLine. + foreach ( $managed_children as $managed_child ) { + if ( update_post_meta( $managed_child, '_stock_status', $status ) ) { + $this->update_lookup_table( $managed_child, 'wc_product_meta_lookup' ); + $changed = true; + } + } + } + + if ( $changed ) { + $children = $this->read_children( $product, true ); + $product->set_children( $children['all'] ); + $product->set_visible_children( $children['visible'] ); + } + } + } + + /** + * Sync variable product prices with children. + * + * @param WC_Product $product Product object. + * + * @since 3.0.0 + */ + public function sync_price( &$product ) { + global $wpdb; + + $children = $product->get_visible_children(); + if ( $children ) { + $format = array_fill( 0, count( $children ), '%d' ); + $query_in = '(' . implode( ',', $format ) . ')'; + $prices = array_unique( $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key = '_price' AND post_id IN {$query_in}", $children ) ) ); // @codingStandardsIgnoreLine. + } else { + $prices = array(); + } + + delete_post_meta( $product->get_id(), '_price' ); + delete_post_meta( $product->get_id(), '_sale_price' ); + delete_post_meta( $product->get_id(), '_regular_price' ); + + if ( $prices ) { + sort( $prices, SORT_NUMERIC ); + // To allow sorting and filtering by multiple values, we have no choice but to store child prices in this manner. + foreach ( $prices as $price ) { + if ( is_null( $price ) || '' === $price ) { + continue; + } + add_post_meta( $product->get_id(), '_price', $price, false ); + } + } + + $this->update_lookup_table( $product->get_id(), 'wc_product_meta_lookup' ); + + /** + * Fire an action for this direct update so it can be detected by other code. + * + * @since 3.6 + * @param int $product_id Product ID that was updated directly. + */ + do_action( 'woocommerce_updated_product_price', $product->get_id() ); + } + + /** + * Sync variable product stock status with children. + * Change does not persist unless saved by caller. + * + * @param WC_Product $product Product object. + * + * @since 3.0.0 + */ + public function sync_stock_status( &$product ) { + if ( $product->child_is_in_stock() ) { + $product->set_stock_status( 'instock' ); + } elseif ( $product->child_is_on_backorder() ) { + $product->set_stock_status( 'onbackorder' ); + } else { + $product->set_stock_status( 'outofstock' ); + } + } + + /** + * Delete variations of a product. + * + * @param int $product_id Product ID. + * @param bool $force_delete False to trash. + * + * @since 3.0.0 + */ + public function delete_variations( $product_id, $force_delete = false ) { + if ( ! is_numeric( $product_id ) || 0 >= $product_id ) { + return; + } + + $variation_ids = wp_parse_id_list( + get_posts( + array( + 'post_parent' => $product_id, + 'post_type' => 'product_variation', + 'fields' => 'ids', + 'post_status' => array( 'any', 'trash', 'auto-draft' ), + 'numberposts' => -1, // phpcs:ignore WordPress.VIP.PostsPerPage.posts_per_page_numberposts + ) + ) + ); + + if ( ! empty( $variation_ids ) ) { + foreach ( $variation_ids as $variation_id ) { + if ( $force_delete ) { + do_action( 'woocommerce_before_delete_product_variation', $variation_id ); + wp_delete_post( $variation_id, true ); + do_action( 'woocommerce_delete_product_variation', $variation_id ); + } else { + wp_trash_post( $variation_id ); + do_action( 'woocommerce_trash_product_variation', $variation_id ); + } + } + } + + delete_transient( 'wc_product_children_' . $product_id ); + } + + /** + * Untrash variations. + * + * @param int $product_id Product ID. + */ + public function untrash_variations( $product_id ) { + $variation_ids = wp_parse_id_list( + get_posts( + array( + 'post_parent' => $product_id, + 'post_type' => 'product_variation', + 'fields' => 'ids', + 'post_status' => 'trash', + 'numberposts' => -1, // phpcs:ignore WordPress.VIP.PostsPerPage.posts_per_page_numberposts + ) + ) + ); + + if ( ! empty( $variation_ids ) ) { + foreach ( $variation_ids as $variation_id ) { + wp_untrash_post( $variation_id ); + } + } + + delete_transient( 'wc_product_children_' . $product_id ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-variation-data-store-cpt.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-variation-data-store-cpt.php new file mode 100644 index 0000000..534ba38 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-product-variation-data-store-cpt.php @@ -0,0 +1,547 @@ +meta_key, $this->internal_meta_keys, true ) && 0 !== stripos( $meta->meta_key, 'attribute_' ) && 0 !== stripos( $meta->meta_key, 'wp_' ); + } + + /* + |-------------------------------------------------------------------------- + | CRUD Methods + |-------------------------------------------------------------------------- + */ + + /** + * Reads a product from the database and sets its data to the class. + * + * @since 3.0.0 + * @param WC_Product_Variation $product Product object. + * @throws WC_Data_Exception If WC_Product::set_tax_status() is called with an invalid tax status (via read_product_data), or when passing an invalid ID. + */ + public function read( &$product ) { + $product->set_defaults(); + + if ( ! $product->get_id() ) { + return; + } + + $post_object = get_post( $product->get_id() ); + + if ( ! $post_object ) { + return; + } + + if ( 'product_variation' !== $post_object->post_type ) { + throw new WC_Data_Exception( 'variation_invalid_id', __( 'Invalid product type: passed ID does not correspond to a product variation.', 'woocommerce' ) ); + } + + $product->set_props( + array( + 'name' => $post_object->post_title, + 'slug' => $post_object->post_name, + 'date_created' => $this->string_to_timestamp( $post_object->post_date_gmt ), + 'date_modified' => $this->string_to_timestamp( $post_object->post_modified_gmt ), + 'status' => $post_object->post_status, + 'menu_order' => $post_object->menu_order, + 'reviews_allowed' => 'open' === $post_object->comment_status, + 'parent_id' => $post_object->post_parent, + 'attribute_summary' => $post_object->post_excerpt, + ) + ); + + // The post parent is not a valid variable product so we should prevent this. + if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) { + $product->set_parent_id( 0 ); + } + + $this->read_downloads( $product ); + $this->read_product_data( $product ); + $this->read_extra_data( $product ); + $product->set_attributes( wc_get_product_variation_attributes( $product->get_id() ) ); + + $updates = array(); + /** + * If a variation title is not in sync with the parent e.g. saved prior to 3.0, or if the parent title has changed, detect here and update. + */ + $new_title = $this->generate_product_title( $product ); + + if ( $post_object->post_title !== $new_title ) { + $product->set_name( $new_title ); + $updates = array_merge( $updates, array( 'post_title' => $new_title ) ); + } + + /** + * If the attribute summary is not in sync, update here. Used when searching for variations by attribute values. + * This is meant to also cover the case when global attribute name or value is updated, then the attribute summary is updated + * for respective products when they're read. + */ + $new_attribute_summary = $this->generate_attribute_summary( $product ); + + if ( $new_attribute_summary !== $post_object->post_excerpt ) { + $product->set_attribute_summary( $new_attribute_summary ); + $updates = array_merge( $updates, array( 'post_excerpt' => $new_attribute_summary ) ); + } + + if ( ! empty( $updates ) ) { + $GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $updates, array( 'ID' => $product->get_id() ) ); + clean_post_cache( $product->get_id() ); + } + + // Set object_read true once all data is read. + $product->set_object_read( true ); + } + + /** + * Create a new product. + * + * @since 3.0.0 + * @param WC_Product_Variation $product Product object. + */ + public function create( &$product ) { + if ( ! $product->get_date_created() ) { + $product->set_date_created( time() ); + } + + $new_title = $this->generate_product_title( $product ); + + if ( $product->get_name( 'edit' ) !== $new_title ) { + $product->set_name( $new_title ); + } + + $attribute_summary = $this->generate_attribute_summary( $product ); + $product->set_attribute_summary( $attribute_summary ); + + // The post parent is not a valid variable product so we should prevent this. + if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) { + $product->set_parent_id( 0 ); + } + + $id = wp_insert_post( + apply_filters( + 'woocommerce_new_product_variation_data', + array( + 'post_type' => 'product_variation', + 'post_status' => $product->get_status() ? $product->get_status() : 'publish', + 'post_author' => get_current_user_id(), + 'post_title' => $product->get_name( 'edit' ), + 'post_excerpt' => $product->get_attribute_summary( 'edit' ), + 'post_content' => '', + 'post_parent' => $product->get_parent_id(), + 'comment_status' => 'closed', + 'ping_status' => 'closed', + 'menu_order' => $product->get_menu_order(), + 'post_date' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getOffsetTimestamp() ), + 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getTimestamp() ), + 'post_name' => $product->get_slug( 'edit' ), + ) + ), + true + ); + + if ( $id && ! is_wp_error( $id ) ) { + $product->set_id( $id ); + + $this->update_post_meta( $product, true ); + $this->update_terms( $product, true ); + $this->update_visibility( $product, true ); + $this->update_attributes( $product, true ); + $this->handle_updated_props( $product ); + + $product->save_meta_data(); + $product->apply_changes(); + + $this->update_version_and_type( $product ); + $this->update_guid( $product ); + + $this->clear_caches( $product ); + + do_action( 'woocommerce_new_product_variation', $id, $product ); + } + } + + /** + * Updates an existing product. + * + * @since 3.0.0 + * @param WC_Product_Variation $product Product object. + */ + public function update( &$product ) { + $product->save_meta_data(); + + if ( ! $product->get_date_created() ) { + $product->set_date_created( time() ); + } + + $new_title = $this->generate_product_title( $product ); + + if ( $product->get_name( 'edit' ) !== $new_title ) { + $product->set_name( $new_title ); + } + + // The post parent is not a valid variable product so we should prevent this. + if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) { + $product->set_parent_id( 0 ); + } + + $changes = $product->get_changes(); + + if ( array_intersect( array( 'attributes' ), array_keys( $changes ) ) ) { + $product->set_attribute_summary( $this->generate_attribute_summary( $product ) ); + } + + // Only update the post when the post data changes. + if ( array_intersect( array( 'name', 'parent_id', 'status', 'menu_order', 'date_created', 'date_modified', 'attributes' ), array_keys( $changes ) ) ) { + $post_data = array( + 'post_title' => $product->get_name( 'edit' ), + 'post_excerpt' => $product->get_attribute_summary( 'edit' ), + 'post_parent' => $product->get_parent_id( 'edit' ), + 'comment_status' => 'closed', + 'post_status' => $product->get_status( 'edit' ) ? $product->get_status( 'edit' ) : 'publish', + 'menu_order' => $product->get_menu_order( 'edit' ), + 'post_date' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getOffsetTimestamp() ), + 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getTimestamp() ), + 'post_modified' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getOffsetTimestamp() ) : current_time( 'mysql' ), + 'post_modified_gmt' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getTimestamp() ) : current_time( 'mysql', 1 ), + 'post_type' => 'product_variation', + 'post_name' => $product->get_slug( 'edit' ), + ); + + /** + * When updating this object, to prevent infinite loops, use $wpdb + * to update data, since wp_update_post spawns more calls to the + * save_post action. + * + * This ensures hooks are fired by either WP itself (admin screen save), + * or an update purely from CRUD. + */ + if ( doing_action( 'save_post' ) ) { + $GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $post_data, array( 'ID' => $product->get_id() ) ); + clean_post_cache( $product->get_id() ); + } else { + wp_update_post( array_merge( array( 'ID' => $product->get_id() ), $post_data ) ); + } + $product->read_meta_data( true ); // Refresh internal meta data, in case things were hooked into `save_post` or another WP hook. + + } else { // Only update post modified time to record this save event. + $GLOBALS['wpdb']->update( + $GLOBALS['wpdb']->posts, + array( + 'post_modified' => current_time( 'mysql' ), + 'post_modified_gmt' => current_time( 'mysql', 1 ), + ), + array( + 'ID' => $product->get_id(), + ) + ); + clean_post_cache( $product->get_id() ); + } + + $this->update_post_meta( $product ); + $this->update_terms( $product ); + $this->update_visibility( $product, true ); + $this->update_attributes( $product ); + $this->handle_updated_props( $product ); + + $product->apply_changes(); + + $this->update_version_and_type( $product ); + + $this->clear_caches( $product ); + + do_action( 'woocommerce_update_product_variation', $product->get_id(), $product ); + } + + /* + |-------------------------------------------------------------------------- + | Additional Methods + |-------------------------------------------------------------------------- + */ + + /** + * Generates a title with attribute information for a variation. + * Products will get a title of the form "Name - Value, Value" or just "Name". + * + * @since 3.0.0 + * @param WC_Product $product Product object. + * @return string + */ + protected function generate_product_title( $product ) { + $attributes = (array) $product->get_attributes(); + + // Do not include attributes if the product has 3+ attributes. + $should_include_attributes = count( $attributes ) < 3; + + // Do not include attributes if an attribute name has 2+ words and the + // product has multiple attributes. + if ( $should_include_attributes && 1 < count( $attributes ) ) { + foreach ( $attributes as $name => $value ) { + if ( false !== strpos( $name, '-' ) ) { + $should_include_attributes = false; + break; + } + } + } + + $should_include_attributes = apply_filters( 'woocommerce_product_variation_title_include_attributes', $should_include_attributes, $product ); + $separator = apply_filters( 'woocommerce_product_variation_title_attributes_separator', ' - ', $product ); + $title_base = get_post_field( 'post_title', $product->get_parent_id() ); + $title_suffix = $should_include_attributes ? wc_get_formatted_variation( $product, true, false ) : ''; + + return apply_filters( 'woocommerce_product_variation_title', $title_suffix ? $title_base . $separator . $title_suffix : $title_base, $product, $title_base, $title_suffix ); + } + + /** + * Generates attribute summary for the variation. + * + * Attribute summary contains comma-delimited 'attribute_name: attribute_value' pairs for all attributes. + * + * @since 3.6.0 + * @param WC_Product_Variation $product Product variation to generate the attribute summary for. + * + * @return string + */ + protected function generate_attribute_summary( $product ) { + return wc_get_formatted_variation( $product, true, true ); + } + + /** + * Make sure we store the product version (to track data changes). + * + * @param WC_Product $product Product object. + * @since 3.0.0 + */ + protected function update_version_and_type( &$product ) { + wp_set_object_terms( $product->get_id(), '', 'product_type' ); + update_post_meta( $product->get_id(), '_product_version', Constants::get_constant( 'WC_VERSION' ) ); + } + + /** + * Read post data. + * + * @since 3.0.0 + * @param WC_Product_Variation $product Product object. + * @throws WC_Data_Exception If WC_Product::set_tax_status() is called with an invalid tax status. + */ + protected function read_product_data( &$product ) { + $id = $product->get_id(); + + $product->set_props( + array( + 'description' => get_post_meta( $id, '_variation_description', true ), + 'regular_price' => get_post_meta( $id, '_regular_price', true ), + 'sale_price' => get_post_meta( $id, '_sale_price', true ), + 'date_on_sale_from' => get_post_meta( $id, '_sale_price_dates_from', true ), + 'date_on_sale_to' => get_post_meta( $id, '_sale_price_dates_to', true ), + 'manage_stock' => get_post_meta( $id, '_manage_stock', true ), + 'stock_status' => get_post_meta( $id, '_stock_status', true ), + 'shipping_class_id' => current( $this->get_term_ids( $id, 'product_shipping_class' ) ), + 'virtual' => get_post_meta( $id, '_virtual', true ), + 'downloadable' => get_post_meta( $id, '_downloadable', true ), + 'gallery_image_ids' => array_filter( explode( ',', get_post_meta( $id, '_product_image_gallery', true ) ) ), + 'download_limit' => get_post_meta( $id, '_download_limit', true ), + 'download_expiry' => get_post_meta( $id, '_download_expiry', true ), + 'image_id' => get_post_thumbnail_id( $id ), + 'backorders' => get_post_meta( $id, '_backorders', true ), + 'sku' => get_post_meta( $id, '_sku', true ), + 'stock_quantity' => get_post_meta( $id, '_stock', true ), + 'weight' => get_post_meta( $id, '_weight', true ), + 'length' => get_post_meta( $id, '_length', true ), + 'width' => get_post_meta( $id, '_width', true ), + 'height' => get_post_meta( $id, '_height', true ), + 'tax_class' => ! metadata_exists( 'post', $id, '_tax_class' ) ? 'parent' : get_post_meta( $id, '_tax_class', true ), + ) + ); + + if ( $product->is_on_sale( 'edit' ) ) { + $product->set_price( $product->get_sale_price( 'edit' ) ); + } else { + $product->set_price( $product->get_regular_price( 'edit' ) ); + } + + $parent_object = get_post( $product->get_parent_id() ); + $terms = get_the_terms( $product->get_parent_id(), 'product_visibility' ); + $term_names = is_array( $terms ) ? wp_list_pluck( $terms, 'name' ) : array(); + $exclude_search = in_array( 'exclude-from-search', $term_names, true ); + $exclude_catalog = in_array( 'exclude-from-catalog', $term_names, true ); + + if ( $exclude_search && $exclude_catalog ) { + $catalog_visibility = 'hidden'; + } elseif ( $exclude_search ) { + $catalog_visibility = 'catalog'; + } elseif ( $exclude_catalog ) { + $catalog_visibility = 'search'; + } else { + $catalog_visibility = 'visible'; + } + + $product->set_parent_data( + array( + 'title' => $parent_object ? $parent_object->post_title : '', + 'status' => $parent_object ? $parent_object->post_status : '', + 'sku' => get_post_meta( $product->get_parent_id(), '_sku', true ), + 'manage_stock' => get_post_meta( $product->get_parent_id(), '_manage_stock', true ), + 'backorders' => get_post_meta( $product->get_parent_id(), '_backorders', true ), + 'low_stock_amount' => get_post_meta( $product->get_parent_id(), '_low_stock_amount', true ), + 'stock_quantity' => wc_stock_amount( get_post_meta( $product->get_parent_id(), '_stock', true ) ), + 'weight' => get_post_meta( $product->get_parent_id(), '_weight', true ), + 'length' => get_post_meta( $product->get_parent_id(), '_length', true ), + 'width' => get_post_meta( $product->get_parent_id(), '_width', true ), + 'height' => get_post_meta( $product->get_parent_id(), '_height', true ), + 'tax_class' => get_post_meta( $product->get_parent_id(), '_tax_class', true ), + 'shipping_class_id' => absint( current( $this->get_term_ids( $product->get_parent_id(), 'product_shipping_class' ) ) ), + 'image_id' => get_post_thumbnail_id( $product->get_parent_id() ), + 'purchase_note' => get_post_meta( $product->get_parent_id(), '_purchase_note', true ), + 'catalog_visibility' => $catalog_visibility, + ) + ); + + // Pull data from the parent when there is no user-facing way to set props. + $product->set_sold_individually( get_post_meta( $product->get_parent_id(), '_sold_individually', true ) ); + $product->set_tax_status( get_post_meta( $product->get_parent_id(), '_tax_status', true ) ); + $product->set_cross_sell_ids( get_post_meta( $product->get_parent_id(), '_crosssell_ids', true ) ); + } + + /** + * For all stored terms in all taxonomies, save them to the DB. + * + * @since 3.0.0 + * @param WC_Product $product Product object. + * @param bool $force Force update. Used during create. + */ + protected function update_terms( &$product, $force = false ) { + $changes = $product->get_changes(); + + if ( $force || array_key_exists( 'shipping_class_id', $changes ) ) { + wp_set_post_terms( $product->get_id(), array( $product->get_shipping_class_id( 'edit' ) ), 'product_shipping_class', false ); + } + } + + /** + * Update visibility terms based on props. + * + * @since 3.0.0 + * + * @param WC_Product $product Product object. + * @param bool $force Force update. Used during create. + */ + protected function update_visibility( &$product, $force = false ) { + $changes = $product->get_changes(); + + if ( $force || array_intersect( array( 'stock_status' ), array_keys( $changes ) ) ) { + $terms = array(); + + if ( 'outofstock' === $product->get_stock_status() ) { + $terms[] = 'outofstock'; + } + + wp_set_post_terms( $product->get_id(), $terms, 'product_visibility', false ); + } + } + + /** + * Update attribute meta values. + * + * @since 3.0.0 + * @param WC_Product $product Product object. + * @param bool $force Force update. Used during create. + */ + protected function update_attributes( &$product, $force = false ) { + $changes = $product->get_changes(); + + if ( $force || array_key_exists( 'attributes', $changes ) ) { + global $wpdb; + + $product_id = $product->get_id(); + $attributes = $product->get_attributes(); + $updated_attribute_keys = array(); + foreach ( $attributes as $key => $value ) { + update_post_meta( $product_id, 'attribute_' . $key, wp_slash( $value ) ); + $updated_attribute_keys[] = 'attribute_' . $key; + } + + // Remove old taxonomies attributes so data is kept up to date - first get attribute key names. + $delete_attribute_keys = $wpdb->get_col( + $wpdb->prepare( + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration + "SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE %s AND meta_key NOT IN ( '" . implode( "','", array_map( 'esc_sql', $updated_attribute_keys ) ) . "' ) AND post_id = %d", + $wpdb->esc_like( 'attribute_' ) . '%', + $product_id + ) + ); + + foreach ( $delete_attribute_keys as $key ) { + delete_post_meta( $product_id, $key ); + } + } + } + + /** + * Helper method that updates all the post meta for a product based on it's settings in the WC_Product class. + * + * @since 3.0.0 + * @param WC_Product $product Product object. + * @param bool $force Force update. Used during create. + */ + public function update_post_meta( &$product, $force = false ) { + $meta_key_to_props = array( + '_variation_description' => 'description', + ); + + $props_to_update = $force ? $meta_key_to_props : $this->get_props_to_update( $product, $meta_key_to_props ); + + foreach ( $props_to_update as $meta_key => $prop ) { + $value = $product->{"get_$prop"}( 'edit' ); + $updated = update_post_meta( $product->get_id(), $meta_key, $value ); + if ( $updated ) { + $this->updated_props[] = $prop; + } + } + + parent::update_post_meta( $product, $force ); + } + + /** + * Update product variation guid. + * + * @param WC_Product_Variation $product Product variation object. + * + * @since 3.6.0 + */ + protected function update_guid( $product ) { + global $wpdb; + + $guid = home_url( + add_query_arg( + array( + 'post_type' => 'product_variation', + 'p' => $product->get_id(), + ), + '' + ) + ); + $wpdb->update( $wpdb->posts, array( 'guid' => $guid ), array( 'ID' => $product->get_id() ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-shipping-zone-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-shipping-zone-data-store.php new file mode 100644 index 0000000..453ec87 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-shipping-zone-data-store.php @@ -0,0 +1,365 @@ +insert( + $wpdb->prefix . 'woocommerce_shipping_zones', + array( + 'zone_name' => $zone->get_zone_name(), + 'zone_order' => $zone->get_zone_order(), + ) + ); + $zone->set_id( $wpdb->insert_id ); + $zone->save_meta_data(); + $this->save_locations( $zone ); + $zone->apply_changes(); + WC_Cache_Helper::invalidate_cache_group( 'shipping_zones' ); + WC_Cache_Helper::get_transient_version( 'shipping', true ); + } + + /** + * Update zone in the database. + * + * @since 3.0.0 + * @param WC_Shipping_Zone $zone Shipping zone object. + */ + public function update( &$zone ) { + global $wpdb; + if ( $zone->get_id() ) { + $wpdb->update( + $wpdb->prefix . 'woocommerce_shipping_zones', + array( + 'zone_name' => $zone->get_zone_name(), + 'zone_order' => $zone->get_zone_order(), + ), + array( 'zone_id' => $zone->get_id() ) + ); + } + $zone->save_meta_data(); + $this->save_locations( $zone ); + $zone->apply_changes(); + WC_Cache_Helper::invalidate_cache_group( 'shipping_zones' ); + WC_Cache_Helper::get_transient_version( 'shipping', true ); + } + + /** + * Method to read a shipping zone from the database. + * + * @since 3.0.0 + * @param WC_Shipping_Zone $zone Shipping zone object. + * @throws Exception If invalid data store. + */ + public function read( &$zone ) { + global $wpdb; + + $zone_data = false; + + if ( 0 !== $zone->get_id() || '0' !== $zone->get_id() ) { + $zone_data = $wpdb->get_row( + $wpdb->prepare( + "SELECT zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones WHERE zone_id = %d LIMIT 1", + $zone->get_id() + ) + ); + } + + if ( 0 === $zone->get_id() || '0' === $zone->get_id() ) { + $this->read_zone_locations( $zone ); + $zone->set_zone_name( __( 'Locations not covered by your other zones', 'woocommerce' ) ); + $zone->read_meta_data(); + $zone->set_object_read( true ); + do_action( 'woocommerce_shipping_zone_loaded', $zone ); + } elseif ( $zone_data ) { + $zone->set_zone_name( $zone_data->zone_name ); + $zone->set_zone_order( $zone_data->zone_order ); + $this->read_zone_locations( $zone ); + $zone->read_meta_data(); + $zone->set_object_read( true ); + do_action( 'woocommerce_shipping_zone_loaded', $zone ); + } else { + throw new Exception( __( 'Invalid data store.', 'woocommerce' ) ); + } + } + + /** + * Deletes a shipping zone from the database. + * + * @since 3.0.0 + * @param WC_Shipping_Zone $zone Shipping zone object. + * @param array $args Array of args to pass to the delete method. + * @return void + */ + public function delete( &$zone, $args = array() ) { + $zone_id = $zone->get_id(); + + if ( $zone_id ) { + global $wpdb; + + // Delete methods and their settings. + $methods = $this->get_methods( $zone_id, false ); + + if ( $methods ) { + foreach ( $methods as $method ) { + $this->delete_method( $method->instance_id ); + } + } + + // Delete zone. + $wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zone_locations', array( 'zone_id' => $zone_id ) ); + $wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zones', array( 'zone_id' => $zone_id ) ); + + $zone->set_id( null ); + + WC_Cache_Helper::invalidate_cache_group( 'shipping_zones' ); + WC_Cache_Helper::get_transient_version( 'shipping', true ); + + do_action( 'woocommerce_delete_shipping_zone', $zone_id ); + } + } + + /** + * Get a list of shipping methods for a specific zone. + * + * @since 3.0.0 + * @param int $zone_id Zone ID. + * @param bool $enabled_only True to request enabled methods only. + * @return array Array of objects containing method_id, method_order, instance_id, is_enabled + */ + public function get_methods( $zone_id, $enabled_only ) { + global $wpdb; + + if ( $enabled_only ) { + $raw_methods_sql = "SELECT method_id, method_order, instance_id, is_enabled FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE zone_id = %d AND is_enabled = 1"; + } else { + $raw_methods_sql = "SELECT method_id, method_order, instance_id, is_enabled FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE zone_id = %d"; + } + + return $wpdb->get_results( $wpdb->prepare( $raw_methods_sql, $zone_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + } + + /** + * Get count of methods for a zone. + * + * @since 3.0.0 + * @param int $zone_id Zone ID. + * @return int Method Count + */ + public function get_method_count( $zone_id ) { + global $wpdb; + return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE zone_id = %d", $zone_id ) ); + } + + /** + * Add a shipping method to a zone. + * + * @since 3.0.0 + * @param int $zone_id Zone ID. + * @param string $type Method Type/ID. + * @param int $order Method Order. + * @return int Instance ID + */ + public function add_method( $zone_id, $type, $order ) { + global $wpdb; + $wpdb->insert( + $wpdb->prefix . 'woocommerce_shipping_zone_methods', + array( + 'method_id' => $type, + 'zone_id' => $zone_id, + 'method_order' => $order, + ), + array( + '%s', + '%d', + '%d', + ) + ); + return $wpdb->insert_id; + } + + /** + * Delete a method instance. + * + * @since 3.0.0 + * @param int $instance_id Instance ID. + */ + public function delete_method( $instance_id ) { + global $wpdb; + + $method = $this->get_method( $instance_id ); + + if ( ! $method ) { + return; + } + + delete_option( 'woocommerce_' . $method->method_id . '_' . $instance_id . '_settings' ); + + $wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zone_methods', array( 'instance_id' => $instance_id ) ); + + do_action( 'woocommerce_delete_shipping_zone_method', $instance_id ); + } + + /** + * Get a shipping zone method instance. + * + * @since 3.0.0 + * @param int $instance_id Instance ID. + * @return object + */ + public function get_method( $instance_id ) { + global $wpdb; + return $wpdb->get_row( $wpdb->prepare( "SELECT zone_id, method_id, instance_id, method_order, is_enabled FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE instance_id = %d LIMIT 1;", $instance_id ) ); + } + + /** + * Find a matching zone ID for a given package. + * + * @since 3.0.0 + * @param object $package Package information. + * @return int + */ + public function get_zone_id_from_package( $package ) { + global $wpdb; + + $country = strtoupper( wc_clean( $package['destination']['country'] ) ); + $state = strtoupper( wc_clean( $package['destination']['state'] ) ); + $continent = strtoupper( wc_clean( WC()->countries->get_continent_code_for_country( $country ) ) ); + $postcode = wc_normalize_postcode( wc_clean( $package['destination']['postcode'] ) ); + + // Work out criteria for our zone search. + $criteria = array(); + $criteria[] = $wpdb->prepare( "( ( location_type = 'country' AND location_code = %s )", $country ); + $criteria[] = $wpdb->prepare( "OR ( location_type = 'state' AND location_code = %s )", $country . ':' . $state ); + $criteria[] = $wpdb->prepare( "OR ( location_type = 'continent' AND location_code = %s )", $continent ); + $criteria[] = 'OR ( location_type IS NULL ) )'; + + // Postcode range and wildcard matching. + $postcode_locations = $wpdb->get_results( "SELECT zone_id, location_code FROM {$wpdb->prefix}woocommerce_shipping_zone_locations WHERE location_type = 'postcode';" ); + + if ( $postcode_locations ) { + $zone_ids_with_postcode_rules = array_map( 'absint', wp_list_pluck( $postcode_locations, 'zone_id' ) ); + $matches = wc_postcode_location_matcher( $postcode, $postcode_locations, 'zone_id', 'location_code', $country ); + $do_not_match = array_unique( array_diff( $zone_ids_with_postcode_rules, array_keys( $matches ) ) ); + + if ( ! empty( $do_not_match ) ) { + $criteria[] = 'AND zones.zone_id NOT IN (' . implode( ',', $do_not_match ) . ')'; + } + } + + /** + * Get shipping zone criteria + * + * @since 3.6.6 + * @param array $criteria Get zone criteria. + * @param array $package Package information. + * @param array $postcode_locations Postcode range and wildcard matching. + */ + $criteria = apply_filters( 'woocommerce_get_zone_criteria', $criteria, $package, $postcode_locations ); + + // Get matching zones. + return $wpdb->get_var( + "SELECT zones.zone_id FROM {$wpdb->prefix}woocommerce_shipping_zones as zones + LEFT OUTER JOIN {$wpdb->prefix}woocommerce_shipping_zone_locations as locations ON zones.zone_id = locations.zone_id AND location_type != 'postcode' + WHERE " . implode( ' ', $criteria ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + . ' ORDER BY zone_order ASC, zones.zone_id ASC LIMIT 1' + ); + } + + /** + * Return an ordered list of zones. + * + * @since 3.0.0 + * @return array An array of objects containing a zone_id, zone_name, and zone_order. + */ + public function get_zones() { + global $wpdb; + return $wpdb->get_results( "SELECT zone_id, zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones order by zone_order ASC, zone_id ASC;" ); + } + + + /** + * Return a zone ID from an instance ID. + * + * @since 3.0.0 + * @param int $id Instnace ID. + * @return int + */ + public function get_zone_id_by_instance_id( $id ) { + global $wpdb; + return $wpdb->get_var( $wpdb->prepare( "SELECT zone_id FROM {$wpdb->prefix}woocommerce_shipping_zone_methods as methods WHERE methods.instance_id = %d LIMIT 1;", $id ) ); + } + + /** + * Read location data from the database. + * + * @param WC_Shipping_Zone $zone Shipping zone object. + */ + private function read_zone_locations( &$zone ) { + global $wpdb; + + $locations = $wpdb->get_results( + $wpdb->prepare( + "SELECT location_code, location_type FROM {$wpdb->prefix}woocommerce_shipping_zone_locations WHERE zone_id = %d", + $zone->get_id() + ) + ); + + if ( $locations ) { + foreach ( $locations as $location ) { + $zone->add_location( $location->location_code, $location->location_type ); + } + } + } + + /** + * Save locations to the DB. + * This function clears old locations, then re-inserts new if any changes are found. + * + * @since 3.0.0 + * + * @param WC_Shipping_Zone $zone Shipping zone object. + * + * @return bool|void + */ + private function save_locations( &$zone ) { + $changed_props = array_keys( $zone->get_changes() ); + if ( ! in_array( 'zone_locations', $changed_props, true ) ) { + return false; + } + + global $wpdb; + $wpdb->delete( $wpdb->prefix . 'woocommerce_shipping_zone_locations', array( 'zone_id' => $zone->get_id() ) ); + + foreach ( $zone->get_zone_locations( 'edit' ) as $location ) { + $wpdb->insert( + $wpdb->prefix . 'woocommerce_shipping_zone_locations', + array( + 'zone_id' => $zone->get_id(), + 'location_code' => $location->code, + 'location_type' => $location->type, + ) + ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-webhook-data-store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-webhook-data-store.php new file mode 100644 index 0000000..947e89e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/data-stores/class-wc-webhook-data-store.php @@ -0,0 +1,447 @@ +get_changes(); + if ( isset( $changes['date_created'] ) ) { + $date_created = $webhook->get_date_created()->date( 'Y-m-d H:i:s' ); + $date_created_gmt = gmdate( 'Y-m-d H:i:s', $webhook->get_date_created()->getTimestamp() ); + } else { + $date_created = current_time( 'mysql' ); + $date_created_gmt = current_time( 'mysql', 1 ); + $webhook->set_date_created( $date_created ); + } + + // Pending delivery by default if not set while creating a new webhook. + if ( ! isset( $changes['pending_delivery'] ) ) { + $webhook->set_pending_delivery( true ); + } + + $data = array( + 'status' => $webhook->get_status( 'edit' ), + 'name' => $webhook->get_name( 'edit' ), + 'user_id' => $webhook->get_user_id( 'edit' ), + 'delivery_url' => $webhook->get_delivery_url( 'edit' ), + 'secret' => $webhook->get_secret( 'edit' ), + 'topic' => $webhook->get_topic( 'edit' ), + 'date_created' => $date_created, + 'date_created_gmt' => $date_created_gmt, + 'api_version' => $this->get_api_version_number( $webhook->get_api_version( 'edit' ) ), + 'failure_count' => $webhook->get_failure_count( 'edit' ), + 'pending_delivery' => $webhook->get_pending_delivery( 'edit' ), + ); + + $wpdb->insert( $wpdb->prefix . 'wc_webhooks', $data ); // WPCS: DB call ok. + + $webhook_id = $wpdb->insert_id; + $webhook->set_id( $webhook_id ); + $webhook->apply_changes(); + + $this->delete_transients( $webhook->get_status( 'edit' ) ); + WC_Cache_Helper::invalidate_cache_group( 'webhooks' ); + do_action( 'woocommerce_new_webhook', $webhook_id, $webhook ); + } + + /** + * Read a webhook from the database. + * + * @since 3.3.0 + * @param WC_Webhook $webhook Webhook instance. + * @throws Exception When webhook is invalid. + */ + public function read( &$webhook ) { + global $wpdb; + + $data = wp_cache_get( $webhook->get_id(), 'webhooks' ); + + if ( false === $data ) { + $data = $wpdb->get_row( $wpdb->prepare( "SELECT webhook_id, status, name, user_id, delivery_url, secret, topic, date_created, date_modified, api_version, failure_count, pending_delivery FROM {$wpdb->prefix}wc_webhooks WHERE webhook_id = %d LIMIT 1;", $webhook->get_id() ), ARRAY_A ); // WPCS: cache ok, DB call ok. + + wp_cache_add( $webhook->get_id(), $data, 'webhooks' ); + } + + if ( is_array( $data ) ) { + $webhook->set_props( + array( + 'id' => $data['webhook_id'], + 'status' => $data['status'], + 'name' => $data['name'], + 'user_id' => $data['user_id'], + 'delivery_url' => $data['delivery_url'], + 'secret' => $data['secret'], + 'topic' => $data['topic'], + 'date_created' => '0000-00-00 00:00:00' === $data['date_created'] ? null : $data['date_created'], + 'date_modified' => '0000-00-00 00:00:00' === $data['date_modified'] ? null : $data['date_modified'], + 'api_version' => $data['api_version'], + 'failure_count' => $data['failure_count'], + 'pending_delivery' => $data['pending_delivery'], + ) + ); + $webhook->set_object_read( true ); + + do_action( 'woocommerce_webhook_loaded', $webhook ); + } else { + throw new Exception( __( 'Invalid webhook.', 'woocommerce' ) ); + } + } + + /** + * Update a webhook. + * + * @since 3.3.0 + * @param WC_Webhook $webhook Webhook instance. + */ + public function update( &$webhook ) { + global $wpdb; + + $changes = $webhook->get_changes(); + $trigger = isset( $changes['delivery_url'] ); + + if ( isset( $changes['date_modified'] ) ) { + $date_modified = $webhook->get_date_modified()->date( 'Y-m-d H:i:s' ); + $date_modified_gmt = gmdate( 'Y-m-d H:i:s', $webhook->get_date_modified()->getTimestamp() ); + } else { + $date_modified = current_time( 'mysql' ); + $date_modified_gmt = current_time( 'mysql', 1 ); + $webhook->set_date_modified( $date_modified ); + } + + $data = array( + 'status' => $webhook->get_status( 'edit' ), + 'name' => $webhook->get_name( 'edit' ), + 'user_id' => $webhook->get_user_id( 'edit' ), + 'delivery_url' => $webhook->get_delivery_url( 'edit' ), + 'secret' => $webhook->get_secret( 'edit' ), + 'topic' => $webhook->get_topic( 'edit' ), + 'date_modified' => $date_modified, + 'date_modified_gmt' => $date_modified_gmt, + 'api_version' => $this->get_api_version_number( $webhook->get_api_version( 'edit' ) ), + 'failure_count' => $webhook->get_failure_count( 'edit' ), + 'pending_delivery' => $webhook->get_pending_delivery( 'edit' ), + ); + + $wpdb->update( + $wpdb->prefix . 'wc_webhooks', + $data, + array( + 'webhook_id' => $webhook->get_id(), + ) + ); // WPCS: DB call ok. + + $webhook->apply_changes(); + + if ( isset( $changes['status'] ) ) { + // We need to delete all transients, because we can't be sure of the old status. + $this->delete_transients( 'all' ); + } + wp_cache_delete( $webhook->get_id(), 'webhooks' ); + WC_Cache_Helper::invalidate_cache_group( 'webhooks' ); + + if ( 'active' === $webhook->get_status() && ( $trigger || $webhook->get_pending_delivery() ) ) { + $webhook->deliver_ping(); + } + + do_action( 'woocommerce_webhook_updated', $webhook->get_id() ); + } + + /** + * Remove a webhook from the database. + * + * @since 3.3.0 + * @param WC_Webhook $webhook Webhook instance. + */ + public function delete( &$webhook ) { + global $wpdb; + + $wpdb->delete( + $wpdb->prefix . 'wc_webhooks', + array( + 'webhook_id' => $webhook->get_id(), + ), + array( '%d' ) + ); // WPCS: cache ok, DB call ok. + + $this->delete_transients( 'all' ); + wp_cache_delete( $webhook->get_id(), 'webhooks' ); + WC_Cache_Helper::invalidate_cache_group( 'webhooks' ); + do_action( 'woocommerce_webhook_deleted', $webhook->get_id(), $webhook ); + } + + /** + * Get API version number. + * + * @since 3.3.0 + * @param string $api_version REST API version. + * @return int + */ + public function get_api_version_number( $api_version ) { + return 'legacy_v3' === $api_version ? -1 : intval( substr( $api_version, -1 ) ); + } + + /** + * Get webhooks IDs from the database. + * + * @since 3.3.0 + * @throws InvalidArgumentException If a $status value is passed in that is not in the known wc_get_webhook_statuses() keys. + * @param string $status Optional - status to filter results by. Must be a key in return value of @see wc_get_webhook_statuses(). @since 3.6.0. + * @return int[] + */ + public function get_webhooks_ids( $status = '' ) { + if ( ! empty( $status ) ) { + $this->validate_status( $status ); + } + + $ids = get_transient( $this->get_transient_key( $status ) ); + + if ( false === $ids ) { + $ids = $this->search_webhooks( + array( + 'limit' => -1, + 'status' => $status, + ) + ); + $ids = array_map( 'absint', $ids ); + set_transient( $this->get_transient_key( $status ), $ids ); + } + + return $ids; + } + + /** + * Search webhooks. + * + * @param array $args Search arguments. + * @return array|object + */ + public function search_webhooks( $args ) { + global $wpdb; + + $args = wp_parse_args( + $args, + array( + 'limit' => 10, + 'offset' => 0, + 'order' => 'DESC', + 'orderby' => 'id', + 'paginate' => false, + ) + ); + + // Map post statuses. + $statuses = array( + 'publish' => 'active', + 'draft' => 'paused', + 'pending' => 'disabled', + ); + + // Map orderby to support a few post keys. + $orderby_mapping = array( + 'ID' => 'webhook_id', + 'id' => 'webhook_id', + 'name' => 'name', + 'title' => 'name', + 'post_title' => 'name', + 'post_name' => 'name', + 'date_created' => 'date_created_gmt', + 'date' => 'date_created_gmt', + 'post_date' => 'date_created_gmt', + 'date_modified' => 'date_modified_gmt', + 'modified' => 'date_modified_gmt', + 'post_modified' => 'date_modified_gmt', + ); + $orderby = isset( $orderby_mapping[ $args['orderby'] ] ) ? $orderby_mapping[ $args['orderby'] ] : 'webhook_id'; + $order = "ORDER BY {$orderby} " . esc_sql( strtoupper( $args['order'] ) ); + $limit = -1 < $args['limit'] ? $wpdb->prepare( 'LIMIT %d', $args['limit'] ) : ''; + $offset = 0 < $args['offset'] ? $wpdb->prepare( 'OFFSET %d', $args['offset'] ) : ''; + $status = ! empty( $args['status'] ) ? $wpdb->prepare( 'AND `status` = %s', isset( $statuses[ $args['status'] ] ) ? $statuses[ $args['status'] ] : $args['status'] ) : ''; + $search = ! empty( $args['search'] ) ? "AND `name` LIKE '%" . $wpdb->esc_like( sanitize_text_field( $args['search'] ) ) . "%'" : ''; + $include = ''; + $exclude = ''; + $date_created = ''; + $date_modified = ''; + + if ( ! empty( $args['include'] ) ) { + $args['include'] = implode( ',', wp_parse_id_list( $args['include'] ) ); + $include = 'AND webhook_id IN (' . $args['include'] . ')'; + } + + if ( ! empty( $args['exclude'] ) ) { + $args['exclude'] = implode( ',', wp_parse_id_list( $args['exclude'] ) ); + $exclude = 'AND webhook_id NOT IN (' . $args['exclude'] . ')'; + } + + if ( ! empty( $args['after'] ) || ! empty( $args['before'] ) ) { + $args['after'] = empty( $args['after'] ) ? '0000-00-00' : $args['after']; + $args['before'] = empty( $args['before'] ) ? current_time( 'mysql', 1 ) : $args['before']; + + $date_created = "AND `date_created_gmt` BETWEEN STR_TO_DATE('" . esc_sql( $args['after'] ) . "', '%Y-%m-%d %H:%i:%s') and STR_TO_DATE('" . esc_sql( $args['before'] ) . "', '%Y-%m-%d %H:%i:%s')"; + } + + if ( ! empty( $args['modified_after'] ) || ! empty( $args['modified_before'] ) ) { + $args['modified_after'] = empty( $args['modified_after'] ) ? '0000-00-00' : $args['modified_after']; + $args['modified_before'] = empty( $args['modified_before'] ) ? current_time( 'mysql', 1 ) : $args['modified_before']; + + $date_modified = "AND `date_modified_gmt` BETWEEN STR_TO_DATE('" . esc_sql( $args['modified_after'] ) . "', '%Y-%m-%d %H:%i:%s') and STR_TO_DATE('" . esc_sql( $args['modified_before'] ) . "', '%Y-%m-%d %H:%i:%s')"; + } + + // Check for cache. + $cache_key = WC_Cache_Helper::get_cache_prefix( 'webhooks' ) . 'search_webhooks' . md5( implode( ',', $args ) ); + $cache_value = wp_cache_get( $cache_key, 'webhook_search_results' ); + + if ( $cache_value ) { + return $cache_value; + } + + if ( $args['paginate'] ) { + $query = trim( + "SELECT SQL_CALC_FOUND_ROWS webhook_id + FROM {$wpdb->prefix}wc_webhooks + WHERE 1=1 + {$status} + {$search} + {$include} + {$exclude} + {$date_created} + {$date_modified} + {$order} + {$limit} + {$offset}" + ); + + $webhook_ids = wp_parse_id_list( $wpdb->get_col( $query ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $total = (int) $wpdb->get_var( 'SELECT FOUND_ROWS();' ); + $return_value = (object) array( + 'webhooks' => $webhook_ids, + 'total' => $total, + 'max_num_pages' => $args['limit'] > 1 ? ceil( $total / $args['limit'] ) : 1, + ); + } else { + $query = trim( + "SELECT webhook_id + FROM {$wpdb->prefix}wc_webhooks + WHERE 1=1 + {$status} + {$search} + {$include} + {$exclude} + {$date_created} + {$date_modified} + {$order} + {$limit} + {$offset}" + ); + + $webhook_ids = wp_parse_id_list( $wpdb->get_col( $query ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $return_value = $webhook_ids; + } + + wp_cache_set( $cache_key, $return_value, 'webhook_search_results' ); + + return $return_value; + } + + /** + * Count webhooks. + * + * @since 3.6.0 + * @param string $status Status to count. + * @return int + */ + protected function get_webhook_count( $status = 'active' ) { + global $wpdb; + $cache_key = WC_Cache_Helper::get_cache_prefix( 'webhooks' ) . $status . '_count'; + $count = wp_cache_get( $cache_key, 'webhooks' ); + + if ( false === $count ) { + $count = absint( $wpdb->get_var( $wpdb->prepare( "SELECT count( webhook_id ) FROM {$wpdb->prefix}wc_webhooks WHERE `status` = %s;", $status ) ) ); + + wp_cache_add( $cache_key, $count, 'webhooks' ); + } + + return $count; + } + + /** + * Get total webhook counts by status. + * + * @return array + */ + public function get_count_webhooks_by_status() { + $statuses = array_keys( wc_get_webhook_statuses() ); + $counts = array(); + + foreach ( $statuses as $status ) { + $counts[ $status ] = $this->get_webhook_count( $status ); + } + + return $counts; + } + + /** + * Check if a given string is in known statuses, based on return value of @see wc_get_webhook_statuses(). + * + * @since 3.6.0 + * @throws InvalidArgumentException If $status is not empty and not in the known wc_get_webhook_statuses() keys. + * @param string $status Status to check. + */ + private function validate_status( $status ) { + if ( ! array_key_exists( $status, wc_get_webhook_statuses() ) ) { + throw new InvalidArgumentException( sprintf( 'Invalid status given: %s. Status must be one of: %s.', $status, implode( ', ', array_keys( wc_get_webhook_statuses() ) ) ) ); + } + } + + /** + * Get the transient key used to cache a set of webhook IDs, optionally filtered by status. + * + * @since 3.6.0 + * @param string $status Optional - status of cache key. + * @return string + */ + private function get_transient_key( $status = '' ) { + return empty( $status ) ? 'woocommerce_webhook_ids' : sprintf( 'woocommerce_webhook_ids_status_%s', $status ); + } + + /** + * Delete the transients used to cache a set of webhook IDs, optionally filtered by status. + * + * @since 3.6.0 + * @param string $status Optional - status of cache to delete, or 'all' to delete all caches. + */ + private function delete_transients( $status = '' ) { + + // Always delete the non-filtered cache. + delete_transient( $this->get_transient_key( '' ) ); + + if ( ! empty( $status ) ) { + if ( 'all' === $status ) { + foreach ( wc_get_webhook_statuses() as $status_key => $status_string ) { + delete_transient( $this->get_transient_key( $status_key ) ); + } + } else { + delete_transient( $this->get_transient_key( $status ) ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-cancelled-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-cancelled-order.php new file mode 100644 index 0000000..eeb4d34 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-cancelled-order.php @@ -0,0 +1,209 @@ +id = 'cancelled_order'; + $this->title = __( 'Cancelled order', 'woocommerce' ); + $this->description = __( 'Cancelled order emails are sent to chosen recipient(s) when orders have been marked cancelled (if they were previously processing or on-hold).', 'woocommerce' ); + $this->template_html = 'emails/admin-cancelled-order.php'; + $this->template_plain = 'emails/plain/admin-cancelled-order.php'; + $this->placeholders = array( + '{order_date}' => '', + '{order_number}' => '', + '{order_billing_full_name}' => '', + ); + + // Triggers for this email. + add_action( 'woocommerce_order_status_processing_to_cancelled_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_on-hold_to_cancelled_notification', array( $this, 'trigger' ), 10, 2 ); + + // Call parent constructor. + parent::__construct(); + + // Other settings. + $this->recipient = $this->get_option( 'recipient', get_option( 'admin_email' ) ); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( '[{site_title}]: Order #{order_number} has been cancelled', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'Order Cancelled: #{order_number}', 'woocommerce' ); + } + + /** + * Trigger the sending of this email. + * + * @param int $order_id The order ID. + * @param WC_Order|false $order Order object. + */ + public function trigger( $order_id, $order = false ) { + $this->setup_locale(); + + if ( $order_id && ! is_a( $order, 'WC_Order' ) ) { + $order = wc_get_order( $order_id ); + } + + if ( is_a( $order, 'WC_Order' ) ) { + $this->object = $order; + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); + $this->placeholders['{order_billing_full_name}'] = $this->object->get_formatted_billing_full_name(); + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => true, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => true, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'Thanks for reading.', 'woocommerce' ); + } + + /** + * Initialise settings form fields. + */ + public function init_form_fields() { + /* translators: %s: list of placeholders */ + $placeholder_text = sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '' . esc_html( implode( ', ', array_keys( $this->placeholders ) ) ) . '' ); + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable this email notification', 'woocommerce' ), + 'default' => 'yes', + ), + 'recipient' => array( + 'title' => __( 'Recipient(s)', 'woocommerce' ), + 'type' => 'text', + /* translators: %s: admin email */ + 'description' => sprintf( __( 'Enter recipients (comma separated) for this email. Defaults to %s.', 'woocommerce' ), '' . esc_attr( get_option( 'admin_email' ) ) . '' ), + 'placeholder' => '', + 'default' => '', + 'desc_tip' => true, + ), + 'subject' => array( + 'title' => __( 'Subject', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_subject(), + 'default' => '', + ), + 'heading' => array( + 'title' => __( 'Email heading', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_heading(), + 'default' => '', + ), + 'additional_content' => array( + 'title' => __( 'Additional content', 'woocommerce' ), + 'description' => __( 'Text to appear below the main email content.', 'woocommerce' ) . ' ' . $placeholder_text, + 'css' => 'width:400px; height: 75px;', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'type' => 'textarea', + 'default' => $this->get_default_additional_content(), + 'desc_tip' => true, + ), + 'email_type' => array( + 'title' => __( 'Email type', 'woocommerce' ), + 'type' => 'select', + 'description' => __( 'Choose which format of email to send.', 'woocommerce' ), + 'default' => 'html', + 'class' => 'email_type wc-enhanced-select', + 'options' => $this->get_email_type_options(), + 'desc_tip' => true, + ), + ); + } + } + +endif; + +return new WC_Email_Cancelled_Order(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-completed-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-completed-order.php new file mode 100644 index 0000000..1795867 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-completed-order.php @@ -0,0 +1,146 @@ +id = 'customer_completed_order'; + $this->customer_email = true; + $this->title = __( 'Completed order', 'woocommerce' ); + $this->description = __( 'Order complete emails are sent to customers when their orders are marked completed and usually indicate that their orders have been shipped.', 'woocommerce' ); + $this->template_html = 'emails/customer-completed-order.php'; + $this->template_plain = 'emails/plain/customer-completed-order.php'; + $this->placeholders = array( + '{order_date}' => '', + '{order_number}' => '', + ); + + // Triggers for this email. + add_action( 'woocommerce_order_status_completed_notification', array( $this, 'trigger' ), 10, 2 ); + + // Call parent constructor. + parent::__construct(); + } + + /** + * Trigger the sending of this email. + * + * @param int $order_id The order ID. + * @param WC_Order|false $order Order object. + */ + public function trigger( $order_id, $order = false ) { + $this->setup_locale(); + + if ( $order_id && ! is_a( $order, 'WC_Order' ) ) { + $order = wc_get_order( $order_id ); + } + + if ( is_a( $order, 'WC_Order' ) ) { + $this->object = $order; + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( 'Your {site_title} order is now complete', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'Thanks for shopping with us', 'woocommerce' ); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'Thanks for shopping with us.', 'woocommerce' ); + } + } + +endif; + +return new WC_Email_Customer_Completed_Order(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-invoice.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-invoice.php new file mode 100644 index 0000000..0a2592c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-invoice.php @@ -0,0 +1,246 @@ +id = 'customer_invoice'; + $this->customer_email = true; + $this->title = __( 'Customer invoice / Order details', 'woocommerce' ); + $this->description = __( 'Customer invoice emails can be sent to customers containing their order information and payment links.', 'woocommerce' ); + $this->template_html = 'emails/customer-invoice.php'; + $this->template_plain = 'emails/plain/customer-invoice.php'; + $this->placeholders = array( + '{order_date}' => '', + '{order_number}' => '', + ); + + // Call parent constructor. + parent::__construct(); + + $this->manual = true; + } + + /** + * Get email subject. + * + * @param bool $paid Whether the order has been paid or not. + * @since 3.1.0 + * @return string + */ + public function get_default_subject( $paid = false ) { + if ( $paid ) { + return __( 'Invoice for order #{order_number} on {site_title}', 'woocommerce' ); + } else { + return __( 'Your latest {site_title} invoice', 'woocommerce' ); + } + } + + /** + * Get email heading. + * + * @param bool $paid Whether the order has been paid or not. + * @since 3.1.0 + * @return string + */ + public function get_default_heading( $paid = false ) { + if ( $paid ) { + return __( 'Invoice for order #{order_number}', 'woocommerce' ); + } else { + return __( 'Your invoice for order #{order_number}', 'woocommerce' ); + } + } + + /** + * Get email subject. + * + * @return string + */ + public function get_subject() { + if ( $this->object->has_status( array( 'completed', 'processing' ) ) ) { + $subject = $this->get_option( 'subject_paid', $this->get_default_subject( true ) ); + + return apply_filters( 'woocommerce_email_subject_customer_invoice_paid', $this->format_string( $subject ), $this->object, $this ); + } + + $subject = $this->get_option( 'subject', $this->get_default_subject() ); + return apply_filters( 'woocommerce_email_subject_customer_invoice', $this->format_string( $subject ), $this->object, $this ); + } + + /** + * Get email heading. + * + * @return string + */ + public function get_heading() { + if ( $this->object->has_status( wc_get_is_paid_statuses() ) ) { + $heading = $this->get_option( 'heading_paid', $this->get_default_heading( true ) ); + return apply_filters( 'woocommerce_email_heading_customer_invoice_paid', $this->format_string( $heading ), $this->object, $this ); + } + + $heading = $this->get_option( 'heading', $this->get_default_heading() ); + return apply_filters( 'woocommerce_email_heading_customer_invoice', $this->format_string( $heading ), $this->object, $this ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'Thanks for using {site_url}!', 'woocommerce' ); + } + + /** + * Trigger the sending of this email. + * + * @param int $order_id The order ID. + * @param WC_Order $order Order object. + */ + public function trigger( $order_id, $order = false ) { + $this->setup_locale(); + + if ( $order_id && ! is_a( $order, 'WC_Order' ) ) { + $order = wc_get_order( $order_id ); + } + + if ( is_a( $order, 'WC_Order' ) ) { + $this->object = $order; + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); + } + + if ( $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Initialise settings form fields. + */ + public function init_form_fields() { + /* translators: %s: list of placeholders */ + $placeholder_text = sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '' . esc_html( implode( ', ', array_keys( $this->placeholders ) ) ) . '' ); + $this->form_fields = array( + 'subject' => array( + 'title' => __( 'Subject', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_subject(), + 'default' => '', + ), + 'heading' => array( + 'title' => __( 'Email heading', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_heading(), + 'default' => '', + ), + 'subject_paid' => array( + 'title' => __( 'Subject (paid)', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_subject( true ), + 'default' => '', + ), + 'heading_paid' => array( + 'title' => __( 'Email heading (paid)', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_heading( true ), + 'default' => '', + ), + 'additional_content' => array( + 'title' => __( 'Additional content', 'woocommerce' ), + 'description' => __( 'Text to appear below the main email content.', 'woocommerce' ) . ' ' . $placeholder_text, + 'css' => 'width:400px; height: 75px;', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'type' => 'textarea', + 'default' => $this->get_default_additional_content(), + 'desc_tip' => true, + ), + 'email_type' => array( + 'title' => __( 'Email type', 'woocommerce' ), + 'type' => 'select', + 'description' => __( 'Choose which format of email to send.', 'woocommerce' ), + 'default' => 'html', + 'class' => 'email_type wc-enhanced-select', + 'options' => $this->get_email_type_options(), + 'desc_tip' => true, + ), + ); + } + } + +endif; + +return new WC_Email_Customer_Invoice(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-new-account.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-new-account.php new file mode 100644 index 0000000..3cd0a82 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-new-account.php @@ -0,0 +1,173 @@ +id = 'customer_new_account'; + $this->customer_email = true; + $this->title = __( 'New account', 'woocommerce' ); + $this->description = __( 'Customer "new account" emails are sent to the customer when a customer signs up via checkout or account pages.', 'woocommerce' ); + $this->template_html = 'emails/customer-new-account.php'; + $this->template_plain = 'emails/plain/customer-new-account.php'; + + // Call parent constructor. + parent::__construct(); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( 'Your {site_title} account has been created!', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'Welcome to {site_title}', 'woocommerce' ); + } + + /** + * Trigger. + * + * @param int $user_id User ID. + * @param string $user_pass User password. + * @param bool $password_generated Whether the password was generated automatically or not. + */ + public function trigger( $user_id, $user_pass = '', $password_generated = false ) { + $this->setup_locale(); + + if ( $user_id ) { + $this->object = new WP_User( $user_id ); + + $this->user_pass = $user_pass; + $this->user_login = stripslashes( $this->object->user_login ); + $this->user_email = stripslashes( $this->object->user_email ); + $this->recipient = $this->user_email; + $this->password_generated = $password_generated; + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'user_login' => $this->user_login, + 'user_pass' => $this->user_pass, + 'blogname' => $this->get_blogname(), + 'password_generated' => $this->password_generated, + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'user_login' => $this->user_login, + 'user_pass' => $this->user_pass, + 'blogname' => $this->get_blogname(), + 'password_generated' => $this->password_generated, + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'We look forward to seeing you soon.', 'woocommerce' ); + } + } + +endif; + +return new WC_Email_Customer_New_Account(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-note.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-note.php new file mode 100644 index 0000000..cf1b265 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-note.php @@ -0,0 +1,166 @@ +id = 'customer_note'; + $this->customer_email = true; + $this->title = __( 'Customer note', 'woocommerce' ); + $this->description = __( 'Customer note emails are sent when you add a note to an order.', 'woocommerce' ); + $this->template_html = 'emails/customer-note.php'; + $this->template_plain = 'emails/plain/customer-note.php'; + $this->placeholders = array( + '{order_date}' => '', + '{order_number}' => '', + ); + + // Triggers. + add_action( 'woocommerce_new_customer_note_notification', array( $this, 'trigger' ) ); + + // Call parent constructor. + parent::__construct(); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( 'Note added to your {site_title} order from {order_date}', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'A note has been added to your order', 'woocommerce' ); + } + + /** + * Trigger. + * + * @param array $args Email arguments. + */ + public function trigger( $args ) { + $this->setup_locale(); + + if ( ! empty( $args ) ) { + $defaults = array( + 'order_id' => '', + 'customer_note' => '', + ); + + $args = wp_parse_args( $args, $defaults ); + + $order_id = $args['order_id']; + $customer_note = $args['customer_note']; + + if ( $order_id ) { + $this->object = wc_get_order( $order_id ); + + if ( $this->object ) { + $this->recipient = $this->object->get_billing_email(); + $this->customer_note = $customer_note; + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); + } + } + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'customer_note' => $this->customer_note, + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'customer_note' => $this->customer_note, + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'Thanks for reading.', 'woocommerce' ); + } + } + +endif; + +return new WC_Email_Customer_Note(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-on-hold-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-on-hold-order.php new file mode 100644 index 0000000..080abb9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-on-hold-order.php @@ -0,0 +1,148 @@ +id = 'customer_on_hold_order'; + $this->customer_email = true; + $this->title = __( 'Order on-hold', 'woocommerce' ); + $this->description = __( 'This is an order notification sent to customers containing order details after an order is placed on-hold.', 'woocommerce' ); + $this->template_html = 'emails/customer-on-hold-order.php'; + $this->template_plain = 'emails/plain/customer-on-hold-order.php'; + $this->placeholders = array( + '{order_date}' => '', + '{order_number}' => '', + ); + + // Triggers for this email. + add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_cancelled_to_on-hold_notification', array( $this, 'trigger' ), 10, 2 ); + + // Call parent constructor. + parent::__construct(); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( 'Your {site_title} order has been received!', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'Thank you for your order', 'woocommerce' ); + } + + /** + * Trigger the sending of this email. + * + * @param int $order_id The order ID. + * @param WC_Order|false $order Order object. + */ + public function trigger( $order_id, $order = false ) { + $this->setup_locale(); + + if ( $order_id && ! is_a( $order, 'WC_Order' ) ) { + $order = wc_get_order( $order_id ); + } + + if ( is_a( $order, 'WC_Order' ) ) { + $this->object = $order; + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'We look forward to fulfilling your order soon.', 'woocommerce' ); + } + } + +endif; + +return new WC_Email_Customer_On_Hold_Order(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-processing-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-processing-order.php new file mode 100644 index 0000000..18b8c95 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-processing-order.php @@ -0,0 +1,150 @@ +id = 'customer_processing_order'; + $this->customer_email = true; + + $this->title = __( 'Processing order', 'woocommerce' ); + $this->description = __( 'This is an order notification sent to customers containing order details after payment.', 'woocommerce' ); + $this->template_html = 'emails/customer-processing-order.php'; + $this->template_plain = 'emails/plain/customer-processing-order.php'; + $this->placeholders = array( + '{order_date}' => '', + '{order_number}' => '', + ); + + // Triggers for this email. + add_action( 'woocommerce_order_status_cancelled_to_processing_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_on-hold_to_processing_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ), 10, 2 ); + + // Call parent constructor. + parent::__construct(); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( 'Your {site_title} order has been received!', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'Thank you for your order', 'woocommerce' ); + } + + /** + * Trigger the sending of this email. + * + * @param int $order_id The order ID. + * @param WC_Order|false $order Order object. + */ + public function trigger( $order_id, $order = false ) { + $this->setup_locale(); + + if ( $order_id && ! is_a( $order, 'WC_Order' ) ) { + $order = wc_get_order( $order_id ); + } + + if ( is_a( $order, 'WC_Order' ) ) { + $this->object = $order; + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'Thanks for using {site_url}!', 'woocommerce' ); + } + } + +endif; + +return new WC_Email_Customer_Processing_Order(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-refunded-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-refunded-order.php new file mode 100644 index 0000000..1536ba3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-refunded-order.php @@ -0,0 +1,302 @@ +customer_email = true; + $this->id = 'customer_refunded_order'; + $this->title = __( 'Refunded order', 'woocommerce' ); + $this->description = __( 'Order refunded emails are sent to customers when their orders are refunded.', 'woocommerce' ); + $this->template_html = 'emails/customer-refunded-order.php'; + $this->template_plain = 'emails/plain/customer-refunded-order.php'; + $this->placeholders = array( + '{order_date}' => '', + '{order_number}' => '', + ); + + // Triggers for this email. + add_action( 'woocommerce_order_fully_refunded_notification', array( $this, 'trigger_full' ), 10, 2 ); + add_action( 'woocommerce_order_partially_refunded_notification', array( $this, 'trigger_partial' ), 10, 2 ); + + // Call parent constructor. + parent::__construct(); + } + + /** + * Get email subject. + * + * @param bool $partial Whether it is a partial refund or a full refund. + * @since 3.1.0 + * @return string + */ + public function get_default_subject( $partial = false ) { + if ( $partial ) { + return __( 'Your {site_title} order #{order_number} has been partially refunded', 'woocommerce' ); + } else { + return __( 'Your {site_title} order #{order_number} has been refunded', 'woocommerce' ); + } + } + + /** + * Get email heading. + * + * @param bool $partial Whether it is a partial refund or a full refund. + * @since 3.1.0 + * @return string + */ + public function get_default_heading( $partial = false ) { + if ( $partial ) { + return __( 'Partial Refund: Order {order_number}', 'woocommerce' ); + } else { + return __( 'Order Refunded: {order_number}', 'woocommerce' ); + } + } + + /** + * Get email subject. + * + * @return string + */ + public function get_subject() { + if ( $this->partial_refund ) { + $subject = $this->get_option( 'subject_partial', $this->get_default_subject( true ) ); + } else { + $subject = $this->get_option( 'subject_full', $this->get_default_subject() ); + } + return apply_filters( 'woocommerce_email_subject_customer_refunded_order', $this->format_string( $subject ), $this->object, $this ); + } + + /** + * Get email heading. + * + * @return string + */ + public function get_heading() { + if ( $this->partial_refund ) { + $heading = $this->get_option( 'heading_partial', $this->get_default_heading( true ) ); + } else { + $heading = $this->get_option( 'heading_full', $this->get_default_heading() ); + } + return apply_filters( 'woocommerce_email_heading_customer_refunded_order', $this->format_string( $heading ), $this->object, $this ); + } + + /** + * Set email strings. + * + * @param bool $partial_refund Whether it is a partial refund or a full refund. + * @deprecated 3.1.0 Unused. + */ + public function set_email_strings( $partial_refund = false ) {} + + /** + * Full refund notification. + * + * @param int $order_id Order ID. + * @param int $refund_id Refund ID. + */ + public function trigger_full( $order_id, $refund_id = null ) { + $this->trigger( $order_id, false, $refund_id ); + } + + /** + * Partial refund notification. + * + * @param int $order_id Order ID. + * @param int $refund_id Refund ID. + */ + public function trigger_partial( $order_id, $refund_id = null ) { + $this->trigger( $order_id, true, $refund_id ); + } + + /** + * Trigger. + * + * @param int $order_id Order ID. + * @param bool $partial_refund Whether it is a partial refund or a full refund. + * @param int $refund_id Refund ID. + */ + public function trigger( $order_id, $partial_refund = false, $refund_id = null ) { + $this->setup_locale(); + $this->partial_refund = $partial_refund; + $this->id = $this->partial_refund ? 'customer_partially_refunded_order' : 'customer_refunded_order'; + + if ( $order_id ) { + $this->object = wc_get_order( $order_id ); + $this->recipient = $this->object->get_billing_email(); + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); + } + + if ( ! empty( $refund_id ) ) { + $this->refund = wc_get_order( $refund_id ); + } else { + $this->refund = false; + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'refund' => $this->refund, + 'partial_refund' => $this->partial_refund, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'refund' => $this->refund, + 'partial_refund' => $this->partial_refund, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'We hope to see you again soon.', 'woocommerce' ); + } + + /** + * Initialise settings form fields. + */ + public function init_form_fields() { + /* translators: %s: list of placeholders */ + $placeholder_text = sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '' . esc_html( implode( ', ', array_keys( $this->placeholders ) ) ) . '' ); + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable this email notification', 'woocommerce' ), + 'default' => 'yes', + ), + 'subject_full' => array( + 'title' => __( 'Full refund subject', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_subject(), + 'default' => '', + ), + 'subject_partial' => array( + 'title' => __( 'Partial refund subject', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_subject( true ), + 'default' => '', + ), + 'heading_full' => array( + 'title' => __( 'Full refund email heading', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_heading(), + 'default' => '', + ), + 'heading_partial' => array( + 'title' => __( 'Partial refund email heading', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_heading( true ), + 'default' => '', + ), + 'additional_content' => array( + 'title' => __( 'Additional content', 'woocommerce' ), + 'description' => __( 'Text to appear below the main email content.', 'woocommerce' ) . ' ' . $placeholder_text, + 'css' => 'width:400px; height: 75px;', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'type' => 'textarea', + 'default' => $this->get_default_additional_content(), + 'desc_tip' => true, + ), + 'email_type' => array( + 'title' => __( 'Email type', 'woocommerce' ), + 'type' => 'select', + 'description' => __( 'Choose which format of email to send.', 'woocommerce' ), + 'default' => 'html', + 'class' => 'email_type wc-enhanced-select', + 'options' => $this->get_email_type_options(), + 'desc_tip' => true, + ), + ); + } + } + +endif; + +return new WC_Email_Customer_Refunded_Order(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-reset-password.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-reset-password.php new file mode 100644 index 0000000..7603097 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-customer-reset-password.php @@ -0,0 +1,177 @@ +id = 'customer_reset_password'; + $this->customer_email = true; + + $this->title = __( 'Reset password', 'woocommerce' ); + $this->description = __( 'Customer "reset password" emails are sent when customers reset their passwords.', 'woocommerce' ); + + $this->template_html = 'emails/customer-reset-password.php'; + $this->template_plain = 'emails/plain/customer-reset-password.php'; + + // Trigger. + add_action( 'woocommerce_reset_password_notification', array( $this, 'trigger' ), 10, 2 ); + + // Call parent constructor. + parent::__construct(); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( 'Password Reset Request for {site_title}', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'Password Reset Request', 'woocommerce' ); + } + + /** + * Trigger. + * + * @param string $user_login User login. + * @param string $reset_key Password reset key. + */ + public function trigger( $user_login = '', $reset_key = '' ) { + $this->setup_locale(); + + if ( $user_login && $reset_key ) { + $this->object = get_user_by( 'login', $user_login ); + $this->user_id = $this->object->ID; + $this->user_login = $user_login; + $this->reset_key = $reset_key; + $this->user_email = stripslashes( $this->object->user_email ); + $this->recipient = $this->user_email; + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'email_heading' => $this->get_heading(), + 'user_id' => $this->user_id, + 'user_login' => $this->user_login, + 'reset_key' => $this->reset_key, + 'blogname' => $this->get_blogname(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'email_heading' => $this->get_heading(), + 'user_id' => $this->user_id, + 'user_login' => $this->user_login, + 'reset_key' => $this->reset_key, + 'blogname' => $this->get_blogname(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'Thanks for reading.', 'woocommerce' ); + } + } + +endif; + +return new WC_Email_Customer_Reset_Password(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-failed-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-failed-order.php new file mode 100644 index 0000000..0766d9a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-failed-order.php @@ -0,0 +1,207 @@ +id = 'failed_order'; + $this->title = __( 'Failed order', 'woocommerce' ); + $this->description = __( 'Failed order emails are sent to chosen recipient(s) when orders have been marked failed (if they were previously pending or on-hold).', 'woocommerce' ); + $this->template_html = 'emails/admin-failed-order.php'; + $this->template_plain = 'emails/plain/admin-failed-order.php'; + $this->placeholders = array( + '{order_date}' => '', + '{order_number}' => '', + ); + + // Triggers for this email. + add_action( 'woocommerce_order_status_pending_to_failed_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_on-hold_to_failed_notification', array( $this, 'trigger' ), 10, 2 ); + + // Call parent constructor. + parent::__construct(); + + // Other settings. + $this->recipient = $this->get_option( 'recipient', get_option( 'admin_email' ) ); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( '[{site_title}]: Order #{order_number} has failed', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'Order Failed: #{order_number}', 'woocommerce' ); + } + + /** + * Trigger the sending of this email. + * + * @param int $order_id The order ID. + * @param WC_Order|false $order Order object. + */ + public function trigger( $order_id, $order = false ) { + $this->setup_locale(); + + if ( $order_id && ! is_a( $order, 'WC_Order' ) ) { + $order = wc_get_order( $order_id ); + } + + if ( is_a( $order, 'WC_Order' ) ) { + $this->object = $order; + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => true, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => true, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'Hopefully they’ll be back. Read more about troubleshooting failed payments.', 'woocommerce' ); + } + + /** + * Initialise settings form fields. + */ + public function init_form_fields() { + /* translators: %s: list of placeholders */ + $placeholder_text = sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '' . esc_html( implode( ', ', array_keys( $this->placeholders ) ) ) . '' ); + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable this email notification', 'woocommerce' ), + 'default' => 'yes', + ), + 'recipient' => array( + 'title' => __( 'Recipient(s)', 'woocommerce' ), + 'type' => 'text', + /* translators: %s: WP admin email */ + 'description' => sprintf( __( 'Enter recipients (comma separated) for this email. Defaults to %s.', 'woocommerce' ), '' . esc_attr( get_option( 'admin_email' ) ) . '' ), + 'placeholder' => '', + 'default' => '', + 'desc_tip' => true, + ), + 'subject' => array( + 'title' => __( 'Subject', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_subject(), + 'default' => '', + ), + 'heading' => array( + 'title' => __( 'Email heading', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_heading(), + 'default' => '', + ), + 'additional_content' => array( + 'title' => __( 'Additional content', 'woocommerce' ), + 'description' => __( 'Text to appear below the main email content.', 'woocommerce' ) . ' ' . $placeholder_text, + 'css' => 'width:400px; height: 75px;', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'type' => 'textarea', + 'default' => $this->get_default_additional_content(), + 'desc_tip' => true, + ), + 'email_type' => array( + 'title' => __( 'Email type', 'woocommerce' ), + 'type' => 'select', + 'description' => __( 'Choose which format of email to send.', 'woocommerce' ), + 'default' => 'html', + 'class' => 'email_type wc-enhanced-select', + 'options' => $this->get_email_type_options(), + 'desc_tip' => true, + ), + ); + } + } + +endif; + +return new WC_Email_Failed_Order(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-new-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-new-order.php new file mode 100644 index 0000000..0c063d6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email-new-order.php @@ -0,0 +1,214 @@ +id = 'new_order'; + $this->title = __( 'New order', 'woocommerce' ); + $this->description = __( 'New order emails are sent to chosen recipient(s) when a new order is received.', 'woocommerce' ); + $this->template_html = 'emails/admin-new-order.php'; + $this->template_plain = 'emails/plain/admin-new-order.php'; + $this->placeholders = array( + '{order_date}' => '', + '{order_number}' => '', + ); + + // Triggers for this email. + add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_pending_to_completed_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_cancelled_to_processing_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_cancelled_to_completed_notification', array( $this, 'trigger' ), 10, 2 ); + add_action( 'woocommerce_order_status_cancelled_to_on-hold_notification', array( $this, 'trigger' ), 10, 2 ); + + // Call parent constructor. + parent::__construct(); + + // Other settings. + $this->recipient = $this->get_option( 'recipient', get_option( 'admin_email' ) ); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( '[{site_title}]: New order #{order_number}', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'New Order: #{order_number}', 'woocommerce' ); + } + + /** + * Trigger the sending of this email. + * + * @param int $order_id The order ID. + * @param WC_Order|false $order Order object. + */ + public function trigger( $order_id, $order = false ) { + $this->setup_locale(); + + if ( $order_id && ! is_a( $order, 'WC_Order' ) ) { + $order = wc_get_order( $order_id ); + } + + if ( is_a( $order, 'WC_Order' ) ) { + $this->object = $order; + $this->placeholders['{order_date}'] = wc_format_datetime( $this->object->get_date_created() ); + $this->placeholders['{order_number}'] = $this->object->get_order_number(); + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => true, + 'plain_text' => false, + 'email' => $this, + ) + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'sent_to_admin' => true, + 'plain_text' => true, + 'email' => $this, + ) + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'Congratulations on the sale.', 'woocommerce' ); + } + + /** + * Initialise settings form fields. + */ + public function init_form_fields() { + /* translators: %s: list of placeholders */ + $placeholder_text = sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '' . implode( ', ', array_keys( $this->placeholders ) ) . '' ); + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable this email notification', 'woocommerce' ), + 'default' => 'yes', + ), + 'recipient' => array( + 'title' => __( 'Recipient(s)', 'woocommerce' ), + 'type' => 'text', + /* translators: %s: WP admin email */ + 'description' => sprintf( __( 'Enter recipients (comma separated) for this email. Defaults to %s.', 'woocommerce' ), '' . esc_attr( get_option( 'admin_email' ) ) . '' ), + 'placeholder' => '', + 'default' => '', + 'desc_tip' => true, + ), + 'subject' => array( + 'title' => __( 'Subject', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_subject(), + 'default' => '', + ), + 'heading' => array( + 'title' => __( 'Email heading', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_heading(), + 'default' => '', + ), + 'additional_content' => array( + 'title' => __( 'Additional content', 'woocommerce' ), + 'description' => __( 'Text to appear below the main email content.', 'woocommerce' ) . ' ' . $placeholder_text, + 'css' => 'width:400px; height: 75px;', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'type' => 'textarea', + 'default' => $this->get_default_additional_content(), + 'desc_tip' => true, + ), + 'email_type' => array( + 'title' => __( 'Email type', 'woocommerce' ), + 'type' => 'select', + 'description' => __( 'Choose which format of email to send.', 'woocommerce' ), + 'default' => 'html', + 'class' => 'email_type wc-enhanced-select', + 'options' => $this->get_email_type_options(), + 'desc_tip' => true, + ), + ); + } + } + +endif; + +return new WC_Email_New_Order(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email.php new file mode 100644 index 0000000..a9c2ff3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/emails/class-wc-email.php @@ -0,0 +1,1080 @@ +', // Greater-than. + '<', // Less-than. + '&', // Ampersand. + '&', // Ampersand. + '(c)', // Copyright. + '(tm)', // Trademark. + '(R)', // Registered. + '--', // mdash. + '-', // ndash. + '*', // Bullet. + '£', // Pound sign. + 'EUR', // Euro sign. € ?. + '$', // Dollar sign. + '', // Unknown/unhandled entities. + ' ', // Runs of spaces, post-handling. + ); + + /** + * Strings to find/replace in subjects/headings. + * + * @var array + */ + protected $placeholders = array(); + + /** + * Strings to find in subjects/headings. + * + * @deprecated 3.2.0 in favour of placeholders + * @var array + */ + public $find = array(); + + /** + * Strings to replace in subjects/headings. + * + * @deprecated 3.2.0 in favour of placeholders + * @var array + */ + public $replace = array(); + + /** + * Constructor. + */ + public function __construct() { + // Find/replace. + $this->placeholders = array_merge( + array( + '{site_title}' => $this->get_blogname(), + '{site_address}' => wp_parse_url( home_url(), PHP_URL_HOST ), + '{site_url}' => wp_parse_url( home_url(), PHP_URL_HOST ), + ), + $this->placeholders + ); + + // Init settings. + $this->init_form_fields(); + $this->init_settings(); + + // Default template base if not declared in child constructor. + if ( is_null( $this->template_base ) ) { + $this->template_base = WC()->plugin_path() . '/templates/'; + } + + $this->email_type = $this->get_option( 'email_type' ); + $this->enabled = $this->get_option( 'enabled' ); + + add_action( 'phpmailer_init', array( $this, 'handle_multipart' ) ); + add_action( 'woocommerce_update_options_email_' . $this->id, array( $this, 'process_admin_options' ) ); + } + + /** + * Handle multipart mail. + * + * @param PHPMailer $mailer PHPMailer object. + * @return PHPMailer + */ + public function handle_multipart( $mailer ) { + if ( $this->sending && 'multipart' === $this->get_email_type() ) { + $mailer->AltBody = wordwrap( // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + preg_replace( $this->plain_search, $this->plain_replace, wp_strip_all_tags( $this->get_content_plain() ) ) + ); + $this->sending = false; + } + return $mailer; + } + + /** + * Format email string. + * + * @param mixed $string Text to replace placeholders in. + * @return string + */ + public function format_string( $string ) { + $find = array_keys( $this->placeholders ); + $replace = array_values( $this->placeholders ); + + // If using legacy find replace, add those to our find/replace arrays first. @todo deprecate in 4.0.0. + $find = array_merge( (array) $this->find, $find ); + $replace = array_merge( (array) $this->replace, $replace ); + + // Take care of blogname which is no longer defined as a valid placeholder. + $find[] = '{blogname}'; + $replace[] = $this->get_blogname(); + + // If using the older style filters for find and replace, ensure the array is associative and then pass through filters. @todo deprecate in 4.0.0. + if ( has_filter( 'woocommerce_email_format_string_replace' ) || has_filter( 'woocommerce_email_format_string_find' ) ) { + $legacy_find = $this->find; + $legacy_replace = $this->replace; + + foreach ( $this->placeholders as $find => $replace ) { + $legacy_key = sanitize_title( str_replace( '_', '-', trim( $find, '{}' ) ) ); + $legacy_find[ $legacy_key ] = $find; + $legacy_replace[ $legacy_key ] = $replace; + } + + $string = str_replace( apply_filters( 'woocommerce_email_format_string_find', $legacy_find, $this ), apply_filters( 'woocommerce_email_format_string_replace', $legacy_replace, $this ), $string ); + } + + /** + * Filter for main find/replace. + * + * @since 3.2.0 + */ + return apply_filters( 'woocommerce_email_format_string', str_replace( $find, $replace, $string ), $this ); + } + + /** + * Set the locale to the store locale for customer emails to make sure emails are in the store language. + */ + public function setup_locale() { + if ( $this->is_customer_email() && apply_filters( 'woocommerce_email_setup_locale', true ) ) { + wc_switch_to_site_locale(); + } + } + + /** + * Restore the locale to the default locale. Use after finished with setup_locale. + */ + public function restore_locale() { + if ( $this->is_customer_email() && apply_filters( 'woocommerce_email_restore_locale', true ) ) { + wc_restore_locale(); + } + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return $this->subject; + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return $this->heading; + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return ''; + } + + /** + * Return content from the additional_content field. + * + * Displayed above the footer. + * + * @since 3.7.0 + * @return string + */ + public function get_additional_content() { + $content = $this->get_option( 'additional_content', '' ); + + return apply_filters( 'woocommerce_email_additional_content_' . $this->id, $this->format_string( $content ), $this->object, $this ); + } + + /** + * Get email subject. + * + * @return string + */ + public function get_subject() { + return apply_filters( 'woocommerce_email_subject_' . $this->id, $this->format_string( $this->get_option( 'subject', $this->get_default_subject() ) ), $this->object, $this ); + } + + /** + * Get email heading. + * + * @return string + */ + public function get_heading() { + return apply_filters( 'woocommerce_email_heading_' . $this->id, $this->format_string( $this->get_option( 'heading', $this->get_default_heading() ) ), $this->object, $this ); + } + + /** + * Get valid recipients. + * + * @return string + */ + public function get_recipient() { + $recipient = apply_filters( 'woocommerce_email_recipient_' . $this->id, $this->recipient, $this->object, $this ); + $recipients = array_map( 'trim', explode( ',', $recipient ) ); + $recipients = array_filter( $recipients, 'is_email' ); + return implode( ', ', $recipients ); + } + + /** + * Get email headers. + * + * @return string + */ + public function get_headers() { + $header = 'Content-Type: ' . $this->get_content_type() . "\r\n"; + + if ( in_array( $this->id, array( 'new_order', 'cancelled_order', 'failed_order' ), true ) ) { + if ( $this->object && $this->object->get_billing_email() && ( $this->object->get_billing_first_name() || $this->object->get_billing_last_name() ) ) { + $header .= 'Reply-to: ' . $this->object->get_billing_first_name() . ' ' . $this->object->get_billing_last_name() . ' <' . $this->object->get_billing_email() . ">\r\n"; + } + } elseif ( $this->get_from_address() && $this->get_from_name() ) { + $header .= 'Reply-to: ' . $this->get_from_name() . ' <' . $this->get_from_address() . ">\r\n"; + } + + return apply_filters( 'woocommerce_email_headers', $header, $this->id, $this->object, $this ); + } + + /** + * Get email attachments. + * + * @return array + */ + public function get_attachments() { + return apply_filters( 'woocommerce_email_attachments', array(), $this->id, $this->object, $this ); + } + + /** + * Return email type. + * + * @return string + */ + public function get_email_type() { + return $this->email_type && class_exists( 'DOMDocument' ) ? $this->email_type : 'plain'; + } + + /** + * Get email content type. + * + * @param string $default_content_type Default wp_mail() content type. + * @return string + */ + public function get_content_type( $default_content_type = '' ) { + switch ( $this->get_email_type() ) { + case 'html': + $content_type = 'text/html'; + break; + case 'multipart': + $content_type = 'multipart/alternative'; + break; + default: + $content_type = 'text/plain'; + break; + } + + return apply_filters( 'woocommerce_email_content_type', $content_type, $this, $default_content_type ); + } + + /** + * Return the email's title + * + * @return string + */ + public function get_title() { + return apply_filters( 'woocommerce_email_title', $this->title, $this ); + } + + /** + * Return the email's description + * + * @return string + */ + public function get_description() { + return apply_filters( 'woocommerce_email_description', $this->description, $this ); + } + + /** + * Proxy to parent's get_option and attempt to localize the result using gettext. + * + * @param string $key Option key. + * @param mixed $empty_value Value to use when option is empty. + * @return string + */ + public function get_option( $key, $empty_value = null ) { + $value = parent::get_option( $key, $empty_value ); + return apply_filters( 'woocommerce_email_get_option', $value, $this, $value, $key, $empty_value ); + } + + /** + * Checks if this email is enabled and will be sent. + * + * @return bool + */ + public function is_enabled() { + return apply_filters( 'woocommerce_email_enabled_' . $this->id, 'yes' === $this->enabled, $this->object, $this ); + } + + /** + * Checks if this email is manually sent + * + * @return bool + */ + public function is_manual() { + return $this->manual; + } + + /** + * Checks if this email is customer focussed. + * + * @return bool + */ + public function is_customer_email() { + return $this->customer_email; + } + + /** + * Get WordPress blog name. + * + * @return string + */ + public function get_blogname() { + return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + } + + /** + * Get email content. + * + * @return string + */ + public function get_content() { + $this->sending = true; + + if ( 'plain' === $this->get_email_type() ) { + $email_content = wordwrap( preg_replace( $this->plain_search, $this->plain_replace, wp_strip_all_tags( $this->get_content_plain() ) ), 70 ); + } else { + $email_content = $this->get_content_html(); + } + + return $email_content; + } + + /** + * Apply inline styles to dynamic content. + * + * We only inline CSS for html emails, and to do so we use Emogrifier library (if supported). + * + * @version 4.0.0 + * @param string|null $content Content that will receive inline styles. + * @return string + */ + public function style_inline( $content ) { + if ( in_array( $this->get_content_type(), array( 'text/html', 'multipart/alternative' ), true ) ) { + ob_start(); + wc_get_template( 'emails/email-styles.php' ); + $css = apply_filters( 'woocommerce_email_styles', ob_get_clean(), $this ); + + $emogrifier_class = 'Pelago\\Emogrifier'; + + if ( $this->supports_emogrifier() && class_exists( $emogrifier_class ) ) { + try { + $emogrifier = new $emogrifier_class( $content, $css ); + + do_action( 'woocommerce_emogrifier', $emogrifier, $this ); + + $content = $emogrifier->emogrify(); + $html_prune = \Pelago\Emogrifier\HtmlProcessor\HtmlPruner::fromHtml( $content ); + $html_prune->removeElementsWithDisplayNone(); + $content = $html_prune->render(); + } catch ( Exception $e ) { + $logger = wc_get_logger(); + $logger->error( $e->getMessage(), array( 'source' => 'emogrifier' ) ); + } + } else { + $content = '' . $content; + } + } + + return $content; + } + + /** + * Return if emogrifier library is supported. + * + * @version 4.0.0 + * @since 3.5.0 + * @return bool + */ + protected function supports_emogrifier() { + return class_exists( 'DOMDocument' ); + } + + /** + * Get the email content in plain text format. + * + * @return string + */ + public function get_content_plain() { + return ''; } + + /** + * Get the email content in HTML format. + * + * @return string + */ + public function get_content_html() { + return ''; } + + /** + * Get the from name for outgoing emails. + * + * @param string $from_name Default wp_mail() name associated with the "from" email address. + * @return string + */ + public function get_from_name( $from_name = '' ) { + $from_name = apply_filters( 'woocommerce_email_from_name', get_option( 'woocommerce_email_from_name' ), $this, $from_name ); + return wp_specialchars_decode( esc_html( $from_name ), ENT_QUOTES ); + } + + /** + * Get the from address for outgoing emails. + * + * @param string $from_email Default wp_mail() email address to send from. + * @return string + */ + public function get_from_address( $from_email = '' ) { + $from_email = apply_filters( 'woocommerce_email_from_address', get_option( 'woocommerce_email_from_address' ), $this, $from_email ); + return sanitize_email( $from_email ); + } + + /** + * Send an email. + * + * @param string $to Email to. + * @param string $subject Email subject. + * @param string $message Email message. + * @param string $headers Email headers. + * @param array $attachments Email attachments. + * @return bool success + */ + public function send( $to, $subject, $message, $headers, $attachments ) { + add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) ); + add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) ); + add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) ); + + $message = apply_filters( 'woocommerce_mail_content', $this->style_inline( $message ) ); + $mail_callback = apply_filters( 'woocommerce_mail_callback', 'wp_mail', $this ); + $mail_callback_params = apply_filters( 'woocommerce_mail_callback_params', array( $to, $subject, $message, $headers, $attachments ), $this ); + $return = $mail_callback( ...$mail_callback_params ); + + remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) ); + remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) ); + remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) ); + + return $return; + } + + /** + * Initialise Settings Form Fields - these are generic email options most will use. + */ + public function init_form_fields() { + /* translators: %s: list of placeholders */ + $placeholder_text = sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '' . esc_html( implode( ', ', array_keys( $this->placeholders ) ) ) . '' ); + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable this email notification', 'woocommerce' ), + 'default' => 'yes', + ), + 'subject' => array( + 'title' => __( 'Subject', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_subject(), + 'default' => '', + ), + 'heading' => array( + 'title' => __( 'Email heading', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => $placeholder_text, + 'placeholder' => $this->get_default_heading(), + 'default' => '', + ), + 'additional_content' => array( + 'title' => __( 'Additional content', 'woocommerce' ), + 'description' => __( 'Text to appear below the main email content.', 'woocommerce' ) . ' ' . $placeholder_text, + 'css' => 'width:400px; height: 75px;', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'type' => 'textarea', + 'default' => $this->get_default_additional_content(), + 'desc_tip' => true, + ), + 'email_type' => array( + 'title' => __( 'Email type', 'woocommerce' ), + 'type' => 'select', + 'description' => __( 'Choose which format of email to send.', 'woocommerce' ), + 'default' => 'html', + 'class' => 'email_type wc-enhanced-select', + 'options' => $this->get_email_type_options(), + 'desc_tip' => true, + ), + ); + } + + /** + * Email type options. + * + * @return array + */ + public function get_email_type_options() { + $types = array( 'plain' => __( 'Plain text', 'woocommerce' ) ); + + if ( class_exists( 'DOMDocument' ) ) { + $types['html'] = __( 'HTML', 'woocommerce' ); + $types['multipart'] = __( 'Multipart', 'woocommerce' ); + } + + return $types; + } + + /** + * Admin Panel Options Processing. + */ + public function process_admin_options() { + // Save regular options. + parent::process_admin_options(); + + $post_data = $this->get_post_data(); + + // Save templates. + if ( isset( $post_data['template_html_code'] ) ) { + $this->save_template( $post_data['template_html_code'], $this->template_html ); + } + if ( isset( $post_data['template_plain_code'] ) ) { + $this->save_template( $post_data['template_plain_code'], $this->template_plain ); + } + } + + /** + * Get template. + * + * @param string $type Template type. Can be either 'template_html' or 'template_plain'. + * @return string + */ + public function get_template( $type ) { + $type = basename( $type ); + + if ( 'template_html' === $type ) { + return $this->template_html; + } elseif ( 'template_plain' === $type ) { + return $this->template_plain; + } + return ''; + } + + /** + * Save the email templates. + * + * @since 2.4.0 + * @param string $template_code Template code. + * @param string $template_path Template path. + */ + protected function save_template( $template_code, $template_path ) { + if ( current_user_can( 'edit_themes' ) && ! empty( $template_code ) && ! empty( $template_path ) ) { + $saved = false; + $file = get_stylesheet_directory() . '/' . WC()->template_path() . $template_path; + $code = wp_unslash( $template_code ); + + if ( is_writeable( $file ) ) { // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writeable + $f = fopen( $file, 'w+' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen + + if ( false !== $f ) { + fwrite( $f, $code ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite + fclose( $f ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose + $saved = true; + } + } + + if ( ! $saved ) { + $redirect = add_query_arg( 'wc_error', rawurlencode( __( 'Could not write to template file.', 'woocommerce' ) ) ); + wp_safe_redirect( $redirect ); + exit; + } + } + } + + /** + * Get the template file in the current theme. + * + * @param string $template Template name. + * + * @return string + */ + public function get_theme_template_file( $template ) { + return get_stylesheet_directory() . '/' . apply_filters( 'woocommerce_template_directory', 'woocommerce', $template ) . '/' . $template; + } + + /** + * Move template action. + * + * @param string $template_type Template type. + */ + protected function move_template_action( $template_type ) { + $template = $this->get_template( $template_type ); + if ( ! empty( $template ) ) { + $theme_file = $this->get_theme_template_file( $template ); + + if ( wp_mkdir_p( dirname( $theme_file ) ) && ! file_exists( $theme_file ) ) { + + // Locate template file. + $core_file = $this->template_base . $template; + $template_file = apply_filters( 'woocommerce_locate_core_template', $core_file, $template, $this->template_base, $this->id ); + + // Copy template file. + copy( $template_file, $theme_file ); + + /** + * Action hook fired after copying email template file. + * + * @param string $template_type The copied template type + * @param string $email The email object + */ + do_action( 'woocommerce_copy_email_template', $template_type, $this ); + + ?> +
    +

    +
    + get_template( $template_type ); + + if ( $template ) { + if ( ! empty( $template ) ) { + $theme_file = $this->get_theme_template_file( $template ); + + if ( file_exists( $theme_file ) ) { + unlink( $theme_file ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink + + /** + * Action hook fired after deleting template file. + * + * @param string $template The deleted template type + * @param string $email The email object + */ + do_action( 'woocommerce_delete_email_template', $template_type, $this ); + ?> +
    +

    +
    + template_html ) || ! empty( $this->template_plain ) ) + && ( ! empty( $_GET['move_template'] ) || ! empty( $_GET['delete_template'] ) ) + && 'GET' === $_SERVER['REQUEST_METHOD'] // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated + ) { + if ( empty( $_GET['_wc_email_nonce'] ) || ! wp_verify_nonce( wc_clean( wp_unslash( $_GET['_wc_email_nonce'] ) ), 'woocommerce_email_template_nonce' ) ) { + wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) ); + } + + if ( ! current_user_can( 'edit_themes' ) ) { + wp_die( esc_html__( 'You don’t have permission to do this.', 'woocommerce' ) ); + } + + if ( ! empty( $_GET['move_template'] ) ) { + $this->move_template_action( wc_clean( wp_unslash( $_GET['move_template'] ) ) ); + } + + if ( ! empty( $_GET['delete_template'] ) ) { + $this->delete_template_action( wc_clean( wp_unslash( $_GET['delete_template'] ) ) ); + } + } + } + + /** + * Admin Options. + * + * Setup the email settings screen. + * Override this in your email. + * + * @since 1.0.0 + */ + public function admin_options() { + // Do admin actions. + $this->admin_actions(); + ?> +

    get_title() ); ?>

    + + get_description() ) ); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped ?> + + + + + generate_settings_html(); ?> +
    + + + + template_html ) || ! empty( $this->template_plain ) ) ) { + ?> +
    + __( 'HTML template', 'woocommerce' ), + 'template_plain' => __( 'Plain text template', 'woocommerce' ), + ); + + foreach ( $templates as $template_type => $title ) : + $template = $this->get_template( $template_type ); + + if ( empty( $template ) ) { + continue; + } + + $local_file = $this->get_theme_template_file( $template ); + $core_file = $this->template_base . $template; + $template_file = apply_filters( 'woocommerce_locate_core_template', $core_file, $template, $this->template_base, $this->id ); + $template_dir = apply_filters( 'woocommerce_template_directory', 'woocommerce', $template ); + ?> +
    +

    + + +

    + + + + + + + + + ' . esc_html( trailingslashit( basename( get_stylesheet_directory() ) ) . $template_dir . '/' . $template ) . '' ); + ?> +

    + + + +

    + + + + + + + + + ' . esc_html( plugin_basename( $template_file ) ) . '', '' . esc_html( trailingslashit( basename( get_stylesheet_directory() ) ) . $template_dir . '/' . $template ) . '' ); + ?> +

    + + + +

    + +
    + +
    + + column_names = $this->get_default_column_names(); + } + + /** + * Get file path to export to. + * + * @return string + */ + protected function get_file_path() { + $upload_dir = wp_upload_dir(); + return trailingslashit( $upload_dir['basedir'] ) . $this->get_filename(); + } + + /** + * Get the file contents. + * + * @since 3.1.0 + * @return string + */ + public function get_file() { + $file = ''; + if ( @file_exists( $this->get_file_path() ) ) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged + $file = @file_get_contents( $this->get_file_path() ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents, WordPress.WP.AlternativeFunctions.file_system_read_file_get_contents + } else { + @file_put_contents( $this->get_file_path(), '' ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_file_put_contents, Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents + @chmod( $this->get_file_path(), 0664 ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.chmod_chmod, WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents, Generic.PHP.NoSilencedErrors.Discouraged + } + return $file; + } + + /** + * Serve the file and remove once sent to the client. + * + * @since 3.1.0 + */ + public function export() { + $this->send_headers(); + $this->send_content( $this->get_file() ); + @unlink( $this->get_file_path() ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink, Generic.PHP.NoSilencedErrors.Discouraged + die(); + } + + /** + * Generate the CSV file. + * + * @since 3.1.0 + */ + public function generate_file() { + if ( 1 === $this->get_page() ) { + @unlink( $this->get_file_path() ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink, Generic.PHP.NoSilencedErrors.Discouraged, + } + $this->prepare_data_to_export(); + $this->write_csv_data( $this->get_csv_data() ); + } + + /** + * Write data to the file. + * + * @since 3.1.0 + * @param string $data Data. + */ + protected function write_csv_data( $data ) { + $file = $this->get_file(); + + // Add columns when finished. + if ( 100 === $this->get_percent_complete() ) { + $file = chr( 239 ) . chr( 187 ) . chr( 191 ) . $this->export_column_headers() . $file; + } + + $file .= $data; + @file_put_contents( $this->get_file_path(), $file ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_file_put_contents, Generic.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents + } + + /** + * Get page. + * + * @since 3.1.0 + * @return int + */ + public function get_page() { + return $this->page; + } + + /** + * Set page. + * + * @since 3.1.0 + * @param int $page Page Nr. + */ + public function set_page( $page ) { + $this->page = absint( $page ); + } + + /** + * Get count of records exported. + * + * @since 3.1.0 + * @return int + */ + public function get_total_exported() { + return ( ( $this->get_page() - 1 ) * $this->get_limit() ) + $this->exported_row_count; + } + + /** + * Get total % complete. + * + * @since 3.1.0 + * @return int + */ + public function get_percent_complete() { + return $this->total_rows ? floor( ( $this->get_total_exported() / $this->total_rows ) * 100 ) : 100; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/export/abstract-wc-csv-exporter.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/export/abstract-wc-csv-exporter.php new file mode 100644 index 0000000..e5631b9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/export/abstract-wc-csv-exporter.php @@ -0,0 +1,507 @@ +export_type}_export_column_names", $this->column_names, $this ); + } + + /** + * Set column names. + * + * @since 3.1.0 + * @param array $column_names Column names array. + */ + public function set_column_names( $column_names ) { + $this->column_names = array(); + + foreach ( $column_names as $column_id => $column_name ) { + $this->column_names[ wc_clean( $column_id ) ] = wc_clean( $column_name ); + } + } + + /** + * Return an array of columns to export. + * + * @since 3.1.0 + * @return array + */ + public function get_columns_to_export() { + return $this->columns_to_export; + } + + /** + * Return the delimiter to use in CSV file + * + * @since 3.9.0 + * @return string + */ + public function get_delimiter() { + return apply_filters( "woocommerce_{$this->export_type}_export_delimiter", $this->delimiter ); + } + + /** + * Set columns to export. + * + * @since 3.1.0 + * @param array $columns Columns array. + */ + public function set_columns_to_export( $columns ) { + $this->columns_to_export = array_map( 'wc_clean', $columns ); + } + + /** + * See if a column is to be exported or not. + * + * @since 3.1.0 + * @param string $column_id ID of the column being exported. + * @return boolean + */ + public function is_column_exporting( $column_id ) { + $column_id = strstr( $column_id, ':' ) ? current( explode( ':', $column_id ) ) : $column_id; + $columns_to_export = $this->get_columns_to_export(); + + if ( empty( $columns_to_export ) ) { + return true; + } + + if ( in_array( $column_id, $columns_to_export, true ) || 'meta' === $column_id ) { + return true; + } + + return false; + } + + /** + * Return default columns. + * + * @since 3.1.0 + * @return array + */ + public function get_default_column_names() { + return array(); + } + + /** + * Do the export. + * + * @since 3.1.0 + */ + public function export() { + $this->prepare_data_to_export(); + $this->send_headers(); + $this->send_content( chr( 239 ) . chr( 187 ) . chr( 191 ) . $this->export_column_headers() . $this->get_csv_data() ); + die(); + } + + /** + * Set the export headers. + * + * @since 3.1.0 + */ + public function send_headers() { + if ( function_exists( 'gc_enable' ) ) { + gc_enable(); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.gc_enableFound + } + if ( function_exists( 'apache_setenv' ) ) { + @apache_setenv( 'no-gzip', 1 ); // @codingStandardsIgnoreLine + } + @ini_set( 'zlib.output_compression', 'Off' ); // @codingStandardsIgnoreLine + @ini_set( 'output_buffering', 'Off' ); // @codingStandardsIgnoreLine + @ini_set( 'output_handler', '' ); // @codingStandardsIgnoreLine + ignore_user_abort( true ); + wc_set_time_limit( 0 ); + wc_nocache_headers(); + header( 'Content-Type: text/csv; charset=utf-8' ); + header( 'Content-Disposition: attachment; filename=' . $this->get_filename() ); + header( 'Pragma: no-cache' ); + header( 'Expires: 0' ); + } + + /** + * Set filename to export to. + * + * @param string $filename Filename to export to. + */ + public function set_filename( $filename ) { + $this->filename = sanitize_file_name( str_replace( '.csv', '', $filename ) . '.csv' ); + } + + /** + * Generate and return a filename. + * + * @return string + */ + public function get_filename() { + return sanitize_file_name( apply_filters( "woocommerce_{$this->export_type}_export_get_filename", $this->filename ) ); + } + + /** + * Set the export content. + * + * @since 3.1.0 + * @param string $csv_data All CSV content. + */ + public function send_content( $csv_data ) { + echo $csv_data; // @codingStandardsIgnoreLine + } + + /** + * Get CSV data for this export. + * + * @since 3.1.0 + * @return string + */ + protected function get_csv_data() { + return $this->export_rows(); + } + + /** + * Export column headers in CSV format. + * + * @since 3.1.0 + * @return string + */ + protected function export_column_headers() { + $columns = $this->get_column_names(); + $export_row = array(); + $buffer = fopen( 'php://output', 'w' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen + ob_start(); + + foreach ( $columns as $column_id => $column_name ) { + if ( ! $this->is_column_exporting( $column_id ) ) { + continue; + } + $export_row[] = $this->format_data( $column_name ); + } + + $this->fputcsv( $buffer, $export_row ); + + return ob_get_clean(); + } + + /** + * Get data that will be exported. + * + * @since 3.1.0 + * @return array + */ + protected function get_data_to_export() { + return $this->row_data; + } + + /** + * Export rows in CSV format. + * + * @since 3.1.0 + * @return string + */ + protected function export_rows() { + $data = $this->get_data_to_export(); + $buffer = fopen( 'php://output', 'w' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen + ob_start(); + + array_walk( $data, array( $this, 'export_row' ), $buffer ); + + return apply_filters( "woocommerce_{$this->export_type}_export_rows", ob_get_clean(), $this ); + } + + /** + * Export rows to an array ready for the CSV. + * + * @since 3.1.0 + * @param array $row_data Data to export. + * @param string $key Column being exported. + * @param resource $buffer Output buffer. + */ + protected function export_row( $row_data, $key, $buffer ) { + $columns = $this->get_column_names(); + $export_row = array(); + + foreach ( $columns as $column_id => $column_name ) { + if ( ! $this->is_column_exporting( $column_id ) ) { + continue; + } + if ( isset( $row_data[ $column_id ] ) ) { + $export_row[] = $this->format_data( $row_data[ $column_id ] ); + } else { + $export_row[] = ''; + } + } + + $this->fputcsv( $buffer, $export_row ); + + ++ $this->exported_row_count; + } + + /** + * Get batch limit. + * + * @since 3.1.0 + * @return int + */ + public function get_limit() { + return apply_filters( "woocommerce_{$this->export_type}_export_batch_limit", $this->limit, $this ); + } + + /** + * Set batch limit. + * + * @since 3.1.0 + * @param int $limit Limit to export. + */ + public function set_limit( $limit ) { + $this->limit = absint( $limit ); + } + + /** + * Get count of records exported. + * + * @since 3.1.0 + * @return int + */ + public function get_total_exported() { + return $this->exported_row_count; + } + + /** + * Escape a string to be used in a CSV context + * + * Malicious input can inject formulas into CSV files, opening up the possibility + * for phishing attacks and disclosure of sensitive information. + * + * Additionally, Excel exposes the ability to launch arbitrary commands through + * the DDE protocol. + * + * @see http://www.contextis.com/resources/blog/comma-separated-vulnerabilities/ + * @see https://hackerone.com/reports/72785 + * + * @since 3.1.0 + * @param string $data CSV field to escape. + * @return string + */ + public function escape_data( $data ) { + $active_content_triggers = array( '=', '+', '-', '@' ); + + if ( in_array( mb_substr( $data, 0, 1 ), $active_content_triggers, true ) ) { + $data = "'" . $data; + } + + return $data; + } + + /** + * Format and escape data ready for the CSV file. + * + * @since 3.1.0 + * @param string $data Data to format. + * @return string + */ + public function format_data( $data ) { + if ( ! is_scalar( $data ) ) { + if ( is_a( $data, 'WC_Datetime' ) ) { + $data = $data->date( 'Y-m-d G:i:s' ); + } else { + $data = ''; // Not supported. + } + } elseif ( is_bool( $data ) ) { + $data = $data ? 1 : 0; + } + + $use_mb = function_exists( 'mb_convert_encoding' ); + + if ( $use_mb ) { + $encoding = mb_detect_encoding( $data, 'UTF-8, ISO-8859-1', true ); + $data = 'UTF-8' === $encoding ? $data : utf8_encode( $data ); + } + + return $this->escape_data( $data ); + } + + /** + * Format term ids to names. + * + * @since 3.1.0 + * @param array $term_ids Term IDs to format. + * @param string $taxonomy Taxonomy name. + * @return string + */ + public function format_term_ids( $term_ids, $taxonomy ) { + $term_ids = wp_parse_id_list( $term_ids ); + + if ( ! count( $term_ids ) ) { + return ''; + } + + $formatted_terms = array(); + + if ( is_taxonomy_hierarchical( $taxonomy ) ) { + foreach ( $term_ids as $term_id ) { + $formatted_term = array(); + $ancestor_ids = array_reverse( get_ancestors( $term_id, $taxonomy ) ); + + foreach ( $ancestor_ids as $ancestor_id ) { + $term = get_term( $ancestor_id, $taxonomy ); + if ( $term && ! is_wp_error( $term ) ) { + $formatted_term[] = $term->name; + } + } + + $term = get_term( $term_id, $taxonomy ); + + if ( $term && ! is_wp_error( $term ) ) { + $formatted_term[] = $term->name; + } + + $formatted_terms[] = implode( ' > ', $formatted_term ); + } + } else { + foreach ( $term_ids as $term_id ) { + $term = get_term( $term_id, $taxonomy ); + + if ( $term && ! is_wp_error( $term ) ) { + $formatted_terms[] = $term->name; + } + } + } + + return $this->implode_values( $formatted_terms ); + } + + /** + * Implode CSV cell values using commas by default, and wrapping values + * which contain the separator. + * + * @since 3.2.0 + * @param array $values Values to implode. + * @return string + */ + protected function implode_values( $values ) { + $values_to_implode = array(); + + foreach ( $values as $value ) { + $value = (string) is_scalar( $value ) ? $value : ''; + $values_to_implode[] = str_replace( ',', '\\,', $value ); + } + + return implode( ', ', $values_to_implode ); + } + + /** + * Write to the CSV file, ensuring escaping works across versions of + * PHP. + * + * PHP 5.5.4 uses '\' as the default escape character. This is not RFC-4180 compliant. + * \0 disables the escape character. + * + * @see https://bugs.php.net/bug.php?id=43225 + * @see https://bugs.php.net/bug.php?id=50686 + * @see https://github.com/woocommerce/woocommerce/issues/19514 + * @since 3.4.0 + * @see https://github.com/woocommerce/woocommerce/issues/24579 + * @since 3.9.0 + * @param resource $buffer Resource we are writing to. + * @param array $export_row Row to export. + */ + protected function fputcsv( $buffer, $export_row ) { + + if ( version_compare( PHP_VERSION, '5.5.4', '<' ) ) { + ob_start(); + $temp = fopen( 'php://output', 'w' ); // @codingStandardsIgnoreLine + fputcsv( $temp, $export_row, $this->get_delimiter(), '"' ); // @codingStandardsIgnoreLine + fclose( $temp ); // @codingStandardsIgnoreLine + $row = ob_get_clean(); + $row = str_replace( '\\"', '\\""', $row ); + fwrite( $buffer, $row ); // @codingStandardsIgnoreLine + } else { + fputcsv( $buffer, $export_row, $this->get_delimiter(), '"', "\0" ); // @codingStandardsIgnoreLine + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/export/class-wc-product-csv-exporter.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/export/class-wc-product-csv-exporter.php new file mode 100644 index 0000000..2326460 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/export/class-wc-product-csv-exporter.php @@ -0,0 +1,730 @@ +set_product_types_to_export( array_merge( array_keys( wc_get_product_types() ), array( 'variation' ) ) ); + } + + /** + * Should meta be exported? + * + * @param bool $enable_meta_export Should meta be exported. + * + * @since 3.1.0 + */ + public function enable_meta_export( $enable_meta_export ) { + $this->enable_meta_export = (bool) $enable_meta_export; + } + + /** + * Product types to export. + * + * @param array $product_types_to_export List of types to export. + * + * @since 3.1.0 + */ + public function set_product_types_to_export( $product_types_to_export ) { + $this->product_types_to_export = array_map( 'wc_clean', $product_types_to_export ); + } + + /** + * Product category to export + * + * @param string $product_category_to_export Product category slug to export, empty string exports all. + * + * @since 3.5.0 + * @return void + */ + public function set_product_category_to_export( $product_category_to_export ) { + $this->product_category_to_export = array_map( 'sanitize_title_with_dashes', $product_category_to_export ); + } + + /** + * Return an array of columns to export. + * + * @since 3.1.0 + * @return array + */ + public function get_default_column_names() { + return apply_filters( + "woocommerce_product_export_{$this->export_type}_default_columns", + array( + 'id' => __( 'ID', 'woocommerce' ), + 'type' => __( 'Type', 'woocommerce' ), + 'sku' => __( 'SKU', 'woocommerce' ), + 'name' => __( 'Name', 'woocommerce' ), + 'published' => __( 'Published', 'woocommerce' ), + 'featured' => __( 'Is featured?', 'woocommerce' ), + 'catalog_visibility' => __( 'Visibility in catalog', 'woocommerce' ), + 'short_description' => __( 'Short description', 'woocommerce' ), + 'description' => __( 'Description', 'woocommerce' ), + 'date_on_sale_from' => __( 'Date sale price starts', 'woocommerce' ), + 'date_on_sale_to' => __( 'Date sale price ends', 'woocommerce' ), + 'tax_status' => __( 'Tax status', 'woocommerce' ), + 'tax_class' => __( 'Tax class', 'woocommerce' ), + 'stock_status' => __( 'In stock?', 'woocommerce' ), + 'stock' => __( 'Stock', 'woocommerce' ), + 'low_stock_amount' => __( 'Low stock amount', 'woocommerce' ), + 'backorders' => __( 'Backorders allowed?', 'woocommerce' ), + 'sold_individually' => __( 'Sold individually?', 'woocommerce' ), + /* translators: %s: weight */ + 'weight' => sprintf( __( 'Weight (%s)', 'woocommerce' ), get_option( 'woocommerce_weight_unit' ) ), + /* translators: %s: length */ + 'length' => sprintf( __( 'Length (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ), + /* translators: %s: width */ + 'width' => sprintf( __( 'Width (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ), + /* translators: %s: Height */ + 'height' => sprintf( __( 'Height (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ), + 'reviews_allowed' => __( 'Allow customer reviews?', 'woocommerce' ), + 'purchase_note' => __( 'Purchase note', 'woocommerce' ), + 'sale_price' => __( 'Sale price', 'woocommerce' ), + 'regular_price' => __( 'Regular price', 'woocommerce' ), + 'category_ids' => __( 'Categories', 'woocommerce' ), + 'tag_ids' => __( 'Tags', 'woocommerce' ), + 'shipping_class_id' => __( 'Shipping class', 'woocommerce' ), + 'images' => __( 'Images', 'woocommerce' ), + 'download_limit' => __( 'Download limit', 'woocommerce' ), + 'download_expiry' => __( 'Download expiry days', 'woocommerce' ), + 'parent_id' => __( 'Parent', 'woocommerce' ), + 'grouped_products' => __( 'Grouped products', 'woocommerce' ), + 'upsell_ids' => __( 'Upsells', 'woocommerce' ), + 'cross_sell_ids' => __( 'Cross-sells', 'woocommerce' ), + 'product_url' => __( 'External URL', 'woocommerce' ), + 'button_text' => __( 'Button text', 'woocommerce' ), + 'menu_order' => __( 'Position', 'woocommerce' ), + ) + ); + } + + /** + * Prepare data for export. + * + * @since 3.1.0 + */ + public function prepare_data_to_export() { + $args = array( + 'status' => array( 'private', 'publish', 'draft', 'future', 'pending' ), + 'type' => $this->product_types_to_export, + 'limit' => $this->get_limit(), + 'page' => $this->get_page(), + 'orderby' => array( + 'ID' => 'ASC', + ), + 'return' => 'objects', + 'paginate' => true, + ); + + if ( ! empty( $this->product_category_to_export ) ) { + $args['category'] = $this->product_category_to_export; + } + $products = wc_get_products( apply_filters( "woocommerce_product_export_{$this->export_type}_query_args", $args ) ); + + $this->total_rows = $products->total; + $this->row_data = array(); + $variable_products = array(); + + foreach ( $products->products as $product ) { + // Check if the category is set, this means we need to fetch variations seperately as they are not tied to a category. + if ( ! empty( $args['category'] ) && $product->is_type( 'variable' ) ) { + $variable_products[] = $product->get_id(); + } + + $this->row_data[] = $this->generate_row_data( $product ); + } + + // If a category was selected we loop through the variations as they are not tied to a category so will be excluded by default. + if ( ! empty( $variable_products ) ) { + foreach ( $variable_products as $parent_id ) { + $products = wc_get_products( + array( + 'parent' => $parent_id, + 'type' => array( 'variation' ), + 'return' => 'objects', + 'limit' => -1, + ) + ); + + if ( ! $products ) { + continue; + } + + foreach ( $products as $product ) { + $this->row_data[] = $this->generate_row_data( $product ); + } + } + } + } + + /** + * Take a product and generate row data from it for export. + * + * @param WC_Product $product WC_Product object. + * + * @return array + */ + protected function generate_row_data( $product ) { + $columns = $this->get_column_names(); + $row = array(); + foreach ( $columns as $column_id => $column_name ) { + $column_id = strstr( $column_id, ':' ) ? current( explode( ':', $column_id ) ) : $column_id; + $value = ''; + + // Skip some columns if dynamically handled later or if we're being selective. + if ( in_array( $column_id, array( 'downloads', 'attributes', 'meta' ), true ) || ! $this->is_column_exporting( $column_id ) ) { + continue; + } + + if ( has_filter( "woocommerce_product_export_{$this->export_type}_column_{$column_id}" ) ) { + // Filter for 3rd parties. + $value = apply_filters( "woocommerce_product_export_{$this->export_type}_column_{$column_id}", '', $product, $column_id ); + + } elseif ( is_callable( array( $this, "get_column_value_{$column_id}" ) ) ) { + // Handle special columns which don't map 1:1 to product data. + $value = $this->{"get_column_value_{$column_id}"}( $product ); + + } elseif ( is_callable( array( $product, "get_{$column_id}" ) ) ) { + // Default and custom handling. + $value = $product->{"get_{$column_id}"}( 'edit' ); + } + + if ( 'description' === $column_id || 'short_description' === $column_id ) { + $value = $this->filter_description_field( $value ); + } + + $row[ $column_id ] = $value; + } + + $this->prepare_downloads_for_export( $product, $row ); + $this->prepare_attributes_for_export( $product, $row ); + $this->prepare_meta_for_export( $product, $row ); + return apply_filters( 'woocommerce_product_export_row_data', $row, $product ); + } + + /** + * Get published value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return int + */ + protected function get_column_value_published( $product ) { + $statuses = array( + 'draft' => -1, + 'private' => 0, + 'publish' => 1, + ); + + // Fix display for variations when parent product is a draft. + if ( 'variation' === $product->get_type() ) { + $parent = $product->get_parent_data(); + $status = 'draft' === $parent['status'] ? $parent['status'] : $product->get_status( 'edit' ); + } else { + $status = $product->get_status( 'edit' ); + } + + return isset( $statuses[ $status ] ) ? $statuses[ $status ] : -1; + } + + /** + * Get formatted sale price. + * + * @param WC_Product $product Product being exported. + * + * @return string + */ + protected function get_column_value_sale_price( $product ) { + return wc_format_localized_price( $product->get_sale_price( 'view' ) ); + } + + /** + * Get formatted regular price. + * + * @param WC_Product $product Product being exported. + * + * @return string + */ + protected function get_column_value_regular_price( $product ) { + return wc_format_localized_price( $product->get_regular_price() ); + } + + /** + * Get product_cat value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_category_ids( $product ) { + $term_ids = $product->get_category_ids( 'edit' ); + return $this->format_term_ids( $term_ids, 'product_cat' ); + } + + /** + * Get product_tag value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_tag_ids( $product ) { + $term_ids = $product->get_tag_ids( 'edit' ); + return $this->format_term_ids( $term_ids, 'product_tag' ); + } + + /** + * Get product_shipping_class value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_shipping_class_id( $product ) { + $term_ids = $product->get_shipping_class_id( 'edit' ); + return $this->format_term_ids( $term_ids, 'product_shipping_class' ); + } + + /** + * Get images value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_images( $product ) { + $image_ids = array_merge( array( $product->get_image_id( 'edit' ) ), $product->get_gallery_image_ids( 'edit' ) ); + $images = array(); + + foreach ( $image_ids as $image_id ) { + $image = wp_get_attachment_image_src( $image_id, 'full' ); + + if ( $image ) { + $images[] = $image[0]; + } + } + + return $this->implode_values( $images ); + } + + /** + * Prepare linked products for export. + * + * @param int[] $linked_products Array of linked product ids. + * + * @since 3.1.0 + * @return string + */ + protected function prepare_linked_products_for_export( $linked_products ) { + $product_list = array(); + + foreach ( $linked_products as $linked_product ) { + if ( $linked_product->get_sku() ) { + $product_list[] = $linked_product->get_sku(); + } else { + $product_list[] = 'id:' . $linked_product->get_id(); + } + } + + return $this->implode_values( $product_list ); + } + + /** + * Get cross_sell_ids value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_cross_sell_ids( $product ) { + return $this->prepare_linked_products_for_export( array_filter( array_map( 'wc_get_product', (array) $product->get_cross_sell_ids( 'edit' ) ) ) ); + } + + /** + * Get upsell_ids value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_upsell_ids( $product ) { + return $this->prepare_linked_products_for_export( array_filter( array_map( 'wc_get_product', (array) $product->get_upsell_ids( 'edit' ) ) ) ); + } + + /** + * Get parent_id value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_parent_id( $product ) { + if ( $product->get_parent_id( 'edit' ) ) { + $parent = wc_get_product( $product->get_parent_id( 'edit' ) ); + if ( ! $parent ) { + return ''; + } + + return $parent->get_sku( 'edit' ) ? $parent->get_sku( 'edit' ) : 'id:' . $parent->get_id(); + } + return ''; + } + + /** + * Get grouped_products value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_grouped_products( $product ) { + if ( 'grouped' !== $product->get_type() ) { + return ''; + } + + $grouped_products = array(); + $child_ids = $product->get_children( 'edit' ); + foreach ( $child_ids as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! $child ) { + continue; + } + + $grouped_products[] = $child->get_sku( 'edit' ) ? $child->get_sku( 'edit' ) : 'id:' . $child_id; + } + return $this->implode_values( $grouped_products ); + } + + /** + * Get download_limit value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_download_limit( $product ) { + return $product->is_downloadable() && $product->get_download_limit( 'edit' ) ? $product->get_download_limit( 'edit' ) : ''; + } + + /** + * Get download_expiry value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_download_expiry( $product ) { + return $product->is_downloadable() && $product->get_download_expiry( 'edit' ) ? $product->get_download_expiry( 'edit' ) : ''; + } + + /** + * Get stock value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_stock( $product ) { + $manage_stock = $product->get_manage_stock( 'edit' ); + $stock_quantity = $product->get_stock_quantity( 'edit' ); + + if ( $product->is_type( 'variation' ) && 'parent' === $manage_stock ) { + return 'parent'; + } elseif ( $manage_stock ) { + return $stock_quantity; + } else { + return ''; + } + } + + /** + * Get stock status value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_stock_status( $product ) { + $status = $product->get_stock_status( 'edit' ); + + if ( 'onbackorder' === $status ) { + return 'backorder'; + } + + return 'instock' === $status ? 1 : 0; + } + + /** + * Get backorders. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_backorders( $product ) { + $backorders = $product->get_backorders( 'edit' ); + + switch ( $backorders ) { + case 'notify': + return 'notify'; + default: + return wc_string_to_bool( $backorders ) ? 1 : 0; + } + } + + /** + * Get low stock amount value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.5.0 + * @return int|string Empty string if value not set + */ + protected function get_column_value_low_stock_amount( $product ) { + return $product->managing_stock() && $product->get_low_stock_amount( 'edit' ) ? $product->get_low_stock_amount( 'edit' ) : ''; + } + + /** + * Get type value. + * + * @param WC_Product $product Product being exported. + * + * @since 3.1.0 + * @return string + */ + protected function get_column_value_type( $product ) { + $types = array(); + $types[] = $product->get_type(); + + if ( $product->is_downloadable() ) { + $types[] = 'downloadable'; + } + + if ( $product->is_virtual() ) { + $types[] = 'virtual'; + } + + return $this->implode_values( $types ); + } + + /** + * Filter description field for export. + * Convert newlines to '\n'. + * + * @param string $description Product description text to filter. + * + * @since 3.5.4 + * @return string + */ + protected function filter_description_field( $description ) { + $description = str_replace( '\n', "\\\\n", $description ); + $description = str_replace( "\n", '\n', $description ); + return $description; + } + /** + * Export downloads. + * + * @param WC_Product $product Product being exported. + * @param array $row Row being exported. + * + * @since 3.1.0 + */ + protected function prepare_downloads_for_export( $product, &$row ) { + if ( $product->is_downloadable() && $this->is_column_exporting( 'downloads' ) ) { + $downloads = $product->get_downloads( 'edit' ); + + if ( $downloads ) { + $i = 1; + foreach ( $downloads as $download ) { + /* translators: %s: download number */ + $this->column_names[ 'downloads:name' . $i ] = sprintf( __( 'Download %d name', 'woocommerce' ), $i ); + /* translators: %s: download number */ + $this->column_names[ 'downloads:url' . $i ] = sprintf( __( 'Download %d URL', 'woocommerce' ), $i ); + $row[ 'downloads:name' . $i ] = $download->get_name(); + $row[ 'downloads:url' . $i ] = $download->get_file(); + $i++; + } + } + } + } + + /** + * Export attributes data. + * + * @param WC_Product $product Product being exported. + * @param array $row Row being exported. + * + * @since 3.1.0 + */ + protected function prepare_attributes_for_export( $product, &$row ) { + if ( $this->is_column_exporting( 'attributes' ) ) { + $attributes = $product->get_attributes(); + $default_attributes = $product->get_default_attributes(); + + if ( count( $attributes ) ) { + $i = 1; + foreach ( $attributes as $attribute_name => $attribute ) { + /* translators: %s: attribute number */ + $this->column_names[ 'attributes:name' . $i ] = sprintf( __( 'Attribute %d name', 'woocommerce' ), $i ); + /* translators: %s: attribute number */ + $this->column_names[ 'attributes:value' . $i ] = sprintf( __( 'Attribute %d value(s)', 'woocommerce' ), $i ); + /* translators: %s: attribute number */ + $this->column_names[ 'attributes:visible' . $i ] = sprintf( __( 'Attribute %d visible', 'woocommerce' ), $i ); + /* translators: %s: attribute number */ + $this->column_names[ 'attributes:taxonomy' . $i ] = sprintf( __( 'Attribute %d global', 'woocommerce' ), $i ); + + if ( is_a( $attribute, 'WC_Product_Attribute' ) ) { + $row[ 'attributes:name' . $i ] = wc_attribute_label( $attribute->get_name(), $product ); + + if ( $attribute->is_taxonomy() ) { + $terms = $attribute->get_terms(); + $values = array(); + + foreach ( $terms as $term ) { + $values[] = $term->name; + } + + $row[ 'attributes:value' . $i ] = $this->implode_values( $values ); + $row[ 'attributes:taxonomy' . $i ] = 1; + } else { + $row[ 'attributes:value' . $i ] = $this->implode_values( $attribute->get_options() ); + $row[ 'attributes:taxonomy' . $i ] = 0; + } + + $row[ 'attributes:visible' . $i ] = $attribute->get_visible(); + } else { + $row[ 'attributes:name' . $i ] = wc_attribute_label( $attribute_name, $product ); + + if ( 0 === strpos( $attribute_name, 'pa_' ) ) { + $option_term = get_term_by( 'slug', $attribute, $attribute_name ); // @codingStandardsIgnoreLine. + $row[ 'attributes:value' . $i ] = $option_term && ! is_wp_error( $option_term ) ? str_replace( ',', '\\,', $option_term->name ) : str_replace( ',', '\\,', $attribute ); + $row[ 'attributes:taxonomy' . $i ] = 1; + } else { + $row[ 'attributes:value' . $i ] = str_replace( ',', '\\,', $attribute ); + $row[ 'attributes:taxonomy' . $i ] = 0; + } + + $row[ 'attributes:visible' . $i ] = ''; + } + + if ( $product->is_type( 'variable' ) && isset( $default_attributes[ sanitize_title( $attribute_name ) ] ) ) { + /* translators: %s: attribute number */ + $this->column_names[ 'attributes:default' . $i ] = sprintf( __( 'Attribute %d default', 'woocommerce' ), $i ); + $default_value = $default_attributes[ sanitize_title( $attribute_name ) ]; + + if ( 0 === strpos( $attribute_name, 'pa_' ) ) { + $option_term = get_term_by( 'slug', $default_value, $attribute_name ); // @codingStandardsIgnoreLine. + $row[ 'attributes:default' . $i ] = $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $default_value; + } else { + $row[ 'attributes:default' . $i ] = $default_value; + } + } + $i++; + } + } + } + } + + /** + * Export meta data. + * + * @param WC_Product $product Product being exported. + * @param array $row Row data. + * + * @since 3.1.0 + */ + protected function prepare_meta_for_export( $product, &$row ) { + if ( $this->enable_meta_export ) { + $meta_data = $product->get_meta_data(); + + if ( count( $meta_data ) ) { + $meta_keys_to_skip = apply_filters( 'woocommerce_product_export_skip_meta_keys', array(), $product ); + + $i = 1; + foreach ( $meta_data as $meta ) { + if ( in_array( $meta->key, $meta_keys_to_skip, true ) ) { + continue; + } + + // Allow 3rd parties to process the meta, e.g. to transform non-scalar values to scalar. + $meta_value = apply_filters( 'woocommerce_product_export_meta_value', $meta->value, $meta, $product, $row ); + + if ( ! is_scalar( $meta_value ) ) { + continue; + } + + $column_key = 'meta:' . esc_attr( $meta->key ); + /* translators: %s: meta data name */ + $this->column_names[ $column_key ] = sprintf( __( 'Meta: %s', 'woocommerce' ), $meta->key ); + $row[ $column_key ] = $meta_value; + $i ++; + } + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/bacs/class-wc-gateway-bacs.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/bacs/class-wc-gateway-bacs.php new file mode 100644 index 0000000..3ec175d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/bacs/class-wc-gateway-bacs.php @@ -0,0 +1,441 @@ +id = 'bacs'; + $this->icon = apply_filters( 'woocommerce_bacs_icon', '' ); + $this->has_fields = false; + $this->method_title = __( 'Direct bank transfer', 'woocommerce' ); + $this->method_description = __( 'Take payments in person via BACS. More commonly known as direct bank/wire transfer', 'woocommerce' ); + + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Define user set variables. + $this->title = $this->get_option( 'title' ); + $this->description = $this->get_option( 'description' ); + $this->instructions = $this->get_option( 'instructions' ); + + // BACS account fields shown on the thanks page and in emails. + $this->account_details = get_option( + 'woocommerce_bacs_accounts', + array( + array( + 'account_name' => $this->get_option( 'account_name' ), + 'account_number' => $this->get_option( 'account_number' ), + 'sort_code' => $this->get_option( 'sort_code' ), + 'bank_name' => $this->get_option( 'bank_name' ), + 'iban' => $this->get_option( 'iban' ), + 'bic' => $this->get_option( 'bic' ), + ), + ) + ); + + // Actions. + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'save_account_details' ) ); + add_action( 'woocommerce_thankyou_bacs', array( $this, 'thankyou_page' ) ); + + // Customer Emails. + add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 ); + } + + /** + * Initialise Gateway Settings Form Fields. + */ + public function init_form_fields() { + + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable bank transfer', 'woocommerce' ), + 'default' => 'no', + ), + 'title' => array( + 'title' => __( 'Title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => __( 'Direct bank transfer', 'woocommerce' ), + 'desc_tip' => true, + ), + 'description' => array( + 'title' => __( 'Description', 'woocommerce' ), + 'type' => 'textarea', + 'description' => __( 'Payment method description that the customer will see on your checkout.', 'woocommerce' ), + 'default' => __( 'Make your payment directly into our bank account. Please use your Order ID as the payment reference. Your order will not be shipped until the funds have cleared in our account.', 'woocommerce' ), + 'desc_tip' => true, + ), + 'instructions' => array( + 'title' => __( 'Instructions', 'woocommerce' ), + 'type' => 'textarea', + 'description' => __( 'Instructions that will be added to the thank you page and emails.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + ), + 'account_details' => array( + 'type' => 'account_details', + ), + ); + + } + + /** + * Generate account details html. + * + * @return string + */ + public function generate_account_details_html() { + + ob_start(); + + $country = WC()->countries->get_base_country(); + $locale = $this->get_country_locale(); + + // Get sortcode label in the $locale array and use appropriate one. + $sortcode = isset( $locale[ $country ]['sortcode']['label'] ) ? $locale[ $country ]['sortcode']['label'] : __( 'Sort code', 'woocommerce' ); + + ?> + + + +
    + + + + + + + + + + + + + + account_details ) { + foreach ( $this->account_details as $account ) { + $i++; + + echo ' + + + + + + + + '; + } + } + ?> + + + + + + +
     
    +
    + + + + $name ) { + if ( ! isset( $account_names[ $i ] ) ) { + continue; + } + + $accounts[] = array( + 'account_name' => $account_names[ $i ], + 'account_number' => $account_numbers[ $i ], + 'bank_name' => $bank_names[ $i ], + 'sort_code' => $sort_codes[ $i ], + 'iban' => $ibans[ $i ], + 'bic' => $bics[ $i ], + ); + } + } + // phpcs:enable + + update_option( 'woocommerce_bacs_accounts', $accounts ); + } + + /** + * Output for the order received page. + * + * @param int $order_id Order ID. + */ + public function thankyou_page( $order_id ) { + + if ( $this->instructions ) { + echo wp_kses_post( wpautop( wptexturize( wp_kses_post( $this->instructions ) ) ) ); + } + $this->bank_details( $order_id ); + + } + + /** + * Add content to the WC emails. + * + * @param WC_Order $order Order object. + * @param bool $sent_to_admin Sent to admin. + * @param bool $plain_text Email format: plain text or HTML. + */ + public function email_instructions( $order, $sent_to_admin, $plain_text = false ) { + + if ( ! $sent_to_admin && 'bacs' === $order->get_payment_method() && $order->has_status( 'on-hold' ) ) { + if ( $this->instructions ) { + echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) . PHP_EOL ); + } + $this->bank_details( $order->get_id() ); + } + + } + + /** + * Get bank details and place into a list format. + * + * @param int $order_id Order ID. + */ + private function bank_details( $order_id = '' ) { + + if ( empty( $this->account_details ) ) { + return; + } + + // Get order and store in $order. + $order = wc_get_order( $order_id ); + + // Get the order country and country $locale. + $country = $order->get_billing_country(); + $locale = $this->get_country_locale(); + + // Get sortcode label in the $locale array and use appropriate one. + $sortcode = isset( $locale[ $country ]['sortcode']['label'] ) ? $locale[ $country ]['sortcode']['label'] : __( 'Sort code', 'woocommerce' ); + + $bacs_accounts = apply_filters( 'woocommerce_bacs_accounts', $this->account_details, $order_id ); + + if ( ! empty( $bacs_accounts ) ) { + $account_html = ''; + $has_details = false; + + foreach ( $bacs_accounts as $bacs_account ) { + $bacs_account = (object) $bacs_account; + + if ( $bacs_account->account_name ) { + $account_html .= '' . PHP_EOL; + } + + $account_html .= '
      ' . PHP_EOL; + + // BACS account fields shown on the thanks page and in emails. + $account_fields = apply_filters( + 'woocommerce_bacs_account_fields', + array( + 'bank_name' => array( + 'label' => __( 'Bank', 'woocommerce' ), + 'value' => $bacs_account->bank_name, + ), + 'account_number' => array( + 'label' => __( 'Account number', 'woocommerce' ), + 'value' => $bacs_account->account_number, + ), + 'sort_code' => array( + 'label' => $sortcode, + 'value' => $bacs_account->sort_code, + ), + 'iban' => array( + 'label' => __( 'IBAN', 'woocommerce' ), + 'value' => $bacs_account->iban, + ), + 'bic' => array( + 'label' => __( 'BIC', 'woocommerce' ), + 'value' => $bacs_account->bic, + ), + ), + $order_id + ); + + foreach ( $account_fields as $field_key => $field ) { + if ( ! empty( $field['value'] ) ) { + $account_html .= '
    • ' . wp_kses_post( $field['label'] ) . ': ' . wp_kses_post( wptexturize( $field['value'] ) ) . '
    • ' . PHP_EOL; + $has_details = true; + } + } + + $account_html .= '
    '; + } + + if ( $has_details ) { + echo '

    ' . esc_html__( 'Our bank details', 'woocommerce' ) . '

    ' . wp_kses_post( PHP_EOL . $account_html ) . '
    '; + } + } + + } + + /** + * Process the payment and return the result. + * + * @param int $order_id Order ID. + * @return array + */ + public function process_payment( $order_id ) { + + $order = wc_get_order( $order_id ); + + if ( $order->get_total() > 0 ) { + // Mark as on-hold (we're awaiting the payment). + $order->update_status( apply_filters( 'woocommerce_bacs_process_payment_order_status', 'on-hold', $order ), __( 'Awaiting BACS payment', 'woocommerce' ) ); + } else { + $order->payment_complete(); + } + + // Remove cart. + WC()->cart->empty_cart(); + + // Return thankyou redirect. + return array( + 'result' => 'success', + 'redirect' => $this->get_return_url( $order ), + ); + + } + + /** + * Get country locale if localized. + * + * @return array + */ + public function get_country_locale() { + + if ( empty( $this->locale ) ) { + + // Locale information to be used - only those that are not 'Sort Code'. + $this->locale = apply_filters( + 'woocommerce_get_bacs_locale', + array( + 'AU' => array( + 'sortcode' => array( + 'label' => __( 'BSB', 'woocommerce' ), + ), + ), + 'CA' => array( + 'sortcode' => array( + 'label' => __( 'Bank transit number', 'woocommerce' ), + ), + ), + 'IN' => array( + 'sortcode' => array( + 'label' => __( 'IFSC', 'woocommerce' ), + ), + ), + 'IT' => array( + 'sortcode' => array( + 'label' => __( 'Branch sort', 'woocommerce' ), + ), + ), + 'NZ' => array( + 'sortcode' => array( + 'label' => __( 'Bank code', 'woocommerce' ), + ), + ), + 'SE' => array( + 'sortcode' => array( + 'label' => __( 'Bank code', 'woocommerce' ), + ), + ), + 'US' => array( + 'sortcode' => array( + 'label' => __( 'Routing number', 'woocommerce' ), + ), + ), + 'ZA' => array( + 'sortcode' => array( + 'label' => __( 'Branch code', 'woocommerce' ), + ), + ), + ) + ); + + } + + return $this->locale; + + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/cheque/class-wc-gateway-cheque.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/cheque/class-wc-gateway-cheque.php new file mode 100644 index 0000000..7f5d003 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/cheque/class-wc-gateway-cheque.php @@ -0,0 +1,136 @@ +id = 'cheque'; + $this->icon = apply_filters( 'woocommerce_cheque_icon', '' ); + $this->has_fields = false; + $this->method_title = _x( 'Check payments', 'Check payment method', 'woocommerce' ); + $this->method_description = __( 'Take payments in person via checks. This offline gateway can also be useful to test purchases.', 'woocommerce' ); + + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Define user set variables. + $this->title = $this->get_option( 'title' ); + $this->description = $this->get_option( 'description' ); + $this->instructions = $this->get_option( 'instructions' ); + + // Actions. + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_thankyou_cheque', array( $this, 'thankyou_page' ) ); + + // Customer Emails. + add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 ); + } + + /** + * Initialise Gateway Settings Form Fields. + */ + public function init_form_fields() { + + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable check payments', 'woocommerce' ), + 'default' => 'no', + ), + 'title' => array( + 'title' => __( 'Title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => _x( 'Check payments', 'Check payment method', 'woocommerce' ), + 'desc_tip' => true, + ), + 'description' => array( + 'title' => __( 'Description', 'woocommerce' ), + 'type' => 'textarea', + 'description' => __( 'Payment method description that the customer will see on your checkout.', 'woocommerce' ), + 'default' => __( 'Please send a check to Store Name, Store Street, Store Town, Store State / County, Store Postcode.', 'woocommerce' ), + 'desc_tip' => true, + ), + 'instructions' => array( + 'title' => __( 'Instructions', 'woocommerce' ), + 'type' => 'textarea', + 'description' => __( 'Instructions that will be added to the thank you page and emails.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + ), + ); + } + + /** + * Output for the order received page. + */ + public function thankyou_page() { + if ( $this->instructions ) { + echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) ); + } + } + + /** + * Add content to the WC emails. + * + * @access public + * @param WC_Order $order Order object. + * @param bool $sent_to_admin Sent to admin. + * @param bool $plain_text Email format: plain text or HTML. + */ + public function email_instructions( $order, $sent_to_admin, $plain_text = false ) { + if ( $this->instructions && ! $sent_to_admin && 'cheque' === $order->get_payment_method() && $order->has_status( 'on-hold' ) ) { + echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) . PHP_EOL ); + } + } + + /** + * Process the payment and return the result. + * + * @param int $order_id Order ID. + * @return array + */ + public function process_payment( $order_id ) { + + $order = wc_get_order( $order_id ); + + if ( $order->get_total() > 0 ) { + // Mark as on-hold (we're awaiting the cheque). + $order->update_status( apply_filters( 'woocommerce_cheque_process_payment_order_status', 'on-hold', $order ), _x( 'Awaiting check payment', 'Check payment method', 'woocommerce' ) ); + } else { + $order->payment_complete(); + } + + // Remove cart. + WC()->cart->empty_cart(); + + // Return thankyou redirect. + return array( + 'result' => 'success', + 'redirect' => $this->get_return_url( $order ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/class-wc-payment-gateway-cc.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/class-wc-payment-gateway-cc.php new file mode 100644 index 0000000..0ddd462 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/class-wc-payment-gateway-cc.php @@ -0,0 +1,99 @@ +supports( 'tokenization' ) && is_checkout() ) { + $this->tokenization_script(); + $this->saved_payment_methods(); + $this->form(); + $this->save_payment_method_checkbox(); + } else { + $this->form(); + } + } + + /** + * Output field name HTML + * + * Gateways which support tokenization do not require names - we don't want the data to post to the server. + * + * @since 2.6.0 + * @param string $name Field name. + * @return string + */ + public function field_name( $name ) { + return $this->supports( 'tokenization' ) ? '' : ' name="' . esc_attr( $this->id . '-' . $name ) . '" '; + } + + /** + * Outputs fields for entering credit card information. + * + * @since 2.6.0 + */ + public function form() { + wp_enqueue_script( 'wc-credit-card-form' ); + + $fields = array(); + + $cvc_field = '

    + + field_name( 'card-cvc' ) . ' style="width:100px" /> +

    '; + + $default_fields = array( + 'card-number-field' => '

    + + field_name( 'card-number' ) . ' /> +

    ', + 'card-expiry-field' => '

    + + field_name( 'card-expiry' ) . ' /> +

    ', + ); + + if ( ! $this->supports( 'credit_card_form_cvc_on_saved_method' ) ) { + $default_fields['card-cvc-field'] = $cvc_field; + } + + $fields = wp_parse_args( $fields, apply_filters( 'woocommerce_credit_card_form_fields', $default_fields, $this->id ) ); + ?> + +
    + id ); ?> + + id ); ?> +
    +
    + supports( 'credit_card_form_cvc_on_saved_method' ) ) { + echo '
    ' . $cvc_field . '
    '; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/class-wc-payment-gateway-echeck.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/class-wc-payment-gateway-echeck.php new file mode 100644 index 0000000..c7754b6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/class-wc-payment-gateway-echeck.php @@ -0,0 +1,71 @@ +supports( 'tokenization' ) && is_checkout() ) { + $this->tokenization_script(); + $this->saved_payment_methods(); + $this->form(); + $this->save_payment_method_checkbox(); + } else { + $this->form(); + } + } + + /** + * Outputs fields for entering eCheck information. + * + * @since 2.6.0 + */ + public function form() { + $fields = array(); + + $default_fields = array( + 'routing-number' => '

    + + +

    ', + 'account-number' => '

    + + +

    ', + ); + + $fields = wp_parse_args( $fields, apply_filters( 'woocommerce_echeck_form_fields', $default_fields, $this->id ) ); + ?> + +
    + id ); ?> + + id ); ?> +
    +
    + setup_properties(); + + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Get settings. + $this->title = $this->get_option( 'title' ); + $this->description = $this->get_option( 'description' ); + $this->instructions = $this->get_option( 'instructions' ); + $this->enable_for_methods = $this->get_option( 'enable_for_methods', array() ); + $this->enable_for_virtual = $this->get_option( 'enable_for_virtual', 'yes' ) === 'yes'; + + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) ); + add_filter( 'woocommerce_payment_complete_order_status', array( $this, 'change_payment_complete_order_status' ), 10, 3 ); + + // Customer Emails. + add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 ); + } + + /** + * Setup general properties for the gateway. + */ + protected function setup_properties() { + $this->id = 'cod'; + $this->icon = apply_filters( 'woocommerce_cod_icon', '' ); + $this->method_title = __( 'Cash on delivery', 'woocommerce' ); + $this->method_description = __( 'Have your customers pay with cash (or by other means) upon delivery.', 'woocommerce' ); + $this->has_fields = false; + } + + /** + * Initialise Gateway Settings Form Fields. + */ + public function init_form_fields() { + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'label' => __( 'Enable cash on delivery', 'woocommerce' ), + 'type' => 'checkbox', + 'description' => '', + 'default' => 'no', + ), + 'title' => array( + 'title' => __( 'Title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Payment method description that the customer will see on your checkout.', 'woocommerce' ), + 'default' => __( 'Cash on delivery', 'woocommerce' ), + 'desc_tip' => true, + ), + 'description' => array( + 'title' => __( 'Description', 'woocommerce' ), + 'type' => 'textarea', + 'description' => __( 'Payment method description that the customer will see on your website.', 'woocommerce' ), + 'default' => __( 'Pay with cash upon delivery.', 'woocommerce' ), + 'desc_tip' => true, + ), + 'instructions' => array( + 'title' => __( 'Instructions', 'woocommerce' ), + 'type' => 'textarea', + 'description' => __( 'Instructions that will be added to the thank you page.', 'woocommerce' ), + 'default' => __( 'Pay with cash upon delivery.', 'woocommerce' ), + 'desc_tip' => true, + ), + 'enable_for_methods' => array( + 'title' => __( 'Enable for shipping methods', 'woocommerce' ), + 'type' => 'multiselect', + 'class' => 'wc-enhanced-select', + 'css' => 'width: 400px;', + 'default' => '', + 'description' => __( 'If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', 'woocommerce' ), + 'options' => $this->load_shipping_method_options(), + 'desc_tip' => true, + 'custom_attributes' => array( + 'data-placeholder' => __( 'Select shipping methods', 'woocommerce' ), + ), + ), + 'enable_for_virtual' => array( + 'title' => __( 'Accept for virtual orders', 'woocommerce' ), + 'label' => __( 'Accept COD if the order is virtual', 'woocommerce' ), + 'type' => 'checkbox', + 'default' => 'yes', + ), + ); + } + + /** + * Check If The Gateway Is Available For Use. + * + * @return bool + */ + public function is_available() { + $order = null; + $needs_shipping = false; + + // Test if shipping is needed first. + if ( WC()->cart && WC()->cart->needs_shipping() ) { + $needs_shipping = true; + } elseif ( is_page( wc_get_page_id( 'checkout' ) ) && 0 < get_query_var( 'order-pay' ) ) { + $order_id = absint( get_query_var( 'order-pay' ) ); + $order = wc_get_order( $order_id ); + + // Test if order needs shipping. + if ( 0 < count( $order->get_items() ) ) { + foreach ( $order->get_items() as $item ) { + $_product = $item->get_product(); + if ( $_product && $_product->needs_shipping() ) { + $needs_shipping = true; + break; + } + } + } + } + + $needs_shipping = apply_filters( 'woocommerce_cart_needs_shipping', $needs_shipping ); + + // Virtual order, with virtual disabled. + if ( ! $this->enable_for_virtual && ! $needs_shipping ) { + return false; + } + + // Only apply if all packages are being shipped via chosen method, or order is virtual. + if ( ! empty( $this->enable_for_methods ) && $needs_shipping ) { + $order_shipping_items = is_object( $order ) ? $order->get_shipping_methods() : false; + $chosen_shipping_methods_session = WC()->session->get( 'chosen_shipping_methods' ); + + if ( $order_shipping_items ) { + $canonical_rate_ids = $this->get_canonical_order_shipping_item_rate_ids( $order_shipping_items ); + } else { + $canonical_rate_ids = $this->get_canonical_package_rate_ids( $chosen_shipping_methods_session ); + } + + if ( ! count( $this->get_matching_rates( $canonical_rate_ids ) ) ) { + return false; + } + } + + return parent::is_available(); + } + + /** + * Checks to see whether or not the admin settings are being accessed by the current request. + * + * @return bool + */ + private function is_accessing_settings() { + if ( is_admin() ) { + // phpcs:disable WordPress.Security.NonceVerification + if ( ! isset( $_REQUEST['page'] ) || 'wc-settings' !== $_REQUEST['page'] ) { + return false; + } + if ( ! isset( $_REQUEST['tab'] ) || 'checkout' !== $_REQUEST['tab'] ) { + return false; + } + if ( ! isset( $_REQUEST['section'] ) || 'cod' !== $_REQUEST['section'] ) { + return false; + } + // phpcs:enable WordPress.Security.NonceVerification + + return true; + } + + if ( Constants::is_true( 'REST_REQUEST' ) ) { + global $wp; + if ( isset( $wp->query_vars['rest_route'] ) && false !== strpos( $wp->query_vars['rest_route'], '/payment_gateways' ) ) { + return true; + } + } + + return false; + } + + /** + * Loads all of the shipping method options for the enable_for_methods field. + * + * @return array + */ + private function load_shipping_method_options() { + // Since this is expensive, we only want to do it if we're actually on the settings page. + if ( ! $this->is_accessing_settings() ) { + return array(); + } + + $data_store = WC_Data_Store::load( 'shipping-zone' ); + $raw_zones = $data_store->get_zones(); + + foreach ( $raw_zones as $raw_zone ) { + $zones[] = new WC_Shipping_Zone( $raw_zone ); + } + + $zones[] = new WC_Shipping_Zone( 0 ); + + $options = array(); + foreach ( WC()->shipping()->load_shipping_methods() as $method ) { + + $options[ $method->get_method_title() ] = array(); + + // Translators: %1$s shipping method name. + $options[ $method->get_method_title() ][ $method->id ] = sprintf( __( 'Any "%1$s" method', 'woocommerce' ), $method->get_method_title() ); + + foreach ( $zones as $zone ) { + + $shipping_method_instances = $zone->get_shipping_methods(); + + foreach ( $shipping_method_instances as $shipping_method_instance_id => $shipping_method_instance ) { + + if ( $shipping_method_instance->id !== $method->id ) { + continue; + } + + $option_id = $shipping_method_instance->get_rate_id(); + + // Translators: %1$s shipping method title, %2$s shipping method id. + $option_instance_title = sprintf( __( '%1$s (#%2$s)', 'woocommerce' ), $shipping_method_instance->get_title(), $shipping_method_instance_id ); + + // Translators: %1$s zone name, %2$s shipping method instance name. + $option_title = sprintf( __( '%1$s – %2$s', 'woocommerce' ), $zone->get_id() ? $zone->get_zone_name() : __( 'Other locations', 'woocommerce' ), $option_instance_title ); + + $options[ $method->get_method_title() ][ $option_id ] = $option_title; + } + } + } + + return $options; + } + + /** + * Converts the chosen rate IDs generated by Shipping Methods to a canonical 'method_id:instance_id' format. + * + * @since 3.4.0 + * + * @param array $order_shipping_items Array of WC_Order_Item_Shipping objects. + * @return array $canonical_rate_ids Rate IDs in a canonical format. + */ + private function get_canonical_order_shipping_item_rate_ids( $order_shipping_items ) { + + $canonical_rate_ids = array(); + + foreach ( $order_shipping_items as $order_shipping_item ) { + $canonical_rate_ids[] = $order_shipping_item->get_method_id() . ':' . $order_shipping_item->get_instance_id(); + } + + return $canonical_rate_ids; + } + + /** + * Converts the chosen rate IDs generated by Shipping Methods to a canonical 'method_id:instance_id' format. + * + * @since 3.4.0 + * + * @param array $chosen_package_rate_ids Rate IDs as generated by shipping methods. Can be anything if a shipping method doesn't honor WC conventions. + * @return array $canonical_rate_ids Rate IDs in a canonical format. + */ + private function get_canonical_package_rate_ids( $chosen_package_rate_ids ) { + + $shipping_packages = WC()->shipping()->get_packages(); + $canonical_rate_ids = array(); + + if ( ! empty( $chosen_package_rate_ids ) && is_array( $chosen_package_rate_ids ) ) { + foreach ( $chosen_package_rate_ids as $package_key => $chosen_package_rate_id ) { + if ( ! empty( $shipping_packages[ $package_key ]['rates'][ $chosen_package_rate_id ] ) ) { + $chosen_rate = $shipping_packages[ $package_key ]['rates'][ $chosen_package_rate_id ]; + $canonical_rate_ids[] = $chosen_rate->get_method_id() . ':' . $chosen_rate->get_instance_id(); + } + } + } + + return $canonical_rate_ids; + } + + /** + * Indicates whether a rate exists in an array of canonically-formatted rate IDs that activates this gateway. + * + * @since 3.4.0 + * + * @param array $rate_ids Rate ids to check. + * @return boolean + */ + private function get_matching_rates( $rate_ids ) { + // First, match entries in 'method_id:instance_id' format. Then, match entries in 'method_id' format by stripping off the instance ID from the candidates. + return array_unique( array_merge( array_intersect( $this->enable_for_methods, $rate_ids ), array_intersect( $this->enable_for_methods, array_unique( array_map( 'wc_get_string_before_colon', $rate_ids ) ) ) ) ); + } + + /** + * Process the payment and return the result. + * + * @param int $order_id Order ID. + * @return array + */ + public function process_payment( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( $order->get_total() > 0 ) { + // Mark as processing or on-hold (payment won't be taken until delivery). + $order->update_status( apply_filters( 'woocommerce_cod_process_payment_order_status', $order->has_downloadable_item() ? 'on-hold' : 'processing', $order ), __( 'Payment to be made upon delivery.', 'woocommerce' ) ); + } else { + $order->payment_complete(); + } + + // Remove cart. + WC()->cart->empty_cart(); + + // Return thankyou redirect. + return array( + 'result' => 'success', + 'redirect' => $this->get_return_url( $order ), + ); + } + + /** + * Output for the order received page. + */ + public function thankyou_page() { + if ( $this->instructions ) { + echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) ); + } + } + + /** + * Change payment complete order status to completed for COD orders. + * + * @since 3.1.0 + * @param string $status Current order status. + * @param int $order_id Order ID. + * @param WC_Order|false $order Order object. + * @return string + */ + public function change_payment_complete_order_status( $status, $order_id = 0, $order = false ) { + if ( $order && 'cod' === $order->get_payment_method() ) { + $status = 'completed'; + } + return $status; + } + + /** + * Add content to the WC emails. + * + * @param WC_Order $order Order object. + * @param bool $sent_to_admin Sent to admin. + * @param bool $plain_text Email format: plain text or HTML. + */ + public function email_instructions( $order, $sent_to_admin, $plain_text = false ) { + if ( $this->instructions && ! $sent_to_admin && $this->id === $order->get_payment_method() ) { + echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) . PHP_EOL ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/assets/images/paypal.png b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/assets/images/paypal.png new file mode 100644 index 0000000..f2e57a2 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/assets/images/paypal.png differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.js new file mode 100644 index 0000000..705d0aa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.js @@ -0,0 +1,46 @@ +jQuery( function( $ ) { + 'use strict'; + + /** + * Object to handle PayPal admin functions. + */ + var wc_paypal_admin = { + isTestMode: function() { + return $( '#woocommerce_paypal_testmode' ).is( ':checked' ); + }, + + /** + * Initialize. + */ + init: function() { + $( document.body ).on( 'change', '#woocommerce_paypal_testmode', function() { + var test_api_username = $( '#woocommerce_paypal_sandbox_api_username' ).parents( 'tr' ).eq( 0 ), + test_api_password = $( '#woocommerce_paypal_sandbox_api_password' ).parents( 'tr' ).eq( 0 ), + test_api_signature = $( '#woocommerce_paypal_sandbox_api_signature' ).parents( 'tr' ).eq( 0 ), + live_api_username = $( '#woocommerce_paypal_api_username' ).parents( 'tr' ).eq( 0 ), + live_api_password = $( '#woocommerce_paypal_api_password' ).parents( 'tr' ).eq( 0 ), + live_api_signature = $( '#woocommerce_paypal_api_signature' ).parents( 'tr' ).eq( 0 ); + + if ( $( this ).is( ':checked' ) ) { + test_api_username.show(); + test_api_password.show(); + test_api_signature.show(); + live_api_username.hide(); + live_api_password.hide(); + live_api_signature.hide(); + } else { + test_api_username.hide(); + test_api_password.hide(); + test_api_signature.hide(); + live_api_username.show(); + live_api_password.show(); + live_api_signature.show(); + } + } ); + + $( '#woocommerce_paypal_testmode' ).change(); + } + }; + + wc_paypal_admin.init(); +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.min.js new file mode 100644 index 0000000..24ad802 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.min.js @@ -0,0 +1 @@ +jQuery(function($){'use strict';var wc_paypal_admin={isTestMode:function(){return $('#woocommerce_paypal_testmode').is(':checked')},init:function(){$(document.body).on('change','#woocommerce_paypal_testmode',function(){var test_api_username=$('#woocommerce_paypal_sandbox_api_username').parents('tr').eq(0),test_api_password=$('#woocommerce_paypal_sandbox_api_password').parents('tr').eq(0),test_api_signature=$('#woocommerce_paypal_sandbox_api_signature').parents('tr').eq(0),live_api_username=$('#woocommerce_paypal_api_username').parents('tr').eq(0),live_api_password=$('#woocommerce_paypal_api_password').parents('tr').eq(0),live_api_signature=$('#woocommerce_paypal_api_signature').parents('tr').eq(0);if($(this).is(':checked')){test_api_username.show();test_api_password.show();test_api_signature.show();live_api_username.hide();live_api_password.hide();live_api_signature.hide()}else{test_api_username.hide();test_api_password.hide();test_api_signature.hide();live_api_username.show();live_api_password.show();live_api_signature.show()}});$('#woocommerce_paypal_testmode').change()}};wc_paypal_admin.init()}) \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php new file mode 100644 index 0000000..68a8095 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php @@ -0,0 +1,476 @@ +id = 'paypal'; + $this->has_fields = false; + $this->order_button_text = __( 'Proceed to PayPal', 'woocommerce' ); + $this->method_title = __( 'PayPal Standard', 'woocommerce' ); + /* translators: %s: Link to WC system status page */ + $this->method_description = __( 'PayPal Standard redirects customers to PayPal to enter their payment information.', 'woocommerce' ); + $this->supports = array( + 'products', + 'refunds', + ); + + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Define user set variables. + $this->title = $this->get_option( 'title' ); + $this->description = $this->get_option( 'description' ); + $this->testmode = 'yes' === $this->get_option( 'testmode', 'no' ); + $this->debug = 'yes' === $this->get_option( 'debug', 'no' ); + $this->email = $this->get_option( 'email' ); + $this->receiver_email = $this->get_option( 'receiver_email', $this->email ); + $this->identity_token = $this->get_option( 'identity_token' ); + self::$log_enabled = $this->debug; + + if ( $this->testmode ) { + /* translators: %s: Link to PayPal sandbox testing guide page */ + $this->description .= ' ' . sprintf( __( 'SANDBOX ENABLED. You can use sandbox testing accounts only. See the PayPal Sandbox Testing Guide for more details.', 'woocommerce' ), 'https://developer.paypal.com/docs/classic/lifecycle/ug_sandbox/' ); + $this->description = trim( $this->description ); + } + + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_order_status_processing', array( $this, 'capture_payment' ) ); + add_action( 'woocommerce_order_status_completed', array( $this, 'capture_payment' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) ); + + if ( ! $this->is_valid_for_use() ) { + $this->enabled = 'no'; + } else { + include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-ipn-handler.php'; + new WC_Gateway_Paypal_IPN_Handler( $this->testmode, $this->receiver_email ); + + if ( $this->identity_token ) { + include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-pdt-handler.php'; + new WC_Gateway_Paypal_PDT_Handler( $this->testmode, $this->identity_token ); + } + } + + if ( 'yes' === $this->enabled ) { + add_filter( 'woocommerce_thankyou_order_received_text', array( $this, 'order_received_text' ), 10, 2 ); + } + } + + /** + * Return whether or not this gateway still requires setup to function. + * + * When this gateway is toggled on via AJAX, if this returns true a + * redirect will occur to the settings page instead. + * + * @since 3.4.0 + * @return bool + */ + public function needs_setup() { + return ! is_email( $this->email ); + } + + /** + * Logging method. + * + * @param string $message Log message. + * @param string $level Optional. Default 'info'. Possible values: + * emergency|alert|critical|error|warning|notice|info|debug. + */ + public static function log( $message, $level = 'info' ) { + if ( self::$log_enabled ) { + if ( empty( self::$log ) ) { + self::$log = wc_get_logger(); + } + self::$log->log( $level, $message, array( 'source' => 'paypal' ) ); + } + } + + /** + * Processes and saves options. + * If there is an error thrown, will continue to save and validate fields, but will leave the erroring field out. + * + * @return bool was anything saved? + */ + public function process_admin_options() { + $saved = parent::process_admin_options(); + + // Maybe clear logs. + if ( 'yes' !== $this->get_option( 'debug', 'no' ) ) { + if ( empty( self::$log ) ) { + self::$log = wc_get_logger(); + } + self::$log->clear( 'paypal' ); + } + + return $saved; + } + + /** + * Get gateway icon. + * + * @return string + */ + public function get_icon() { + // We need a base country for the link to work, bail if in the unlikely event no country is set. + $base_country = WC()->countries->get_base_country(); + if ( empty( $base_country ) ) { + return ''; + } + $icon_html = ''; + $icon = (array) $this->get_icon_image( $base_country ); + + foreach ( $icon as $i ) { + $icon_html .= '' . esc_attr__( 'PayPal acceptance mark', 'woocommerce' ) . ''; + } + + $icon_html .= sprintf( '' . esc_attr__( 'What is PayPal?', 'woocommerce' ) . '', esc_url( $this->get_icon_url( $base_country ) ) ); + + return apply_filters( 'woocommerce_gateway_icon', $icon_html, $this->id ); + } + + /** + * Get the link for an icon based on country. + * + * @param string $country Country two letter code. + * @return string + */ + protected function get_icon_url( $country ) { + $url = 'https://www.paypal.com/' . strtolower( $country ); + $home_counties = array( 'BE', 'CZ', 'DK', 'HU', 'IT', 'JP', 'NL', 'NO', 'ES', 'SE', 'TR', 'IN' ); + $countries = array( 'DZ', 'AU', 'BH', 'BQ', 'BW', 'CA', 'CN', 'CW', 'FI', 'FR', 'DE', 'GR', 'HK', 'ID', 'JO', 'KE', 'KW', 'LU', 'MY', 'MA', 'OM', 'PH', 'PL', 'PT', 'QA', 'IE', 'RU', 'BL', 'SX', 'MF', 'SA', 'SG', 'SK', 'KR', 'SS', 'TW', 'TH', 'AE', 'GB', 'US', 'VN' ); + + if ( in_array( $country, $home_counties, true ) ) { + return $url . '/webapps/mpp/home'; + } elseif ( in_array( $country, $countries, true ) ) { + return $url . '/webapps/mpp/paypal-popup'; + } else { + return $url . '/cgi-bin/webscr?cmd=xpt/Marketing/general/WIPaypal-outside'; + } + } + + /** + * Get PayPal images for a country. + * + * @param string $country Country code. + * @return array of image URLs + */ + protected function get_icon_image( $country ) { + switch ( $country ) { + case 'US': + case 'NZ': + case 'CZ': + case 'HU': + case 'MY': + $icon = 'https://www.paypalobjects.com/webstatic/mktg/logo/AM_mc_vs_dc_ae.jpg'; + break; + case 'TR': + $icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_paypal_odeme_secenekleri.jpg'; + break; + case 'GB': + $icon = 'https://www.paypalobjects.com/webstatic/mktg/Logo/AM_mc_vs_ms_ae_UK.png'; + break; + case 'MX': + $icon = array( + 'https://www.paypal.com/es_XC/Marketing/i/banner/paypal_visa_mastercard_amex.png', + 'https://www.paypal.com/es_XC/Marketing/i/banner/paypal_debit_card_275x60.gif', + ); + break; + case 'FR': + $icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_paypal_moyens_paiement_fr.jpg'; + break; + case 'AU': + $icon = 'https://www.paypalobjects.com/webstatic/en_AU/mktg/logo/Solutions-graphics-1-184x80.jpg'; + break; + case 'DK': + $icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/logo_PayPal_betalingsmuligheder_dk.jpg'; + break; + case 'RU': + $icon = 'https://www.paypalobjects.com/webstatic/ru_RU/mktg/business/pages/logo-center/AM_mc_vs_dc_ae.jpg'; + break; + case 'NO': + $icon = 'https://www.paypalobjects.com/webstatic/mktg/logo-center/banner_pl_just_pp_319x110.jpg'; + break; + case 'CA': + $icon = 'https://www.paypalobjects.com/webstatic/en_CA/mktg/logo-image/AM_mc_vs_dc_ae.jpg'; + break; + case 'HK': + $icon = 'https://www.paypalobjects.com/webstatic/en_HK/mktg/logo/AM_mc_vs_dc_ae.jpg'; + break; + case 'SG': + $icon = 'https://www.paypalobjects.com/webstatic/en_SG/mktg/Logos/AM_mc_vs_dc_ae.jpg'; + break; + case 'TW': + $icon = 'https://www.paypalobjects.com/webstatic/en_TW/mktg/logos/AM_mc_vs_dc_ae.jpg'; + break; + case 'TH': + $icon = 'https://www.paypalobjects.com/webstatic/en_TH/mktg/Logos/AM_mc_vs_dc_ae.jpg'; + break; + case 'JP': + $icon = 'https://www.paypal.com/ja_JP/JP/i/bnr/horizontal_solution_4_jcb.gif'; + break; + case 'IN': + $icon = 'https://www.paypalobjects.com/webstatic/mktg/logo/AM_mc_vs_dc_ae.jpg'; + break; + default: + $icon = WC_HTTPS::force_https_url( WC()->plugin_url() . '/includes/gateways/paypal/assets/images/paypal.png' ); + break; + } + return apply_filters( 'woocommerce_paypal_icon', $icon ); + } + + /** + * Check if this gateway is available in the user's country based on currency. + * + * @return bool + */ + public function is_valid_for_use() { + return in_array( + get_woocommerce_currency(), + apply_filters( + 'woocommerce_paypal_supported_currencies', + array( 'AUD', 'BRL', 'CAD', 'MXN', 'NZD', 'HKD', 'SGD', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'CZK', 'DKK', 'HUF', 'ILS', 'MYR', 'PHP', 'PLN', 'SEK', 'CHF', 'TWD', 'THB', 'GBP', 'RMB', 'RUB', 'INR' ) + ), + true + ); + } + + /** + * Admin Panel Options. + * - Options for bits like 'title' and availability on a country-by-country basis. + * + * @since 1.0.0 + */ + public function admin_options() { + if ( $this->is_valid_for_use() ) { + parent::admin_options(); + } else { + ?> +
    +

    + : +

    +
    + form_fields = include __DIR__ . '/includes/settings-paypal.php'; + } + + /** + * Get the transaction URL. + * + * @param WC_Order $order Order object. + * @return string + */ + public function get_transaction_url( $order ) { + if ( $this->testmode ) { + $this->view_transaction_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s'; + } else { + $this->view_transaction_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s'; + } + return parent::get_transaction_url( $order ); + } + + /** + * Process the payment and return the result. + * + * @param int $order_id Order ID. + * @return array + */ + public function process_payment( $order_id ) { + include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-request.php'; + + $order = wc_get_order( $order_id ); + $paypal_request = new WC_Gateway_Paypal_Request( $this ); + + return array( + 'result' => 'success', + 'redirect' => $paypal_request->get_request_url( $order, $this->testmode ), + ); + } + + /** + * Can the order be refunded via PayPal? + * + * @param WC_Order $order Order object. + * @return bool + */ + public function can_refund_order( $order ) { + $has_api_creds = false; + + if ( $this->testmode ) { + $has_api_creds = $this->get_option( 'sandbox_api_username' ) && $this->get_option( 'sandbox_api_password' ) && $this->get_option( 'sandbox_api_signature' ); + } else { + $has_api_creds = $this->get_option( 'api_username' ) && $this->get_option( 'api_password' ) && $this->get_option( 'api_signature' ); + } + + return $order && $order->get_transaction_id() && $has_api_creds; + } + + /** + * Init the API class and set the username/password etc. + */ + protected function init_api() { + include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-api-handler.php'; + + WC_Gateway_Paypal_API_Handler::$api_username = $this->testmode ? $this->get_option( 'sandbox_api_username' ) : $this->get_option( 'api_username' ); + WC_Gateway_Paypal_API_Handler::$api_password = $this->testmode ? $this->get_option( 'sandbox_api_password' ) : $this->get_option( 'api_password' ); + WC_Gateway_Paypal_API_Handler::$api_signature = $this->testmode ? $this->get_option( 'sandbox_api_signature' ) : $this->get_option( 'api_signature' ); + WC_Gateway_Paypal_API_Handler::$sandbox = $this->testmode; + } + + /** + * Process a refund if supported. + * + * @param int $order_id Order ID. + * @param float $amount Refund amount. + * @param string $reason Refund reason. + * @return bool|WP_Error + */ + public function process_refund( $order_id, $amount = null, $reason = '' ) { + $order = wc_get_order( $order_id ); + + if ( ! $this->can_refund_order( $order ) ) { + return new WP_Error( 'error', __( 'Refund failed.', 'woocommerce' ) ); + } + + $this->init_api(); + + $result = WC_Gateway_Paypal_API_Handler::refund_transaction( $order, $amount, $reason ); + + if ( is_wp_error( $result ) ) { + $this->log( 'Refund Failed: ' . $result->get_error_message(), 'error' ); + return new WP_Error( 'error', $result->get_error_message() ); + } + + $this->log( 'Refund Result: ' . wc_print_r( $result, true ) ); + + switch ( strtolower( $result->ACK ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + case 'success': + case 'successwithwarning': + $order->add_order_note( + /* translators: 1: Refund amount, 2: Refund ID */ + sprintf( __( 'Refunded %1$s - Refund ID: %2$s', 'woocommerce' ), $result->GROSSREFUNDAMT, $result->REFUNDTRANSACTIONID ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + ); + return true; + } + + return isset( $result->L_LONGMESSAGE0 ) ? new WP_Error( 'error', $result->L_LONGMESSAGE0 ) : false; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + } + + /** + * Capture payment when the order is changed from on-hold to complete or processing + * + * @param int $order_id Order ID. + */ + public function capture_payment( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( 'paypal' === $order->get_payment_method() && 'pending' === $order->get_meta( '_paypal_status', true ) && $order->get_transaction_id() ) { + $this->init_api(); + $result = WC_Gateway_Paypal_API_Handler::do_capture( $order ); + + if ( is_wp_error( $result ) ) { + $this->log( 'Capture Failed: ' . $result->get_error_message(), 'error' ); + /* translators: %s: Paypal gateway error message */ + $order->add_order_note( sprintf( __( 'Payment could not be captured: %s', 'woocommerce' ), $result->get_error_message() ) ); + return; + } + + $this->log( 'Capture Result: ' . wc_print_r( $result, true ) ); + + // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + if ( ! empty( $result->PAYMENTSTATUS ) ) { + switch ( $result->PAYMENTSTATUS ) { + case 'Completed': + /* translators: 1: Amount, 2: Authorization ID, 3: Transaction ID */ + $order->add_order_note( sprintf( __( 'Payment of %1$s was captured - Auth ID: %2$s, Transaction ID: %3$s', 'woocommerce' ), $result->AMT, $result->AUTHORIZATIONID, $result->TRANSACTIONID ) ); + update_post_meta( $order->get_id(), '_paypal_status', $result->PAYMENTSTATUS ); + update_post_meta( $order->get_id(), '_transaction_id', $result->TRANSACTIONID ); + break; + default: + /* translators: 1: Authorization ID, 2: Payment status */ + $order->add_order_note( sprintf( __( 'Payment could not be captured - Auth ID: %1$s, Status: %2$s', 'woocommerce' ), $result->AUTHORIZATIONID, $result->PAYMENTSTATUS ) ); + break; + } + } + // phpcs:enable + } + } + + /** + * Load admin scripts. + * + * @since 3.3.0 + */ + public function admin_scripts() { + $screen = get_current_screen(); + $screen_id = $screen ? $screen->id : ''; + + if ( 'woocommerce_page_wc-settings' !== $screen_id ) { + return; + } + + $suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min'; + $version = Constants::get_constant( 'WC_VERSION' ); + + wp_enqueue_script( 'woocommerce_paypal_admin', WC()->plugin_url() . '/includes/gateways/paypal/assets/js/paypal-admin' . $suffix . '.js', array(), $version, true ); + } + + /** + * Custom PayPal order received text. + * + * @since 3.9.0 + * @param string $text Default text. + * @param WC_Order $order Order data. + * @return string + */ + public function order_received_text( $text, $order ) { + if ( $order && $this->id === $order->get_payment_method() ) { + return esc_html__( 'Thank you for your payment. Your transaction has been completed, and a receipt for your purchase has been emailed to you. Log into your PayPal account to view transaction details.', 'woocommerce' ); + } + + return $text; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php new file mode 100644 index 0000000..6d012d4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php @@ -0,0 +1,202 @@ + '84.0', + 'SIGNATURE' => self::$api_signature, + 'USER' => self::$api_username, + 'PWD' => self::$api_password, + 'METHOD' => 'DoCapture', + 'AUTHORIZATIONID' => $order->get_transaction_id(), + 'AMT' => number_format( is_null( $amount ) ? $order->get_total() : $amount, 2, '.', '' ), + 'CURRENCYCODE' => $order->get_currency(), + 'COMPLETETYPE' => 'Complete', + ); + return apply_filters( 'woocommerce_paypal_capture_request', $request, $order, $amount ); + } + + /** + * Get refund request args. + * + * @param WC_Order $order Order object. + * @param float $amount Refund amount. + * @param string $reason Refund reason. + * @return array + */ + public static function get_refund_request( $order, $amount = null, $reason = '' ) { + $request = array( + 'VERSION' => '84.0', + 'SIGNATURE' => self::$api_signature, + 'USER' => self::$api_username, + 'PWD' => self::$api_password, + 'METHOD' => 'RefundTransaction', + 'TRANSACTIONID' => $order->get_transaction_id(), + 'NOTE' => html_entity_decode( wc_trim_string( $reason, 255 ), ENT_NOQUOTES, 'UTF-8' ), + 'REFUNDTYPE' => 'Full', + ); + if ( ! is_null( $amount ) ) { + $request['AMT'] = number_format( $amount, 2, '.', '' ); + $request['CURRENCYCODE'] = $order->get_currency(); + $request['REFUNDTYPE'] = 'Partial'; + } + return apply_filters( 'woocommerce_paypal_refund_request', $request, $order, $amount, $reason ); + } + + /** + * Capture an authorization. + * + * @param WC_Order $order Order object. + * @param float $amount Amount. + * @return object Either an object of name value pairs for a success, or a WP_ERROR object. + */ + public static function do_capture( $order, $amount = null ) { + $raw_response = wp_safe_remote_post( + self::$sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp', + array( + 'method' => 'POST', + 'body' => self::get_capture_request( $order, $amount ), + 'timeout' => 70, + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', + ) + ); + + WC_Gateway_Paypal::log( 'DoCapture Response: ' . wc_print_r( $raw_response, true ) ); + + if ( is_wp_error( $raw_response ) ) { + return $raw_response; + } elseif ( empty( $raw_response['body'] ) ) { + return new WP_Error( 'paypal-api', 'Empty Response' ); + } + + parse_str( $raw_response['body'], $response ); + + return (object) $response; + } + + /** + * Refund an order via PayPal. + * + * @param WC_Order $order Order object. + * @param float $amount Refund amount. + * @param string $reason Refund reason. + * @return object Either an object of name value pairs for a success, or a WP_ERROR object. + */ + public static function refund_transaction( $order, $amount = null, $reason = '' ) { + $raw_response = wp_safe_remote_post( + self::$sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp', + array( + 'method' => 'POST', + 'body' => self::get_refund_request( $order, $amount, $reason ), + 'timeout' => 70, + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', + ) + ); + + WC_Gateway_Paypal::log( 'Refund Response: ' . wc_print_r( $raw_response, true ) ); + + if ( is_wp_error( $raw_response ) ) { + return $raw_response; + } elseif ( empty( $raw_response['body'] ) ) { + return new WP_Error( 'paypal-api', 'Empty Response' ); + } + + parse_str( $raw_response['body'], $response ); + + return (object) $response; + } +} + +/** + * Here for backwards compatibility. + * + * @since 3.0.0 + */ +class WC_Gateway_Paypal_Refund extends WC_Gateway_Paypal_API_Handler { + /** + * Get refund request args. Proxy to WC_Gateway_Paypal_API_Handler::get_refund_request(). + * + * @param WC_Order $order Order object. + * @param float $amount Refund amount. + * @param string $reason Refund reason. + * + * @return array + */ + public static function get_request( $order, $amount = null, $reason = '' ) { + return self::get_refund_request( $order, $amount, $reason ); + } + + /** + * Process an order refund. + * + * @param WC_Order $order Order object. + * @param float $amount Refund amount. + * @param string $reason Refund reason. + * @param bool $sandbox Whether to use sandbox mode or not. + * @return object Either an object of name value pairs for a success, or a WP_ERROR object. + */ + public static function refund_order( $order, $amount = null, $reason = '', $sandbox = false ) { + if ( $sandbox ) { + self::$sandbox = $sandbox; + } + $result = self::refund_transaction( $order, $amount, $reason ); + if ( is_wp_error( $result ) ) { + return $result; + } else { + return (array) $result; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php new file mode 100644 index 0000000..b98b8ee --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php @@ -0,0 +1,376 @@ +receiver_email = $receiver_email; + $this->sandbox = $sandbox; + } + + /** + * Check for PayPal IPN Response. + */ + public function check_response() { + if ( ! empty( $_POST ) && $this->validate_ipn() ) { // WPCS: CSRF ok. + $posted = wp_unslash( $_POST ); // WPCS: CSRF ok, input var ok. + + // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + do_action( 'valid-paypal-standard-ipn-request', $posted ); + exit; + } + + wp_die( 'PayPal IPN Request Failure', 'PayPal IPN', array( 'response' => 500 ) ); + } + + /** + * There was a valid response. + * + * @param array $posted Post data after wp_unslash. + */ + public function valid_response( $posted ) { + $order = ! empty( $posted['custom'] ) ? $this->get_paypal_order( $posted['custom'] ) : false; + + if ( $order ) { + + // Lowercase returned variables. + $posted['payment_status'] = strtolower( $posted['payment_status'] ); + + WC_Gateway_Paypal::log( 'Found order #' . $order->get_id() ); + WC_Gateway_Paypal::log( 'Payment status: ' . $posted['payment_status'] ); + + if ( method_exists( $this, 'payment_status_' . $posted['payment_status'] ) ) { + call_user_func( array( $this, 'payment_status_' . $posted['payment_status'] ), $order, $posted ); + } + } + } + + /** + * Check PayPal IPN validity. + */ + public function validate_ipn() { + WC_Gateway_Paypal::log( 'Checking IPN response is valid' ); + + // Get received values from post data. + $validate_ipn = wp_unslash( $_POST ); // WPCS: CSRF ok, input var ok. + $validate_ipn['cmd'] = '_notify-validate'; + + // Send back post vars to paypal. + $params = array( + 'body' => $validate_ipn, + 'timeout' => 60, + 'httpversion' => '1.1', + 'compress' => false, + 'decompress' => false, + 'user-agent' => 'WooCommerce/' . WC()->version, + ); + + // Post back to get a response. + $response = wp_safe_remote_post( $this->sandbox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr', $params ); + + WC_Gateway_Paypal::log( 'IPN Response: ' . wc_print_r( $response, true ) ); + + // Check to see if the request was valid. + if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && strstr( $response['body'], 'VERIFIED' ) ) { + WC_Gateway_Paypal::log( 'Received valid response from PayPal IPN' ); + return true; + } + + WC_Gateway_Paypal::log( 'Received invalid response from PayPal IPN' ); + + if ( is_wp_error( $response ) ) { + WC_Gateway_Paypal::log( 'Error response: ' . $response->get_error_message() ); + } + + return false; + } + + /** + * Check for a valid transaction type. + * + * @param string $txn_type Transaction type. + */ + protected function validate_transaction_type( $txn_type ) { + $accepted_types = array( 'cart', 'instant', 'express_checkout', 'web_accept', 'masspay', 'send_money', 'paypal_here' ); + + if ( ! in_array( strtolower( $txn_type ), $accepted_types, true ) ) { + WC_Gateway_Paypal::log( 'Aborting, Invalid type:' . $txn_type ); + exit; + } + } + + /** + * Check currency from IPN matches the order. + * + * @param WC_Order $order Order object. + * @param string $currency Currency code. + */ + protected function validate_currency( $order, $currency ) { + if ( $order->get_currency() !== $currency ) { + WC_Gateway_Paypal::log( 'Payment error: Currencies do not match (sent "' . $order->get_currency() . '" | returned "' . $currency . '")' ); + + /* translators: %s: currency code. */ + $order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal currencies do not match (code %s).', 'woocommerce' ), $currency ) ); + exit; + } + } + + /** + * Check payment amount from IPN matches the order. + * + * @param WC_Order $order Order object. + * @param int $amount Amount to validate. + */ + protected function validate_amount( $order, $amount ) { + if ( number_format( $order->get_total(), 2, '.', '' ) !== number_format( $amount, 2, '.', '' ) ) { + WC_Gateway_Paypal::log( 'Payment error: Amounts do not match (gross ' . $amount . ')' ); + + /* translators: %s: Amount. */ + $order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal amounts do not match (gross %s).', 'woocommerce' ), $amount ) ); + exit; + } + } + + /** + * Check receiver email from PayPal. If the receiver email in the IPN is different than what is stored in. + * WooCommerce -> Settings -> Checkout -> PayPal, it will log an error about it. + * + * @param WC_Order $order Order object. + * @param string $receiver_email Email to validate. + */ + protected function validate_receiver_email( $order, $receiver_email ) { + if ( strcasecmp( trim( $receiver_email ), trim( $this->receiver_email ) ) !== 0 ) { + WC_Gateway_Paypal::log( "IPN Response is for another account: {$receiver_email}. Your email is {$this->receiver_email}" ); + + /* translators: %s: email address . */ + $order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal IPN response from a different email address (%s).', 'woocommerce' ), $receiver_email ) ); + exit; + } + } + + /** + * Handle a completed payment. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_completed( $order, $posted ) { + if ( $order->has_status( wc_get_is_paid_statuses() ) ) { + WC_Gateway_Paypal::log( 'Aborting, Order #' . $order->get_id() . ' is already complete.' ); + exit; + } + + $this->validate_transaction_type( $posted['txn_type'] ); + $this->validate_currency( $order, $posted['mc_currency'] ); + $this->validate_amount( $order, $posted['mc_gross'] ); + $this->validate_receiver_email( $order, $posted['receiver_email'] ); + $this->save_paypal_meta_data( $order, $posted ); + + if ( 'completed' === $posted['payment_status'] ) { + if ( $order->has_status( 'cancelled' ) ) { + $this->payment_status_paid_cancelled_order( $order, $posted ); + } + + if ( ! empty( $posted['mc_fee'] ) ) { + $order->add_meta_data( 'PayPal Transaction Fee', wc_clean( $posted['mc_fee'] ) ); + } + + $this->payment_complete( $order, ( ! empty( $posted['txn_id'] ) ? wc_clean( $posted['txn_id'] ) : '' ), __( 'IPN payment completed', 'woocommerce' ) ); + } else { + if ( 'authorization' === $posted['pending_reason'] ) { + $this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce' ) ); + } else { + /* translators: %s: pending reason. */ + $this->payment_on_hold( $order, sprintf( __( 'Payment pending (%s).', 'woocommerce' ), $posted['pending_reason'] ) ); + } + } + } + + /** + * Handle a pending payment. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_pending( $order, $posted ) { + $this->payment_status_completed( $order, $posted ); + } + + /** + * Handle a failed payment. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_failed( $order, $posted ) { + /* translators: %s: payment status. */ + $order->update_status( 'failed', sprintf( __( 'Payment %s via IPN.', 'woocommerce' ), wc_clean( $posted['payment_status'] ) ) ); + } + + /** + * Handle a denied payment. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_denied( $order, $posted ) { + $this->payment_status_failed( $order, $posted ); + } + + /** + * Handle an expired payment. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_expired( $order, $posted ) { + $this->payment_status_failed( $order, $posted ); + } + + /** + * Handle a voided payment. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_voided( $order, $posted ) { + $this->payment_status_failed( $order, $posted ); + } + + /** + * When a user cancelled order is marked paid. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_paid_cancelled_order( $order, $posted ) { + $this->send_ipn_email_notification( + /* translators: %s: order link. */ + sprintf( __( 'Payment for cancelled order %s received', 'woocommerce' ), '' . $order->get_order_number() . '' ), + /* translators: %s: order ID. */ + sprintf( __( 'Order #%s has been marked paid by PayPal IPN, but was previously cancelled. Admin handling required.', 'woocommerce' ), $order->get_order_number() ) + ); + } + + /** + * Handle a refunded order. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_refunded( $order, $posted ) { + // Only handle full refunds, not partial. + if ( $order->get_total() === wc_format_decimal( $posted['mc_gross'] * -1, wc_get_price_decimals() ) ) { + + /* translators: %s: payment status. */ + $order->update_status( 'refunded', sprintf( __( 'Payment %s via IPN.', 'woocommerce' ), strtolower( $posted['payment_status'] ) ) ); + + $this->send_ipn_email_notification( + /* translators: %s: order link. */ + sprintf( __( 'Payment for order %s refunded', 'woocommerce' ), '' . $order->get_order_number() . '' ), + /* translators: %1$s: order ID, %2$s: reason code. */ + sprintf( __( 'Order #%1$s has been marked as refunded - PayPal reason code: %2$s', 'woocommerce' ), $order->get_order_number(), $posted['reason_code'] ) + ); + } + } + + /** + * Handle a reversal. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_reversed( $order, $posted ) { + /* translators: %s: payment status. */ + $order->update_status( 'on-hold', sprintf( __( 'Payment %s via IPN.', 'woocommerce' ), wc_clean( $posted['payment_status'] ) ) ); + + $this->send_ipn_email_notification( + /* translators: %s: order link. */ + sprintf( __( 'Payment for order %s reversed', 'woocommerce' ), '' . $order->get_order_number() . '' ), + /* translators: %1$s: order ID, %2$s: reason code. */ + sprintf( __( 'Order #%1$s has been marked on-hold due to a reversal - PayPal reason code: %2$s', 'woocommerce' ), $order->get_order_number(), wc_clean( $posted['reason_code'] ) ) + ); + } + + /** + * Handle a cancelled reversal. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function payment_status_canceled_reversal( $order, $posted ) { + $this->send_ipn_email_notification( + /* translators: %s: order link. */ + sprintf( __( 'Reversal cancelled for order #%s', 'woocommerce' ), $order->get_order_number() ), + /* translators: %1$s: order ID, %2$s: order link. */ + sprintf( __( 'Order #%1$s has had a reversal cancelled. Please check the status of payment and update the order status accordingly here: %2$s', 'woocommerce' ), $order->get_order_number(), esc_url( $order->get_edit_order_url() ) ) + ); + } + + /** + * Save important data from the IPN to the order. + * + * @param WC_Order $order Order object. + * @param array $posted Posted data. + */ + protected function save_paypal_meta_data( $order, $posted ) { + if ( ! empty( $posted['payment_type'] ) ) { + update_post_meta( $order->get_id(), 'Payment type', wc_clean( $posted['payment_type'] ) ); + } + if ( ! empty( $posted['txn_id'] ) ) { + update_post_meta( $order->get_id(), '_transaction_id', wc_clean( $posted['txn_id'] ) ); + } + if ( ! empty( $posted['payment_status'] ) ) { + update_post_meta( $order->get_id(), '_paypal_status', wc_clean( $posted['payment_status'] ) ); + } + } + + /** + * Send a notification to the user handling orders. + * + * @param string $subject Email subject. + * @param string $message Email message. + */ + protected function send_ipn_email_notification( $subject, $message ) { + $new_order_settings = get_option( 'woocommerce_new_order_settings', array() ); + $mailer = WC()->mailer(); + $message = $mailer->wrap_message( $subject, $message ); + + $woocommerce_paypal_settings = get_option( 'woocommerce_paypal_settings' ); + if ( ! empty( $woocommerce_paypal_settings['ipn_notification'] ) && 'no' === $woocommerce_paypal_settings['ipn_notification'] ) { + return; + } + + $mailer->send( ! empty( $new_order_settings['recipient'] ) ? $new_order_settings['recipient'] : get_option( 'admin_email' ), strip_tags( $subject ), $message ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php new file mode 100644 index 0000000..c37d4d1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -0,0 +1,138 @@ +identity_token = $identity_token; + $this->sandbox = $sandbox; + } + + /** + * Validate a PDT transaction to ensure its authentic. + * + * @param string $transaction TX ID. + * @return bool|array False or result array if successful and valid. + */ + protected function validate_transaction( $transaction ) { + $pdt = array( + 'body' => array( + 'cmd' => '_notify-synch', + 'tx' => $transaction, + 'at' => $this->identity_token, + ), + 'timeout' => 60, + 'httpversion' => '1.1', + 'user-agent' => 'WooCommerce/' . Constants::get_constant( 'WC_VERSION' ), + ); + + // Post back to get a response. + $response = wp_safe_remote_post( $this->sandbox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr', $pdt ); + + if ( is_wp_error( $response ) || strpos( $response['body'], 'SUCCESS' ) !== 0 ) { + return false; + } + + // Parse transaction result data. + $transaction_result = array_map( 'wc_clean', array_map( 'urldecode', explode( "\n", $response['body'] ) ) ); + $transaction_results = array(); + + foreach ( $transaction_result as $line ) { + $line = explode( '=', $line ); + $transaction_results[ $line[0] ] = isset( $line[1] ) ? $line[1] : ''; + } + + if ( ! empty( $transaction_results['charset'] ) && function_exists( 'iconv' ) ) { + foreach ( $transaction_results as $key => $value ) { + $transaction_results[ $key ] = iconv( $transaction_results['charset'], 'utf-8', $value ); + } + } + + return $transaction_results; + } + + /** + * Check Response for PDT. + */ + public function check_response() { + if ( empty( $_REQUEST['cm'] ) || empty( $_REQUEST['tx'] ) || empty( $_REQUEST['st'] ) ) { // WPCS: Input var ok, CSRF ok, sanitization ok. + return; + } + + $order_id = wc_clean( wp_unslash( $_REQUEST['cm'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok. + $status = wc_clean( strtolower( wp_unslash( $_REQUEST['st'] ) ) ); // WPCS: input var ok, CSRF ok, sanitization ok. + $amount = isset( $_REQUEST['amt'] ) ? wc_clean( wp_unslash( $_REQUEST['amt'] ) ) : 0; // WPCS: input var ok, CSRF ok, sanitization ok. + $transaction = wc_clean( wp_unslash( $_REQUEST['tx'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok. + $order = $this->get_paypal_order( $order_id ); + + if ( ! $order || ! $order->needs_payment() ) { + return false; + } + + $transaction_result = $this->validate_transaction( $transaction ); + + if ( $transaction_result ) { + WC_Gateway_Paypal::log( 'PDT Transaction Status: ' . wc_print_r( $status, true ) ); + + $order->add_meta_data( '_paypal_status', $status ); + $order->set_transaction_id( $transaction ); + + if ( 'completed' === $status ) { + if ( number_format( $order->get_total(), 2, '.', '' ) !== number_format( $amount, 2, '.', '' ) ) { + WC_Gateway_Paypal::log( 'Payment error: Amounts do not match (amt ' . $amount . ')', 'error' ); + /* translators: 1: Payment amount */ + $this->payment_on_hold( $order, sprintf( __( 'Validation error: PayPal amounts do not match (amt %s).', 'woocommerce' ), $amount ) ); + } else { + // Log paypal transaction fee and payment type. + if ( ! empty( $transaction_result['mc_fee'] ) ) { + $order->add_meta_data( 'PayPal Transaction Fee', wc_clean( $transaction_result['mc_fee'] ) ); + } + if ( ! empty( $transaction_result['payment_type'] ) ) { + $order->add_meta_data( 'Payment type', wc_clean( $transaction_result['payment_type'] ) ); + } + + $this->payment_complete( $order, $transaction, __( 'PDT payment completed', 'woocommerce' ) ); + } + } else { + if ( 'authorization' === $transaction_result['pending_reason'] ) { + $this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce' ) ); + } else { + /* translators: 1: Pending reason */ + $this->payment_on_hold( $order, sprintf( __( 'Payment pending (%s).', 'woocommerce' ), $transaction_result['pending_reason'] ) ); + } + } + } else { + WC_Gateway_Paypal::log( 'Received invalid response from PayPal PDT' ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-request.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-request.php new file mode 100644 index 0000000..149d087 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-request.php @@ -0,0 +1,581 @@ +gateway = $gateway; + $this->notify_url = WC()->api_request_url( 'WC_Gateway_Paypal' ); + } + + /** + * Get the PayPal request URL for an order. + * + * @param WC_Order $order Order object. + * @param bool $sandbox Whether to use sandbox mode or not. + * @return string + */ + public function get_request_url( $order, $sandbox = false ) { + $this->endpoint = $sandbox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr?test_ipn=1&' : 'https://www.paypal.com/cgi-bin/webscr?'; + $paypal_args = $this->get_paypal_args( $order ); + $paypal_args['bn'] = 'WooThemes_Cart'; // Append WooCommerce PayPal Partner Attribution ID. This should not be overridden for this gateway. + + // Mask (remove) PII from the logs. + $mask = array( + 'first_name' => '***', + 'last_name' => '***', + 'address1' => '***', + 'address2' => '***', + 'city' => '***', + 'state' => '***', + 'zip' => '***', + 'country' => '***', + 'email' => '***@***', + 'night_phone_a' => '***', + 'night_phone_b' => '***', + 'night_phone_c' => '***', + ); + + WC_Gateway_Paypal::log( 'PayPal Request Args for order ' . $order->get_order_number() . ': ' . wc_print_r( array_merge( $paypal_args, array_intersect_key( $mask, $paypal_args ) ), true ) ); + + return $this->endpoint . http_build_query( $paypal_args, '', '&' ); + } + + /** + * Limit length of an arg. + * + * @param string $string Argument to limit. + * @param integer $limit Limit size in characters. + * @return string + */ + protected function limit_length( $string, $limit = 127 ) { + $str_limit = $limit - 3; + if ( function_exists( 'mb_strimwidth' ) ) { + if ( mb_strlen( $string ) > $limit ) { + $string = mb_strimwidth( $string, 0, $str_limit ) . '...'; + } + } else { + if ( strlen( $string ) > $limit ) { + $string = substr( $string, 0, $str_limit ) . '...'; + } + } + return $string; + } + + /** + * Get transaction args for paypal request, except for line item args. + * + * @param WC_Order $order Order object. + * @return array + */ + protected function get_transaction_args( $order ) { + return array_merge( + array( + 'cmd' => '_cart', + 'business' => $this->gateway->get_option( 'email' ), + 'no_note' => 1, + 'currency_code' => get_woocommerce_currency(), + 'charset' => 'utf-8', + 'rm' => is_ssl() ? 2 : 1, + 'upload' => 1, + 'return' => esc_url_raw( add_query_arg( 'utm_nooverride', '1', $this->gateway->get_return_url( $order ) ) ), + 'cancel_return' => esc_url_raw( $order->get_cancel_order_url_raw() ), + 'page_style' => $this->gateway->get_option( 'page_style' ), + 'image_url' => esc_url_raw( $this->gateway->get_option( 'image_url' ) ), + 'paymentaction' => $this->gateway->get_option( 'paymentaction' ), + 'invoice' => $this->limit_length( $this->gateway->get_option( 'invoice_prefix' ) . $order->get_order_number(), 127 ), + 'custom' => wp_json_encode( + array( + 'order_id' => $order->get_id(), + 'order_key' => $order->get_order_key(), + ) + ), + 'notify_url' => $this->limit_length( $this->notify_url, 255 ), + 'first_name' => $this->limit_length( $order->get_billing_first_name(), 32 ), + 'last_name' => $this->limit_length( $order->get_billing_last_name(), 64 ), + 'address1' => $this->limit_length( $order->get_billing_address_1(), 100 ), + 'address2' => $this->limit_length( $order->get_billing_address_2(), 100 ), + 'city' => $this->limit_length( $order->get_billing_city(), 40 ), + 'state' => $this->get_paypal_state( $order->get_billing_country(), $order->get_billing_state() ), + 'zip' => $this->limit_length( wc_format_postcode( $order->get_billing_postcode(), $order->get_billing_country() ), 32 ), + 'country' => $this->limit_length( $order->get_billing_country(), 2 ), + 'email' => $this->limit_length( $order->get_billing_email() ), + ), + $this->get_phone_number_args( $order ), + $this->get_shipping_args( $order ) + ); + } + + /** + * If the default request with line items is too long, generate a new one with only one line item. + * + * If URL is longer than 2,083 chars, ignore line items and send cart to Paypal as a single item. + * One item's name can only be 127 characters long, so the URL should not be longer than limit. + * URL character limit via: + * https://support.microsoft.com/en-us/help/208427/maximum-url-length-is-2-083-characters-in-internet-explorer. + * + * @param WC_Order $order Order to be sent to Paypal. + * @param array $paypal_args Arguments sent to Paypal in the request. + * @return array + */ + protected function fix_request_length( $order, $paypal_args ) { + $max_paypal_length = 2083; + $query_candidate = http_build_query( $paypal_args, '', '&' ); + + if ( strlen( $this->endpoint . $query_candidate ) <= $max_paypal_length ) { + return $paypal_args; + } + + return apply_filters( + 'woocommerce_paypal_args', + array_merge( + $this->get_transaction_args( $order ), + $this->get_line_item_args( $order, true ) + ), + $order + ); + + } + + /** + * Get PayPal Args for passing to PP. + * + * @param WC_Order $order Order object. + * @return array + */ + protected function get_paypal_args( $order ) { + WC_Gateway_Paypal::log( 'Generating payment form for order ' . $order->get_order_number() . '. Notify URL: ' . $this->notify_url ); + + $force_one_line_item = apply_filters( 'woocommerce_paypal_force_one_line_item', false, $order ); + + if ( ( wc_tax_enabled() && wc_prices_include_tax() ) || ! $this->line_items_valid( $order ) ) { + $force_one_line_item = true; + } + + $paypal_args = apply_filters( + 'woocommerce_paypal_args', + array_merge( + $this->get_transaction_args( $order ), + $this->get_line_item_args( $order, $force_one_line_item ) + ), + $order + ); + + return $this->fix_request_length( $order, $paypal_args ); + } + + /** + * Get phone number args for paypal request. + * + * @param WC_Order $order Order object. + * @return array + */ + protected function get_phone_number_args( $order ) { + $phone_number = wc_sanitize_phone_number( $order->get_billing_phone() ); + + if ( in_array( $order->get_billing_country(), array( 'US', 'CA' ), true ) ) { + $phone_number = ltrim( $phone_number, '+1' ); + $phone_args = array( + 'night_phone_a' => substr( $phone_number, 0, 3 ), + 'night_phone_b' => substr( $phone_number, 3, 3 ), + 'night_phone_c' => substr( $phone_number, 6, 4 ), + ); + } else { + $calling_code = WC()->countries->get_country_calling_code( $order->get_billing_country() ); + $calling_code = is_array( $calling_code ) ? $calling_code[0] : $calling_code; + + if ( $calling_code ) { + $phone_number = str_replace( $calling_code, '', preg_replace( '/^0/', '', $order->get_billing_phone() ) ); + } + + $phone_args = array( + 'night_phone_a' => $calling_code, + 'night_phone_b' => $phone_number, + ); + } + return $phone_args; + } + + /** + * Get shipping args for paypal request. + * + * @param WC_Order $order Order object. + * @return array + */ + protected function get_shipping_args( $order ) { + $shipping_args = array(); + if ( $order->needs_shipping_address() ) { + $shipping_args['address_override'] = $this->gateway->get_option( 'address_override' ) === 'yes' ? 1 : 0; + $shipping_args['no_shipping'] = 0; + if ( 'yes' === $this->gateway->get_option( 'send_shipping' ) ) { + // If we are sending shipping, send shipping address instead of billing. + $shipping_args['first_name'] = $this->limit_length( $order->get_shipping_first_name(), 32 ); + $shipping_args['last_name'] = $this->limit_length( $order->get_shipping_last_name(), 64 ); + $shipping_args['address1'] = $this->limit_length( $order->get_shipping_address_1(), 100 ); + $shipping_args['address2'] = $this->limit_length( $order->get_shipping_address_2(), 100 ); + $shipping_args['city'] = $this->limit_length( $order->get_shipping_city(), 40 ); + $shipping_args['state'] = $this->get_paypal_state( $order->get_shipping_country(), $order->get_shipping_state() ); + $shipping_args['country'] = $this->limit_length( $order->get_shipping_country(), 2 ); + $shipping_args['zip'] = $this->limit_length( wc_format_postcode( $order->get_shipping_postcode(), $order->get_shipping_country() ), 32 ); + } + } else { + $shipping_args['no_shipping'] = 1; + } + return $shipping_args; + } + + /** + * Get shipping cost line item args for paypal request. + * + * @param WC_Order $order Order object. + * @param bool $force_one_line_item Whether one line item was forced by validation or URL length. + * @return array + */ + protected function get_shipping_cost_line_item( $order, $force_one_line_item ) { + $line_item_args = array(); + $shipping_total = $order->get_shipping_total(); + if ( $force_one_line_item ) { + $shipping_total += $order->get_shipping_tax(); + } + + // Add shipping costs. Paypal ignores anything over 5 digits (999.99 is the max). + // We also check that shipping is not the **only** cost as PayPal won't allow payment + // if the items have no cost. + if ( $order->get_shipping_total() > 0 && $order->get_shipping_total() < 999.99 && $this->number_format( $order->get_shipping_total() + $order->get_shipping_tax(), $order ) !== $this->number_format( $order->get_total(), $order ) ) { + $line_item_args['shipping_1'] = $this->number_format( $shipping_total, $order ); + } elseif ( $order->get_shipping_total() > 0 ) { + /* translators: %s: Order shipping method */ + $this->add_line_item( sprintf( __( 'Shipping via %s', 'woocommerce' ), $order->get_shipping_method() ), 1, $this->number_format( $shipping_total, $order ) ); + } + + return $line_item_args; + } + + /** + * Get line item args for paypal request as a single line item. + * + * @param WC_Order $order Order object. + * @return array + */ + protected function get_line_item_args_single_item( $order ) { + $this->delete_line_items(); + + $all_items_name = $this->get_order_item_names( $order ); + $this->add_line_item( $all_items_name ? $all_items_name : __( 'Order', 'woocommerce' ), 1, $this->number_format( $order->get_total() - $this->round( $order->get_shipping_total() + $order->get_shipping_tax(), $order ), $order ), $order->get_order_number() ); + $line_item_args = $this->get_shipping_cost_line_item( $order, true ); + + return array_merge( $line_item_args, $this->get_line_items() ); + } + + /** + * Get line item args for paypal request. + * + * @param WC_Order $order Order object. + * @param bool $force_one_line_item Create only one item for this order. + * @return array + */ + protected function get_line_item_args( $order, $force_one_line_item = false ) { + $line_item_args = array(); + + if ( $force_one_line_item ) { + /** + * Send order as a single item. + * + * For shipping, we longer use shipping_1 because paypal ignores it if *any* shipping rules are within paypal, and paypal ignores anything over 5 digits (999.99 is the max). + */ + $line_item_args = $this->get_line_item_args_single_item( $order ); + } else { + /** + * Passing a line item per product if supported. + */ + $this->prepare_line_items( $order ); + $line_item_args['tax_cart'] = $this->number_format( $order->get_total_tax(), $order ); + + if ( $order->get_total_discount() > 0 ) { + $line_item_args['discount_amount_cart'] = $this->number_format( $this->round( $order->get_total_discount(), $order ), $order ); + } + + $line_item_args = array_merge( $line_item_args, $this->get_shipping_cost_line_item( $order, false ) ); + $line_item_args = array_merge( $line_item_args, $this->get_line_items() ); + + } + + return $line_item_args; + } + + /** + * Get order item names as a string. + * + * @param WC_Order $order Order object. + * @return string + */ + protected function get_order_item_names( $order ) { + $item_names = array(); + + foreach ( $order->get_items() as $item ) { + $item_name = $item->get_name(); + $item_meta = wp_strip_all_tags( + wc_display_item_meta( + $item, + array( + 'before' => '', + 'separator' => ', ', + 'after' => '', + 'echo' => false, + 'autop' => false, + ) + ) + ); + + if ( $item_meta ) { + $item_name .= ' (' . $item_meta . ')'; + } + + $item_names[] = $item_name . ' x ' . $item->get_quantity(); + } + + return apply_filters( 'woocommerce_paypal_get_order_item_names', implode( ', ', $item_names ), $order ); + } + + /** + * Get order item names as a string. + * + * @param WC_Order $order Order object. + * @param WC_Order_Item $item Order item object. + * @return string + */ + protected function get_order_item_name( $order, $item ) { + $item_name = $item->get_name(); + $item_meta = wp_strip_all_tags( + wc_display_item_meta( + $item, + array( + 'before' => '', + 'separator' => ', ', + 'after' => '', + 'echo' => false, + 'autop' => false, + ) + ) + ); + + if ( $item_meta ) { + $item_name .= ' (' . $item_meta . ')'; + } + + return apply_filters( 'woocommerce_paypal_get_order_item_name', $item_name, $order, $item ); + } + + /** + * Return all line items. + */ + protected function get_line_items() { + return $this->line_items; + } + + /** + * Remove all line items. + */ + protected function delete_line_items() { + $this->line_items = array(); + } + + /** + * Check if the order has valid line items to use for PayPal request. + * + * The line items are invalid in case of mismatch in totals or if any amount < 0. + * + * @param WC_Order $order Order to be examined. + * @return bool + */ + protected function line_items_valid( $order ) { + $negative_item_amount = false; + $calculated_total = 0; + + // Products. + foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item ) { + if ( 'fee' === $item['type'] ) { + $item_line_total = $this->number_format( $item['line_total'], $order ); + $calculated_total += $item_line_total; + } else { + $item_line_total = $this->number_format( $order->get_item_subtotal( $item, false ), $order ); + $calculated_total += $item_line_total * $item->get_quantity(); + } + + if ( $item_line_total < 0 ) { + $negative_item_amount = true; + } + } + $mismatched_totals = $this->number_format( $calculated_total + $order->get_total_tax() + $this->round( $order->get_shipping_total(), $order ) - $this->round( $order->get_total_discount(), $order ), $order ) !== $this->number_format( $order->get_total(), $order ); + return ! $negative_item_amount && ! $mismatched_totals; + } + + /** + * Get line items to send to paypal. + * + * @param WC_Order $order Order object. + */ + protected function prepare_line_items( $order ) { + $this->delete_line_items(); + + // Products. + foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item ) { + if ( 'fee' === $item['type'] ) { + $item_line_total = $this->number_format( $item['line_total'], $order ); + $this->add_line_item( $item->get_name(), 1, $item_line_total ); + } else { + $product = $item->get_product(); + $sku = $product ? $product->get_sku() : ''; + $item_line_total = $this->number_format( $order->get_item_subtotal( $item, false ), $order ); + $this->add_line_item( $this->get_order_item_name( $order, $item ), $item->get_quantity(), $item_line_total, $sku ); + } + } + } + + /** + * Add PayPal Line Item. + * + * @param string $item_name Item name. + * @param int $quantity Item quantity. + * @param float $amount Amount. + * @param string $item_number Item number. + */ + protected function add_line_item( $item_name, $quantity = 1, $amount = 0.0, $item_number = '' ) { + $index = ( count( $this->line_items ) / 4 ) + 1; + + $item = apply_filters( + 'woocommerce_paypal_line_item', + array( + 'item_name' => html_entity_decode( wc_trim_string( $item_name ? wp_strip_all_tags( $item_name ) : __( 'Item', 'woocommerce' ), 127 ), ENT_NOQUOTES, 'UTF-8' ), + 'quantity' => (int) $quantity, + 'amount' => wc_float_to_string( (float) $amount ), + 'item_number' => $item_number, + ), + $item_name, + $quantity, + $amount, + $item_number + ); + + $this->line_items[ 'item_name_' . $index ] = $this->limit_length( $item['item_name'], 127 ); + $this->line_items[ 'quantity_' . $index ] = $item['quantity']; + $this->line_items[ 'amount_' . $index ] = $item['amount']; + $this->line_items[ 'item_number_' . $index ] = $this->limit_length( $item['item_number'], 127 ); + } + + /** + * Get the state to send to paypal. + * + * @param string $cc Country two letter code. + * @param string $state State code. + * @return string + */ + protected function get_paypal_state( $cc, $state ) { + if ( 'US' === $cc ) { + return $state; + } + + $states = WC()->countries->get_states( $cc ); + + if ( isset( $states[ $state ] ) ) { + return $states[ $state ]; + } + + return $state; + } + + /** + * Check if currency has decimals. + * + * @param string $currency Currency to check. + * @return bool + */ + protected function currency_has_decimals( $currency ) { + if ( in_array( $currency, array( 'HUF', 'JPY', 'TWD' ), true ) ) { + return false; + } + + return true; + } + + /** + * Round prices. + * + * @param double $price Price to round. + * @param WC_Order $order Order object. + * @return double + */ + protected function round( $price, $order ) { + $precision = 2; + + if ( ! $this->currency_has_decimals( $order->get_currency() ) ) { + $precision = 0; + } + + return NumberUtil::round( $price, $precision ); + } + + /** + * Format prices. + * + * @param float|int $price Price to format. + * @param WC_Order $order Order object. + * @return string + */ + protected function number_format( $price, $order ) { + $decimals = 2; + + if ( ! $this->currency_has_decimals( $order->get_currency() ) ) { + $decimals = 0; + } + + return number_format( $price, $decimals, '.', '' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-response.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-response.php new file mode 100644 index 0000000..ba3ab28 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-response.php @@ -0,0 +1,89 @@ +order_id; + $order_key = $custom->order_key; + } else { + // Nothing was found. + WC_Gateway_Paypal::log( 'Order ID and key were not found in "custom".', 'error' ); + return false; + } + + $order = wc_get_order( $order_id ); + + if ( ! $order ) { + // We have an invalid $order_id, probably because invoice_prefix has changed. + $order_id = wc_get_order_id_by_order_key( $order_key ); + $order = wc_get_order( $order_id ); + } + + if ( ! $order || ! hash_equals( $order->get_order_key(), $order_key ) ) { + WC_Gateway_Paypal::log( 'Order Keys do not match.', 'error' ); + return false; + } + + return $order; + } + + /** + * Complete order, add transaction ID and note. + * + * @param WC_Order $order Order object. + * @param string $txn_id Transaction ID. + * @param string $note Payment note. + */ + protected function payment_complete( $order, $txn_id = '', $note = '' ) { + if ( ! $order->has_status( array( 'processing', 'completed' ) ) ) { + $order->add_order_note( $note ); + $order->payment_complete( $txn_id ); + + if ( isset( WC()->cart ) ) { + WC()->cart->empty_cart(); + } + } + } + + /** + * Hold order and add note. + * + * @param WC_Order $order Order object. + * @param string $reason Reason why the payment is on hold. + */ + protected function payment_on_hold( $order, $reason = '' ) { + $order->update_status( 'on-hold', $reason ); + + if ( isset( WC()->cart ) ) { + WC()->cart->empty_cart(); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/settings-paypal.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/settings-paypal.php new file mode 100644 index 0000000..c197463 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/gateways/paypal/includes/settings-paypal.php @@ -0,0 +1,186 @@ + array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable PayPal Standard', 'woocommerce' ), + 'default' => 'no', + ), + 'title' => array( + 'title' => __( 'Title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => __( 'PayPal', 'woocommerce' ), + 'desc_tip' => true, + ), + 'description' => array( + 'title' => __( 'Description', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => true, + 'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce' ), + 'default' => __( "Pay via PayPal; you can pay with your credit card if you don't have a PayPal account.", 'woocommerce' ), + ), + 'email' => array( + 'title' => __( 'PayPal email', 'woocommerce' ), + 'type' => 'email', + 'description' => __( 'Please enter your PayPal email address; this is needed in order to take payment.', 'woocommerce' ), + 'default' => get_option( 'admin_email' ), + 'desc_tip' => true, + 'placeholder' => 'you@youremail.com', + ), + 'advanced' => array( + 'title' => __( 'Advanced options', 'woocommerce' ), + 'type' => 'title', + 'description' => '', + ), + 'testmode' => array( + 'title' => __( 'PayPal sandbox', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable PayPal sandbox', 'woocommerce' ), + 'default' => 'no', + /* translators: %s: URL */ + 'description' => sprintf( __( 'PayPal sandbox can be used to test payments. Sign up for a developer account.', 'woocommerce' ), 'https://developer.paypal.com/' ), + ), + 'debug' => array( + 'title' => __( 'Debug log', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable logging', 'woocommerce' ), + 'default' => 'no', + /* translators: %s: URL */ + 'description' => sprintf( __( 'Log PayPal events, such as IPN requests, inside %s Note: this may log personal information. We recommend using this for debugging purposes only and deleting the logs when finished.', 'woocommerce' ), '' . WC_Log_Handler_File::get_log_file_path( 'paypal' ) . '' ), + ), + 'ipn_notification' => array( + 'title' => __( 'IPN Email Notifications', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable IPN email notifications', 'woocommerce' ), + 'default' => 'yes', + 'description' => __( 'Send notifications when an IPN is received from PayPal indicating refunds, chargebacks and cancellations.', 'woocommerce' ), + ), + 'receiver_email' => array( + 'title' => __( 'Receiver email', 'woocommerce' ), + 'type' => 'email', + 'description' => __( 'If your main PayPal email differs from the PayPal email entered above, input your main receiver email for your PayPal account here. This is used to validate IPN requests.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => 'you@youremail.com', + ), + 'identity_token' => array( + 'title' => __( 'PayPal identity token', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Optionally enable "Payment Data Transfer" (Profile > Profile and Settings > My Selling Tools > Website Preferences) and then copy your identity token here. This will allow payments to be verified without the need for PayPal IPN.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => '', + ), + 'invoice_prefix' => array( + 'title' => __( 'Invoice prefix', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Please enter a prefix for your invoice numbers. If you use your PayPal account for multiple stores ensure this prefix is unique as PayPal will not allow orders with the same invoice number.', 'woocommerce' ), + 'default' => 'WC-', + 'desc_tip' => true, + ), + 'send_shipping' => array( + 'title' => __( 'Shipping details', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Send shipping details to PayPal instead of billing.', 'woocommerce' ), + 'description' => __( 'PayPal allows us to send one address. If you are using PayPal for shipping labels you may prefer to send the shipping address rather than billing. Turning this option off may prevent PayPal Seller protection from applying.', 'woocommerce' ), + 'default' => 'yes', + ), + 'address_override' => array( + 'title' => __( 'Address override', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Enable "address_override" to prevent address information from being changed.', 'woocommerce' ), + 'description' => __( 'PayPal verifies addresses therefore this setting can cause errors (we recommend keeping it disabled).', 'woocommerce' ), + 'default' => 'no', + ), + 'paymentaction' => array( + 'title' => __( 'Payment action', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'description' => __( 'Choose whether you wish to capture funds immediately or authorize payment only.', 'woocommerce' ), + 'default' => 'sale', + 'desc_tip' => true, + 'options' => array( + 'sale' => __( 'Capture', 'woocommerce' ), + 'authorization' => __( 'Authorize', 'woocommerce' ), + ), + ), + 'page_style' => array( + 'title' => __( 'Page style', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Optionally enter the name of the page style you wish to use. These are defined within your PayPal account. This affects classic PayPal checkout screens.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Optional', 'woocommerce' ), + ), + 'image_url' => array( + 'title' => __( 'Image url', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Optionally enter the URL to a 150x50px image displayed as your logo in the upper left corner of the PayPal checkout pages.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Optional', 'woocommerce' ), + ), + 'api_details' => array( + 'title' => __( 'API credentials', 'woocommerce' ), + 'type' => 'title', + /* translators: %s: URL */ + 'description' => sprintf( __( 'Enter your PayPal API credentials to process refunds via PayPal. Learn how to access your PayPal API Credentials.', 'woocommerce' ), 'https://developer.paypal.com/webapps/developer/docs/classic/api/apiCredentials/#create-an-api-signature' ), + ), + 'api_username' => array( + 'title' => __( 'Live API username', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Optional', 'woocommerce' ), + ), + 'api_password' => array( + 'title' => __( 'Live API password', 'woocommerce' ), + 'type' => 'password', + 'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Optional', 'woocommerce' ), + ), + 'api_signature' => array( + 'title' => __( 'Live API signature', 'woocommerce' ), + 'type' => 'password', + 'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Optional', 'woocommerce' ), + ), + 'sandbox_api_username' => array( + 'title' => __( 'Sandbox API username', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Optional', 'woocommerce' ), + ), + 'sandbox_api_password' => array( + 'title' => __( 'Sandbox API password', 'woocommerce' ), + 'type' => 'password', + 'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Optional', 'woocommerce' ), + ), + 'sandbox_api_signature' => array( + 'title' => __( 'Sandbox API signature', 'woocommerce' ), + 'type' => 'password', + 'description' => __( 'Get your API credentials from PayPal.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Optional', 'woocommerce' ), + ), +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/import/abstract-wc-product-importer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/import/abstract-wc-product-importer.php new file mode 100644 index 0000000..075506f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/import/abstract-wc-product-importer.php @@ -0,0 +1,814 @@ +raw_keys; + } + + /** + * Get file mapped headers. + * + * @return array + */ + public function get_mapped_keys() { + return ! empty( $this->mapped_keys ) ? $this->mapped_keys : $this->raw_keys; + } + + /** + * Get raw data. + * + * @return array + */ + public function get_raw_data() { + return $this->raw_data; + } + + /** + * Get parsed data. + * + * @return array + */ + public function get_parsed_data() { + /** + * Filter product importer parsed data. + * + * @param array $parsed_data Parsed data. + * @param WC_Product_Importer $importer Importer instance. + */ + return apply_filters( 'woocommerce_product_importer_parsed_data', $this->parsed_data, $this ); + } + + /** + * Get importer parameters. + * + * @return array + */ + public function get_params() { + return $this->params; + } + + /** + * Get file pointer position from the last read. + * + * @return int + */ + public function get_file_position() { + return $this->file_position; + } + + /** + * Get file pointer position as a percentage of file size. + * + * @return int + */ + public function get_percent_complete() { + $size = filesize( $this->file ); + if ( ! $size ) { + return 0; + } + + return absint( min( NumberUtil::round( ( $this->file_position / $size ) * 100 ), 100 ) ); + } + + /** + * Prepare a single product for create or update. + * + * @param array $data Item data. + * @return WC_Product|WP_Error + */ + protected function get_product_object( $data ) { + $id = isset( $data['id'] ) ? absint( $data['id'] ) : 0; + + // 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() ); + $types[] = 'variation'; + + if ( ! in_array( $data['type'], $types, true ) ) { + return new WP_Error( 'woocommerce_product_importer_invalid_type', __( 'Invalid product type.', 'woocommerce' ), array( 'status' => 401 ) ); + } + + try { + // Prevent getting "variation_invalid_id" error message from Variation Data Store. + if ( 'variation' === $data['type'] ) { + $id = wp_update_post( + array( + 'ID' => $id, + 'post_type' => 'product_variation', + ) + ); + } + + $product = wc_get_product_object( $data['type'], $id ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( 'woocommerce_product_csv_importer_' . $e->getErrorCode(), $e->getMessage(), array( 'status' => 401 ) ); + } + } elseif ( ! empty( $data['id'] ) ) { + $product = wc_get_product( $id ); + + if ( ! $product ) { + return new WP_Error( + 'woocommerce_product_csv_importer_invalid_id', + /* translators: %d: product ID */ + sprintf( __( 'Invalid product ID %d.', 'woocommerce' ), $id ), + array( + 'id' => $id, + 'status' => 401, + ) + ); + } + } else { + $product = wc_get_product_object( 'simple', $id ); + } + + return apply_filters( 'woocommerce_product_import_get_product_object', $product, $data ); + } + + /** + * Process a single item and save. + * + * @throws Exception If item cannot be processed. + * @param array $data Raw CSV data. + * @return array|WP_Error + */ + protected function process_item( $data ) { + try { + do_action( 'woocommerce_product_import_before_process_item', $data ); + $data = apply_filters( 'woocommerce_product_import_process_item_data', $data ); + + // Get product ID from SKU if created during the importation. + if ( empty( $data['id'] ) && ! empty( $data['sku'] ) ) { + $product_id = wc_get_product_id_by_sku( $data['sku'] ); + + if ( $product_id ) { + $data['id'] = $product_id; + } + } + + $object = $this->get_product_object( $data ); + $updating = false; + + if ( is_wp_error( $object ) ) { + return $object; + } + + if ( $object->get_id() && 'importing' !== $object->get_status() ) { + $updating = true; + } + + if ( 'external' === $object->get_type() ) { + unset( $data['manage_stock'], $data['stock_status'], $data['backorders'], $data['low_stock_amount'] ); + } + + if ( 'variation' === $object->get_type() ) { + if ( isset( $data['status'] ) && -1 === $data['status'] ) { + $data['status'] = 0; // Variations cannot be drafts - set to private. + } + } + + if ( 'importing' === $object->get_status() ) { + $object->set_status( 'publish' ); + $object->set_slug( '' ); + } + + $result = $object->set_props( array_diff_key( $data, array_flip( array( 'meta_data', 'raw_image_id', 'raw_gallery_image_ids', 'raw_attributes' ) ) ) ); + + if ( is_wp_error( $result ) ) { + throw new Exception( $result->get_error_message() ); + } + + if ( 'variation' === $object->get_type() ) { + $this->set_variation_data( $object, $data ); + } else { + $this->set_product_data( $object, $data ); + } + + $this->set_image_data( $object, $data ); + $this->set_meta_data( $object, $data ); + + $object = apply_filters( 'woocommerce_product_import_pre_insert_product_object', $object, $data ); + $object->save(); + + do_action( 'woocommerce_product_import_inserted_product_object', $object, $data ); + + return array( + 'id' => $object->get_id(), + 'updated' => $updating, + ); + } catch ( Exception $e ) { + return new WP_Error( 'woocommerce_product_importer_error', $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Convert raw image URLs to IDs and set. + * + * @param WC_Product $product Product instance. + * @param array $data Item data. + */ + protected function set_image_data( &$product, $data ) { + // Image URLs need converting to IDs before inserting. + if ( isset( $data['raw_image_id'] ) ) { + $product->set_image_id( $this->get_attachment_id_from_url( $data['raw_image_id'], $product->get_id() ) ); + } + + // Gallery image URLs need converting to IDs before inserting. + if ( isset( $data['raw_gallery_image_ids'] ) ) { + $gallery_image_ids = array(); + + foreach ( $data['raw_gallery_image_ids'] as $image_id ) { + $gallery_image_ids[] = $this->get_attachment_id_from_url( $image_id, $product->get_id() ); + } + $product->set_gallery_image_ids( $gallery_image_ids ); + } + } + + /** + * Append meta data. + * + * @param WC_Product $product Product instance. + * @param array $data Item data. + */ + protected function set_meta_data( &$product, $data ) { + if ( isset( $data['meta_data'] ) ) { + foreach ( $data['meta_data'] as $meta ) { + $product->update_meta_data( $meta['key'], $meta['value'] ); + } + } + } + + /** + * Set product data. + * + * @param WC_Product $product Product instance. + * @param array $data Item data. + * @throws Exception If data cannot be set. + */ + protected function set_product_data( &$product, $data ) { + if ( isset( $data['raw_attributes'] ) ) { + $attributes = array(); + $default_attributes = array(); + $existing_attributes = $product->get_attributes(); + + foreach ( $data['raw_attributes'] as $position => $attribute ) { + $attribute_id = 0; + + // Get ID if is a global attribute. + if ( ! empty( $attribute['taxonomy'] ) ) { + $attribute_id = $this->get_attribute_taxonomy_id( $attribute['name'] ); + } + + // Set attribute visibility. + if ( isset( $attribute['visible'] ) ) { + $is_visible = $attribute['visible']; + } else { + $is_visible = 1; + } + + // Get name. + $attribute_name = $attribute_id ? wc_attribute_taxonomy_name_by_id( $attribute_id ) : $attribute['name']; + + // Set if is a variation attribute based on existing attributes if possible so updates via CSV do not change this. + $is_variation = 0; + + if ( $existing_attributes ) { + foreach ( $existing_attributes as $existing_attribute ) { + if ( $existing_attribute->get_name() === $attribute_name ) { + $is_variation = $existing_attribute->get_variation(); + break; + } + } + } + + if ( $attribute_id ) { + if ( isset( $attribute['value'] ) ) { + $options = array_map( 'wc_sanitize_term_text_based', $attribute['value'] ); + $options = array_filter( $options, 'strlen' ); + } else { + $options = array(); + } + + // Check for default attributes and set "is_variation". + if ( ! empty( $attribute['default'] ) && in_array( $attribute['default'], $options, true ) ) { + $default_term = get_term_by( 'name', $attribute['default'], $attribute_name ); + + if ( $default_term && ! is_wp_error( $default_term ) ) { + $default = $default_term->slug; + } else { + $default = sanitize_title( $attribute['default'] ); + } + + $default_attributes[ $attribute_name ] = $default; + $is_variation = 1; + } + + if ( ! empty( $options ) ) { + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $options ); + $attribute_object->set_position( $position ); + $attribute_object->set_visible( $is_visible ); + $attribute_object->set_variation( $is_variation ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['value'] ) ) { + // Check for default attributes and set "is_variation". + if ( ! empty( $attribute['default'] ) && in_array( $attribute['default'], $attribute['value'], true ) ) { + $default_attributes[ sanitize_title( $attribute['name'] ) ] = $attribute['default']; + $is_variation = 1; + } + + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute['name'] ); + $attribute_object->set_options( $attribute['value'] ); + $attribute_object->set_position( $position ); + $attribute_object->set_visible( $is_visible ); + $attribute_object->set_variation( $is_variation ); + $attributes[] = $attribute_object; + } + } + + $product->set_attributes( $attributes ); + + // Set variable default attributes. + if ( $product->is_type( 'variable' ) ) { + $product->set_default_attributes( $default_attributes ); + } + } + } + + /** + * Set variation data. + * + * @param WC_Product $variation Product instance. + * @param array $data Item data. + * @return WC_Product|WP_Error + * @throws Exception If data cannot be set. + */ + protected function set_variation_data( &$variation, $data ) { + $parent = false; + + // Check if parent exist. + if ( isset( $data['parent_id'] ) ) { + $parent = wc_get_product( $data['parent_id'] ); + + if ( $parent ) { + $variation->set_parent_id( $parent->get_id() ); + } + } + + // Stop if parent does not exists. + if ( ! $parent ) { + return new WP_Error( 'woocommerce_product_importer_missing_variation_parent_id', __( 'Variation cannot be imported: Missing parent ID or parent does not exist yet.', 'woocommerce' ), array( 'status' => 401 ) ); + } + + // Stop if parent is a product variation. + if ( $parent->is_type( 'variation' ) ) { + return new WP_Error( 'woocommerce_product_importer_parent_set_as_variation', __( 'Variation cannot be imported: Parent product cannot be a product variation', 'woocommerce' ), array( 'status' => 401 ) ); + } + + if ( isset( $data['raw_attributes'] ) ) { + $attributes = array(); + $parent_attributes = $this->get_variation_parent_attributes( $data['raw_attributes'], $parent ); + + foreach ( $data['raw_attributes'] as $attribute ) { + $attribute_id = 0; + + // Get ID if is a global attribute. + if ( ! empty( $attribute['taxonomy'] ) ) { + $attribute_id = $this->get_attribute_taxonomy_id( $attribute['name'] ); + } + + if ( $attribute_id ) { + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } else { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['value'] ) ? current( $attribute['value'] ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + } + + /** + * Get variation parent attributes and set "is_variation". + * + * @param array $attributes Attributes list. + * @param WC_Product $parent Parent product data. + * @return array + */ + protected function get_variation_parent_attributes( $attributes, $parent ) { + $parent_attributes = $parent->get_attributes(); + $require_save = false; + + foreach ( $attributes as $attribute ) { + $attribute_id = 0; + + // Get ID if is a global attribute. + if ( ! empty( $attribute['taxonomy'] ) ) { + $attribute_id = $this->get_attribute_taxonomy_id( $attribute['name'] ); + } + + if ( $attribute_id ) { + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } else { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + // Check if attribute handle variations. + if ( isset( $parent_attributes[ $attribute_name ] ) && ! $parent_attributes[ $attribute_name ]->get_variation() ) { + // Re-create the attribute to CRUD save and generate again. + $parent_attributes[ $attribute_name ] = clone $parent_attributes[ $attribute_name ]; + $parent_attributes[ $attribute_name ]->set_variation( 1 ); + + $require_save = true; + } + } + + // Save variation attributes. + if ( $require_save ) { + $parent->set_attributes( array_values( $parent_attributes ) ); + $parent->save(); + } + + return $parent_attributes; + } + + /** + * Get attachment ID. + * + * @param string $url Attachment URL. + * @param int $product_id Product ID. + * @return int + * @throws Exception If attachment cannot be loaded. + */ + public function get_attachment_id_from_url( $url, $product_id ) { + if ( empty( $url ) ) { + return 0; + } + + $id = 0; + $upload_dir = wp_upload_dir( null, false ); + $base_url = $upload_dir['baseurl'] . '/'; + + // Check first if attachment is inside the WordPress uploads directory, or we're given a filename only. + if ( false !== strpos( $url, $base_url ) || false === strpos( $url, '://' ) ) { + // Search for yyyy/mm/slug.extension or slug.extension - remove the base URL. + $file = str_replace( $base_url, '', $url ); + $args = array( + 'post_type' => 'attachment', + 'post_status' => 'any', + 'fields' => 'ids', + 'meta_query' => array( // @codingStandardsIgnoreLine. + 'relation' => 'OR', + array( + 'key' => '_wp_attached_file', + 'value' => '^' . $file, + 'compare' => 'REGEXP', + ), + array( + 'key' => '_wp_attached_file', + 'value' => '/' . $file, + 'compare' => 'LIKE', + ), + array( + 'key' => '_wc_attachment_source', + 'value' => '/' . $file, + 'compare' => 'LIKE', + ), + ), + ); + } else { + // This is an external URL, so compare to source. + $args = array( + 'post_type' => 'attachment', + 'post_status' => 'any', + 'fields' => 'ids', + 'meta_query' => array( // @codingStandardsIgnoreLine. + array( + 'value' => $url, + 'key' => '_wc_attachment_source', + ), + ), + ); + } + + $ids = get_posts( $args ); // @codingStandardsIgnoreLine. + + if ( $ids ) { + $id = current( $ids ); + } + + // Upload if attachment does not exists. + if ( ! $id && stristr( $url, '://' ) ) { + $upload = wc_rest_upload_image_from_url( $url ); + + if ( is_wp_error( $upload ) ) { + throw new Exception( $upload->get_error_message(), 400 ); + } + + $id = wc_rest_set_uploaded_image_as_attachment( $upload, $product_id ); + + if ( ! wp_attachment_is_image( $id ) ) { + /* translators: %s: image URL */ + throw new Exception( sprintf( __( 'Not able to attach "%s".', 'woocommerce' ), $url ), 400 ); + } + + // Save attachment source for future reference. + update_post_meta( $id, '_wc_attachment_source', $url ); + } + + if ( ! $id ) { + /* translators: %s: image URL */ + throw new Exception( sprintf( __( 'Unable to use image "%s".', 'woocommerce' ), $url ), 400 ); + } + + return $id; + } + + /** + * Get attribute taxonomy ID from the imported data. + * If does not exists register a new attribute. + * + * @param string $raw_name Attribute name. + * @return int + * @throws Exception If taxonomy cannot be loaded. + */ + public function get_attribute_taxonomy_id( $raw_name ) { + global $wpdb, $wc_product_attributes; + + // These are exported as labels, so convert the label to a name if possible first. + $attribute_labels = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_name' ); + $attribute_name = array_search( $raw_name, $attribute_labels, true ); + + if ( ! $attribute_name ) { + $attribute_name = wc_sanitize_taxonomy_name( $raw_name ); + } + + $attribute_id = wc_attribute_taxonomy_id_by_name( $attribute_name ); + + // Get the ID from the name. + if ( $attribute_id ) { + return $attribute_id; + } + + // If the attribute does not exist, create it. + $attribute_id = wc_create_attribute( + array( + 'name' => $raw_name, + 'slug' => $attribute_name, + 'type' => 'select', + 'order_by' => 'menu_order', + 'has_archives' => false, + ) + ); + + if ( is_wp_error( $attribute_id ) ) { + throw new Exception( $attribute_id->get_error_message(), 400 ); + } + + // Register as taxonomy while importing. + $taxonomy_name = wc_attribute_taxonomy_name( $attribute_name ); + register_taxonomy( + $taxonomy_name, + apply_filters( 'woocommerce_taxonomy_objects_' . $taxonomy_name, array( 'product' ) ), + apply_filters( + 'woocommerce_taxonomy_args_' . $taxonomy_name, + array( + 'labels' => array( + 'name' => $raw_name, + ), + 'hierarchical' => true, + 'show_ui' => false, + 'query_var' => true, + 'rewrite' => false, + ) + ) + ); + + // Set product attributes global. + $wc_product_attributes = array(); + + foreach ( wc_get_attribute_taxonomies() as $taxonomy ) { + $wc_product_attributes[ wc_attribute_taxonomy_name( $taxonomy->attribute_name ) ] = $taxonomy; + } + + return $attribute_id; + } + + /** + * 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( 'woocommerce_product_importer_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( 'woocommerce_product_importer_default_time_limit', 20 ); // 20 seconds + $return = false; + if ( time() >= $finish ) { + $return = true; + } + return apply_filters( 'woocommerce_product_importer_time_exceeded', $return ); + } + + /** + * Explode CSV cell values using commas by default, and handling escaped + * separators. + * + * @since 3.2.0 + * @param string $value Value to explode. + * @param string $separator Separator separating each value. Defaults to comma. + * @return array + */ + protected function explode_values( $value, $separator = ',' ) { + $value = str_replace( '\\,', '::separator::', $value ); + $values = explode( $separator, $value ); + $values = array_map( array( $this, 'explode_values_formatter' ), $values ); + + return $values; + } + + /** + * Remove formatting and trim each value. + * + * @since 3.2.0 + * @param string $value Value to format. + * @return string + */ + protected function explode_values_formatter( $value ) { + return trim( str_replace( '::separator::', ',', $value ) ); + } + + /** + * The exporter prepends a ' to escape fields that start with =, +, - or @. + * Remove the prepended ' character preceding those characters. + * + * @since 3.5.2 + * @param string $value A string that may or may not have been escaped with '. + * @return string + */ + protected function unescape_data( $value ) { + $active_content_triggers = array( "'=", "'+", "'-", "'@" ); + + if ( in_array( mb_substr( $value, 0, 2 ), $active_content_triggers, true ) ) { + $value = mb_substr( $value, 1 ); + } + + return $value; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/import/class-wc-product-csv-importer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/import/class-wc-product-csv-importer.php new file mode 100644 index 0000000..c9c11f4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/import/class-wc-product-csv-importer.php @@ -0,0 +1,1128 @@ + 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. + 'prevent_timeouts' => true, // Check memory and time usage and abort if reaching limit. + 'enclosure' => '"', // The character used to wrap text in the CSV. + 'escape' => "\0", // PHP uses '\' as the default escape character. This is not RFC-4180 compliant. This disables the escape character. + ); + + $this->params = wp_parse_args( $params, $default_args ); + $this->file = $file; + + if ( isset( $this->params['mapping']['from'], $this->params['mapping']['to'] ) ) { + $this->params['mapping'] = array_combine( $this->params['mapping']['from'], $this->params['mapping']['to'] ); + } + + // Import mappings for CSV data. + include_once dirname( dirname( __FILE__ ) ) . '/admin/importers/mappings/mappings.php'; + + $this->read_file(); + } + + /** + * Read file. + */ + protected function read_file() { + if ( ! WC_Product_CSV_Importer_Controller::is_file_valid_csv( $this->file ) ) { + wp_die( esc_html__( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) ); + } + + $handle = fopen( $this->file, 'r' ); // @codingStandardsIgnoreLine. + + if ( false !== $handle ) { + $this->raw_keys = version_compare( PHP_VERSION, '5.3', '>=' ) ? array_map( 'trim', fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'], $this->params['escape'] ) ) : array_map( 'trim', fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'] ) ); // @codingStandardsIgnoreLine + + // Remove BOM signature from the first item. + if ( isset( $this->raw_keys[0] ) ) { + $this->raw_keys[0] = $this->remove_utf8_bom( $this->raw_keys[0] ); + } + + if ( 0 !== $this->params['start_pos'] ) { + fseek( $handle, (int) $this->params['start_pos'] ); + } + + while ( 1 ) { + $row = version_compare( PHP_VERSION, '5.3', '>=' ) ? fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'], $this->params['escape'] ) : fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'] ); // @codingStandardsIgnoreLine + + if ( false !== $row ) { + $this->raw_data[] = $row; + $this->file_positions[ count( $this->raw_data ) ] = ftell( $handle ); + + if ( ( $this->params['end_pos'] > 0 && ftell( $handle ) >= $this->params['end_pos'] ) || 0 === --$this->params['lines'] ) { + break; + } + } else { + break; + } + } + + $this->file_position = ftell( $handle ); + } + + if ( ! empty( $this->params['mapping'] ) ) { + $this->set_mapped_keys(); + } + + if ( $this->params['parse'] ) { + $this->set_parsed_data(); + } + } + + /** + * Remove UTF-8 BOM signature. + * + * @param string $string String to handle. + * + * @return string + */ + protected function remove_utf8_bom( $string ) { + if ( 'efbbbf' === substr( bin2hex( $string ), 0, 6 ) ) { + $string = substr( $string, 3 ); + } + + return $string; + } + + /** + * Set file mapped keys. + */ + protected function set_mapped_keys() { + $mapping = $this->params['mapping']; + + foreach ( $this->raw_keys as $key ) { + $this->mapped_keys[] = isset( $mapping[ $key ] ) ? $mapping[ $key ] : $key; + } + } + + /** + * Parse relative field and return product ID. + * + * Handles `id:xx` and SKUs. + * + * If mapping to an id: and the product ID does not exist, this link is not + * valid. + * + * If mapping to a SKU and the product ID does not exist, a temporary object + * will be created so it can be updated later. + * + * @param string $value Field value. + * + * @return int|string + */ + public function parse_relative_field( $value ) { + global $wpdb; + + if ( empty( $value ) ) { + return ''; + } + + // IDs are prefixed with id:. + if ( preg_match( '/^id:(\d+)$/', $value, $matches ) ) { + $id = intval( $matches[1] ); + + // If original_id is found, use that instead of the given ID since a new placeholder must have been created already. + $original_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_original_id' AND meta_value = %s;", $id ) ); // WPCS: db call ok, cache ok. + + if ( $original_id ) { + return absint( $original_id ); + } + + // See if the given ID maps to a valid product allready. + $existing_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type IN ( 'product', 'product_variation' ) AND ID = %d;", $id ) ); // WPCS: db call ok, cache ok. + + if ( $existing_id ) { + return absint( $existing_id ); + } + + // If we're not updating existing posts, we may need a placeholder product to map to. + if ( ! $this->params['update_existing'] ) { + $product = wc_get_product_object( 'simple' ); + $product->set_name( 'Import placeholder for ' . $id ); + $product->set_status( 'importing' ); + $product->add_meta_data( '_original_id', $id, true ); + $id = $product->save(); + } + + return $id; + } + + $id = wc_get_product_id_by_sku( $value ); + + if ( $id ) { + return $id; + } + + try { + $product = wc_get_product_object( 'simple' ); + $product->set_name( 'Import placeholder for ' . $value ); + $product->set_status( 'importing' ); + $product->set_sku( $value ); + $id = $product->save(); + + if ( $id && ! is_wp_error( $id ) ) { + return $id; + } + } catch ( Exception $e ) { + return ''; + } + + return ''; + } + + /** + * Parse the ID field. + * + * If we're not doing an update, create a placeholder product so mapping works + * for rows following this one. + * + * @param string $value Field value. + * + * @return int + */ + public function parse_id_field( $value ) { + global $wpdb; + + $id = absint( $value ); + + if ( ! $id ) { + return 0; + } + + // See if this maps to an ID placeholder already. + $original_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_original_id' AND meta_value = %s;", $id ) ); // WPCS: db call ok, cache ok. + + if ( $original_id ) { + return absint( $original_id ); + } + + // Not updating? Make sure we have a new placeholder for this ID. + if ( ! $this->params['update_existing'] ) { + $mapped_keys = $this->get_mapped_keys(); + $sku_column_index = absint( array_search( 'sku', $mapped_keys, true ) ); + $row_sku = isset( $this->raw_data[ $this->parsing_raw_data_index ][ $sku_column_index ] ) ? $this->raw_data[ $this->parsing_raw_data_index ][ $sku_column_index ] : ''; + $id_from_sku = $row_sku ? wc_get_product_id_by_sku( $row_sku ) : ''; + + // If row has a SKU, make sure placeholder was not made already. + if ( $id_from_sku ) { + return $id_from_sku; + } + + $product = wc_get_product_object( 'simple' ); + $product->set_name( 'Import placeholder for ' . $id ); + $product->set_status( 'importing' ); + $product->add_meta_data( '_original_id', $id, true ); + + // If row has a SKU, make sure placeholder has it too. + if ( $row_sku ) { + $product->set_sku( $row_sku ); + } + $id = $product->save(); + } + + return $id && ! is_wp_error( $id ) ? $id : 0; + } + + /** + * Parse relative comma-delineated field and return product ID. + * + * @param string $value Field value. + * + * @return array + */ + public function parse_relative_comma_field( $value ) { + if ( empty( $value ) ) { + return array(); + } + + return array_filter( array_map( array( $this, 'parse_relative_field' ), $this->explode_values( $value ) ) ); + } + + /** + * Parse a comma-delineated field from a CSV. + * + * @param string $value Field value. + * + * @return array + */ + public function parse_comma_field( $value ) { + if ( empty( $value ) && '0' !== $value ) { + return array(); + } + + $value = $this->unescape_data( $value ); + return array_map( 'wc_clean', $this->explode_values( $value ) ); + } + + /** + * Parse a field that is generally '1' or '0' but can be something else. + * + * @param string $value Field value. + * + * @return bool|string + */ + public function parse_bool_field( $value ) { + if ( '0' === $value ) { + return false; + } + + if ( '1' === $value ) { + return true; + } + + // Don't return explicit true or false for empty fields or values like 'notify'. + return wc_clean( $value ); + } + + /** + * Parse a float value field. + * + * @param string $value Field value. + * + * @return float|string + */ + public function parse_float_field( $value ) { + if ( '' === $value ) { + return $value; + } + + // Remove the ' prepended to fields that start with - if needed. + $value = $this->unescape_data( $value ); + + return floatval( $value ); + } + + /** + * Parse the stock qty field. + * + * @param string $value Field value. + * + * @return float|string + */ + public function parse_stock_quantity_field( $value ) { + if ( '' === $value ) { + return $value; + } + + // Remove the ' prepended to fields that start with - if needed. + $value = $this->unescape_data( $value ); + + return wc_stock_amount( $value ); + } + + /** + * Parse the tax status field. + * + * @param string $value Field value. + * + * @return string + */ + public function parse_tax_status_field( $value ) { + if ( '' === $value ) { + return $value; + } + + // Remove the ' prepended to fields that start with - if needed. + $value = $this->unescape_data( $value ); + + if ( 'true' === strtolower( $value ) || 'false' === strtolower( $value ) ) { + $value = wc_string_to_bool( $value ) ? 'taxable' : 'none'; + } + + return wc_clean( $value ); + } + + /** + * Parse a category field from a CSV. + * Categories are separated by commas and subcategories are "parent > subcategory". + * + * @param string $value Field value. + * + * @return array of arrays with "parent" and "name" keys. + */ + public function parse_categories_field( $value ) { + if ( empty( $value ) ) { + return array(); + } + + $row_terms = $this->explode_values( $value ); + $categories = array(); + + foreach ( $row_terms as $row_term ) { + $parent = null; + $_terms = array_map( 'trim', explode( '>', $row_term ) ); + $total = count( $_terms ); + + foreach ( $_terms as $index => $_term ) { + // Don't allow users without capabilities to create new categories. + if ( ! current_user_can( 'manage_product_terms' ) ) { + break; + } + + $term = wp_insert_term( $_term, 'product_cat', array( 'parent' => intval( $parent ) ) ); + + if ( is_wp_error( $term ) ) { + if ( $term->get_error_code() === 'term_exists' ) { + // When term exists, error data should contain existing term id. + $term_id = $term->get_error_data(); + } else { + break; // We cannot continue on any other error. + } + } else { + // New term. + $term_id = $term['term_id']; + } + + // Only requires assign the last category. + if ( ( 1 + $index ) === $total ) { + $categories[] = $term_id; + } else { + // Store parent to be able to insert or query categories based in parent ID. + $parent = $term_id; + } + } + } + + return $categories; + } + + /** + * Parse a tag field from a CSV. + * + * @param string $value Field value. + * + * @return array + */ + public function parse_tags_field( $value ) { + if ( empty( $value ) ) { + return array(); + } + + $value = $this->unescape_data( $value ); + $names = $this->explode_values( $value ); + $tags = array(); + + foreach ( $names as $name ) { + $term = get_term_by( 'name', $name, 'product_tag' ); + + if ( ! $term || is_wp_error( $term ) ) { + $term = (object) wp_insert_term( $name, 'product_tag' ); + } + + if ( ! is_wp_error( $term ) ) { + $tags[] = $term->term_id; + } + } + + return $tags; + } + + /** + * Parse a tag field from a CSV with space separators. + * + * @param string $value Field value. + * + * @return array + */ + public function parse_tags_spaces_field( $value ) { + if ( empty( $value ) ) { + return array(); + } + + $value = $this->unescape_data( $value ); + $names = $this->explode_values( $value, ' ' ); + $tags = array(); + + foreach ( $names as $name ) { + $term = get_term_by( 'name', $name, 'product_tag' ); + + if ( ! $term || is_wp_error( $term ) ) { + $term = (object) wp_insert_term( $name, 'product_tag' ); + } + + if ( ! is_wp_error( $term ) ) { + $tags[] = $term->term_id; + } + } + + return $tags; + } + + /** + * Parse a shipping class field from a CSV. + * + * @param string $value Field value. + * + * @return int + */ + public function parse_shipping_class_field( $value ) { + if ( empty( $value ) ) { + return 0; + } + + $term = get_term_by( 'name', $value, 'product_shipping_class' ); + + if ( ! $term || is_wp_error( $term ) ) { + $term = (object) wp_insert_term( $value, 'product_shipping_class' ); + } + + if ( is_wp_error( $term ) ) { + return 0; + } + + return $term->term_id; + } + + /** + * Parse images list from a CSV. Images can be filenames or URLs. + * + * @param string $value Field value. + * + * @return array + */ + public function parse_images_field( $value ) { + if ( empty( $value ) ) { + return array(); + } + + $images = array(); + $separator = apply_filters( 'woocommerce_product_import_image_separator', ',' ); + + foreach ( $this->explode_values( $value, $separator ) as $image ) { + if ( stristr( $image, '://' ) ) { + $images[] = esc_url_raw( $image ); + } else { + $images[] = sanitize_file_name( $image ); + } + } + + return $images; + } + + /** + * Parse dates from a CSV. + * Dates requires the format YYYY-MM-DD and time is optional. + * + * @param string $value Field value. + * + * @return string|null + */ + public function parse_date_field( $value ) { + if ( empty( $value ) ) { + return null; + } + + if ( preg_match( '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])([ 01-9:]*)$/', $value ) ) { + // Don't include the time if the field had time in it. + return current( explode( ' ', $value ) ); + } + + return null; + } + + /** + * Parse backorders from a CSV. + * + * @param string $value Field value. + * + * @return string + */ + public function parse_backorders_field( $value ) { + if ( empty( $value ) ) { + return 'no'; + } + + $value = $this->parse_bool_field( $value ); + + if ( 'notify' === $value ) { + return 'notify'; + } elseif ( is_bool( $value ) ) { + return $value ? 'yes' : 'no'; + } + + return 'no'; + } + + /** + * Just skip current field. + * + * By default is applied wc_clean() to all not listed fields + * in self::get_formatting_callback(), use this method to skip any formatting. + * + * @param string $value Field value. + * + * @return string + */ + public function parse_skip_field( $value ) { + return $value; + } + + /** + * Parse download file urls, we should allow shortcodes here. + * + * Allow shortcodes if present, othersiwe esc_url the value. + * + * @param string $value Field value. + * + * @return string + */ + public function parse_download_file_field( $value ) { + // Absolute file paths. + if ( 0 === strpos( $value, 'http' ) ) { + return esc_url_raw( $value ); + } + // Relative and shortcode paths. + return wc_clean( $value ); + } + + /** + * Parse an int value field + * + * @param int $value field value. + * + * @return int + */ + public function parse_int_field( $value ) { + // Remove the ' prepended to fields that start with - if needed. + $value = $this->unescape_data( $value ); + + return intval( $value ); + } + + /** + * Parse a description value field + * + * @param string $description field value. + * + * @return string + */ + public function parse_description_field( $description ) { + $parts = explode( "\\\\n", $description ); + foreach ( $parts as $key => $part ) { + $parts[ $key ] = str_replace( '\n', "\n", $part ); + } + + return implode( '\\\n', $parts ); + } + + /** + * Parse the published field. 1 is published, 0 is private, -1 is draft. + * Alternatively, 'true' can be used for published and 'false' for draft. + * + * @param string $value Field value. + * + * @return float|string + */ + public function parse_published_field( $value ) { + if ( '' === $value ) { + return $value; + } + + // Remove the ' prepended to fields that start with - if needed. + $value = $this->unescape_data( $value ); + + if ( 'true' === strtolower( $value ) || 'false' === strtolower( $value ) ) { + return wc_string_to_bool( $value ) ? 1 : -1; + } + + return floatval( $value ); + } + + /** + * Deprecated get formatting callback method. + * + * @deprecated 4.3.0 + * @return array + */ + protected function get_formating_callback() { + return $this->get_formatting_callback(); + } + + /** + * Get formatting callback. + * + * @since 4.3.0 + * @return array + */ + protected function get_formatting_callback() { + + /** + * Columns not mentioned here will get parsed with 'wc_clean'. + * column_name => callback. + */ + $data_formatting = array( + 'id' => array( $this, 'parse_id_field' ), + 'type' => array( $this, 'parse_comma_field' ), + 'published' => array( $this, 'parse_published_field' ), + 'featured' => array( $this, 'parse_bool_field' ), + 'date_on_sale_from' => array( $this, 'parse_date_field' ), + 'date_on_sale_to' => array( $this, 'parse_date_field' ), + 'name' => array( $this, 'parse_skip_field' ), + 'short_description' => array( $this, 'parse_description_field' ), + 'description' => array( $this, 'parse_description_field' ), + 'manage_stock' => array( $this, 'parse_bool_field' ), + 'low_stock_amount' => array( $this, 'parse_stock_quantity_field' ), + 'backorders' => array( $this, 'parse_backorders_field' ), + 'stock_status' => array( $this, 'parse_bool_field' ), + 'sold_individually' => array( $this, 'parse_bool_field' ), + 'width' => array( $this, 'parse_float_field' ), + 'length' => array( $this, 'parse_float_field' ), + 'height' => array( $this, 'parse_float_field' ), + 'weight' => array( $this, 'parse_float_field' ), + 'reviews_allowed' => array( $this, 'parse_bool_field' ), + 'purchase_note' => 'wp_filter_post_kses', + 'price' => 'wc_format_decimal', + 'regular_price' => 'wc_format_decimal', + 'stock_quantity' => array( $this, 'parse_stock_quantity_field' ), + 'category_ids' => array( $this, 'parse_categories_field' ), + 'tag_ids' => array( $this, 'parse_tags_field' ), + 'tag_ids_spaces' => array( $this, 'parse_tags_spaces_field' ), + 'shipping_class_id' => array( $this, 'parse_shipping_class_field' ), + 'images' => array( $this, 'parse_images_field' ), + 'parent_id' => array( $this, 'parse_relative_field' ), + 'grouped_products' => array( $this, 'parse_relative_comma_field' ), + 'upsell_ids' => array( $this, 'parse_relative_comma_field' ), + 'cross_sell_ids' => array( $this, 'parse_relative_comma_field' ), + 'download_limit' => array( $this, 'parse_int_field' ), + 'download_expiry' => array( $this, 'parse_int_field' ), + 'product_url' => 'esc_url_raw', + 'menu_order' => 'intval', + 'tax_status' => array( $this, 'parse_tax_status_field' ), + ); + + /** + * Match special column names. + */ + $regex_match_data_formatting = array( + '/attributes:value*/' => array( $this, 'parse_comma_field' ), + '/attributes:visible*/' => array( $this, 'parse_bool_field' ), + '/attributes:taxonomy*/' => array( $this, 'parse_bool_field' ), + '/downloads:url*/' => array( $this, 'parse_download_file_field' ), + '/meta:*/' => 'wp_kses_post', // Allow some HTML in meta fields. + ); + + $callbacks = array(); + + // Figure out the parse function for each column. + foreach ( $this->get_mapped_keys() as $index => $heading ) { + $callback = 'wc_clean'; + + if ( isset( $data_formatting[ $heading ] ) ) { + $callback = $data_formatting[ $heading ]; + } else { + foreach ( $regex_match_data_formatting as $regex => $callback ) { + if ( preg_match( $regex, $heading ) ) { + $callback = $callback; + break; + } + } + } + + $callbacks[] = $callback; + } + + return apply_filters( 'woocommerce_product_importer_formatting_callbacks', $callbacks, $this ); + } + + /** + * Check if strings starts with determined word. + * + * @param string $haystack Complete sentence. + * @param string $needle Excerpt. + * + * @return bool + */ + protected function starts_with( $haystack, $needle ) { + return substr( $haystack, 0, strlen( $needle ) ) === $needle; + } + + /** + * Expand special and internal data into the correct formats for the product CRUD. + * + * @param array $data Data to import. + * + * @return array + */ + protected function expand_data( $data ) { + $data = apply_filters( 'woocommerce_product_importer_pre_expand_data', $data ); + + // Images field maps to image and gallery id fields. + if ( isset( $data['images'] ) ) { + $images = $data['images']; + $data['raw_image_id'] = array_shift( $images ); + + if ( ! empty( $images ) ) { + $data['raw_gallery_image_ids'] = $images; + } + unset( $data['images'] ); + } + + // Type, virtual and downloadable are all stored in the same column. + if ( isset( $data['type'] ) ) { + $data['type'] = array_map( 'strtolower', $data['type'] ); + $data['virtual'] = in_array( 'virtual', $data['type'], true ); + $data['downloadable'] = in_array( 'downloadable', $data['type'], true ); + + // Convert type to string. + $data['type'] = current( array_diff( $data['type'], array( 'virtual', 'downloadable' ) ) ); + + if ( ! $data['type'] ) { + $data['type'] = 'simple'; + } + } + + // Status is mapped from a special published field. + if ( isset( $data['published'] ) ) { + $statuses = array( + -1 => 'draft', + 0 => 'private', + 1 => 'publish', + ); + $data['status'] = isset( $statuses[ $data['published'] ] ) ? $statuses[ $data['published'] ] : 'draft'; + + // Fix draft status of variations. + if ( isset( $data['type'] ) && 'variation' === $data['type'] && -1 === $data['published'] ) { + $data['status'] = 'publish'; + } + + unset( $data['published'] ); + } + + if ( isset( $data['stock_quantity'] ) ) { + if ( '' === $data['stock_quantity'] ) { + $data['manage_stock'] = false; + $data['stock_status'] = isset( $data['stock_status'] ) ? $data['stock_status'] : true; + } else { + $data['manage_stock'] = true; + } + } + + // Stock is bool or 'backorder'. + if ( isset( $data['stock_status'] ) ) { + if ( 'backorder' === $data['stock_status'] ) { + $data['stock_status'] = 'onbackorder'; + } else { + $data['stock_status'] = $data['stock_status'] ? 'instock' : 'outofstock'; + } + } + + // Prepare grouped products. + if ( isset( $data['grouped_products'] ) ) { + $data['children'] = $data['grouped_products']; + unset( $data['grouped_products'] ); + } + + // Tag ids. + if ( isset( $data['tag_ids_spaces'] ) ) { + $data['tag_ids'] = $data['tag_ids_spaces']; + unset( $data['tag_ids_spaces'] ); + } + + // Handle special column names which span multiple columns. + $attributes = array(); + $downloads = array(); + $meta_data = array(); + + foreach ( $data as $key => $value ) { + if ( $this->starts_with( $key, 'attributes:name' ) ) { + if ( ! empty( $value ) ) { + $attributes[ str_replace( 'attributes:name', '', $key ) ]['name'] = $value; + } + unset( $data[ $key ] ); + + } elseif ( $this->starts_with( $key, 'attributes:value' ) ) { + $attributes[ str_replace( 'attributes:value', '', $key ) ]['value'] = $value; + unset( $data[ $key ] ); + + } elseif ( $this->starts_with( $key, 'attributes:taxonomy' ) ) { + $attributes[ str_replace( 'attributes:taxonomy', '', $key ) ]['taxonomy'] = wc_string_to_bool( $value ); + unset( $data[ $key ] ); + + } elseif ( $this->starts_with( $key, 'attributes:visible' ) ) { + $attributes[ str_replace( 'attributes:visible', '', $key ) ]['visible'] = wc_string_to_bool( $value ); + unset( $data[ $key ] ); + + } elseif ( $this->starts_with( $key, 'attributes:default' ) ) { + if ( ! empty( $value ) ) { + $attributes[ str_replace( 'attributes:default', '', $key ) ]['default'] = $value; + } + unset( $data[ $key ] ); + + } elseif ( $this->starts_with( $key, 'downloads:name' ) ) { + if ( ! empty( $value ) ) { + $downloads[ str_replace( 'downloads:name', '', $key ) ]['name'] = $value; + } + unset( $data[ $key ] ); + + } elseif ( $this->starts_with( $key, 'downloads:url' ) ) { + if ( ! empty( $value ) ) { + $downloads[ str_replace( 'downloads:url', '', $key ) ]['url'] = $value; + } + unset( $data[ $key ] ); + + } elseif ( $this->starts_with( $key, 'meta:' ) ) { + $meta_data[] = array( + 'key' => str_replace( 'meta:', '', $key ), + 'value' => $value, + ); + unset( $data[ $key ] ); + } + } + + if ( ! empty( $attributes ) ) { + // Remove empty attributes and clear indexes. + foreach ( $attributes as $attribute ) { + if ( empty( $attribute['name'] ) ) { + continue; + } + + $data['raw_attributes'][] = $attribute; + } + } + + if ( ! empty( $downloads ) ) { + $data['downloads'] = array(); + + foreach ( $downloads as $key => $file ) { + if ( empty( $file['url'] ) ) { + continue; + } + + $data['downloads'][] = array( + 'name' => $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['url'] ), + 'file' => $file['url'], + ); + } + } + + if ( ! empty( $meta_data ) ) { + $data['meta_data'] = $meta_data; + } + + return $data; + } + + /** + * Map and format raw data to known fields. + */ + protected function set_parsed_data() { + $parse_functions = $this->get_formatting_callback(); + $mapped_keys = $this->get_mapped_keys(); + $use_mb = function_exists( 'mb_convert_encoding' ); + + // Parse the data. + foreach ( $this->raw_data as $row_index => $row ) { + // Skip empty rows. + if ( ! count( array_filter( $row ) ) ) { + continue; + } + + $this->parsing_raw_data_index = $row_index; + + $data = array(); + + do_action( 'woocommerce_product_importer_before_set_parsed_data', $row, $mapped_keys ); + + foreach ( $row as $id => $value ) { + // Skip ignored columns. + if ( empty( $mapped_keys[ $id ] ) ) { + continue; + } + + // Convert UTF8. + if ( $use_mb ) { + $encoding = mb_detect_encoding( $value, mb_detect_order(), true ); + if ( $encoding ) { + $value = mb_convert_encoding( $value, 'UTF-8', $encoding ); + } else { + $value = mb_convert_encoding( $value, 'UTF-8', 'UTF-8' ); + } + } else { + $value = wp_check_invalid_utf8( $value, true ); + } + + $data[ $mapped_keys[ $id ] ] = call_user_func( $parse_functions[ $id ], $value ); + } + + /** + * Filter product importer parsed data. + * + * @param array $parsed_data Parsed data. + * @param WC_Product_Importer $importer Importer instance. + */ + $this->parsed_data[] = apply_filters( 'woocommerce_product_importer_parsed_data', $this->expand_data( $data ), $this ); + } + } + + /** + * Get a string to identify the row from parsed data. + * + * @param array $parsed_data 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 ) { + /* translators: %d: product ID */ + $row_data[] = sprintf( __( 'ID %d', 'woocommerce' ), $id ); + } + if ( $sku ) { + /* translators: %s: product SKU */ + $row_data[] = sprintf( __( 'SKU %s', 'woocommerce' ), $sku ); + } + + return implode( ', ', $row_data ); + } + + /** + * Process importer. + * + * Do not import products with IDs or SKUs that already exist if option + * update existing is false, and likewise, if updating products, do not + * process rows which do not exist if an ID/SKU is provided. + * + * @return array + */ + public function import() { + $this->start_time = time(); + $index = 0; + $update_existing = $this->params['update_existing']; + $data = array( + 'imported' => array(), + 'failed' => array(), + 'updated' => array(), + 'skipped' => array(), + ); + + foreach ( $this->parsed_data as $parsed_data_key => $parsed_data ) { + do_action( 'woocommerce_product_import_before_import', $parsed_data ); + + $id = isset( $parsed_data['id'] ) ? absint( $parsed_data['id'] ) : 0; + $sku = isset( $parsed_data['sku'] ) ? $parsed_data['sku'] : ''; + $id_exists = false; + $sku_exists = false; + + if ( $id ) { + $product = wc_get_product( $id ); + $id_exists = $product && 'importing' !== $product->get_status(); + } + + if ( $sku ) { + $id_from_sku = wc_get_product_id_by_sku( $sku ); + $product = $id_from_sku ? wc_get_product( $id_from_sku ) : false; + $sku_exists = $product && 'importing' !== $product->get_status(); + } + + if ( $id_exists && ! $update_existing ) { + $data['skipped'][] = new WP_Error( + 'woocommerce_product_importer_error', + esc_html__( 'A product with this ID already exists.', 'woocommerce' ), + array( + 'id' => $id, + 'row' => $this->get_row_id( $parsed_data ), + ) + ); + continue; + } + + if ( $sku_exists && ! $update_existing ) { + $data['skipped'][] = new WP_Error( + 'woocommerce_product_importer_error', + esc_html__( 'A product with this SKU already exists.', 'woocommerce' ), + array( + 'sku' => esc_attr( $sku ), + 'row' => $this->get_row_id( $parsed_data ), + ) + ); + continue; + } + + if ( $update_existing && ( isset( $parsed_data['id'] ) || isset( $parsed_data['sku'] ) ) && ! $id_exists && ! $sku_exists ) { + $data['skipped'][] = new WP_Error( + 'woocommerce_product_importer_error', + esc_html__( 'No matching product exists to update.', 'woocommerce' ), + array( + 'id' => $id, + 'sku' => esc_attr( $sku ), + 'row' => $this->get_row_id( $parsed_data ), + ) + ); + continue; + } + + $result = $this->process_item( $parsed_data ); + + if ( is_wp_error( $result ) ) { + $result->add_data( array( 'row' => $this->get_row_id( $parsed_data ) ) ); + $data['failed'][] = $result; + } elseif ( $result['updated'] ) { + $data['updated'][] = $result['id']; + } else { + $data['imported'][] = $result['id']; + } + + $index ++; + + if ( $this->params['prevent_timeouts'] && ( $this->time_exceeded() || $this->memory_exceeded() ) ) { + $this->file_position = $this->file_positions[ $index ]; + break; + } + } + + return $data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-database-service.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-database-service.php new file mode 100644 index 0000000..8a78efb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-database-service.php @@ -0,0 +1,172 @@ +database_prefix = $database_prefix; + } + + /** + * Fetches the path that the database should be stored. + * + * @return string The local database path. + */ + public function get_database_path() { + $uploads_dir = wp_upload_dir(); + + $database_path = trailingslashit( $uploads_dir['basedir'] ) . 'woocommerce_uploads/'; + if ( ! empty( $this->database_prefix ) ) { + $database_path .= $this->database_prefix . '-'; + } + $database_path .= self::DATABASE . self::DATABASE_EXTENSION; + + /** + * Filter the geolocation database storage path. + * + * @param string $database_path The path to the database. + * @param int $version Deprecated since 3.4.0. + * @deprecated 3.9.0 + */ + $database_path = apply_filters_deprecated( + 'woocommerce_geolocation_local_database_path', + array( $database_path, 2 ), + '3.9.0', + 'woocommerce_maxmind_geolocation_database_path' + ); + + /** + * Filter the geolocation database storage path. + * + * @since 3.9.0 + * @param string $database_path The path to the database. + */ + return apply_filters( 'woocommerce_maxmind_geolocation_database_path', $database_path ); + } + + /** + * Fetches the database from the MaxMind service. + * + * @param string $license_key The license key to be used when downloading the database. + * @return string|WP_Error The path to the database file or an error if invalid. + */ + public function download_database( $license_key ) { + $download_uri = add_query_arg( + array( + 'edition_id' => self::DATABASE, + 'license_key' => urlencode( wc_clean( $license_key ) ), + 'suffix' => 'tar.gz', + ), + 'https://download.maxmind.com/app/geoip_download' + ); + + // Needed for the download_url call right below. + require_once ABSPATH . 'wp-admin/includes/file.php'; + + $tmp_archive_path = download_url( esc_url_raw( $download_uri ) ); + if ( is_wp_error( $tmp_archive_path ) ) { + // Transform the error into something more informative. + $error_data = $tmp_archive_path->get_error_data(); + if ( isset( $error_data['code'] ) ) { + switch ( $error_data['code'] ) { + case 401: + return new WP_Error( + 'woocommerce_maxmind_geolocation_database_license_key', + __( 'The MaxMind license key is invalid. If you have recently created this key, you may need to wait for it to become active.', 'woocommerce' ) + ); + } + } + + return new WP_Error( 'woocommerce_maxmind_geolocation_database_download', __( 'Failed to download the MaxMind database.', 'woocommerce' ) ); + } + + // Extract the database from the archive. + try { + $file = new PharData( $tmp_archive_path ); + + $tmp_database_path = trailingslashit( dirname( $tmp_archive_path ) ) . trailingslashit( $file->current()->getFilename() ) . self::DATABASE . self::DATABASE_EXTENSION; + + $file->extractTo( + dirname( $tmp_archive_path ), + trailingslashit( $file->current()->getFilename() ) . self::DATABASE . self::DATABASE_EXTENSION, + true + ); + } catch ( Exception $exception ) { + return new WP_Error( 'woocommerce_maxmind_geolocation_database_archive', $exception->getMessage() ); + } finally { + // Remove the archive since we only care about a single file in it. + unlink( $tmp_archive_path ); + } + + return $tmp_database_path; + } + + /** + * Fetches the ISO country code associated with an IP address. + * + * @param string $ip_address The IP address to find the country code for. + * @return string The country code for the IP address, or empty if not found. + */ + public function get_iso_country_code_for_ip( $ip_address ) { + $country_code = ''; + + if ( ! class_exists( 'MaxMind\Db\Reader' ) ) { + wc_get_logger()->notice( __( 'Missing MaxMind Reader library!', 'woocommerce' ), array( 'source' => 'maxmind-geolocation' ) ); + return $country_code; + } + + $database_path = $this->get_database_path(); + if ( ! file_exists( $database_path ) ) { + return $country_code; + } + + try { + $reader = new MaxMind\Db\Reader( $database_path ); + $data = $reader->get( $ip_address ); + + if ( isset( $data['country']['iso_code'] ) ) { + $country_code = $data['country']['iso_code']; + } + + $reader->close(); + } catch ( Exception $e ) { + wc_get_logger()->notice( $e->getMessage(), array( 'source' => 'maxmind-geolocation' ) ); + } + + return $country_code; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-geolocation.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-geolocation.php new file mode 100644 index 0000000..43c3c26 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/integrations/maxmind-geolocation/class-wc-integration-maxmind-geolocation.php @@ -0,0 +1,292 @@ +id = 'maxmind_geolocation'; + $this->method_title = __( 'MaxMind Geolocation', 'woocommerce' ); + $this->method_description = __( 'An integration for utilizing MaxMind to do Geolocation lookups. Please note that this integration will only do country lookups.', 'woocommerce' ); + + /** + * Supports overriding the database service to be used. + * + * @since 3.9.0 + * @return mixed|null The geolocation database service. + */ + $this->database_service = apply_filters( 'woocommerce_maxmind_geolocation_database_service', null ); + if ( null === $this->database_service ) { + $this->database_service = new WC_Integration_MaxMind_Database_Service( $this->get_database_prefix() ); + } + + $this->init_form_fields(); + $this->init_settings(); + + // Bind to the save action for the settings. + add_action( 'woocommerce_update_options_integration_' . $this->id, array( $this, 'process_admin_options' ) ); + + // Trigger notice if license key is missing. + add_action( 'update_option_woocommerce_default_customer_address', array( $this, 'display_missing_license_key_notice' ), 1000, 2 ); + + /** + * Allows for the automatic database update to be disabled. + * + * @deprecated 3.9.0 + * @return bool Whether or not the database should be updated periodically. + */ + $bind_updater = apply_filters_deprecated( + 'woocommerce_geolocation_update_database_periodically', + array( true ), + '3.9.0', + 'woocommerce_maxmind_geolocation_update_database_periodically' + ); + + /** + * Allows for the automatic database update to be disabled. + * Note that MaxMind's TOS requires that the databases be updated or removed periodically. + * + * @since 3.9.0 + * @param bool $bind_updater Whether or not the database should be updated periodically. + */ + $bind_updater = apply_filters( 'woocommerce_maxmind_geolocation_update_database_periodically', $bind_updater ); + + // Bind to the scheduled updater action. + if ( $bind_updater ) { + add_action( 'woocommerce_geoip_updater', array( $this, 'update_database' ) ); + } + + // Bind to the geolocation filter for MaxMind database lookups. + add_filter( 'woocommerce_get_geolocation', array( $this, 'get_geolocation' ), 10, 2 ); + } + + /** + * Override the normal options so we can print the database file path to the admin, + */ + public function admin_options() { + parent::admin_options(); + + include dirname( __FILE__ ) . '/views/html-admin-options.php'; + } + + /** + * Initializes the settings fields. + */ + public function init_form_fields() { + $this->form_fields = array( + 'license_key' => array( + 'title' => __( 'MaxMind License Key', 'woocommerce' ), + 'type' => 'password', + 'description' => sprintf( + /* translators: %1$s: Documentation URL */ + __( + 'The key that will be used when dealing with MaxMind Geolocation services. You can read how to generate one in MaxMind Geolocation Integration documentation.', + 'woocommerce' + ), + 'https://docs.woocommerce.com/document/maxmind-geolocation-integration/' + ), + 'desc_tip' => false, + 'default' => '', + ), + ); + } + + /** + * Get database service. + * + * @return WC_Integration_MaxMind_Database_Service|null + */ + public function get_database_service() { + return $this->database_service; + } + + /** + * Checks to make sure that the license key is valid. + * + * @param string $key The key of the field. + * @param mixed $value The value of the field. + * @return mixed + * @throws Exception When the license key is invalid. + */ + public function validate_license_key_field( $key, $value ) { + // Trim whitespaces and strip slashes. + $value = $this->validate_password_field( $key, $value ); + + // Empty license keys have no need test downloading a database. + if ( empty( $value ) ) { + return $value; + } + + // Check the license key by attempting to download the Geolocation database. + $tmp_database_path = $this->database_service->download_database( $value ); + if ( is_wp_error( $tmp_database_path ) ) { + WC_Admin_Settings::add_error( $tmp_database_path->get_error_message() ); + + // Throw an exception to keep from changing this value. This will prevent + // users from accidentally losing their license key, which cannot + // be viewed again after generating. + throw new Exception( $tmp_database_path->get_error_message() ); + } + + // We may as well put this archive to good use, now that we've downloaded one. + self::update_database( $tmp_database_path ); + + // Remove missing license key notice. + $this->remove_missing_license_key_notice(); + + return $value; + } + + /** + * Updates the database used for geolocation queries. + * + * @param string|null $new_database_path The path to the new database file. Null will fetch a new archive. + */ + public function update_database( $new_database_path = null ) { + // Allow us to easily interact with the filesystem. + require_once ABSPATH . 'wp-admin/includes/file.php'; + WP_Filesystem(); + global $wp_filesystem; + + // Remove any existing archives to comply with the MaxMind TOS. + $target_database_path = $this->database_service->get_database_path(); + + // If there's no database path, we can't store the database. + if ( empty( $target_database_path ) ) { + return; + } + + if ( $wp_filesystem->exists( $target_database_path ) ) { + $wp_filesystem->delete( $target_database_path ); + } + + if ( isset( $new_database_path ) ) { + $tmp_database_path = $new_database_path; + } else { + // We can't download a database if there's no license key configured. + $license_key = $this->get_option( 'license_key' ); + if ( empty( $license_key ) ) { + return; + } + + $tmp_database_path = $this->database_service->download_database( $license_key ); + if ( is_wp_error( $tmp_database_path ) ) { + wc_get_logger()->notice( $tmp_database_path->get_error_message(), array( 'source' => 'maxmind-geolocation' ) ); + return; + } + } + + // Move the new database into position. + $wp_filesystem->move( $tmp_database_path, $target_database_path, true ); + $wp_filesystem->delete( dirname( $tmp_database_path ) ); + } + + /** + * Performs a geolocation lookup against the MaxMind database for the given IP address. + * + * @param array $data Geolocation data. + * @param string $ip_address The IP address to geolocate. + * @return array Geolocation including country code, state, city and postcode based on an IP address. + */ + public function get_geolocation( $data, $ip_address ) { + // WooCommerce look for headers first, and at this moment could be just enough. + if ( ! empty( $data['country'] ) ) { + return $data; + } + + if ( empty( $ip_address ) ) { + return $data; + } + + $country_code = $this->database_service->get_iso_country_code_for_ip( $ip_address ); + + return array( + 'country' => $country_code, + 'state' => '', + 'city' => '', + 'postcode' => '', + ); + } + + /** + * Fetches the prefix for the MaxMind database file. + * + * @return string + */ + private function get_database_prefix() { + $prefix = $this->get_option( 'database_prefix' ); + if ( empty( $prefix ) ) { + $prefix = wp_generate_password( 32, false ); + $this->update_option( 'database_prefix', $prefix ); + } + + return $prefix; + } + + /** + * Add missing license key notice. + */ + private function add_missing_license_key_notice() { + if ( ! class_exists( 'WC_Admin_Notices' ) ) { + include_once WC_ABSPATH . 'includes/admin/class-wc-admin-notices.php'; + } + WC_Admin_Notices::add_notice( 'maxmind_license_key' ); + } + + /** + * Remove missing license key notice. + */ + private function remove_missing_license_key_notice() { + if ( ! class_exists( 'WC_Admin_Notices' ) ) { + include_once WC_ABSPATH . 'includes/admin/class-wc-admin-notices.php'; + } + WC_Admin_Notices::remove_notice( 'maxmind_license_key' ); + } + + /** + * Display notice if license key is missing. + * + * @param mixed $old_value Option old value. + * @param mixed $new_value Current value. + */ + public function display_missing_license_key_notice( $old_value, $new_value ) { + if ( ! apply_filters( 'woocommerce_maxmind_geolocation_display_notices', true ) ) { + return; + } + + if ( ! in_array( $new_value, array( 'geolocation', 'geolocation_ajax' ), true ) ) { + $this->remove_missing_license_key_notice(); + return; + } + + $license_key = $this->get_option( 'license_key' ); + if ( ! empty( $license_key ) ) { + return; + } + + $this->add_missing_license_key_notice(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/integrations/maxmind-geolocation/views/html-admin-options.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/integrations/maxmind-geolocation/views/html-admin-options.php new file mode 100644 index 0000000..a027e00 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/integrations/maxmind-geolocation/views/html-admin-options.php @@ -0,0 +1,25 @@ + + + + + + + +
    + + +
    + + +

    +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-abstract-order-data-store-interface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-abstract-order-data-store-interface.php new file mode 100644 index 0000000..c043c34 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-abstract-order-data-store-interface.php @@ -0,0 +1,54 @@ + [], 'failed' => []] + * + * @return array + */ + public function import(); + + /** + * Get file raw keys. + * + * CSV - Headers. + * XML - Element names. + * JSON - Keys + * + * @return array + */ + public function get_raw_keys(); + + /** + * Get file mapped headers. + * + * @return array + */ + public function get_mapped_keys(); + + /** + * Get raw data. + * + * @return array + */ + public function get_raw_data(); + + /** + * Get parsed data. + * + * @return array + */ + public function get_parsed_data(); + + /** + * Get file pointer position from the last read. + * + * @return int + */ + public function get_file_position(); + + /** + * Get file pointer position as a percentage of file size. + * + * @return int + */ + public function get_percent_complete(); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-log-handler-interface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-log-handler-interface.php new file mode 100644 index 0000000..d84e397 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-log-handler-interface.php @@ -0,0 +1,33 @@ +id). + * @return array + */ + public function delete_meta( &$data, $meta ); + + /** + * Add new piece of meta. + * + * @param WC_Data $data Data object. + * @param object $meta Meta object (containing ->key and ->value). + * @return int meta ID + */ + public function add_meta( &$data, $meta ); + + /** + * Update meta. + * + * @param WC_Data $data Data object. + * @param object $meta Meta object (containing ->id, ->key and ->value). + */ + public function update_meta( &$data, $meta ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-order-data-store-interface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-order-data-store-interface.php new file mode 100644 index 0000000..6f00c8a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-order-data-store-interface.php @@ -0,0 +1,141 @@ +get_id() will be set. + * + * @param WC_Order_Item $item Item object. + */ + public function save_item_data( &$item ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-order-refund-data-store-interface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-order-refund-data-store-interface.php new file mode 100644 index 0000000..b97864d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-order-refund-data-store-interface.php @@ -0,0 +1,21 @@ +id, $return[0]->parent_id. + * + * @return array + */ + public function get_on_sale_products(); + + /** + * Returns a list of product IDs ( id as key => parent as value) that are + * featured. Uses get_posts instead of wc_get_products since we want + * some extra meta queries and ALL products (posts_per_page = -1). + * + * @return array + */ + public function get_featured_product_ids(); + + /** + * Check if product sku is found for any other product IDs. + * + * @param int $product_id Product ID. + * @param string $sku SKU. + * @return bool + */ + public function is_existing_sku( $product_id, $sku ); + + /** + * Return product ID based on SKU. + * + * @param string $sku SKU. + * @return int + */ + public function get_product_id_by_sku( $sku ); + + /** + * Returns an array of IDs of products that have sales starting soon. + * + * @return array + */ + public function get_starting_sales(); + + /** + * Returns an array of IDs of products that have sales which are due to end. + * + * @return array + */ + public function get_ending_sales(); + + /** + * Find a matching (enabled) variation within a variable product. + * + * @param WC_Product $product Variable product object. + * @param array $match_attributes Array of attributes we want to try to match. + * @return int Matching variation ID or 0. + */ + public function find_matching_product_variation( $product, $match_attributes = array() ); + + /** + * Make sure all variations have a sort order set so they can be reordered correctly. + * + * @param int $parent_id Parent ID. + */ + public function sort_all_product_variations( $parent_id ); + + /** + * Return a list of related products (using data like categories and IDs). + * + * @param array $cats_array List of categories IDs. + * @param array $tags_array List of tags IDs. + * @param array $exclude_ids Excluded IDs. + * @param int $limit Limit of results. + * @param int $product_id Product ID. + * @return array + */ + public function get_related_products( $cats_array, $tags_array, $exclude_ids, $limit, $product_id ); + + /** + * Update a product's stock amount directly. + * + * Uses queries rather than update_post_meta so we can do this in one query (to avoid stock issues). + * + * @param int $product_id_with_stock Product ID. + * @param int|null $stock_quantity Stock quantity to update to. + * @param string $operation Either set, increase or decrease. + */ + public function update_product_stock( $product_id_with_stock, $stock_quantity = null, $operation = 'set' ); + + /** + * Update a product's sale count directly. + * + * Uses queries rather than update_post_meta so we can do this in one query for performance. + * + * @param int $product_id Product ID. + * @param int|null $quantity Stock quantity to use for update. + * @param string $operation Either set, increase or decrease. + */ + public function update_product_sales( $product_id, $quantity = null, $operation = 'set' ); + + /** + * Get shipping class ID by slug. + * + * @param string $slug Shipping class slug. + * @return int|false + */ + public function get_shipping_class_id_by_slug( $slug ); + + /** + * Returns an array of products. + * + * @param array $args @see wc_get_products. + * @return array + */ + public function get_products( $args = array() ); + + /** + * Get the product type based on product ID. + * + * @param int $product_id Product ID. + * @return bool|string + */ + public function get_product_type( $product_id ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-product-variable-data-store-interface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-product-variable-data-store-interface.php new file mode 100644 index 0000000..b22893d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-product-variable-data-store-interface.php @@ -0,0 +1,83 @@ + '' - the name of the action that will be triggered. + * 'args' => null - the args array that will be passed with the action. + * 'date' => null - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. + * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '='. + * 'modified' => null - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. + * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '='. + * 'group' => '' - the group the action belongs to. + * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING. + * 'claimed' => null - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID. + * 'per_page' => 5 - Number of results to return. + * 'offset' => 0. + * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date'. + * 'order' => 'ASC'. + * @param string $return_format OBJECT, ARRAY_A, or ids. + * @return array + */ + public function search( $args = array(), $return_format = OBJECT ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-shipping-zone-data-store-interface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-shipping-zone-data-store-interface.php new file mode 100644 index 0000000..7009c5b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/interfaces/class-wc-shipping-zone-data-store-interface.php @@ -0,0 +1,85 @@ +set_props( array( + 'code' => $code, + 'discount' => $discount, + 'discount_tax' => $discount_tax, + 'order_id' => $this->get_id(), + ) ); + $item->save(); + $this->add_item( $item ); + wc_do_deprecated_action( 'woocommerce_order_add_coupon', array( $this->get_id(), $item->get_id(), $code, $discount, $discount_tax ), '3.0', 'woocommerce_new_order_item action instead.' ); + return $item->get_id(); + } + + /** + * Add a tax row to the order. + * @param int $tax_rate_id + * @param int $tax_amount amount of tax. + * @param int $shipping_tax_amount shipping amount. + * @return int order item ID + * @throws WC_Data_Exception + */ + public function add_tax( $tax_rate_id, $tax_amount = 0, $shipping_tax_amount = 0 ) { + wc_deprecated_function( 'WC_Order::add_tax', '3.0', 'a new WC_Order_Item_Tax object and add to order with WC_Order::add_item()' ); + + $item = new WC_Order_Item_Tax(); + $item->set_props( array( + 'rate_id' => $tax_rate_id, + 'tax_total' => $tax_amount, + 'shipping_tax_total' => $shipping_tax_amount, + ) ); + $item->set_rate( $tax_rate_id ); + $item->set_order_id( $this->get_id() ); + $item->save(); + $this->add_item( $item ); + wc_do_deprecated_action( 'woocommerce_order_add_tax', array( $this->get_id(), $item->get_id(), $tax_rate_id, $tax_amount, $shipping_tax_amount ), '3.0', 'woocommerce_new_order_item action instead.' ); + return $item->get_id(); + } + + /** + * Add a shipping row to the order. + * @param WC_Shipping_Rate shipping_rate + * @return int order item ID + * @throws WC_Data_Exception + */ + public function add_shipping( $shipping_rate ) { + wc_deprecated_function( 'WC_Order::add_shipping', '3.0', 'a new WC_Order_Item_Shipping object and add to order with WC_Order::add_item()' ); + + $item = new WC_Order_Item_Shipping(); + $item->set_props( array( + 'method_title' => $shipping_rate->label, + 'method_id' => $shipping_rate->id, + 'total' => wc_format_decimal( $shipping_rate->cost ), + 'taxes' => $shipping_rate->taxes, + 'order_id' => $this->get_id(), + ) ); + foreach ( $shipping_rate->get_meta_data() as $key => $value ) { + $item->add_meta_data( $key, $value, true ); + } + $item->save(); + $this->add_item( $item ); + wc_do_deprecated_action( 'woocommerce_order_add_shipping', array( $this->get_id(), $item->get_id(), $shipping_rate ), '3.0', 'woocommerce_new_order_item action instead.' ); + return $item->get_id(); + } + + /** + * Add a fee to the order. + * Order must be saved prior to adding items. + * + * Fee is an amount of money charged for a particular piece of work + * or for a particular right or service, and not supposed to be negative. + * + * @throws WC_Data_Exception + * @param object $fee Fee data. + * @return int Updated order item ID. + */ + public function add_fee( $fee ) { + wc_deprecated_function( 'WC_Order::add_fee', '3.0', 'a new WC_Order_Item_Fee object and add to order with WC_Order::add_item()' ); + + $item = new WC_Order_Item_Fee(); + $item->set_props( array( + 'name' => $fee->name, + 'tax_class' => $fee->taxable ? $fee->tax_class : 0, + 'total' => $fee->amount, + 'total_tax' => $fee->tax, + 'taxes' => array( + 'total' => $fee->tax_data, + ), + 'order_id' => $this->get_id(), + ) ); + $item->save(); + $this->add_item( $item ); + wc_do_deprecated_action( 'woocommerce_order_add_fee', array( $this->get_id(), $item->get_id(), $fee ), '3.0', 'woocommerce_new_order_item action instead.' ); + return $item->get_id(); + } + + /** + * Update a line item for the order. + * + * Note this does not update order totals. + * + * @param object|int $item order item ID or item object. + * @param WC_Product $product + * @param array $args data to update. + * @return int updated order item ID + * @throws WC_Data_Exception + */ + public function update_product( $item, $product, $args ) { + wc_deprecated_function( 'WC_Order::update_product', '3.0', 'an interaction with the WC_Order_Item_Product class' ); + if ( is_numeric( $item ) ) { + $item = $this->get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'line_item' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + // BW compatibility with old args + if ( isset( $args['totals'] ) ) { + foreach ( $args['totals'] as $key => $value ) { + if ( 'tax' === $key ) { + $args['total_tax'] = $value; + } elseif ( 'tax_data' === $key ) { + $args['taxes'] = $value; + } else { + $args[ $key ] = $value; + } + } + } + + // Handle qty if set. + if ( isset( $args['qty'] ) ) { + if ( $product->backorders_require_notification() && $product->is_on_backorder( $args['qty'] ) ) { + $item->add_meta_data( apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ), $item ), $args['qty'] - max( 0, $product->get_stock_quantity() ), true ); + } + $args['subtotal'] = $args['subtotal'] ? $args['subtotal'] : wc_get_price_excluding_tax( $product, array( 'qty' => $args['qty'] ) ); + $args['total'] = $args['total'] ? $args['total'] : wc_get_price_excluding_tax( $product, array( 'qty' => $args['qty'] ) ); + } + + $item->set_order_id( $this->get_id() ); + $item->set_props( $args ); + $item->save(); + do_action( 'woocommerce_order_edit_product', $this->get_id(), $item->get_id(), $args, $product ); + + return $item->get_id(); + } + + /** + * Update coupon for order. Note this does not update order totals. + * @param object|int $item + * @param array $args + * @return int updated order item ID + * @throws WC_Data_Exception + */ + public function update_coupon( $item, $args ) { + wc_deprecated_function( 'WC_Order::update_coupon', '3.0', 'an interaction with the WC_Order_Item_Coupon class' ); + if ( is_numeric( $item ) ) { + $item = $this->get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'coupon' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + // BW compatibility for old args + if ( isset( $args['discount_amount'] ) ) { + $args['discount'] = $args['discount_amount']; + } + if ( isset( $args['discount_amount_tax'] ) ) { + $args['discount_tax'] = $args['discount_amount_tax']; + } + + $item->set_order_id( $this->get_id() ); + $item->set_props( $args ); + $item->save(); + + do_action( 'woocommerce_order_update_coupon', $this->get_id(), $item->get_id(), $args ); + + return $item->get_id(); + } + + /** + * Update shipping method for order. + * + * Note this does not update the order total. + * + * @param object|int $item + * @param array $args + * @return int updated order item ID + * @throws WC_Data_Exception + */ + public function update_shipping( $item, $args ) { + wc_deprecated_function( 'WC_Order::update_shipping', '3.0', 'an interaction with the WC_Order_Item_Shipping class' ); + if ( is_numeric( $item ) ) { + $item = $this->get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'shipping' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + // BW compatibility for old args + if ( isset( $args['cost'] ) ) { + $args['total'] = $args['cost']; + } + + $item->set_order_id( $this->get_id() ); + $item->set_props( $args ); + $item->save(); + $this->calculate_shipping(); + + do_action( 'woocommerce_order_update_shipping', $this->get_id(), $item->get_id(), $args ); + + return $item->get_id(); + } + + /** + * Update fee for order. + * + * Note this does not update order totals. + * + * @param object|int $item + * @param array $args + * @return int updated order item ID + * @throws WC_Data_Exception + */ + public function update_fee( $item, $args ) { + wc_deprecated_function( 'WC_Order::update_fee', '3.0', 'an interaction with the WC_Order_Item_Fee class' ); + if ( is_numeric( $item ) ) { + $item = $this->get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'fee' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + $item->set_order_id( $this->get_id() ); + $item->set_props( $args ); + $item->save(); + + do_action( 'woocommerce_order_update_fee', $this->get_id(), $item->get_id(), $args ); + + return $item->get_id(); + } + + /** + * Update tax line on order. + * Note this does not update order totals. + * + * @since 3.0 + * @param object|int $item + * @param array $args + * @return int updated order item ID + * @throws WC_Data_Exception + */ + public function update_tax( $item, $args ) { + wc_deprecated_function( 'WC_Order::update_tax', '3.0', 'an interaction with the WC_Order_Item_Tax class' ); + if ( is_numeric( $item ) ) { + $item = $this->get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'tax' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + $item->set_order_id( $this->get_id() ); + $item->set_props( $args ); + $item->save(); + + do_action( 'woocommerce_order_update_tax', $this->get_id(), $item->get_id(), $args ); + + return $item->get_id(); + } + + /** + * Get a product (either product or variation). + * @deprecated 4.4.0 + * @param object $item + * @return WC_Product|bool + */ + public function get_product_from_item( $item ) { + wc_deprecated_function( 'WC_Abstract_Legacy_Order::get_product_from_item', '4.4.0', '$item->get_product()' ); + if ( is_callable( array( $item, 'get_product' ) ) ) { + $product = $item->get_product(); + } else { + $product = false; + } + return apply_filters( 'woocommerce_get_product_from_item', $product, $item, $this ); + } + + /** + * Set the customer address. + * @param array $address Address data. + * @param string $type billing or shipping. + */ + public function set_address( $address, $type = 'billing' ) { + foreach ( $address as $key => $value ) { + update_post_meta( $this->get_id(), "_{$type}_" . $key, $value ); + if ( is_callable( array( $this, "set_{$type}_{$key}" ) ) ) { + $this->{"set_{$type}_{$key}"}( $value ); + } + } + } + + /** + * Set an order total. + * @param float $amount + * @param string $total_type + * @return bool + */ + public function legacy_set_total( $amount, $total_type = 'total' ) { + if ( ! in_array( $total_type, array( 'shipping', 'tax', 'shipping_tax', 'total', 'cart_discount', 'cart_discount_tax' ) ) ) { + return false; + } + + switch ( $total_type ) { + case 'total' : + $amount = wc_format_decimal( $amount, wc_get_price_decimals() ); + $this->set_total( $amount ); + update_post_meta( $this->get_id(), '_order_total', $amount ); + break; + case 'cart_discount' : + $amount = wc_format_decimal( $amount ); + $this->set_discount_total( $amount ); + update_post_meta( $this->get_id(), '_cart_discount', $amount ); + break; + case 'cart_discount_tax' : + $amount = wc_format_decimal( $amount ); + $this->set_discount_tax( $amount ); + update_post_meta( $this->get_id(), '_cart_discount_tax', $amount ); + break; + case 'shipping' : + $amount = wc_format_decimal( $amount ); + $this->set_shipping_total( $amount ); + update_post_meta( $this->get_id(), '_order_shipping', $amount ); + break; + case 'shipping_tax' : + $amount = wc_format_decimal( $amount ); + $this->set_shipping_tax( $amount ); + update_post_meta( $this->get_id(), '_order_shipping_tax', $amount ); + break; + case 'tax' : + $amount = wc_format_decimal( $amount ); + $this->set_cart_tax( $amount ); + update_post_meta( $this->get_id(), '_order_tax', $amount ); + break; + } + + return true; + } + + /** + * Magic __isset method for backwards compatibility. Handles legacy properties which could be accessed directly in the past. + * + * @param string $key + * @return bool + */ + public function __isset( $key ) { + $legacy_props = array( 'completed_date', 'id', 'order_type', 'post', 'status', 'post_status', 'customer_note', 'customer_message', 'user_id', 'customer_user', 'prices_include_tax', 'tax_display_cart', 'display_totals_ex_tax', 'display_cart_ex_tax', 'order_date', 'modified_date', 'cart_discount', 'cart_discount_tax', 'order_shipping', 'order_shipping_tax', 'order_total', 'order_tax', 'billing_first_name', 'billing_last_name', 'billing_company', 'billing_address_1', 'billing_address_2', 'billing_city', 'billing_state', 'billing_postcode', 'billing_country', 'billing_phone', 'billing_email', 'shipping_first_name', 'shipping_last_name', 'shipping_company', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_state', 'shipping_postcode', 'shipping_country', 'customer_ip_address', 'customer_user_agent', 'payment_method_title', 'payment_method', 'order_currency' ); + return $this->get_id() ? ( in_array( $key, $legacy_props ) || metadata_exists( 'post', $this->get_id(), '_' . $key ) ) : false; + } + + /** + * Magic __get method for backwards compatibility. + * + * @param string $key + * @return mixed + */ + public function __get( $key ) { + wc_doing_it_wrong( $key, 'Order properties should not be accessed directly.', '3.0' ); + + if ( 'completed_date' === $key ) { + return $this->get_date_completed() ? gmdate( 'Y-m-d H:i:s', $this->get_date_completed()->getOffsetTimestamp() ) : ''; + } elseif ( 'paid_date' === $key ) { + return $this->get_date_paid() ? gmdate( 'Y-m-d H:i:s', $this->get_date_paid()->getOffsetTimestamp() ) : ''; + } elseif ( 'modified_date' === $key ) { + return $this->get_date_modified() ? gmdate( 'Y-m-d H:i:s', $this->get_date_modified()->getOffsetTimestamp() ) : ''; + } elseif ( 'order_date' === $key ) { + return $this->get_date_created() ? gmdate( 'Y-m-d H:i:s', $this->get_date_created()->getOffsetTimestamp() ) : ''; + } elseif ( 'id' === $key ) { + return $this->get_id(); + } elseif ( 'post' === $key ) { + return get_post( $this->get_id() ); + } elseif ( 'status' === $key ) { + return $this->get_status(); + } elseif ( 'post_status' === $key ) { + return get_post_status( $this->get_id() ); + } elseif ( 'customer_message' === $key || 'customer_note' === $key ) { + return $this->get_customer_note(); + } elseif ( in_array( $key, array( 'user_id', 'customer_user' ) ) ) { + return $this->get_customer_id(); + } elseif ( 'tax_display_cart' === $key ) { + return get_option( 'woocommerce_tax_display_cart' ); + } elseif ( 'display_totals_ex_tax' === $key ) { + return 'excl' === get_option( 'woocommerce_tax_display_cart' ); + } elseif ( 'display_cart_ex_tax' === $key ) { + return 'excl' === get_option( 'woocommerce_tax_display_cart' ); + } elseif ( 'cart_discount' === $key ) { + return $this->get_total_discount(); + } elseif ( 'cart_discount_tax' === $key ) { + return $this->get_discount_tax(); + } elseif ( 'order_tax' === $key ) { + return $this->get_cart_tax(); + } elseif ( 'order_shipping_tax' === $key ) { + return $this->get_shipping_tax(); + } elseif ( 'order_shipping' === $key ) { + return $this->get_shipping_total(); + } elseif ( 'order_total' === $key ) { + return $this->get_total(); + } elseif ( 'order_type' === $key ) { + return $this->get_type(); + } elseif ( 'order_currency' === $key ) { + return $this->get_currency(); + } elseif ( 'order_version' === $key ) { + return $this->get_version(); + } elseif ( is_callable( array( $this, "get_{$key}" ) ) ) { + return $this->{"get_{$key}"}(); + } else { + return get_post_meta( $this->get_id(), '_' . $key, true ); + } + } + + /** + * has_meta function for order items. This is different to the WC_Data + * version and should be removed in future versions. + * + * @deprecated 3.0 + * + * @param int $order_item_id + * + * @return array of meta data. + */ + public function has_meta( $order_item_id ) { + global $wpdb; + + wc_deprecated_function( 'WC_Order::has_meta( $order_item_id )', '3.0', 'WC_Order_item::get_meta_data' ); + + return $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value, meta_id, order_item_id + FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id = %d + ORDER BY meta_id", absint( $order_item_id ) ), ARRAY_A ); + } + + /** + * Display meta data belonging to an item. + * @param array $item + */ + public function display_item_meta( $item ) { + wc_deprecated_function( 'WC_Order::display_item_meta', '3.0', 'wc_display_item_meta' ); + $product = $item->get_product(); + $item_meta = new WC_Order_Item_Meta( $item, $product ); + $item_meta->display(); + } + + /** + * Display download links for an order item. + * @param array $item + */ + public function display_item_downloads( $item ) { + wc_deprecated_function( 'WC_Order::display_item_downloads', '3.0', 'wc_display_item_downloads' ); + $product = $item->get_product(); + + if ( $product && $product->exists() && $product->is_downloadable() && $this->is_download_permitted() ) { + $download_files = $this->get_item_downloads( $item ); + $i = 0; + $links = array(); + + foreach ( $download_files as $download_id => $file ) { + $i++; + /* translators: 1: current item count */ + $prefix = count( $download_files ) > 1 ? sprintf( __( 'Download %d', 'woocommerce' ), $i ) : __( 'Download', 'woocommerce' ); + $links[] = '' . esc_html( $prefix ) . ': ' . esc_html( $file['name'] ) . '' . "\n"; + } + + echo '
    ' . implode( '
    ', $links ); + } + } + + /** + * Get the Download URL. + * + * @param int $product_id + * @param int $download_id + * @return string + */ + public function get_download_url( $product_id, $download_id ) { + wc_deprecated_function( 'WC_Order::get_download_url', '3.0', 'WC_Order_Item_Product::get_item_download_url' ); + return add_query_arg( array( + 'download_file' => $product_id, + 'order' => $this->get_order_key(), + 'email' => urlencode( $this->get_billing_email() ), + 'key' => $download_id, + ), trailingslashit( home_url() ) ); + } + + /** + * Get the downloadable files for an item in this order. + * + * @param array $item + * @return array + */ + public function get_item_downloads( $item ) { + wc_deprecated_function( 'WC_Order::get_item_downloads', '3.0', 'WC_Order_Item_Product::get_item_downloads' ); + + if ( ! $item instanceof WC_Order_Item ) { + if ( ! empty( $item['variation_id'] ) ) { + $product_id = $item['variation_id']; + } elseif ( ! empty( $item['product_id'] ) ) { + $product_id = $item['product_id']; + } else { + return array(); + } + + // Create a 'virtual' order item to allow retrieving item downloads when + // an array of product_id is passed instead of actual order item. + $item = new WC_Order_Item_Product(); + $item->set_product( wc_get_product( $product_id ) ); + $item->set_order_id( $this->get_id() ); + } + + return $item->get_item_downloads(); + } + + /** + * Gets shipping total. Alias of WC_Order::get_shipping_total(). + * @deprecated 3.0.0 since this is an alias only. + * @return float + */ + public function get_total_shipping() { + return $this->get_shipping_total(); + } + + /** + * Get order item meta. + * @deprecated 3.0.0 + * @param mixed $order_item_id + * @param string $key (default: '') + * @param bool $single (default: false) + * @return array|string + */ + public function get_item_meta( $order_item_id, $key = '', $single = false ) { + wc_deprecated_function( 'WC_Order::get_item_meta', '3.0', 'wc_get_order_item_meta' ); + return get_metadata( 'order_item', $order_item_id, $key, $single ); + } + + /** + * Get all item meta data in array format in the order it was saved. Does not group meta by key like get_item_meta(). + * + * @param mixed $order_item_id + * @return array of objects + */ + public function get_item_meta_array( $order_item_id ) { + wc_deprecated_function( 'WC_Order::get_item_meta_array', '3.0', 'WC_Order_Item::get_meta_data() (note the format has changed)' ); + $item = $this->get_item( $order_item_id ); + $meta_data = $item->get_meta_data(); + $item_meta_array = array(); + + foreach ( $meta_data as $meta ) { + $item_meta_array[ $meta->id ] = $meta; + } + + return $item_meta_array; + } + + /** + * Get coupon codes only. + * + * @deprecated 3.7.0 - Replaced with better named method to reflect the actual data being returned. + * @return array + */ + public function get_used_coupons() { + wc_deprecated_function( 'get_used_coupons', '3.7', 'WC_Abstract_Order::get_coupon_codes' ); + return $this->get_coupon_codes(); + } + + /** + * Expand item meta into the $item array. + * @deprecated 3.0.0 Item meta no longer expanded due to new order item + * classes. This function now does nothing to avoid data breakage. + * @param array $item before expansion. + * @return array + */ + public function expand_item_meta( $item ) { + wc_deprecated_function( 'WC_Order::expand_item_meta', '3.0' ); + return $item; + } + + /** + * Load the order object. Called from the constructor. + * @deprecated 3.0.0 Logic moved to constructor + * @param int|object|WC_Order $order Order to init. + */ + protected function init( $order ) { + wc_deprecated_function( 'WC_Order::init', '3.0', 'Logic moved to constructor' ); + if ( is_numeric( $order ) ) { + $this->set_id( $order ); + } elseif ( $order instanceof WC_Order ) { + $this->set_id( absint( $order->get_id() ) ); + } elseif ( isset( $order->ID ) ) { + $this->set_id( absint( $order->ID ) ); + } + $this->set_object_read( false ); + $this->data_store->read( $this ); + } + + /** + * Gets an order from the database. + * @deprecated 3.0 + * @param int $id (default: 0). + * @return bool + */ + public function get_order( $id = 0 ) { + wc_deprecated_function( 'WC_Order::get_order', '3.0' ); + + if ( ! $id ) { + return false; + } + + $result = get_post( $id ); + + if ( $result ) { + $this->populate( $result ); + return true; + } + + return false; + } + + /** + * Populates an order from the loaded post data. + * @deprecated 3.0 + * @param mixed $result + */ + public function populate( $result ) { + wc_deprecated_function( 'WC_Order::populate', '3.0' ); + $this->set_id( $result->ID ); + $this->set_object_read( false ); + $this->data_store->read( $this ); + } + + /** + * Cancel the order and restore the cart (before payment). + * @deprecated 3.0.0 Moved to event handler. + * @param string $note (default: '') Optional note to add. + */ + public function cancel_order( $note = '' ) { + wc_deprecated_function( 'WC_Order::cancel_order', '3.0', 'WC_Order::update_status' ); + WC()->session->set( 'order_awaiting_payment', false ); + $this->update_status( 'cancelled', $note ); + } + + /** + * Record sales. + * @deprecated 3.0.0 + */ + public function record_product_sales() { + wc_deprecated_function( 'WC_Order::record_product_sales', '3.0', 'wc_update_total_sales_counts' ); + wc_update_total_sales_counts( $this->get_id() ); + } + + /** + * Increase applied coupon counts. + * @deprecated 3.0.0 + */ + public function increase_coupon_usage_counts() { + wc_deprecated_function( 'WC_Order::increase_coupon_usage_counts', '3.0', 'wc_update_coupon_usage_counts' ); + wc_update_coupon_usage_counts( $this->get_id() ); + } + + /** + * Decrease applied coupon counts. + * @deprecated 3.0.0 + */ + public function decrease_coupon_usage_counts() { + wc_deprecated_function( 'WC_Order::decrease_coupon_usage_counts', '3.0', 'wc_update_coupon_usage_counts' ); + wc_update_coupon_usage_counts( $this->get_id() ); + } + + /** + * Reduce stock levels for all line items in the order. + * @deprecated 3.0.0 + */ + public function reduce_order_stock() { + wc_deprecated_function( 'WC_Order::reduce_order_stock', '3.0', 'wc_reduce_stock_levels' ); + wc_reduce_stock_levels( $this->get_id() ); + } + + /** + * Send the stock notifications. + * @deprecated 3.0.0 No longer needs to be called directly. + * + * @param $product + * @param $new_stock + * @param $qty_ordered + */ + public function send_stock_notifications( $product, $new_stock, $qty_ordered ) { + wc_deprecated_function( 'WC_Order::send_stock_notifications', '3.0' ); + } + + /** + * Output items for display in html emails. + * @deprecated 3.0.0 Moved to template functions. + * @param array $args Items args. + * @return string + */ + public function email_order_items_table( $args = array() ) { + wc_deprecated_function( 'WC_Order::email_order_items_table', '3.0', 'wc_get_email_order_items' ); + return wc_get_email_order_items( $this, $args ); + } + + /** + * Get currency. + * @deprecated 3.0.0 + */ + public function get_order_currency() { + wc_deprecated_function( 'WC_Order::get_order_currency', '3.0', 'WC_Order::get_currency' ); + return apply_filters( 'woocommerce_get_order_currency', $this->get_currency(), $this ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/abstract-wc-legacy-payment-token.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/abstract-wc-legacy-payment-token.php new file mode 100644 index 0000000..ed7201a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/abstract-wc-legacy-payment-token.php @@ -0,0 +1,70 @@ +read, ->update or ->create + * directly on the object. + * + * @version 3.0.0 + * @package WooCommerce\Classes + * @category Class + * @author WooCommerce + */ +abstract class WC_Legacy_Payment_Token extends WC_Data { + + /** + * Sets the type of this payment token (CC, eCheck, or something else). + * + * @param string Payment Token Type (CC, eCheck) + */ + public function set_type( $type ) { + wc_deprecated_function( 'WC_Payment_Token::set_type', '3.0.0', 'Type cannot be overwritten.' ); + } + + /** + * Read a token by ID. + * @deprecated 3.0.0 - Init a token class with an ID. + * + * @param int $token_id + */ + public function read( $token_id ) { + wc_deprecated_function( 'WC_Payment_Token::read', '3.0.0', 'a new token class initialized with an ID.' ); + $this->set_id( $token_id ); + $data_store = WC_Data_Store::load( 'payment-token' ); + $data_store->read( $this ); + } + + /** + * Update a token. + * @deprecated 3.0.0 - Use ::save instead. + */ + public function update() { + wc_deprecated_function( 'WC_Payment_Token::update', '3.0.0', 'WC_Payment_Token::save instead.' ); + $data_store = WC_Data_Store::load( 'payment-token' ); + try { + $data_store->update( $this ); + } catch ( Exception $e ) { + return false; + } + } + + /** + * Create a token. + * @deprecated 3.0.0 - Use ::save instead. + */ + public function create() { + wc_deprecated_function( 'WC_Payment_Token::create', '3.0.0', 'WC_Payment_Token::save instead.' ); + $data_store = WC_Data_Store::load( 'payment-token' ); + try { + $data_store->create( $this ); + } catch ( Exception $e ) { + return false; + } + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/abstract-wc-legacy-product.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/abstract-wc-legacy-product.php new file mode 100644 index 0000000..97f370e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/abstract-wc-legacy-product.php @@ -0,0 +1,692 @@ +is_type( 'variation' ) ) { + $valid = array_merge( $valid, array( + 'variation_id', + 'variation_data', + 'variation_has_stock', + 'variation_shipping_class_id', + 'variation_has_sku', + 'variation_has_length', + 'variation_has_width', + 'variation_has_height', + 'variation_has_weight', + 'variation_has_tax_class', + 'variation_has_downloadable_files', + ) ); + } + return in_array( $key, array_merge( $valid, array_keys( $this->data ) ) ) || metadata_exists( 'post', $this->get_id(), '_' . $key ) || metadata_exists( 'post', $this->get_parent_id(), '_' . $key ); + } + + /** + * Magic __get method for backwards compatibility. Maps legacy vars to new getters. + * + * @param string $key Key name. + * @return mixed + */ + public function __get( $key ) { + + if ( 'post_type' === $key ) { + return $this->post_type; + } + + wc_doing_it_wrong( $key, __( 'Product properties should not be accessed directly.', 'woocommerce' ), '3.0' ); + + switch ( $key ) { + case 'id' : + $value = $this->is_type( 'variation' ) ? $this->get_parent_id() : $this->get_id(); + break; + case 'product_type' : + $value = $this->get_type(); + break; + case 'product_attributes' : + $value = isset( $this->data['attributes'] ) ? $this->data['attributes'] : ''; + break; + case 'visibility' : + $value = $this->get_catalog_visibility(); + break; + case 'sale_price_dates_from' : + return $this->get_date_on_sale_from() ? $this->get_date_on_sale_from()->getTimestamp() : ''; + break; + case 'sale_price_dates_to' : + return $this->get_date_on_sale_to() ? $this->get_date_on_sale_to()->getTimestamp() : ''; + break; + case 'post' : + $value = get_post( $this->get_id() ); + break; + case 'download_type' : + return 'standard'; + break; + case 'product_image_gallery' : + $value = $this->get_gallery_image_ids(); + break; + case 'variation_shipping_class' : + case 'shipping_class' : + $value = $this->get_shipping_class(); + break; + case 'total_stock' : + $value = $this->get_total_stock(); + break; + case 'downloadable' : + case 'virtual' : + case 'manage_stock' : + case 'featured' : + case 'sold_individually' : + $value = $this->{"get_$key"}() ? 'yes' : 'no'; + break; + case 'crosssell_ids' : + $value = $this->get_cross_sell_ids(); + break; + case 'upsell_ids' : + $value = $this->get_upsell_ids(); + break; + case 'parent' : + $value = wc_get_product( $this->get_parent_id() ); + break; + case 'variation_id' : + $value = $this->is_type( 'variation' ) ? $this->get_id() : ''; + break; + case 'variation_data' : + $value = $this->is_type( 'variation' ) ? wc_get_product_variation_attributes( $this->get_id() ) : ''; + break; + case 'variation_has_stock' : + $value = $this->is_type( 'variation' ) ? $this->managing_stock() : ''; + break; + case 'variation_shipping_class_id' : + $value = $this->is_type( 'variation' ) ? $this->get_shipping_class_id() : ''; + break; + case 'variation_has_sku' : + case 'variation_has_length' : + case 'variation_has_width' : + case 'variation_has_height' : + case 'variation_has_weight' : + case 'variation_has_tax_class' : + case 'variation_has_downloadable_files' : + $value = true; // These were deprecated in 2.2 and simply returned true in 2.6.x. + break; + default : + if ( in_array( $key, array_keys( $this->data ) ) ) { + $value = $this->{"get_$key"}(); + } else { + $value = get_post_meta( $this->id, '_' . $key, true ); + } + break; + } + return $value; + } + + /** + * If set, get the default attributes for a variable product. + * + * @deprecated 3.0.0 + * @return array + */ + public function get_variation_default_attributes() { + wc_deprecated_function( 'WC_Product_Variable::get_variation_default_attributes', '3.0', 'WC_Product::get_default_attributes' ); + return apply_filters( 'woocommerce_product_default_attributes', $this->get_default_attributes(), $this ); + } + + /** + * Returns the gallery attachment ids. + * + * @deprecated 3.0.0 + * @return array + */ + public function get_gallery_attachment_ids() { + wc_deprecated_function( 'WC_Product::get_gallery_attachment_ids', '3.0', 'WC_Product::get_gallery_image_ids' ); + return $this->get_gallery_image_ids(); + } + + /** + * Set stock level of the product. + * + * @deprecated 3.0.0 + * + * @param int $amount + * @param string $mode + * + * @return int + */ + public function set_stock( $amount = null, $mode = 'set' ) { + wc_deprecated_function( 'WC_Product::set_stock', '3.0', 'wc_update_product_stock' ); + return wc_update_product_stock( $this, $amount, $mode ); + } + + /** + * Reduce stock level of the product. + * + * @deprecated 3.0.0 + * @param int $amount Amount to reduce by. Default: 1 + * @return int new stock level + */ + public function reduce_stock( $amount = 1 ) { + wc_deprecated_function( 'WC_Product::reduce_stock', '3.0', 'wc_update_product_stock' ); + return wc_update_product_stock( $this, $amount, 'decrease' ); + } + + /** + * Increase stock level of the product. + * + * @deprecated 3.0.0 + * @param int $amount Amount to increase by. Default 1. + * @return int new stock level + */ + public function increase_stock( $amount = 1 ) { + wc_deprecated_function( 'WC_Product::increase_stock', '3.0', 'wc_update_product_stock' ); + return wc_update_product_stock( $this, $amount, 'increase' ); + } + + /** + * Check if the stock status needs changing. + * + * @deprecated 3.0.0 Sync is done automatically on read/save, so calling this should not be needed any more. + */ + public function check_stock_status() { + wc_deprecated_function( 'WC_Product::check_stock_status', '3.0' ); + } + + /** + * Get and return related products. + * @deprecated 3.0.0 Use wc_get_related_products instead. + * + * @param int $limit + * + * @return array + */ + public function get_related( $limit = 5 ) { + wc_deprecated_function( 'WC_Product::get_related', '3.0', 'wc_get_related_products' ); + return wc_get_related_products( $this->get_id(), $limit ); + } + + /** + * Retrieves related product terms. + * @deprecated 3.0.0 Use wc_get_product_term_ids instead. + * + * @param $term + * + * @return array + */ + protected function get_related_terms( $term ) { + wc_deprecated_function( 'WC_Product::get_related_terms', '3.0', 'wc_get_product_term_ids' ); + return array_merge( array( 0 ), wc_get_product_term_ids( $this->get_id(), $term ) ); + } + + /** + * Builds the related posts query. + * @deprecated 3.0.0 Use Product Data Store get_related_products_query instead. + * + * @param $cats_array + * @param $tags_array + * @param $exclude_ids + * @param $limit + */ + protected function build_related_query( $cats_array, $tags_array, $exclude_ids, $limit ) { + wc_deprecated_function( 'WC_Product::build_related_query', '3.0', 'Product Data Store get_related_products_query' ); + $data_store = WC_Data_Store::load( 'product' ); + return $data_store->get_related_products_query( $cats_array, $tags_array, $exclude_ids, $limit ); + } + + /** + * Returns the child product. + * @deprecated 3.0.0 Use wc_get_product instead. + * @param mixed $child_id + * @return WC_Product|WC_Product|WC_Product_variation + */ + public function get_child( $child_id ) { + wc_deprecated_function( 'WC_Product::get_child', '3.0', 'wc_get_product' ); + return wc_get_product( $child_id ); + } + + /** + * Functions for getting parts of a price, in html, used by get_price_html. + * + * @deprecated 3.0.0 + * @return string + */ + public function get_price_html_from_text() { + wc_deprecated_function( 'WC_Product::get_price_html_from_text', '3.0', 'wc_get_price_html_from_text' ); + return wc_get_price_html_from_text(); + } + + /** + * Functions for getting parts of a price, in html, used by get_price_html. + * + * @deprecated 3.0.0 Use wc_format_sale_price instead. + * @param string $from String or float to wrap with 'from' text + * @param mixed $to String or float to wrap with 'to' text + * @return string + */ + public function get_price_html_from_to( $from, $to ) { + wc_deprecated_function( 'WC_Product::get_price_html_from_to', '3.0', 'wc_format_sale_price' ); + return apply_filters( 'woocommerce_get_price_html_from_to', wc_format_sale_price( $from, $to ), $from, $to, $this ); + } + + /** + * Lists a table of attributes for the product page. + * @deprecated 3.0.0 Use wc_display_product_attributes instead. + */ + public function list_attributes() { + wc_deprecated_function( 'WC_Product::list_attributes', '3.0', 'wc_display_product_attributes' ); + wc_display_product_attributes( $this ); + } + + /** + * Returns the price (including tax). Uses customer tax rates. Can work for a specific $qty for more accurate taxes. + * + * @deprecated 3.0.0 Use wc_get_price_including_tax instead. + * @param int $qty + * @param string $price to calculate, left blank to just use get_price() + * @return string + */ + public function get_price_including_tax( $qty = 1, $price = '' ) { + wc_deprecated_function( 'WC_Product::get_price_including_tax', '3.0', 'wc_get_price_including_tax' ); + return wc_get_price_including_tax( $this, array( 'qty' => $qty, 'price' => $price ) ); + } + + /** + * Returns the price including or excluding tax, based on the 'woocommerce_tax_display_shop' setting. + * + * @deprecated 3.0.0 Use wc_get_price_to_display instead. + * @param string $price to calculate, left blank to just use get_price() + * @param integer $qty passed on to get_price_including_tax() or get_price_excluding_tax() + * @return string + */ + public function get_display_price( $price = '', $qty = 1 ) { + wc_deprecated_function( 'WC_Product::get_display_price', '3.0', 'wc_get_price_to_display' ); + return wc_get_price_to_display( $this, array( 'qty' => $qty, 'price' => $price ) ); + } + + /** + * Returns the price (excluding tax) - ignores tax_class filters since the price may *include* tax and thus needs subtracting. + * Uses store base tax rates. Can work for a specific $qty for more accurate taxes. + * + * @deprecated 3.0.0 Use wc_get_price_excluding_tax instead. + * @param int $qty + * @param string $price to calculate, left blank to just use get_price() + * @return string + */ + public function get_price_excluding_tax( $qty = 1, $price = '' ) { + wc_deprecated_function( 'WC_Product::get_price_excluding_tax', '3.0', 'wc_get_price_excluding_tax' ); + return wc_get_price_excluding_tax( $this, array( 'qty' => $qty, 'price' => $price ) ); + } + + /** + * Adjust a products price dynamically. + * + * @deprecated 3.0.0 + * @param mixed $price + */ + public function adjust_price( $price ) { + wc_deprecated_function( 'WC_Product::adjust_price', '3.0', 'WC_Product::set_price / WC_Product::get_price' ); + $this->data['price'] = $this->data['price'] + $price; + } + + /** + * Returns the product categories. + * + * @deprecated 3.0.0 + * @param string $sep (default: ', '). + * @param string $before (default: ''). + * @param string $after (default: ''). + * @return string + */ + public function get_categories( $sep = ', ', $before = '', $after = '' ) { + wc_deprecated_function( 'WC_Product::get_categories', '3.0', 'wc_get_product_category_list' ); + return wc_get_product_category_list( $this->get_id(), $sep, $before, $after ); + } + + /** + * Returns the product tags. + * + * @deprecated 3.0.0 + * @param string $sep (default: ', '). + * @param string $before (default: ''). + * @param string $after (default: ''). + * @return array + */ + public function get_tags( $sep = ', ', $before = '', $after = '' ) { + wc_deprecated_function( 'WC_Product::get_tags', '3.0', 'wc_get_product_tag_list' ); + return wc_get_product_tag_list( $this->get_id(), $sep, $before, $after ); + } + + /** + * Get the product's post data. + * + * @deprecated 3.0.0 + * @return WP_Post + */ + public function get_post_data() { + wc_deprecated_function( 'WC_Product::get_post_data', '3.0', 'get_post' ); + + // In order to keep backwards compatibility it's required to use the parent data for variations. + if ( $this->is_type( 'variation' ) ) { + $post_data = get_post( $this->get_parent_id() ); + } else { + $post_data = get_post( $this->get_id() ); + } + + return $post_data; + } + + /** + * Get the parent of the post. + * + * @deprecated 3.0.0 + * @return int + */ + public function get_parent() { + wc_deprecated_function( 'WC_Product::get_parent', '3.0', 'WC_Product::get_parent_id' ); + return apply_filters( 'woocommerce_product_parent', absint( $this->get_post_data()->post_parent ), $this ); + } + + /** + * Returns the upsell product ids. + * + * @deprecated 3.0.0 + * @return array + */ + public function get_upsells() { + wc_deprecated_function( 'WC_Product::get_upsells', '3.0', 'WC_Product::get_upsell_ids' ); + return apply_filters( 'woocommerce_product_upsell_ids', $this->get_upsell_ids(), $this ); + } + + /** + * Returns the cross sell product ids. + * + * @deprecated 3.0.0 + * @return array + */ + public function get_cross_sells() { + wc_deprecated_function( 'WC_Product::get_cross_sells', '3.0', 'WC_Product::get_cross_sell_ids' ); + return apply_filters( 'woocommerce_product_crosssell_ids', $this->get_cross_sell_ids(), $this ); + } + + /** + * Check if variable product has default attributes set. + * + * @deprecated 3.0.0 + * @return bool + */ + public function has_default_attributes() { + wc_deprecated_function( 'WC_Product_Variable::has_default_attributes', '3.0', 'a check against WC_Product::get_default_attributes directly' ); + if ( ! $this->get_default_attributes() ) { + return true; + } + return false; + } + + /** + * Get variation ID. + * + * @deprecated 3.0.0 + * @return int + */ + public function get_variation_id() { + wc_deprecated_function( 'WC_Product::get_variation_id', '3.0', 'WC_Product::get_id(). It will always be the variation ID if this is a variation.' ); + return $this->get_id(); + } + + /** + * Get product variation description. + * + * @deprecated 3.0.0 + * @return string + */ + public function get_variation_description() { + wc_deprecated_function( 'WC_Product::get_variation_description', '3.0', 'WC_Product::get_description()' ); + return $this->get_description(); + } + + /** + * Check if all variation's attributes are set. + * + * @deprecated 3.0.0 + * @return boolean + */ + public function has_all_attributes_set() { + wc_deprecated_function( 'WC_Product::has_all_attributes_set', '3.0', 'an array filter on get_variation_attributes for a quick solution.' ); + $set = true; + + // undefined attributes have null strings as array values + foreach ( $this->get_variation_attributes() as $att ) { + if ( ! $att ) { + $set = false; + break; + } + } + return $set; + } + + /** + * Returns whether or not the variations parent is visible. + * + * @deprecated 3.0.0 + * @return bool + */ + public function parent_is_visible() { + wc_deprecated_function( 'WC_Product::parent_is_visible', '3.0' ); + return $this->is_visible(); + } + + /** + * Get total stock - This is the stock of parent and children combined. + * + * @deprecated 3.0.0 + * @return int + */ + public function get_total_stock() { + wc_deprecated_function( 'WC_Product::get_total_stock', '3.0', 'get_stock_quantity on each child. Beware of performance issues in doing so.' ); + if ( sizeof( $this->get_children() ) > 0 ) { + $total_stock = max( 0, $this->get_stock_quantity() ); + + foreach ( $this->get_children() as $child_id ) { + if ( 'yes' === get_post_meta( $child_id, '_manage_stock', true ) ) { + $stock = get_post_meta( $child_id, '_stock', true ); + $total_stock += max( 0, wc_stock_amount( $stock ) ); + } + } + } else { + $total_stock = $this->get_stock_quantity(); + } + return wc_stock_amount( $total_stock ); + } + + /** + * Get formatted variation data with WC < 2.4 back compat and proper formatting of text-based attribute names. + * + * @deprecated 3.0.0 + * + * @param bool $flat + * + * @return string + */ + public function get_formatted_variation_attributes( $flat = false ) { + wc_deprecated_function( 'WC_Product::get_formatted_variation_attributes', '3.0', 'wc_get_formatted_variation' ); + return wc_get_formatted_variation( $this, $flat ); + } + + /** + * Sync variable product prices with the children lowest/highest prices. + * + * @deprecated 3.0.0 not used in core. + * + * @param int $product_id + */ + public function variable_product_sync( $product_id = 0 ) { + wc_deprecated_function( 'WC_Product::variable_product_sync', '3.0' ); + if ( empty( $product_id ) ) { + $product_id = $this->get_id(); + } + + // Sync prices with children + if ( is_callable( array( __CLASS__, 'sync' ) ) ) { + self::sync( $product_id ); + } + } + + /** + * Sync the variable product's attributes with the variations. + * + * @param $product + * @param bool $children + */ + public static function sync_attributes( $product, $children = false ) { + if ( ! is_a( $product, 'WC_Product' ) ) { + $product = wc_get_product( $product ); + } + + /** + * Pre 2.4 handling where 'slugs' were saved instead of the full text attribute. + * Attempt to get full version of the text attribute from the parent and UPDATE meta. + */ + if ( version_compare( get_post_meta( $product->get_id(), '_product_version', true ), '2.4.0', '<' ) ) { + $parent_attributes = array_filter( (array) get_post_meta( $product->get_id(), '_product_attributes', true ) ); + + if ( ! $children ) { + $children = $product->get_children( 'edit' ); + } + + foreach ( $children as $child_id ) { + $all_meta = get_post_meta( $child_id ); + + foreach ( $all_meta as $name => $value ) { + if ( 0 !== strpos( $name, 'attribute_' ) ) { + continue; + } + if ( sanitize_title( $value[0] ) === $value[0] ) { + foreach ( $parent_attributes as $attribute ) { + if ( 'attribute_' . sanitize_title( $attribute['name'] ) !== $name ) { + continue; + } + $text_attributes = wc_get_text_attributes( $attribute['value'] ); + foreach ( $text_attributes as $text_attribute ) { + if ( sanitize_title( $text_attribute ) === $value[0] ) { + update_post_meta( $child_id, $name, $text_attribute ); + break; + } + } + } + } + } + } + } + } + + /** + * Match a variation to a given set of attributes using a WP_Query. + * @deprecated 3.0.0 in favour of Product data store's find_matching_product_variation. + * + * @param array $match_attributes + */ + public function get_matching_variation( $match_attributes = array() ) { + wc_deprecated_function( 'WC_Product::get_matching_variation', '3.0', 'Product data store find_matching_product_variation' ); + $data_store = WC_Data_Store::load( 'product' ); + return $data_store->find_matching_product_variation( $this, $match_attributes ); + } + + /** + * Returns whether or not we are showing dimensions on the product page. + * @deprecated 3.0.0 Unused. + * @return bool + */ + public function enable_dimensions_display() { + wc_deprecated_function( 'WC_Product::enable_dimensions_display', '3.0' ); + return apply_filters( 'wc_product_enable_dimensions_display', true ) && ( $this->has_dimensions() || $this->has_weight() || $this->child_has_weight() || $this->child_has_dimensions() ); + } + + /** + * Returns the product rating in html format. + * + * @deprecated 3.0.0 + * @param string $rating (default: '') + * @return string + */ + public function get_rating_html( $rating = null ) { + wc_deprecated_function( 'WC_Product::get_rating_html', '3.0', 'wc_get_rating_html' ); + return wc_get_rating_html( $rating ); + } + + /** + * Sync product rating. Can be called statically. + * + * @deprecated 3.0.0 + * @param int $post_id + */ + public static function sync_average_rating( $post_id ) { + wc_deprecated_function( 'WC_Product::sync_average_rating', '3.0', 'WC_Comments::get_average_rating_for_product or leave to CRUD.' ); + // See notes in https://github.com/woocommerce/woocommerce/pull/22909#discussion_r262393401. + // Sync count first like in the original method https://github.com/woocommerce/woocommerce/blob/2.6.0/includes/abstracts/abstract-wc-product.php#L1101-L1128. + self::sync_rating_count( $post_id ); + $average = WC_Comments::get_average_rating_for_product( wc_get_product( $post_id ) ); + update_post_meta( $post_id, '_wc_average_rating', $average ); + } + + /** + * Sync product rating count. Can be called statically. + * + * @deprecated 3.0.0 + * @param int $post_id + */ + public static function sync_rating_count( $post_id ) { + wc_deprecated_function( 'WC_Product::sync_rating_count', '3.0', 'WC_Comments::get_rating_counts_for_product or leave to CRUD.' ); + $counts = WC_Comments::get_rating_counts_for_product( wc_get_product( $post_id ) ); + update_post_meta( $post_id, '_wc_rating_count', $counts ); + } + + /** + * Same as get_downloads in CRUD. + * + * @deprecated 3.0.0 + * @return array + */ + public function get_files() { + wc_deprecated_function( 'WC_Product::get_files', '3.0', 'WC_Product::get_downloads' ); + return $this->get_downloads(); + } + + /** + * @deprecated 3.0.0 Sync is taken care of during save - no need to call this directly. + */ + public function grouped_product_sync() { + wc_deprecated_function( 'WC_Product::grouped_product_sync', '3.0' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/class-wc-rest-legacy-coupons-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/class-wc-rest-legacy-coupons-controller.php new file mode 100644 index 0000000..dc88a4c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/class-wc-rest-legacy-coupons-controller.php @@ -0,0 +1,164 @@ +ID ); + $data = $coupon->get_data(); + + $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); + $format_date = array( 'date_created', 'date_modified', 'date_expires' ); + $format_null = array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], 2 ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $data[ $key ] = $data[ $key ] ? wc_rest_prepare_date_response( get_gmt_from_date( date( 'Y-m-d H:i:s', $data[ $key ] ) ) ) : null; + } + + // Format null values. + foreach ( $format_null as $key ) { + $data[ $key ] = $data[ $key ] ? $data[ $key ] : null; + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $post, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare a single coupon for create or update. + * + * @deprecated 3.0.0 + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + global $wpdb; + + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $coupon = new WC_Coupon( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Validate required POST fields. + if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) { + if ( empty( $request['code'] ) ) { + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + } + } + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'code' : + $coupon_code = wc_format_coupon_code( $value ); + $id = $coupon->get_id() ? $coupon->get_id() : 0; + $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); + + if ( $id_from_code ) { + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon->set_code( $coupon_code ); + break; + case 'meta_data' : + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + case 'description' : + $coupon->set_description( wp_filter_post_kses( $value ) ); + break; + default : + if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { + $coupon->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param WC_Coupon $coupon The coupon object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $coupon, $request ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/class-wc-rest-legacy-orders-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/class-wc-rest-legacy-orders-controller.php new file mode 100644 index 0000000..d96849c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/class-wc-rest-legacy-orders-controller.php @@ -0,0 +1,306 @@ + '_customer_user', + 'value' => $request['customer'], + 'type' => 'NUMERIC', + ); + } + + // Search by product. + if ( ! empty( $request['product'] ) ) { + $order_ids = $wpdb->get_col( $wpdb->prepare( " + SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items + WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) + AND order_item_type = 'line_item' + ", $request['product'] ) ); + + // Force WP_Query return empty if don't found any order. + $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); + + $args['post__in'] = $order_ids; + } + + // Search. + if ( ! empty( $args['s'] ) ) { + $order_ids = wc_order_search( $args['s'] ); + + if ( ! empty( $order_ids ) ) { + unset( $args['s'] ); + $args['post__in'] = array_merge( $order_ids, array( 0 ) ); + } + } + + return $args; + } + + /** + * Prepare a single order output for response. + * + * @deprecated 3.0 + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $data + */ + public function prepare_item_for_response( $post, $request ) { + $this->request = $request; + $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); + $statuses = wc_get_order_statuses(); + $order = wc_get_order( $post ); + $data = array_merge( array( 'id' => $order->get_id() ), $order->get_data() ); + $format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' ); + $format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' ); + $format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $data[ $key ] = $data[ $key ] ? wc_rest_prepare_date_response( get_gmt_from_date( date( 'Y-m-d H:i:s', $data[ $key ] ) ) ) : false; + } + + // Format the order status. + $data['status'] = 'wc-' === substr( $data['status'], 0, 3 ) ? substr( $data['status'], 3 ) : $data['status']; + + // Format line items. + foreach ( $format_line_items as $key ) { + $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); + } + + // Refunds. + $data['refunds'] = array(); + foreach ( $order->get_refunds() as $refund ) { + $data['refunds'][] = array( + 'id' => $refund->get_id(), + 'refund' => $refund->get_reason() ? $refund->get_reason() : '', + 'total' => '-' . wc_format_decimal( $refund->get_amount(), $this->request['dp'] ), + ); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $order, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare a single order for create. + * + * @deprecated 3.0 + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|WC_Order $data Object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $order = new WC_Order( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Handle all writable props + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'billing' : + case 'shipping' : + $this->update_address( $order, $value, $key ); + break; + case 'line_items' : + case 'shipping_lines' : + case 'fee_lines' : + case 'coupon_lines' : + if ( is_array( $value ) ) { + foreach ( $value as $item ) { + if ( is_array( $item ) ) { + if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { + $order->remove_item( $item['id'] ); + } else { + $this->set_item( $order, $key, $item ); + } + } + } + } + break; + case 'meta_data' : + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + default : + if ( is_callable( array( $order, "set_{$key}" ) ) ) { + $order->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filter the data for the insert. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WC_Order $order The Order object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $order, $request ); + } + + /** + * Create base WC Order object. + * + * @deprecated 3.0.0 + * + * @param array $data + * @return WC_Order + */ + protected function create_base_order( $data ) { + return wc_create_order( $data ); + } + + /** + * Create order. + * + * @deprecated 3.0.0 + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function create_order( $request ) { + try { + // Make sure customer exists. + if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] && false === get_user_by( 'id', $request['customer_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { + add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + } + + $order = $this->prepare_item_for_database( $request ); + $order->set_created_via( 'rest-api' ); + $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $order->calculate_totals(); + $order->save(); + + // Handle set paid. + if ( true === $request['set_paid'] ) { + $order->payment_complete( $request['transaction_id'] ); + } + + return $order->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update order. + * + * @deprecated 3.0.0 + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function update_order( $request ) { + try { + $order = $this->prepare_item_for_database( $request ); + $order->save(); + + // Handle set paid. + if ( $order->needs_payment() && true === $request['set_paid'] ) { + $order->payment_complete( $request['transaction_id'] ); + } + + // If items have changed, recalculate order totals. + if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { + $order->calculate_totals(); + } + + return $order->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/class-wc-rest-legacy-products-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/class-wc-rest-legacy-products-controller.php new file mode 100644 index 0000000..4f7ce18 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/class-wc-rest-legacy-products-controller.php @@ -0,0 +1,804 @@ + 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + ); + } + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ); + } + + // Filter by attribute and term. + if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { + if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $tax_query[] = array( + 'taxonomy' => $request['attribute'], + 'field' => 'term_id', + 'terms' => $request['attribute_term'], + ); + } + } + + if ( ! empty( $tax_query ) ) { + $args['tax_query'] = $tax_query; + } + + // Filter featured. + if ( is_bool( $request['featured'] ) ) { + $args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => 'featured', + 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', + ); + } + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( $args, array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); + } + + // Filter product in stock or out of stock. + if ( is_bool( $request['in_stock'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, array( + 'key' => '_stock_status', + 'value' => true === $request['in_stock'] ? 'instock' : 'outofstock', + ) ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $args[ $on_sale_key ] += wc_get_product_ids_on_sale(); + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + return $args; + } + + /** + * Prepare a single product output for response. + * + * @deprecated 3.0.0 + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $post, $request ) { + $product = wc_get_product( $post ); + $data = $this->get_product_data( $product ); + + // Add variations to variable products. + if ( $product->is_type( 'variable' ) && $product->has_child() ) { + $data['variations'] = $product->get_children(); + } + + // Add grouped products data. + if ( $product->is_type( 'grouped' ) && $product->has_child() ) { + $data['grouped_products'] = $product->get_children(); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $product, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Get product menu order. + * + * @deprecated 3.0.0 + * @param WC_Product $product Product instance. + * @return int + */ + protected function get_product_menu_order( $product ) { + return $product->get_menu_order(); + } + + /** + * Save product meta. + * + * @deprecated 3.0.0 + * @param WC_Product $product + * @param WP_REST_Request $request + * @return bool + * @throws WC_REST_Exception + */ + protected function save_product_meta( $product, $request ) { + $product = $this->set_product_meta( $product, $request ); + $product->save(); + + return true; + } + + /** + * Set product meta. + * + * @deprecated 3.0.0 + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return WC_Product + */ + protected function set_product_meta( $product, $request ) { + // Virtual. + if ( isset( $request['virtual'] ) ) { + $product->set_virtual( $request['virtual'] ); + } + + // Tax status. + if ( isset( $request['tax_status'] ) ) { + $product->set_tax_status( $request['tax_status'] ); + } + + // Tax Class. + if ( isset( $request['tax_class'] ) ) { + $product->set_tax_class( $request['tax_class'] ); + } + + // Catalog Visibility. + if ( isset( $request['catalog_visibility'] ) ) { + $product->set_catalog_visibility( $request['catalog_visibility'] ); + } + + // Purchase Note. + if ( isset( $request['purchase_note'] ) ) { + $product->set_purchase_note( wc_clean( $request['purchase_note'] ) ); + } + + // Featured Product. + if ( isset( $request['featured'] ) ) { + $product->set_featured( $request['featured'] ); + } + + // Shipping data. + $product = $this->save_product_shipping_data( $product, $request ); + + // SKU. + if ( isset( $request['sku'] ) ) { + $product->set_sku( wc_clean( $request['sku'] ) ); + } + + // Attributes. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + } else { + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $product->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $product->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + } + + // Product parent ID for groups. + if ( isset( $request['parent_id'] ) ) { + $product->set_parent_id( $request['parent_id'] ); + } + + // Sold individually. + if ( isset( $request['sold_individually'] ) ) { + $product->set_sold_individually( $request['sold_individually'] ); + } + + // Stock status. + if ( isset( $request['in_stock'] ) ) { + $stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock'; + } else { + $stock_status = $product->get_stock_status(); + } + + // Stock data. + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock. + if ( isset( $request['manage_stock'] ) ) { + $product->set_manage_stock( $request['manage_stock'] ); + } + + // Backorders. + if ( isset( $request['backorders'] ) ) { + $product->set_backorders( $request['backorders'] ); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( $product->get_manage_stock() ) { + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity. + if ( isset( $request['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells. + if ( isset( $request['upsell_ids'] ) ) { + $upsells = array(); + $ids = $request['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + } + + $product->set_upsell_ids( $upsells ); + } + + // Cross sells. + if ( isset( $request['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $request['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + } + + $product->set_cross_sell_ids( $crosssells ); + } + + // Product categories. + if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['categories'] ); + } + + // Product tags. + if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); + } + + // Downloadable. + if ( isset( $request['downloadable'] ) ) { + $product->set_downloadable( $request['downloadable'] ); + } + + // Downloadable options. + if ( $product->get_downloadable() ) { + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $product->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $product->set_download_expiry( $request['download_expiry'] ); + } + } + + // Product url and button text for external products. + if ( $product->is_type( 'external' ) ) { + if ( isset( $request['external_url'] ) ) { + $product->set_product_url( $request['external_url'] ); + } + + if ( isset( $request['button_text'] ) ) { + $product->set_button_text( $request['button_text'] ); + } + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $request ); + } + + return $product; + } + + /** + * Save variations. + * + * @deprecated 3.0.0 + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return bool + */ + protected function save_variations_data( $product, $request ) { + foreach ( $request['variations'] as $menu_order => $data ) { + $variation = new WC_Product_Variation( isset( $data['id'] ) ? absint( $data['id'] ) : 0 ); + + // Create initial name and status. + if ( ! $variation->get_slug() ) { + /* translators: 1: variation id 2: product name */ + $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation->get_id(), $product->get_name() ) ); + $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); + } + + // Parent ID. + $variation->set_parent_id( $product->get_id() ); + + // Menu order. + $variation->set_menu_order( $menu_order ); + + // Status. + if ( isset( $data['visible'] ) ) { + $variation->set_status( false === $data['visible'] ? 'private' : 'publish' ); + } + + // SKU. + if ( isset( $data['sku'] ) ) { + $variation->set_sku( wc_clean( $data['sku'] ) ); + } + + // Thumbnail. + if ( isset( $data['image'] ) && is_array( $data['image'] ) ) { + $image = $data['image']; + $image = current( $image ); + if ( is_array( $image ) ) { + $image['position'] = 0; + } + + $variation = $this->set_product_images( $variation, array( $image ) ); + } + + // Virtual variation. + if ( isset( $data['virtual'] ) ) { + $variation->set_virtual( $data['virtual'] ); + } + + // Downloadable variation. + if ( isset( $data['downloadable'] ) ) { + $variation->set_downloadable( $data['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $data['downloads'] ); + } + + // Download limit. + if ( isset( $data['download_limit'] ) ) { + $variation->set_download_limit( $data['download_limit'] ); + } + + // Download expiry. + if ( isset( $data['download_expiry'] ) ) { + $variation->set_download_expiry( $data['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $data ); + + // Stock handling. + if ( isset( $data['manage_stock'] ) ) { + $variation->set_manage_stock( $data['manage_stock'] ); + } + + if ( isset( $data['in_stock'] ) ) { + $variation->set_stock_status( true === $data['in_stock'] ? 'instock' : 'outofstock' ); + } + + if ( isset( $data['backorders'] ) ) { + $variation->set_backorders( $data['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $data['stock_quantity'] ) ) { + $variation->set_stock_quantity( $data['stock_quantity'] ); + } elseif ( isset( $data['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $data['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $data['regular_price'] ) ) { + $variation->set_regular_price( $data['regular_price'] ); + } + + // Sale Price. + if ( isset( $data['sale_price'] ) ) { + $variation->set_sale_price( $data['sale_price'] ); + } + + if ( isset( $data['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $data['date_on_sale_from'] ); + } + + if ( isset( $data['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $data['date_on_sale_to'] ); + } + + // Tax class. + if ( isset( $data['tax_class'] ) ) { + $variation->set_tax_class( $data['tax_class'] ); + } + + // Description. + if ( isset( $data['description'] ) ) { + $variation->set_description( wp_kses_post( $data['description'] ) ); + } + + // Update taxonomies. + if ( isset( $data['attributes'] ) ) { + $attributes = array(); + $parent_attributes = $product->get_attributes(); + + foreach ( $data['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + $variation->save(); + + do_action( 'woocommerce_rest_save_product_variation', $variation->get_id(), $menu_order, $data ); + } + + return true; + } + + /** + * Add post meta fields. + * + * @deprecated 3.0.0 + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request data. + * @return bool|WP_Error + */ + protected function add_post_meta_fields( $post, $request ) { + return $this->update_post_meta_fields( $post, $request ); + } + + /** + * Update post meta fields. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request data. + * @return bool|WP_Error + */ + protected function update_post_meta_fields( $post, $request ) { + $product = wc_get_product( $post ); + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['images'] ) ) { + $product = $this->set_product_images( $product, $request['images'] ); + } + + // Save product meta fields. + $product = $this->set_product_meta( $product, $request ); + + // Save the product data. + $product->save(); + + // Save variations. + if ( $product->is_type( 'variable' ) ) { + if ( isset( $request['variations'] ) && is_array( $request['variations'] ) ) { + $this->save_variations_data( $product, $request ); + } + } + + // Clear caches here so in sync with any new variations/children. + wc_delete_product_transients( $product->get_id() ); + wp_cache_delete( 'product-' . $product->get_id(), 'products' ); + + return true; + } + + /** + * Delete post. + * + * @deprecated 3.0.0 + * + * @param int|WP_Post $id Post ID or WP_Post instance. + */ + protected function delete_post( $id ) { + if ( ! empty( $id->ID ) ) { + $id = $id->ID; + } elseif ( ! is_numeric( $id ) || 0 >= $id ) { + return; + } + + // Delete product attachments. + $attachments = get_posts( array( + 'post_parent' => $id, + 'post_status' => 'any', + 'post_type' => 'attachment', + ) ); + + foreach ( (array) $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + // Delete product. + $product = wc_get_product( $id ); + $product->delete( true ); + } + + /** + * Get post types. + * + * @deprecated 3.0.0 + * + * @return array + */ + protected function get_post_types() { + return array( 'product', 'product_variation' ); + } + + /** + * Save product images. + * + * @deprecated 3.0.0 + * + * @param int $product_id + * @param array $images + * @throws WC_REST_Exception + */ + protected function save_product_images( $product_id, $images ) { + $product = wc_get_product( $product_id ); + + return set_product_images( $product, $images ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-authentication.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-authentication.php new file mode 100644 index 0000000..b80b26b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-authentication.php @@ -0,0 +1,410 @@ +api->server->path ) { + return new WP_User( 0 ); + } + + try { + + if ( is_ssl() ) { + $keys = $this->perform_ssl_authentication(); + } else { + $keys = $this->perform_oauth_authentication(); + } + + // Check API key-specific permission + $this->check_api_key_permissions( $keys['permissions'] ); + + $user = $this->get_user_by_id( $keys['user_id'] ); + + $this->update_api_key_last_access( $keys['key_id'] ); + + } catch ( Exception $e ) { + $user = new WP_Error( 'woocommerce_api_authentication_error', $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + return $user; + } + + /** + * SSL-encrypted requests are not subject to sniffing or man-in-the-middle + * attacks, so the request can be authenticated by simply looking up the user + * associated with the given consumer key and confirming the consumer secret + * provided is valid + * + * @since 2.1 + * @return array + * @throws Exception + */ + private function perform_ssl_authentication() { + + $params = WC()->api->server->params['GET']; + + // Get consumer key + if ( ! empty( $_SERVER['PHP_AUTH_USER'] ) ) { + + // Should be in HTTP Auth header by default + $consumer_key = $_SERVER['PHP_AUTH_USER']; + + } elseif ( ! empty( $params['consumer_key'] ) ) { + + // Allow a query string parameter as a fallback + $consumer_key = $params['consumer_key']; + + } else { + + throw new Exception( __( 'Consumer key is missing.', 'woocommerce' ), 404 ); + } + + // Get consumer secret + if ( ! empty( $_SERVER['PHP_AUTH_PW'] ) ) { + + // Should be in HTTP Auth header by default + $consumer_secret = $_SERVER['PHP_AUTH_PW']; + + } elseif ( ! empty( $params['consumer_secret'] ) ) { + + // Allow a query string parameter as a fallback + $consumer_secret = $params['consumer_secret']; + + } else { + + throw new Exception( __( 'Consumer secret is missing.', 'woocommerce' ), 404 ); + } + + $keys = $this->get_keys_by_consumer_key( $consumer_key ); + + if ( ! $this->is_consumer_secret_valid( $keys['consumer_secret'], $consumer_secret ) ) { + throw new Exception( __( 'Consumer secret is invalid.', 'woocommerce' ), 401 ); + } + + return $keys; + } + + /** + * Perform OAuth 1.0a "one-legged" (http://oauthbible.com/#oauth-10a-one-legged) authentication for non-SSL requests + * + * This is required so API credentials cannot be sniffed or intercepted when making API requests over plain HTTP + * + * This follows the spec for simple OAuth 1.0a authentication (RFC 5849) as closely as possible, with two exceptions: + * + * 1) There is no token associated with request/responses, only consumer keys/secrets are used + * + * 2) The OAuth parameters are included as part of the request query string instead of part of the Authorization header, + * This is because there is no cross-OS function within PHP to get the raw Authorization header + * + * @link http://tools.ietf.org/html/rfc5849 for the full spec + * @since 2.1 + * @return array + * @throws Exception + */ + private function perform_oauth_authentication() { + + $params = WC()->api->server->params['GET']; + + $param_names = array( 'oauth_consumer_key', 'oauth_timestamp', 'oauth_nonce', 'oauth_signature', 'oauth_signature_method' ); + + // Check for required OAuth parameters + foreach ( $param_names as $param_name ) { + + if ( empty( $params[ $param_name ] ) ) { + /* translators: %s: parameter name */ + throw new Exception( sprintf( __( '%s parameter is missing', 'woocommerce' ), $param_name ), 404 ); + } + } + + // Fetch WP user by consumer key + $keys = $this->get_keys_by_consumer_key( $params['oauth_consumer_key'] ); + + // Perform OAuth validation + $this->check_oauth_signature( $keys, $params ); + $this->check_oauth_timestamp_and_nonce( $keys, $params['oauth_timestamp'], $params['oauth_nonce'] ); + + // Authentication successful, return user + return $keys; + } + + /** + * Return the keys for the given consumer key + * + * @since 2.4.0 + * @param string $consumer_key + * @return array + * @throws Exception + */ + private function get_keys_by_consumer_key( $consumer_key ) { + global $wpdb; + + $consumer_key = wc_api_hash( sanitize_text_field( $consumer_key ) ); + + $keys = $wpdb->get_row( $wpdb->prepare( " + SELECT key_id, user_id, permissions, consumer_key, consumer_secret, nonces + FROM {$wpdb->prefix}woocommerce_api_keys + WHERE consumer_key = '%s' + ", $consumer_key ), ARRAY_A ); + + if ( empty( $keys ) ) { + throw new Exception( __( 'Consumer key is invalid.', 'woocommerce' ), 401 ); + } + + return $keys; + } + + /** + * Get user by ID + * + * @since 2.4.0 + * @param int $user_id + * @return WP_User + * + * @throws Exception + */ + private function get_user_by_id( $user_id ) { + $user = get_user_by( 'id', $user_id ); + + if ( ! $user ) { + throw new Exception( __( 'API user is invalid', 'woocommerce' ), 401 ); + } + + return $user; + } + + /** + * Check if the consumer secret provided for the given user is valid + * + * @since 2.1 + * @param string $keys_consumer_secret + * @param string $consumer_secret + * @return bool + */ + private function is_consumer_secret_valid( $keys_consumer_secret, $consumer_secret ) { + return hash_equals( $keys_consumer_secret, $consumer_secret ); + } + + /** + * Verify that the consumer-provided request signature matches our generated signature, this ensures the consumer + * has a valid key/secret + * + * @param array $keys + * @param array $params the request parameters + * @throws Exception + */ + private function check_oauth_signature( $keys, $params ) { + + $http_method = strtoupper( WC()->api->server->method ); + + $base_request_uri = rawurlencode( untrailingslashit( get_woocommerce_api_url( '' ) ) . WC()->api->server->path ); + + // Get the signature provided by the consumer and remove it from the parameters prior to checking the signature + $consumer_signature = rawurldecode( str_replace( ' ', '+', $params['oauth_signature'] ) ); + unset( $params['oauth_signature'] ); + + // Remove filters and convert them from array to strings to void normalize issues + if ( isset( $params['filter'] ) ) { + $filters = $params['filter']; + unset( $params['filter'] ); + foreach ( $filters as $filter => $filter_value ) { + $params[ 'filter[' . $filter . ']' ] = $filter_value; + } + } + + // Normalize parameter key/values + $params = $this->normalize_parameters( $params ); + + // Sort parameters + if ( ! uksort( $params, 'strcmp' ) ) { + throw new Exception( __( 'Invalid signature - failed to sort parameters.', 'woocommerce' ), 401 ); + } + + // Form query string + $query_params = array(); + foreach ( $params as $param_key => $param_value ) { + + $query_params[] = $param_key . '%3D' . $param_value; // join with equals sign + } + $query_string = implode( '%26', $query_params ); // join with ampersand + + $string_to_sign = $http_method . '&' . $base_request_uri . '&' . $query_string; + + if ( 'HMAC-SHA1' !== $params['oauth_signature_method'] && 'HMAC-SHA256' !== $params['oauth_signature_method'] ) { + throw new Exception( __( 'Invalid signature - signature method is invalid.', 'woocommerce' ), 401 ); + } + + $hash_algorithm = strtolower( str_replace( 'HMAC-', '', $params['oauth_signature_method'] ) ); + + $signature = base64_encode( hash_hmac( $hash_algorithm, $string_to_sign, $keys['consumer_secret'], true ) ); + + if ( ! hash_equals( $signature, $consumer_signature ) ) { + throw new Exception( __( 'Invalid signature - provided signature does not match.', 'woocommerce' ), 401 ); + } + } + + /** + * Normalize each parameter by assuming each parameter may have already been + * encoded, so attempt to decode, and then re-encode according to RFC 3986 + * + * Note both the key and value is normalized so a filter param like: + * + * 'filter[period]' => 'week' + * + * is encoded to: + * + * 'filter%5Bperiod%5D' => 'week' + * + * This conforms to the OAuth 1.0a spec which indicates the entire query string + * should be URL encoded + * + * @since 2.1 + * @see rawurlencode() + * @param array $parameters un-normalized parameters + * @return array normalized parameters + */ + private function normalize_parameters( $parameters ) { + + $normalized_parameters = array(); + + foreach ( $parameters as $key => $value ) { + + // Percent symbols (%) must be double-encoded + $key = str_replace( '%', '%25', rawurlencode( rawurldecode( $key ) ) ); + $value = str_replace( '%', '%25', rawurlencode( rawurldecode( $value ) ) ); + + $normalized_parameters[ $key ] = $value; + } + + return $normalized_parameters; + } + + /** + * Verify that the timestamp and nonce provided with the request are valid. This prevents replay attacks where + * an attacker could attempt to re-send an intercepted request at a later time. + * + * - A timestamp is valid if it is within 15 minutes of now + * - A nonce is valid if it has not been used within the last 15 minutes + * + * @param array $keys + * @param int $timestamp the unix timestamp for when the request was made + * @param string $nonce a unique (for the given user) 32 alphanumeric string, consumer-generated + * @throws Exception + */ + private function check_oauth_timestamp_and_nonce( $keys, $timestamp, $nonce ) { + global $wpdb; + + $valid_window = 15 * 60; // 15 minute window + + if ( ( $timestamp < time() - $valid_window ) || ( $timestamp > time() + $valid_window ) ) { + throw new Exception( __( 'Invalid timestamp.', 'woocommerce' ) ); + } + + $used_nonces = maybe_unserialize( $keys['nonces'] ); + + if ( empty( $used_nonces ) ) { + $used_nonces = array(); + } + + if ( in_array( $nonce, $used_nonces ) ) { + throw new Exception( __( 'Invalid nonce - nonce has already been used.', 'woocommerce' ), 401 ); + } + + $used_nonces[ $timestamp ] = $nonce; + + // Remove expired nonces + foreach ( $used_nonces as $nonce_timestamp => $nonce ) { + if ( $nonce_timestamp < ( time() - $valid_window ) ) { + unset( $used_nonces[ $nonce_timestamp ] ); + } + } + + $used_nonces = maybe_serialize( $used_nonces ); + + $wpdb->update( + $wpdb->prefix . 'woocommerce_api_keys', + array( 'nonces' => $used_nonces ), + array( 'key_id' => $keys['key_id'] ), + array( '%s' ), + array( '%d' ) + ); + } + + /** + * Check that the API keys provided have the proper key-specific permissions to either read or write API resources + * + * @param string $key_permissions + * @throws Exception if the permission check fails + */ + public function check_api_key_permissions( $key_permissions ) { + switch ( WC()->api->server->method ) { + + case 'HEAD': + case 'GET': + if ( 'read' !== $key_permissions && 'read_write' !== $key_permissions ) { + throw new Exception( __( 'The API key provided does not have read permissions.', 'woocommerce' ), 401 ); + } + break; + + case 'POST': + case 'PUT': + case 'PATCH': + case 'DELETE': + if ( 'write' !== $key_permissions && 'read_write' !== $key_permissions ) { + throw new Exception( __( 'The API key provided does not have write permissions.', 'woocommerce' ), 401 ); + } + break; + } + } + + /** + * Updated API Key last access datetime + * + * @since 2.4.0 + * + * @param int $key_id + */ + private function update_api_key_last_access( $key_id ) { + global $wpdb; + + $wpdb->update( + $wpdb->prefix . 'woocommerce_api_keys', + array( 'last_access' => current_time( 'mysql' ) ), + array( 'key_id' => $key_id ), + array( '%s' ), + array( '%d' ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-coupons.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-coupons.php new file mode 100644 index 0000000..49036c6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-coupons.php @@ -0,0 +1,247 @@ + + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET /coupons + $routes[ $this->base ] = array( + array( array( $this, 'get_coupons' ), WC_API_Server::READABLE ), + ); + + # GET /coupons/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_coupons_count' ), WC_API_Server::READABLE ), + ); + + # GET /coupons/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_coupon' ), WC_API_Server::READABLE ), + ); + + # GET /coupons/code/, note that coupon codes can contain spaces, dashes and underscores + $routes[ $this->base . '/code/(?P\w[\w\s\-]*)' ] = array( + array( array( $this, 'get_coupon_by_code' ), WC_API_Server::READABLE ), + ); + + return $routes; + } + + /** + * Get all coupons + * + * @since 2.1 + * @param string $fields + * @param array $filter + * @param int $page + * @return array + */ + public function get_coupons( $fields = null, $filter = array(), $page = 1 ) { + + $filter['page'] = $page; + + $query = $this->query_coupons( $filter ); + + $coupons = array(); + + foreach ( $query->posts as $coupon_id ) { + + if ( ! $this->is_readable( $coupon_id ) ) { + continue; + } + + $coupons[] = current( $this->get_coupon( $coupon_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'coupons' => $coupons ); + } + + /** + * Get the coupon for the given ID + * + * @since 2.1 + * + * @param int $id the coupon ID + * @param string $fields fields to include in response + * + * @return array|WP_Error + * @throws WC_API_Exception + */ + public function get_coupon( $id, $fields = null ) { + $id = $this->validate_request( $id, 'shop_coupon', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $coupon = new WC_Coupon( $id ); + + if ( 0 === $coupon->get_id() ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_id', __( 'Invalid coupon ID', 'woocommerce' ), 404 ); + } + + $coupon_data = array( + 'id' => $coupon->get_id(), + 'code' => $coupon->get_code(), + 'type' => $coupon->get_discount_type(), + 'created_at' => $this->server->format_datetime( $coupon->get_date_created() ? $coupon->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. + 'updated_at' => $this->server->format_datetime( $coupon->get_date_modified() ? $coupon->get_date_modified()->getTimestamp() : 0 ), // API gives UTC times. + 'amount' => wc_format_decimal( $coupon->get_amount(), 2 ), + 'individual_use' => $coupon->get_individual_use(), + 'product_ids' => array_map( 'absint', (array) $coupon->get_product_ids() ), + 'exclude_product_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_ids() ), + 'usage_limit' => $coupon->get_usage_limit() ? $coupon->get_usage_limit() : null, + 'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null, + 'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(), + 'usage_count' => (int) $coupon->get_usage_count(), + 'expiry_date' => $this->server->format_datetime( $coupon->get_date_expires() ? $coupon->get_date_expires()->getTimestamp() : 0 ), // API gives UTC times. + 'enable_free_shipping' => $coupon->get_free_shipping(), + 'product_category_ids' => array_map( 'absint', (array) $coupon->get_product_categories() ), + 'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ), + 'exclude_sale_items' => $coupon->get_exclude_sale_items(), + 'minimum_amount' => wc_format_decimal( $coupon->get_minimum_amount(), 2 ), + 'customer_emails' => $coupon->get_email_restrictions(), + ); + + return array( 'coupon' => apply_filters( 'woocommerce_api_coupon_response', $coupon_data, $coupon, $fields, $this->server ) ); + } + + /** + * Get the total number of coupons + * + * @since 2.1 + * + * @param array $filter + * + * @return array|WP_Error + */ + public function get_coupons_count( $filter = array() ) { + + $query = $this->query_coupons( $filter ); + + if ( ! current_user_can( 'read_private_shop_coupons' ) ) { + return new WP_Error( 'woocommerce_api_user_cannot_read_coupons_count', __( 'You do not have permission to read the coupons count', 'woocommerce' ), array( 'status' => 401 ) ); + } + + return array( 'count' => (int) $query->found_posts ); + } + + /** + * Get the coupon for the given code + * + * @since 2.1 + * @param string $code the coupon code + * @param string $fields fields to include in response + * @return int|WP_Error + */ + public function get_coupon_by_code( $code, $fields = null ) { + global $wpdb; + + $id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1;", $code ) ); + + if ( is_null( $id ) ) { + return new WP_Error( 'woocommerce_api_invalid_coupon_code', __( 'Invalid coupon code', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return $this->get_coupon( $id, $fields ); + } + + /** + * Create a coupon + * + * @param array $data + * @return array + */ + public function create_coupon( $data ) { + + return array(); + } + + /** + * Edit a coupon + * + * @param int $id the coupon ID + * @param array $data + * @return array|WP_Error + */ + public function edit_coupon( $id, $data ) { + + $id = $this->validate_request( $id, 'shop_coupon', 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + return $this->get_coupon( $id ); + } + + /** + * Delete a coupon + * + * @param int $id the coupon ID + * @param bool $force true to permanently delete coupon, false to move to trash + * @return array|WP_Error + */ + public function delete_coupon( $id, $force = false ) { + + $id = $this->validate_request( $id, 'shop_coupon', 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + return $this->delete( $id, 'shop_coupon', ( 'true' === $force ) ); + } + + /** + * Helper method to get coupon post objects + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_Query + */ + private function query_coupons( $args ) { + + // set base query arguments + $query_args = array( + 'fields' => 'ids', + 'post_type' => 'shop_coupon', + 'post_status' => 'publish', + ); + + $query_args = $this->merge_query_args( $query_args, $args ); + + return new WP_Query( $query_args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-customers.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-customers.php new file mode 100644 index 0000000..1860815 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-customers.php @@ -0,0 +1,481 @@ + + * GET /customers//orders + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET /customers + $routes[ $this->base ] = array( + array( array( $this, 'get_customers' ), WC_API_SERVER::READABLE ), + ); + + # GET /customers/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_customers_count' ), WC_API_SERVER::READABLE ), + ); + + # GET /customers/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_customer' ), WC_API_SERVER::READABLE ), + ); + + # GET /customers//orders + $routes[ $this->base . '/(?P\d+)/orders' ] = array( + array( array( $this, 'get_customer_orders' ), WC_API_SERVER::READABLE ), + ); + + return $routes; + } + + /** + * Get all customers + * + * @since 2.1 + * @param array $fields + * @param array $filter + * @param int $page + * @return array + */ + public function get_customers( $fields = null, $filter = array(), $page = 1 ) { + + $filter['page'] = $page; + + $query = $this->query_customers( $filter ); + + $customers = array(); + + foreach ( $query->get_results() as $user_id ) { + + if ( ! $this->is_readable( $user_id ) ) { + continue; + } + + $customers[] = current( $this->get_customer( $user_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'customers' => $customers ); + } + + /** + * Get the customer for the given ID + * + * @since 2.1 + * @param int $id the customer ID + * @param string $fields + * @return array|WP_Error + */ + public function get_customer( $id, $fields = null ) { + global $wpdb; + + $id = $this->validate_request( $id, 'customer', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $customer = new WC_Customer( $id ); + $last_order = $customer->get_last_order(); + $customer_data = array( + 'id' => $customer->get_id(), + 'created_at' => $this->server->format_datetime( $customer->get_date_created() ? $customer->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. + 'email' => $customer->get_email(), + 'first_name' => $customer->get_first_name(), + 'last_name' => $customer->get_last_name(), + 'username' => $customer->get_username(), + 'last_order_id' => is_object( $last_order ) ? $last_order->get_id() : null, + 'last_order_date' => is_object( $last_order ) ? $this->server->format_datetime( $last_order->get_date_created() ? $last_order->get_date_created()->getTimestamp() : 0 ) : null, // API gives UTC times. + 'orders_count' => $customer->get_order_count(), + 'total_spent' => wc_format_decimal( $customer->get_total_spent(), 2 ), + 'avatar_url' => $customer->get_avatar_url(), + 'billing_address' => array( + 'first_name' => $customer->get_billing_first_name(), + 'last_name' => $customer->get_billing_last_name(), + 'company' => $customer->get_billing_company(), + 'address_1' => $customer->get_billing_address_1(), + 'address_2' => $customer->get_billing_address_2(), + 'city' => $customer->get_billing_city(), + 'state' => $customer->get_billing_state(), + 'postcode' => $customer->get_billing_postcode(), + 'country' => $customer->get_billing_country(), + 'email' => $customer->get_billing_email(), + 'phone' => $customer->get_billing_phone(), + ), + 'shipping_address' => array( + 'first_name' => $customer->get_shipping_first_name(), + 'last_name' => $customer->get_shipping_last_name(), + 'company' => $customer->get_shipping_company(), + 'address_1' => $customer->get_shipping_address_1(), + 'address_2' => $customer->get_shipping_address_2(), + 'city' => $customer->get_shipping_city(), + 'state' => $customer->get_shipping_state(), + 'postcode' => $customer->get_shipping_postcode(), + 'country' => $customer->get_shipping_country(), + ), + ); + + return array( 'customer' => apply_filters( 'woocommerce_api_customer_response', $customer_data, $customer, $fields, $this->server ) ); + } + + /** + * Get the total number of customers + * + * @since 2.1 + * @param array $filter + * @return array|WP_Error + */ + public function get_customers_count( $filter = array() ) { + + $query = $this->query_customers( $filter ); + + if ( ! current_user_can( 'list_users' ) ) { + return new WP_Error( 'woocommerce_api_user_cannot_read_customers_count', __( 'You do not have permission to read the customers count', 'woocommerce' ), array( 'status' => 401 ) ); + } + + return array( 'count' => count( $query->get_results() ) ); + } + + + /** + * Create a customer + * + * @param array $data + * @return array|WP_Error + */ + public function create_customer( $data ) { + + if ( ! current_user_can( 'create_users' ) ) { + return new WP_Error( 'woocommerce_api_user_cannot_create_customer', __( 'You do not have permission to create this customer', 'woocommerce' ), array( 'status' => 401 ) ); + } + + return array(); + } + + /** + * Edit a customer + * + * @param int $id the customer ID + * @param array $data + * @return array|WP_Error + */ + public function edit_customer( $id, $data ) { + + $id = $this->validate_request( $id, 'customer', 'edit' ); + + if ( ! is_wp_error( $id ) ) { + return $id; + } + + return $this->get_customer( $id ); + } + + /** + * Delete a customer + * + * @param int $id the customer ID + * @return array|WP_Error + */ + public function delete_customer( $id ) { + + $id = $this->validate_request( $id, 'customer', 'delete' ); + + if ( ! is_wp_error( $id ) ) { + return $id; + } + + return $this->delete( $id, 'customer' ); + } + + /** + * Get the orders for a customer + * + * @since 2.1 + * @param int $id the customer ID + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_customer_orders( $id, $fields = null ) { + global $wpdb; + + $id = $this->validate_request( $id, 'customer', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $order_ids = wc_get_orders( array( + 'customer' => $id, + 'limit' => -1, + 'orderby' => 'date', + 'order' => 'ASC', + 'return' => 'ids', + ) ); + + if ( empty( $order_ids ) ) { + return array( 'orders' => array() ); + } + + $orders = array(); + + foreach ( $order_ids as $order_id ) { + $orders[] = current( WC()->api->WC_API_Orders->get_order( $order_id, $fields ) ); + } + + return array( 'orders' => apply_filters( 'woocommerce_api_customer_orders_response', $orders, $id, $fields, $order_ids, $this->server ) ); + } + + /** + * Helper method to get customer user objects + * + * Note that WP_User_Query does not have built-in pagination so limit & offset are used to provide limited + * pagination support + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_User_Query + */ + private function query_customers( $args = array() ) { + + // default users per page + $users_per_page = get_option( 'posts_per_page' ); + + // set base query arguments + $query_args = array( + 'fields' => 'ID', + 'role' => 'customer', + 'orderby' => 'registered', + 'number' => $users_per_page, + ); + + // search + if ( ! empty( $args['q'] ) ) { + $query_args['search'] = $args['q']; + } + + // limit number of users returned + if ( ! empty( $args['limit'] ) ) { + + $query_args['number'] = absint( $args['limit'] ); + + $users_per_page = absint( $args['limit'] ); + } + + // page + $page = ( isset( $args['page'] ) ) ? absint( $args['page'] ) : 1; + + // offset + if ( ! empty( $args['offset'] ) ) { + $query_args['offset'] = absint( $args['offset'] ); + } else { + $query_args['offset'] = $users_per_page * ( $page - 1 ); + } + + // created date + if ( ! empty( $args['created_at_min'] ) ) { + $this->created_at_min = $this->server->parse_datetime( $args['created_at_min'] ); + } + + if ( ! empty( $args['created_at_max'] ) ) { + $this->created_at_max = $this->server->parse_datetime( $args['created_at_max'] ); + } + + $query = new WP_User_Query( $query_args ); + + // helper members for pagination headers + $query->total_pages = ceil( $query->get_total() / $users_per_page ); + $query->page = $page; + + return $query; + } + + /** + * Add customer data to orders + * + * @since 2.1 + * @param $order_data + * @param $order + * @return array + */ + public function add_customer_data( $order_data, $order ) { + + if ( 0 == $order->get_user_id() ) { + + // add customer data from order + $order_data['customer'] = array( + 'id' => 0, + 'email' => $order->get_billing_email(), + 'first_name' => $order->get_billing_first_name(), + 'last_name' => $order->get_billing_last_name(), + 'billing_address' => array( + 'first_name' => $order->get_billing_first_name(), + 'last_name' => $order->get_billing_last_name(), + 'company' => $order->get_billing_company(), + 'address_1' => $order->get_billing_address_1(), + 'address_2' => $order->get_billing_address_2(), + 'city' => $order->get_billing_city(), + 'state' => $order->get_billing_state(), + 'postcode' => $order->get_billing_postcode(), + 'country' => $order->get_billing_country(), + 'email' => $order->get_billing_email(), + 'phone' => $order->get_billing_phone(), + ), + 'shipping_address' => array( + 'first_name' => $order->get_shipping_first_name(), + 'last_name' => $order->get_shipping_last_name(), + 'company' => $order->get_shipping_company(), + 'address_1' => $order->get_shipping_address_1(), + 'address_2' => $order->get_shipping_address_2(), + 'city' => $order->get_shipping_city(), + 'state' => $order->get_shipping_state(), + 'postcode' => $order->get_shipping_postcode(), + 'country' => $order->get_shipping_country(), + ), + ); + + } else { + + $order_data['customer'] = current( $this->get_customer( $order->get_user_id() ) ); + } + + return $order_data; + } + + /** + * Modify the WP_User_Query to support filtering on the date the customer was created + * + * @since 2.1 + * @param WP_User_Query $query + */ + public function modify_user_query( $query ) { + + if ( $this->created_at_min ) { + $query->query_where .= sprintf( " AND user_registered >= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%h:%%i:%%s' )", esc_sql( $this->created_at_min ) ); + } + + if ( $this->created_at_max ) { + $query->query_where .= sprintf( " AND user_registered <= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%h:%%i:%%s' )", esc_sql( $this->created_at_max ) ); + } + } + + /** + * Validate the request by checking: + * + * 1) the ID is a valid integer + * 2) the ID returns a valid WP_User + * 3) the current user has the proper permissions + * + * @since 2.1 + * @see WC_API_Resource::validate_request() + * @param string|int $id the customer ID + * @param string $type the request type, unused because this method overrides the parent class + * @param string $context the context of the request, either `read`, `edit` or `delete` + * @return int|WP_Error valid user ID or WP_Error if any of the checks fails + */ + protected function validate_request( $id, $type, $context ) { + + $id = absint( $id ); + + // validate ID + if ( empty( $id ) ) { + return new WP_Error( 'woocommerce_api_invalid_customer_id', __( 'Invalid customer ID', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // non-existent IDs return a valid WP_User object with the user ID = 0 + $customer = new WP_User( $id ); + + if ( 0 === $customer->ID ) { + return new WP_Error( 'woocommerce_api_invalid_customer', __( 'Invalid customer', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // validate permissions + switch ( $context ) { + + case 'read': + if ( ! current_user_can( 'list_users' ) ) { + return new WP_Error( 'woocommerce_api_user_cannot_read_customer', __( 'You do not have permission to read this customer', 'woocommerce' ), array( 'status' => 401 ) ); + } + break; + + case 'edit': + if ( ! current_user_can( 'edit_users' ) ) { + return new WP_Error( 'woocommerce_api_user_cannot_edit_customer', __( 'You do not have permission to edit this customer', 'woocommerce' ), array( 'status' => 401 ) ); + } + break; + + case 'delete': + if ( ! current_user_can( 'delete_users' ) ) { + return new WP_Error( 'woocommerce_api_user_cannot_delete_customer', __( 'You do not have permission to delete this customer', 'woocommerce' ), array( 'status' => 401 ) ); + } + break; + } + + return $id; + } + + /** + * Check if the current user can read users + * + * @since 2.1 + * @see WC_API_Resource::is_readable() + * @param int|WP_Post $post unused + * @return bool true if the current user can read users, false otherwise + */ + protected function is_readable( $post ) { + + return current_user_can( 'list_users' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-json-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-json-handler.php new file mode 100644 index 0000000..7a7de67 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-json-handler.php @@ -0,0 +1,74 @@ +api->server->send_status( 400 ); + return wp_json_encode( array( array( 'code' => 'woocommerce_api_jsonp_disabled', 'message' => __( 'JSONP support is disabled on this site', 'woocommerce' ) ) ) ); + } + + $jsonp_callback = $_GET['_jsonp']; + + if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) { + WC()->api->server->send_status( 400 ); + return wp_json_encode( array( array( 'code' => 'woocommerce_api_jsonp_callback_invalid', __( 'The JSONP callback function is invalid', 'woocommerce' ) ) ) ); + } + + WC()->api->server->header( 'X-Content-Type-Options', 'nosniff' ); + + // Prepend '/**/' to mitigate possible JSONP Flash attacks. + // https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/ + return '/**/' . $jsonp_callback . '(' . wp_json_encode( $data ) . ')'; + } + + return wp_json_encode( $data ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-orders.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-orders.php new file mode 100644 index 0000000..d3ce4ad --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-orders.php @@ -0,0 +1,396 @@ + + * GET /orders//notes + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET /orders + $routes[ $this->base ] = array( + array( array( $this, 'get_orders' ), WC_API_Server::READABLE ), + ); + + # GET /orders/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_orders_count' ), WC_API_Server::READABLE ), + ); + + # GET|PUT /orders/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_order' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_order' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /orders//notes + $routes[ $this->base . '/(?P\d+)/notes' ] = array( + array( array( $this, 'get_order_notes' ), WC_API_Server::READABLE ), + ); + + return $routes; + } + + /** + * Get all orders + * + * @since 2.1 + * @param string $fields + * @param array $filter + * @param string $status + * @param int $page + * @return array + */ + public function get_orders( $fields = null, $filter = array(), $status = null, $page = 1 ) { + + if ( ! empty( $status ) ) { + $filter['status'] = $status; + } + + $filter['page'] = $page; + + $query = $this->query_orders( $filter ); + + $orders = array(); + + foreach ( $query->posts as $order_id ) { + + if ( ! $this->is_readable( $order_id ) ) { + continue; + } + + $orders[] = current( $this->get_order( $order_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'orders' => $orders ); + } + + + /** + * Get the order for the given ID + * + * @since 2.1 + * @param int $id the order ID + * @param array $fields + * @return array|WP_Error + */ + public function get_order( $id, $fields = null ) { + + // ensure order ID is valid & user has permission to read + $id = $this->validate_request( $id, 'shop_order', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $order = wc_get_order( $id ); + $order_data = array( + 'id' => $order->get_id(), + 'order_number' => $order->get_order_number(), + 'created_at' => $this->server->format_datetime( $order->get_date_created() ? $order->get_date_created()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'updated_at' => $this->server->format_datetime( $order->get_date_modified() ? $order->get_date_modified()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'completed_at' => $this->server->format_datetime( $order->get_date_completed() ? $order->get_date_completed()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'status' => $order->get_status(), + 'currency' => $order->get_currency(), + 'total' => wc_format_decimal( $order->get_total(), 2 ), + 'subtotal' => wc_format_decimal( $this->get_order_subtotal( $order ), 2 ), + 'total_line_items_quantity' => $order->get_item_count(), + 'total_tax' => wc_format_decimal( $order->get_total_tax(), 2 ), + 'total_shipping' => wc_format_decimal( $order->get_shipping_total(), 2 ), + 'cart_tax' => wc_format_decimal( $order->get_cart_tax(), 2 ), + 'shipping_tax' => wc_format_decimal( $order->get_shipping_tax(), 2 ), + 'total_discount' => wc_format_decimal( $order->get_total_discount(), 2 ), + 'cart_discount' => wc_format_decimal( 0, 2 ), + 'order_discount' => wc_format_decimal( 0, 2 ), + 'shipping_methods' => $order->get_shipping_method(), + 'payment_details' => array( + 'method_id' => $order->get_payment_method(), + 'method_title' => $order->get_payment_method_title(), + 'paid' => ! is_null( $order->get_date_paid() ), + ), + 'billing_address' => array( + 'first_name' => $order->get_billing_first_name(), + 'last_name' => $order->get_billing_last_name(), + 'company' => $order->get_billing_company(), + 'address_1' => $order->get_billing_address_1(), + 'address_2' => $order->get_billing_address_2(), + 'city' => $order->get_billing_city(), + 'state' => $order->get_billing_state(), + 'postcode' => $order->get_billing_postcode(), + 'country' => $order->get_billing_country(), + 'email' => $order->get_billing_email(), + 'phone' => $order->get_billing_phone(), + ), + 'shipping_address' => array( + 'first_name' => $order->get_shipping_first_name(), + 'last_name' => $order->get_shipping_last_name(), + 'company' => $order->get_shipping_company(), + 'address_1' => $order->get_shipping_address_1(), + 'address_2' => $order->get_shipping_address_2(), + 'city' => $order->get_shipping_city(), + 'state' => $order->get_shipping_state(), + 'postcode' => $order->get_shipping_postcode(), + 'country' => $order->get_shipping_country(), + ), + 'note' => $order->get_customer_note(), + 'customer_ip' => $order->get_customer_ip_address(), + 'customer_user_agent' => $order->get_customer_user_agent(), + 'customer_id' => $order->get_user_id(), + 'view_order_url' => $order->get_view_order_url(), + 'line_items' => array(), + 'shipping_lines' => array(), + 'tax_lines' => array(), + 'fee_lines' => array(), + 'coupon_lines' => array(), + ); + + // add line items + foreach ( $order->get_items() as $item_id => $item ) { + $product = $item->get_product(); + $order_data['line_items'][] = array( + 'id' => $item_id, + 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item ), 2 ), + 'total' => wc_format_decimal( $order->get_line_total( $item ), 2 ), + 'total_tax' => wc_format_decimal( $order->get_line_tax( $item ), 2 ), + 'price' => wc_format_decimal( $order->get_item_total( $item ), 2 ), + 'quantity' => $item->get_quantity(), + 'tax_class' => $item->get_tax_class(), + 'name' => $item->get_name(), + 'product_id' => $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id(), + 'sku' => is_object( $product ) ? $product->get_sku() : null, + ); + } + + // add shipping + foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) { + $order_data['shipping_lines'][] = array( + 'id' => $shipping_item_id, + 'method_id' => $shipping_item->get_method_id(), + 'method_title' => $shipping_item->get_name(), + 'total' => wc_format_decimal( $shipping_item->get_total(), 2 ), + ); + } + + // add taxes + foreach ( $order->get_tax_totals() as $tax_code => $tax ) { + $order_data['tax_lines'][] = array( + 'code' => $tax_code, + 'title' => $tax->label, + 'total' => wc_format_decimal( $tax->amount, 2 ), + 'compound' => (bool) $tax->is_compound, + ); + } + + // add fees + foreach ( $order->get_fees() as $fee_item_id => $fee_item ) { + $order_data['fee_lines'][] = array( + 'id' => $fee_item_id, + 'title' => $fee_item->get_name(), + 'tax_class' => $fee_item->get_tax_class(), + 'total' => wc_format_decimal( $order->get_line_total( $fee_item ), 2 ), + 'total_tax' => wc_format_decimal( $order->get_line_tax( $fee_item ), 2 ), + ); + } + + // add coupons + foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) { + $order_data['coupon_lines'][] = array( + 'id' => $coupon_item_id, + 'code' => $coupon_item->get_code(), + 'amount' => wc_format_decimal( $coupon_item->get_discount(), 2 ), + ); + } + + return array( 'order' => apply_filters( 'woocommerce_api_order_response', $order_data, $order, $fields, $this->server ) ); + } + + /** + * Get the total number of orders + * + * @since 2.1 + * + * @param string $status + * @param array $filter + * + * @return array|WP_Error + */ + public function get_orders_count( $status = null, $filter = array() ) { + + if ( ! empty( $status ) ) { + $filter['status'] = $status; + } + + $query = $this->query_orders( $filter ); + + if ( ! current_user_can( 'read_private_shop_orders' ) ) { + return new WP_Error( 'woocommerce_api_user_cannot_read_orders_count', __( 'You do not have permission to read the orders count', 'woocommerce' ), array( 'status' => 401 ) ); + } + + return array( 'count' => (int) $query->found_posts ); + } + + /** + * Edit an order + * + * API v1 only allows updating the status of an order + * + * @since 2.1 + * @param int $id the order ID + * @param array $data + * @return array|WP_Error + */ + public function edit_order( $id, $data ) { + + $id = $this->validate_request( $id, 'shop_order', 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $order = wc_get_order( $id ); + + if ( ! empty( $data['status'] ) ) { + + $order->update_status( $data['status'], isset( $data['note'] ) ? $data['note'] : '' ); + } + + return $this->get_order( $id ); + } + + /** + * Delete an order + * + * @param int $id the order ID + * @param bool $force true to permanently delete order, false to move to trash + * @return array + */ + public function delete_order( $id, $force = false ) { + + $id = $this->validate_request( $id, 'shop_order', 'delete' ); + + return $this->delete( $id, 'order', ( 'true' === $force ) ); + } + + /** + * Get the admin order notes for an order + * + * @since 2.1 + * @param int $id the order ID + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_order_notes( $id, $fields = null ) { + + // ensure ID is valid order ID + $id = $this->validate_request( $id, 'shop_order', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $args = array( + 'post_id' => $id, + 'approve' => 'approve', + 'type' => 'order_note', + ); + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $notes = get_comments( $args ); + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $order_notes = array(); + + foreach ( $notes as $note ) { + + $order_notes[] = array( + 'id' => $note->comment_ID, + 'created_at' => $this->server->format_datetime( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + } + + return array( 'order_notes' => apply_filters( 'woocommerce_api_order_notes_response', $order_notes, $id, $fields, $notes, $this->server ) ); + } + + /** + * Helper method to get order post objects + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_Query + */ + private function query_orders( $args ) { + + // set base query arguments + $query_args = array( + 'fields' => 'ids', + 'post_type' => 'shop_order', + 'post_status' => array_keys( wc_get_order_statuses() ), + ); + + // add status argument + if ( ! empty( $args['status'] ) ) { + + $statuses = 'wc-' . str_replace( ',', ',wc-', $args['status'] ); + $statuses = explode( ',', $statuses ); + $query_args['post_status'] = $statuses; + + unset( $args['status'] ); + + } + + $query_args = $this->merge_query_args( $query_args, $args ); + + return new WP_Query( $query_args ); + } + + /** + * Helper method to get the order subtotal + * + * @since 2.1 + * @param WC_Order $order + * @return float + */ + private function get_order_subtotal( $order ) { + $subtotal = 0; + + // subtotal + foreach ( $order->get_items() as $item ) { + $subtotal += $item->get_subtotal(); + } + + return $subtotal; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-products.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-products.php new file mode 100644 index 0000000..a303e74 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-products.php @@ -0,0 +1,548 @@ + + * GET /products//reviews + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET /products + $routes[ $this->base ] = array( + array( array( $this, 'get_products' ), WC_API_Server::READABLE ), + ); + + # GET /products/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_products_count' ), WC_API_Server::READABLE ), + ); + + # GET /products/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_product' ), WC_API_Server::READABLE ), + ); + + # GET /products//reviews + $routes[ $this->base . '/(?P\d+)/reviews' ] = array( + array( array( $this, 'get_product_reviews' ), WC_API_Server::READABLE ), + ); + + return $routes; + } + + /** + * Get all products + * + * @since 2.1 + * @param string $fields + * @param string $type + * @param array $filter + * @param int $page + * @return array + */ + public function get_products( $fields = null, $type = null, $filter = array(), $page = 1 ) { + + if ( ! empty( $type ) ) { + $filter['type'] = $type; + } + + $filter['page'] = $page; + + $query = $this->query_products( $filter ); + + $products = array(); + + foreach ( $query->posts as $product_id ) { + + if ( ! $this->is_readable( $product_id ) ) { + continue; + } + + $products[] = current( $this->get_product( $product_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'products' => $products ); + } + + /** + * Get the product for the given ID + * + * @since 2.1 + * @param int $id the product ID + * @param string $fields + * @return array|WP_Error + */ + public function get_product( $id, $fields = null ) { + + $id = $this->validate_request( $id, 'product', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $product = wc_get_product( $id ); + + // add data that applies to every product type + $product_data = $this->get_product_data( $product ); + + // add variations to variable products + if ( $product->is_type( 'variable' ) && $product->has_child() ) { + $product_data['variations'] = $this->get_variation_data( $product ); + } + + // add the parent product data to an individual variation + if ( $product->is_type( 'variation' ) ) { + $product_data['parent'] = $this->get_product_data( $product->get_parent_id() ); + } + + return array( 'product' => apply_filters( 'woocommerce_api_product_response', $product_data, $product, $fields, $this->server ) ); + } + + /** + * Get the total number of orders + * + * @since 2.1 + * + * @param string $type + * @param array $filter + * + * @return array|WP_Error + */ + public function get_products_count( $type = null, $filter = array() ) { + + if ( ! empty( $type ) ) { + $filter['type'] = $type; + } + + if ( ! current_user_can( 'read_private_products' ) ) { + return new WP_Error( 'woocommerce_api_user_cannot_read_products_count', __( 'You do not have permission to read the products count', 'woocommerce' ), array( 'status' => 401 ) ); + } + + $query = $this->query_products( $filter ); + + return array( 'count' => (int) $query->found_posts ); + } + + /** + * Edit a product + * + * @param int $id the product ID + * @param array $data + * @return array|WP_Error + */ + public function edit_product( $id, $data ) { + + $id = $this->validate_request( $id, 'product', 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + return $this->get_product( $id ); + } + + /** + * Delete a product + * + * @param int $id the product ID + * @param bool $force true to permanently delete order, false to move to trash + * @return array|WP_Error + */ + public function delete_product( $id, $force = false ) { + + $id = $this->validate_request( $id, 'product', 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + return $this->delete( $id, 'product', ( 'true' === $force ) ); + } + + /** + * Get the reviews for a product + * + * @since 2.1 + * @param int $id the product ID to get reviews for + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_product_reviews( $id, $fields = null ) { + + $id = $this->validate_request( $id, 'product', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $args = array( + 'post_id' => $id, + 'approve' => 'approve', + ); + + $comments = get_comments( $args ); + + $reviews = array(); + + foreach ( $comments as $comment ) { + + $reviews[] = array( + 'id' => $comment->comment_ID, + 'created_at' => $this->server->format_datetime( $comment->comment_date_gmt ), + 'review' => $comment->comment_content, + 'rating' => get_comment_meta( $comment->comment_ID, 'rating', true ), + 'reviewer_name' => $comment->comment_author, + 'reviewer_email' => $comment->comment_author_email, + 'verified' => wc_review_is_from_verified_owner( $comment->comment_ID ), + ); + } + + return array( 'product_reviews' => apply_filters( 'woocommerce_api_product_reviews_response', $reviews, $id, $fields, $comments, $this->server ) ); + } + + /** + * Helper method to get product post objects + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_Query + */ + private function query_products( $args ) { + + // set base query arguments + $query_args = array( + 'fields' => 'ids', + 'post_type' => 'product', + 'post_status' => 'publish', + 'meta_query' => array(), + ); + + if ( ! empty( $args['type'] ) ) { + + $types = explode( ',', $args['type'] ); + + $query_args['tax_query'] = array( + array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $types, + ), + ); + + unset( $args['type'] ); + } + + $query_args = $this->merge_query_args( $query_args, $args ); + + return new WP_Query( $query_args ); + } + + /** + * Get standard product data that applies to every product type + * + * @since 2.1 + * @param WC_Product|int $product + * @return array + */ + private function get_product_data( $product ) { + if ( is_numeric( $product ) ) { + $product = wc_get_product( $product ); + } + + if ( ! is_a( $product, 'WC_Product' ) ) { + return array(); + } + + return array( + 'title' => $product->get_name(), + 'id' => $product->get_id(), + 'created_at' => $this->server->format_datetime( $product->get_date_created(), false, true ), + 'updated_at' => $this->server->format_datetime( $product->get_date_modified(), false, true ), + 'type' => $product->get_type(), + 'status' => $product->get_status(), + 'downloadable' => $product->is_downloadable(), + 'virtual' => $product->is_virtual(), + 'permalink' => $product->get_permalink(), + 'sku' => $product->get_sku(), + 'price' => wc_format_decimal( $product->get_price(), 2 ), + 'regular_price' => wc_format_decimal( $product->get_regular_price(), 2 ), + 'sale_price' => $product->get_sale_price() ? wc_format_decimal( $product->get_sale_price(), 2 ) : null, + 'price_html' => $product->get_price_html(), + 'taxable' => $product->is_taxable(), + 'tax_status' => $product->get_tax_status(), + 'tax_class' => $product->get_tax_class(), + 'managing_stock' => $product->managing_stock(), + 'stock_quantity' => $product->get_stock_quantity(), + 'in_stock' => $product->is_in_stock(), + 'backorders_allowed' => $product->backorders_allowed(), + 'backordered' => $product->is_on_backorder(), + 'sold_individually' => $product->is_sold_individually(), + 'purchaseable' => $product->is_purchasable(), + 'featured' => $product->is_featured(), + 'visible' => $product->is_visible(), + 'catalog_visibility' => $product->get_catalog_visibility(), + 'on_sale' => $product->is_on_sale(), + 'weight' => $product->get_weight() ? wc_format_decimal( $product->get_weight(), 2 ) : null, + 'dimensions' => array( + 'length' => $product->get_length(), + 'width' => $product->get_width(), + 'height' => $product->get_height(), + 'unit' => get_option( 'woocommerce_dimension_unit' ), + ), + 'shipping_required' => $product->needs_shipping(), + 'shipping_taxable' => $product->is_shipping_taxable(), + 'shipping_class' => $product->get_shipping_class(), + 'shipping_class_id' => ( 0 !== $product->get_shipping_class_id() ) ? $product->get_shipping_class_id() : null, + 'description' => apply_filters( 'the_content', $product->get_description() ), + 'short_description' => apply_filters( 'woocommerce_short_description', $product->get_short_description() ), + 'reviews_allowed' => $product->get_reviews_allowed(), + 'average_rating' => wc_format_decimal( $product->get_average_rating(), 2 ), + 'rating_count' => $product->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids() ), + 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids() ), + 'categories' => wc_get_object_terms( $product->get_id(), 'product_cat', 'name' ), + 'tags' => wc_get_object_terms( $product->get_id(), 'product_tag', 'name' ), + 'images' => $this->get_images( $product ), + 'featured_src' => wp_get_attachment_url( get_post_thumbnail_id( $product->get_id() ) ), + 'attributes' => $this->get_attributes( $product ), + 'downloads' => $this->get_downloads( $product ), + 'download_limit' => $product->get_download_limit(), + 'download_expiry' => $product->get_download_expiry(), + 'download_type' => 'standard', + 'purchase_note' => apply_filters( 'the_content', $product->get_purchase_note() ), + 'total_sales' => $product->get_total_sales(), + 'variations' => array(), + 'parent' => array(), + ); + } + + /** + * Get an individual variation's data + * + * @since 2.1 + * @param WC_Product $product + * @return array + */ + private function get_variation_data( $product ) { + $variations = array(); + + foreach ( $product->get_children() as $child_id ) { + $variation = wc_get_product( $child_id ); + + if ( ! $variation || ! $variation->exists() ) { + continue; + } + + $variations[] = array( + 'id' => $variation->get_id(), + 'created_at' => $this->server->format_datetime( $variation->get_date_created(), false, true ), + 'updated_at' => $this->server->format_datetime( $variation->get_date_modified(), false, true ), + 'downloadable' => $variation->is_downloadable(), + 'virtual' => $variation->is_virtual(), + 'permalink' => $variation->get_permalink(), + 'sku' => $variation->get_sku(), + 'price' => wc_format_decimal( $variation->get_price(), 2 ), + 'regular_price' => wc_format_decimal( $variation->get_regular_price(), 2 ), + 'sale_price' => $variation->get_sale_price() ? wc_format_decimal( $variation->get_sale_price(), 2 ) : null, + 'taxable' => $variation->is_taxable(), + 'tax_status' => $variation->get_tax_status(), + 'tax_class' => $variation->get_tax_class(), + 'stock_quantity' => (int) $variation->get_stock_quantity(), + 'in_stock' => $variation->is_in_stock(), + 'backordered' => $variation->is_on_backorder(), + 'purchaseable' => $variation->is_purchasable(), + 'visible' => $variation->variation_is_visible(), + 'on_sale' => $variation->is_on_sale(), + 'weight' => $variation->get_weight() ? wc_format_decimal( $variation->get_weight(), 2 ) : null, + 'dimensions' => array( + 'length' => $variation->get_length(), + 'width' => $variation->get_width(), + 'height' => $variation->get_height(), + 'unit' => get_option( 'woocommerce_dimension_unit' ), + ), + 'shipping_class' => $variation->get_shipping_class(), + 'shipping_class_id' => ( 0 !== $variation->get_shipping_class_id() ) ? $variation->get_shipping_class_id() : null, + 'image' => $this->get_images( $variation ), + 'attributes' => $this->get_attributes( $variation ), + 'downloads' => $this->get_downloads( $variation ), + 'download_limit' => (int) $product->get_download_limit(), + 'download_expiry' => (int) $product->get_download_expiry(), + ); + } + + return $variations; + } + + /** + * Get the images for a product or product variation + * + * @since 2.1 + * @param WC_Product|WC_Product_Variation $product + * @return array + */ + private function get_images( $product ) { + $images = $attachment_ids = array(); + $product_image = $product->get_image_id(); + + // Add featured image. + if ( ! empty( $product_image ) ) { + $attachment_ids[] = $product_image; + } + + // add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $position => $attachment_id ) { + + $attachment_post = get_post( $attachment_id ); + + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'created_at' => $this->server->format_datetime( $attachment_post->post_date_gmt ), + 'updated_at' => $this->server->format_datetime( $attachment_post->post_modified_gmt ), + 'src' => current( $attachment ), + 'title' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + 'position' => $position, + ); + } + + // Set a placeholder image if the product has no images set. + if ( empty( $images ) ) { + + $images[] = array( + 'id' => 0, + 'created_at' => $this->server->format_datetime( time() ), // default to now + 'updated_at' => $this->server->format_datetime( time() ), + 'src' => wc_placeholder_img_src(), + 'title' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), + 'position' => 0, + ); + } + + return $images; + } + + /** + * Get attribute options. + * + * @param int $product_id + * @param array $attribute + * @return array + */ + protected function get_attribute_options( $product_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( $product_id, $attribute['name'], array( 'fields' => 'names' ) ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation + * + * @since 2.1 + * @param WC_Product|WC_Product_Variation $product + * @return array + */ + private function get_attributes( $product ) { + + $attributes = array(); + + if ( $product->is_type( 'variation' ) ) { + + // variation attributes + foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { + + // taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_` + $attributes[] = array( + 'name' => ucwords( str_replace( 'attribute_', '', wc_attribute_taxonomy_slug( $attribute_name ) ) ), + 'option' => $attribute, + ); + } + } else { + + foreach ( $product->get_attributes() as $attribute ) { + $attributes[] = array( + 'name' => ucwords( wc_attribute_taxonomy_slug( $attribute['name'] ) ), + 'position' => $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } + } + + return $attributes; + } + + /** + * Get the downloads for a product or product variation + * + * @since 2.1 + * @param WC_Product|WC_Product_Variation $product + * @return array + */ + private function get_downloads( $product ) { + + $downloads = array(); + + if ( $product->is_downloadable() ) { + + foreach ( $product->get_downloads() as $file_id => $file ) { + + $downloads[] = array( + 'id' => $file_id, // do not cast as int as this is a hash + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-reports.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-reports.php new file mode 100644 index 0000000..1f35428 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-reports.php @@ -0,0 +1,482 @@ +base ] = array( + array( array( $this, 'get_reports' ), WC_API_Server::READABLE ), + ); + + # GET /reports/sales + $routes[ $this->base . '/sales' ] = array( + array( array( $this, 'get_sales_report' ), WC_API_Server::READABLE ), + ); + + # GET /reports/sales/top_sellers + $routes[ $this->base . '/sales/top_sellers' ] = array( + array( array( $this, 'get_top_sellers_report' ), WC_API_Server::READABLE ), + ); + + return $routes; + } + + /** + * Get a simple listing of available reports + * + * @since 2.1 + * @return array + */ + public function get_reports() { + + return array( 'reports' => array( 'sales', 'sales/top_sellers' ) ); + } + + /** + * Get the sales report + * + * @since 2.1 + * @param string $fields fields to include in response + * @param array $filter date filtering + * @return array|WP_Error + */ + public function get_sales_report( $fields = null, $filter = array() ) { + + // check user permissions + $check = $this->validate_request(); + + if ( is_wp_error( $check ) ) { + return $check; + } + + // set date filtering + $this->setup_report( $filter ); + + // total sales, taxes, shipping, and order count + $totals = $this->report->get_order_report_data( array( + 'data' => array( + '_order_total' => array( + 'type' => 'meta', + 'function' => 'SUM', + 'name' => 'sales', + ), + '_order_tax' => array( + 'type' => 'meta', + 'function' => 'SUM', + 'name' => 'tax', + ), + '_order_shipping_tax' => array( + 'type' => 'meta', + 'function' => 'SUM', + 'name' => 'shipping_tax', + ), + '_order_shipping' => array( + 'type' => 'meta', + 'function' => 'SUM', + 'name' => 'shipping', + ), + 'ID' => array( + 'type' => 'post_data', + 'function' => 'COUNT', + 'name' => 'order_count', + ), + ), + 'filter_range' => true, + ) ); + + // total items ordered + $total_items = absint( $this->report->get_order_report_data( array( + 'data' => array( + '_qty' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => 'SUM', + 'name' => 'order_item_qty', + ), + ), + 'query_type' => 'get_var', + 'filter_range' => true, + ) ) ); + + // total discount used + $total_discount = $this->report->get_order_report_data( array( + 'data' => array( + 'discount_amount' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'coupon', + 'function' => 'SUM', + 'name' => 'discount_amount', + ), + ), + 'where' => array( + array( + 'key' => 'order_item_type', + 'value' => 'coupon', + 'operator' => '=', + ), + ), + 'query_type' => 'get_var', + 'filter_range' => true, + ) ); + + // new customers + $users_query = new WP_User_Query( + array( + 'fields' => array( 'user_registered' ), + 'role' => 'customer', + ) + ); + + $customers = $users_query->get_results(); + + foreach ( $customers as $key => $customer ) { + if ( strtotime( $customer->user_registered ) < $this->report->start_date || strtotime( $customer->user_registered ) > $this->report->end_date ) { + unset( $customers[ $key ] ); + } + } + + $total_customers = count( $customers ); + + // get order totals grouped by period + $orders = $this->report->get_order_report_data( array( + 'data' => array( + '_order_total' => array( + 'type' => 'meta', + 'function' => 'SUM', + 'name' => 'total_sales', + ), + '_order_shipping' => array( + 'type' => 'meta', + 'function' => 'SUM', + 'name' => 'total_shipping', + ), + '_order_tax' => array( + 'type' => 'meta', + 'function' => 'SUM', + 'name' => 'total_tax', + ), + '_order_shipping_tax' => array( + 'type' => 'meta', + 'function' => 'SUM', + 'name' => 'total_shipping_tax', + ), + 'ID' => array( + 'type' => 'post_data', + 'function' => 'COUNT', + 'name' => 'total_orders', + 'distinct' => true, + ), + 'post_date' => array( + 'type' => 'post_data', + 'function' => '', + 'name' => 'post_date', + ), + ), + 'group_by' => $this->report->group_by_query, + 'order_by' => 'post_date ASC', + 'query_type' => 'get_results', + 'filter_range' => true, + ) ); + + // get order item totals grouped by period + $order_items = $this->report->get_order_report_data( array( + 'data' => array( + '_qty' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => 'SUM', + 'name' => 'order_item_count', + ), + 'post_date' => array( + 'type' => 'post_data', + 'function' => '', + 'name' => 'post_date', + ), + ), + 'where' => array( + array( + 'key' => 'order_item_type', + 'value' => 'line_item', + 'operator' => '=', + ), + ), + 'group_by' => $this->report->group_by_query, + 'order_by' => 'post_date ASC', + 'query_type' => 'get_results', + 'filter_range' => true, + ) ); + + // get discount totals grouped by period + $discounts = $this->report->get_order_report_data( array( + 'data' => array( + 'discount_amount' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'coupon', + 'function' => 'SUM', + 'name' => 'discount_amount', + ), + 'post_date' => array( + 'type' => 'post_data', + 'function' => '', + 'name' => 'post_date', + ), + ), + 'where' => array( + array( + 'key' => 'order_item_type', + 'value' => 'coupon', + 'operator' => '=', + ), + ), + 'group_by' => $this->report->group_by_query . ', order_item_name', + 'order_by' => 'post_date ASC', + 'query_type' => 'get_results', + 'filter_range' => true, + ) ); + + $period_totals = array(); + + // setup period totals by ensuring each period in the interval has data + for ( $i = 0; $i <= $this->report->chart_interval; $i ++ ) { + + switch ( $this->report->chart_groupby ) { + case 'day' : + $time = date( 'Y-m-d', strtotime( "+{$i} DAY", $this->report->start_date ) ); + break; + case 'month' : + $time = date( 'Y-m', strtotime( "+{$i} MONTH", $this->report->start_date ) ); + break; + } + + // set the customer signups for each period + $customer_count = 0; + foreach ( $customers as $customer ) { + + if ( date( ( 'day' == $this->report->chart_groupby ) ? 'Y-m-d' : 'Y-m', strtotime( $customer->user_registered ) ) == $time ) { + $customer_count++; + } + } + + $period_totals[ $time ] = array( + 'sales' => wc_format_decimal( 0.00, 2 ), + 'orders' => 0, + 'items' => 0, + 'tax' => wc_format_decimal( 0.00, 2 ), + 'shipping' => wc_format_decimal( 0.00, 2 ), + 'discount' => wc_format_decimal( 0.00, 2 ), + 'customers' => $customer_count, + ); + } + + // add total sales, total order count, total tax and total shipping for each period + foreach ( $orders as $order ) { + + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['sales'] = wc_format_decimal( $order->total_sales, 2 ); + $period_totals[ $time ]['orders'] = (int) $order->total_orders; + $period_totals[ $time ]['tax'] = wc_format_decimal( $order->total_tax + $order->total_shipping_tax, 2 ); + $period_totals[ $time ]['shipping'] = wc_format_decimal( $order->total_shipping, 2 ); + } + + // add total order items for each period + foreach ( $order_items as $order_item ) { + + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['items'] = (int) $order_item->order_item_count; + } + + // add total discount for each period + foreach ( $discounts as $discount ) { + + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['discount'] = wc_format_decimal( $discount->discount_amount, 2 ); + } + + $sales_data = array( + 'total_sales' => wc_format_decimal( $totals->sales, 2 ), + 'average_sales' => wc_format_decimal( $totals->sales / ( $this->report->chart_interval + 1 ), 2 ), + 'total_orders' => (int) $totals->order_count, + 'total_items' => $total_items, + 'total_tax' => wc_format_decimal( $totals->tax + $totals->shipping_tax, 2 ), + 'total_shipping' => wc_format_decimal( $totals->shipping, 2 ), + 'total_discount' => is_null( $total_discount ) ? wc_format_decimal( 0.00, 2 ) : wc_format_decimal( $total_discount, 2 ), + 'totals_grouped_by' => $this->report->chart_groupby, + 'totals' => $period_totals, + 'total_customers' => $total_customers, + ); + + return array( 'sales' => apply_filters( 'woocommerce_api_report_response', $sales_data, $this->report, $fields, $this->server ) ); + } + + /** + * Get the top sellers report + * + * @since 2.1 + * @param string $fields fields to include in response + * @param array $filter date filtering + * @return array|WP_Error + */ + public function get_top_sellers_report( $fields = null, $filter = array() ) { + + // check user permissions + $check = $this->validate_request(); + + if ( is_wp_error( $check ) ) { + return $check; + } + + // set date filtering + $this->setup_report( $filter ); + + $top_sellers = $this->report->get_order_report_data( array( + 'data' => array( + '_product_id' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => '', + 'name' => 'product_id', + ), + '_qty' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => 'SUM', + 'name' => 'order_item_qty', + ), + ), + 'order_by' => 'order_item_qty DESC', + 'group_by' => 'product_id', + 'limit' => isset( $filter['limit'] ) ? absint( $filter['limit'] ) : 12, + 'query_type' => 'get_results', + 'filter_range' => true, + ) ); + + $top_sellers_data = array(); + + foreach ( $top_sellers as $top_seller ) { + + $product = wc_get_product( $top_seller->product_id ); + + $top_sellers_data[] = array( + 'title' => $product->get_name(), + 'product_id' => $top_seller->product_id, + 'quantity' => $top_seller->order_item_qty, + ); + } + + return array( 'top_sellers' => apply_filters( 'woocommerce_api_report_response', $top_sellers_data, $this->report, $fields, $this->server ) ); + } + + /** + * Setup the report object and parse any date filtering + * + * @since 2.1 + * @param array $filter date filtering + */ + private function setup_report( $filter ) { + + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' ); + + $this->report = new WC_Admin_Report(); + + if ( empty( $filter['period'] ) ) { + + // custom date range + $filter['period'] = 'custom'; + + if ( ! empty( $filter['date_min'] ) || ! empty( $filter['date_max'] ) ) { + + // overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges + $_GET['start_date'] = $this->server->parse_datetime( $filter['date_min'] ); + $_GET['end_date'] = isset( $filter['date_max'] ) ? $this->server->parse_datetime( $filter['date_max'] ) : null; + + } else { + + // default custom range to today + $_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) ); + } + } else { + + // ensure period is valid + if ( ! in_array( $filter['period'], array( 'week', 'month', 'last_month', 'year' ) ) ) { + $filter['period'] = 'week'; + } + + // TODO: change WC_Admin_Report class to use "week" instead, as it's more consistent with other periods + // allow "week" for period instead of "7day" + if ( 'week' === $filter['period'] ) { + $filter['period'] = '7day'; + } + } + + $this->report->calculate_current_range( $filter['period'] ); + } + + /** + * Verify that the current user has permission to view reports + * + * @since 2.1 + * @see WC_API_Resource::validate_request() + * @param null $id unused + * @param null $type unused + * @param null $context unused + * @return true|WP_Error + */ + protected function validate_request( $id = null, $type = null, $context = null ) { + + if ( ! current_user_can( 'view_woocommerce_reports' ) ) { + + return new WP_Error( 'woocommerce_api_user_cannot_read_report', __( 'You do not have permission to read this report', 'woocommerce' ), array( 'status' => 401 ) ); + + } else { + + return true; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-resource.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-resource.php new file mode 100644 index 0000000..6eeefcf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-resource.php @@ -0,0 +1,409 @@ +server = $server; + + // automatically register routes for sub-classes + add_filter( 'woocommerce_api_endpoints', array( $this, 'register_routes' ) ); + + // remove fields from responses when requests specify certain fields + // note these are hooked at a later priority so data added via filters (e.g. customer data to the order response) + // still has the fields filtered properly + foreach ( array( 'order', 'coupon', 'customer', 'product', 'report' ) as $resource ) { + + add_filter( "woocommerce_api_{$resource}_response", array( $this, 'maybe_add_meta' ), 15, 2 ); + add_filter( "woocommerce_api_{$resource}_response", array( $this, 'filter_response_fields' ), 20, 3 ); + } + } + + /** + * Validate the request by checking: + * + * 1) the ID is a valid integer + * 2) the ID returns a valid post object and matches the provided post type + * 3) the current user has the proper permissions to read/edit/delete the post + * + * @since 2.1 + * @param string|int $id the post ID + * @param string $type the post type, either `shop_order`, `shop_coupon`, or `product` + * @param string $context the context of the request, either `read`, `edit` or `delete` + * @return int|WP_Error valid post ID or WP_Error if any of the checks fails + */ + protected function validate_request( $id, $type, $context ) { + + if ( 'shop_order' === $type || 'shop_coupon' === $type ) { + $resource_name = str_replace( 'shop_', '', $type ); + } else { + $resource_name = $type; + } + + $id = absint( $id ); + + // validate ID + if ( empty( $id ) ) { + return new WP_Error( "woocommerce_api_invalid_{$resource_name}_id", sprintf( __( 'Invalid %s ID', 'woocommerce' ), $type ), array( 'status' => 404 ) ); + } + + // only custom post types have per-post type/permission checks + if ( 'customer' !== $type ) { + + $post = get_post( $id ); + + // for checking permissions, product variations are the same as the product post type + $post_type = ( 'product_variation' === $post->post_type ) ? 'product' : $post->post_type; + + // validate post type + if ( $type !== $post_type ) { + return new WP_Error( "woocommerce_api_invalid_{$resource_name}", sprintf( __( 'Invalid %s', 'woocommerce' ), $resource_name ), array( 'status' => 404 ) ); + } + + // validate permissions + switch ( $context ) { + + case 'read': + if ( ! $this->is_readable( $post ) ) { + return new WP_Error( "woocommerce_api_user_cannot_read_{$resource_name}", sprintf( __( 'You do not have permission to read this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) ); + } + break; + + case 'edit': + if ( ! $this->is_editable( $post ) ) { + return new WP_Error( "woocommerce_api_user_cannot_edit_{$resource_name}", sprintf( __( 'You do not have permission to edit this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) ); + } + break; + + case 'delete': + if ( ! $this->is_deletable( $post ) ) { + return new WP_Error( "woocommerce_api_user_cannot_delete_{$resource_name}", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) ); + } + break; + } + } + + return $id; + } + + /** + * Add common request arguments to argument list before WP_Query is run + * + * @since 2.1 + * @param array $base_args required arguments for the query (e.g. `post_type`, etc) + * @param array $request_args arguments provided in the request + * @return array + */ + protected function merge_query_args( $base_args, $request_args ) { + + $args = array(); + + // date + if ( ! empty( $request_args['created_at_min'] ) || ! empty( $request_args['created_at_max'] ) || ! empty( $request_args['updated_at_min'] ) || ! empty( $request_args['updated_at_max'] ) ) { + + $args['date_query'] = array(); + + // resources created after specified date + if ( ! empty( $request_args['created_at_min'] ) ) { + $args['date_query'][] = array( 'column' => 'post_date_gmt', 'after' => $this->server->parse_datetime( $request_args['created_at_min'] ), 'inclusive' => true ); + } + + // resources created before specified date + if ( ! empty( $request_args['created_at_max'] ) ) { + $args['date_query'][] = array( 'column' => 'post_date_gmt', 'before' => $this->server->parse_datetime( $request_args['created_at_max'] ), 'inclusive' => true ); + } + + // resources updated after specified date + if ( ! empty( $request_args['updated_at_min'] ) ) { + $args['date_query'][] = array( 'column' => 'post_modified_gmt', 'after' => $this->server->parse_datetime( $request_args['updated_at_min'] ), 'inclusive' => true ); + } + + // resources updated before specified date + if ( ! empty( $request_args['updated_at_max'] ) ) { + $args['date_query'][] = array( 'column' => 'post_modified_gmt', 'before' => $this->server->parse_datetime( $request_args['updated_at_max'] ), 'inclusive' => true ); + } + } + + // search + if ( ! empty( $request_args['q'] ) ) { + $args['s'] = $request_args['q']; + } + + // resources per response + if ( ! empty( $request_args['limit'] ) ) { + $args['posts_per_page'] = $request_args['limit']; + } + + // resource offset + if ( ! empty( $request_args['offset'] ) ) { + $args['offset'] = $request_args['offset']; + } + + // resource page + $args['paged'] = ( isset( $request_args['page'] ) ) ? absint( $request_args['page'] ) : 1; + + return array_merge( $base_args, $args ); + } + + /** + * Add meta to resources when requested by the client. Meta is added as a top-level + * `_meta` attribute (e.g. `order_meta`) as a list of key/value pairs + * + * @since 2.1 + * @param array $data the resource data + * @param object $resource the resource object (e.g WC_Order) + * @return mixed + */ + public function maybe_add_meta( $data, $resource ) { + + if ( isset( $this->server->params['GET']['filter']['meta'] ) && 'true' === $this->server->params['GET']['filter']['meta'] && is_object( $resource ) ) { + + // don't attempt to add meta more than once + if ( preg_grep( '/[a-z]+_meta/', array_keys( $data ) ) ) { + return $data; + } + + // define the top-level property name for the meta + switch ( get_class( $resource ) ) { + + case 'WC_Order': + $meta_name = 'order_meta'; + break; + + case 'WC_Coupon': + $meta_name = 'coupon_meta'; + break; + + case 'WP_User': + $meta_name = 'customer_meta'; + break; + + default: + $meta_name = 'product_meta'; + break; + } + + if ( is_a( $resource, 'WP_User' ) ) { + + // customer meta + $meta = (array) get_user_meta( $resource->ID ); + + } else { + + // coupon/order/product meta + $meta = (array) get_post_meta( $resource->get_id() ); + } + + foreach ( $meta as $meta_key => $meta_value ) { + + // don't add hidden meta by default + if ( ! is_protected_meta( $meta_key ) ) { + $data[ $meta_name ][ $meta_key ] = maybe_unserialize( $meta_value[0] ); + } + } + } + + return $data; + } + + /** + * Restrict the fields included in the response if the request specified certain only certain fields should be returned + * + * @since 2.1 + * @param array $data the response data + * @param object $resource the object that provided the response data, e.g. WC_Coupon or WC_Order + * @param array|string the requested list of fields to include in the response + * @return array response data + */ + public function filter_response_fields( $data, $resource, $fields ) { + + if ( ! is_array( $data ) || empty( $fields ) ) { + return $data; + } + + $fields = explode( ',', $fields ); + $sub_fields = array(); + + // get sub fields + foreach ( $fields as $field ) { + + if ( false !== strpos( $field, '.' ) ) { + + list( $name, $value ) = explode( '.', $field ); + + $sub_fields[ $name ] = $value; + } + } + + // iterate through top-level fields + foreach ( $data as $data_field => $data_value ) { + + // if a field has sub-fields and the top-level field has sub-fields to filter + if ( is_array( $data_value ) && in_array( $data_field, array_keys( $sub_fields ) ) ) { + + // iterate through each sub-field + foreach ( $data_value as $sub_field => $sub_field_value ) { + + // remove non-matching sub-fields + if ( ! in_array( $sub_field, $sub_fields ) ) { + unset( $data[ $data_field ][ $sub_field ] ); + } + } + } else { + + // remove non-matching top-level fields + if ( ! in_array( $data_field, $fields ) ) { + unset( $data[ $data_field ] ); + } + } + } + + return $data; + } + + /** + * Delete a given resource + * + * @since 2.1 + * @param int $id the resource ID + * @param string $type the resource post type, or `customer` + * @param bool $force true to permanently delete resource, false to move to trash (not supported for `customer`) + * @return array|WP_Error + */ + protected function delete( $id, $type, $force = false ) { + + if ( 'shop_order' === $type || 'shop_coupon' === $type ) { + $resource_name = str_replace( 'shop_', '', $type ); + } else { + $resource_name = $type; + } + + if ( 'customer' === $type ) { + + $result = wp_delete_user( $id ); + + if ( $result ) { + return array( 'message' => __( 'Permanently deleted customer', 'woocommerce' ) ); + } else { + return new WP_Error( 'woocommerce_api_cannot_delete_customer', __( 'The customer cannot be deleted', 'woocommerce' ), array( 'status' => 500 ) ); + } + } else { + + // delete order/coupon/product + $result = ( $force ) ? wp_delete_post( $id, true ) : wp_trash_post( $id ); + + if ( ! $result ) { + return new WP_Error( "woocommerce_api_cannot_delete_{$resource_name}", sprintf( __( 'This %s cannot be deleted', 'woocommerce' ), $resource_name ), array( 'status' => 500 ) ); + } + + if ( $force ) { + return array( 'message' => sprintf( __( 'Permanently deleted %s', 'woocommerce' ), $resource_name ) ); + + } else { + + $this->server->send_status( '202' ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), $resource_name ) ); + } + } + } + + + /** + * Checks if the given post is readable by the current user + * + * @since 2.1 + * @see WC_API_Resource::check_permission() + * @param WP_Post|int $post + * @return bool + */ + protected function is_readable( $post ) { + + return $this->check_permission( $post, 'read' ); + } + + /** + * Checks if the given post is editable by the current user + * + * @since 2.1 + * @see WC_API_Resource::check_permission() + * @param WP_Post|int $post + * @return bool + */ + protected function is_editable( $post ) { + + return $this->check_permission( $post, 'edit' ); + + } + + /** + * Checks if the given post is deletable by the current user + * + * @since 2.1 + * @see WC_API_Resource::check_permission() + * @param WP_Post|int $post + * @return bool + */ + protected function is_deletable( $post ) { + + return $this->check_permission( $post, 'delete' ); + } + + /** + * Checks the permissions for the current user given a post and context + * + * @since 2.1 + * @param WP_Post|int $post + * @param string $context the type of permission to check, either `read`, `write`, or `delete` + * @return bool true if the current user has the permissions to perform the context on the post + */ + private function check_permission( $post, $context ) { + + if ( ! is_a( $post, 'WP_Post' ) ) { + $post = get_post( $post ); + } + + if ( is_null( $post ) ) { + return false; + } + + $post_type = get_post_type_object( $post->post_type ); + + if ( 'read' === $context ) { + return current_user_can( $post_type->cap->read_private_posts, $post->ID ); + } elseif ( 'edit' === $context ) { + return current_user_can( $post_type->cap->edit_post, $post->ID ); + } elseif ( 'delete' === $context ) { + return current_user_can( $post_type->cap->delete_post, $post->ID ); + } else { + return false; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-server.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-server.php new file mode 100644 index 0000000..743eac2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-server.php @@ -0,0 +1,782 @@ + self::METHOD_GET, + 'GET' => self::METHOD_GET, + 'POST' => self::METHOD_POST, + 'PUT' => self::METHOD_PUT, + 'PATCH' => self::METHOD_PATCH, + 'DELETE' => self::METHOD_DELETE, + ); + + /** + * Requested path (relative to the API root, wp-json.php) + * + * @var string + */ + public $path = ''; + + /** + * Requested method (GET/HEAD/POST/PUT/PATCH/DELETE) + * + * @var string + */ + public $method = 'HEAD'; + + /** + * Request parameters + * + * This acts as an abstraction of the superglobals + * (GET => $_GET, POST => $_POST) + * + * @var array + */ + public $params = array( 'GET' => array(), 'POST' => array() ); + + /** + * Request headers + * + * @var array + */ + public $headers = array(); + + /** + * Request files (matches $_FILES) + * + * @var array + */ + public $files = array(); + + /** + * Request/Response handler, either JSON by default + * or XML if requested by client + * + * @var WC_API_Handler + */ + public $handler; + + + /** + * Setup class and set request/response handler + * + * @since 2.1 + * @param $path + */ + public function __construct( $path ) { + + if ( empty( $path ) ) { + if ( isset( $_SERVER['PATH_INFO'] ) ) { + $path = $_SERVER['PATH_INFO']; + } else { + $path = '/'; + } + } + + $this->path = $path; + $this->method = $_SERVER['REQUEST_METHOD']; + $this->params['GET'] = $_GET; + $this->params['POST'] = $_POST; + $this->headers = $this->get_headers( $_SERVER ); + $this->files = $_FILES; + + // Compatibility for clients that can't use PUT/PATCH/DELETE + if ( isset( $_GET['_method'] ) ) { + $this->method = strtoupper( $_GET['_method'] ); + } elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) { + $this->method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']; + } + + // determine type of request/response and load handler, JSON by default + if ( $this->is_json_request() ) { + $handler_class = 'WC_API_JSON_Handler'; + } elseif ( $this->is_xml_request() ) { + $handler_class = 'WC_API_XML_Handler'; + } else { + $handler_class = apply_filters( 'woocommerce_api_default_response_handler', 'WC_API_JSON_Handler', $this->path, $this ); + } + + $this->handler = new $handler_class(); + } + + /** + * Check authentication for the request + * + * @since 2.1 + * @return WP_User|WP_Error WP_User object indicates successful login, WP_Error indicates unsuccessful login + */ + public function check_authentication() { + + // allow plugins to remove default authentication or add their own authentication + $user = apply_filters( 'woocommerce_api_check_authentication', null, $this ); + + // API requests run under the context of the authenticated user + if ( is_a( $user, 'WP_User' ) ) { + wp_set_current_user( $user->ID ); + } elseif ( ! is_wp_error( $user ) ) { + // WP_Errors are handled in serve_request() + $user = new WP_Error( 'woocommerce_api_authentication_error', __( 'Invalid authentication method', 'woocommerce' ), array( 'code' => 500 ) ); + } + + return $user; + } + + /** + * Convert an error to an array + * + * This iterates over all error codes and messages to change it into a flat + * array. This enables simpler client behaviour, as it is represented as a + * list in JSON rather than an object/map + * + * @since 2.1 + * @param WP_Error $error + * @return array List of associative arrays with code and message keys + */ + protected function error_to_array( $error ) { + $errors = array(); + foreach ( (array) $error->errors as $code => $messages ) { + foreach ( (array) $messages as $message ) { + $errors[] = array( 'code' => $code, 'message' => $message ); + } + } + return array( 'errors' => $errors ); + } + + /** + * Handle serving an API request + * + * Matches the current server URI to a route and runs the first matching + * callback then outputs a JSON representation of the returned value. + * + * @since 2.1 + * @uses WC_API_Server::dispatch() + */ + public function serve_request() { + + do_action( 'woocommerce_api_server_before_serve', $this ); + + $this->header( 'Content-Type', $this->handler->get_content_type(), true ); + + // the API is enabled by default + if ( ! apply_filters( 'woocommerce_api_enabled', true, $this ) || ( 'no' === get_option( 'woocommerce_api_enabled' ) ) ) { + + $this->send_status( 404 ); + + echo $this->handler->generate_response( array( 'errors' => array( 'code' => 'woocommerce_api_disabled', 'message' => 'The WooCommerce API is disabled on this site' ) ) ); + + return; + } + + $result = $this->check_authentication(); + + // if authorization check was successful, dispatch the request + if ( ! is_wp_error( $result ) ) { + $result = $this->dispatch(); + } + + // handle any dispatch errors + if ( is_wp_error( $result ) ) { + $data = $result->get_error_data(); + if ( is_array( $data ) && isset( $data['status'] ) ) { + $this->send_status( $data['status'] ); + } + + $result = $this->error_to_array( $result ); + } + + // This is a filter rather than an action, since this is designed to be + // re-entrant if needed + $served = apply_filters( 'woocommerce_api_serve_request', false, $result, $this ); + + if ( ! $served ) { + + if ( 'HEAD' === $this->method ) { + return; + } + + echo $this->handler->generate_response( $result ); + } + } + + /** + * Retrieve the route map + * + * The route map is an associative array with path regexes as the keys. The + * value is an indexed array with the callback function/method as the first + * item, and a bitmask of HTTP methods as the second item (see the class + * constants). + * + * Each route can be mapped to more than one callback by using an array of + * the indexed arrays. This allows mapping e.g. GET requests to one callback + * and POST requests to another. + * + * Note that the path regexes (array keys) must have @ escaped, as this is + * used as the delimiter with preg_match() + * + * @since 2.1 + * @return array `'/path/regex' => array( $callback, $bitmask )` or `'/path/regex' => array( array( $callback, $bitmask ), ...)` + */ + public function get_routes() { + + // index added by default + $endpoints = array( + + '/' => array( array( $this, 'get_index' ), self::READABLE ), + ); + + $endpoints = apply_filters( 'woocommerce_api_endpoints', $endpoints ); + + // Normalise the endpoints + foreach ( $endpoints as $route => &$handlers ) { + if ( count( $handlers ) <= 2 && isset( $handlers[1] ) && ! is_array( $handlers[1] ) ) { + $handlers = array( $handlers ); + } + } + + return $endpoints; + } + + /** + * Match the request to a callback and call it + * + * @since 2.1 + * @return mixed The value returned by the callback, or a WP_Error instance + */ + public function dispatch() { + + switch ( $this->method ) { + + case 'HEAD': + case 'GET': + $method = self::METHOD_GET; + break; + + case 'POST': + $method = self::METHOD_POST; + break; + + case 'PUT': + $method = self::METHOD_PUT; + break; + + case 'PATCH': + $method = self::METHOD_PATCH; + break; + + case 'DELETE': + $method = self::METHOD_DELETE; + break; + + default: + return new WP_Error( 'woocommerce_api_unsupported_method', __( 'Unsupported request method', 'woocommerce' ), array( 'status' => 400 ) ); + } + + foreach ( $this->get_routes() as $route => $handlers ) { + foreach ( $handlers as $handler ) { + $callback = $handler[0]; + $supported = isset( $handler[1] ) ? $handler[1] : self::METHOD_GET; + + if ( ! ( $supported & $method ) ) { + continue; + } + + $match = preg_match( '@^' . $route . '$@i', urldecode( $this->path ), $args ); + + if ( ! $match ) { + continue; + } + + if ( ! is_callable( $callback ) ) { + return new WP_Error( 'woocommerce_api_invalid_handler', __( 'The handler for the route is invalid', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $args = array_merge( $args, $this->params['GET'] ); + if ( $method & self::METHOD_POST ) { + $args = array_merge( $args, $this->params['POST'] ); + } + if ( $supported & self::ACCEPT_DATA ) { + $data = $this->handler->parse_body( $this->get_raw_data() ); + $args = array_merge( $args, array( 'data' => $data ) ); + } elseif ( $supported & self::ACCEPT_RAW_DATA ) { + $data = $this->get_raw_data(); + $args = array_merge( $args, array( 'data' => $data ) ); + } + + $args['_method'] = $method; + $args['_route'] = $route; + $args['_path'] = $this->path; + $args['_headers'] = $this->headers; + $args['_files'] = $this->files; + + $args = apply_filters( 'woocommerce_api_dispatch_args', $args, $callback ); + + // Allow plugins to halt the request via this filter + if ( is_wp_error( $args ) ) { + return $args; + } + + $params = $this->sort_callback_params( $callback, $args ); + if ( is_wp_error( $params ) ) { + return $params; + } + + return call_user_func_array( $callback, $params ); + } + } + + return new WP_Error( 'woocommerce_api_no_route', __( 'No route was found matching the URL and request method', 'woocommerce' ), array( 'status' => 404 ) ); + } + + /** + * Sort parameters by order specified in method declaration + * + * Takes a callback and a list of available params, then filters and sorts + * by the parameters the method actually needs, using the Reflection API + * + * @since 2.1 + * + * @param callable|array $callback the endpoint callback + * @param array $provided the provided request parameters + * + * @return array|WP_Error + */ + protected function sort_callback_params( $callback, $provided ) { + if ( is_array( $callback ) ) { + $ref_func = new ReflectionMethod( $callback[0], $callback[1] ); + } else { + $ref_func = new ReflectionFunction( $callback ); + } + + $wanted = $ref_func->getParameters(); + $ordered_parameters = array(); + + foreach ( $wanted as $param ) { + if ( isset( $provided[ $param->getName() ] ) ) { + // We have this parameters in the list to choose from + $ordered_parameters[] = is_array( $provided[ $param->getName() ] ) ? array_map( 'urldecode', $provided[ $param->getName() ] ) : urldecode( $provided[ $param->getName() ] ); + } elseif ( $param->isDefaultValueAvailable() ) { + // We don't have this parameter, but it's optional + $ordered_parameters[] = $param->getDefaultValue(); + } else { + // We don't have this parameter and it wasn't optional, abort! + return new WP_Error( 'woocommerce_api_missing_callback_param', sprintf( __( 'Missing parameter %s', 'woocommerce' ), $param->getName() ), array( 'status' => 400 ) ); + } + } + return $ordered_parameters; + } + + /** + * Get the site index. + * + * This endpoint describes the capabilities of the site. + * + * @since 2.1 + * @return array Index entity + */ + public function get_index() { + + // General site data + $available = array( + 'store' => array( + 'name' => get_option( 'blogname' ), + 'description' => get_option( 'blogdescription' ), + 'URL' => get_option( 'siteurl' ), + 'wc_version' => WC()->version, + 'routes' => array(), + 'meta' => array( + 'timezone' => wc_timezone_string(), + 'currency' => get_woocommerce_currency(), + 'currency_format' => get_woocommerce_currency_symbol(), + 'tax_included' => wc_prices_include_tax(), + 'weight_unit' => get_option( 'woocommerce_weight_unit' ), + 'dimension_unit' => get_option( 'woocommerce_dimension_unit' ), + 'ssl_enabled' => ( 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) ), + 'permalinks_enabled' => ( '' !== get_option( 'permalink_structure' ) ), + 'links' => array( + 'help' => 'https://woocommerce.github.io/woocommerce/rest-api/', + ), + ), + ), + ); + + // Find the available routes + foreach ( $this->get_routes() as $route => $callbacks ) { + $data = array(); + + $route = preg_replace( '#\(\?P(<\w+?>).*?\)#', '$1', $route ); + $methods = array(); + foreach ( self::$method_map as $name => $bitmask ) { + foreach ( $callbacks as $callback ) { + // Skip to the next route if any callback is hidden + if ( $callback[1] & self::HIDDEN_ENDPOINT ) { + continue 3; + } + + if ( $callback[1] & $bitmask ) { + $data['supports'][] = $name; + } + + if ( $callback[1] & self::ACCEPT_DATA ) { + $data['accepts_data'] = true; + } + + // For non-variable routes, generate links + if ( strpos( $route, '<' ) === false ) { + $data['meta'] = array( + 'self' => get_woocommerce_api_url( $route ), + ); + } + } + } + $available['store']['routes'][ $route ] = apply_filters( 'woocommerce_api_endpoints_description', $data ); + } + return apply_filters( 'woocommerce_api_index', $available ); + } + + /** + * Send a HTTP status code + * + * @since 2.1 + * @param int $code HTTP status + */ + public function send_status( $code ) { + status_header( $code ); + } + + /** + * Send a HTTP header + * + * @since 2.1 + * @param string $key Header key + * @param string $value Header value + * @param boolean $replace Should we replace the existing header? + */ + public function header( $key, $value, $replace = true ) { + header( sprintf( '%s: %s', $key, $value ), $replace ); + } + + /** + * Send a Link header + * + * @internal The $rel parameter is first, as this looks nicer when sending multiple + * + * @link http://tools.ietf.org/html/rfc5988 + * @link http://www.iana.org/assignments/link-relations/link-relations.xml + * + * @since 2.1 + * @param string $rel Link relation. Either a registered type, or an absolute URL + * @param string $link Target IRI for the link + * @param array $other Other parameters to send, as an associative array + */ + public function link_header( $rel, $link, $other = array() ) { + + $header = sprintf( '<%s>; rel="%s"', $link, esc_attr( $rel ) ); + + foreach ( $other as $key => $value ) { + + if ( 'title' == $key ) { + + $value = '"' . $value . '"'; + } + + $header .= '; ' . $key . '=' . $value; + } + + $this->header( 'Link', $header, false ); + } + + /** + * Send pagination headers for resources + * + * @since 2.1 + * @param WP_Query|WP_User_Query $query + */ + public function add_pagination_headers( $query ) { + + // WP_User_Query + if ( is_a( $query, 'WP_User_Query' ) ) { + + $page = $query->page; + $single = count( $query->get_results() ) == 1; + $total = $query->get_total(); + $total_pages = $query->total_pages; + + // WP_Query + } else { + + $page = $query->get( 'paged' ); + $single = $query->is_single(); + $total = $query->found_posts; + $total_pages = $query->max_num_pages; + } + + if ( ! $page ) { + $page = 1; + } + + $next_page = absint( $page ) + 1; + + if ( ! $single ) { + + // first/prev + if ( $page > 1 ) { + $this->link_header( 'first', $this->get_paginated_url( 1 ) ); + $this->link_header( 'prev', $this->get_paginated_url( $page -1 ) ); + } + + // next + if ( $next_page <= $total_pages ) { + $this->link_header( 'next', $this->get_paginated_url( $next_page ) ); + } + + // last + if ( $page != $total_pages ) { + $this->link_header( 'last', $this->get_paginated_url( $total_pages ) ); + } + } + + $this->header( 'X-WC-Total', $total ); + $this->header( 'X-WC-TotalPages', $total_pages ); + + do_action( 'woocommerce_api_pagination_headers', $this, $query ); + } + + /** + * Returns the request URL with the page query parameter set to the specified page + * + * @since 2.1 + * @param int $page + * @return string + */ + private function get_paginated_url( $page ) { + + // remove existing page query param + $request = remove_query_arg( 'page' ); + + // add provided page query param + $request = urldecode( add_query_arg( 'page', $page, $request ) ); + + // get the home host + $host = parse_url( get_home_url(), PHP_URL_HOST ); + + return set_url_scheme( "http://{$host}{$request}" ); + } + + /** + * Retrieve the raw request entity (body) + * + * @since 2.1 + * @return string + */ + public function get_raw_data() { + // @codingStandardsIgnoreStart + // $HTTP_RAW_POST_DATA is deprecated on PHP 5.6. + if ( function_exists( 'phpversion' ) && version_compare( phpversion(), '5.6', '>=' ) ) { + return file_get_contents( 'php://input' ); + } + + global $HTTP_RAW_POST_DATA; + + // A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default, + // but we can do it ourself. + if ( ! isset( $HTTP_RAW_POST_DATA ) ) { + $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); + } + + return $HTTP_RAW_POST_DATA; + // @codingStandardsIgnoreEnd + } + + /** + * Parse an RFC3339 datetime into a MySQl datetime + * + * Invalid dates default to unix epoch + * + * @since 2.1 + * @param string $datetime RFC3339 datetime + * @return string MySQl datetime (YYYY-MM-DD HH:MM:SS) + */ + public function parse_datetime( $datetime ) { + + // Strip millisecond precision (a full stop followed by one or more digits) + if ( strpos( $datetime, '.' ) !== false ) { + $datetime = preg_replace( '/\.\d+/', '', $datetime ); + } + + // default timezone to UTC + $datetime = preg_replace( '/[+-]\d+:+\d+$/', '+00:00', $datetime ); + + try { + + $datetime = new DateTime( $datetime, new DateTimeZone( 'UTC' ) ); + + } catch ( Exception $e ) { + + $datetime = new DateTime( '@0' ); + + } + + return $datetime->format( 'Y-m-d H:i:s' ); + } + + /** + * Format a unix timestamp or MySQL datetime into an RFC3339 datetime + * + * @since 2.1 + * @param int|string $timestamp unix timestamp or MySQL datetime + * @param bool $convert_to_utc + * @param bool $convert_to_gmt Use GMT timezone. + * @return string RFC3339 datetime + */ + public function format_datetime( $timestamp, $convert_to_utc = false, $convert_to_gmt = false ) { + if ( $convert_to_gmt ) { + if ( is_numeric( $timestamp ) ) { + $timestamp = date( 'Y-m-d H:i:s', $timestamp ); + } + + $timestamp = get_gmt_from_date( $timestamp ); + } + + if ( $convert_to_utc ) { + $timezone = new DateTimeZone( wc_timezone_string() ); + } else { + $timezone = new DateTimeZone( 'UTC' ); + } + + try { + + if ( is_numeric( $timestamp ) ) { + $date = new DateTime( "@{$timestamp}" ); + } else { + $date = new DateTime( $timestamp, $timezone ); + } + + // convert to UTC by adjusting the time based on the offset of the site's timezone + if ( $convert_to_utc ) { + $date->modify( -1 * $date->getOffset() . ' seconds' ); + } + } catch ( Exception $e ) { + + $date = new DateTime( '@0' ); + } + + return $date->format( 'Y-m-d\TH:i:s\Z' ); + } + + /** + * Extract headers from a PHP-style $_SERVER array + * + * @since 2.1 + * @param array $server Associative array similar to $_SERVER + * @return array Headers extracted from the input + */ + public function get_headers( $server ) { + $headers = array(); + // CONTENT_* headers are not prefixed with HTTP_ + $additional = array( 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true ); + + foreach ( $server as $key => $value ) { + if ( strpos( $key, 'HTTP_' ) === 0 ) { + $headers[ substr( $key, 5 ) ] = $value; + } elseif ( isset( $additional[ $key ] ) ) { + $headers[ $key ] = $value; + } + } + + return $headers; + } + + /** + * Check if the current request accepts a JSON response by checking the endpoint suffix (.json) or + * the HTTP ACCEPT header + * + * @since 2.1 + * @return bool + */ + private function is_json_request() { + + // check path + if ( false !== stripos( $this->path, '.json' ) ) { + return true; + } + + // check ACCEPT header, only 'application/json' is acceptable, see RFC 4627 + if ( isset( $this->headers['ACCEPT'] ) && 'application/json' == $this->headers['ACCEPT'] ) { + return true; + } + + return false; + } + + /** + * Check if the current request accepts an XML response by checking the endpoint suffix (.xml) or + * the HTTP ACCEPT header + * + * @since 2.1 + * @return bool + */ + private function is_xml_request() { + + // check path + if ( false !== stripos( $this->path, '.xml' ) ) { + return true; + } + + // check headers, 'application/xml' or 'text/xml' are acceptable, see RFC 2376 + if ( isset( $this->headers['ACCEPT'] ) && ( 'application/xml' == $this->headers['ACCEPT'] || 'text/xml' == $this->headers['ACCEPT'] ) ) { + return true; + } + + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-xml-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-xml-handler.php new file mode 100644 index 0000000..7e8cc94 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-xml-handler.php @@ -0,0 +1,308 @@ +xml = new XMLWriter(); + + $this->xml->openMemory(); + + $this->xml->setIndent( true ); + + $this->xml->startDocument( '1.0', 'UTF-8' ); + + $root_element = key( $data ); + + $data = $data[ $root_element ]; + + switch ( $root_element ) { + + case 'orders': + $data = array( 'order' => $data ); + break; + + case 'order_notes': + $data = array( 'order_note' => $data ); + break; + + case 'customers': + $data = array( 'customer' => $data ); + break; + + case 'coupons': + $data = array( 'coupon' => $data ); + break; + + case 'products': + $data = array( 'product' => $data ); + break; + + case 'product_reviews': + $data = array( 'product_review' => $data ); + break; + + default: + $data = apply_filters( 'woocommerce_api_xml_data', $data, $root_element ); + break; + } + + // generate xml starting with the root element and recursively generating child elements + $this->array_to_xml( $root_element, $data ); + + $this->xml->endDocument(); + + return $this->xml->outputMemory(); + } + + /** + * Convert array into XML by recursively generating child elements + * + * @since 2.1 + * @param string|array $element_key - name for element, e.g. + * @param string|array $element_value - value for element, e.g. 1234 + * @return string - generated XML + */ + private function array_to_xml( $element_key, $element_value = array() ) { + + if ( is_array( $element_value ) ) { + + // handle attributes + if ( '@attributes' === $element_key ) { + foreach ( $element_value as $attribute_key => $attribute_value ) { + + $this->xml->startAttribute( $attribute_key ); + $this->xml->text( $attribute_value ); + $this->xml->endAttribute(); + } + return; + } + + // handle multi-elements (e.g. multiple elements) + if ( is_numeric( key( $element_value ) ) ) { + + // recursively generate child elements + foreach ( $element_value as $child_element_key => $child_element_value ) { + + $this->xml->startElement( $element_key ); + + foreach ( $child_element_value as $sibling_element_key => $sibling_element_value ) { + $this->array_to_xml( $sibling_element_key, $sibling_element_value ); + } + + $this->xml->endElement(); + } + } else { + + // start root element + $this->xml->startElement( $element_key ); + + // recursively generate child elements + foreach ( $element_value as $child_element_key => $child_element_value ) { + $this->array_to_xml( $child_element_key, $child_element_value ); + } + + // end root element + $this->xml->endElement(); + } + } else { + + // handle single elements + if ( '@value' == $element_key ) { + + $this->xml->text( $element_value ); + + } else { + + // wrap element in CDATA tags if it contains illegal characters + if ( false !== strpos( $element_value, '<' ) || false !== strpos( $element_value, '>' ) ) { + + $this->xml->startElement( $element_key ); + $this->xml->writeCdata( $element_value ); + $this->xml->endElement(); + + } else { + + $this->xml->writeElement( $element_key, $element_value ); + } + } + + return; + } + } + + /** + * Adjust the sales report array format to change totals keyed with the sales date to become an + * attribute for the totals element instead + * + * @since 2.1 + * @param array $data + * @return array + */ + public function format_sales_report_data( $data ) { + + if ( ! empty( $data['totals'] ) ) { + + foreach ( $data['totals'] as $date => $totals ) { + + unset( $data['totals'][ $date ] ); + + $data['totals'][] = array_merge( array( '@attributes' => array( 'date' => $date ) ), $totals ); + } + } + + return $data; + } + + /** + * Adjust the product data to handle options for attributes without a named child element and other + * fields that have no named child elements (e.g. categories = array( 'cat1', 'cat2' ) ) + * + * Note that the parent product data for variations is also adjusted in the same manner as needed + * + * @since 2.1 + * @param array $data + * @return array + */ + public function format_product_data( $data ) { + + // handle attribute values + if ( ! empty( $data['attributes'] ) ) { + + foreach ( $data['attributes'] as $attribute_key => $attribute ) { + + if ( ! empty( $attribute['options'] ) && is_array( $attribute['options'] ) ) { + + foreach ( $attribute['options'] as $option_key => $option ) { + + unset( $data['attributes'][ $attribute_key ]['options'][ $option_key ] ); + + $data['attributes'][ $attribute_key ]['options']['option'][] = array( $option ); + } + } + } + } + + // simple arrays are fine for JSON, but XML requires a child element name, so this adjusts the data + // array to define a child element name for each field + $fields_to_fix = array( + 'related_ids' => 'related_id', + 'upsell_ids' => 'upsell_id', + 'cross_sell_ids' => 'cross_sell_id', + 'categories' => 'category', + 'tags' => 'tag', + ); + + foreach ( $fields_to_fix as $parent_field_name => $child_field_name ) { + + if ( ! empty( $data[ $parent_field_name ] ) ) { + + foreach ( $data[ $parent_field_name ] as $field_key => $field ) { + + unset( $data[ $parent_field_name ][ $field_key ] ); + + $data[ $parent_field_name ][ $child_field_name ][] = array( $field ); + } + } + } + + // handle adjusting the parent product for variations + if ( ! empty( $data['parent'] ) ) { + + // attributes + if ( ! empty( $data['parent']['attributes'] ) ) { + + foreach ( $data['parent']['attributes'] as $attribute_key => $attribute ) { + + if ( ! empty( $attribute['options'] ) && is_array( $attribute['options'] ) ) { + + foreach ( $attribute['options'] as $option_key => $option ) { + + unset( $data['parent']['attributes'][ $attribute_key ]['options'][ $option_key ] ); + + $data['parent']['attributes'][ $attribute_key ]['options']['option'][] = array( $option ); + } + } + } + } + + // fields + foreach ( $fields_to_fix as $parent_field_name => $child_field_name ) { + + if ( ! empty( $data['parent'][ $parent_field_name ] ) ) { + + foreach ( $data['parent'][ $parent_field_name ] as $field_key => $field ) { + + unset( $data['parent'][ $parent_field_name ][ $field_key ] ); + + $data['parent'][ $parent_field_name ][ $child_field_name ][] = array( $field ); + } + } + } + } + + return $data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/interface-wc-api-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/interface-wc-api-handler.php new file mode 100644 index 0000000..4e252f6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v1/interface-wc-api-handler.php @@ -0,0 +1,48 @@ +api->server->path ) { + return new WP_User( 0 ); + } + + try { + + if ( is_ssl() ) { + $keys = $this->perform_ssl_authentication(); + } else { + $keys = $this->perform_oauth_authentication(); + } + + // Check API key-specific permission + $this->check_api_key_permissions( $keys['permissions'] ); + + $user = $this->get_user_by_id( $keys['user_id'] ); + + $this->update_api_key_last_access( $keys['key_id'] ); + + } catch ( Exception $e ) { + $user = new WP_Error( 'woocommerce_api_authentication_error', $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + return $user; + } + + /** + * SSL-encrypted requests are not subject to sniffing or man-in-the-middle + * attacks, so the request can be authenticated by simply looking up the user + * associated with the given consumer key and confirming the consumer secret + * provided is valid + * + * @since 2.1 + * @return array + * @throws Exception + */ + private function perform_ssl_authentication() { + + $params = WC()->api->server->params['GET']; + + // Get consumer key + if ( ! empty( $_SERVER['PHP_AUTH_USER'] ) ) { + + // Should be in HTTP Auth header by default + $consumer_key = $_SERVER['PHP_AUTH_USER']; + + } elseif ( ! empty( $params['consumer_key'] ) ) { + + // Allow a query string parameter as a fallback + $consumer_key = $params['consumer_key']; + + } else { + + throw new Exception( __( 'Consumer key is missing.', 'woocommerce' ), 404 ); + } + + // Get consumer secret + if ( ! empty( $_SERVER['PHP_AUTH_PW'] ) ) { + + // Should be in HTTP Auth header by default + $consumer_secret = $_SERVER['PHP_AUTH_PW']; + + } elseif ( ! empty( $params['consumer_secret'] ) ) { + + // Allow a query string parameter as a fallback + $consumer_secret = $params['consumer_secret']; + + } else { + + throw new Exception( __( 'Consumer secret is missing.', 'woocommerce' ), 404 ); + } + + $keys = $this->get_keys_by_consumer_key( $consumer_key ); + + if ( ! $this->is_consumer_secret_valid( $keys['consumer_secret'], $consumer_secret ) ) { + throw new Exception( __( 'Consumer secret is invalid.', 'woocommerce' ), 401 ); + } + + return $keys; + } + + /** + * Perform OAuth 1.0a "one-legged" (http://oauthbible.com/#oauth-10a-one-legged) authentication for non-SSL requests + * + * This is required so API credentials cannot be sniffed or intercepted when making API requests over plain HTTP + * + * This follows the spec for simple OAuth 1.0a authentication (RFC 5849) as closely as possible, with two exceptions: + * + * 1) There is no token associated with request/responses, only consumer keys/secrets are used + * + * 2) The OAuth parameters are included as part of the request query string instead of part of the Authorization header, + * This is because there is no cross-OS function within PHP to get the raw Authorization header + * + * @link http://tools.ietf.org/html/rfc5849 for the full spec + * @since 2.1 + * @return array + * @throws Exception + */ + private function perform_oauth_authentication() { + + $params = WC()->api->server->params['GET']; + + $param_names = array( 'oauth_consumer_key', 'oauth_timestamp', 'oauth_nonce', 'oauth_signature', 'oauth_signature_method' ); + + // Check for required OAuth parameters + foreach ( $param_names as $param_name ) { + + if ( empty( $params[ $param_name ] ) ) { + throw new Exception( sprintf( __( '%s parameter is missing', 'woocommerce' ), $param_name ), 404 ); + } + } + + // Fetch WP user by consumer key + $keys = $this->get_keys_by_consumer_key( $params['oauth_consumer_key'] ); + + // Perform OAuth validation + $this->check_oauth_signature( $keys, $params ); + $this->check_oauth_timestamp_and_nonce( $keys, $params['oauth_timestamp'], $params['oauth_nonce'] ); + + // Authentication successful, return user + return $keys; + } + + /** + * Return the keys for the given consumer key + * + * @since 2.4.0 + * @param string $consumer_key + * @return array + * @throws Exception + */ + private function get_keys_by_consumer_key( $consumer_key ) { + global $wpdb; + + $consumer_key = wc_api_hash( sanitize_text_field( $consumer_key ) ); + + $keys = $wpdb->get_row( $wpdb->prepare( " + SELECT key_id, user_id, permissions, consumer_key, consumer_secret, nonces + FROM {$wpdb->prefix}woocommerce_api_keys + WHERE consumer_key = '%s' + ", $consumer_key ), ARRAY_A ); + + if ( empty( $keys ) ) { + throw new Exception( __( 'Consumer key is invalid.', 'woocommerce' ), 401 ); + } + + return $keys; + } + + /** + * Get user by ID + * + * @since 2.4.0 + * @param int $user_id + * @return WP_User + * @throws Exception + */ + private function get_user_by_id( $user_id ) { + $user = get_user_by( 'id', $user_id ); + + if ( ! $user ) { + throw new Exception( __( 'API user is invalid', 'woocommerce' ), 401 ); + } + + return $user; + } + + /** + * Check if the consumer secret provided for the given user is valid + * + * @since 2.1 + * @param string $keys_consumer_secret + * @param string $consumer_secret + * @return bool + */ + private function is_consumer_secret_valid( $keys_consumer_secret, $consumer_secret ) { + return hash_equals( $keys_consumer_secret, $consumer_secret ); + } + + /** + * Verify that the consumer-provided request signature matches our generated signature, this ensures the consumer + * has a valid key/secret + * + * @param array $keys + * @param array $params the request parameters + * @throws Exception + */ + private function check_oauth_signature( $keys, $params ) { + + $http_method = strtoupper( WC()->api->server->method ); + + $base_request_uri = rawurlencode( untrailingslashit( get_woocommerce_api_url( '' ) ) . WC()->api->server->path ); + + // Get the signature provided by the consumer and remove it from the parameters prior to checking the signature + $consumer_signature = rawurldecode( str_replace( ' ', '+', $params['oauth_signature'] ) ); + unset( $params['oauth_signature'] ); + + // Remove filters and convert them from array to strings to void normalize issues + if ( isset( $params['filter'] ) ) { + $filters = $params['filter']; + unset( $params['filter'] ); + foreach ( $filters as $filter => $filter_value ) { + $params[ 'filter[' . $filter . ']' ] = $filter_value; + } + } + + // Normalize parameter key/values + $params = $this->normalize_parameters( $params ); + + // Sort parameters + if ( ! uksort( $params, 'strcmp' ) ) { + throw new Exception( __( 'Invalid signature - failed to sort parameters.', 'woocommerce' ), 401 ); + } + + // Form query string + $query_params = array(); + foreach ( $params as $param_key => $param_value ) { + + $query_params[] = $param_key . '%3D' . $param_value; // join with equals sign + } + $query_string = implode( '%26', $query_params ); // join with ampersand + + $string_to_sign = $http_method . '&' . $base_request_uri . '&' . $query_string; + + if ( 'HMAC-SHA1' !== $params['oauth_signature_method'] && 'HMAC-SHA256' !== $params['oauth_signature_method'] ) { + throw new Exception( __( 'Invalid signature - signature method is invalid.', 'woocommerce' ), 401 ); + } + + $hash_algorithm = strtolower( str_replace( 'HMAC-', '', $params['oauth_signature_method'] ) ); + + $signature = base64_encode( hash_hmac( $hash_algorithm, $string_to_sign, $keys['consumer_secret'], true ) ); + + if ( ! hash_equals( $signature, $consumer_signature ) ) { + throw new Exception( __( 'Invalid signature - provided signature does not match.', 'woocommerce' ), 401 ); + } + } + + /** + * Normalize each parameter by assuming each parameter may have already been + * encoded, so attempt to decode, and then re-encode according to RFC 3986 + * + * Note both the key and value is normalized so a filter param like: + * + * 'filter[period]' => 'week' + * + * is encoded to: + * + * 'filter%5Bperiod%5D' => 'week' + * + * This conforms to the OAuth 1.0a spec which indicates the entire query string + * should be URL encoded + * + * @since 2.1 + * @see rawurlencode() + * @param array $parameters un-normalized parameters + * @return array normalized parameters + */ + private function normalize_parameters( $parameters ) { + + $normalized_parameters = array(); + + foreach ( $parameters as $key => $value ) { + + // Percent symbols (%) must be double-encoded + $key = str_replace( '%', '%25', rawurlencode( rawurldecode( $key ) ) ); + $value = str_replace( '%', '%25', rawurlencode( rawurldecode( $value ) ) ); + + $normalized_parameters[ $key ] = $value; + } + + return $normalized_parameters; + } + + /** + * Verify that the timestamp and nonce provided with the request are valid. This prevents replay attacks where + * an attacker could attempt to re-send an intercepted request at a later time. + * + * - A timestamp is valid if it is within 15 minutes of now + * - A nonce is valid if it has not been used within the last 15 minutes + * + * @param array $keys + * @param int $timestamp the unix timestamp for when the request was made + * @param string $nonce a unique (for the given user) 32 alphanumeric string, consumer-generated + * @throws Exception + */ + private function check_oauth_timestamp_and_nonce( $keys, $timestamp, $nonce ) { + global $wpdb; + + $valid_window = 15 * 60; // 15 minute window + + if ( ( $timestamp < time() - $valid_window ) || ( $timestamp > time() + $valid_window ) ) { + throw new Exception( __( 'Invalid timestamp.', 'woocommerce' ), 401 ); + } + + $used_nonces = maybe_unserialize( $keys['nonces'] ); + + if ( empty( $used_nonces ) ) { + $used_nonces = array(); + } + + if ( in_array( $nonce, $used_nonces ) ) { + throw new Exception( __( 'Invalid nonce - nonce has already been used.', 'woocommerce' ), 401 ); + } + + $used_nonces[ $timestamp ] = $nonce; + + // Remove expired nonces + foreach ( $used_nonces as $nonce_timestamp => $nonce ) { + if ( $nonce_timestamp < ( time() - $valid_window ) ) { + unset( $used_nonces[ $nonce_timestamp ] ); + } + } + + $used_nonces = maybe_serialize( $used_nonces ); + + $wpdb->update( + $wpdb->prefix . 'woocommerce_api_keys', + array( 'nonces' => $used_nonces ), + array( 'key_id' => $keys['key_id'] ), + array( '%s' ), + array( '%d' ) + ); + } + + /** + * Check that the API keys provided have the proper key-specific permissions to either read or write API resources + * + * @param string $key_permissions + * @throws Exception if the permission check fails + */ + public function check_api_key_permissions( $key_permissions ) { + switch ( WC()->api->server->method ) { + + case 'HEAD': + case 'GET': + if ( 'read' !== $key_permissions && 'read_write' !== $key_permissions ) { + throw new Exception( __( 'The API key provided does not have read permissions.', 'woocommerce' ), 401 ); + } + break; + + case 'POST': + case 'PUT': + case 'PATCH': + case 'DELETE': + if ( 'write' !== $key_permissions && 'read_write' !== $key_permissions ) { + throw new Exception( __( 'The API key provided does not have write permissions.', 'woocommerce' ), 401 ); + } + break; + } + } + + /** + * Updated API Key last access datetime + * + * @since 2.4.0 + * + * @param int $key_id + */ + private function update_api_key_last_access( $key_id ) { + global $wpdb; + + $wpdb->update( + $wpdb->prefix . 'woocommerce_api_keys', + array( 'last_access' => current_time( 'mysql' ) ), + array( 'key_id' => $key_id ), + array( '%s' ), + array( '%d' ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-coupons.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-coupons.php new file mode 100644 index 0000000..71165dc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-coupons.php @@ -0,0 +1,575 @@ + + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET/POST /coupons + $routes[ $this->base ] = array( + array( array( $this, 'get_coupons' ), WC_API_Server::READABLE ), + array( array( $this, 'create_coupon' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /coupons/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_coupons_count' ), WC_API_Server::READABLE ), + ); + + # GET/PUT/DELETE /coupons/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_coupon' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_coupon' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ), + array( array( $this, 'delete_coupon' ), WC_API_SERVER::DELETABLE ), + ); + + # GET /coupons/code/, note that coupon codes can contain spaces, dashes and underscores + $routes[ $this->base . '/code/(?P\w[\w\s\-]*)' ] = array( + array( array( $this, 'get_coupon_by_code' ), WC_API_Server::READABLE ), + ); + + # POST|PUT /coupons/bulk + $routes[ $this->base . '/bulk' ] = array( + array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + return $routes; + } + + /** + * Get all coupons + * + * @since 2.1 + * @param string $fields + * @param array $filter + * @param int $page + * @return array + */ + public function get_coupons( $fields = null, $filter = array(), $page = 1 ) { + + $filter['page'] = $page; + + $query = $this->query_coupons( $filter ); + + $coupons = array(); + + foreach ( $query->posts as $coupon_id ) { + + if ( ! $this->is_readable( $coupon_id ) ) { + continue; + } + + $coupons[] = current( $this->get_coupon( $coupon_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'coupons' => $coupons ); + } + + /** + * Get the coupon for the given ID + * + * @since 2.1 + * @param int $id the coupon ID + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_coupon( $id, $fields = null ) { + try { + + $id = $this->validate_request( $id, 'shop_coupon', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $coupon = new WC_Coupon( $id ); + + if ( 0 === $coupon->get_id() ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_id', __( 'Invalid coupon ID', 'woocommerce' ), 404 ); + } + + $coupon_data = array( + 'id' => $coupon->get_id(), + 'code' => $coupon->get_code(), + 'type' => $coupon->get_discount_type(), + 'created_at' => $this->server->format_datetime( $coupon->get_date_created() ? $coupon->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. + 'updated_at' => $this->server->format_datetime( $coupon->get_date_modified() ? $coupon->get_date_modified()->getTimestamp() : 0 ), // API gives UTC times. + 'amount' => wc_format_decimal( $coupon->get_amount(), 2 ), + 'individual_use' => $coupon->get_individual_use(), + 'product_ids' => array_map( 'absint', (array) $coupon->get_product_ids() ), + 'exclude_product_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_ids() ), + 'usage_limit' => $coupon->get_usage_limit() ? $coupon->get_usage_limit() : null, + 'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null, + 'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(), + 'usage_count' => (int) $coupon->get_usage_count(), + 'expiry_date' => $coupon->get_date_expires() ? $this->server->format_datetime( $coupon->get_date_expires()->getTimestamp() ) : null, // API gives UTC times. + 'enable_free_shipping' => $coupon->get_free_shipping(), + 'product_category_ids' => array_map( 'absint', (array) $coupon->get_product_categories() ), + 'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ), + 'exclude_sale_items' => $coupon->get_exclude_sale_items(), + 'minimum_amount' => wc_format_decimal( $coupon->get_minimum_amount(), 2 ), + 'maximum_amount' => wc_format_decimal( $coupon->get_maximum_amount(), 2 ), + 'customer_emails' => $coupon->get_email_restrictions(), + 'description' => $coupon->get_description(), + ); + + return array( 'coupon' => apply_filters( 'woocommerce_api_coupon_response', $coupon_data, $coupon, $fields, $this->server ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the total number of coupons + * + * @since 2.1 + * + * @param array $filter + * + * @return array|WP_Error + */ + public function get_coupons_count( $filter = array() ) { + try { + if ( ! current_user_can( 'read_private_shop_coupons' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_coupons_count', __( 'You do not have permission to read the coupons count', 'woocommerce' ), 401 ); + } + + $query = $this->query_coupons( $filter ); + + return array( 'count' => (int) $query->found_posts ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the coupon for the given code + * + * @since 2.1 + * @param string $code the coupon code + * @param string $fields fields to include in response + * @return int|WP_Error + */ + public function get_coupon_by_code( $code, $fields = null ) { + global $wpdb; + + try { + $id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1;", $code ) ); + + if ( is_null( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_code', __( 'Invalid coupon code', 'woocommerce' ), 404 ); + } + + return $this->get_coupon( $id, $fields ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a coupon + * + * @since 2.2 + * + * @param array $data + * + * @return array|WP_Error + */ + public function create_coupon( $data ) { + global $wpdb; + + try { + if ( ! isset( $data['coupon'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_coupon_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'coupon' ), 400 ); + } + + $data = $data['coupon']; + + // Check user permission + if ( ! current_user_can( 'publish_shop_coupons' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_coupon', __( 'You do not have permission to create coupons', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_coupon_data', $data, $this ); + + // Check if coupon code is specified + if ( ! isset( $data['code'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_coupon_code', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'code' ), 400 ); + } + + $coupon_code = wc_format_coupon_code( $data['code'] ); + $id_from_code = wc_get_coupon_id_by_code( $coupon_code ); + + if ( $id_from_code ) { + throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 ); + } + + $defaults = array( + 'type' => 'fixed_cart', + 'amount' => 0, + 'individual_use' => false, + 'product_ids' => array(), + 'exclude_product_ids' => array(), + 'usage_limit' => '', + 'usage_limit_per_user' => '', + 'limit_usage_to_x_items' => '', + 'usage_count' => '', + 'expiry_date' => '', + 'enable_free_shipping' => false, + 'product_category_ids' => array(), + 'exclude_product_category_ids' => array(), + 'exclude_sale_items' => false, + 'minimum_amount' => '', + 'maximum_amount' => '', + 'customer_emails' => array(), + 'description' => '', + ); + + $coupon_data = wp_parse_args( $data, $defaults ); + + // Validate coupon types + if ( ! in_array( wc_clean( $coupon_data['type'] ), array_keys( wc_get_coupon_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ), 400 ); + } + + $new_coupon = array( + 'post_title' => $coupon_code, + 'post_content' => '', + 'post_status' => 'publish', + 'post_author' => get_current_user_id(), + 'post_type' => 'shop_coupon', + 'post_excerpt' => $coupon_data['description'], + ); + + $id = wp_insert_post( $new_coupon, true ); + + if ( is_wp_error( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_coupon', $id->get_error_message(), 400 ); + } + + // Set coupon meta + update_post_meta( $id, 'discount_type', $coupon_data['type'] ); + update_post_meta( $id, 'coupon_amount', wc_format_decimal( $coupon_data['amount'] ) ); + update_post_meta( $id, 'individual_use', ( true === $coupon_data['individual_use'] ) ? 'yes' : 'no' ); + update_post_meta( $id, 'product_ids', implode( ',', array_filter( array_map( 'intval', $coupon_data['product_ids'] ) ) ) ); + update_post_meta( $id, 'exclude_product_ids', implode( ',', array_filter( array_map( 'intval', $coupon_data['exclude_product_ids'] ) ) ) ); + update_post_meta( $id, 'usage_limit', absint( $coupon_data['usage_limit'] ) ); + update_post_meta( $id, 'usage_limit_per_user', absint( $coupon_data['usage_limit_per_user'] ) ); + update_post_meta( $id, 'limit_usage_to_x_items', absint( $coupon_data['limit_usage_to_x_items'] ) ); + update_post_meta( $id, 'usage_count', absint( $coupon_data['usage_count'] ) ); + update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $coupon_data['expiry_date'] ) ) ); + update_post_meta( $id, 'date_expires', $this->get_coupon_expiry_date( wc_clean( $coupon_data['expiry_date'] ), true ) ); + update_post_meta( $id, 'free_shipping', ( true === $coupon_data['enable_free_shipping'] ) ? 'yes' : 'no' ); + update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $coupon_data['product_category_ids'] ) ) ); + update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $coupon_data['exclude_product_category_ids'] ) ) ); + update_post_meta( $id, 'exclude_sale_items', ( true === $coupon_data['exclude_sale_items'] ) ? 'yes' : 'no' ); + update_post_meta( $id, 'minimum_amount', wc_format_decimal( $coupon_data['minimum_amount'] ) ); + update_post_meta( $id, 'maximum_amount', wc_format_decimal( $coupon_data['maximum_amount'] ) ); + update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $coupon_data['customer_emails'] ) ) ); + + do_action( 'woocommerce_api_create_coupon', $id, $data ); + do_action( 'woocommerce_new_coupon', $id ); + + $this->server->send_status( 201 ); + + return $this->get_coupon( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a coupon + * + * @since 2.2 + * + * @param int $id the coupon ID + * @param array $data + * + * @return array|WP_Error + */ + public function edit_coupon( $id, $data ) { + + try { + if ( ! isset( $data['coupon'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_coupon_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'coupon' ), 400 ); + } + + $data = $data['coupon']; + + $id = $this->validate_request( $id, 'shop_coupon', 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $data = apply_filters( 'woocommerce_api_edit_coupon_data', $data, $id, $this ); + + if ( isset( $data['code'] ) ) { + global $wpdb; + + $coupon_code = wc_format_coupon_code( $data['code'] ); + $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); + + if ( $id_from_code ) { + throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 ); + } + + $updated = wp_update_post( array( 'ID' => intval( $id ), 'post_title' => $coupon_code ) ); + + if ( 0 === $updated ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 ); + } + } + + if ( isset( $data['description'] ) ) { + $updated = wp_update_post( array( 'ID' => intval( $id ), 'post_excerpt' => $data['description'] ) ); + + if ( 0 === $updated ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 ); + } + } + + if ( isset( $data['type'] ) ) { + // Validate coupon types + if ( ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_coupon_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ), 400 ); + } + update_post_meta( $id, 'discount_type', $data['type'] ); + } + + if ( isset( $data['amount'] ) ) { + update_post_meta( $id, 'coupon_amount', wc_format_decimal( $data['amount'] ) ); + } + + if ( isset( $data['individual_use'] ) ) { + update_post_meta( $id, 'individual_use', ( true === $data['individual_use'] ) ? 'yes' : 'no' ); + } + + if ( isset( $data['product_ids'] ) ) { + update_post_meta( $id, 'product_ids', implode( ',', array_filter( array_map( 'intval', $data['product_ids'] ) ) ) ); + } + + if ( isset( $data['exclude_product_ids'] ) ) { + update_post_meta( $id, 'exclude_product_ids', implode( ',', array_filter( array_map( 'intval', $data['exclude_product_ids'] ) ) ) ); + } + + if ( isset( $data['usage_limit'] ) ) { + update_post_meta( $id, 'usage_limit', absint( $data['usage_limit'] ) ); + } + + if ( isset( $data['usage_limit_per_user'] ) ) { + update_post_meta( $id, 'usage_limit_per_user', absint( $data['usage_limit_per_user'] ) ); + } + + if ( isset( $data['limit_usage_to_x_items'] ) ) { + update_post_meta( $id, 'limit_usage_to_x_items', absint( $data['limit_usage_to_x_items'] ) ); + } + + if ( isset( $data['usage_count'] ) ) { + update_post_meta( $id, 'usage_count', absint( $data['usage_count'] ) ); + } + + if ( isset( $data['expiry_date'] ) ) { + update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $data['expiry_date'] ) ) ); + update_post_meta( $id, 'date_expires', $this->get_coupon_expiry_date( wc_clean( $data['expiry_date'] ), true ) ); + } + + if ( isset( $data['enable_free_shipping'] ) ) { + update_post_meta( $id, 'free_shipping', ( true === $data['enable_free_shipping'] ) ? 'yes' : 'no' ); + } + + if ( isset( $data['product_category_ids'] ) ) { + update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $data['product_category_ids'] ) ) ); + } + + if ( isset( $data['exclude_product_category_ids'] ) ) { + update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $data['exclude_product_category_ids'] ) ) ); + } + + if ( isset( $data['exclude_sale_items'] ) ) { + update_post_meta( $id, 'exclude_sale_items', ( true === $data['exclude_sale_items'] ) ? 'yes' : 'no' ); + } + + if ( isset( $data['minimum_amount'] ) ) { + update_post_meta( $id, 'minimum_amount', wc_format_decimal( $data['minimum_amount'] ) ); + } + + if ( isset( $data['maximum_amount'] ) ) { + update_post_meta( $id, 'maximum_amount', wc_format_decimal( $data['maximum_amount'] ) ); + } + + if ( isset( $data['customer_emails'] ) ) { + update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $data['customer_emails'] ) ) ); + } + + do_action( 'woocommerce_api_edit_coupon', $id, $data ); + do_action( 'woocommerce_update_coupon', $id ); + + return $this->get_coupon( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a coupon + * + * @since 2.2 + * @param int $id the coupon ID + * @param bool $force true to permanently delete coupon, false to move to trash + * @return array|WP_Error + */ + public function delete_coupon( $id, $force = false ) { + + $id = $this->validate_request( $id, 'shop_coupon', 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + do_action( 'woocommerce_api_delete_coupon', $id, $this ); + + return $this->delete( $id, 'shop_coupon', ( 'true' === $force ) ); + } + + /** + * expiry_date format + * + * @since 2.3.0 + * @param string $expiry_date + * @param bool $as_timestamp (default: false) + * @return string|int + */ + protected function get_coupon_expiry_date( $expiry_date, $as_timestamp = false ) { + if ( '' != $expiry_date ) { + if ( $as_timestamp ) { + return strtotime( $expiry_date ); + } + + return date( 'Y-m-d', strtotime( $expiry_date ) ); + } + + return ''; + } + + /** + * Helper method to get coupon post objects + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_Query + */ + private function query_coupons( $args ) { + + // set base query arguments + $query_args = array( + 'fields' => 'ids', + 'post_type' => 'shop_coupon', + 'post_status' => 'publish', + ); + + $query_args = $this->merge_query_args( $query_args, $args ); + + return new WP_Query( $query_args ); + } + + /** + * Bulk update or insert coupons + * Accepts an array with coupons in the formats supported by + * WC_API_Coupons->create_coupon() and WC_API_Coupons->edit_coupon() + * + * @since 2.4.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function bulk( $data ) { + + try { + if ( ! isset( $data['coupons'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_coupons_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'coupons' ), 400 ); + } + + $data = $data['coupons']; + $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'coupons' ); + + // Limit bulk operation + if ( count( $data ) > $limit ) { + throw new WC_API_Exception( 'woocommerce_api_coupons_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); + } + + $coupons = array(); + + foreach ( $data as $_coupon ) { + $coupon_id = 0; + + // Try to get the coupon ID + if ( isset( $_coupon['id'] ) ) { + $coupon_id = intval( $_coupon['id'] ); + } + + // Coupon exists / edit coupon + if ( $coupon_id ) { + $edit = $this->edit_coupon( $coupon_id, array( 'coupon' => $_coupon ) ); + + if ( is_wp_error( $edit ) ) { + $coupons[] = array( + 'id' => $coupon_id, + 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ), + ); + } else { + $coupons[] = $edit['coupon']; + } + } else { + + // Coupon don't exists / create coupon + $new = $this->create_coupon( array( 'coupon' => $_coupon ) ); + + if ( is_wp_error( $new ) ) { + $coupons[] = array( + 'id' => $coupon_id, + 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ), + ); + } else { + $coupons[] = $new['coupon']; + } + } + } + + return array( 'coupons' => apply_filters( 'woocommerce_api_coupons_bulk_response', $coupons, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-customers.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-customers.php new file mode 100644 index 0000000..7598025 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-customers.php @@ -0,0 +1,837 @@ + + * GET /customers//orders + * + * @since 2.2 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET/POST /customers + $routes[ $this->base ] = array( + array( array( $this, 'get_customers' ), WC_API_SERVER::READABLE ), + array( array( $this, 'create_customer' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /customers/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_customers_count' ), WC_API_SERVER::READABLE ), + ); + + # GET/PUT/DELETE /customers/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_customer' ), WC_API_SERVER::READABLE ), + array( array( $this, 'edit_customer' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ), + array( array( $this, 'delete_customer' ), WC_API_SERVER::DELETABLE ), + ); + + # GET /customers/email/ + $routes[ $this->base . '/email/(?P.+)' ] = array( + array( array( $this, 'get_customer_by_email' ), WC_API_SERVER::READABLE ), + ); + + # GET /customers//orders + $routes[ $this->base . '/(?P\d+)/orders' ] = array( + array( array( $this, 'get_customer_orders' ), WC_API_SERVER::READABLE ), + ); + + # GET /customers//downloads + $routes[ $this->base . '/(?P\d+)/downloads' ] = array( + array( array( $this, 'get_customer_downloads' ), WC_API_SERVER::READABLE ), + ); + + # POST|PUT /customers/bulk + $routes[ $this->base . '/bulk' ] = array( + array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + return $routes; + } + + /** + * Get all customers + * + * @since 2.1 + * @param array $fields + * @param array $filter + * @param int $page + * @return array + */ + public function get_customers( $fields = null, $filter = array(), $page = 1 ) { + + $filter['page'] = $page; + + $query = $this->query_customers( $filter ); + + $customers = array(); + + foreach ( $query->get_results() as $user_id ) { + + if ( ! $this->is_readable( $user_id ) ) { + continue; + } + + $customers[] = current( $this->get_customer( $user_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'customers' => $customers ); + } + + /** + * Get the customer for the given ID + * + * @since 2.1 + * @param int $id the customer ID + * @param array $fields + * @return array|WP_Error + */ + public function get_customer( $id, $fields = null ) { + global $wpdb; + + $id = $this->validate_request( $id, 'customer', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $customer = new WC_Customer( $id ); + $last_order = $customer->get_last_order(); + $customer_data = array( + 'id' => $customer->get_id(), + 'created_at' => $this->server->format_datetime( $customer->get_date_created() ? $customer->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. + 'email' => $customer->get_email(), + 'first_name' => $customer->get_first_name(), + 'last_name' => $customer->get_last_name(), + 'username' => $customer->get_username(), + 'role' => $customer->get_role(), + 'last_order_id' => is_object( $last_order ) ? $last_order->get_id() : null, + 'last_order_date' => is_object( $last_order ) ? $this->server->format_datetime( $last_order->get_date_created() ? $last_order->get_date_created()->getTimestamp() : 0 ) : null, // API gives UTC times. + 'orders_count' => $customer->get_order_count(), + 'total_spent' => wc_format_decimal( $customer->get_total_spent(), 2 ), + 'avatar_url' => $customer->get_avatar_url(), + 'billing_address' => array( + 'first_name' => $customer->get_billing_first_name(), + 'last_name' => $customer->get_billing_last_name(), + 'company' => $customer->get_billing_company(), + 'address_1' => $customer->get_billing_address_1(), + 'address_2' => $customer->get_billing_address_2(), + 'city' => $customer->get_billing_city(), + 'state' => $customer->get_billing_state(), + 'postcode' => $customer->get_billing_postcode(), + 'country' => $customer->get_billing_country(), + 'email' => $customer->get_billing_email(), + 'phone' => $customer->get_billing_phone(), + ), + 'shipping_address' => array( + 'first_name' => $customer->get_shipping_first_name(), + 'last_name' => $customer->get_shipping_last_name(), + 'company' => $customer->get_shipping_company(), + 'address_1' => $customer->get_shipping_address_1(), + 'address_2' => $customer->get_shipping_address_2(), + 'city' => $customer->get_shipping_city(), + 'state' => $customer->get_shipping_state(), + 'postcode' => $customer->get_shipping_postcode(), + 'country' => $customer->get_shipping_country(), + ), + ); + + return array( 'customer' => apply_filters( 'woocommerce_api_customer_response', $customer_data, $customer, $fields, $this->server ) ); + } + + /** + * Get the customer for the given email + * + * @since 2.1 + * + * @param string $email the customer email + * @param array $fields + * + * @return array|WP_Error + */ + public function get_customer_by_email( $email, $fields = null ) { + try { + if ( is_email( $email ) ) { + $customer = get_user_by( 'email', $email ); + if ( ! is_object( $customer ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_email', __( 'Invalid customer email', 'woocommerce' ), 404 ); + } + } else { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_email', __( 'Invalid customer email', 'woocommerce' ), 404 ); + } + + return $this->get_customer( $customer->ID, $fields ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the total number of customers + * + * @since 2.1 + * + * @param array $filter + * + * @return array|WP_Error + */ + public function get_customers_count( $filter = array() ) { + try { + if ( ! current_user_can( 'list_users' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_customers_count', __( 'You do not have permission to read the customers count', 'woocommerce' ), 401 ); + } + + $query = $this->query_customers( $filter ); + + return array( 'count' => $query->get_total() ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get customer billing address fields. + * + * @since 2.2 + * @return array + */ + protected function get_customer_billing_address() { + $billing_address = apply_filters( 'woocommerce_api_customer_billing_address', array( + 'first_name', + 'last_name', + 'company', + 'address_1', + 'address_2', + 'city', + 'state', + 'postcode', + 'country', + 'email', + 'phone', + ) ); + + return $billing_address; + } + + /** + * Get customer shipping address fields. + * + * @since 2.2 + * @return array + */ + protected function get_customer_shipping_address() { + $shipping_address = apply_filters( 'woocommerce_api_customer_shipping_address', array( + 'first_name', + 'last_name', + 'company', + 'address_1', + 'address_2', + 'city', + 'state', + 'postcode', + 'country', + ) ); + + return $shipping_address; + } + + /** + * Add/Update customer data. + * + * @since 2.2 + * @param int $id the customer ID + * @param array $data + * @param WC_Customer $customer + */ + protected function update_customer_data( $id, $data, $customer ) { + + // Customer first name. + if ( isset( $data['first_name'] ) ) { + $customer->set_first_name( wc_clean( $data['first_name'] ) ); + } + + // Customer last name. + if ( isset( $data['last_name'] ) ) { + $customer->set_last_name( wc_clean( $data['last_name'] ) ); + } + + // Customer billing address. + if ( isset( $data['billing_address'] ) ) { + foreach ( $this->get_customer_billing_address() as $field ) { + if ( isset( $data['billing_address'][ $field ] ) ) { + if ( is_callable( array( $customer, "set_billing_{$field}" ) ) ) { + $customer->{"set_billing_{$field}"}( $data['billing_address'][ $field ] ); + } else { + $customer->update_meta_data( 'billing_' . $field, wc_clean( $data['billing_address'][ $field ] ) ); + } + } + } + } + + // Customer shipping address. + if ( isset( $data['shipping_address'] ) ) { + foreach ( $this->get_customer_shipping_address() as $field ) { + if ( isset( $data['shipping_address'][ $field ] ) ) { + if ( is_callable( array( $customer, "set_shipping_{$field}" ) ) ) { + $customer->{"set_shipping_{$field}"}( $data['shipping_address'][ $field ] ); + } else { + $customer->update_meta_data( 'shipping_' . $field, wc_clean( $data['shipping_address'][ $field ] ) ); + } + } + } + } + + do_action( 'woocommerce_api_update_customer_data', $id, $data, $customer ); + } + + /** + * Create a customer + * + * @since 2.2 + * + * @param array $data + * + * @return array|WP_Error + */ + public function create_customer( $data ) { + try { + if ( ! isset( $data['customer'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_customer_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'customer' ), 400 ); + } + + $data = $data['customer']; + + // Checks with can create new users. + if ( ! current_user_can( 'create_users' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_customer', __( 'You do not have permission to create this customer', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_customer_data', $data, $this ); + + // Checks with the email is missing. + if ( ! isset( $data['email'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_customer_email', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'email' ), 400 ); + } + + // Create customer. + $customer = new WC_Customer; + $customer->set_username( ! empty( $data['username'] ) ? $data['username'] : '' ); + $customer->set_password( ! empty( $data['password'] ) ? $data['password'] : '' ); + $customer->set_email( $data['email'] ); + $customer->save(); + + if ( ! $customer->get_id() ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_customer', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); + } + + // Added customer data. + $this->update_customer_data( $customer->get_id(), $data, $customer ); + $customer->save(); + + do_action( 'woocommerce_api_create_customer', $customer->get_id(), $data ); + + $this->server->send_status( 201 ); + + return $this->get_customer( $customer->get_id() ); + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a customer + * + * @since 2.2 + * + * @param int $id the customer ID + * @param array $data + * + * @return array|WP_Error + */ + public function edit_customer( $id, $data ) { + try { + if ( ! isset( $data['customer'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_customer_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'customer' ), 400 ); + } + + $data = $data['customer']; + + // Validate the customer ID. + $id = $this->validate_request( $id, 'customer', 'edit' ); + + // Return the validate error. + if ( is_wp_error( $id ) ) { + throw new WC_API_Exception( $id->get_error_code(), $id->get_error_message(), 400 ); + } + + $data = apply_filters( 'woocommerce_api_edit_customer_data', $data, $this ); + + $customer = new WC_Customer( $id ); + + // Customer email. + if ( isset( $data['email'] ) ) { + $customer->set_email( $data['email'] ); + } + + // Customer password. + if ( isset( $data['password'] ) ) { + $customer->set_password( $data['password'] ); + } + + // Update customer data. + $this->update_customer_data( $customer->get_id(), $data, $customer ); + + $customer->save(); + + do_action( 'woocommerce_api_edit_customer', $customer->get_id(), $data ); + + return $this->get_customer( $customer->get_id() ); + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a customer + * + * @since 2.2 + * @param int $id the customer ID + * @return array|WP_Error + */ + public function delete_customer( $id ) { + + // Validate the customer ID. + $id = $this->validate_request( $id, 'customer', 'delete' ); + + // Return the validate error. + if ( is_wp_error( $id ) ) { + return $id; + } + + do_action( 'woocommerce_api_delete_customer', $id, $this ); + + return $this->delete( $id, 'customer' ); + } + + /** + * Get the orders for a customer + * + * @since 2.1 + * @param int $id the customer ID + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_customer_orders( $id, $fields = null ) { + global $wpdb; + + $id = $this->validate_request( $id, 'customer', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $order_ids = wc_get_orders( array( + 'customer' => $id, + 'limit' => -1, + 'orderby' => 'date', + 'order' => 'ASC', + 'return' => 'ids', + ) ); + + if ( empty( $order_ids ) ) { + return array( 'orders' => array() ); + } + + $orders = array(); + + foreach ( $order_ids as $order_id ) { + $orders[] = current( WC()->api->WC_API_Orders->get_order( $order_id, $fields ) ); + } + + return array( 'orders' => apply_filters( 'woocommerce_api_customer_orders_response', $orders, $id, $fields, $order_ids, $this->server ) ); + } + + /** + * Get the available downloads for a customer + * + * @since 2.2 + * @param int $id the customer ID + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_customer_downloads( $id, $fields = null ) { + $id = $this->validate_request( $id, 'customer', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $downloads = array(); + $_downloads = wc_get_customer_available_downloads( $id ); + + foreach ( $_downloads as $key => $download ) { + $downloads[] = array( + 'download_url' => $download['download_url'], + 'download_id' => $download['download_id'], + 'product_id' => $download['product_id'], + 'download_name' => $download['download_name'], + 'order_id' => $download['order_id'], + 'order_key' => $download['order_key'], + 'downloads_remaining' => $download['downloads_remaining'], + 'access_expires' => $download['access_expires'] ? $this->server->format_datetime( $download['access_expires'] ) : null, + 'file' => $download['file'], + ); + } + + return array( 'downloads' => apply_filters( 'woocommerce_api_customer_downloads_response', $downloads, $id, $fields, $this->server ) ); + } + + /** + * Helper method to get customer user objects + * + * Note that WP_User_Query does not have built-in pagination so limit & offset are used to provide limited + * pagination support + * + * The filter for role can only be a single role in a string. + * + * @since 2.3 + * @param array $args request arguments for filtering query + * @return WP_User_Query + */ + private function query_customers( $args = array() ) { + + // default users per page + $users_per_page = get_option( 'posts_per_page' ); + + // Set base query arguments + $query_args = array( + 'fields' => 'ID', + 'role' => 'customer', + 'orderby' => 'registered', + 'number' => $users_per_page, + ); + + // Custom Role + if ( ! empty( $args['role'] ) ) { + $query_args['role'] = $args['role']; + } + + // Search + if ( ! empty( $args['q'] ) ) { + $query_args['search'] = $args['q']; + } + + // Limit number of users returned + if ( ! empty( $args['limit'] ) ) { + if ( -1 == $args['limit'] ) { + unset( $query_args['number'] ); + } else { + $query_args['number'] = absint( $args['limit'] ); + $users_per_page = absint( $args['limit'] ); + } + } else { + $args['limit'] = $query_args['number']; + } + + // Page + $page = ( isset( $args['page'] ) ) ? absint( $args['page'] ) : 1; + + // Offset + if ( ! empty( $args['offset'] ) ) { + $query_args['offset'] = absint( $args['offset'] ); + } else { + $query_args['offset'] = $users_per_page * ( $page - 1 ); + } + + // Created date + if ( ! empty( $args['created_at_min'] ) ) { + $this->created_at_min = $this->server->parse_datetime( $args['created_at_min'] ); + } + + if ( ! empty( $args['created_at_max'] ) ) { + $this->created_at_max = $this->server->parse_datetime( $args['created_at_max'] ); + } + + // Order (ASC or DESC, ASC by default) + if ( ! empty( $args['order'] ) ) { + $query_args['order'] = $args['order']; + } + + // Order by + if ( ! empty( $args['orderby'] ) ) { + $query_args['orderby'] = $args['orderby']; + + // Allow sorting by meta value + if ( ! empty( $args['orderby_meta_key'] ) ) { + $query_args['meta_key'] = $args['orderby_meta_key']; + } + } + + $query = new WP_User_Query( $query_args ); + + // Helper members for pagination headers + $query->total_pages = ( -1 == $args['limit'] ) ? 1 : ceil( $query->get_total() / $users_per_page ); + $query->page = $page; + + return $query; + } + + /** + * Add customer data to orders + * + * @since 2.1 + * @param $order_data + * @param $order + * @return array + */ + public function add_customer_data( $order_data, $order ) { + + if ( 0 == $order->get_user_id() ) { + + // add customer data from order + $order_data['customer'] = array( + 'id' => 0, + 'email' => $order->get_billing_email(), + 'first_name' => $order->get_billing_first_name(), + 'last_name' => $order->get_billing_last_name(), + 'billing_address' => array( + 'first_name' => $order->get_billing_first_name(), + 'last_name' => $order->get_billing_last_name(), + 'company' => $order->get_billing_company(), + 'address_1' => $order->get_billing_address_1(), + 'address_2' => $order->get_billing_address_2(), + 'city' => $order->get_billing_city(), + 'state' => $order->get_billing_state(), + 'postcode' => $order->get_billing_postcode(), + 'country' => $order->get_billing_country(), + 'email' => $order->get_billing_email(), + 'phone' => $order->get_billing_phone(), + ), + 'shipping_address' => array( + 'first_name' => $order->get_shipping_first_name(), + 'last_name' => $order->get_shipping_last_name(), + 'company' => $order->get_shipping_company(), + 'address_1' => $order->get_shipping_address_1(), + 'address_2' => $order->get_shipping_address_2(), + 'city' => $order->get_shipping_city(), + 'state' => $order->get_shipping_state(), + 'postcode' => $order->get_shipping_postcode(), + 'country' => $order->get_shipping_country(), + ), + ); + + } else { + + $order_data['customer'] = current( $this->get_customer( $order->get_user_id() ) ); + } + + return $order_data; + } + + /** + * Modify the WP_User_Query to support filtering on the date the customer was created + * + * @since 2.1 + * @param WP_User_Query $query + */ + public function modify_user_query( $query ) { + + if ( $this->created_at_min ) { + $query->query_where .= sprintf( " AND user_registered >= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%H:%%i:%%s' )", esc_sql( $this->created_at_min ) ); + } + + if ( $this->created_at_max ) { + $query->query_where .= sprintf( " AND user_registered <= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%H:%%i:%%s' )", esc_sql( $this->created_at_max ) ); + } + } + + /** + * Validate the request by checking: + * + * 1) the ID is a valid integer + * 2) the ID returns a valid WP_User + * 3) the current user has the proper permissions + * + * @since 2.1 + * @see WC_API_Resource::validate_request() + * @param integer $id the customer ID + * @param string $type the request type, unused because this method overrides the parent class + * @param string $context the context of the request, either `read`, `edit` or `delete` + * @return int|WP_Error valid user ID or WP_Error if any of the checks fails + */ + protected function validate_request( $id, $type, $context ) { + + try { + $id = absint( $id ); + + // validate ID + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_id', __( 'Invalid customer ID', 'woocommerce' ), 404 ); + } + + // non-existent IDs return a valid WP_User object with the user ID = 0 + $customer = new WP_User( $id ); + + if ( 0 === $customer->ID ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer', __( 'Invalid customer', 'woocommerce' ), 404 ); + } + + // validate permissions + switch ( $context ) { + + case 'read': + if ( ! current_user_can( 'list_users' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_customer', __( 'You do not have permission to read this customer', 'woocommerce' ), 401 ); + } + break; + + case 'edit': + if ( ! wc_rest_check_user_permissions( 'edit', $customer->ID ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_customer', __( 'You do not have permission to edit this customer', 'woocommerce' ), 401 ); + } + break; + + case 'delete': + if ( ! wc_rest_check_user_permissions( 'delete', $customer->ID ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_customer', __( 'You do not have permission to delete this customer', 'woocommerce' ), 401 ); + } + break; + } + + return $id; + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Check if the current user can read users + * + * @since 2.1 + * @see WC_API_Resource::is_readable() + * @param int|WP_Post $post unused + * @return bool true if the current user can read users, false otherwise + */ + protected function is_readable( $post ) { + return current_user_can( 'list_users' ); + } + + /** + * Bulk update or insert customers + * Accepts an array with customers in the formats supported by + * WC_API_Customers->create_customer() and WC_API_Customers->edit_customer() + * + * @since 2.4.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function bulk( $data ) { + + try { + if ( ! isset( $data['customers'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_customers_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'customers' ), 400 ); + } + + $data = $data['customers']; + $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'customers' ); + + // Limit bulk operation + if ( count( $data ) > $limit ) { + throw new WC_API_Exception( 'woocommerce_api_customers_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); + } + + $customers = array(); + + foreach ( $data as $_customer ) { + $customer_id = 0; + + // Try to get the customer ID + if ( isset( $_customer['id'] ) ) { + $customer_id = intval( $_customer['id'] ); + } + + // Customer exists / edit customer + if ( $customer_id ) { + $edit = $this->edit_customer( $customer_id, array( 'customer' => $_customer ) ); + + if ( is_wp_error( $edit ) ) { + $customers[] = array( + 'id' => $customer_id, + 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ), + ); + } else { + $customers[] = $edit['customer']; + } + } else { + // Customer don't exists / create customer + $new = $this->create_customer( array( 'customer' => $_customer ) ); + + if ( is_wp_error( $new ) ) { + $customers[] = array( + 'id' => $customer_id, + 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ), + ); + } else { + $customers[] = $new['customer']; + } + } + } + + return array( 'customers' => apply_filters( 'woocommerce_api_customers_bulk_response', $customers, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-exception.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-exception.php new file mode 100644 index 0000000..5000f76 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-exception.php @@ -0,0 +1,48 @@ +error_code = $error_code; + parent::__construct( $error_message, $http_status_code ); + } + + /** + * Returns the error code + * + * @since 2.2 + * @return string + */ + public function getErrorCode() { + return $this->error_code; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-json-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-json-handler.php new file mode 100644 index 0000000..ee4d5e8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-json-handler.php @@ -0,0 +1,73 @@ +api->server->send_status( 400 ); + return wp_json_encode( array( array( 'code' => 'woocommerce_api_jsonp_disabled', 'message' => __( 'JSONP support is disabled on this site', 'woocommerce' ) ) ) ); + } + + $jsonp_callback = $_GET['_jsonp']; + + if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) { + WC()->api->server->send_status( 400 ); + return wp_json_encode( array( array( 'code' => 'woocommerce_api_jsonp_callback_invalid', __( 'The JSONP callback function is invalid', 'woocommerce' ) ) ) ); + } + + WC()->api->server->header( 'X-Content-Type-Options', 'nosniff' ); + + // Prepend '/**/' to mitigate possible JSONP Flash attacks. + // https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/ + return '/**/' . $jsonp_callback . '(' . wp_json_encode( $data ) . ')'; + } + + return wp_json_encode( $data ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php new file mode 100644 index 0000000..cfc2d13 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php @@ -0,0 +1,1830 @@ + + * GET /orders//notes + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET|POST /orders + $routes[ $this->base ] = array( + array( array( $this, 'get_orders' ), WC_API_Server::READABLE ), + array( array( $this, 'create_order' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /orders/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_orders_count' ), WC_API_Server::READABLE ), + ); + + # GET /orders/statuses + $routes[ $this->base . '/statuses' ] = array( + array( array( $this, 'get_order_statuses' ), WC_API_Server::READABLE ), + ); + + # GET|PUT|DELETE /orders/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_order' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_order' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_order' ), WC_API_Server::DELETABLE ), + ); + + # GET|POST /orders//notes + $routes[ $this->base . '/(?P\d+)/notes' ] = array( + array( array( $this, 'get_order_notes' ), WC_API_Server::READABLE ), + array( array( $this, 'create_order_note' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET|PUT|DELETE /orders//notes/ + $routes[ $this->base . '/(?P\d+)/notes/(?P\d+)' ] = array( + array( array( $this, 'get_order_note' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_order_note' ), WC_API_SERVER::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_order_note' ), WC_API_SERVER::DELETABLE ), + ); + + # GET|POST /orders//refunds + $routes[ $this->base . '/(?P\d+)/refunds' ] = array( + array( array( $this, 'get_order_refunds' ), WC_API_Server::READABLE ), + array( array( $this, 'create_order_refund' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET|PUT|DELETE /orders//refunds/ + $routes[ $this->base . '/(?P\d+)/refunds/(?P\d+)' ] = array( + array( array( $this, 'get_order_refund' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_order_refund' ), WC_API_SERVER::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_order_refund' ), WC_API_SERVER::DELETABLE ), + ); + + # POST|PUT /orders/bulk + $routes[ $this->base . '/bulk' ] = array( + array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + return $routes; + } + + /** + * Get all orders + * + * @since 2.1 + * @param string $fields + * @param array $filter + * @param string $status + * @param int $page + * @return array + */ + public function get_orders( $fields = null, $filter = array(), $status = null, $page = 1 ) { + + if ( ! empty( $status ) ) { + $filter['status'] = $status; + } + + $filter['page'] = $page; + + $query = $this->query_orders( $filter ); + + $orders = array(); + + foreach ( $query->posts as $order_id ) { + + if ( ! $this->is_readable( $order_id ) ) { + continue; + } + + $orders[] = current( $this->get_order( $order_id, $fields, $filter ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'orders' => $orders ); + } + + + /** + * Get the order for the given ID + * + * @since 2.1 + * @param int $id the order ID + * @param array $fields + * @param array $filter + * @return array|WP_Error + */ + public function get_order( $id, $fields = null, $filter = array() ) { + + // ensure order ID is valid & user has permission to read + $id = $this->validate_request( $id, $this->post_type, 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + // Get the decimal precession + $dp = ( isset( $filter['dp'] ) ? intval( $filter['dp'] ) : 2 ); + $order = wc_get_order( $id ); + $order_data = array( + 'id' => $order->get_id(), + 'order_number' => $order->get_order_number(), + 'created_at' => $this->server->format_datetime( $order->get_date_created() ? $order->get_date_created()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'updated_at' => $this->server->format_datetime( $order->get_date_modified() ? $order->get_date_modified()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'completed_at' => $this->server->format_datetime( $order->get_date_completed() ? $order->get_date_completed()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'status' => $order->get_status(), + 'currency' => $order->get_currency(), + 'total' => wc_format_decimal( $order->get_total(), $dp ), + 'subtotal' => wc_format_decimal( $order->get_subtotal(), $dp ), + 'total_line_items_quantity' => $order->get_item_count(), + 'total_tax' => wc_format_decimal( $order->get_total_tax(), $dp ), + 'total_shipping' => wc_format_decimal( $order->get_shipping_total(), $dp ), + 'cart_tax' => wc_format_decimal( $order->get_cart_tax(), $dp ), + 'shipping_tax' => wc_format_decimal( $order->get_shipping_tax(), $dp ), + 'total_discount' => wc_format_decimal( $order->get_total_discount(), $dp ), + 'shipping_methods' => $order->get_shipping_method(), + 'payment_details' => array( + 'method_id' => $order->get_payment_method(), + 'method_title' => $order->get_payment_method_title(), + 'paid' => ! is_null( $order->get_date_paid() ), + ), + 'billing_address' => array( + 'first_name' => $order->get_billing_first_name(), + 'last_name' => $order->get_billing_last_name(), + 'company' => $order->get_billing_company(), + 'address_1' => $order->get_billing_address_1(), + 'address_2' => $order->get_billing_address_2(), + 'city' => $order->get_billing_city(), + 'state' => $order->get_billing_state(), + 'postcode' => $order->get_billing_postcode(), + 'country' => $order->get_billing_country(), + 'email' => $order->get_billing_email(), + 'phone' => $order->get_billing_phone(), + ), + 'shipping_address' => array( + 'first_name' => $order->get_shipping_first_name(), + 'last_name' => $order->get_shipping_last_name(), + 'company' => $order->get_shipping_company(), + 'address_1' => $order->get_shipping_address_1(), + 'address_2' => $order->get_shipping_address_2(), + 'city' => $order->get_shipping_city(), + 'state' => $order->get_shipping_state(), + 'postcode' => $order->get_shipping_postcode(), + 'country' => $order->get_shipping_country(), + ), + 'note' => $order->get_customer_note(), + 'customer_ip' => $order->get_customer_ip_address(), + 'customer_user_agent' => $order->get_customer_user_agent(), + 'customer_id' => $order->get_user_id(), + 'view_order_url' => $order->get_view_order_url(), + 'line_items' => array(), + 'shipping_lines' => array(), + 'tax_lines' => array(), + 'fee_lines' => array(), + 'coupon_lines' => array(), + ); + + // add line items + foreach ( $order->get_items() as $item_id => $item ) { + $product = $item->get_product(); + $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; + $item_meta = $item->get_formatted_meta_data( $hideprefix ); + + foreach ( $item_meta as $key => $values ) { + $item_meta[ $key ]->label = $values->display_key; + unset( $item_meta[ $key ]->display_key ); + unset( $item_meta[ $key ]->display_value ); + } + + $order_data['line_items'][] = array( + 'id' => $item_id, + 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item, false, false ), $dp ), + 'subtotal_tax' => wc_format_decimal( $item->get_subtotal_tax(), $dp ), + 'total' => wc_format_decimal( $order->get_line_total( $item, false, false ), $dp ), + 'total_tax' => wc_format_decimal( $item->get_total_tax(), $dp ), + 'price' => wc_format_decimal( $order->get_item_total( $item, false, false ), $dp ), + 'quantity' => $item->get_quantity(), + 'tax_class' => $item->get_tax_class(), + 'name' => $item->get_name(), + 'product_id' => $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id(), + 'sku' => is_object( $product ) ? $product->get_sku() : null, + 'meta' => array_values( $item_meta ), + ); + } + + // add shipping + foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) { + $order_data['shipping_lines'][] = array( + 'id' => $shipping_item_id, + 'method_id' => $shipping_item->get_method_id(), + 'method_title' => $shipping_item->get_name(), + 'total' => wc_format_decimal( $shipping_item->get_total(), $dp ), + ); + } + + // add taxes + foreach ( $order->get_tax_totals() as $tax_code => $tax ) { + $order_data['tax_lines'][] = array( + 'id' => $tax->id, + 'rate_id' => $tax->rate_id, + 'code' => $tax_code, + 'title' => $tax->label, + 'total' => wc_format_decimal( $tax->amount, $dp ), + 'compound' => (bool) $tax->is_compound, + ); + } + + // add fees + foreach ( $order->get_fees() as $fee_item_id => $fee_item ) { + $order_data['fee_lines'][] = array( + 'id' => $fee_item_id, + 'title' => $fee_item->get_name(), + 'tax_class' => $fee_item->get_tax_class(), + 'total' => wc_format_decimal( $order->get_line_total( $fee_item ), $dp ), + 'total_tax' => wc_format_decimal( $order->get_line_tax( $fee_item ), $dp ), + ); + } + + // add coupons + foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) { + $order_data['coupon_lines'][] = array( + 'id' => $coupon_item_id, + 'code' => $coupon_item->get_code(), + 'amount' => wc_format_decimal( $coupon_item->get_discount(), $dp ), + ); + } + + return array( 'order' => apply_filters( 'woocommerce_api_order_response', $order_data, $order, $fields, $this->server ) ); + } + + /** + * Get the total number of orders + * + * @since 2.4 + * + * @param string $status + * @param array $filter + * + * @return array|WP_Error + */ + public function get_orders_count( $status = null, $filter = array() ) { + + try { + if ( ! current_user_can( 'read_private_shop_orders' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_orders_count', __( 'You do not have permission to read the orders count', 'woocommerce' ), 401 ); + } + + if ( ! empty( $status ) ) { + + if ( 'any' === $status ) { + + $order_statuses = array(); + + foreach ( wc_get_order_statuses() as $slug => $name ) { + $filter['status'] = str_replace( 'wc-', '', $slug ); + $query = $this->query_orders( $filter ); + $order_statuses[ str_replace( 'wc-', '', $slug ) ] = (int) $query->found_posts; + } + + return array( 'count' => $order_statuses ); + + } else { + $filter['status'] = $status; + } + } + + $query = $this->query_orders( $filter ); + + return array( 'count' => (int) $query->found_posts ); + + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get a list of valid order statuses + * + * Note this requires no specific permissions other than being an authenticated + * API user. Order statuses (particularly custom statuses) could be considered + * private information which is why it's not in the API index. + * + * @since 2.1 + * @return array + */ + public function get_order_statuses() { + + $order_statuses = array(); + + foreach ( wc_get_order_statuses() as $slug => $name ) { + $order_statuses[ str_replace( 'wc-', '', $slug ) ] = $name; + } + + return array( 'order_statuses' => apply_filters( 'woocommerce_api_order_statuses_response', $order_statuses, $this ) ); + } + + /** + * Create an order + * + * @since 2.2 + * + * @param array $data raw order data + * + * @return array|WP_Error + */ + public function create_order( $data ) { + global $wpdb; + + try { + if ( ! isset( $data['order'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'order' ), 400 ); + } + + $data = $data['order']; + + // permission check + if ( ! current_user_can( 'publish_shop_orders' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_order', __( 'You do not have permission to create orders', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_order_data', $data, $this ); + + // default order args, note that status is checked for validity in wc_create_order() + $default_order_args = array( + 'status' => isset( $data['status'] ) ? $data['status'] : '', + 'customer_note' => isset( $data['note'] ) ? $data['note'] : null, + ); + + // if creating order for existing customer + if ( ! empty( $data['customer_id'] ) ) { + + // make sure customer exists + if ( false === get_user_by( 'id', $data['customer_id'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + $default_order_args['customer_id'] = $data['customer_id']; + } + + // create the pending order + $order = $this->create_base_order( $default_order_args, $data ); + + if ( is_wp_error( $order ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_order', sprintf( __( 'Cannot create order: %s', 'woocommerce' ), implode( ', ', $order->get_error_messages() ) ), 400 ); + } + + // billing/shipping addresses + $this->set_order_addresses( $order, $data ); + + $lines = array( + 'line_item' => 'line_items', + 'shipping' => 'shipping_lines', + 'fee' => 'fee_lines', + 'coupon' => 'coupon_lines', + ); + + foreach ( $lines as $line_type => $line ) { + + if ( isset( $data[ $line ] ) && is_array( $data[ $line ] ) ) { + + $set_item = "set_{$line_type}"; + + foreach ( $data[ $line ] as $item ) { + + $this->$set_item( $order, $item, 'create' ); + } + } + } + + // calculate totals and set them + $order->calculate_totals(); + + // payment method (and payment_complete() if `paid` == true) + if ( isset( $data['payment_details'] ) && is_array( $data['payment_details'] ) ) { + + // method ID & title are required + if ( empty( $data['payment_details']['method_id'] ) || empty( $data['payment_details']['method_title'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_payment_details', __( 'Payment method ID and title are required', 'woocommerce' ), 400 ); + } + + update_post_meta( $order->get_id(), '_payment_method', $data['payment_details']['method_id'] ); + update_post_meta( $order->get_id(), '_payment_method_title', sanitize_text_field( $data['payment_details']['method_title'] ) ); + + // mark as paid if set + if ( isset( $data['payment_details']['paid'] ) && true === $data['payment_details']['paid'] ) { + $order->payment_complete( isset( $data['payment_details']['transaction_id'] ) ? $data['payment_details']['transaction_id'] : '' ); + } + } + + // set order currency + if ( isset( $data['currency'] ) ) { + + if ( ! array_key_exists( $data['currency'], get_woocommerce_currencies() ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_order_currency', __( 'Provided order currency is invalid.', 'woocommerce' ), 400 ); + } + + update_post_meta( $order->get_id(), '_order_currency', $data['currency'] ); + } + + // set order meta + if ( isset( $data['order_meta'] ) && is_array( $data['order_meta'] ) ) { + $this->set_order_meta( $order->get_id(), $data['order_meta'] ); + } + + // HTTP 201 Created + $this->server->send_status( 201 ); + + wc_delete_shop_order_transients( $order ); + + do_action( 'woocommerce_api_create_order', $order->get_id(), $data, $this ); + do_action( 'woocommerce_new_order', $order->get_id() ); + + return $this->get_order( $order->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Creates new WC_Order. + * + * Requires a separate function for classes that extend WC_API_Orders. + * + * @since 2.3 + * + * @param $args array + * @param $data + * + * @return WC_Order + */ + protected function create_base_order( $args, $data ) { + return wc_create_order( $args ); + } + + /** + * Edit an order + * + * @since 2.2 + * + * @param int $id the order ID + * @param array $data + * + * @return array|WP_Error + */ + public function edit_order( $id, $data ) { + try { + if ( ! isset( $data['order'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'order' ), 400 ); + } + + $data = $data['order']; + + $update_totals = false; + + $id = $this->validate_request( $id, $this->post_type, 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $data = apply_filters( 'woocommerce_api_edit_order_data', $data, $id, $this ); + $order = wc_get_order( $id ); + + if ( empty( $order ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_id', __( 'Order ID is invalid', 'woocommerce' ), 400 ); + } + + $order_args = array( 'order_id' => $order->get_id() ); + + // Customer note. + if ( isset( $data['note'] ) ) { + $order_args['customer_note'] = $data['note']; + } + + // Customer ID. + if ( isset( $data['customer_id'] ) && $data['customer_id'] != $order->get_user_id() ) { + // Make sure customer exists. + if ( false === get_user_by( 'id', $data['customer_id'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + update_post_meta( $order->get_id(), '_customer_user', $data['customer_id'] ); + } + + // Billing/shipping address. + $this->set_order_addresses( $order, $data ); + + $lines = array( + 'line_item' => 'line_items', + 'shipping' => 'shipping_lines', + 'fee' => 'fee_lines', + 'coupon' => 'coupon_lines', + ); + + foreach ( $lines as $line_type => $line ) { + + if ( isset( $data[ $line ] ) && is_array( $data[ $line ] ) ) { + + $update_totals = true; + + foreach ( $data[ $line ] as $item ) { + + // Item ID is always required. + if ( ! array_key_exists( 'id', $item ) ) { + $item['id'] = null; + } + + // Create item. + if ( is_null( $item['id'] ) ) { + $this->set_item( $order, $line_type, $item, 'create' ); + } elseif ( $this->item_is_null( $item ) ) { + // Delete item. + wc_delete_order_item( $item['id'] ); + } else { + // Update item. + $this->set_item( $order, $line_type, $item, 'update' ); + } + } + } + } + + // Payment method (and payment_complete() if `paid` == true and order needs payment). + if ( isset( $data['payment_details'] ) && is_array( $data['payment_details'] ) ) { + + // Method ID. + if ( isset( $data['payment_details']['method_id'] ) ) { + update_post_meta( $order->get_id(), '_payment_method', $data['payment_details']['method_id'] ); + } + + // Method title. + if ( isset( $data['payment_details']['method_title'] ) ) { + update_post_meta( $order->get_id(), '_payment_method_title', sanitize_text_field( $data['payment_details']['method_title'] ) ); + } + + // Mark as paid if set. + if ( $order->needs_payment() && isset( $data['payment_details']['paid'] ) && true === $data['payment_details']['paid'] ) { + $order->payment_complete( isset( $data['payment_details']['transaction_id'] ) ? $data['payment_details']['transaction_id'] : '' ); + } + } + + // Set order currency. + if ( isset( $data['currency'] ) ) { + if ( ! array_key_exists( $data['currency'], get_woocommerce_currencies() ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_order_currency', __( 'Provided order currency is invalid.', 'woocommerce' ), 400 ); + } + + update_post_meta( $order->get_id(), '_order_currency', $data['currency'] ); + } + + // If items have changed, recalculate order totals. + if ( $update_totals ) { + $order->calculate_totals(); + } + + // Update order meta. + if ( isset( $data['order_meta'] ) && is_array( $data['order_meta'] ) ) { + $this->set_order_meta( $order->get_id(), $data['order_meta'] ); + } + + // Update the order post to set customer note/modified date. + wc_update_order( $order_args ); + + // Order status. + if ( ! empty( $data['status'] ) ) { + // Refresh the order instance. + $order = wc_get_order( $order->get_id() ); + $order->update_status( $data['status'], isset( $data['status_note'] ) ? $data['status_note'] : '', true ); + } + + wc_delete_shop_order_transients( $order ); + + do_action( 'woocommerce_api_edit_order', $order->get_id(), $data, $this ); + do_action( 'woocommerce_update_order', $order->get_id() ); + + return $this->get_order( $id ); + + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete an order + * + * @param int $id the order ID + * @param bool $force true to permanently delete order, false to move to trash + * @return array|WP_Error + */ + public function delete_order( $id, $force = false ) { + + $id = $this->validate_request( $id, $this->post_type, 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + wc_delete_shop_order_transients( $id ); + + do_action( 'woocommerce_api_delete_order', $id, $this ); + + return $this->delete( $id, 'order', ( 'true' === $force ) ); + } + + /** + * Helper method to get order post objects + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_Query + */ + protected function query_orders( $args ) { + + // set base query arguments + $query_args = array( + 'fields' => 'ids', + 'post_type' => $this->post_type, + 'post_status' => array_keys( wc_get_order_statuses() ), + ); + + // add status argument + if ( ! empty( $args['status'] ) ) { + + $statuses = 'wc-' . str_replace( ',', ',wc-', $args['status'] ); + $statuses = explode( ',', $statuses ); + $query_args['post_status'] = $statuses; + + unset( $args['status'] ); + + } + + $query_args = $this->merge_query_args( $query_args, $args ); + + return new WP_Query( $query_args ); + } + + /** + * Helper method to set/update the billing & shipping addresses for + * an order + * + * @since 2.1 + * @param \WC_Order $order + * @param array $data + */ + protected function set_order_addresses( $order, $data ) { + + $address_fields = array( + 'first_name', + 'last_name', + 'company', + 'email', + 'phone', + 'address_1', + 'address_2', + 'city', + 'state', + 'postcode', + 'country', + ); + + $billing_address = $shipping_address = array(); + + // billing address + if ( isset( $data['billing_address'] ) && is_array( $data['billing_address'] ) ) { + + foreach ( $address_fields as $field ) { + + if ( isset( $data['billing_address'][ $field ] ) ) { + $billing_address[ $field ] = wc_clean( $data['billing_address'][ $field ] ); + } + } + + unset( $address_fields['email'] ); + unset( $address_fields['phone'] ); + } + + // shipping address + if ( isset( $data['shipping_address'] ) && is_array( $data['shipping_address'] ) ) { + + foreach ( $address_fields as $field ) { + + if ( isset( $data['shipping_address'][ $field ] ) ) { + $shipping_address[ $field ] = wc_clean( $data['shipping_address'][ $field ] ); + } + } + } + + $this->update_address( $order, $billing_address, 'billing' ); + $this->update_address( $order, $shipping_address, 'shipping' ); + + // update user meta + if ( $order->get_user_id() ) { + foreach ( $billing_address as $key => $value ) { + update_user_meta( $order->get_user_id(), 'billing_' . $key, $value ); + } + foreach ( $shipping_address as $key => $value ) { + update_user_meta( $order->get_user_id(), 'shipping_' . $key, $value ); + } + } + } + + /** + * Update address. + * + * @param WC_Order $order + * @param array $posted + * @param string $type + */ + protected function update_address( $order, $posted, $type = 'billing' ) { + foreach ( $posted as $key => $value ) { + if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { + $order->{"set_{$type}_{$key}"}( $value ); + } + } + } + + /** + * Helper method to add/update order meta, with two restrictions: + * + * 1) Only non-protected meta (no leading underscore) can be set + * 2) Meta values must be scalar (int, string, bool) + * + * @since 2.2 + * @param int $order_id valid order ID + * @param array $order_meta order meta in array( 'meta_key' => 'meta_value' ) format + */ + protected function set_order_meta( $order_id, $order_meta ) { + + foreach ( $order_meta as $meta_key => $meta_value ) { + + if ( is_string( $meta_key ) && ! is_protected_meta( $meta_key ) && is_scalar( $meta_value ) ) { + update_post_meta( $order_id, $meta_key, $meta_value ); + } + } + } + + /** + * Helper method to check if the resource ID associated with the provided item is null + * + * Items can be deleted by setting the resource ID to null + * + * @since 2.2 + * @param array $item item provided in the request body + * @return bool true if the item resource ID is null, false otherwise + */ + protected function item_is_null( $item ) { + + $keys = array( 'product_id', 'method_id', 'title', 'code' ); + + foreach ( $keys as $key ) { + if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { + return true; + } + } + + return false; + } + + /** + * Wrapper method to create/update order items + * + * When updating, the item ID provided is checked to ensure it is associated + * with the order. + * + * @since 2.2 + * @param \WC_Order $order order + * @param string $item_type + * @param array $item item provided in the request body + * @param string $action either 'create' or 'update' + * @throws WC_API_Exception if item ID is not associated with order + */ + protected function set_item( $order, $item_type, $item, $action ) { + global $wpdb; + + $set_method = "set_{$item_type}"; + + // verify provided line item ID is associated with order + if ( 'update' === $action ) { + + $result = $wpdb->get_row( + $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d AND order_id = %d", + absint( $item['id'] ), + absint( $order->get_id() ) + ) ); + + if ( is_null( $result ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + } + } + + $this->$set_method( $order, $item, $action ); + } + + /** + * Create or update a line item + * + * @since 2.2 + * @param \WC_Order $order + * @param array $item line item data + * @param string $action 'create' to add line item or 'update' to update it + * @throws WC_API_Exception invalid data, server error + */ + protected function set_line_item( $order, $item, $action ) { + $creating = ( 'create' === $action ); + + // product is always required + if ( ! isset( $item['product_id'] ) && ! isset( $item['sku'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_id', __( 'Product ID or SKU is required', 'woocommerce' ), 400 ); + } + + // when updating, ensure product ID provided matches + if ( 'update' === $action ) { + + $item_product_id = wc_get_order_item_meta( $item['id'], '_product_id' ); + $item_variation_id = wc_get_order_item_meta( $item['id'], '_variation_id' ); + + if ( $item['product_id'] != $item_product_id && $item['product_id'] != $item_variation_id ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_id', __( 'Product ID provided does not match this line item', 'woocommerce' ), 400 ); + } + } + + if ( isset( $item['product_id'] ) ) { + $product_id = $item['product_id']; + } elseif ( isset( $item['sku'] ) ) { + $product_id = wc_get_product_id_by_sku( $item['sku'] ); + } + + // variations must each have a key & value + $variation_id = 0; + if ( isset( $item['variations'] ) && is_array( $item['variations'] ) ) { + foreach ( $item['variations'] as $key => $value ) { + if ( ! $key || ! $value ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_variation', __( 'The product variation is invalid', 'woocommerce' ), 400 ); + } + } + $variation_id = $this->get_variation_id( wc_get_product( $product_id ), $item['variations'] ); + } + + $product = wc_get_product( $variation_id ? $variation_id : $product_id ); + + // must be a valid WC_Product + if ( ! is_object( $product ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product', __( 'Product is invalid.', 'woocommerce' ), 400 ); + } + + // quantity must be positive float + if ( isset( $item['quantity'] ) && floatval( $item['quantity'] ) <= 0 ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_quantity', __( 'Product quantity must be a positive float.', 'woocommerce' ), 400 ); + } + + // quantity is required when creating + if ( $creating && ! isset( $item['quantity'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_quantity', __( 'Product quantity is required.', 'woocommerce' ), 400 ); + } + + if ( $creating ) { + $line_item = new WC_Order_Item_Product(); + } else { + $line_item = new WC_Order_Item_Product( $item['id'] ); + } + + $line_item->set_product( $product ); + $line_item->set_order_id( $order->get_id() ); + + if ( isset( $item['quantity'] ) ) { + $line_item->set_quantity( $item['quantity'] ); + } + if ( isset( $item['total'] ) ) { + $line_item->set_total( floatval( $item['total'] ) ); + } elseif ( $creating ) { + $total = wc_get_price_excluding_tax( $product, array( 'qty' => $line_item->get_quantity() ) ); + $line_item->set_total( $total ); + $line_item->set_subtotal( $total ); + } + if ( isset( $item['total_tax'] ) ) { + $line_item->set_total_tax( floatval( $item['total_tax'] ) ); + } + if ( isset( $item['subtotal'] ) ) { + $line_item->set_subtotal( floatval( $item['subtotal'] ) ); + } + if ( isset( $item['subtotal_tax'] ) ) { + $line_item->set_subtotal_tax( floatval( $item['subtotal_tax'] ) ); + } + if ( $variation_id ) { + $line_item->set_variation_id( $variation_id ); + $line_item->set_variation( $item['variations'] ); + } + + // Save or add to order. + if ( $creating ) { + $order->add_item( $line_item ); + } else { + $item_id = $line_item->save(); + + if ( ! $item_id ) { + throw new WC_API_Exception( 'woocommerce_cannot_create_line_item', __( 'Cannot create line item, try again.', 'woocommerce' ), 500 ); + } + } + } + + /** + * Given a product ID & API provided variations, find the correct variation ID to use for calculation + * We can't just trust input from the API to pass a variation_id manually, otherwise you could pass + * the cheapest variation ID but provide other information so we have to look up the variation ID. + * + * @param WC_Product $product + * @param array $variations + * + * @return int returns an ID if a valid variation was found for this product + */ + function get_variation_id( $product, $variations = array() ) { + $variation_id = null; + $variations_normalized = array(); + + if ( $product->is_type( 'variable' ) && $product->has_child() ) { + if ( isset( $variations ) && is_array( $variations ) ) { + // start by normalizing the passed variations + foreach ( $variations as $key => $value ) { + $key = str_replace( 'attribute_', '', wc_attribute_taxonomy_slug( $key ) ); // from get_attributes in class-wc-api-products.php + $variations_normalized[ $key ] = strtolower( $value ); + } + // now search through each product child and see if our passed variations match anything + foreach ( $product->get_children() as $variation ) { + $meta = array(); + foreach ( get_post_meta( $variation ) as $key => $value ) { + $value = $value[0]; + $key = str_replace( 'attribute_', '', wc_attribute_taxonomy_slug( $key ) ); + $meta[ $key ] = strtolower( $value ); + } + // if the variation array is a part of the $meta array, we found our match + if ( $this->array_contains( $variations_normalized, $meta ) ) { + $variation_id = $variation; + break; + } + } + } + } + + return $variation_id; + } + + /** + * Utility function to see if the meta array contains data from variations + * + * @param array $needles + * @param array $haystack + * + * @return bool + */ + protected function array_contains( $needles, $haystack ) { + foreach ( $needles as $key => $value ) { + if ( $haystack[ $key ] !== $value ) { + return false; + } + } + return true; + } + + /** + * Create or update an order shipping method + * + * @since 2.2 + * @param \WC_Order $order + * @param array $shipping item data + * @param string $action 'create' to add shipping or 'update' to update it + * @throws WC_API_Exception invalid data, server error + */ + protected function set_shipping( $order, $shipping, $action ) { + + // total must be a positive float + if ( isset( $shipping['total'] ) && floatval( $shipping['total'] ) < 0 ) { + throw new WC_API_Exception( 'woocommerce_invalid_shipping_total', __( 'Shipping total must be a positive amount.', 'woocommerce' ), 400 ); + } + + if ( 'create' === $action ) { + + // method ID is required + if ( ! isset( $shipping['method_id'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + } + + $rate = new WC_Shipping_Rate( $shipping['method_id'], isset( $shipping['method_title'] ) ? $shipping['method_title'] : '', isset( $shipping['total'] ) ? floatval( $shipping['total'] ) : 0, array(), $shipping['method_id'] ); + $item = new WC_Order_Item_Shipping(); + $item->set_order_id( $order->get_id() ); + $item->set_shipping_rate( $rate ); + $order->add_item( $item ); + } else { + + $item = new WC_Order_Item_Shipping( $shipping['id'] ); + + if ( isset( $shipping['method_id'] ) ) { + $item->set_method_id( $shipping['method_id'] ); + } + + if ( isset( $shipping['method_title'] ) ) { + $item->set_method_title( $shipping['method_title'] ); + } + + if ( isset( $shipping['total'] ) ) { + $item->set_total( floatval( $shipping['total'] ) ); + } + + $shipping_id = $item->save(); + + if ( ! $shipping_id ) { + throw new WC_API_Exception( 'woocommerce_cannot_update_shipping', __( 'Cannot update shipping method, try again.', 'woocommerce' ), 500 ); + } + } + } + + /** + * Create or update an order fee + * + * @since 2.2 + * @param \WC_Order $order + * @param array $fee item data + * @param string $action 'create' to add fee or 'update' to update it + * @throws WC_API_Exception invalid data, server error + */ + protected function set_fee( $order, $fee, $action ) { + + if ( 'create' === $action ) { + + // fee title is required + if ( ! isset( $fee['title'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_fee_item', __( 'Fee title is required', 'woocommerce' ), 400 ); + } + + $item = new WC_Order_Item_Fee(); + $item->set_order_id( $order->get_id() ); + $item->set_name( wc_clean( $fee['title'] ) ); + $item->set_total( isset( $fee['total'] ) ? floatval( $fee['total'] ) : 0 ); + + // if taxable, tax class and total are required + if ( ! empty( $fee['taxable'] ) ) { + if ( ! isset( $fee['tax_class'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_fee_item', __( 'Fee tax class is required when fee is taxable.', 'woocommerce' ), 400 ); + } + + $item->set_tax_status( 'taxable' ); + $item->set_tax_class( $fee['tax_class'] ); + + if ( isset( $fee['total_tax'] ) ) { + $item->set_total_tax( isset( $fee['total_tax'] ) ? wc_format_refund_total( $fee['total_tax'] ) : 0 ); + } + + if ( isset( $fee['tax_data'] ) ) { + $item->set_total_tax( wc_format_refund_total( array_sum( $fee['tax_data'] ) ) ); + $item->set_taxes( array_map( 'wc_format_refund_total', $fee['tax_data'] ) ); + } + } + + $order->add_item( $item ); + } else { + + $item = new WC_Order_Item_Fee( $fee['id'] ); + + if ( isset( $fee['title'] ) ) { + $item->set_name( wc_clean( $fee['title'] ) ); + } + + if ( isset( $fee['tax_class'] ) ) { + $item->set_tax_class( $fee['tax_class'] ); + } + + if ( isset( $fee['total'] ) ) { + $item->set_total( floatval( $fee['total'] ) ); + } + + if ( isset( $fee['total_tax'] ) ) { + $item->set_total_tax( floatval( $fee['total_tax'] ) ); + } + + $fee_id = $item->save(); + + if ( ! $fee_id ) { + throw new WC_API_Exception( 'woocommerce_cannot_update_fee', __( 'Cannot update fee, try again.', 'woocommerce' ), 500 ); + } + } + } + + /** + * Create or update an order coupon + * + * @since 2.2 + * @param \WC_Order $order + * @param array $coupon item data + * @param string $action 'create' to add coupon or 'update' to update it + * @throws WC_API_Exception invalid data, server error + */ + protected function set_coupon( $order, $coupon, $action ) { + + // coupon amount must be positive float + if ( isset( $coupon['amount'] ) && floatval( $coupon['amount'] ) < 0 ) { + throw new WC_API_Exception( 'woocommerce_invalid_coupon_total', __( 'Coupon discount total must be a positive amount.', 'woocommerce' ), 400 ); + } + + if ( 'create' === $action ) { + + // coupon code is required + if ( empty( $coupon['code'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + + $item = new WC_Order_Item_Coupon(); + $item->set_props( array( + 'code' => $coupon['code'], + 'discount' => isset( $coupon['amount'] ) ? floatval( $coupon['amount'] ) : 0, + 'discount_tax' => 0, + 'order_id' => $order->get_id(), + ) ); + $order->add_item( $item ); + } else { + + $item = new WC_Order_Item_Coupon( $coupon['id'] ); + + if ( isset( $coupon['code'] ) ) { + $item->set_code( $coupon['code'] ); + } + + if ( isset( $coupon['amount'] ) ) { + $item->set_discount( floatval( $coupon['amount'] ) ); + } + + $coupon_id = $item->save(); + + if ( ! $coupon_id ) { + throw new WC_API_Exception( 'woocommerce_cannot_update_order_coupon', __( 'Cannot update coupon, try again.', 'woocommerce' ), 500 ); + } + } + } + + /** + * Get the admin order notes for an order + * + * @since 2.1 + * @param string $order_id order ID + * @param string|null $fields fields to include in response + * @return array|WP_Error + */ + public function get_order_notes( $order_id, $fields = null ) { + + // ensure ID is valid order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'read' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $args = array( + 'post_id' => $order_id, + 'approve' => 'approve', + 'type' => 'order_note', + ); + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $notes = get_comments( $args ); + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $order_notes = array(); + + foreach ( $notes as $note ) { + + $order_notes[] = current( $this->get_order_note( $order_id, $note->comment_ID, $fields ) ); + } + + return array( 'order_notes' => apply_filters( 'woocommerce_api_order_notes_response', $order_notes, $order_id, $fields, $notes, $this->server ) ); + } + + /** + * Get an order note for the given order ID and ID + * + * @since 2.2 + * + * @param string $order_id order ID + * @param string $id order note ID + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_order_note( $order_id, $id, $fields = null ) { + try { + // Validate order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'read' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'Invalid order note ID', 'woocommerce' ), 400 ); + } + + $note = get_comment( $id ); + + if ( is_null( $note ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'An order note with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $order_note = array( + 'id' => $note->comment_ID, + 'created_at' => $this->server->format_datetime( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + + return array( 'order_note' => apply_filters( 'woocommerce_api_order_note_response', $order_note, $id, $fields, $note, $order_id, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new order note for the given order + * + * @since 2.2 + * @param string $order_id order ID + * @param array $data raw request data + * @return WP_Error|array error or created note response data + */ + public function create_order_note( $order_id, $data ) { + try { + if ( ! isset( $data['order_note'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_note_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'order_note' ), 400 ); + } + + $data = $data['order_note']; + + // permission check + if ( ! current_user_can( 'publish_shop_orders' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_order_note', __( 'You do not have permission to create order notes', 'woocommerce' ), 401 ); + } + + $order_id = $this->validate_request( $order_id, $this->post_type, 'edit' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $order = wc_get_order( $order_id ); + + $data = apply_filters( 'woocommerce_api_create_order_note_data', $data, $order_id, $this ); + + // note content is required + if ( ! isset( $data['note'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note', __( 'Order note is required', 'woocommerce' ), 400 ); + } + + $is_customer_note = ( isset( $data['customer_note'] ) && true === $data['customer_note'] ); + + // create the note + $note_id = $order->add_order_note( $data['note'], $is_customer_note ); + + if ( ! $note_id ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), 500 ); + } + + // HTTP 201 Created + $this->server->send_status( 201 ); + + do_action( 'woocommerce_api_create_order_note', $note_id, $order_id, $this ); + + return $this->get_order_note( $order->get_id(), $note_id ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit the order note + * + * @since 2.2 + * @param string $order_id order ID + * @param string $id note ID + * @param array $data parsed request data + * @return WP_Error|array error or edited note response data + */ + public function edit_order_note( $order_id, $id, $data ) { + try { + if ( ! isset( $data['order_note'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_note_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'order_note' ), 400 ); + } + + $data = $data['order_note']; + + // Validate order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'edit' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $order = wc_get_order( $order_id ); + + // Validate note ID + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'Invalid order note ID', 'woocommerce' ), 400 ); + } + + // Ensure note ID is valid + $note = get_comment( $id ); + + if ( is_null( $note ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'An order note with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + // Ensure note ID is associated with given order + if ( $note->comment_post_ID != $order->get_id() ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'The order note ID provided is not associated with the order', 'woocommerce' ), 400 ); + } + + $data = apply_filters( 'woocommerce_api_edit_order_note_data', $data, $note->comment_ID, $order->get_id(), $this ); + + // Note content + if ( isset( $data['note'] ) ) { + + wp_update_comment( + array( + 'comment_ID' => $note->comment_ID, + 'comment_content' => $data['note'], + ) + ); + } + + // Customer note + if ( isset( $data['customer_note'] ) ) { + + update_comment_meta( $note->comment_ID, 'is_customer_note', true === $data['customer_note'] ? 1 : 0 ); + } + + do_action( 'woocommerce_api_edit_order_note', $note->comment_ID, $order->get_id(), $this ); + + return $this->get_order_note( $order->get_id(), $note->comment_ID ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete order note + * + * @since 2.2 + * @param string $order_id order ID + * @param string $id note ID + * @return WP_Error|array error or deleted message + */ + public function delete_order_note( $order_id, $id ) { + try { + $order_id = $this->validate_request( $order_id, $this->post_type, 'delete' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + // Validate note ID + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'Invalid order note ID', 'woocommerce' ), 400 ); + } + + // Ensure note ID is valid + $note = get_comment( $id ); + + if ( is_null( $note ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'An order note with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + // Ensure note ID is associated with given order + if ( $note->comment_post_ID != $order_id ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'The order note ID provided is not associated with the order', 'woocommerce' ), 400 ); + } + + // Force delete since trashed order notes could not be managed through comments list table + $result = wc_delete_order_note( $note->comment_ID ); + + if ( ! $result ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_order_note', __( 'This order note cannot be deleted', 'woocommerce' ), 500 ); + } + + do_action( 'woocommerce_api_delete_order_note', $note->comment_ID, $order_id, $this ); + + return array( 'message' => __( 'Permanently deleted order note', 'woocommerce' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the order refunds for an order + * + * @since 2.2 + * @param string $order_id order ID + * @param string|null $fields fields to include in response + * @return array|WP_Error + */ + public function get_order_refunds( $order_id, $fields = null ) { + + // Ensure ID is valid order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'read' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $refund_items = wc_get_orders( array( + 'type' => 'shop_order_refund', + 'parent' => $order_id, + 'limit' => -1, + 'return' => 'ids', + ) ); + $order_refunds = array(); + + foreach ( $refund_items as $refund_id ) { + $order_refunds[] = current( $this->get_order_refund( $order_id, $refund_id, $fields ) ); + } + + return array( 'order_refunds' => apply_filters( 'woocommerce_api_order_refunds_response', $order_refunds, $order_id, $fields, $refund_items, $this ) ); + } + + /** + * Get an order refund for the given order ID and ID + * + * @since 2.2 + * + * @param string $order_id order ID + * @param int $id + * @param string|null $fields fields to limit response to + * @param array $filter + * + * @return array|WP_Error + */ + public function get_order_refund( $order_id, $id, $fields = null, $filter = array() ) { + try { + // Validate order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'read' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 400 ); + } + + $order = wc_get_order( $order_id ); + $refund = wc_get_order( $id ); + + if ( ! $refund ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'An order refund with the provided ID could not be found.', 'woocommerce' ), 404 ); + } + + $line_items = array(); + + // Add line items + foreach ( $refund->get_items( 'line_item' ) as $item_id => $item ) { + $product = $item->get_product(); + $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; + $item_meta = $item->get_formatted_meta_data( $hideprefix ); + + foreach ( $item_meta as $key => $values ) { + $item_meta[ $key ]->label = $values->display_key; + unset( $item_meta[ $key ]->display_key ); + unset( $item_meta[ $key ]->display_value ); + } + + $line_items[] = array( + 'id' => $item_id, + 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item ), 2 ), + 'subtotal_tax' => wc_format_decimal( $item->get_subtotal_tax(), 2 ), + 'total' => wc_format_decimal( $order->get_line_total( $item ), 2 ), + 'total_tax' => wc_format_decimal( $order->get_line_tax( $item ), 2 ), + 'price' => wc_format_decimal( $order->get_item_total( $item ), 2 ), + 'quantity' => $item->get_quantity(), + 'tax_class' => $item->get_tax_class(), + 'name' => $item->get_name(), + 'product_id' => $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id(), + 'sku' => is_object( $product ) ? $product->get_sku() : null, + 'meta' => array_values( $item_meta ), + 'refunded_item_id' => (int) $item->get_meta( 'refunded_item_id' ), + ); + } + + $order_refund = array( + 'id' => $refund->get_id(), + 'created_at' => $this->server->format_datetime( $refund->get_date_created() ? $refund->get_date_created()->getTimestamp() : 0, false, false ), + 'amount' => wc_format_decimal( $refund->get_amount(), 2 ), + 'reason' => $refund->get_reason(), + 'line_items' => $line_items, + ); + + return array( 'order_refund' => apply_filters( 'woocommerce_api_order_refund_response', $order_refund, $id, $fields, $refund, $order_id, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new order refund for the given order + * + * @since 2.2 + * @param string $order_id order ID + * @param array $data raw request data + * @param bool $api_refund do refund using a payment gateway API + * @return WP_Error|array error or created refund response data + */ + public function create_order_refund( $order_id, $data, $api_refund = true ) { + try { + if ( ! isset( $data['order_refund'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_refund_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'order_refund' ), 400 ); + } + + $data = $data['order_refund']; + + // Permission check + if ( ! current_user_can( 'publish_shop_orders' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_order_refund', __( 'You do not have permission to create order refunds', 'woocommerce' ), 401 ); + } + + $order_id = absint( $order_id ); + + if ( empty( $order_id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_id', __( 'Order ID is invalid', 'woocommerce' ), 400 ); + } + + $data = apply_filters( 'woocommerce_api_create_order_refund_data', $data, $order_id, $this ); + + // Refund amount is required + if ( ! isset( $data['amount'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund', __( 'Refund amount is required.', 'woocommerce' ), 400 ); + } elseif ( 0 > $data['amount'] ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund', __( 'Refund amount must be positive.', 'woocommerce' ), 400 ); + } + + $data['order_id'] = $order_id; + $data['refund_id'] = 0; + + // Create the refund + $refund = wc_create_refund( $data ); + + if ( ! $refund ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + // Refund via API + if ( $api_refund ) { + if ( WC()->payment_gateways() ) { + $payment_gateways = WC()->payment_gateways->payment_gateways(); + } + + $order = wc_get_order( $order_id ); + + if ( isset( $payment_gateways[ $order->get_payment_method() ] ) && $payment_gateways[ $order->get_payment_method() ]->supports( 'refunds' ) ) { + $result = $payment_gateways[ $order->get_payment_method() ]->process_refund( $order_id, $refund->get_amount(), $refund->get_reason() ); + + if ( is_wp_error( $result ) ) { + return $result; + } elseif ( ! $result ) { + throw new WC_API_Exception( 'woocommerce_api_create_order_refund_api_failed', __( 'An error occurred while attempting to create the refund using the payment gateway API.', 'woocommerce' ), 500 ); + } + } + } + + // HTTP 201 Created + $this->server->send_status( 201 ); + + do_action( 'woocommerce_api_create_order_refund', $refund->get_id(), $order_id, $this ); + + return $this->get_order_refund( $order_id, $refund->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit an order refund + * + * @since 2.2 + * @param string $order_id order ID + * @param string $id refund ID + * @param array $data parsed request data + * @return WP_Error|array error or edited refund response data + */ + public function edit_order_refund( $order_id, $id, $data ) { + try { + if ( ! isset( $data['order_refund'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_refund_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'order_refund' ), 400 ); + } + + $data = $data['order_refund']; + + // Validate order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'edit' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + // Validate refund ID + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 400 ); + } + + // Ensure order ID is valid + $refund = get_post( $id ); + + if ( ! $refund ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'An order refund with the provided ID could not be found.', 'woocommerce' ), 404 ); + } + + // Ensure refund ID is associated with given order + if ( $refund->post_parent != $order_id ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'The order refund ID provided is not associated with the order.', 'woocommerce' ), 400 ); + } + + $data = apply_filters( 'woocommerce_api_edit_order_refund_data', $data, $refund->ID, $order_id, $this ); + + // Update reason + if ( isset( $data['reason'] ) ) { + $updated_refund = wp_update_post( array( 'ID' => $refund->ID, 'post_excerpt' => $data['reason'] ) ); + + if ( is_wp_error( $updated_refund ) ) { + return $updated_refund; + } + } + + // Update refund amount + if ( isset( $data['amount'] ) && 0 < $data['amount'] ) { + update_post_meta( $refund->ID, '_refund_amount', wc_format_decimal( $data['amount'] ) ); + } + + do_action( 'woocommerce_api_edit_order_refund', $refund->ID, $order_id, $this ); + + return $this->get_order_refund( $order_id, $refund->ID ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete order refund + * + * @since 2.2 + * @param string $order_id order ID + * @param string $id refund ID + * @return WP_Error|array error or deleted message + */ + public function delete_order_refund( $order_id, $id ) { + try { + $order_id = $this->validate_request( $order_id, $this->post_type, 'delete' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + // Validate refund ID + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 400 ); + } + + // Ensure refund ID is valid + $refund = get_post( $id ); + + if ( ! $refund ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'An order refund with the provided ID could not be found.', 'woocommerce' ), 404 ); + } + + // Ensure refund ID is associated with given order + if ( $refund->post_parent != $order_id ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'The order refund ID provided is not associated with the order.', 'woocommerce' ), 400 ); + } + + wc_delete_shop_order_transients( $order_id ); + + do_action( 'woocommerce_api_delete_order_refund', $refund->ID, $order_id, $this ); + + return $this->delete( $refund->ID, 'refund', true ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Bulk update or insert orders + * Accepts an array with orders in the formats supported by + * WC_API_Orders->create_order() and WC_API_Orders->edit_order() + * + * @since 2.4.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function bulk( $data ) { + + try { + if ( ! isset( $data['orders'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_orders_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'orders' ), 400 ); + } + + $data = $data['orders']; + $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'orders' ); + + // Limit bulk operation + if ( count( $data ) > $limit ) { + throw new WC_API_Exception( 'woocommerce_api_orders_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); + } + + $orders = array(); + + foreach ( $data as $_order ) { + $order_id = 0; + + // Try to get the order ID + if ( isset( $_order['id'] ) ) { + $order_id = intval( $_order['id'] ); + } + + // Order exists / edit order + if ( $order_id ) { + $edit = $this->edit_order( $order_id, array( 'order' => $_order ) ); + + if ( is_wp_error( $edit ) ) { + $orders[] = array( + 'id' => $order_id, + 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ), + ); + } else { + $orders[] = $edit['order']; + } + } else { + // Order don't exists / create order + $new = $this->create_order( array( 'order' => $_order ) ); + + if ( is_wp_error( $new ) ) { + $orders[] = array( + 'id' => $order_id, + 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ), + ); + } else { + $orders[] = $new['order']; + } + } + } + + return array( 'orders' => apply_filters( 'woocommerce_api_orders_bulk_response', $orders, $this ) ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-products.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-products.php new file mode 100644 index 0000000..80ee148 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-products.php @@ -0,0 +1,2312 @@ + + * GET /products//reviews + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET/POST /products + $routes[ $this->base ] = array( + array( array( $this, 'get_products' ), WC_API_Server::READABLE ), + array( array( $this, 'create_product' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /products/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_products_count' ), WC_API_Server::READABLE ), + ); + + # GET/PUT/DELETE /products/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_product' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_product' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_product' ), WC_API_Server::DELETABLE ), + ); + + # GET /products//reviews + $routes[ $this->base . '/(?P\d+)/reviews' ] = array( + array( array( $this, 'get_product_reviews' ), WC_API_Server::READABLE ), + ); + + # GET /products//orders + $routes[ $this->base . '/(?P\d+)/orders' ] = array( + array( array( $this, 'get_product_orders' ), WC_API_Server::READABLE ), + ); + + # GET /products/categories + $routes[ $this->base . '/categories' ] = array( + array( array( $this, 'get_product_categories' ), WC_API_Server::READABLE ), + ); + + # GET /products/categories/ + $routes[ $this->base . '/categories/(?P\d+)' ] = array( + array( array( $this, 'get_product_category' ), WC_API_Server::READABLE ), + ); + + # GET/POST /products/attributes + $routes[ $this->base . '/attributes' ] = array( + array( array( $this, 'get_product_attributes' ), WC_API_Server::READABLE ), + array( array( $this, 'create_product_attribute' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET/PUT/DELETE /attributes/ + $routes[ $this->base . '/attributes/(?P\d+)' ] = array( + array( array( $this, 'get_product_attribute' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_product_attribute' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_product_attribute' ), WC_API_Server::DELETABLE ), + ); + + # GET /products/sku/ + $routes[ $this->base . '/sku/(?P\w[\w\s\-]*)' ] = array( + array( array( $this, 'get_product_by_sku' ), WC_API_Server::READABLE ), + ); + + # POST|PUT /products/bulk + $routes[ $this->base . '/bulk' ] = array( + array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + return $routes; + } + + /** + * Get all products + * + * @since 2.1 + * @param string $fields + * @param string $type + * @param array $filter + * @param int $page + * @return array + */ + public function get_products( $fields = null, $type = null, $filter = array(), $page = 1 ) { + + if ( ! empty( $type ) ) { + $filter['type'] = $type; + } + + $filter['page'] = $page; + + $query = $this->query_products( $filter ); + + $products = array(); + + foreach ( $query->posts as $product_id ) { + + if ( ! $this->is_readable( $product_id ) ) { + continue; + } + + $products[] = current( $this->get_product( $product_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'products' => $products ); + } + + /** + * Get the product for the given ID + * + * @since 2.1 + * @param int $id the product ID + * @param string $fields + * @return array|WP_Error + */ + public function get_product( $id, $fields = null ) { + + $id = $this->validate_request( $id, 'product', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $product = wc_get_product( $id ); + + // add data that applies to every product type + $product_data = $this->get_product_data( $product ); + + // add variations to variable products + if ( $product->is_type( 'variable' ) && $product->has_child() ) { + $product_data['variations'] = $this->get_variation_data( $product ); + } + + // add the parent product data to an individual variation + if ( $product->is_type( 'variation' ) && $product->get_parent_id() ) { + $_product = wc_get_product( $product->get_parent_id() ); + $product_data['parent'] = $this->get_product_data( $_product ); + } + + return array( 'product' => apply_filters( 'woocommerce_api_product_response', $product_data, $product, $fields, $this->server ) ); + } + + /** + * Get the total number of products + * + * @since 2.1 + * + * @param string $type + * @param array $filter + * + * @return array|WP_Error + */ + public function get_products_count( $type = null, $filter = array() ) { + try { + if ( ! current_user_can( 'read_private_products' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_products_count', __( 'You do not have permission to read the products count', 'woocommerce' ), 401 ); + } + + if ( ! empty( $type ) ) { + $filter['type'] = $type; + } + + $query = $this->query_products( $filter ); + + return array( 'count' => (int) $query->found_posts ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new product + * + * @since 2.2 + * + * @param array $data posted data + * + * @return array|WP_Error + */ + public function create_product( $data ) { + $id = 0; + + try { + if ( ! isset( $data['product'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product' ), 400 ); + } + + $data = $data['product']; + + // Check permissions + if ( ! current_user_can( 'publish_products' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_product', __( 'You do not have permission to create products', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_product_data', $data, $this ); + + // Check if product title is specified + if ( ! isset( $data['title'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_title', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'title' ), 400 ); + } + + // Check product type + if ( ! isset( $data['type'] ) ) { + $data['type'] = 'simple'; + } + + // Set visible visibility when not sent + if ( ! isset( $data['catalog_visibility'] ) ) { + $data['catalog_visibility'] = 'visible'; + } + + // Validate the product type + if ( ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_product_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_type', sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_product_types() ) ) ), 400 ); + } + + // Enable description html tags. + $post_content = isset( $data['description'] ) ? wc_clean( $data['description'] ) : ''; + if ( $post_content && isset( $data['enable_html_description'] ) && true === $data['enable_html_description'] ) { + + $post_content = wp_filter_post_kses( $data['description'] ); + } + + // Enable short description html tags. + $post_excerpt = isset( $data['short_description'] ) ? wc_clean( $data['short_description'] ) : ''; + if ( $post_excerpt && isset( $data['enable_html_short_description'] ) && true === $data['enable_html_short_description'] ) { + $post_excerpt = wp_filter_post_kses( $data['short_description'] ); + } + + $classname = WC_Product_Factory::get_classname_from_product_type( $data['type'] ); + if ( ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + $product = new $classname(); + + $product->set_name( wc_clean( $data['title'] ) ); + $product->set_status( isset( $data['status'] ) ? wc_clean( $data['status'] ) : 'publish' ); + $product->set_short_description( isset( $data['short_description'] ) ? $post_excerpt : '' ); + $product->set_description( isset( $data['description'] ) ? $post_content : '' ); + + // Attempts to create the new product. + $product->save(); + $id = $product->get_id(); + + // Checks for an error in the product creation + if ( 0 >= $id ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_product', $id->get_error_message(), 400 ); + } + + // Check for featured/gallery images, upload it and set it + if ( isset( $data['images'] ) ) { + $product = $this->save_product_images( $product, $data['images'] ); + } + + // Save product meta fields + $product = $this->save_product_meta( $product, $data ); + $product->save(); + + // Save variations + if ( isset( $data['type'] ) && 'variable' == $data['type'] && isset( $data['variations'] ) && is_array( $data['variations'] ) ) { + $this->save_variations( $product, $data ); + } + + do_action( 'woocommerce_api_create_product', $id, $data ); + + // Clear cache/transients + wc_delete_product_transients( $id ); + + $this->server->send_status( 201 ); + + return $this->get_product( $id ); + } catch ( WC_Data_Exception $e ) { + $this->clear_product( $id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } catch ( WC_API_Exception $e ) { + $this->clear_product( $id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a product + * + * @since 2.2 + * + * @param int $id the product ID + * @param array $data + * + * @return array|WP_Error + */ + public function edit_product( $id, $data ) { + try { + if ( ! isset( $data['product'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product' ), 400 ); + } + + $data = $data['product']; + + $id = $this->validate_request( $id, 'product', 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $product = wc_get_product( $id ); + + $data = apply_filters( 'woocommerce_api_edit_product_data', $data, $this ); + + // Product title. + if ( isset( $data['title'] ) ) { + $product->set_name( wc_clean( $data['title'] ) ); + } + + // Product name (slug). + if ( isset( $data['name'] ) ) { + $product->set_slug( wc_clean( $data['name'] ) ); + } + + // Product status. + if ( isset( $data['status'] ) ) { + $product->set_status( wc_clean( $data['status'] ) ); + } + + // Product short description. + if ( isset( $data['short_description'] ) ) { + // Enable short description html tags. + $post_excerpt = ( isset( $data['enable_html_short_description'] ) && true === $data['enable_html_short_description'] ) ? wp_filter_post_kses( $data['short_description'] ) : wc_clean( $data['short_description'] ); + $product->set_short_description( $post_excerpt ); + } + + // Product description. + if ( isset( $data['description'] ) ) { + // Enable description html tags. + $post_content = ( isset( $data['enable_html_description'] ) && true === $data['enable_html_description'] ) ? wp_filter_post_kses( $data['description'] ) : wc_clean( $data['description'] ); + $product->set_description( $post_content ); + } + + // Validate the product type. + if ( isset( $data['type'] ) && ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_product_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_type', sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_product_types() ) ) ), 400 ); + } + + // Check for featured/gallery images, upload it and set it. + if ( isset( $data['images'] ) ) { + $product = $this->save_product_images( $product, $data['images'] ); + } + + // Save product meta fields. + $product = $this->save_product_meta( $product, $data ); + + // Save variations. + if ( $product->is_type( 'variable' ) ) { + if ( isset( $data['variations'] ) && is_array( $data['variations'] ) ) { + $this->save_variations( $product, $data ); + } else { + // Just sync variations. + $product = WC_Product_Variable::sync( $product, false ); + } + } + + $product->save(); + + do_action( 'woocommerce_api_edit_product', $id, $data ); + + // Clear cache/transients. + wc_delete_product_transients( $id ); + + return $this->get_product( $id ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a product. + * + * @since 2.2 + * + * @param int $id the product ID. + * @param bool $force true to permanently delete order, false to move to trash. + * + * @return array|WP_Error + */ + public function delete_product( $id, $force = false ) { + + $id = $this->validate_request( $id, 'product', 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $product = wc_get_product( $id ); + + do_action( 'woocommerce_api_delete_product', $id, $this ); + + // If we're forcing, then delete permanently. + if ( $force ) { + if ( $product->is_type( 'variable' ) ) { + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->delete( true ); + } + } + } else { + // For other product types, if the product has children, remove the relationship. + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->set_parent_id( 0 ); + $child->save(); + } + } + } + + $product->delete( true ); + $result = ! ( $product->get_id() > 0 ); + } else { + $product->delete(); + $result = 'trash' === $product->get_status(); + } + + if ( ! $result ) { + return new WP_Error( 'woocommerce_api_cannot_delete_product', sprintf( __( 'This %s cannot be deleted', 'woocommerce' ), 'product' ), array( 'status' => 500 ) ); + } + + // Delete parent product transients. + if ( $parent_id = wp_get_post_parent_id( $id ) ) { + wc_delete_product_transients( $parent_id ); + } + + if ( $force ) { + return array( 'message' => sprintf( __( 'Permanently deleted %s', 'woocommerce' ), 'product' ) ); + } else { + $this->server->send_status( '202' ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product' ) ); + } + } + + /** + * Get the reviews for a product + * + * @since 2.1 + * @param int $id the product ID to get reviews for + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_product_reviews( $id, $fields = null ) { + + $id = $this->validate_request( $id, 'product', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $comments = get_approved_comments( $id ); + $reviews = array(); + + foreach ( $comments as $comment ) { + + $reviews[] = array( + 'id' => intval( $comment->comment_ID ), + 'created_at' => $this->server->format_datetime( $comment->comment_date_gmt ), + 'review' => $comment->comment_content, + 'rating' => get_comment_meta( $comment->comment_ID, 'rating', true ), + 'reviewer_name' => $comment->comment_author, + 'reviewer_email' => $comment->comment_author_email, + 'verified' => wc_review_is_from_verified_owner( $comment->comment_ID ), + ); + } + + return array( 'product_reviews' => apply_filters( 'woocommerce_api_product_reviews_response', $reviews, $id, $fields, $comments, $this->server ) ); + } + + /** + * Get the orders for a product + * + * @since 2.4.0 + * @param int $id the product ID to get orders for + * @param string fields fields to retrieve + * @param array $filter filters to include in response + * @param string $status the order status to retrieve + * @param $page $page page to retrieve + * @return array|WP_Error + */ + public function get_product_orders( $id, $fields = null, $filter = array(), $status = null, $page = 1 ) { + global $wpdb; + + $id = $this->validate_request( $id, 'product', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $order_ids = $wpdb->get_col( $wpdb->prepare( " + SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items + WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) + AND order_item_type = 'line_item' + ", $id ) ); + + if ( empty( $order_ids ) ) { + return array( 'orders' => array() ); + } + + $filter = array_merge( $filter, array( + 'in' => implode( ',', $order_ids ), + ) ); + + $orders = WC()->api->WC_API_Orders->get_orders( $fields, $filter, $status, $page ); + + return array( 'orders' => apply_filters( 'woocommerce_api_product_orders_response', $orders['orders'], $id, $filter, $fields, $this->server ) ); + } + + /** + * Get a listing of product categories + * + * @since 2.2 + * + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_categories( $fields = null ) { + try { + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_categories', __( 'You do not have permission to read product categories', 'woocommerce' ), 401 ); + } + + $product_categories = array(); + + $terms = get_terms( 'product_cat', array( 'hide_empty' => false, 'fields' => 'ids' ) ); + + foreach ( $terms as $term_id ) { + $product_categories[] = current( $this->get_product_category( $term_id, $fields ) ); + } + + return array( 'product_categories' => apply_filters( 'woocommerce_api_product_categories_response', $product_categories, $terms, $fields, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the product category for the given ID + * + * @since 2.2 + * + * @param string $id product category term ID + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_category( $id, $fields = null ) { + try { + $id = absint( $id ); + + // Validate ID + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_category_id', __( 'Invalid product category ID', 'woocommerce' ), 400 ); + } + + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_categories', __( 'You do not have permission to read product categories', 'woocommerce' ), 401 ); + } + + $term = get_term( $id, 'product_cat' ); + + if ( is_wp_error( $term ) || is_null( $term ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_category_id', __( 'A product category with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $term_id = intval( $term->term_id ); + + // Get category display type + $display_type = get_term_meta( $term_id, 'display_type', true ); + + // Get category image + $image = ''; + if ( $image_id = get_term_meta( $term_id, 'thumbnail_id', true ) ) { + $image = wp_get_attachment_url( $image_id ); + } + + $product_category = array( + 'id' => $term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'parent' => $term->parent, + 'description' => $term->description, + 'display' => $display_type ? $display_type : 'default', + 'image' => $image ? esc_url( $image ) : '', + 'count' => intval( $term->count ), + ); + + return array( 'product_category' => apply_filters( 'woocommerce_api_product_category_response', $product_category, $id, $fields, $term, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Helper method to get product post objects + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_Query + */ + private function query_products( $args ) { + + // Set base query arguments + $query_args = array( + 'fields' => 'ids', + 'post_type' => 'product', + 'post_status' => 'publish', + 'meta_query' => array(), + ); + + if ( ! empty( $args['type'] ) ) { + + $types = explode( ',', $args['type'] ); + + $query_args['tax_query'] = array( + array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $types, + ), + ); + + unset( $args['type'] ); + } + + // Filter products by category + if ( ! empty( $args['category'] ) ) { + $query_args['product_cat'] = $args['category']; + } + + // Filter by specific sku + if ( ! empty( $args['sku'] ) ) { + if ( ! is_array( $query_args['meta_query'] ) ) { + $query_args['meta_query'] = array(); + } + + $query_args['meta_query'][] = array( + 'key' => '_sku', + 'value' => $args['sku'], + 'compare' => '=', + ); + + $query_args['post_type'] = array( 'product', 'product_variation' ); + } + + $query_args = $this->merge_query_args( $query_args, $args ); + + return new WP_Query( $query_args ); + } + + /** + * Get standard product data that applies to every product type + * + * @since 2.1 + * @param WC_Product|int $product + * @return array + */ + private function get_product_data( $product ) { + if ( is_numeric( $product ) ) { + $product = wc_get_product( $product ); + } + + if ( ! is_a( $product, 'WC_Product' ) ) { + return array(); + } + + $prices_precision = wc_get_price_decimals(); + return array( + 'title' => $product->get_name(), + 'id' => $product->get_id(), + 'created_at' => $this->server->format_datetime( $product->get_date_created(), false, true ), + 'updated_at' => $this->server->format_datetime( $product->get_date_modified(), false, true ), + 'type' => $product->get_type(), + 'status' => $product->get_status(), + 'downloadable' => $product->is_downloadable(), + 'virtual' => $product->is_virtual(), + 'permalink' => $product->get_permalink(), + 'sku' => $product->get_sku(), + 'price' => wc_format_decimal( $product->get_price(), $prices_precision ), + 'regular_price' => wc_format_decimal( $product->get_regular_price(), $prices_precision ), + 'sale_price' => $product->get_sale_price() ? wc_format_decimal( $product->get_sale_price(), $prices_precision ) : null, + 'price_html' => $product->get_price_html(), + 'taxable' => $product->is_taxable(), + 'tax_status' => $product->get_tax_status(), + 'tax_class' => $product->get_tax_class(), + 'managing_stock' => $product->managing_stock(), + 'stock_quantity' => $product->get_stock_quantity(), + 'in_stock' => $product->is_in_stock(), + 'backorders_allowed' => $product->backorders_allowed(), + 'backordered' => $product->is_on_backorder(), + 'sold_individually' => $product->is_sold_individually(), + 'purchaseable' => $product->is_purchasable(), + 'featured' => $product->is_featured(), + 'visible' => $product->is_visible(), + 'catalog_visibility' => $product->get_catalog_visibility(), + 'on_sale' => $product->is_on_sale(), + 'product_url' => $product->is_type( 'external' ) ? $product->get_product_url() : '', + 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text() : '', + 'weight' => $product->get_weight() ? wc_format_decimal( $product->get_weight(), 2 ) : null, + 'dimensions' => array( + 'length' => $product->get_length(), + 'width' => $product->get_width(), + 'height' => $product->get_height(), + 'unit' => get_option( 'woocommerce_dimension_unit' ), + ), + 'shipping_required' => $product->needs_shipping(), + 'shipping_taxable' => $product->is_shipping_taxable(), + 'shipping_class' => $product->get_shipping_class(), + 'shipping_class_id' => ( 0 !== $product->get_shipping_class_id() ) ? $product->get_shipping_class_id() : null, + 'description' => wpautop( do_shortcode( $product->get_description() ) ), + 'short_description' => apply_filters( 'woocommerce_short_description', $product->get_short_description() ), + 'reviews_allowed' => $product->get_reviews_allowed(), + 'average_rating' => wc_format_decimal( $product->get_average_rating(), 2 ), + 'rating_count' => $product->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids() ), + 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids() ), + 'parent_id' => $product->get_parent_id(), + 'categories' => wc_get_object_terms( $product->get_id(), 'product_cat', 'name' ), + 'tags' => wc_get_object_terms( $product->get_id(), 'product_tag', 'name' ), + 'images' => $this->get_images( $product ), + 'featured_src' => wp_get_attachment_url( get_post_thumbnail_id( $product->get_id() ) ), + 'attributes' => $this->get_attributes( $product ), + 'downloads' => $this->get_downloads( $product ), + 'download_limit' => $product->get_download_limit(), + 'download_expiry' => $product->get_download_expiry(), + 'download_type' => 'standard', + 'purchase_note' => wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ), + 'total_sales' => $product->get_total_sales(), + 'variations' => array(), + 'parent' => array(), + ); + } + + /** + * Get an individual variation's data + * + * @since 2.1 + * @param WC_Product $product + * @return array + */ + private function get_variation_data( $product ) { + $prices_precision = wc_get_price_decimals(); + $variations = array(); + + foreach ( $product->get_children() as $child_id ) { + + $variation = wc_get_product( $child_id ); + + if ( ! $variation || ! $variation->exists() ) { + continue; + } + + $variations[] = array( + 'id' => $variation->get_id(), + 'created_at' => $this->server->format_datetime( $variation->get_date_created(), false, true ), + 'updated_at' => $this->server->format_datetime( $variation->get_date_modified(), false, true ), + 'downloadable' => $variation->is_downloadable(), + 'virtual' => $variation->is_virtual(), + 'permalink' => $variation->get_permalink(), + 'sku' => $variation->get_sku(), + 'price' => wc_format_decimal( $variation->get_price(), $prices_precision ), + 'regular_price' => wc_format_decimal( $variation->get_regular_price(), $prices_precision ), + 'sale_price' => $variation->get_sale_price() ? wc_format_decimal( $variation->get_sale_price(), $prices_precision ) : null, + 'taxable' => $variation->is_taxable(), + 'tax_status' => $variation->get_tax_status(), + 'tax_class' => $variation->get_tax_class(), + 'managing_stock' => $variation->managing_stock(), + 'stock_quantity' => (int) $variation->get_stock_quantity(), + 'in_stock' => $variation->is_in_stock(), + 'backordered' => $variation->is_on_backorder(), + 'purchaseable' => $variation->is_purchasable(), + 'visible' => $variation->variation_is_visible(), + 'on_sale' => $variation->is_on_sale(), + 'weight' => $variation->get_weight() ? wc_format_decimal( $variation->get_weight(), 2 ) : null, + 'dimensions' => array( + 'length' => $variation->get_length(), + 'width' => $variation->get_width(), + 'height' => $variation->get_height(), + 'unit' => get_option( 'woocommerce_dimension_unit' ), + ), + 'shipping_class' => $variation->get_shipping_class(), + 'shipping_class_id' => ( 0 !== $variation->get_shipping_class_id() ) ? $variation->get_shipping_class_id() : null, + 'image' => $this->get_images( $variation ), + 'attributes' => $this->get_attributes( $variation ), + 'downloads' => $this->get_downloads( $variation ), + 'download_limit' => (int) $product->get_download_limit(), + 'download_expiry' => (int) $product->get_download_expiry(), + ); + } + + return $variations; + } + + /** + * Save default attributes. + * + * @since 3.0.0 + * @param WC_Product $product + * @param array $request + * @return WC_Product + */ + protected function save_default_attributes( $product, $request ) { + // Update default attributes options setting. + if ( isset( $request['default_attribute'] ) ) { + $request['default_attributes'] = $request['default_attribute']; + } + + if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { + $attributes = $product->get_attributes(); + $default_attributes = array(); + + foreach ( $request['default_attributes'] as $default_attr_key => $default_attr ) { + if ( ! isset( $default_attr['name'] ) ) { + continue; + } + + $taxonomy = sanitize_title( $default_attr['name'] ); + + if ( isset( $default_attr['slug'] ) ) { + $taxonomy = $this->get_attribute_taxonomy_by_slug( $default_attr['slug'] ); + } + + if ( isset( $attributes[ $taxonomy ] ) ) { + $_attribute = $attributes[ $taxonomy ]; + + if ( $_attribute['is_variation'] ) { + $value = ''; + + if ( isset( $default_attr['option'] ) ) { + if ( $_attribute['is_taxonomy'] ) { + // Don't use wc_clean as it destroys sanitized characters. + $value = sanitize_title( trim( stripslashes( $default_attr['option'] ) ) ); + } else { + $value = wc_clean( trim( stripslashes( $default_attr['option'] ) ) ); + } + } + + if ( $value ) { + $default_attributes[ $taxonomy ] = $value; + } + } + } + } + + $product->set_default_attributes( $default_attributes ); + } + + return $product; + } + + /** + * Save product meta + * + * @since 2.2 + * @param WC_Product $product + * @param array $data + * @return WC_Product + * @throws WC_API_Exception + */ + protected function save_product_meta( $product, $data ) { + global $wpdb; + + // Virtual + if ( isset( $data['virtual'] ) ) { + $product->set_virtual( $data['virtual'] ); + } + + // Tax status + if ( isset( $data['tax_status'] ) ) { + $product->set_tax_status( wc_clean( $data['tax_status'] ) ); + } + + // Tax Class + if ( isset( $data['tax_class'] ) ) { + $product->set_tax_class( wc_clean( $data['tax_class'] ) ); + } + + // Catalog Visibility + if ( isset( $data['catalog_visibility'] ) ) { + $product->set_catalog_visibility( wc_clean( $data['catalog_visibility'] ) ); + } + + // Purchase Note + if ( isset( $data['purchase_note'] ) ) { + $product->set_purchase_note( wc_clean( $data['purchase_note'] ) ); + } + + // Featured Product + if ( isset( $data['featured'] ) ) { + $product->set_featured( $data['featured'] ); + } + + // Shipping data + $product = $this->save_product_shipping_data( $product, $data ); + + // SKU + if ( isset( $data['sku'] ) ) { + $sku = $product->get_sku(); + $new_sku = wc_clean( $data['sku'] ); + + if ( '' == $new_sku ) { + $product->set_sku( '' ); + } elseif ( $new_sku !== $sku ) { + if ( ! empty( $new_sku ) ) { + $unique_sku = wc_product_has_unique_sku( $product->get_id(), $new_sku ); + if ( ! $unique_sku ) { + throw new WC_API_Exception( 'woocommerce_api_product_sku_already_exists', __( 'The SKU already exists on another product.', 'woocommerce' ), 400 ); + } else { + $product->set_sku( $new_sku ); + } + } else { + $product->set_sku( '' ); + } + } + } + + // Attributes + if ( isset( $data['attributes'] ) ) { + $attributes = array(); + + foreach ( $data['attributes'] as $attribute ) { + $is_taxonomy = 0; + $taxonomy = 0; + + if ( ! isset( $attribute['name'] ) ) { + continue; + } + + $attribute_slug = sanitize_title( $attribute['name'] ); + + if ( isset( $attribute['slug'] ) ) { + $taxonomy = $this->get_attribute_taxonomy_by_slug( $attribute['slug'] ); + $attribute_slug = sanitize_title( $attribute['slug'] ); + } + + if ( $taxonomy ) { + $is_taxonomy = 1; + } + + if ( $is_taxonomy ) { + + $attribute_id = wc_attribute_taxonomy_id_by_name( $attribute['name'] ); + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + // Update post terms + if ( taxonomy_exists( $taxonomy ) ) { + wp_set_object_terms( $product->get_id(), $values, $taxonomy ); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $taxonomy ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? absint( $attribute['position'] ) : 0 ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Array based + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + + // Text based, separate by pipe + } else { + $values = array_map( 'wc_clean', explode( WC_DELIMITER, $attribute['options'] ) ); + } + + // Custom attribute - Add attribute to array and set the values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute['name'] ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? absint( $attribute['position'] ) : 0 ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + + uasort( $attributes, 'wc_product_attribute_uasort_comparison' ); + + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ) ) ) { + + // Variable and grouped products have no prices. + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + + } else { + + // Regular Price. + if ( isset( $data['regular_price'] ) ) { + $regular_price = ( '' === $data['regular_price'] ) ? '' : $data['regular_price']; + $product->set_regular_price( $regular_price ); + } + + // Sale Price. + if ( isset( $data['sale_price'] ) ) { + $sale_price = ( '' === $data['sale_price'] ) ? '' : $data['sale_price']; + $product->set_sale_price( $sale_price ); + } + + if ( isset( $data['sale_price_dates_from'] ) ) { + $date_from = $data['sale_price_dates_from']; + } else { + $date_from = $product->get_date_on_sale_from() ? date( 'Y-m-d', $product->get_date_on_sale_from()->getTimestamp() ) : ''; + } + + if ( isset( $data['sale_price_dates_to'] ) ) { + $date_to = $data['sale_price_dates_to']; + } else { + $date_to = $product->get_date_on_sale_to() ? date( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ) : ''; + } + + if ( $date_to && ! $date_from ) { + $date_from = strtotime( 'NOW', current_time( 'timestamp', true ) ); + } + + $product->set_date_on_sale_to( $date_to ); + $product->set_date_on_sale_from( $date_from ); + + if ( $product->is_on_sale( 'edit' ) ) { + $product->set_price( $product->get_sale_price( 'edit' ) ); + } else { + $product->set_price( $product->get_regular_price( 'edit' ) ); + } + } + + // Product parent ID for groups + if ( isset( $data['parent_id'] ) ) { + $product->set_parent_id( absint( $data['parent_id'] ) ); + } + + // Sold Individually + if ( isset( $data['sold_individually'] ) ) { + $product->set_sold_individually( true === $data['sold_individually'] ? 'yes' : '' ); + } + + // Stock status + if ( isset( $data['in_stock'] ) ) { + $stock_status = ( true === $data['in_stock'] ) ? 'instock' : 'outofstock'; + } else { + $stock_status = $product->get_stock_status(); + + if ( '' === $stock_status ) { + $stock_status = 'instock'; + } + } + + // Stock Data + if ( 'yes' == get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock + if ( isset( $data['managing_stock'] ) ) { + $managing_stock = ( true === $data['managing_stock'] ) ? 'yes' : 'no'; + $product->set_manage_stock( $managing_stock ); + } else { + $managing_stock = $product->get_manage_stock() ? 'yes' : 'no'; + } + + // Backorders + if ( isset( $data['backorders'] ) ) { + if ( 'notify' == $data['backorders'] ) { + $backorders = 'notify'; + } else { + $backorders = ( true === $data['backorders'] ) ? 'yes' : 'no'; + } + + $product->set_backorders( $backorders ); + } else { + $backorders = $product->get_backorders(); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( 'yes' == $managing_stock ) { + $product->set_backorders( $backorders ); + + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity + if ( isset( $data['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $data['stock_quantity'] ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_backorders( $backorders ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells + if ( isset( $data['upsell_ids'] ) ) { + $upsells = array(); + $ids = $data['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + + $product->set_upsell_ids( $upsells ); + } else { + $product->set_upsell_ids( array() ); + } + } + + // Cross sells + if ( isset( $data['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $data['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + + $product->set_cross_sell_ids( $crosssells ); + } else { + $product->set_cross_sell_ids( array() ); + } + } + + // Product categories + if ( isset( $data['categories'] ) && is_array( $data['categories'] ) ) { + $product->set_category_ids( $data['categories'] ); + } + + // Product tags + if ( isset( $data['tags'] ) && is_array( $data['tags'] ) ) { + $product->set_tag_ids( $data['tags'] ); + } + + // Downloadable + if ( isset( $data['downloadable'] ) ) { + $is_downloadable = ( true === $data['downloadable'] ) ? 'yes' : 'no'; + $product->set_downloadable( $is_downloadable ); + } else { + $is_downloadable = $product->get_downloadable() ? 'yes' : 'no'; + } + + // Downloadable options + if ( 'yes' == $is_downloadable ) { + + // Downloadable files + if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $data['downloads'] ); + } + + // Download limit + if ( isset( $data['download_limit'] ) ) { + $product->set_download_limit( $data['download_limit'] ); + } + + // Download expiry + if ( isset( $data['download_expiry'] ) ) { + $product->set_download_expiry( $data['download_expiry'] ); + } + } + + // Product url + if ( $product->is_type( 'external' ) ) { + if ( isset( $data['product_url'] ) ) { + $product->set_product_url( $data['product_url'] ); + } + + if ( isset( $data['button_text'] ) ) { + $product->set_button_text( $data['button_text'] ); + } + } + + // Reviews allowed + if ( isset( $data['reviews_allowed'] ) ) { + $product->set_reviews_allowed( $data['reviews_allowed'] ); + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $data ); + } + + // Do action for product type + do_action( 'woocommerce_api_process_product_meta_' . $product->get_type(), $product->get_id(), $data ); + + return $product; + } + + /** + * Save variations + * + * @since 2.2 + * @param WC_Product $product + * @param array $request + * + * @return true + * + * @throws WC_API_Exception + */ + protected function save_variations( $product, $request ) { + global $wpdb; + + $id = $product->get_id(); + $attributes = $product->get_attributes(); + + foreach ( $request['variations'] as $menu_order => $data ) { + $variation_id = isset( $data['id'] ) ? absint( $data['id'] ) : 0; + $variation = new WC_Product_Variation( $variation_id ); + + // Create initial name and status. + if ( ! $variation->get_slug() ) { + /* translators: 1: variation id 2: product name */ + $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation->get_id(), $product->get_name() ) ); + $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); + } + + // Parent ID. + $variation->set_parent_id( $product->get_id() ); + + // Menu order. + $variation->set_menu_order( $menu_order ); + + // Status. + if ( isset( $data['visible'] ) ) { + $variation->set_status( false === $data['visible'] ? 'private' : 'publish' ); + } + + // SKU. + if ( isset( $data['sku'] ) ) { + $variation->set_sku( wc_clean( $data['sku'] ) ); + } + + // Thumbnail. + if ( isset( $data['image'] ) && is_array( $data['image'] ) ) { + $image = current( $data['image'] ); + if ( is_array( $image ) ) { + $image['position'] = 0; + } + + $variation = $this->save_product_images( $variation, array( $image ) ); + } + + // Virtual variation. + if ( isset( $data['virtual'] ) ) { + $variation->set_virtual( $data['virtual'] ); + } + + // Downloadable variation. + if ( isset( $data['downloadable'] ) ) { + $is_downloadable = $data['downloadable']; + $variation->set_downloadable( $is_downloadable ); + } else { + $is_downloadable = $variation->get_downloadable(); + } + + // Downloads. + if ( $is_downloadable ) { + // Downloadable files. + if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $data['downloads'] ); + } + + // Download limit. + if ( isset( $data['download_limit'] ) ) { + $variation->set_download_limit( $data['download_limit'] ); + } + + // Download expiry. + if ( isset( $data['download_expiry'] ) ) { + $variation->set_download_expiry( $data['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $data ); + + // Stock handling. + $manage_stock = (bool) $variation->get_manage_stock(); + if ( isset( $data['managing_stock'] ) ) { + $manage_stock = $data['managing_stock']; + } + $variation->set_manage_stock( $manage_stock ); + + $stock_status = $variation->get_stock_status(); + if ( isset( $data['in_stock'] ) ) { + $stock_status = true === $data['in_stock'] ? 'instock' : 'outofstock'; + } + $variation->set_stock_status( $stock_status ); + + $backorders = $variation->get_backorders(); + if ( isset( $data['backorders'] ) ) { + $backorders = $data['backorders']; + } + $variation->set_backorders( $backorders ); + + if ( $manage_stock ) { + if ( isset( $data['stock_quantity'] ) ) { + $variation->set_stock_quantity( $data['stock_quantity'] ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $data['regular_price'] ) ) { + $variation->set_regular_price( $data['regular_price'] ); + } + + // Sale Price. + if ( isset( $data['sale_price'] ) ) { + $variation->set_sale_price( $data['sale_price'] ); + } + + if ( isset( $data['sale_price_dates_from'] ) ) { + $variation->set_date_on_sale_from( $data['sale_price_dates_from'] ); + } + + if ( isset( $data['sale_price_dates_to'] ) ) { + $variation->set_date_on_sale_to( $data['sale_price_dates_to'] ); + } + + // Tax class. + if ( isset( $data['tax_class'] ) ) { + $variation->set_tax_class( $data['tax_class'] ); + } + + // Update taxonomies. + if ( isset( $data['attributes'] ) ) { + $_attributes = array(); + + foreach ( $data['attributes'] as $attribute_key => $attribute ) { + if ( ! isset( $attribute['name'] ) ) { + continue; + } + + $taxonomy = 0; + $_attribute = array(); + + if ( isset( $attribute['slug'] ) ) { + $taxonomy = $this->get_attribute_taxonomy_by_slug( $attribute['slug'] ); + } + + if ( ! $taxonomy ) { + $taxonomy = sanitize_title( $attribute['name'] ); + } + + if ( isset( $attributes[ $taxonomy ] ) ) { + $_attribute = $attributes[ $taxonomy ]; + } + + if ( isset( $_attribute['is_variation'] ) && $_attribute['is_variation'] ) { + $_attribute_key = sanitize_title( $_attribute['name'] ); + + if ( isset( $_attribute['is_taxonomy'] ) && $_attribute['is_taxonomy'] ) { + // Don't use wc_clean as it destroys sanitized characters + $_attribute_value = isset( $attribute['option'] ) ? sanitize_title( stripslashes( $attribute['option'] ) ) : ''; + } else { + $_attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + } + + $_attributes[ $_attribute_key ] = $_attribute_value; + } + } + + $variation->set_attributes( $_attributes ); + } + + $variation->save(); + + do_action( 'woocommerce_api_save_product_variation', $variation_id, $menu_order, $variation ); + } + + return true; + } + + /** + * Save product shipping data + * + * @since 2.2 + * @param WC_Product $product + * @param array $data + * @return WC_Product + */ + private function save_product_shipping_data( $product, $data ) { + if ( isset( $data['weight'] ) ) { + $product->set_weight( '' === $data['weight'] ? '' : wc_format_decimal( $data['weight'] ) ); + } + + // Product dimensions + if ( isset( $data['dimensions'] ) ) { + // Height + if ( isset( $data['dimensions']['height'] ) ) { + $product->set_height( '' === $data['dimensions']['height'] ? '' : wc_format_decimal( $data['dimensions']['height'] ) ); + } + + // Width + if ( isset( $data['dimensions']['width'] ) ) { + $product->set_width( '' === $data['dimensions']['width'] ? '' : wc_format_decimal( $data['dimensions']['width'] ) ); + } + + // Length + if ( isset( $data['dimensions']['length'] ) ) { + $product->set_length( '' === $data['dimensions']['length'] ? '' : wc_format_decimal( $data['dimensions']['length'] ) ); + } + } + + // Virtual + if ( isset( $data['virtual'] ) ) { + $virtual = ( true === $data['virtual'] ) ? 'yes' : 'no'; + + if ( 'yes' == $virtual ) { + $product->set_weight( '' ); + $product->set_height( '' ); + $product->set_length( '' ); + $product->set_width( '' ); + } + } + + // Shipping class + if ( isset( $data['shipping_class'] ) ) { + $data_store = $product->get_data_store(); + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + + return $product; + } + + /** + * Save downloadable files + * + * @since 2.2 + * @param WC_Product $product + * @param array $downloads + * @param int $deprecated Deprecated since 3.0. + * @return WC_Product + */ + private function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { + if ( $deprecated ) { + wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() does not require a variation_id anymore.' ); + } + + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( isset( $file['url'] ) ) { + $file['file'] = $file['url']; + } + + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); + $files[] = $download; + } + $product->set_downloads( $files ); + + return $product; + } + + /** + * Get attribute taxonomy by slug. + * + * @since 2.2 + * @param string $slug + * @return string|null + */ + private function get_attribute_taxonomy_by_slug( $slug ) { + $taxonomy = null; + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + foreach ( $attribute_taxonomies as $key => $tax ) { + if ( $slug == $tax->attribute_name ) { + $taxonomy = 'pa_' . $tax->attribute_name; + + break; + } + } + + return $taxonomy; + } + + /** + * Get the images for a product or product variation + * + * @since 2.1 + * @param WC_Product|WC_Product_Variation $product + * @return array + */ + private function get_images( $product ) { + $images = $attachment_ids = array(); + $product_image = $product->get_image_id(); + + // Add featured image. + if ( ! empty( $product_image ) ) { + $attachment_ids[] = $product_image; + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $position => $attachment_id ) { + + $attachment_post = get_post( $attachment_id ); + + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'created_at' => $this->server->format_datetime( $attachment_post->post_date_gmt ), + 'updated_at' => $this->server->format_datetime( $attachment_post->post_modified_gmt ), + 'src' => current( $attachment ), + 'title' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + 'position' => (int) $position, + ); + } + + // Set a placeholder image if the product has no images set. + if ( empty( $images ) ) { + + $images[] = array( + 'id' => 0, + 'created_at' => $this->server->format_datetime( time() ), // Default to now. + 'updated_at' => $this->server->format_datetime( time() ), + 'src' => wc_placeholder_img_src(), + 'title' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), + 'position' => 0, + ); + } + + return $images; + } + + /** + * Save product images + * + * @since 2.2 + * + * @param WC_Product $product + * @param array $images + * + * @return WC_Product + * @throws WC_API_Exception + */ + protected function save_product_images( $product, $images ) { + if ( is_array( $images ) ) { + $gallery = array(); + + foreach ( $images as $image ) { + if ( isset( $image['position'] ) && 0 == $image['position'] ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = $this->upload_product_image( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_upload_product_image', $upload->get_error_message(), 400 ); + } + + $attachment_id = $this->set_product_image_as_attachment( $upload, $product->get_id() ); + } + + $product->set_image_id( $attachment_id ); + } else { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = $this->upload_product_image( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_upload_product_image', $upload->get_error_message(), 400 ); + } + + $gallery[] = $this->set_product_image_as_attachment( $upload, $product->get_id() ); + } else { + $gallery[] = $attachment_id; + } + } + } + + if ( ! empty( $gallery ) ) { + $product->set_gallery_image_ids( $gallery ); + } + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Upload image from URL + * + * @since 2.2 + * + * @param string $image_url + * + * @return array + * + * @throws WC_API_Exception + */ + public function upload_product_image( $image_url ) { + $upload = wc_rest_upload_image_from_url( $image_url ); + if ( is_wp_error( $upload ) ) { + throw new WC_API_Exception( 'woocommerce_api_product_image_upload_error', $upload->get_error_message(), 400 ); + } + + return $upload; + } + + /** + * Sets product image as attachment and returns the attachment ID. + * + * @since 2.2 + * @param array $upload + * @param int $id + * @return int + */ + protected function set_product_image_as_attachment( $upload, $id ) { + $info = wp_check_filetype( $upload['file'] ); + $title = ''; + $content = ''; + + if ( $image_meta = @wp_read_image_metadata( $upload['file'] ) ) { + if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { + $title = wc_clean( $image_meta['title'] ); + } + if ( trim( $image_meta['caption'] ) ) { + $content = wc_clean( $image_meta['caption'] ); + } + } + + $attachment = array( + 'post_mime_type' => $info['type'], + 'guid' => $upload['url'], + 'post_parent' => $id, + 'post_title' => $title, + 'post_content' => $content, + ); + + $attachment_id = wp_insert_attachment( $attachment, $upload['file'], $id ); + if ( ! is_wp_error( $attachment_id ) ) { + wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $upload['file'] ) ); + } + + return $attachment_id; + } + + /** + * Get attribute options. + * + * @param int $product_id + * @param array $attribute + * @return array + */ + protected function get_attribute_options( $product_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( $product_id, $attribute['name'], array( 'fields' => 'names' ) ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation + * + * @since 2.1 + * @param WC_Product|WC_Product_Variation $product + * @return array + */ + private function get_attributes( $product ) { + + $attributes = array(); + + if ( $product->is_type( 'variation' ) ) { + + // variation attributes + foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { + + // taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_` + $attributes[] = array( + 'name' => wc_attribute_label( str_replace( 'attribute_', '', $attribute_name ) ), + 'slug' => str_replace( 'attribute_', '', wc_attribute_taxonomy_slug( $attribute_name ) ), + 'option' => $attribute, + ); + } + } else { + + foreach ( $product->get_attributes() as $attribute ) { + $attributes[] = array( + 'name' => wc_attribute_label( $attribute['name'] ), + 'slug' => wc_attribute_taxonomy_slug( $attribute['name'] ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } + } + + return $attributes; + } + + /** + * Get the downloads for a product or product variation + * + * @since 2.1 + * @param WC_Product|WC_Product_Variation $product + * @return array + */ + private function get_downloads( $product ) { + + $downloads = array(); + + if ( $product->is_downloadable() ) { + + foreach ( $product->get_downloads() as $file_id => $file ) { + + $downloads[] = array( + 'id' => $file_id, // do not cast as int as this is a hash + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get a listing of product attributes + * + * @since 2.4.0 + * + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_attributes( $fields = null ) { + try { + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_attributes', __( 'You do not have permission to read product attributes', 'woocommerce' ), 401 ); + } + + $product_attributes = array(); + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + foreach ( $attribute_taxonomies as $attribute ) { + $product_attributes[] = array( + 'id' => intval( $attribute->attribute_id ), + 'name' => $attribute->attribute_label, + 'slug' => wc_attribute_taxonomy_name( $attribute->attribute_name ), + 'type' => $attribute->attribute_type, + 'order_by' => $attribute->attribute_orderby, + 'has_archives' => (bool) $attribute->attribute_public, + ); + } + + return array( 'product_attributes' => apply_filters( 'woocommerce_api_product_attributes_response', $product_attributes, $attribute_taxonomies, $fields, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the product attribute for the given ID + * + * @since 2.4.0 + * + * @param string $id product attribute term ID + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_attribute( $id, $fields = null ) { + global $wpdb; + + try { + $id = absint( $id ); + + // Validate ID + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'Invalid product attribute ID', 'woocommerce' ), 400 ); + } + + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_categories', __( 'You do not have permission to read product attributes', 'woocommerce' ), 401 ); + } + + $attribute = $wpdb->get_row( $wpdb->prepare( " + SELECT * + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) ); + + if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $product_attribute = array( + 'id' => intval( $attribute->attribute_id ), + 'name' => $attribute->attribute_label, + 'slug' => wc_attribute_taxonomy_name( $attribute->attribute_name ), + 'type' => $attribute->attribute_type, + 'order_by' => $attribute->attribute_orderby, + 'has_archives' => (bool) $attribute->attribute_public, + ); + + return array( 'product_attribute' => apply_filters( 'woocommerce_api_product_attribute_response', $product_attribute, $id, $fields, $attribute, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Validate attribute data. + * + * @since 2.4.0 + * @param string $name + * @param string $slug + * @param string $type + * @param string $order_by + * @param bool $new_data + * @return bool + * @throws WC_API_Exception + */ + protected function validate_attribute_data( $name, $slug, $type, $order_by, $new_data = true ) { + if ( empty( $name ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_attribute_name', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'name' ), 400 ); + } + + if ( strlen( $slug ) >= 28 ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), 400 ); + } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), 400 ); + } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), 400 ); + } + + // Validate the attribute type + if ( ! in_array( wc_clean( $type ), array_keys( wc_get_attribute_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_type', sprintf( __( 'Invalid product attribute type - the product attribute type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_attribute_types() ) ) ), 400 ); + } + + // Validate the attribute order by + if ( ! in_array( wc_clean( $order_by ), array( 'menu_order', 'name', 'name_num', 'id' ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_order_by', sprintf( __( 'Invalid product attribute order_by type - the product attribute order_by type must be any of these: %s', 'woocommerce' ), implode( ', ', array( 'menu_order', 'name', 'name_num', 'id' ) ) ), 400 ); + } + + return true; + } + + /** + * Create a new product attribute + * + * @since 2.4.0 + * + * @param array $data posted data + * + * @return array|WP_Error + */ + public function create_product_attribute( $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_attribute'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_attribute_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product_attribute' ), 400 ); + } + + $data = $data['product_attribute']; + + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_product_attribute', __( 'You do not have permission to create product attributes', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_product_attribute_data', $data, $this ); + + if ( ! isset( $data['name'] ) ) { + $data['name'] = ''; + } + + // Set the attribute slug + if ( ! isset( $data['slug'] ) ) { + $data['slug'] = wc_sanitize_taxonomy_name( stripslashes( $data['name'] ) ); + } else { + $data['slug'] = preg_replace( '/^pa\_/', '', wc_sanitize_taxonomy_name( stripslashes( $data['slug'] ) ) ); + } + + // Set attribute type when not sent + if ( ! isset( $data['type'] ) ) { + $data['type'] = 'select'; + } + + // Set order by when not sent + if ( ! isset( $data['order_by'] ) ) { + $data['order_by'] = 'menu_order'; + } + + // Validate the attribute data + $this->validate_attribute_data( $data['name'], $data['slug'], $data['type'], $data['order_by'], true ); + + $insert = $wpdb->insert( + $wpdb->prefix . 'woocommerce_attribute_taxonomies', + array( + 'attribute_label' => $data['name'], + 'attribute_name' => $data['slug'], + 'attribute_type' => $data['type'], + 'attribute_orderby' => $data['order_by'], + 'attribute_public' => isset( $data['has_archives'] ) && true === $data['has_archives'] ? 1 : 0, + ), + array( '%s', '%s', '%s', '%s', '%d' ) + ); + + // Checks for an error in the product creation + if ( is_wp_error( $insert ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_product_attribute', $insert->get_error_message(), 400 ); + } + + $id = $wpdb->insert_id; + + do_action( 'woocommerce_api_create_product_attribute', $id, $data ); + + // Clear transients + delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); + + $this->server->send_status( 201 ); + + return $this->get_product_attribute( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a product attribute + * + * @since 2.4.0 + * + * @param int $id the attribute ID + * @param array $data + * + * @return array|WP_Error + */ + public function edit_product_attribute( $id, $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_attribute'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_attribute_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product_attribute' ), 400 ); + } + + $id = absint( $id ); + $data = $data['product_attribute']; + + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_product_attribute', __( 'You do not have permission to edit product attributes', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_edit_product_attribute_data', $data, $this ); + $attribute = $this->get_product_attribute( $id ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $attribute_name = isset( $data['name'] ) ? $data['name'] : $attribute['product_attribute']['name']; + $attribute_type = isset( $data['type'] ) ? $data['type'] : $attribute['product_attribute']['type']; + $attribute_order_by = isset( $data['order_by'] ) ? $data['order_by'] : $attribute['product_attribute']['order_by']; + + if ( isset( $data['slug'] ) ) { + $attribute_slug = wc_sanitize_taxonomy_name( stripslashes( $data['slug'] ) ); + } else { + $attribute_slug = $attribute['product_attribute']['slug']; + } + $attribute_slug = preg_replace( '/^pa\_/', '', $attribute_slug ); + + if ( isset( $data['has_archives'] ) ) { + $attribute_public = true === $data['has_archives'] ? 1 : 0; + } else { + $attribute_public = $attribute['product_attribute']['has_archives']; + } + + // Validate the attribute data + $this->validate_attribute_data( $attribute_name, $attribute_slug, $attribute_type, $attribute_order_by, false ); + + $update = $wpdb->update( + $wpdb->prefix . 'woocommerce_attribute_taxonomies', + array( + 'attribute_label' => $attribute_name, + 'attribute_name' => $attribute_slug, + 'attribute_type' => $attribute_type, + 'attribute_orderby' => $attribute_order_by, + 'attribute_public' => $attribute_public, + ), + array( 'attribute_id' => $id ), + array( '%s', '%s', '%s', '%s', '%d' ), + array( '%d' ) + ); + + // Checks for an error in the product creation + if ( false === $update ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_edit_product_attribute', __( 'Could not edit the attribute', 'woocommerce' ), 400 ); + } + + do_action( 'woocommerce_api_edit_product_attribute', $id, $data ); + + // Clear transients + delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); + + return $this->get_product_attribute( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a product attribute + * + * @since 2.4.0 + * + * @param int $id the product attribute ID + * + * @return array|WP_Error + */ + public function delete_product_attribute( $id ) { + global $wpdb; + + try { + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_product_attribute', __( 'You do not have permission to delete product attributes', 'woocommerce' ), 401 ); + } + + $id = absint( $id ); + + $attribute_name = $wpdb->get_var( $wpdb->prepare( " + SELECT attribute_name + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) ); + + if ( is_null( $attribute_name ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $deleted = $wpdb->delete( + $wpdb->prefix . 'woocommerce_attribute_taxonomies', + array( 'attribute_id' => $id ), + array( '%d' ) + ); + + if ( false === $deleted ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_product_attribute', __( 'Could not delete the attribute', 'woocommerce' ), 401 ); + } + + $taxonomy = wc_attribute_taxonomy_name( $attribute_name ); + + if ( taxonomy_exists( $taxonomy ) ) { + $terms = get_terms( $taxonomy, 'orderby=name&hide_empty=0' ); + foreach ( $terms as $term ) { + wp_delete_term( $term->term_id, $taxonomy ); + } + } + + do_action( 'woocommerce_attribute_deleted', $id, $attribute_name, $taxonomy ); + do_action( 'woocommerce_api_delete_product_attribute', $id, $this ); + + // Clear transients + delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product_attribute' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get product by SKU + * + * @deprecated 2.4.0 + * + * @since 2.3.0 + * + * @param int $sku the product SKU + * @param string $fields + * + * @return array|WP_Error + */ + public function get_product_by_sku( $sku, $fields = null ) { + try { + $id = wc_get_product_id_by_sku( $sku ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_sku', __( 'Invalid product SKU', 'woocommerce' ), 404 ); + } + + return $this->get_product( $id, $fields ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Clear product + * + * @param int $product_id + */ + protected function clear_product( $product_id ) { + if ( ! is_numeric( $product_id ) || 0 >= $product_id ) { + return; + } + + // Delete product attachments + $attachments = get_children( array( + 'post_parent' => $product_id, + 'post_status' => 'any', + 'post_type' => 'attachment', + ) ); + + foreach ( (array) $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + // Delete product + $product = wc_get_product( $product_id ); + $product->delete(); + } + + /** + * Bulk update or insert products + * Accepts an array with products in the formats supported by + * WC_API_Products->create_product() and WC_API_Products->edit_product() + * + * @since 2.4.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function bulk( $data ) { + + try { + if ( ! isset( $data['products'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_products_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'products' ), 400 ); + } + + $data = $data['products']; + $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'products' ); + + // Limit bulk operation + if ( count( $data ) > $limit ) { + throw new WC_API_Exception( 'woocommerce_api_products_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); + } + + $products = array(); + + foreach ( $data as $_product ) { + $product_id = 0; + $product_sku = ''; + + // Try to get the product ID + if ( isset( $_product['id'] ) ) { + $product_id = intval( $_product['id'] ); + } + + if ( ! $product_id && isset( $_product['sku'] ) ) { + $product_sku = wc_clean( $_product['sku'] ); + $product_id = wc_get_product_id_by_sku( $product_sku ); + } + + if ( $product_id ) { + + // Product exists / edit product + $edit = $this->edit_product( $product_id, array( 'product' => $_product ) ); + + if ( is_wp_error( $edit ) ) { + $products[] = array( + 'id' => $product_id, + 'sku' => $product_sku, + 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ), + ); + } else { + $products[] = $edit['product']; + } + } else { + + // Product don't exists / create product + $new = $this->create_product( array( 'product' => $_product ) ); + + if ( is_wp_error( $new ) ) { + $products[] = array( + 'id' => $product_id, + 'sku' => $product_sku, + 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ), + ); + } else { + $products[] = $new['product']; + } + } + } + + return array( 'products' => apply_filters( 'woocommerce_api_products_bulk_response', $products, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-reports.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-reports.php new file mode 100644 index 0000000..6a22e7a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-reports.php @@ -0,0 +1,329 @@ +base ] = array( + array( array( $this, 'get_reports' ), WC_API_Server::READABLE ), + ); + + # GET /reports/sales + $routes[ $this->base . '/sales' ] = array( + array( array( $this, 'get_sales_report' ), WC_API_Server::READABLE ), + ); + + # GET /reports/sales/top_sellers + $routes[ $this->base . '/sales/top_sellers' ] = array( + array( array( $this, 'get_top_sellers_report' ), WC_API_Server::READABLE ), + ); + + return $routes; + } + + /** + * Get a simple listing of available reports + * + * @since 2.1 + * @return array + */ + public function get_reports() { + return array( 'reports' => array( 'sales', 'sales/top_sellers' ) ); + } + + /** + * Get the sales report + * + * @since 2.1 + * @param string $fields fields to include in response + * @param array $filter date filtering + * @return array|WP_Error + */ + public function get_sales_report( $fields = null, $filter = array() ) { + + // check user permissions + $check = $this->validate_request(); + + // check for WP_Error + if ( is_wp_error( $check ) ) { + return $check; + } + + // set date filtering + $this->setup_report( $filter ); + + // new customers + $users_query = new WP_User_Query( + array( + 'fields' => array( 'user_registered' ), + 'role' => 'customer', + ) + ); + + $customers = $users_query->get_results(); + + foreach ( $customers as $key => $customer ) { + if ( strtotime( $customer->user_registered ) < $this->report->start_date || strtotime( $customer->user_registered ) > $this->report->end_date ) { + unset( $customers[ $key ] ); + } + } + + $total_customers = count( $customers ); + $report_data = $this->report->get_report_data(); + $period_totals = array(); + + // setup period totals by ensuring each period in the interval has data + for ( $i = 0; $i <= $this->report->chart_interval; $i ++ ) { + + switch ( $this->report->chart_groupby ) { + case 'day' : + $time = date( 'Y-m-d', strtotime( "+{$i} DAY", $this->report->start_date ) ); + break; + default : + $time = date( 'Y-m', strtotime( "+{$i} MONTH", $this->report->start_date ) ); + break; + } + + // set the customer signups for each period + $customer_count = 0; + foreach ( $customers as $customer ) { + if ( date( ( 'day' == $this->report->chart_groupby ) ? 'Y-m-d' : 'Y-m', strtotime( $customer->user_registered ) ) == $time ) { + $customer_count++; + } + } + + $period_totals[ $time ] = array( + 'sales' => wc_format_decimal( 0.00, 2 ), + 'orders' => 0, + 'items' => 0, + 'tax' => wc_format_decimal( 0.00, 2 ), + 'shipping' => wc_format_decimal( 0.00, 2 ), + 'discount' => wc_format_decimal( 0.00, 2 ), + 'customers' => $customer_count, + ); + } + + // add total sales, total order count, total tax and total shipping for each period + foreach ( $report_data->orders as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['sales'] = wc_format_decimal( $order->total_sales, 2 ); + $period_totals[ $time ]['tax'] = wc_format_decimal( $order->total_tax + $order->total_shipping_tax, 2 ); + $period_totals[ $time ]['shipping'] = wc_format_decimal( $order->total_shipping, 2 ); + } + + foreach ( $report_data->order_counts as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['orders'] = (int) $order->count; + } + + // add total order items for each period + foreach ( $report_data->order_items as $order_item ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['items'] = (int) $order_item->order_item_count; + } + + // add total discount for each period + foreach ( $report_data->coupons as $discount ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['discount'] = wc_format_decimal( $discount->discount_amount, 2 ); + } + + $sales_data = array( + 'total_sales' => $report_data->total_sales, + 'net_sales' => $report_data->net_sales, + 'average_sales' => $report_data->average_sales, + 'total_orders' => $report_data->total_orders, + 'total_items' => $report_data->total_items, + 'total_tax' => wc_format_decimal( $report_data->total_tax + $report_data->total_shipping_tax, 2 ), + 'total_shipping' => $report_data->total_shipping, + 'total_refunds' => $report_data->total_refunds, + 'total_discount' => $report_data->total_coupons, + 'totals_grouped_by' => $this->report->chart_groupby, + 'totals' => $period_totals, + 'total_customers' => $total_customers, + ); + + return array( 'sales' => apply_filters( 'woocommerce_api_report_response', $sales_data, $this->report, $fields, $this->server ) ); + } + + /** + * Get the top sellers report + * + * @since 2.1 + * @param string $fields fields to include in response + * @param array $filter date filtering + * @return array|WP_Error + */ + public function get_top_sellers_report( $fields = null, $filter = array() ) { + + // check user permissions + $check = $this->validate_request(); + + if ( is_wp_error( $check ) ) { + return $check; + } + + // set date filtering + $this->setup_report( $filter ); + + $top_sellers = $this->report->get_order_report_data( array( + 'data' => array( + '_product_id' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => '', + 'name' => 'product_id', + ), + '_qty' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => 'SUM', + 'name' => 'order_item_qty', + ), + ), + 'order_by' => 'order_item_qty DESC', + 'group_by' => 'product_id', + 'limit' => isset( $filter['limit'] ) ? absint( $filter['limit'] ) : 12, + 'query_type' => 'get_results', + 'filter_range' => true, + ) ); + + $top_sellers_data = array(); + + foreach ( $top_sellers as $top_seller ) { + + $product = wc_get_product( $top_seller->product_id ); + + if ( $product ) { + $top_sellers_data[] = array( + 'title' => $product->get_name(), + 'product_id' => $top_seller->product_id, + 'quantity' => $top_seller->order_item_qty, + ); + } + } + + return array( 'top_sellers' => apply_filters( 'woocommerce_api_report_response', $top_sellers_data, $this->report, $fields, $this->server ) ); + } + + /** + * Setup the report object and parse any date filtering + * + * @since 2.1 + * @param array $filter date filtering + */ + private function setup_report( $filter ) { + + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' ); + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-report-sales-by-date.php' ); + + $this->report = new WC_Report_Sales_By_Date(); + + if ( empty( $filter['period'] ) ) { + + // custom date range + $filter['period'] = 'custom'; + + if ( ! empty( $filter['date_min'] ) || ! empty( $filter['date_max'] ) ) { + + // overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges + $_GET['start_date'] = $this->server->parse_datetime( $filter['date_min'] ); + $_GET['end_date'] = isset( $filter['date_max'] ) ? $this->server->parse_datetime( $filter['date_max'] ) : null; + + } else { + + // default custom range to today + $_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) ); + } + } else { + + // ensure period is valid + if ( ! in_array( $filter['period'], array( 'week', 'month', 'last_month', 'year' ) ) ) { + $filter['period'] = 'week'; + } + + // TODO: change WC_Admin_Report class to use "week" instead, as it's more consistent with other periods + // allow "week" for period instead of "7day" + if ( 'week' === $filter['period'] ) { + $filter['period'] = '7day'; + } + } + + $this->report->calculate_current_range( $filter['period'] ); + } + + /** + * Verify that the current user has permission to view reports + * + * @since 2.1 + * @see WC_API_Resource::validate_request() + * + * @param null $id unused + * @param null $type unused + * @param null $context unused + * + * @return bool|WP_Error + */ + protected function validate_request( $id = null, $type = null, $context = null ) { + + if ( ! current_user_can( 'view_woocommerce_reports' ) ) { + + return new WP_Error( 'woocommerce_api_user_cannot_read_report', __( 'You do not have permission to read this report', 'woocommerce' ), array( 'status' => 401 ) ); + + } else { + + return true; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-resource.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-resource.php new file mode 100644 index 0000000..0bfa3f0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-resource.php @@ -0,0 +1,466 @@ +server = $server; + + // automatically register routes for sub-classes + add_filter( 'woocommerce_api_endpoints', array( $this, 'register_routes' ) ); + + // maybe add meta to top-level resource responses + foreach ( array( 'order', 'coupon', 'customer', 'product', 'report' ) as $resource ) { + add_filter( "woocommerce_api_{$resource}_response", array( $this, 'maybe_add_meta' ), 15, 2 ); + } + + $response_names = array( + 'order', + 'coupon', + 'customer', + 'product', + 'report', + 'customer_orders', + 'customer_downloads', + 'order_note', + 'order_refund', + 'product_reviews', + 'product_category', + ); + + foreach ( $response_names as $name ) { + + /** + * Remove fields from responses when requests specify certain fields + * note these are hooked at a later priority so data added via + * filters (e.g. customer data to the order response) still has the + * fields filtered properly + */ + add_filter( "woocommerce_api_{$name}_response", array( $this, 'filter_response_fields' ), 20, 3 ); + } + } + + /** + * Validate the request by checking: + * + * 1) the ID is a valid integer + * 2) the ID returns a valid post object and matches the provided post type + * 3) the current user has the proper permissions to read/edit/delete the post + * + * @since 2.1 + * @param string|int $id the post ID + * @param string $type the post type, either `shop_order`, `shop_coupon`, or `product` + * @param string $context the context of the request, either `read`, `edit` or `delete` + * @return int|WP_Error valid post ID or WP_Error if any of the checks fails + */ + protected function validate_request( $id, $type, $context ) { + + if ( 'shop_order' === $type || 'shop_coupon' === $type || 'shop_webhook' === $type ) { + $resource_name = str_replace( 'shop_', '', $type ); + } else { + $resource_name = $type; + } + + $id = absint( $id ); + + // Validate ID + if ( empty( $id ) ) { + return new WP_Error( "woocommerce_api_invalid_{$resource_name}_id", sprintf( __( 'Invalid %s ID', 'woocommerce' ), $type ), array( 'status' => 404 ) ); + } + + // Only custom post types have per-post type/permission checks + if ( 'customer' !== $type ) { + + $post = get_post( $id ); + + if ( null === $post ) { + return new WP_Error( "woocommerce_api_no_{$resource_name}_found", sprintf( __( 'No %1$s found with the ID equal to %2$s', 'woocommerce' ), $resource_name, $id ), array( 'status' => 404 ) ); + } + + // For checking permissions, product variations are the same as the product post type + $post_type = ( 'product_variation' === $post->post_type ) ? 'product' : $post->post_type; + + // Validate post type + if ( $type !== $post_type ) { + return new WP_Error( "woocommerce_api_invalid_{$resource_name}", sprintf( __( 'Invalid %s', 'woocommerce' ), $resource_name ), array( 'status' => 404 ) ); + } + + // Validate permissions + switch ( $context ) { + + case 'read': + if ( ! $this->is_readable( $post ) ) { + return new WP_Error( "woocommerce_api_user_cannot_read_{$resource_name}", sprintf( __( 'You do not have permission to read this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) ); + } + break; + + case 'edit': + if ( ! $this->is_editable( $post ) ) { + return new WP_Error( "woocommerce_api_user_cannot_edit_{$resource_name}", sprintf( __( 'You do not have permission to edit this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) ); + } + break; + + case 'delete': + if ( ! $this->is_deletable( $post ) ) { + return new WP_Error( "woocommerce_api_user_cannot_delete_{$resource_name}", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) ); + } + break; + } + } + + return $id; + } + + /** + * Add common request arguments to argument list before WP_Query is run + * + * @since 2.1 + * @param array $base_args required arguments for the query (e.g. `post_type`, etc) + * @param array $request_args arguments provided in the request + * @return array + */ + protected function merge_query_args( $base_args, $request_args ) { + + $args = array(); + + // date + if ( ! empty( $request_args['created_at_min'] ) || ! empty( $request_args['created_at_max'] ) || ! empty( $request_args['updated_at_min'] ) || ! empty( $request_args['updated_at_max'] ) ) { + + $args['date_query'] = array(); + + // resources created after specified date + if ( ! empty( $request_args['created_at_min'] ) ) { + $args['date_query'][] = array( 'column' => 'post_date_gmt', 'after' => $this->server->parse_datetime( $request_args['created_at_min'] ), 'inclusive' => true ); + } + + // resources created before specified date + if ( ! empty( $request_args['created_at_max'] ) ) { + $args['date_query'][] = array( 'column' => 'post_date_gmt', 'before' => $this->server->parse_datetime( $request_args['created_at_max'] ), 'inclusive' => true ); + } + + // resources updated after specified date + if ( ! empty( $request_args['updated_at_min'] ) ) { + $args['date_query'][] = array( 'column' => 'post_modified_gmt', 'after' => $this->server->parse_datetime( $request_args['updated_at_min'] ), 'inclusive' => true ); + } + + // resources updated before specified date + if ( ! empty( $request_args['updated_at_max'] ) ) { + $args['date_query'][] = array( 'column' => 'post_modified_gmt', 'before' => $this->server->parse_datetime( $request_args['updated_at_max'] ), 'inclusive' => true ); + } + } + + // search + if ( ! empty( $request_args['q'] ) ) { + $args['s'] = $request_args['q']; + } + + // resources per response + if ( ! empty( $request_args['limit'] ) ) { + $args['posts_per_page'] = $request_args['limit']; + } + + // resource offset + if ( ! empty( $request_args['offset'] ) ) { + $args['offset'] = $request_args['offset']; + } + + // order (ASC or DESC, ASC by default) + if ( ! empty( $request_args['order'] ) ) { + $args['order'] = $request_args['order']; + } + + // orderby + if ( ! empty( $request_args['orderby'] ) ) { + $args['orderby'] = $request_args['orderby']; + + // allow sorting by meta value + if ( ! empty( $request_args['orderby_meta_key'] ) ) { + $args['meta_key'] = $request_args['orderby_meta_key']; + } + } + + // allow post status change + if ( ! empty( $request_args['post_status'] ) ) { + $args['post_status'] = $request_args['post_status']; + unset( $request_args['post_status'] ); + } + + // filter by a list of post id + if ( ! empty( $request_args['in'] ) ) { + $args['post__in'] = explode( ',', $request_args['in'] ); + unset( $request_args['in'] ); + } + + // filter by a list of post id + if ( ! empty( $request_args['in'] ) ) { + $args['post__in'] = explode( ',', $request_args['in'] ); + unset( $request_args['in'] ); + } + + // resource page + $args['paged'] = ( isset( $request_args['page'] ) ) ? absint( $request_args['page'] ) : 1; + + $args = apply_filters( 'woocommerce_api_query_args', $args, $request_args ); + + return array_merge( $base_args, $args ); + } + + /** + * Add meta to resources when requested by the client. Meta is added as a top-level + * `_meta` attribute (e.g. `order_meta`) as a list of key/value pairs + * + * @since 2.1 + * @param array $data the resource data + * @param object $resource the resource object (e.g WC_Order) + * @return mixed + */ + public function maybe_add_meta( $data, $resource ) { + + if ( isset( $this->server->params['GET']['filter']['meta'] ) && 'true' === $this->server->params['GET']['filter']['meta'] && is_object( $resource ) ) { + + // don't attempt to add meta more than once + if ( preg_grep( '/[a-z]+_meta/', array_keys( $data ) ) ) { + return $data; + } + + // define the top-level property name for the meta + switch ( get_class( $resource ) ) { + + case 'WC_Order': + $meta_name = 'order_meta'; + break; + + case 'WC_Coupon': + $meta_name = 'coupon_meta'; + break; + + case 'WP_User': + $meta_name = 'customer_meta'; + break; + + default: + $meta_name = 'product_meta'; + break; + } + + if ( is_a( $resource, 'WP_User' ) ) { + + // customer meta + $meta = (array) get_user_meta( $resource->ID ); + + } else { + + // coupon/order/product meta + $meta = (array) get_post_meta( $resource->get_id() ); + } + + foreach ( $meta as $meta_key => $meta_value ) { + + // don't add hidden meta by default + if ( ! is_protected_meta( $meta_key ) ) { + $data[ $meta_name ][ $meta_key ] = maybe_unserialize( $meta_value[0] ); + } + } + } + + return $data; + } + + /** + * Restrict the fields included in the response if the request specified certain only certain fields should be returned + * + * @since 2.1 + * @param array $data the response data + * @param object $resource the object that provided the response data, e.g. WC_Coupon or WC_Order + * @param array|string the requested list of fields to include in the response + * @return array response data + */ + public function filter_response_fields( $data, $resource, $fields ) { + + if ( ! is_array( $data ) || empty( $fields ) ) { + return $data; + } + + $fields = explode( ',', $fields ); + $sub_fields = array(); + + // get sub fields + foreach ( $fields as $field ) { + + if ( false !== strpos( $field, '.' ) ) { + + list( $name, $value ) = explode( '.', $field ); + + $sub_fields[ $name ] = $value; + } + } + + // iterate through top-level fields + foreach ( $data as $data_field => $data_value ) { + + // if a field has sub-fields and the top-level field has sub-fields to filter + if ( is_array( $data_value ) && in_array( $data_field, array_keys( $sub_fields ) ) ) { + + // iterate through each sub-field + foreach ( $data_value as $sub_field => $sub_field_value ) { + + // remove non-matching sub-fields + if ( ! in_array( $sub_field, $sub_fields ) ) { + unset( $data[ $data_field ][ $sub_field ] ); + } + } + } else { + + // remove non-matching top-level fields + if ( ! in_array( $data_field, $fields ) ) { + unset( $data[ $data_field ] ); + } + } + } + + return $data; + } + + /** + * Delete a given resource + * + * @since 2.1 + * @param int $id the resource ID + * @param string $type the resource post type, or `customer` + * @param bool $force true to permanently delete resource, false to move to trash (not supported for `customer`) + * @return array|WP_Error + */ + protected function delete( $id, $type, $force = false ) { + + if ( 'shop_order' === $type || 'shop_coupon' === $type ) { + $resource_name = str_replace( 'shop_', '', $type ); + } else { + $resource_name = $type; + } + + if ( 'customer' === $type ) { + + $result = wp_delete_user( $id ); + + if ( $result ) { + return array( 'message' => __( 'Permanently deleted customer', 'woocommerce' ) ); + } else { + return new WP_Error( 'woocommerce_api_cannot_delete_customer', __( 'The customer cannot be deleted', 'woocommerce' ), array( 'status' => 500 ) ); + } + } else { + + // delete order/coupon/webhook + $result = ( $force ) ? wp_delete_post( $id, true ) : wp_trash_post( $id ); + + if ( ! $result ) { + return new WP_Error( "woocommerce_api_cannot_delete_{$resource_name}", sprintf( __( 'This %s cannot be deleted', 'woocommerce' ), $resource_name ), array( 'status' => 500 ) ); + } + + if ( $force ) { + return array( 'message' => sprintf( __( 'Permanently deleted %s', 'woocommerce' ), $resource_name ) ); + } else { + $this->server->send_status( '202' ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), $resource_name ) ); + } + } + } + + + /** + * Checks if the given post is readable by the current user + * + * @since 2.1 + * @see WC_API_Resource::check_permission() + * @param WP_Post|int $post + * @return bool + */ + protected function is_readable( $post ) { + + return $this->check_permission( $post, 'read' ); + } + + /** + * Checks if the given post is editable by the current user + * + * @since 2.1 + * @see WC_API_Resource::check_permission() + * @param WP_Post|int $post + * @return bool + */ + protected function is_editable( $post ) { + + return $this->check_permission( $post, 'edit' ); + + } + + /** + * Checks if the given post is deletable by the current user + * + * @since 2.1 + * @see WC_API_Resource::check_permission() + * @param WP_Post|int $post + * @return bool + */ + protected function is_deletable( $post ) { + + return $this->check_permission( $post, 'delete' ); + } + + /** + * Checks the permissions for the current user given a post and context + * + * @since 2.1 + * @param WP_Post|int $post + * @param string $context the type of permission to check, either `read`, `write`, or `delete` + * @return bool true if the current user has the permissions to perform the context on the post + */ + private function check_permission( $post, $context ) { + + if ( ! is_a( $post, 'WP_Post' ) ) { + $post = get_post( $post ); + } + + if ( is_null( $post ) ) { + return false; + } + + $post_type = get_post_type_object( $post->post_type ); + + if ( 'read' === $context ) { + return ( 'revision' !== $post->post_type && current_user_can( $post_type->cap->read_private_posts, $post->ID ) ); + } elseif ( 'edit' === $context ) { + return current_user_can( $post_type->cap->edit_post, $post->ID ); + } elseif ( 'delete' === $context ) { + return current_user_can( $post_type->cap->delete_post, $post->ID ); + } else { + return false; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-server.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-server.php new file mode 100644 index 0000000..1ed69cc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-server.php @@ -0,0 +1,775 @@ + self::METHOD_GET, + 'GET' => self::METHOD_GET, + 'POST' => self::METHOD_POST, + 'PUT' => self::METHOD_PUT, + 'PATCH' => self::METHOD_PATCH, + 'DELETE' => self::METHOD_DELETE, + ); + + /** + * Requested path (relative to the API root, wp-json.php) + * + * @var string + */ + public $path = ''; + + /** + * Requested method (GET/HEAD/POST/PUT/PATCH/DELETE) + * + * @var string + */ + public $method = 'HEAD'; + + /** + * Request parameters + * + * This acts as an abstraction of the superglobals + * (GET => $_GET, POST => $_POST) + * + * @var array + */ + public $params = array( 'GET' => array(), 'POST' => array() ); + + /** + * Request headers + * + * @var array + */ + public $headers = array(); + + /** + * Request files (matches $_FILES) + * + * @var array + */ + public $files = array(); + + /** + * Request/Response handler, either JSON by default + * or XML if requested by client + * + * @var WC_API_Handler + */ + public $handler; + + + /** + * Setup class and set request/response handler + * + * @since 2.1 + * @param $path + */ + public function __construct( $path ) { + + if ( empty( $path ) ) { + if ( isset( $_SERVER['PATH_INFO'] ) ) { + $path = $_SERVER['PATH_INFO']; + } else { + $path = '/'; + } + } + + $this->path = $path; + $this->method = $_SERVER['REQUEST_METHOD']; + $this->params['GET'] = $_GET; + $this->params['POST'] = $_POST; + $this->headers = $this->get_headers( $_SERVER ); + $this->files = $_FILES; + + // Compatibility for clients that can't use PUT/PATCH/DELETE + if ( isset( $_GET['_method'] ) ) { + $this->method = strtoupper( $_GET['_method'] ); + } elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) { + $this->method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']; + } + + // load response handler + $handler_class = apply_filters( 'woocommerce_api_default_response_handler', 'WC_API_JSON_Handler', $this->path, $this ); + + $this->handler = new $handler_class(); + } + + /** + * Check authentication for the request + * + * @since 2.1 + * @return WP_User|WP_Error WP_User object indicates successful login, WP_Error indicates unsuccessful login + */ + public function check_authentication() { + + // allow plugins to remove default authentication or add their own authentication + $user = apply_filters( 'woocommerce_api_check_authentication', null, $this ); + + if ( is_a( $user, 'WP_User' ) ) { + + // API requests run under the context of the authenticated user + wp_set_current_user( $user->ID ); + + } elseif ( ! is_wp_error( $user ) ) { + + // WP_Errors are handled in serve_request() + $user = new WP_Error( 'woocommerce_api_authentication_error', __( 'Invalid authentication method', 'woocommerce' ), array( 'code' => 500 ) ); + + } + + return $user; + } + + /** + * Convert an error to an array + * + * This iterates over all error codes and messages to change it into a flat + * array. This enables simpler client behaviour, as it is represented as a + * list in JSON rather than an object/map + * + * @since 2.1 + * @param WP_Error $error + * @return array List of associative arrays with code and message keys + */ + protected function error_to_array( $error ) { + $errors = array(); + foreach ( (array) $error->errors as $code => $messages ) { + foreach ( (array) $messages as $message ) { + $errors[] = array( 'code' => $code, 'message' => $message ); + } + } + + return array( 'errors' => $errors ); + } + + /** + * Handle serving an API request + * + * Matches the current server URI to a route and runs the first matching + * callback then outputs a JSON representation of the returned value. + * + * @since 2.1 + * @uses WC_API_Server::dispatch() + */ + public function serve_request() { + + do_action( 'woocommerce_api_server_before_serve', $this ); + + $this->header( 'Content-Type', $this->handler->get_content_type(), true ); + + // the API is enabled by default + if ( ! apply_filters( 'woocommerce_api_enabled', true, $this ) || ( 'no' === get_option( 'woocommerce_api_enabled' ) ) ) { + + $this->send_status( 404 ); + + echo $this->handler->generate_response( array( 'errors' => array( 'code' => 'woocommerce_api_disabled', 'message' => 'The WooCommerce API is disabled on this site' ) ) ); + + return; + } + + $result = $this->check_authentication(); + + // if authorization check was successful, dispatch the request + if ( ! is_wp_error( $result ) ) { + $result = $this->dispatch(); + } + + // handle any dispatch errors + if ( is_wp_error( $result ) ) { + $data = $result->get_error_data(); + if ( is_array( $data ) && isset( $data['status'] ) ) { + $this->send_status( $data['status'] ); + } + + $result = $this->error_to_array( $result ); + } + + // This is a filter rather than an action, since this is designed to be + // re-entrant if needed + $served = apply_filters( 'woocommerce_api_serve_request', false, $result, $this ); + + if ( ! $served ) { + + if ( 'HEAD' === $this->method ) { + return; + } + + echo $this->handler->generate_response( $result ); + } + } + + /** + * Retrieve the route map + * + * The route map is an associative array with path regexes as the keys. The + * value is an indexed array with the callback function/method as the first + * item, and a bitmask of HTTP methods as the second item (see the class + * constants). + * + * Each route can be mapped to more than one callback by using an array of + * the indexed arrays. This allows mapping e.g. GET requests to one callback + * and POST requests to another. + * + * Note that the path regexes (array keys) must have @ escaped, as this is + * used as the delimiter with preg_match() + * + * @since 2.1 + * @return array `'/path/regex' => array( $callback, $bitmask )` or `'/path/regex' => array( array( $callback, $bitmask ), ...)` + */ + public function get_routes() { + + // index added by default + $endpoints = array( + + '/' => array( array( $this, 'get_index' ), self::READABLE ), + ); + + $endpoints = apply_filters( 'woocommerce_api_endpoints', $endpoints ); + + // Normalise the endpoints + foreach ( $endpoints as $route => &$handlers ) { + if ( count( $handlers ) <= 2 && isset( $handlers[1] ) && ! is_array( $handlers[1] ) ) { + $handlers = array( $handlers ); + } + } + + return $endpoints; + } + + /** + * Match the request to a callback and call it + * + * @since 2.1 + * @return mixed The value returned by the callback, or a WP_Error instance + */ + public function dispatch() { + + switch ( $this->method ) { + + case 'HEAD' : + case 'GET' : + $method = self::METHOD_GET; + break; + + case 'POST' : + $method = self::METHOD_POST; + break; + + case 'PUT' : + $method = self::METHOD_PUT; + break; + + case 'PATCH' : + $method = self::METHOD_PATCH; + break; + + case 'DELETE' : + $method = self::METHOD_DELETE; + break; + + default : + return new WP_Error( 'woocommerce_api_unsupported_method', __( 'Unsupported request method', 'woocommerce' ), array( 'status' => 400 ) ); + } + + foreach ( $this->get_routes() as $route => $handlers ) { + foreach ( $handlers as $handler ) { + $callback = $handler[0]; + $supported = isset( $handler[1] ) ? $handler[1] : self::METHOD_GET; + + if ( ! ( $supported & $method ) ) { + continue; + } + + $match = preg_match( '@^' . $route . '$@i', urldecode( $this->path ), $args ); + + if ( ! $match ) { + continue; + } + + if ( ! is_callable( $callback ) ) { + return new WP_Error( 'woocommerce_api_invalid_handler', __( 'The handler for the route is invalid', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $args = array_merge( $args, $this->params['GET'] ); + if ( $method & self::METHOD_POST ) { + $args = array_merge( $args, $this->params['POST'] ); + } + if ( $supported & self::ACCEPT_DATA ) { + $data = $this->handler->parse_body( $this->get_raw_data() ); + $args = array_merge( $args, array( 'data' => $data ) ); + } elseif ( $supported & self::ACCEPT_RAW_DATA ) { + $data = $this->get_raw_data(); + $args = array_merge( $args, array( 'data' => $data ) ); + } + + $args['_method'] = $method; + $args['_route'] = $route; + $args['_path'] = $this->path; + $args['_headers'] = $this->headers; + $args['_files'] = $this->files; + + $args = apply_filters( 'woocommerce_api_dispatch_args', $args, $callback ); + + // Allow plugins to halt the request via this filter + if ( is_wp_error( $args ) ) { + return $args; + } + + $params = $this->sort_callback_params( $callback, $args ); + if ( is_wp_error( $params ) ) { + return $params; + } + + return call_user_func_array( $callback, $params ); + } + } + + return new WP_Error( 'woocommerce_api_no_route', __( 'No route was found matching the URL and request method', 'woocommerce' ), array( 'status' => 404 ) ); + } + + /** + * urldecode deep. + * + * @since 2.2 + * @param string|array $value Data to decode with urldecode. + * @return string|array Decoded data. + */ + protected function urldecode_deep( $value ) { + if ( is_array( $value ) ) { + return array_map( array( $this, 'urldecode_deep' ), $value ); + } else { + return urldecode( $value ); + } + } + + /** + * Sort parameters by order specified in method declaration + * + * Takes a callback and a list of available params, then filters and sorts + * by the parameters the method actually needs, using the Reflection API + * + * @since 2.2 + * + * @param callable|array $callback the endpoint callback + * @param array $provided the provided request parameters + * + * @return array|WP_Error + */ + protected function sort_callback_params( $callback, $provided ) { + if ( is_array( $callback ) ) { + $ref_func = new ReflectionMethod( $callback[0], $callback[1] ); + } else { + $ref_func = new ReflectionFunction( $callback ); + } + + $wanted = $ref_func->getParameters(); + $ordered_parameters = array(); + + foreach ( $wanted as $param ) { + if ( isset( $provided[ $param->getName() ] ) ) { + // We have this parameters in the list to choose from + if ( 'data' == $param->getName() ) { + $ordered_parameters[] = $provided[ $param->getName() ]; + continue; + } + + $ordered_parameters[] = $this->urldecode_deep( $provided[ $param->getName() ] ); + } elseif ( $param->isDefaultValueAvailable() ) { + // We don't have this parameter, but it's optional + $ordered_parameters[] = $param->getDefaultValue(); + } else { + // We don't have this parameter and it wasn't optional, abort! + return new WP_Error( 'woocommerce_api_missing_callback_param', sprintf( __( 'Missing parameter %s', 'woocommerce' ), $param->getName() ), array( 'status' => 400 ) ); + } + } + + return $ordered_parameters; + } + + /** + * Get the site index. + * + * This endpoint describes the capabilities of the site. + * + * @since 2.3 + * @return array Index entity + */ + public function get_index() { + + // General site data + $available = array( + 'store' => array( + 'name' => get_option( 'blogname' ), + 'description' => get_option( 'blogdescription' ), + 'URL' => get_option( 'siteurl' ), + 'wc_version' => WC()->version, + 'routes' => array(), + 'meta' => array( + 'timezone' => wc_timezone_string(), + 'currency' => get_woocommerce_currency(), + 'currency_format' => get_woocommerce_currency_symbol(), + 'currency_position' => get_option( 'woocommerce_currency_pos' ), + 'thousand_separator' => get_option( 'woocommerce_price_thousand_sep' ), + 'decimal_separator' => get_option( 'woocommerce_price_decimal_sep' ), + 'price_num_decimals' => wc_get_price_decimals(), + 'tax_included' => wc_prices_include_tax(), + 'weight_unit' => get_option( 'woocommerce_weight_unit' ), + 'dimension_unit' => get_option( 'woocommerce_dimension_unit' ), + 'ssl_enabled' => ( 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) ), + 'permalinks_enabled' => ( '' !== get_option( 'permalink_structure' ) ), + 'generate_password' => ( 'yes' === get_option( 'woocommerce_registration_generate_password' ) ), + 'links' => array( + 'help' => 'https://woocommerce.github.io/woocommerce-rest-api-docs/', + ), + ), + ), + ); + + // Find the available routes + foreach ( $this->get_routes() as $route => $callbacks ) { + $data = array(); + + $route = preg_replace( '#\(\?P(<\w+?>).*?\)#', '$1', $route ); + + foreach ( self::$method_map as $name => $bitmask ) { + foreach ( $callbacks as $callback ) { + // Skip to the next route if any callback is hidden + if ( $callback[1] & self::HIDDEN_ENDPOINT ) { + continue 3; + } + + if ( $callback[1] & $bitmask ) { + $data['supports'][] = $name; + } + + if ( $callback[1] & self::ACCEPT_DATA ) { + $data['accepts_data'] = true; + } + + // For non-variable routes, generate links + if ( strpos( $route, '<' ) === false ) { + $data['meta'] = array( + 'self' => get_woocommerce_api_url( $route ), + ); + } + } + } + + $available['store']['routes'][ $route ] = apply_filters( 'woocommerce_api_endpoints_description', $data ); + } + + return apply_filters( 'woocommerce_api_index', $available ); + } + + /** + * Send a HTTP status code + * + * @since 2.1 + * @param int $code HTTP status + */ + public function send_status( $code ) { + status_header( $code ); + } + + /** + * Send a HTTP header + * + * @since 2.1 + * @param string $key Header key + * @param string $value Header value + * @param boolean $replace Should we replace the existing header? + */ + public function header( $key, $value, $replace = true ) { + header( sprintf( '%s: %s', $key, $value ), $replace ); + } + + /** + * Send a Link header + * + * @internal The $rel parameter is first, as this looks nicer when sending multiple + * + * @link http://tools.ietf.org/html/rfc5988 + * @link http://www.iana.org/assignments/link-relations/link-relations.xml + * + * @since 2.1 + * @param string $rel Link relation. Either a registered type, or an absolute URL + * @param string $link Target IRI for the link + * @param array $other Other parameters to send, as an associative array + */ + public function link_header( $rel, $link, $other = array() ) { + + $header = sprintf( '<%s>; rel="%s"', $link, esc_attr( $rel ) ); + + foreach ( $other as $key => $value ) { + + if ( 'title' == $key ) { + + $value = '"' . $value . '"'; + } + + $header .= '; ' . $key . '=' . $value; + } + + $this->header( 'Link', $header, false ); + } + + /** + * Send pagination headers for resources + * + * @since 2.1 + * @param WP_Query|WP_User_Query|stdClass $query + */ + public function add_pagination_headers( $query ) { + + // WP_User_Query + if ( is_a( $query, 'WP_User_Query' ) ) { + + $single = count( $query->get_results() ) == 1; + $total = $query->get_total(); + + if ( $query->get( 'number' ) > 0 ) { + $page = ( $query->get( 'offset' ) / $query->get( 'number' ) ) + 1; + $total_pages = ceil( $total / $query->get( 'number' ) ); + } else { + $page = 1; + $total_pages = 1; + } + } elseif ( is_a( $query, 'stdClass' ) ) { + $page = $query->page; + $single = $query->is_single; + $total = $query->total; + $total_pages = $query->total_pages; + + // WP_Query + } else { + + $page = $query->get( 'paged' ); + $single = $query->is_single(); + $total = $query->found_posts; + $total_pages = $query->max_num_pages; + } + + if ( ! $page ) { + $page = 1; + } + + $next_page = absint( $page ) + 1; + + if ( ! $single ) { + + // first/prev + if ( $page > 1 ) { + $this->link_header( 'first', $this->get_paginated_url( 1 ) ); + $this->link_header( 'prev', $this->get_paginated_url( $page -1 ) ); + } + + // next + if ( $next_page <= $total_pages ) { + $this->link_header( 'next', $this->get_paginated_url( $next_page ) ); + } + + // last + if ( $page != $total_pages ) { + $this->link_header( 'last', $this->get_paginated_url( $total_pages ) ); + } + } + + $this->header( 'X-WC-Total', $total ); + $this->header( 'X-WC-TotalPages', $total_pages ); + + do_action( 'woocommerce_api_pagination_headers', $this, $query ); + } + + /** + * Returns the request URL with the page query parameter set to the specified page + * + * @since 2.1 + * @param int $page + * @return string + */ + private function get_paginated_url( $page ) { + + // remove existing page query param + $request = remove_query_arg( 'page' ); + + // add provided page query param + $request = urldecode( add_query_arg( 'page', $page, $request ) ); + + // get the home host + $host = parse_url( get_home_url(), PHP_URL_HOST ); + + return set_url_scheme( "http://{$host}{$request}" ); + } + + /** + * Retrieve the raw request entity (body) + * + * @since 2.1 + * @return string + */ + public function get_raw_data() { + // @codingStandardsIgnoreStart + // $HTTP_RAW_POST_DATA is deprecated on PHP 5.6. + if ( function_exists( 'phpversion' ) && version_compare( phpversion(), '5.6', '>=' ) ) { + return file_get_contents( 'php://input' ); + } + + global $HTTP_RAW_POST_DATA; + + // A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default, + // but we can do it ourself. + if ( ! isset( $HTTP_RAW_POST_DATA ) ) { + $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); + } + + return $HTTP_RAW_POST_DATA; + // @codingStandardsIgnoreEnd + } + + /** + * Parse an RFC3339 datetime into a MySQl datetime + * + * Invalid dates default to unix epoch + * + * @since 2.1 + * @param string $datetime RFC3339 datetime + * @return string MySQl datetime (YYYY-MM-DD HH:MM:SS) + */ + public function parse_datetime( $datetime ) { + + // Strip millisecond precision (a full stop followed by one or more digits) + if ( strpos( $datetime, '.' ) !== false ) { + $datetime = preg_replace( '/\.\d+/', '', $datetime ); + } + + // default timezone to UTC + $datetime = preg_replace( '/[+-]\d+:+\d+$/', '+00:00', $datetime ); + + try { + + $datetime = new DateTime( $datetime, new DateTimeZone( 'UTC' ) ); + + } catch ( Exception $e ) { + + $datetime = new DateTime( '@0' ); + + } + + return $datetime->format( 'Y-m-d H:i:s' ); + } + + /** + * Format a unix timestamp or MySQL datetime into an RFC3339 datetime + * + * @since 2.1 + * @param int|string $timestamp unix timestamp or MySQL datetime + * @param bool $convert_to_utc + * @param bool $convert_to_gmt Use GMT timezone. + * @return string RFC3339 datetime + */ + public function format_datetime( $timestamp, $convert_to_utc = false, $convert_to_gmt = false ) { + if ( $convert_to_gmt ) { + if ( is_numeric( $timestamp ) ) { + $timestamp = date( 'Y-m-d H:i:s', $timestamp ); + } + + $timestamp = get_gmt_from_date( $timestamp ); + } + + if ( $convert_to_utc ) { + $timezone = new DateTimeZone( wc_timezone_string() ); + } else { + $timezone = new DateTimeZone( 'UTC' ); + } + + try { + + if ( is_numeric( $timestamp ) ) { + $date = new DateTime( "@{$timestamp}" ); + } else { + $date = new DateTime( $timestamp, $timezone ); + } + + // convert to UTC by adjusting the time based on the offset of the site's timezone + if ( $convert_to_utc ) { + $date->modify( -1 * $date->getOffset() . ' seconds' ); + } + } catch ( Exception $e ) { + + $date = new DateTime( '@0' ); + } + + return $date->format( 'Y-m-d\TH:i:s\Z' ); + } + + /** + * Extract headers from a PHP-style $_SERVER array + * + * @since 2.1 + * @param array $server Associative array similar to $_SERVER + * @return array Headers extracted from the input + */ + public function get_headers( $server ) { + $headers = array(); + // CONTENT_* headers are not prefixed with HTTP_ + $additional = array( 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true ); + + foreach ( $server as $key => $value ) { + if ( strpos( $key, 'HTTP_' ) === 0 ) { + $headers[ substr( $key, 5 ) ] = $value; + } elseif ( isset( $additional[ $key ] ) ) { + $headers[ $key ] = $value; + } + } + + return $headers; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-webhooks.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-webhooks.php new file mode 100644 index 0000000..98e14b5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-webhooks.php @@ -0,0 +1,509 @@ +base ] = array( + array( array( $this, 'get_webhooks' ), WC_API_Server::READABLE ), + array( array( $this, 'create_webhook' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /webhooks/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_webhooks_count' ), WC_API_Server::READABLE ), + ); + + # GET|PUT|DELETE /webhooks/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_webhook' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_webhook' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_webhook' ), WC_API_Server::DELETABLE ), + ); + + # GET /webhooks//deliveries + $routes[ $this->base . '/(?P\d+)/deliveries' ] = array( + array( array( $this, 'get_webhook_deliveries' ), WC_API_Server::READABLE ), + ); + + # GET /webhooks//deliveries/ + $routes[ $this->base . '/(?P\d+)/deliveries/(?P\d+)' ] = array( + array( array( $this, 'get_webhook_delivery' ), WC_API_Server::READABLE ), + ); + + return $routes; + } + + /** + * Get all webhooks + * + * @since 2.2 + * + * @param array $fields + * @param array $filter + * @param string $status + * @param int $page + * + * @return array + */ + public function get_webhooks( $fields = null, $filter = array(), $status = null, $page = 1 ) { + + if ( ! empty( $status ) ) { + $filter['status'] = $status; + } + + $filter['page'] = $page; + + $query = $this->query_webhooks( $filter ); + + $webhooks = array(); + + foreach ( $query['results'] as $webhook_id ) { + $webhooks[] = current( $this->get_webhook( $webhook_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query['headers'] ); + + return array( 'webhooks' => $webhooks ); + } + + /** + * Get the webhook for the given ID + * + * @since 2.2 + * @param int $id webhook ID + * @param array $fields + * @return array|WP_Error + */ + public function get_webhook( $id, $fields = null ) { + + // ensure webhook ID is valid & user has permission to read + $id = $this->validate_request( $id, 'shop_webhook', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $webhook = wc_get_webhook( $id ); + + $webhook_data = array( + 'id' => $webhook->get_id(), + 'name' => $webhook->get_name(), + 'status' => $webhook->get_status(), + 'topic' => $webhook->get_topic(), + 'resource' => $webhook->get_resource(), + 'event' => $webhook->get_event(), + 'hooks' => $webhook->get_hooks(), + 'delivery_url' => $webhook->get_delivery_url(), + 'created_at' => $this->server->format_datetime( $webhook->get_date_created() ? $webhook->get_date_created()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'updated_at' => $this->server->format_datetime( $webhook->get_date_modified() ? $webhook->get_date_modified()->getTimestamp() : 0, false, false ), // API gives UTC times. + ); + + return array( 'webhook' => apply_filters( 'woocommerce_api_webhook_response', $webhook_data, $webhook, $fields, $this ) ); + } + + /** + * Get the total number of webhooks + * + * @since 2.2 + * + * @param string $status + * @param array $filter + * + * @return array|WP_Error + */ + public function get_webhooks_count( $status = null, $filter = array() ) { + try { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_webhooks_count', __( 'You do not have permission to read the webhooks count', 'woocommerce' ), 401 ); + } + + if ( ! empty( $status ) ) { + $filter['status'] = $status; + } + + $query = $this->query_webhooks( $filter ); + + return array( 'count' => $query['headers']->total ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create an webhook + * + * @since 2.2 + * + * @param array $data parsed webhook data + * + * @return array|WP_Error + */ + public function create_webhook( $data ) { + + try { + if ( ! isset( $data['webhook'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_webhook_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'webhook' ), 400 ); + } + + $data = $data['webhook']; + + // permission check + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_webhooks', __( 'You do not have permission to create webhooks.', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_webhook_data', $data, $this ); + + // validate topic + if ( empty( $data['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $data['topic'] ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_topic', __( 'Webhook topic is required and must be valid.', 'woocommerce' ), 400 ); + } + + // validate delivery URL + if ( empty( $data['delivery_url'] ) || ! wc_is_valid_url( $data['delivery_url'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_url', __( 'Webhook delivery URL must be a valid URL starting with http:// or https://', 'woocommerce' ), 400 ); + } + + $webhook_data = apply_filters( 'woocommerce_new_webhook_data', array( + 'post_type' => 'shop_webhook', + 'post_status' => 'publish', + 'ping_status' => 'closed', + 'post_author' => get_current_user_id(), + 'post_password' => 'webhook_' . wp_generate_password(), + 'post_title' => ! empty( $data['name'] ) ? $data['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ), + ), $data, $this ); + + $webhook = new WC_Webhook(); + + $webhook->set_name( $webhook_data['post_title'] ); + $webhook->set_user_id( $webhook_data['post_author'] ); + $webhook->set_status( 'publish' === $webhook_data['post_status'] ? 'active' : 'disabled' ); + $webhook->set_topic( $data['topic'] ); + $webhook->set_delivery_url( $data['delivery_url'] ); + $webhook->set_secret( ! empty( $data['secret'] ) ? $data['secret'] : wp_generate_password( 50, true, true ) ); + $webhook->set_api_version( 'legacy_v3' ); + $webhook->save(); + + $webhook->deliver_ping(); + + // HTTP 201 Created + $this->server->send_status( 201 ); + + do_action( 'woocommerce_api_create_webhook', $webhook->get_id(), $this ); + + return $this->get_webhook( $webhook->get_id() ); + + } catch ( WC_API_Exception $e ) { + + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a webhook + * + * @since 2.2 + * + * @param int $id webhook ID + * @param array $data parsed webhook data + * + * @return array|WP_Error + */ + public function edit_webhook( $id, $data ) { + + try { + if ( ! isset( $data['webhook'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_webhook_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'webhook' ), 400 ); + } + + $data = $data['webhook']; + + $id = $this->validate_request( $id, 'shop_webhook', 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $data = apply_filters( 'woocommerce_api_edit_webhook_data', $data, $id, $this ); + + $webhook = wc_get_webhook( $id ); + + // update topic + if ( ! empty( $data['topic'] ) ) { + + if ( wc_is_webhook_valid_topic( strtolower( $data['topic'] ) ) ) { + + $webhook->set_topic( $data['topic'] ); + + } else { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_topic', __( 'Webhook topic must be valid.', 'woocommerce' ), 400 ); + } + } + + // update delivery URL + if ( ! empty( $data['delivery_url'] ) ) { + if ( wc_is_valid_url( $data['delivery_url'] ) ) { + + $webhook->set_delivery_url( $data['delivery_url'] ); + + } else { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_url', __( 'Webhook delivery URL must be a valid URL starting with http:// or https://', 'woocommerce' ), 400 ); + } + } + + // update secret + if ( ! empty( $data['secret'] ) ) { + $webhook->set_secret( $data['secret'] ); + } + + // update status + if ( ! empty( $data['status'] ) ) { + $webhook->set_status( $data['status'] ); + } + + // update name + if ( ! empty( $data['name'] ) ) { + $webhook->set_name( $data['name'] ); + } + + $webhook->save(); + + do_action( 'woocommerce_api_edit_webhook', $webhook->get_id(), $this ); + + return $this->get_webhook( $webhook->get_id() ); + + } catch ( WC_API_Exception $e ) { + + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a webhook + * + * @since 2.2 + * @param int $id webhook ID + * @return array|WP_Error + */ + public function delete_webhook( $id ) { + + $id = $this->validate_request( $id, 'shop_webhook', 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + do_action( 'woocommerce_api_delete_webhook', $id, $this ); + + $webhook = wc_get_webhook( $id ); + + return $webhook->delete( true ); + } + + /** + * Helper method to get webhook post objects + * + * @since 2.2 + * @param array $args Request arguments for filtering query. + * @return array + */ + private function query_webhooks( $args ) { + $args = $this->merge_query_args( array(), $args ); + + $args['limit'] = isset( $args['posts_per_page'] ) ? intval( $args['posts_per_page'] ) : intval( get_option( 'posts_per_page' ) ); + + if ( empty( $args['offset'] ) ) { + $args['offset'] = 1 < $args['paged'] ? ( $args['paged'] - 1 ) * $args['limit'] : 0; + } + + $page = $args['paged']; + unset( $args['paged'], $args['posts_per_page'] ); + + if ( isset( $args['s'] ) ) { + $args['search'] = $args['s']; + unset( $args['s'] ); + } + + // Post type to webhook status. + if ( ! empty( $args['post_status'] ) ) { + $args['status'] = $args['post_status']; + unset( $args['post_status'] ); + } + + if ( ! empty( $args['post__in'] ) ) { + $args['include'] = $args['post__in']; + unset( $args['post__in'] ); + } + + if ( ! empty( $args['date_query'] ) ) { + foreach ( $args['date_query'] as $date_query ) { + if ( 'post_date_gmt' === $date_query['column'] ) { + $args['after'] = isset( $date_query['after'] ) ? $date_query['after'] : null; + $args['before'] = isset( $date_query['before'] ) ? $date_query['before'] : null; + } elseif ( 'post_modified_gmt' === $date_query['column'] ) { + $args['modified_after'] = isset( $date_query['after'] ) ? $date_query['after'] : null; + $args['modified_before'] = isset( $date_query['before'] ) ? $date_query['before'] : null; + } + } + + unset( $args['date_query'] ); + } + + $args['paginate'] = true; + + // Get the webhooks. + $data_store = WC_Data_Store::load( 'webhook' ); + $results = $data_store->search_webhooks( $args ); + + // Get total items. + $headers = new stdClass; + $headers->page = $page; + $headers->total = $results->total; + $headers->is_single = $args['limit'] > $headers->total; + $headers->total_pages = $results->max_num_pages; + + return array( + 'results' => $results->webhooks, + 'headers' => $headers, + ); + } + + /** + * Get deliveries for a webhook + * + * @since 2.2 + * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. + * @param string $webhook_id webhook ID + * @param string|null $fields fields to include in response + * @return array|WP_Error + */ + public function get_webhook_deliveries( $webhook_id, $fields = null ) { + + // Ensure ID is valid webhook ID + $webhook_id = $this->validate_request( $webhook_id, 'shop_webhook', 'read' ); + + if ( is_wp_error( $webhook_id ) ) { + return $webhook_id; + } + + return array( 'webhook_deliveries' => array() ); + } + + /** + * Get the delivery log for the given webhook ID and delivery ID + * + * @since 2.2 + * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. + * @param string $webhook_id webhook ID + * @param string $id delivery log ID + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_webhook_delivery( $webhook_id, $id, $fields = null ) { + try { + // Validate webhook ID + $webhook_id = $this->validate_request( $webhook_id, 'shop_webhook', 'read' ); + + if ( is_wp_error( $webhook_id ) ) { + return $webhook_id; + } + + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_id', __( 'Invalid webhook delivery ID.', 'woocommerce' ), 404 ); + } + + $webhook = new WC_Webhook( $webhook_id ); + + $log = 0; + + if ( ! $log ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_id', __( 'Invalid webhook delivery.', 'woocommerce' ), 400 ); + } + + return array( 'webhook_delivery' => apply_filters( 'woocommerce_api_webhook_delivery_response', array(), $id, $fields, $log, $webhook_id, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Validate the request by checking: + * + * 1) the ID is a valid integer. + * 2) the ID returns a valid post object and matches the provided post type. + * 3) the current user has the proper permissions to read/edit/delete the post. + * + * @since 3.3.0 + * @param string|int $id The post ID + * @param string $type The post type, either `shop_order`, `shop_coupon`, or `product`. + * @param string $context The context of the request, either `read`, `edit` or `delete`. + * @return int|WP_Error Valid post ID or WP_Error if any of the checks fails. + */ + protected function validate_request( $id, $type, $context ) { + $id = absint( $id ); + + // Validate ID. + if ( empty( $id ) ) { + return new WP_Error( "woocommerce_api_invalid_webhook_id", sprintf( __( 'Invalid %s ID', 'woocommerce' ), $type ), array( 'status' => 404 ) ); + } + + $webhook = wc_get_webhook( $id ); + + if ( null === $webhook ) { + return new WP_Error( "woocommerce_api_no_webhook_found", sprintf( __( 'No %1$s found with the ID equal to %2$s', 'woocommerce' ), 'webhook', $id ), array( 'status' => 404 ) ); + } + + // Validate permissions. + switch ( $context ) { + + case 'read': + if ( ! current_user_can( 'manage_woocommerce' ) ) { + return new WP_Error( "woocommerce_api_user_cannot_read_webhook", sprintf( __( 'You do not have permission to read this %s', 'woocommerce' ), 'webhook' ), array( 'status' => 401 ) ); + } + break; + + case 'edit': + if ( ! current_user_can( 'manage_woocommerce' ) ) { + return new WP_Error( "woocommerce_api_user_cannot_edit_webhook", sprintf( __( 'You do not have permission to edit this %s', 'woocommerce' ), 'webhook' ), array( 'status' => 401 ) ); + } + break; + + case 'delete': + if ( ! current_user_can( 'manage_woocommerce' ) ) { + return new WP_Error( "woocommerce_api_user_cannot_delete_webhook", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce' ), 'webhook' ), array( 'status' => 401 ) ); + } + break; + } + + return $id; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/interface-wc-api-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/interface-wc-api-handler.php new file mode 100644 index 0000000..94ce87d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v2/interface-wc-api-handler.php @@ -0,0 +1,47 @@ +api->server->path ) { + return new WP_User( 0 ); + } + + try { + if ( is_ssl() ) { + $keys = $this->perform_ssl_authentication(); + } else { + $keys = $this->perform_oauth_authentication(); + } + + // Check API key-specific permission + $this->check_api_key_permissions( $keys['permissions'] ); + + $user = $this->get_user_by_id( $keys['user_id'] ); + + $this->update_api_key_last_access( $keys['key_id'] ); + + } catch ( Exception $e ) { + $user = new WP_Error( 'woocommerce_api_authentication_error', $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + return $user; + } + + /** + * SSL-encrypted requests are not subject to sniffing or man-in-the-middle + * attacks, so the request can be authenticated by simply looking up the user + * associated with the given consumer key and confirming the consumer secret + * provided is valid + * + * @since 2.1 + * @return array + * @throws Exception + */ + private function perform_ssl_authentication() { + $params = WC()->api->server->params['GET']; + + // if the $_GET parameters are present, use those first + if ( ! empty( $params['consumer_key'] ) && ! empty( $params['consumer_secret'] ) ) { + $keys = $this->get_keys_by_consumer_key( $params['consumer_key'] ); + + if ( ! $this->is_consumer_secret_valid( $keys['consumer_secret'], $params['consumer_secret'] ) ) { + throw new Exception( __( 'Consumer secret is invalid.', 'woocommerce' ), 401 ); + } + + return $keys; + } + + // if the above is not present, we will do full basic auth + if ( empty( $_SERVER['PHP_AUTH_USER'] ) || empty( $_SERVER['PHP_AUTH_PW'] ) ) { + $this->exit_with_unauthorized_headers(); + } + + $keys = $this->get_keys_by_consumer_key( $_SERVER['PHP_AUTH_USER'] ); + + if ( ! $this->is_consumer_secret_valid( $keys['consumer_secret'], $_SERVER['PHP_AUTH_PW'] ) ) { + $this->exit_with_unauthorized_headers(); + } + + return $keys; + } + + /** + * If the consumer_key and consumer_secret $_GET parameters are NOT provided + * and the Basic auth headers are either not present or the consumer secret does not match the consumer + * key provided, then return the correct Basic headers and an error message. + * + * @since 2.4 + */ + private function exit_with_unauthorized_headers() { + $auth_message = __( 'WooCommerce API. Use a consumer key in the username field and a consumer secret in the password field.', 'woocommerce' ); + header( 'WWW-Authenticate: Basic realm="' . $auth_message . '"' ); + header( 'HTTP/1.0 401 Unauthorized' ); + throw new Exception( __( 'Consumer Secret is invalid.', 'woocommerce' ), 401 ); + } + + /** + * Perform OAuth 1.0a "one-legged" (http://oauthbible.com/#oauth-10a-one-legged) authentication for non-SSL requests + * + * This is required so API credentials cannot be sniffed or intercepted when making API requests over plain HTTP + * + * This follows the spec for simple OAuth 1.0a authentication (RFC 5849) as closely as possible, with two exceptions: + * + * 1) There is no token associated with request/responses, only consumer keys/secrets are used + * + * 2) The OAuth parameters are included as part of the request query string instead of part of the Authorization header, + * This is because there is no cross-OS function within PHP to get the raw Authorization header + * + * @link http://tools.ietf.org/html/rfc5849 for the full spec + * @since 2.1 + * @return array + * @throws Exception + */ + private function perform_oauth_authentication() { + + $params = WC()->api->server->params['GET']; + + $param_names = array( 'oauth_consumer_key', 'oauth_timestamp', 'oauth_nonce', 'oauth_signature', 'oauth_signature_method' ); + + // Check for required OAuth parameters + foreach ( $param_names as $param_name ) { + + if ( empty( $params[ $param_name ] ) ) { + throw new Exception( sprintf( __( '%s parameter is missing', 'woocommerce' ), $param_name ), 404 ); + } + } + + // Fetch WP user by consumer key + $keys = $this->get_keys_by_consumer_key( $params['oauth_consumer_key'] ); + + // Perform OAuth validation + $this->check_oauth_signature( $keys, $params ); + $this->check_oauth_timestamp_and_nonce( $keys, $params['oauth_timestamp'], $params['oauth_nonce'] ); + + // Authentication successful, return user + return $keys; + } + + /** + * Return the keys for the given consumer key + * + * @since 2.4.0 + * @param string $consumer_key + * @return array + * @throws Exception + */ + private function get_keys_by_consumer_key( $consumer_key ) { + global $wpdb; + + $consumer_key = wc_api_hash( sanitize_text_field( $consumer_key ) ); + + $keys = $wpdb->get_row( $wpdb->prepare( " + SELECT key_id, user_id, permissions, consumer_key, consumer_secret, nonces + FROM {$wpdb->prefix}woocommerce_api_keys + WHERE consumer_key = '%s' + ", $consumer_key ), ARRAY_A ); + + if ( empty( $keys ) ) { + throw new Exception( __( 'Consumer key is invalid.', 'woocommerce' ), 401 ); + } + + return $keys; + } + + /** + * Get user by ID + * + * @since 2.4.0 + * + * @param int $user_id + * + * @return WP_User + * @throws Exception + */ + private function get_user_by_id( $user_id ) { + $user = get_user_by( 'id', $user_id ); + + if ( ! $user ) { + throw new Exception( __( 'API user is invalid', 'woocommerce' ), 401 ); + } + + return $user; + } + + /** + * Check if the consumer secret provided for the given user is valid + * + * @since 2.1 + * @param string $keys_consumer_secret + * @param string $consumer_secret + * @return bool + */ + private function is_consumer_secret_valid( $keys_consumer_secret, $consumer_secret ) { + return hash_equals( $keys_consumer_secret, $consumer_secret ); + } + + /** + * Verify that the consumer-provided request signature matches our generated signature, this ensures the consumer + * has a valid key/secret + * + * @param array $keys + * @param array $params the request parameters + * @throws Exception + */ + private function check_oauth_signature( $keys, $params ) { + $http_method = strtoupper( WC()->api->server->method ); + + $server_path = WC()->api->server->path; + + // if the requested URL has a trailingslash, make sure our base URL does as well + if ( isset( $_SERVER['REDIRECT_URL'] ) && '/' === substr( $_SERVER['REDIRECT_URL'], -1 ) ) { + $server_path .= '/'; + } + + $base_request_uri = rawurlencode( untrailingslashit( get_woocommerce_api_url( '' ) ) . $server_path ); + + // Get the signature provided by the consumer and remove it from the parameters prior to checking the signature + $consumer_signature = rawurldecode( str_replace( ' ', '+', $params['oauth_signature'] ) ); + unset( $params['oauth_signature'] ); + + // Sort parameters + if ( ! uksort( $params, 'strcmp' ) ) { + throw new Exception( __( 'Invalid signature - failed to sort parameters.', 'woocommerce' ), 401 ); + } + + // Normalize parameter key/values + $params = $this->normalize_parameters( $params ); + $query_parameters = array(); + foreach ( $params as $param_key => $param_value ) { + if ( is_array( $param_value ) ) { + foreach ( $param_value as $param_key_inner => $param_value_inner ) { + $query_parameters[] = $param_key . '%255B' . $param_key_inner . '%255D%3D' . $param_value_inner; + } + } else { + $query_parameters[] = $param_key . '%3D' . $param_value; // join with equals sign + } + } + $query_string = implode( '%26', $query_parameters ); // join with ampersand + + $string_to_sign = $http_method . '&' . $base_request_uri . '&' . $query_string; + + if ( 'HMAC-SHA1' !== $params['oauth_signature_method'] && 'HMAC-SHA256' !== $params['oauth_signature_method'] ) { + throw new Exception( __( 'Invalid signature - signature method is invalid.', 'woocommerce' ), 401 ); + } + + $hash_algorithm = strtolower( str_replace( 'HMAC-', '', $params['oauth_signature_method'] ) ); + + $secret = $keys['consumer_secret'] . '&'; + $signature = base64_encode( hash_hmac( $hash_algorithm, $string_to_sign, $secret, true ) ); + + if ( ! hash_equals( $signature, $consumer_signature ) ) { + throw new Exception( __( 'Invalid signature - provided signature does not match.', 'woocommerce' ), 401 ); + } + } + + /** + * Normalize each parameter by assuming each parameter may have already been + * encoded, so attempt to decode, and then re-encode according to RFC 3986 + * + * Note both the key and value is normalized so a filter param like: + * + * 'filter[period]' => 'week' + * + * is encoded to: + * + * 'filter%5Bperiod%5D' => 'week' + * + * This conforms to the OAuth 1.0a spec which indicates the entire query string + * should be URL encoded + * + * @since 2.1 + * @see rawurlencode() + * @param array $parameters un-normalized parameters + * @return array normalized parameters + */ + private function normalize_parameters( $parameters ) { + $keys = WC_API_Authentication::urlencode_rfc3986( array_keys( $parameters ) ); + $values = WC_API_Authentication::urlencode_rfc3986( array_values( $parameters ) ); + $parameters = array_combine( $keys, $values ); + return $parameters; + } + + /** + * Encodes a value according to RFC 3986. Supports multidimensional arrays. + * + * @since 2.4 + * @param string|array $value The value to encode + * @return string|array Encoded values + */ + public static function urlencode_rfc3986( $value ) { + if ( is_array( $value ) ) { + return array_map( array( 'WC_API_Authentication', 'urlencode_rfc3986' ), $value ); + } else { + // Percent symbols (%) must be double-encoded + return str_replace( '%', '%25', rawurlencode( rawurldecode( $value ) ) ); + } + } + + /** + * Verify that the timestamp and nonce provided with the request are valid. This prevents replay attacks where + * an attacker could attempt to re-send an intercepted request at a later time. + * + * - A timestamp is valid if it is within 15 minutes of now + * - A nonce is valid if it has not been used within the last 15 minutes + * + * @param array $keys + * @param int $timestamp the unix timestamp for when the request was made + * @param string $nonce a unique (for the given user) 32 alphanumeric string, consumer-generated + * @throws Exception + */ + private function check_oauth_timestamp_and_nonce( $keys, $timestamp, $nonce ) { + global $wpdb; + + $valid_window = 15 * 60; // 15 minute window + + if ( ( $timestamp < time() - $valid_window ) || ( $timestamp > time() + $valid_window ) ) { + throw new Exception( __( 'Invalid timestamp.', 'woocommerce' ), 401 ); + } + + $used_nonces = maybe_unserialize( $keys['nonces'] ); + + if ( empty( $used_nonces ) ) { + $used_nonces = array(); + } + + if ( in_array( $nonce, $used_nonces ) ) { + throw new Exception( __( 'Invalid nonce - nonce has already been used.', 'woocommerce' ), 401 ); + } + + $used_nonces[ $timestamp ] = $nonce; + + // Remove expired nonces + foreach ( $used_nonces as $nonce_timestamp => $nonce ) { + if ( $nonce_timestamp < ( time() - $valid_window ) ) { + unset( $used_nonces[ $nonce_timestamp ] ); + } + } + + $used_nonces = maybe_serialize( $used_nonces ); + + $wpdb->update( + $wpdb->prefix . 'woocommerce_api_keys', + array( 'nonces' => $used_nonces ), + array( 'key_id' => $keys['key_id'] ), + array( '%s' ), + array( '%d' ) + ); + } + + /** + * Check that the API keys provided have the proper key-specific permissions to either read or write API resources + * + * @param string $key_permissions + * @throws Exception if the permission check fails + */ + public function check_api_key_permissions( $key_permissions ) { + switch ( WC()->api->server->method ) { + + case 'HEAD': + case 'GET': + if ( 'read' !== $key_permissions && 'read_write' !== $key_permissions ) { + throw new Exception( __( 'The API key provided does not have read permissions.', 'woocommerce' ), 401 ); + } + break; + + case 'POST': + case 'PUT': + case 'PATCH': + case 'DELETE': + if ( 'write' !== $key_permissions && 'read_write' !== $key_permissions ) { + throw new Exception( __( 'The API key provided does not have write permissions.', 'woocommerce' ), 401 ); + } + break; + } + } + + /** + * Updated API Key last access datetime + * + * @since 2.4.0 + * + * @param int $key_id + */ + private function update_api_key_last_access( $key_id ) { + global $wpdb; + + $wpdb->update( + $wpdb->prefix . 'woocommerce_api_keys', + array( 'last_access' => current_time( 'mysql' ) ), + array( 'key_id' => $key_id ), + array( '%s' ), + array( '%d' ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-coupons.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-coupons.php new file mode 100644 index 0000000..870dfd2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-coupons.php @@ -0,0 +1,576 @@ + + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET/POST /coupons + $routes[ $this->base ] = array( + array( array( $this, 'get_coupons' ), WC_API_Server::READABLE ), + array( array( $this, 'create_coupon' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /coupons/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_coupons_count' ), WC_API_Server::READABLE ), + ); + + # GET/PUT/DELETE /coupons/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_coupon' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_coupon' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ), + array( array( $this, 'delete_coupon' ), WC_API_SERVER::DELETABLE ), + ); + + # GET /coupons/code/, note that coupon codes can contain spaces, dashes and underscores + $routes[ $this->base . '/code/(?P\w[\w\s\-]*)' ] = array( + array( array( $this, 'get_coupon_by_code' ), WC_API_Server::READABLE ), + ); + + # POST|PUT /coupons/bulk + $routes[ $this->base . '/bulk' ] = array( + array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + return $routes; + } + + /** + * Get all coupons + * + * @since 2.1 + * @param string $fields + * @param array $filter + * @param int $page + * @return array + */ + public function get_coupons( $fields = null, $filter = array(), $page = 1 ) { + + $filter['page'] = $page; + + $query = $this->query_coupons( $filter ); + + $coupons = array(); + + foreach ( $query->posts as $coupon_id ) { + + if ( ! $this->is_readable( $coupon_id ) ) { + continue; + } + + $coupons[] = current( $this->get_coupon( $coupon_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'coupons' => $coupons ); + } + + /** + * Get the coupon for the given ID + * + * @since 2.1 + * @param int $id the coupon ID + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_coupon( $id, $fields = null ) { + try { + + $id = $this->validate_request( $id, 'shop_coupon', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $coupon = new WC_Coupon( $id ); + + if ( 0 === $coupon->get_id() ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_id', __( 'Invalid coupon ID', 'woocommerce' ), 404 ); + } + + $coupon_data = array( + 'id' => $coupon->get_id(), + 'code' => $coupon->get_code(), + 'type' => $coupon->get_discount_type(), + 'created_at' => $this->server->format_datetime( $coupon->get_date_created() ? $coupon->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. + 'updated_at' => $this->server->format_datetime( $coupon->get_date_modified() ? $coupon->get_date_modified()->getTimestamp() : 0 ), // API gives UTC times. + 'amount' => wc_format_decimal( $coupon->get_amount(), 2 ), + 'individual_use' => $coupon->get_individual_use(), + 'product_ids' => array_map( 'absint', (array) $coupon->get_product_ids() ), + 'exclude_product_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_ids() ), + 'usage_limit' => $coupon->get_usage_limit() ? $coupon->get_usage_limit() : null, + 'usage_limit_per_user' => $coupon->get_usage_limit_per_user() ? $coupon->get_usage_limit_per_user() : null, + 'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(), + 'usage_count' => (int) $coupon->get_usage_count(), + 'expiry_date' => $coupon->get_date_expires() ? $this->server->format_datetime( $coupon->get_date_expires()->getTimestamp() ) : null, // API gives UTC times. + 'enable_free_shipping' => $coupon->get_free_shipping(), + 'product_category_ids' => array_map( 'absint', (array) $coupon->get_product_categories() ), + 'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->get_excluded_product_categories() ), + 'exclude_sale_items' => $coupon->get_exclude_sale_items(), + 'minimum_amount' => wc_format_decimal( $coupon->get_minimum_amount(), 2 ), + 'maximum_amount' => wc_format_decimal( $coupon->get_maximum_amount(), 2 ), + 'customer_emails' => $coupon->get_email_restrictions(), + 'description' => $coupon->get_description(), + ); + + return array( 'coupon' => apply_filters( 'woocommerce_api_coupon_response', $coupon_data, $coupon, $fields, $this->server ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the total number of coupons + * + * @since 2.1 + * @param array $filter + * @return array|WP_Error + */ + public function get_coupons_count( $filter = array() ) { + try { + if ( ! current_user_can( 'read_private_shop_coupons' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_coupons_count', __( 'You do not have permission to read the coupons count', 'woocommerce' ), 401 ); + } + + $query = $this->query_coupons( $filter ); + + return array( 'count' => (int) $query->found_posts ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the coupon for the given code + * + * @since 2.1 + * @param string $code the coupon code + * @param string $fields fields to include in response + * @return int|WP_Error + */ + public function get_coupon_by_code( $code, $fields = null ) { + global $wpdb; + + try { + $id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1;", $code ) ); + + if ( is_null( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_code', __( 'Invalid coupon code', 'woocommerce' ), 404 ); + } + + return $this->get_coupon( $id, $fields ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a coupon + * + * @since 2.2 + * + * @param array $data + * + * @return array|WP_Error + */ + public function create_coupon( $data ) { + global $wpdb; + + try { + if ( ! isset( $data['coupon'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_coupon_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'coupon' ), 400 ); + } + + $data = $data['coupon']; + + // Check user permission + if ( ! current_user_can( 'publish_shop_coupons' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_coupon', __( 'You do not have permission to create coupons', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_coupon_data', $data, $this ); + + // Check if coupon code is specified + if ( ! isset( $data['code'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_coupon_code', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'code' ), 400 ); + } + + $coupon_code = wc_format_coupon_code( $data['code'] ); + $id_from_code = wc_get_coupon_id_by_code( $coupon_code ); + + if ( $id_from_code ) { + throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 ); + } + + $defaults = array( + 'type' => 'fixed_cart', + 'amount' => 0, + 'individual_use' => false, + 'product_ids' => array(), + 'exclude_product_ids' => array(), + 'usage_limit' => '', + 'usage_limit_per_user' => '', + 'limit_usage_to_x_items' => '', + 'usage_count' => '', + 'expiry_date' => '', + 'enable_free_shipping' => false, + 'product_category_ids' => array(), + 'exclude_product_category_ids' => array(), + 'exclude_sale_items' => false, + 'minimum_amount' => '', + 'maximum_amount' => '', + 'customer_emails' => array(), + 'description' => '', + ); + + $coupon_data = wp_parse_args( $data, $defaults ); + + // Validate coupon types + if ( ! in_array( wc_clean( $coupon_data['type'] ), array_keys( wc_get_coupon_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ), 400 ); + } + + $new_coupon = array( + 'post_title' => $coupon_code, + 'post_content' => '', + 'post_status' => 'publish', + 'post_author' => get_current_user_id(), + 'post_type' => 'shop_coupon', + 'post_excerpt' => $coupon_data['description'], + ); + + $id = wp_insert_post( $new_coupon, true ); + + if ( is_wp_error( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_coupon', $id->get_error_message(), 400 ); + } + + // Set coupon meta + update_post_meta( $id, 'discount_type', $coupon_data['type'] ); + update_post_meta( $id, 'coupon_amount', wc_format_decimal( $coupon_data['amount'] ) ); + update_post_meta( $id, 'individual_use', ( true === $coupon_data['individual_use'] ) ? 'yes' : 'no' ); + update_post_meta( $id, 'product_ids', implode( ',', array_filter( array_map( 'intval', $coupon_data['product_ids'] ) ) ) ); + update_post_meta( $id, 'exclude_product_ids', implode( ',', array_filter( array_map( 'intval', $coupon_data['exclude_product_ids'] ) ) ) ); + update_post_meta( $id, 'usage_limit', absint( $coupon_data['usage_limit'] ) ); + update_post_meta( $id, 'usage_limit_per_user', absint( $coupon_data['usage_limit_per_user'] ) ); + update_post_meta( $id, 'limit_usage_to_x_items', absint( $coupon_data['limit_usage_to_x_items'] ) ); + update_post_meta( $id, 'usage_count', absint( $coupon_data['usage_count'] ) ); + update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $coupon_data['expiry_date'] ) ) ); + update_post_meta( $id, 'date_expires', $this->get_coupon_expiry_date( wc_clean( $coupon_data['expiry_date'] ), true ) ); + update_post_meta( $id, 'free_shipping', ( true === $coupon_data['enable_free_shipping'] ) ? 'yes' : 'no' ); + update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $coupon_data['product_category_ids'] ) ) ); + update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $coupon_data['exclude_product_category_ids'] ) ) ); + update_post_meta( $id, 'exclude_sale_items', ( true === $coupon_data['exclude_sale_items'] ) ? 'yes' : 'no' ); + update_post_meta( $id, 'minimum_amount', wc_format_decimal( $coupon_data['minimum_amount'] ) ); + update_post_meta( $id, 'maximum_amount', wc_format_decimal( $coupon_data['maximum_amount'] ) ); + update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $coupon_data['customer_emails'] ) ) ); + + do_action( 'woocommerce_api_create_coupon', $id, $data ); + do_action( 'woocommerce_new_coupon', $id ); + + $this->server->send_status( 201 ); + + return $this->get_coupon( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a coupon + * + * @since 2.2 + * + * @param int $id the coupon ID + * @param array $data + * + * @return array|WP_Error + */ + public function edit_coupon( $id, $data ) { + + try { + if ( ! isset( $data['coupon'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_coupon_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'coupon' ), 400 ); + } + + $data = $data['coupon']; + + $id = $this->validate_request( $id, 'shop_coupon', 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $data = apply_filters( 'woocommerce_api_edit_coupon_data', $data, $id, $this ); + + if ( isset( $data['code'] ) ) { + global $wpdb; + + $coupon_code = wc_format_coupon_code( $data['code'] ); + $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); + + if ( $id_from_code ) { + throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 ); + } + + $updated = wp_update_post( array( 'ID' => intval( $id ), 'post_title' => $coupon_code ) ); + + if ( 0 === $updated ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 ); + } + } + + if ( isset( $data['description'] ) ) { + $updated = wp_update_post( array( 'ID' => intval( $id ), 'post_excerpt' => $data['description'] ) ); + + if ( 0 === $updated ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 ); + } + } + + if ( isset( $data['type'] ) ) { + // Validate coupon types + if ( ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_coupon_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ), 400 ); + } + update_post_meta( $id, 'discount_type', $data['type'] ); + } + + if ( isset( $data['amount'] ) ) { + update_post_meta( $id, 'coupon_amount', wc_format_decimal( $data['amount'] ) ); + } + + if ( isset( $data['individual_use'] ) ) { + update_post_meta( $id, 'individual_use', ( true === $data['individual_use'] ) ? 'yes' : 'no' ); + } + + if ( isset( $data['product_ids'] ) ) { + update_post_meta( $id, 'product_ids', implode( ',', array_filter( array_map( 'intval', $data['product_ids'] ) ) ) ); + } + + if ( isset( $data['exclude_product_ids'] ) ) { + update_post_meta( $id, 'exclude_product_ids', implode( ',', array_filter( array_map( 'intval', $data['exclude_product_ids'] ) ) ) ); + } + + if ( isset( $data['usage_limit'] ) ) { + update_post_meta( $id, 'usage_limit', absint( $data['usage_limit'] ) ); + } + + if ( isset( $data['usage_limit_per_user'] ) ) { + update_post_meta( $id, 'usage_limit_per_user', absint( $data['usage_limit_per_user'] ) ); + } + + if ( isset( $data['limit_usage_to_x_items'] ) ) { + update_post_meta( $id, 'limit_usage_to_x_items', absint( $data['limit_usage_to_x_items'] ) ); + } + + if ( isset( $data['usage_count'] ) ) { + update_post_meta( $id, 'usage_count', absint( $data['usage_count'] ) ); + } + + if ( isset( $data['expiry_date'] ) ) { + update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $data['expiry_date'] ) ) ); + update_post_meta( $id, 'date_expires', $this->get_coupon_expiry_date( wc_clean( $data['expiry_date'] ), true ) ); + } + + if ( isset( $data['enable_free_shipping'] ) ) { + update_post_meta( $id, 'free_shipping', ( true === $data['enable_free_shipping'] ) ? 'yes' : 'no' ); + } + + if ( isset( $data['product_category_ids'] ) ) { + update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $data['product_category_ids'] ) ) ); + } + + if ( isset( $data['exclude_product_category_ids'] ) ) { + update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $data['exclude_product_category_ids'] ) ) ); + } + + if ( isset( $data['exclude_sale_items'] ) ) { + update_post_meta( $id, 'exclude_sale_items', ( true === $data['exclude_sale_items'] ) ? 'yes' : 'no' ); + } + + if ( isset( $data['minimum_amount'] ) ) { + update_post_meta( $id, 'minimum_amount', wc_format_decimal( $data['minimum_amount'] ) ); + } + + if ( isset( $data['maximum_amount'] ) ) { + update_post_meta( $id, 'maximum_amount', wc_format_decimal( $data['maximum_amount'] ) ); + } + + if ( isset( $data['customer_emails'] ) ) { + update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $data['customer_emails'] ) ) ); + } + + do_action( 'woocommerce_api_edit_coupon', $id, $data ); + do_action( 'woocommerce_update_coupon', $id ); + + return $this->get_coupon( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a coupon + * + * @since 2.2 + * + * @param int $id the coupon ID + * @param bool $force true to permanently delete coupon, false to move to trash + * + * @return array|int|WP_Error + */ + public function delete_coupon( $id, $force = false ) { + + $id = $this->validate_request( $id, 'shop_coupon', 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + do_action( 'woocommerce_api_delete_coupon', $id, $this ); + + return $this->delete( $id, 'shop_coupon', ( 'true' === $force ) ); + } + + /** + * expiry_date format + * + * @since 2.3.0 + * @param string $expiry_date + * @param bool $as_timestamp (default: false) + * @return string|int + */ + protected function get_coupon_expiry_date( $expiry_date, $as_timestamp = false ) { + if ( '' != $expiry_date ) { + if ( $as_timestamp ) { + return strtotime( $expiry_date ); + } + + return date( 'Y-m-d', strtotime( $expiry_date ) ); + } + + return ''; + } + + /** + * Helper method to get coupon post objects + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_Query + */ + private function query_coupons( $args ) { + + // set base query arguments + $query_args = array( + 'fields' => 'ids', + 'post_type' => 'shop_coupon', + 'post_status' => 'publish', + ); + + $query_args = $this->merge_query_args( $query_args, $args ); + + return new WP_Query( $query_args ); + } + + /** + * Bulk update or insert coupons + * Accepts an array with coupons in the formats supported by + * WC_API_Coupons->create_coupon() and WC_API_Coupons->edit_coupon() + * + * @since 2.4.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function bulk( $data ) { + + try { + if ( ! isset( $data['coupons'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_coupons_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'coupons' ), 400 ); + } + + $data = $data['coupons']; + $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'coupons' ); + + // Limit bulk operation + if ( count( $data ) > $limit ) { + throw new WC_API_Exception( 'woocommerce_api_coupons_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); + } + + $coupons = array(); + + foreach ( $data as $_coupon ) { + $coupon_id = 0; + + // Try to get the coupon ID + if ( isset( $_coupon['id'] ) ) { + $coupon_id = intval( $_coupon['id'] ); + } + + if ( $coupon_id ) { + + // Coupon exists / edit coupon + $edit = $this->edit_coupon( $coupon_id, array( 'coupon' => $_coupon ) ); + + if ( is_wp_error( $edit ) ) { + $coupons[] = array( + 'id' => $coupon_id, + 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ), + ); + } else { + $coupons[] = $edit['coupon']; + } + } else { + + // Coupon don't exists / create coupon + $new = $this->create_coupon( array( 'coupon' => $_coupon ) ); + + if ( is_wp_error( $new ) ) { + $coupons[] = array( + 'id' => $coupon_id, + 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ), + ); + } else { + $coupons[] = $new['coupon']; + } + } + } + + return array( 'coupons' => apply_filters( 'woocommerce_api_coupons_bulk_response', $coupons, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-customers.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-customers.php new file mode 100644 index 0000000..2df6fd8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-customers.php @@ -0,0 +1,829 @@ + + * GET /customers//orders + * + * @since 2.2 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET/POST /customers + $routes[ $this->base ] = array( + array( array( $this, 'get_customers' ), WC_API_SERVER::READABLE ), + array( array( $this, 'create_customer' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /customers/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_customers_count' ), WC_API_SERVER::READABLE ), + ); + + # GET/PUT/DELETE /customers/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_customer' ), WC_API_SERVER::READABLE ), + array( array( $this, 'edit_customer' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ), + array( array( $this, 'delete_customer' ), WC_API_SERVER::DELETABLE ), + ); + + # GET /customers/email/ + $routes[ $this->base . '/email/(?P.+)' ] = array( + array( array( $this, 'get_customer_by_email' ), WC_API_SERVER::READABLE ), + ); + + # GET /customers//orders + $routes[ $this->base . '/(?P\d+)/orders' ] = array( + array( array( $this, 'get_customer_orders' ), WC_API_SERVER::READABLE ), + ); + + # GET /customers//downloads + $routes[ $this->base . '/(?P\d+)/downloads' ] = array( + array( array( $this, 'get_customer_downloads' ), WC_API_SERVER::READABLE ), + ); + + # POST|PUT /customers/bulk + $routes[ $this->base . '/bulk' ] = array( + array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + return $routes; + } + + /** + * Get all customers + * + * @since 2.1 + * @param array $fields + * @param array $filter + * @param int $page + * @return array + */ + public function get_customers( $fields = null, $filter = array(), $page = 1 ) { + + $filter['page'] = $page; + + $query = $this->query_customers( $filter ); + + $customers = array(); + + foreach ( $query->get_results() as $user_id ) { + + if ( ! $this->is_readable( $user_id ) ) { + continue; + } + + $customers[] = current( $this->get_customer( $user_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'customers' => $customers ); + } + + /** + * Get the customer for the given ID + * + * @since 2.1 + * @param int $id the customer ID + * @param array $fields + * @return array|WP_Error + */ + public function get_customer( $id, $fields = null ) { + global $wpdb; + + $id = $this->validate_request( $id, 'customer', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $customer = new WC_Customer( $id ); + $last_order = $customer->get_last_order(); + $customer_data = array( + 'id' => $customer->get_id(), + 'created_at' => $this->server->format_datetime( $customer->get_date_created() ? $customer->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. + 'last_update' => $this->server->format_datetime( $customer->get_date_modified() ? $customer->get_date_modified()->getTimestamp() : 0 ), // API gives UTC times. + 'email' => $customer->get_email(), + 'first_name' => $customer->get_first_name(), + 'last_name' => $customer->get_last_name(), + 'username' => $customer->get_username(), + 'role' => $customer->get_role(), + 'last_order_id' => is_object( $last_order ) ? $last_order->get_id() : null, + 'last_order_date' => is_object( $last_order ) ? $this->server->format_datetime( $last_order->get_date_created() ? $last_order->get_date_created()->getTimestamp() : 0 ) : null, // API gives UTC times. + 'orders_count' => $customer->get_order_count(), + 'total_spent' => wc_format_decimal( $customer->get_total_spent(), 2 ), + 'avatar_url' => $customer->get_avatar_url(), + 'billing_address' => array( + 'first_name' => $customer->get_billing_first_name(), + 'last_name' => $customer->get_billing_last_name(), + 'company' => $customer->get_billing_company(), + 'address_1' => $customer->get_billing_address_1(), + 'address_2' => $customer->get_billing_address_2(), + 'city' => $customer->get_billing_city(), + 'state' => $customer->get_billing_state(), + 'postcode' => $customer->get_billing_postcode(), + 'country' => $customer->get_billing_country(), + 'email' => $customer->get_billing_email(), + 'phone' => $customer->get_billing_phone(), + ), + 'shipping_address' => array( + 'first_name' => $customer->get_shipping_first_name(), + 'last_name' => $customer->get_shipping_last_name(), + 'company' => $customer->get_shipping_company(), + 'address_1' => $customer->get_shipping_address_1(), + 'address_2' => $customer->get_shipping_address_2(), + 'city' => $customer->get_shipping_city(), + 'state' => $customer->get_shipping_state(), + 'postcode' => $customer->get_shipping_postcode(), + 'country' => $customer->get_shipping_country(), + ), + ); + + return array( 'customer' => apply_filters( 'woocommerce_api_customer_response', $customer_data, $customer, $fields, $this->server ) ); + } + + /** + * Get the customer for the given email + * + * @since 2.1 + * + * @param string $email the customer email + * @param array $fields + * + * @return array|WP_Error + */ + public function get_customer_by_email( $email, $fields = null ) { + try { + if ( is_email( $email ) ) { + $customer = get_user_by( 'email', $email ); + if ( ! is_object( $customer ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_email', __( 'Invalid customer email', 'woocommerce' ), 404 ); + } + } else { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_email', __( 'Invalid customer email', 'woocommerce' ), 404 ); + } + + return $this->get_customer( $customer->ID, $fields ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the total number of customers + * + * @since 2.1 + * + * @param array $filter + * + * @return array|WP_Error + */ + public function get_customers_count( $filter = array() ) { + try { + if ( ! current_user_can( 'list_users' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_customers_count', __( 'You do not have permission to read the customers count', 'woocommerce' ), 401 ); + } + + $query = $this->query_customers( $filter ); + + return array( 'count' => $query->get_total() ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get customer billing address fields. + * + * @since 2.2 + * @return array + */ + protected function get_customer_billing_address() { + $billing_address = apply_filters( 'woocommerce_api_customer_billing_address', array( + 'first_name', + 'last_name', + 'company', + 'address_1', + 'address_2', + 'city', + 'state', + 'postcode', + 'country', + 'email', + 'phone', + ) ); + + return $billing_address; + } + + /** + * Get customer shipping address fields. + * + * @since 2.2 + * @return array + */ + protected function get_customer_shipping_address() { + $shipping_address = apply_filters( 'woocommerce_api_customer_shipping_address', array( + 'first_name', + 'last_name', + 'company', + 'address_1', + 'address_2', + 'city', + 'state', + 'postcode', + 'country', + ) ); + + return $shipping_address; + } + + /** + * Add/Update customer data. + * + * @since 2.2 + * @param int $id the customer ID + * @param array $data + * @param WC_Customer $customer + */ + protected function update_customer_data( $id, $data, $customer ) { + + // Customer first name. + if ( isset( $data['first_name'] ) ) { + $customer->set_first_name( wc_clean( $data['first_name'] ) ); + } + + // Customer last name. + if ( isset( $data['last_name'] ) ) { + $customer->set_last_name( wc_clean( $data['last_name'] ) ); + } + + // Customer billing address. + if ( isset( $data['billing_address'] ) ) { + foreach ( $this->get_customer_billing_address() as $field ) { + if ( isset( $data['billing_address'][ $field ] ) ) { + if ( is_callable( array( $customer, "set_billing_{$field}" ) ) ) { + $customer->{"set_billing_{$field}"}( $data['billing_address'][ $field ] ); + } else { + $customer->update_meta_data( 'billing_' . $field, wc_clean( $data['billing_address'][ $field ] ) ); + } + } + } + } + + // Customer shipping address. + if ( isset( $data['shipping_address'] ) ) { + foreach ( $this->get_customer_shipping_address() as $field ) { + if ( isset( $data['shipping_address'][ $field ] ) ) { + if ( is_callable( array( $customer, "set_shipping_{$field}" ) ) ) { + $customer->{"set_shipping_{$field}"}( $data['shipping_address'][ $field ] ); + } else { + $customer->update_meta_data( 'shipping_' . $field, wc_clean( $data['shipping_address'][ $field ] ) ); + } + } + } + } + + do_action( 'woocommerce_api_update_customer_data', $id, $data, $customer ); + } + + /** + * Create a customer + * + * @since 2.2 + * + * @param array $data + * + * @return array|WP_Error + */ + public function create_customer( $data ) { + try { + if ( ! isset( $data['customer'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_customer_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'customer' ), 400 ); + } + + $data = $data['customer']; + + // Checks with can create new users. + if ( ! current_user_can( 'create_users' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_customer', __( 'You do not have permission to create this customer', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_customer_data', $data, $this ); + + // Checks with the email is missing. + if ( ! isset( $data['email'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_customer_email', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'email' ), 400 ); + } + + // Create customer. + $customer = new WC_Customer; + $customer->set_username( ! empty( $data['username'] ) ? $data['username'] : '' ); + $customer->set_password( ! empty( $data['password'] ) ? $data['password'] : '' ); + $customer->set_email( $data['email'] ); + $customer->save(); + + if ( ! $customer->get_id() ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_customer', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); + } + + // Added customer data. + $this->update_customer_data( $customer->get_id(), $data, $customer ); + $customer->save(); + + do_action( 'woocommerce_api_create_customer', $customer->get_id(), $data ); + + $this->server->send_status( 201 ); + + return $this->get_customer( $customer->get_id() ); + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a customer + * + * @since 2.2 + * + * @param int $id the customer ID + * @param array $data + * + * @return array|WP_Error + */ + public function edit_customer( $id, $data ) { + try { + if ( ! isset( $data['customer'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_customer_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'customer' ), 400 ); + } + + $data = $data['customer']; + + // Validate the customer ID. + $id = $this->validate_request( $id, 'customer', 'edit' ); + + // Return the validate error. + if ( is_wp_error( $id ) ) { + throw new WC_API_Exception( $id->get_error_code(), $id->get_error_message(), 400 ); + } + + $data = apply_filters( 'woocommerce_api_edit_customer_data', $data, $this ); + + $customer = new WC_Customer( $id ); + + // Customer email. + if ( isset( $data['email'] ) ) { + $customer->set_email( $data['email'] ); + } + + // Customer password. + if ( isset( $data['password'] ) ) { + $customer->set_password( $data['password'] ); + } + + // Update customer data. + $this->update_customer_data( $customer->get_id(), $data, $customer ); + + $customer->save(); + + do_action( 'woocommerce_api_edit_customer', $customer->get_id(), $data ); + + return $this->get_customer( $customer->get_id() ); + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a customer + * + * @since 2.2 + * @param int $id the customer ID + * @return array|WP_Error + */ + public function delete_customer( $id ) { + + // Validate the customer ID. + $id = $this->validate_request( $id, 'customer', 'delete' ); + + // Return the validate error. + if ( is_wp_error( $id ) ) { + return $id; + } + + do_action( 'woocommerce_api_delete_customer', $id, $this ); + + return $this->delete( $id, 'customer' ); + } + + /** + * Get the orders for a customer + * + * @since 2.1 + * @param int $id the customer ID + * @param string $fields fields to include in response + * @param array $filter filters + * @return array|WP_Error + */ + public function get_customer_orders( $id, $fields = null, $filter = array() ) { + $id = $this->validate_request( $id, 'customer', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $filter['customer_id'] = $id; + $orders = WC()->api->WC_API_Orders->get_orders( $fields, $filter, null, -1 ); + + return $orders; + } + + /** + * Get the available downloads for a customer + * + * @since 2.2 + * @param int $id the customer ID + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_customer_downloads( $id, $fields = null ) { + $id = $this->validate_request( $id, 'customer', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $downloads = array(); + $_downloads = wc_get_customer_available_downloads( $id ); + + foreach ( $_downloads as $key => $download ) { + $downloads[] = array( + 'download_url' => $download['download_url'], + 'download_id' => $download['download_id'], + 'product_id' => $download['product_id'], + 'download_name' => $download['download_name'], + 'order_id' => $download['order_id'], + 'order_key' => $download['order_key'], + 'downloads_remaining' => $download['downloads_remaining'], + 'access_expires' => $download['access_expires'] ? $this->server->format_datetime( $download['access_expires'] ) : null, + 'file' => $download['file'], + ); + } + + return array( 'downloads' => apply_filters( 'woocommerce_api_customer_downloads_response', $downloads, $id, $fields, $this->server ) ); + } + + /** + * Helper method to get customer user objects + * + * Note that WP_User_Query does not have built-in pagination so limit & offset are used to provide limited + * pagination support + * + * The filter for role can only be a single role in a string. + * + * @since 2.3 + * @param array $args request arguments for filtering query + * @return WP_User_Query + */ + private function query_customers( $args = array() ) { + + // default users per page + $users_per_page = get_option( 'posts_per_page' ); + + // Set base query arguments + $query_args = array( + 'fields' => 'ID', + 'role' => 'customer', + 'orderby' => 'registered', + 'number' => $users_per_page, + ); + + // Custom Role + if ( ! empty( $args['role'] ) ) { + $query_args['role'] = $args['role']; + + // Show users on all roles + if ( 'all' === $query_args['role'] ) { + unset( $query_args['role'] ); + } + } + + // Search + if ( ! empty( $args['q'] ) ) { + $query_args['search'] = $args['q']; + } + + // Limit number of users returned + if ( ! empty( $args['limit'] ) ) { + if ( -1 == $args['limit'] ) { + unset( $query_args['number'] ); + } else { + $query_args['number'] = absint( $args['limit'] ); + $users_per_page = absint( $args['limit'] ); + } + } else { + $args['limit'] = $query_args['number']; + } + + // Page + $page = ( isset( $args['page'] ) ) ? absint( $args['page'] ) : 1; + + // Offset + if ( ! empty( $args['offset'] ) ) { + $query_args['offset'] = absint( $args['offset'] ); + } else { + $query_args['offset'] = $users_per_page * ( $page - 1 ); + } + + // Created date + if ( ! empty( $args['created_at_min'] ) ) { + $this->created_at_min = $this->server->parse_datetime( $args['created_at_min'] ); + } + + if ( ! empty( $args['created_at_max'] ) ) { + $this->created_at_max = $this->server->parse_datetime( $args['created_at_max'] ); + } + + // Order (ASC or DESC, ASC by default) + if ( ! empty( $args['order'] ) ) { + $query_args['order'] = $args['order']; + } + + // Order by + if ( ! empty( $args['orderby'] ) ) { + $query_args['orderby'] = $args['orderby']; + + // Allow sorting by meta value + if ( ! empty( $args['orderby_meta_key'] ) ) { + $query_args['meta_key'] = $args['orderby_meta_key']; + } + } + + $query = new WP_User_Query( $query_args ); + + // Helper members for pagination headers + $query->total_pages = ( -1 == $args['limit'] ) ? 1 : ceil( $query->get_total() / $users_per_page ); + $query->page = $page; + + return $query; + } + + /** + * Add customer data to orders + * + * @since 2.1 + * @param $order_data + * @param $order + * @return array + */ + public function add_customer_data( $order_data, $order ) { + + if ( 0 == $order->get_user_id() ) { + + // add customer data from order + $order_data['customer'] = array( + 'id' => 0, + 'email' => $order->get_billing_email(), + 'first_name' => $order->get_billing_first_name(), + 'last_name' => $order->get_billing_last_name(), + 'billing_address' => array( + 'first_name' => $order->get_billing_first_name(), + 'last_name' => $order->get_billing_last_name(), + 'company' => $order->get_billing_company(), + 'address_1' => $order->get_billing_address_1(), + 'address_2' => $order->get_billing_address_2(), + 'city' => $order->get_billing_city(), + 'state' => $order->get_billing_state(), + 'postcode' => $order->get_billing_postcode(), + 'country' => $order->get_billing_country(), + 'email' => $order->get_billing_email(), + 'phone' => $order->get_billing_phone(), + ), + 'shipping_address' => array( + 'first_name' => $order->get_shipping_first_name(), + 'last_name' => $order->get_shipping_last_name(), + 'company' => $order->get_shipping_company(), + 'address_1' => $order->get_shipping_address_1(), + 'address_2' => $order->get_shipping_address_2(), + 'city' => $order->get_shipping_city(), + 'state' => $order->get_shipping_state(), + 'postcode' => $order->get_shipping_postcode(), + 'country' => $order->get_shipping_country(), + ), + ); + + } else { + + $order_data['customer'] = current( $this->get_customer( $order->get_user_id() ) ); + } + + return $order_data; + } + + /** + * Modify the WP_User_Query to support filtering on the date the customer was created + * + * @since 2.1 + * @param WP_User_Query $query + */ + public function modify_user_query( $query ) { + + if ( $this->created_at_min ) { + $query->query_where .= sprintf( " AND user_registered >= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%H:%%i:%%s' )", esc_sql( $this->created_at_min ) ); + } + + if ( $this->created_at_max ) { + $query->query_where .= sprintf( " AND user_registered <= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%H:%%i:%%s' )", esc_sql( $this->created_at_max ) ); + } + } + + /** + * Validate the request by checking: + * + * 1) the ID is a valid integer + * 2) the ID returns a valid WP_User + * 3) the current user has the proper permissions + * + * @since 2.1 + * @see WC_API_Resource::validate_request() + * @param integer $id the customer ID + * @param string $type the request type, unused because this method overrides the parent class + * @param string $context the context of the request, either `read`, `edit` or `delete` + * @return int|WP_Error valid user ID or WP_Error if any of the checks fails + */ + protected function validate_request( $id, $type, $context ) { + + try { + $id = absint( $id ); + + // validate ID + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_id', __( 'Invalid customer ID', 'woocommerce' ), 404 ); + } + + // non-existent IDs return a valid WP_User object with the user ID = 0 + $customer = new WP_User( $id ); + + if ( 0 === $customer->ID ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer', __( 'Invalid customer', 'woocommerce' ), 404 ); + } + + // validate permissions + switch ( $context ) { + + case 'read': + if ( ! current_user_can( 'list_users' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_customer', __( 'You do not have permission to read this customer', 'woocommerce' ), 401 ); + } + break; + + case 'edit': + if ( ! wc_rest_check_user_permissions( 'edit', $customer->ID ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_customer', __( 'You do not have permission to edit this customer', 'woocommerce' ), 401 ); + } + break; + + case 'delete': + if ( ! wc_rest_check_user_permissions( 'delete', $customer->ID ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_customer', __( 'You do not have permission to delete this customer', 'woocommerce' ), 401 ); + } + break; + } + + return $id; + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Check if the current user can read users + * + * @since 2.1 + * @see WC_API_Resource::is_readable() + * @param int|WP_Post $post unused + * @return bool true if the current user can read users, false otherwise + */ + protected function is_readable( $post ) { + return current_user_can( 'list_users' ); + } + + /** + * Bulk update or insert customers + * Accepts an array with customers in the formats supported by + * WC_API_Customers->create_customer() and WC_API_Customers->edit_customer() + * + * @since 2.4.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function bulk( $data ) { + + try { + if ( ! isset( $data['customers'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_customers_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'customers' ), 400 ); + } + + $data = $data['customers']; + $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'customers' ); + + // Limit bulk operation + if ( count( $data ) > $limit ) { + throw new WC_API_Exception( 'woocommerce_api_customers_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); + } + + $customers = array(); + + foreach ( $data as $_customer ) { + $customer_id = 0; + + // Try to get the customer ID + if ( isset( $_customer['id'] ) ) { + $customer_id = intval( $_customer['id'] ); + } + + if ( $customer_id ) { + + // Customer exists / edit customer + $edit = $this->edit_customer( $customer_id, array( 'customer' => $_customer ) ); + + if ( is_wp_error( $edit ) ) { + $customers[] = array( + 'id' => $customer_id, + 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ), + ); + } else { + $customers[] = $edit['customer']; + } + } else { + + // Customer don't exists / create customer + $new = $this->create_customer( array( 'customer' => $_customer ) ); + + if ( is_wp_error( $new ) ) { + $customers[] = array( + 'id' => $customer_id, + 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ), + ); + } else { + $customers[] = $new['customer']; + } + } + } + + return array( 'customers' => apply_filters( 'woocommerce_api_customers_bulk_response', $customers, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-exception.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-exception.php new file mode 100644 index 0000000..5000f76 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-exception.php @@ -0,0 +1,48 @@ +error_code = $error_code; + parent::__construct( $error_message, $http_status_code ); + } + + /** + * Returns the error code + * + * @since 2.2 + * @return string + */ + public function getErrorCode() { + return $this->error_code; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-json-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-json-handler.php new file mode 100644 index 0000000..ee4d5e8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-json-handler.php @@ -0,0 +1,73 @@ +api->server->send_status( 400 ); + return wp_json_encode( array( array( 'code' => 'woocommerce_api_jsonp_disabled', 'message' => __( 'JSONP support is disabled on this site', 'woocommerce' ) ) ) ); + } + + $jsonp_callback = $_GET['_jsonp']; + + if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) { + WC()->api->server->send_status( 400 ); + return wp_json_encode( array( array( 'code' => 'woocommerce_api_jsonp_callback_invalid', __( 'The JSONP callback function is invalid', 'woocommerce' ) ) ) ); + } + + WC()->api->server->header( 'X-Content-Type-Options', 'nosniff' ); + + // Prepend '/**/' to mitigate possible JSONP Flash attacks. + // https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/ + return '/**/' . $jsonp_callback . '(' . wp_json_encode( $data ) . ')'; + } + + return wp_json_encode( $data ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php new file mode 100644 index 0000000..2fe2b6c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php @@ -0,0 +1,1877 @@ + + * GET /orders//notes + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET|POST /orders + $routes[ $this->base ] = array( + array( array( $this, 'get_orders' ), WC_API_Server::READABLE ), + array( array( $this, 'create_order' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /orders/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_orders_count' ), WC_API_Server::READABLE ), + ); + + # GET /orders/statuses + $routes[ $this->base . '/statuses' ] = array( + array( array( $this, 'get_order_statuses' ), WC_API_Server::READABLE ), + ); + + # GET|PUT|DELETE /orders/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_order' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_order' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_order' ), WC_API_Server::DELETABLE ), + ); + + # GET|POST /orders//notes + $routes[ $this->base . '/(?P\d+)/notes' ] = array( + array( array( $this, 'get_order_notes' ), WC_API_Server::READABLE ), + array( array( $this, 'create_order_note' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET|PUT|DELETE /orders//notes/ + $routes[ $this->base . '/(?P\d+)/notes/(?P\d+)' ] = array( + array( array( $this, 'get_order_note' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_order_note' ), WC_API_SERVER::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_order_note' ), WC_API_SERVER::DELETABLE ), + ); + + # GET|POST /orders//refunds + $routes[ $this->base . '/(?P\d+)/refunds' ] = array( + array( array( $this, 'get_order_refunds' ), WC_API_Server::READABLE ), + array( array( $this, 'create_order_refund' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET|PUT|DELETE /orders//refunds/ + $routes[ $this->base . '/(?P\d+)/refunds/(?P\d+)' ] = array( + array( array( $this, 'get_order_refund' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_order_refund' ), WC_API_SERVER::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_order_refund' ), WC_API_SERVER::DELETABLE ), + ); + + # POST|PUT /orders/bulk + $routes[ $this->base . '/bulk' ] = array( + array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + return $routes; + } + + /** + * Get all orders + * + * @since 2.1 + * @param string $fields + * @param array $filter + * @param string $status + * @param int $page + * @return array + */ + public function get_orders( $fields = null, $filter = array(), $status = null, $page = 1 ) { + + if ( ! empty( $status ) ) { + $filter['status'] = $status; + } + + $filter['page'] = $page; + + $query = $this->query_orders( $filter ); + + $orders = array(); + + foreach ( $query->posts as $order_id ) { + + if ( ! $this->is_readable( $order_id ) ) { + continue; + } + + $orders[] = current( $this->get_order( $order_id, $fields, $filter ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'orders' => $orders ); + } + + + /** + * Get the order for the given ID. + * + * @since 2.1 + * @param int $id The order ID. + * @param array $fields Request fields. + * @param array $filter Request filters. + * @return array|WP_Error + */ + public function get_order( $id, $fields = null, $filter = array() ) { + + // Ensure order ID is valid & user has permission to read. + $id = $this->validate_request( $id, $this->post_type, 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + // Get the decimal precession. + $dp = ( isset( $filter['dp'] ) ? intval( $filter['dp'] ) : 2 ); + $order = wc_get_order( $id ); + $expand = array(); + + if ( ! empty( $filter['expand'] ) ) { + $expand = explode( ',', $filter['expand'] ); + } + + $order_data = array( + 'id' => $order->get_id(), + 'order_number' => $order->get_order_number(), + 'order_key' => $order->get_order_key(), + 'created_at' => $this->server->format_datetime( $order->get_date_created() ? $order->get_date_created()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'updated_at' => $this->server->format_datetime( $order->get_date_modified() ? $order->get_date_modified()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'completed_at' => $this->server->format_datetime( $order->get_date_completed() ? $order->get_date_completed()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'status' => $order->get_status(), + 'currency' => $order->get_currency(), + 'total' => wc_format_decimal( $order->get_total(), $dp ), + 'subtotal' => wc_format_decimal( $order->get_subtotal(), $dp ), + 'total_line_items_quantity' => $order->get_item_count(), + 'total_tax' => wc_format_decimal( $order->get_total_tax(), $dp ), + 'total_shipping' => wc_format_decimal( $order->get_shipping_total(), $dp ), + 'cart_tax' => wc_format_decimal( $order->get_cart_tax(), $dp ), + 'shipping_tax' => wc_format_decimal( $order->get_shipping_tax(), $dp ), + 'total_discount' => wc_format_decimal( $order->get_total_discount(), $dp ), + 'shipping_methods' => $order->get_shipping_method(), + 'payment_details' => array( + 'method_id' => $order->get_payment_method(), + 'method_title' => $order->get_payment_method_title(), + 'paid' => ! is_null( $order->get_date_paid() ), + ), + 'billing_address' => array( + 'first_name' => $order->get_billing_first_name(), + 'last_name' => $order->get_billing_last_name(), + 'company' => $order->get_billing_company(), + 'address_1' => $order->get_billing_address_1(), + 'address_2' => $order->get_billing_address_2(), + 'city' => $order->get_billing_city(), + 'state' => $order->get_billing_state(), + 'postcode' => $order->get_billing_postcode(), + 'country' => $order->get_billing_country(), + 'email' => $order->get_billing_email(), + 'phone' => $order->get_billing_phone(), + ), + 'shipping_address' => array( + 'first_name' => $order->get_shipping_first_name(), + 'last_name' => $order->get_shipping_last_name(), + 'company' => $order->get_shipping_company(), + 'address_1' => $order->get_shipping_address_1(), + 'address_2' => $order->get_shipping_address_2(), + 'city' => $order->get_shipping_city(), + 'state' => $order->get_shipping_state(), + 'postcode' => $order->get_shipping_postcode(), + 'country' => $order->get_shipping_country(), + ), + 'note' => $order->get_customer_note(), + 'customer_ip' => $order->get_customer_ip_address(), + 'customer_user_agent' => $order->get_customer_user_agent(), + 'customer_id' => $order->get_user_id(), + 'view_order_url' => $order->get_view_order_url(), + 'line_items' => array(), + 'shipping_lines' => array(), + 'tax_lines' => array(), + 'fee_lines' => array(), + 'coupon_lines' => array(), + ); + + // Add line items. + foreach ( $order->get_items() as $item_id => $item ) { + $product = $item->get_product(); + $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; + $item_meta = $item->get_formatted_meta_data( $hideprefix ); + + foreach ( $item_meta as $key => $values ) { + $item_meta[ $key ]->label = $values->display_key; + unset( $item_meta[ $key ]->display_key ); + unset( $item_meta[ $key ]->display_value ); + } + + $line_item = array( + 'id' => $item_id, + 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item, false, false ), $dp ), + 'subtotal_tax' => wc_format_decimal( $item->get_subtotal_tax(), $dp ), + 'total' => wc_format_decimal( $order->get_line_total( $item, false, false ), $dp ), + 'total_tax' => wc_format_decimal( $item->get_total_tax(), $dp ), + 'price' => wc_format_decimal( $order->get_item_total( $item, false, false ), $dp ), + 'quantity' => $item->get_quantity(), + 'tax_class' => $item->get_tax_class(), + 'name' => $item->get_name(), + 'product_id' => $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id(), + 'sku' => is_object( $product ) ? $product->get_sku() : null, + 'meta' => array_values( $item_meta ), + ); + + if ( in_array( 'products', $expand ) && is_object( $product ) ) { + $_product_data = WC()->api->WC_API_Products->get_product( $product->get_id() ); + + if ( isset( $_product_data['product'] ) ) { + $line_item['product_data'] = $_product_data['product']; + } + } + + $order_data['line_items'][] = $line_item; + } + + // Add shipping. + foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) { + $order_data['shipping_lines'][] = array( + 'id' => $shipping_item_id, + 'method_id' => $shipping_item->get_method_id(), + 'method_title' => $shipping_item->get_name(), + 'total' => wc_format_decimal( $shipping_item->get_total(), $dp ), + ); + } + + // Add taxes. + foreach ( $order->get_tax_totals() as $tax_code => $tax ) { + $tax_line = array( + 'id' => $tax->id, + 'rate_id' => $tax->rate_id, + 'code' => $tax_code, + 'title' => $tax->label, + 'total' => wc_format_decimal( $tax->amount, $dp ), + 'compound' => (bool) $tax->is_compound, + ); + + if ( in_array( 'taxes', $expand ) ) { + $_rate_data = WC()->api->WC_API_Taxes->get_tax( $tax->rate_id ); + + if ( isset( $_rate_data['tax'] ) ) { + $tax_line['rate_data'] = $_rate_data['tax']; + } + } + + $order_data['tax_lines'][] = $tax_line; + } + + // Add fees. + foreach ( $order->get_fees() as $fee_item_id => $fee_item ) { + $order_data['fee_lines'][] = array( + 'id' => $fee_item_id, + 'title' => $fee_item->get_name(), + 'tax_class' => $fee_item->get_tax_class(), + 'total' => wc_format_decimal( $order->get_line_total( $fee_item ), $dp ), + 'total_tax' => wc_format_decimal( $order->get_line_tax( $fee_item ), $dp ), + ); + } + + // Add coupons. + foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) { + $coupon_line = array( + 'id' => $coupon_item_id, + 'code' => $coupon_item->get_code(), + 'amount' => wc_format_decimal( $coupon_item->get_discount(), $dp ), + ); + + if ( in_array( 'coupons', $expand ) ) { + $_coupon_data = WC()->api->WC_API_Coupons->get_coupon_by_code( $coupon_item->get_code() ); + + if ( ! is_wp_error( $_coupon_data ) && isset( $_coupon_data['coupon'] ) ) { + $coupon_line['coupon_data'] = $_coupon_data['coupon']; + } + } + + $order_data['coupon_lines'][] = $coupon_line; + } + + return array( 'order' => apply_filters( 'woocommerce_api_order_response', $order_data, $order, $fields, $this->server ) ); + } + + /** + * Get the total number of orders + * + * @since 2.4 + * + * @param string $status + * @param array $filter + * + * @return array|WP_Error + */ + public function get_orders_count( $status = null, $filter = array() ) { + + try { + if ( ! current_user_can( 'read_private_shop_orders' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_orders_count', __( 'You do not have permission to read the orders count', 'woocommerce' ), 401 ); + } + + if ( ! empty( $status ) ) { + + if ( 'any' === $status ) { + + $order_statuses = array(); + + foreach ( wc_get_order_statuses() as $slug => $name ) { + $filter['status'] = str_replace( 'wc-', '', $slug ); + $query = $this->query_orders( $filter ); + $order_statuses[ str_replace( 'wc-', '', $slug ) ] = (int) $query->found_posts; + } + + return array( 'count' => $order_statuses ); + + } else { + $filter['status'] = $status; + } + } + + $query = $this->query_orders( $filter ); + + return array( 'count' => (int) $query->found_posts ); + + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get a list of valid order statuses + * + * Note this requires no specific permissions other than being an authenticated + * API user. Order statuses (particularly custom statuses) could be considered + * private information which is why it's not in the API index. + * + * @since 2.1 + * @return array + */ + public function get_order_statuses() { + + $order_statuses = array(); + + foreach ( wc_get_order_statuses() as $slug => $name ) { + $order_statuses[ str_replace( 'wc-', '', $slug ) ] = $name; + } + + return array( 'order_statuses' => apply_filters( 'woocommerce_api_order_statuses_response', $order_statuses, $this ) ); + } + + /** + * Create an order + * + * @since 2.2 + * @param array $data raw order data + * @return array|WP_Error + */ + public function create_order( $data ) { + global $wpdb; + + try { + if ( ! isset( $data['order'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'order' ), 400 ); + } + + $data = $data['order']; + + // permission check + if ( ! current_user_can( 'publish_shop_orders' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_order', __( 'You do not have permission to create orders', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_order_data', $data, $this ); + + // default order args, note that status is checked for validity in wc_create_order() + $default_order_args = array( + 'status' => isset( $data['status'] ) ? $data['status'] : '', + 'customer_note' => isset( $data['note'] ) ? $data['note'] : null, + ); + + // if creating order for existing customer + if ( ! empty( $data['customer_id'] ) ) { + + // make sure customer exists + if ( false === get_user_by( 'id', $data['customer_id'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + $default_order_args['customer_id'] = $data['customer_id']; + } + + // create the pending order + $order = $this->create_base_order( $default_order_args, $data ); + + if ( is_wp_error( $order ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_order', sprintf( __( 'Cannot create order: %s', 'woocommerce' ), implode( ', ', $order->get_error_messages() ) ), 400 ); + } + + // billing/shipping addresses + $this->set_order_addresses( $order, $data ); + + $lines = array( + 'line_item' => 'line_items', + 'shipping' => 'shipping_lines', + 'fee' => 'fee_lines', + 'coupon' => 'coupon_lines', + ); + + foreach ( $lines as $line_type => $line ) { + + if ( isset( $data[ $line ] ) && is_array( $data[ $line ] ) ) { + + $set_item = "set_{$line_type}"; + + foreach ( $data[ $line ] as $item ) { + + $this->$set_item( $order, $item, 'create' ); + } + } + } + + // set is vat exempt + if ( isset( $data['is_vat_exempt'] ) ) { + update_post_meta( $order->get_id(), '_is_vat_exempt', $data['is_vat_exempt'] ? 'yes' : 'no' ); + } + + // calculate totals and set them + $order->calculate_totals(); + + // payment method (and payment_complete() if `paid` == true) + if ( isset( $data['payment_details'] ) && is_array( $data['payment_details'] ) ) { + + // method ID & title are required + if ( empty( $data['payment_details']['method_id'] ) || empty( $data['payment_details']['method_title'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_payment_details', __( 'Payment method ID and title are required', 'woocommerce' ), 400 ); + } + + update_post_meta( $order->get_id(), '_payment_method', $data['payment_details']['method_id'] ); + update_post_meta( $order->get_id(), '_payment_method_title', sanitize_text_field( $data['payment_details']['method_title'] ) ); + + // mark as paid if set + if ( isset( $data['payment_details']['paid'] ) && true === $data['payment_details']['paid'] ) { + $order->payment_complete( isset( $data['payment_details']['transaction_id'] ) ? $data['payment_details']['transaction_id'] : '' ); + } + } + + // set order currency + if ( isset( $data['currency'] ) ) { + + if ( ! array_key_exists( $data['currency'], get_woocommerce_currencies() ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_order_currency', __( 'Provided order currency is invalid.', 'woocommerce' ), 400 ); + } + + update_post_meta( $order->get_id(), '_order_currency', $data['currency'] ); + } + + // set order meta + if ( isset( $data['order_meta'] ) && is_array( $data['order_meta'] ) ) { + $this->set_order_meta( $order->get_id(), $data['order_meta'] ); + } + + // HTTP 201 Created + $this->server->send_status( 201 ); + + wc_delete_shop_order_transients( $order ); + + do_action( 'woocommerce_api_create_order', $order->get_id(), $data, $this ); + do_action( 'woocommerce_new_order', $order->get_id() ); + + return $this->get_order( $order->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Creates new WC_Order. + * + * Requires a separate function for classes that extend WC_API_Orders. + * + * @since 2.3 + * + * @param $args array + * @param $data + * + * @return WC_Order + */ + protected function create_base_order( $args, $data ) { + return wc_create_order( $args ); + } + + /** + * Edit an order + * + * @since 2.2 + * @param int $id the order ID + * @param array $data + * @return array|WP_Error + */ + public function edit_order( $id, $data ) { + try { + if ( ! isset( $data['order'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'order' ), 400 ); + } + + $data = $data['order']; + + $update_totals = false; + + $id = $this->validate_request( $id, $this->post_type, 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $data = apply_filters( 'woocommerce_api_edit_order_data', $data, $id, $this ); + $order = wc_get_order( $id ); + + if ( empty( $order ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_id', __( 'Order ID is invalid', 'woocommerce' ), 400 ); + } + + $order_args = array( 'order_id' => $order->get_id() ); + + // Customer note. + if ( isset( $data['note'] ) ) { + $order_args['customer_note'] = $data['note']; + } + + // Customer ID. + if ( isset( $data['customer_id'] ) && $data['customer_id'] != $order->get_user_id() ) { + // Make sure customer exists. + if ( false === get_user_by( 'id', $data['customer_id'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + update_post_meta( $order->get_id(), '_customer_user', $data['customer_id'] ); + } + + // Billing/shipping address. + $this->set_order_addresses( $order, $data ); + + $lines = array( + 'line_item' => 'line_items', + 'shipping' => 'shipping_lines', + 'fee' => 'fee_lines', + 'coupon' => 'coupon_lines', + ); + + foreach ( $lines as $line_type => $line ) { + + if ( isset( $data[ $line ] ) && is_array( $data[ $line ] ) ) { + + $update_totals = true; + + foreach ( $data[ $line ] as $item ) { + // Item ID is always required. + if ( ! array_key_exists( 'id', $item ) ) { + $item['id'] = null; + } + + // Create item. + if ( is_null( $item['id'] ) ) { + $this->set_item( $order, $line_type, $item, 'create' ); + } elseif ( $this->item_is_null( $item ) ) { + // Delete item. + wc_delete_order_item( $item['id'] ); + } else { + // Update item. + $this->set_item( $order, $line_type, $item, 'update' ); + } + } + } + } + + // Payment method (and payment_complete() if `paid` == true and order needs payment). + if ( isset( $data['payment_details'] ) && is_array( $data['payment_details'] ) ) { + + // Method ID. + if ( isset( $data['payment_details']['method_id'] ) ) { + update_post_meta( $order->get_id(), '_payment_method', $data['payment_details']['method_id'] ); + } + + // Method title. + if ( isset( $data['payment_details']['method_title'] ) ) { + update_post_meta( $order->get_id(), '_payment_method_title', sanitize_text_field( $data['payment_details']['method_title'] ) ); + } + + // Mark as paid if set. + if ( $order->needs_payment() && isset( $data['payment_details']['paid'] ) && true === $data['payment_details']['paid'] ) { + $order->payment_complete( isset( $data['payment_details']['transaction_id'] ) ? $data['payment_details']['transaction_id'] : '' ); + } + } + + // Set order currency. + if ( isset( $data['currency'] ) ) { + if ( ! array_key_exists( $data['currency'], get_woocommerce_currencies() ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_order_currency', __( 'Provided order currency is invalid.', 'woocommerce' ), 400 ); + } + + update_post_meta( $order->get_id(), '_order_currency', $data['currency'] ); + } + + // If items have changed, recalculate order totals. + if ( $update_totals ) { + $order->calculate_totals(); + } + + // Update order meta. + if ( isset( $data['order_meta'] ) && is_array( $data['order_meta'] ) ) { + $this->set_order_meta( $order->get_id(), $data['order_meta'] ); + } + + // Update the order post to set customer note/modified date. + wc_update_order( $order_args ); + + // Order status. + if ( ! empty( $data['status'] ) ) { + // Refresh the order instance. + $order = wc_get_order( $order->get_id() ); + $order->update_status( $data['status'], isset( $data['status_note'] ) ? $data['status_note'] : '', true ); + } + + wc_delete_shop_order_transients( $order ); + + do_action( 'woocommerce_api_edit_order', $order->get_id(), $data, $this ); + do_action( 'woocommerce_update_order', $order->get_id() ); + + return $this->get_order( $id ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete an order + * + * @param int $id the order ID + * @param bool $force true to permanently delete order, false to move to trash + * @return array|WP_Error + */ + public function delete_order( $id, $force = false ) { + + $id = $this->validate_request( $id, $this->post_type, 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + wc_delete_shop_order_transients( $id ); + + do_action( 'woocommerce_api_delete_order', $id, $this ); + + return $this->delete( $id, 'order', ( 'true' === $force ) ); + } + + /** + * Helper method to get order post objects + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_Query + */ + protected function query_orders( $args ) { + + // set base query arguments + $query_args = array( + 'fields' => 'ids', + 'post_type' => $this->post_type, + 'post_status' => array_keys( wc_get_order_statuses() ), + ); + + // add status argument + if ( ! empty( $args['status'] ) ) { + $statuses = 'wc-' . str_replace( ',', ',wc-', $args['status'] ); + $statuses = explode( ',', $statuses ); + $query_args['post_status'] = $statuses; + + unset( $args['status'] ); + } + + if ( ! empty( $args['customer_id'] ) ) { + $query_args['meta_query'] = array( + array( + 'key' => '_customer_user', + 'value' => absint( $args['customer_id'] ), + 'compare' => '=', + ), + ); + } + + $query_args = $this->merge_query_args( $query_args, $args ); + + return new WP_Query( $query_args ); + } + + /** + * Helper method to set/update the billing & shipping addresses for + * an order + * + * @since 2.1 + * @param \WC_Order $order + * @param array $data + */ + protected function set_order_addresses( $order, $data ) { + + $address_fields = array( + 'first_name', + 'last_name', + 'company', + 'email', + 'phone', + 'address_1', + 'address_2', + 'city', + 'state', + 'postcode', + 'country', + ); + + $billing_address = $shipping_address = array(); + + // billing address + if ( isset( $data['billing_address'] ) && is_array( $data['billing_address'] ) ) { + + foreach ( $address_fields as $field ) { + + if ( isset( $data['billing_address'][ $field ] ) ) { + $billing_address[ $field ] = wc_clean( $data['billing_address'][ $field ] ); + } + } + + unset( $address_fields['email'] ); + unset( $address_fields['phone'] ); + } + + // shipping address + if ( isset( $data['shipping_address'] ) && is_array( $data['shipping_address'] ) ) { + + foreach ( $address_fields as $field ) { + + if ( isset( $data['shipping_address'][ $field ] ) ) { + $shipping_address[ $field ] = wc_clean( $data['shipping_address'][ $field ] ); + } + } + } + + $this->update_address( $order, $billing_address, 'billing' ); + $this->update_address( $order, $shipping_address, 'shipping' ); + + // update user meta + if ( $order->get_user_id() ) { + foreach ( $billing_address as $key => $value ) { + update_user_meta( $order->get_user_id(), 'billing_' . $key, $value ); + } + foreach ( $shipping_address as $key => $value ) { + update_user_meta( $order->get_user_id(), 'shipping_' . $key, $value ); + } + } + } + + /** + * Update address. + * + * @param WC_Order $order + * @param array $posted + * @param string $type + */ + protected function update_address( $order, $posted, $type = 'billing' ) { + foreach ( $posted as $key => $value ) { + if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { + $order->{"set_{$type}_{$key}"}( $value ); + } + } + } + + /** + * Helper method to add/update order meta, with two restrictions: + * + * 1) Only non-protected meta (no leading underscore) can be set + * 2) Meta values must be scalar (int, string, bool) + * + * @since 2.2 + * @param int $order_id valid order ID + * @param array $order_meta order meta in array( 'meta_key' => 'meta_value' ) format + */ + protected function set_order_meta( $order_id, $order_meta ) { + + foreach ( $order_meta as $meta_key => $meta_value ) { + + if ( is_string( $meta_key ) && ! is_protected_meta( $meta_key ) && is_scalar( $meta_value ) ) { + update_post_meta( $order_id, $meta_key, $meta_value ); + } + } + } + + /** + * Helper method to check if the resource ID associated with the provided item is null + * + * Items can be deleted by setting the resource ID to null + * + * @since 2.2 + * @param array $item item provided in the request body + * @return bool true if the item resource ID is null, false otherwise + */ + protected function item_is_null( $item ) { + + $keys = array( 'product_id', 'method_id', 'title', 'code' ); + + foreach ( $keys as $key ) { + if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { + return true; + } + } + + return false; + } + + /** + * Wrapper method to create/update order items + * + * When updating, the item ID provided is checked to ensure it is associated + * with the order. + * + * @since 2.2 + * @param \WC_Order $order order + * @param string $item_type + * @param array $item item provided in the request body + * @param string $action either 'create' or 'update' + * @throws WC_API_Exception if item ID is not associated with order + */ + protected function set_item( $order, $item_type, $item, $action ) { + global $wpdb; + + $set_method = "set_{$item_type}"; + + // verify provided line item ID is associated with order + if ( 'update' === $action ) { + + $result = $wpdb->get_row( + $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d AND order_id = %d", + absint( $item['id'] ), + absint( $order->get_id() ) + ) ); + + if ( is_null( $result ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + } + } + + $this->$set_method( $order, $item, $action ); + } + + /** + * Create or update a line item + * + * @since 2.2 + * @param \WC_Order $order + * @param array $item line item data + * @param string $action 'create' to add line item or 'update' to update it + * @throws WC_API_Exception invalid data, server error + */ + protected function set_line_item( $order, $item, $action ) { + $creating = ( 'create' === $action ); + + // product is always required + if ( ! isset( $item['product_id'] ) && ! isset( $item['sku'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_id', __( 'Product ID or SKU is required', 'woocommerce' ), 400 ); + } + + // when updating, ensure product ID provided matches + if ( 'update' === $action ) { + + $item_product_id = wc_get_order_item_meta( $item['id'], '_product_id' ); + $item_variation_id = wc_get_order_item_meta( $item['id'], '_variation_id' ); + + if ( $item['product_id'] != $item_product_id && $item['product_id'] != $item_variation_id ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_id', __( 'Product ID provided does not match this line item', 'woocommerce' ), 400 ); + } + } + + if ( isset( $item['product_id'] ) ) { + $product_id = $item['product_id']; + } elseif ( isset( $item['sku'] ) ) { + $product_id = wc_get_product_id_by_sku( $item['sku'] ); + } + + // variations must each have a key & value + $variation_id = 0; + if ( isset( $item['variations'] ) && is_array( $item['variations'] ) ) { + foreach ( $item['variations'] as $key => $value ) { + if ( ! $key || ! $value ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_variation', __( 'The product variation is invalid', 'woocommerce' ), 400 ); + } + } + $variation_id = $this->get_variation_id( wc_get_product( $product_id ), $item['variations'] ); + } + + $product = wc_get_product( $variation_id ? $variation_id : $product_id ); + + // must be a valid WC_Product + if ( ! is_object( $product ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product', __( 'Product is invalid.', 'woocommerce' ), 400 ); + } + + // quantity must be positive float + if ( isset( $item['quantity'] ) && floatval( $item['quantity'] ) <= 0 ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_quantity', __( 'Product quantity must be a positive float.', 'woocommerce' ), 400 ); + } + + // quantity is required when creating + if ( $creating && ! isset( $item['quantity'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_quantity', __( 'Product quantity is required.', 'woocommerce' ), 400 ); + } + + // quantity + if ( $creating ) { + $line_item = new WC_Order_Item_Product(); + } else { + $line_item = new WC_Order_Item_Product( $item['id'] ); + } + + $line_item->set_product( $product ); + $line_item->set_order_id( $order->get_id() ); + + if ( isset( $item['quantity'] ) ) { + $line_item->set_quantity( $item['quantity'] ); + } + if ( isset( $item['total'] ) ) { + $line_item->set_total( floatval( $item['total'] ) ); + } elseif ( $creating ) { + $total = wc_get_price_excluding_tax( $product, array( 'qty' => $line_item->get_quantity() ) ); + $line_item->set_total( $total ); + $line_item->set_subtotal( $total ); + } + if ( isset( $item['total_tax'] ) ) { + $line_item->set_total_tax( floatval( $item['total_tax'] ) ); + } + if ( isset( $item['subtotal'] ) ) { + $line_item->set_subtotal( floatval( $item['subtotal'] ) ); + } + if ( isset( $item['subtotal_tax'] ) ) { + $line_item->set_subtotal_tax( floatval( $item['subtotal_tax'] ) ); + } + if ( $variation_id ) { + $line_item->set_variation_id( $variation_id ); + $line_item->set_variation( $item['variations'] ); + } + + // Save or add to order. + if ( $creating ) { + $order->add_item( $line_item ); + } else { + $item_id = $line_item->save(); + + if ( ! $item_id ) { + throw new WC_API_Exception( 'woocommerce_cannot_create_line_item', __( 'Cannot create line item, try again.', 'woocommerce' ), 500 ); + } + } + } + + /** + * Given a product ID & API provided variations, find the correct variation ID to use for calculation + * We can't just trust input from the API to pass a variation_id manually, otherwise you could pass + * the cheapest variation ID but provide other information so we have to look up the variation ID. + * + * @param WC_Product $product Product instance + * @param array $variations + * + * @return int Returns an ID if a valid variation was found for this product + */ + public function get_variation_id( $product, $variations = array() ) { + $variation_id = null; + $variations_normalized = array(); + + if ( $product->is_type( 'variable' ) && $product->has_child() ) { + if ( isset( $variations ) && is_array( $variations ) ) { + // start by normalizing the passed variations + foreach ( $variations as $key => $value ) { + $key = str_replace( 'attribute_', '', wc_attribute_taxonomy_slug( $key ) ); // from get_attributes in class-wc-api-products.php + $variations_normalized[ $key ] = strtolower( $value ); + } + // now search through each product child and see if our passed variations match anything + foreach ( $product->get_children() as $variation ) { + $meta = array(); + foreach ( get_post_meta( $variation ) as $key => $value ) { + $value = $value[0]; + $key = str_replace( 'attribute_', '', wc_attribute_taxonomy_slug( $key ) ); + $meta[ $key ] = strtolower( $value ); + } + // if the variation array is a part of the $meta array, we found our match + if ( $this->array_contains( $variations_normalized, $meta ) ) { + $variation_id = $variation; + break; + } + } + } + } + + return $variation_id; + } + + /** + * Utility function to see if the meta array contains data from variations + * + * @param array $needles + * @param array $haystack + * + * @return bool + */ + protected function array_contains( $needles, $haystack ) { + foreach ( $needles as $key => $value ) { + if ( $haystack[ $key ] !== $value ) { + return false; + } + } + return true; + } + + /** + * Create or update an order shipping method + * + * @since 2.2 + * @param \WC_Order $order + * @param array $shipping item data + * @param string $action 'create' to add shipping or 'update' to update it + * @throws WC_API_Exception invalid data, server error + */ + protected function set_shipping( $order, $shipping, $action ) { + + // total must be a positive float + if ( isset( $shipping['total'] ) && floatval( $shipping['total'] ) < 0 ) { + throw new WC_API_Exception( 'woocommerce_invalid_shipping_total', __( 'Shipping total must be a positive amount.', 'woocommerce' ), 400 ); + } + + if ( 'create' === $action ) { + + // method ID is required + if ( ! isset( $shipping['method_id'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + } + + $rate = new WC_Shipping_Rate( $shipping['method_id'], isset( $shipping['method_title'] ) ? $shipping['method_title'] : '', isset( $shipping['total'] ) ? floatval( $shipping['total'] ) : 0, array(), $shipping['method_id'] ); + $item = new WC_Order_Item_Shipping(); + $item->set_order_id( $order->get_id() ); + $item->set_shipping_rate( $rate ); + $order->add_item( $item ); + } else { + + $item = new WC_Order_Item_Shipping( $shipping['id'] ); + + if ( isset( $shipping['method_id'] ) ) { + $item->set_method_id( $shipping['method_id'] ); + } + + if ( isset( $shipping['method_title'] ) ) { + $item->set_method_title( $shipping['method_title'] ); + } + + if ( isset( $shipping['total'] ) ) { + $item->set_total( floatval( $shipping['total'] ) ); + } + + $shipping_id = $item->save(); + + if ( ! $shipping_id ) { + throw new WC_API_Exception( 'woocommerce_cannot_update_shipping', __( 'Cannot update shipping method, try again.', 'woocommerce' ), 500 ); + } + } + } + + /** + * Create or update an order fee + * + * @since 2.2 + * @param \WC_Order $order + * @param array $fee item data + * @param string $action 'create' to add fee or 'update' to update it + * @throws WC_API_Exception invalid data, server error + */ + protected function set_fee( $order, $fee, $action ) { + + if ( 'create' === $action ) { + + // fee title is required + if ( ! isset( $fee['title'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_fee_item', __( 'Fee title is required', 'woocommerce' ), 400 ); + } + + $item = new WC_Order_Item_Fee(); + $item->set_order_id( $order->get_id() ); + $item->set_name( wc_clean( $fee['title'] ) ); + $item->set_total( isset( $fee['total'] ) ? floatval( $fee['total'] ) : 0 ); + + // if taxable, tax class and total are required + if ( ! empty( $fee['taxable'] ) ) { + if ( ! isset( $fee['tax_class'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_fee_item', __( 'Fee tax class is required when fee is taxable.', 'woocommerce' ), 400 ); + } + + $item->set_tax_status( 'taxable' ); + $item->set_tax_class( $fee['tax_class'] ); + + if ( isset( $fee['total_tax'] ) ) { + $item->set_total_tax( isset( $fee['total_tax'] ) ? wc_format_refund_total( $fee['total_tax'] ) : 0 ); + } + + if ( isset( $fee['tax_data'] ) ) { + $item->set_total_tax( wc_format_refund_total( array_sum( $fee['tax_data'] ) ) ); + $item->set_taxes( array_map( 'wc_format_refund_total', $fee['tax_data'] ) ); + } + } + + $order->add_item( $item ); + } else { + + $item = new WC_Order_Item_Fee( $fee['id'] ); + + if ( isset( $fee['title'] ) ) { + $item->set_name( wc_clean( $fee['title'] ) ); + } + + if ( isset( $fee['tax_class'] ) ) { + $item->set_tax_class( $fee['tax_class'] ); + } + + if ( isset( $fee['total'] ) ) { + $item->set_total( floatval( $fee['total'] ) ); + } + + if ( isset( $fee['total_tax'] ) ) { + $item->set_total_tax( floatval( $fee['total_tax'] ) ); + } + + $fee_id = $item->save(); + + if ( ! $fee_id ) { + throw new WC_API_Exception( 'woocommerce_cannot_update_fee', __( 'Cannot update fee, try again.', 'woocommerce' ), 500 ); + } + } + } + + /** + * Create or update an order coupon + * + * @since 2.2 + * @param \WC_Order $order + * @param array $coupon item data + * @param string $action 'create' to add coupon or 'update' to update it + * @throws WC_API_Exception invalid data, server error + */ + protected function set_coupon( $order, $coupon, $action ) { + + // coupon amount must be positive float + if ( isset( $coupon['amount'] ) && floatval( $coupon['amount'] ) < 0 ) { + throw new WC_API_Exception( 'woocommerce_invalid_coupon_total', __( 'Coupon discount total must be a positive amount.', 'woocommerce' ), 400 ); + } + + if ( 'create' === $action ) { + + // coupon code is required + if ( empty( $coupon['code'] ) ) { + throw new WC_API_Exception( 'woocommerce_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + + $item = new WC_Order_Item_Coupon(); + $item->set_props( array( + 'code' => $coupon['code'], + 'discount' => isset( $coupon['amount'] ) ? floatval( $coupon['amount'] ) : 0, + 'discount_tax' => 0, + 'order_id' => $order->get_id(), + ) ); + $order->add_item( $item ); + } else { + + $item = new WC_Order_Item_Coupon( $coupon['id'] ); + + if ( isset( $coupon['code'] ) ) { + $item->set_code( $coupon['code'] ); + } + + if ( isset( $coupon['amount'] ) ) { + $item->set_discount( floatval( $coupon['amount'] ) ); + } + + $coupon_id = $item->save(); + + if ( ! $coupon_id ) { + throw new WC_API_Exception( 'woocommerce_cannot_update_order_coupon', __( 'Cannot update coupon, try again.', 'woocommerce' ), 500 ); + } + } + } + + /** + * Get the admin order notes for an order + * + * @since 2.1 + * @param string $order_id order ID + * @param string|null $fields fields to include in response + * @return array|WP_Error + */ + public function get_order_notes( $order_id, $fields = null ) { + + // ensure ID is valid order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'read' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $args = array( + 'post_id' => $order_id, + 'approve' => 'approve', + 'type' => 'order_note', + ); + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $notes = get_comments( $args ); + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $order_notes = array(); + + foreach ( $notes as $note ) { + + $order_notes[] = current( $this->get_order_note( $order_id, $note->comment_ID, $fields ) ); + } + + return array( 'order_notes' => apply_filters( 'woocommerce_api_order_notes_response', $order_notes, $order_id, $fields, $notes, $this->server ) ); + } + + /** + * Get an order note for the given order ID and ID + * + * @since 2.2 + * + * @param string $order_id order ID + * @param string $id order note ID + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_order_note( $order_id, $id, $fields = null ) { + try { + // Validate order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'read' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'Invalid order note ID', 'woocommerce' ), 400 ); + } + + $note = get_comment( $id ); + + if ( is_null( $note ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'An order note with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $order_note = array( + 'id' => $note->comment_ID, + 'created_at' => $this->server->format_datetime( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + + return array( 'order_note' => apply_filters( 'woocommerce_api_order_note_response', $order_note, $id, $fields, $note, $order_id, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new order note for the given order + * + * @since 2.2 + * @param string $order_id order ID + * @param array $data raw request data + * @return WP_Error|array error or created note response data + */ + public function create_order_note( $order_id, $data ) { + try { + if ( ! isset( $data['order_note'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_note_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'order_note' ), 400 ); + } + + $data = $data['order_note']; + + // permission check + if ( ! current_user_can( 'publish_shop_orders' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_order_note', __( 'You do not have permission to create order notes', 'woocommerce' ), 401 ); + } + + $order_id = $this->validate_request( $order_id, $this->post_type, 'edit' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $order = wc_get_order( $order_id ); + + $data = apply_filters( 'woocommerce_api_create_order_note_data', $data, $order_id, $this ); + + // note content is required + if ( ! isset( $data['note'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note', __( 'Order note is required', 'woocommerce' ), 400 ); + } + + $is_customer_note = ( isset( $data['customer_note'] ) && true === $data['customer_note'] ); + + // create the note + $note_id = $order->add_order_note( $data['note'], $is_customer_note ); + + if ( ! $note_id ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), 500 ); + } + + // HTTP 201 Created + $this->server->send_status( 201 ); + + do_action( 'woocommerce_api_create_order_note', $note_id, $order_id, $this ); + + return $this->get_order_note( $order->get_id(), $note_id ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit the order note + * + * @since 2.2 + * @param string $order_id order ID + * @param string $id note ID + * @param array $data parsed request data + * @return WP_Error|array error or edited note response data + */ + public function edit_order_note( $order_id, $id, $data ) { + try { + if ( ! isset( $data['order_note'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_note_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'order_note' ), 400 ); + } + + $data = $data['order_note']; + + // Validate order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'edit' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $order = wc_get_order( $order_id ); + + // Validate note ID + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'Invalid order note ID', 'woocommerce' ), 400 ); + } + + // Ensure note ID is valid + $note = get_comment( $id ); + + if ( is_null( $note ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'An order note with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + // Ensure note ID is associated with given order + if ( $note->comment_post_ID != $order->get_id() ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'The order note ID provided is not associated with the order', 'woocommerce' ), 400 ); + } + + $data = apply_filters( 'woocommerce_api_edit_order_note_data', $data, $note->comment_ID, $order->get_id(), $this ); + + // Note content + if ( isset( $data['note'] ) ) { + + wp_update_comment( + array( + 'comment_ID' => $note->comment_ID, + 'comment_content' => $data['note'], + ) + ); + } + + // Customer note + if ( isset( $data['customer_note'] ) ) { + + update_comment_meta( $note->comment_ID, 'is_customer_note', true === $data['customer_note'] ? 1 : 0 ); + } + + do_action( 'woocommerce_api_edit_order_note', $note->comment_ID, $order->get_id(), $this ); + + return $this->get_order_note( $order->get_id(), $note->comment_ID ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete order note + * + * @since 2.2 + * @param string $order_id order ID + * @param string $id note ID + * @return WP_Error|array error or deleted message + */ + public function delete_order_note( $order_id, $id ) { + try { + $order_id = $this->validate_request( $order_id, $this->post_type, 'delete' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + // Validate note ID + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'Invalid order note ID', 'woocommerce' ), 400 ); + } + + // Ensure note ID is valid + $note = get_comment( $id ); + + if ( is_null( $note ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'An order note with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + // Ensure note ID is associated with given order + if ( $note->comment_post_ID != $order_id ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_note_id', __( 'The order note ID provided is not associated with the order', 'woocommerce' ), 400 ); + } + + // Force delete since trashed order notes could not be managed through comments list table + $result = wc_delete_order_note( $note->comment_ID ); + + if ( ! $result ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_order_note', __( 'This order note cannot be deleted', 'woocommerce' ), 500 ); + } + + do_action( 'woocommerce_api_delete_order_note', $note->comment_ID, $order_id, $this ); + + return array( 'message' => __( 'Permanently deleted order note', 'woocommerce' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the order refunds for an order + * + * @since 2.2 + * @param string $order_id order ID + * @param string|null $fields fields to include in response + * @return array|WP_Error + */ + public function get_order_refunds( $order_id, $fields = null ) { + + // Ensure ID is valid order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'read' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $refund_items = wc_get_orders( array( + 'type' => 'shop_order_refund', + 'parent' => $order_id, + 'limit' => -1, + 'return' => 'ids', + ) ); + $order_refunds = array(); + + foreach ( $refund_items as $refund_id ) { + $order_refunds[] = current( $this->get_order_refund( $order_id, $refund_id, $fields ) ); + } + + return array( 'order_refunds' => apply_filters( 'woocommerce_api_order_refunds_response', $order_refunds, $order_id, $fields, $refund_items, $this ) ); + } + + /** + * Get an order refund for the given order ID and ID + * + * @since 2.2 + * + * @param string $order_id order ID + * @param int $id + * @param string|null $fields fields to limit response to + * @param array $filter + * + * @return array|WP_Error + */ + public function get_order_refund( $order_id, $id, $fields = null, $filter = array() ) { + try { + // Validate order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'read' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 400 ); + } + + $order = wc_get_order( $order_id ); + $refund = wc_get_order( $id ); + + if ( ! $refund ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'An order refund with the provided ID could not be found.', 'woocommerce' ), 404 ); + } + + $line_items = array(); + + // Add line items + foreach ( $refund->get_items( 'line_item' ) as $item_id => $item ) { + $product = $item->get_product(); + $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; + $item_meta = $item->get_formatted_meta_data( $hideprefix ); + + foreach ( $item_meta as $key => $values ) { + $item_meta[ $key ]->label = $values->display_key; + unset( $item_meta[ $key ]->display_key ); + unset( $item_meta[ $key ]->display_value ); + } + + $line_items[] = array( + 'id' => $item_id, + 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item ), 2 ), + 'subtotal_tax' => wc_format_decimal( $item->get_subtotal_tax(), 2 ), + 'total' => wc_format_decimal( $order->get_line_total( $item ), 2 ), + 'total_tax' => wc_format_decimal( $order->get_line_tax( $item ), 2 ), + 'price' => wc_format_decimal( $order->get_item_total( $item ), 2 ), + 'quantity' => $item->get_quantity(), + 'tax_class' => $item->get_tax_class(), + 'name' => $item->get_name(), + 'product_id' => $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id(), + 'sku' => is_object( $product ) ? $product->get_sku() : null, + 'meta' => array_values( $item_meta ), + 'refunded_item_id' => (int) $item->get_meta( 'refunded_item_id' ), + ); + } + + $order_refund = array( + 'id' => $refund->get_id(), + 'created_at' => $this->server->format_datetime( $refund->get_date_created() ? $refund->get_date_created()->getTimestamp() : 0, false, false ), + 'amount' => wc_format_decimal( $refund->get_amount(), 2 ), + 'reason' => $refund->get_reason(), + 'line_items' => $line_items, + ); + + return array( 'order_refund' => apply_filters( 'woocommerce_api_order_refund_response', $order_refund, $id, $fields, $refund, $order_id, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new order refund for the given order + * + * @since 2.2 + * @param string $order_id order ID + * @param array $data raw request data + * @param bool $api_refund do refund using a payment gateway API + * @return WP_Error|array error or created refund response data + */ + public function create_order_refund( $order_id, $data, $api_refund = true ) { + try { + if ( ! isset( $data['order_refund'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_refund_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'order_refund' ), 400 ); + } + + $data = $data['order_refund']; + + // Permission check + if ( ! current_user_can( 'publish_shop_orders' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_order_refund', __( 'You do not have permission to create order refunds', 'woocommerce' ), 401 ); + } + + $order_id = absint( $order_id ); + + if ( empty( $order_id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_id', __( 'Order ID is invalid', 'woocommerce' ), 400 ); + } + + $data = apply_filters( 'woocommerce_api_create_order_refund_data', $data, $order_id, $this ); + + // Refund amount is required + if ( ! isset( $data['amount'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund', __( 'Refund amount is required.', 'woocommerce' ), 400 ); + } elseif ( 0 > $data['amount'] ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund', __( 'Refund amount must be positive.', 'woocommerce' ), 400 ); + } + + $data['order_id'] = $order_id; + $data['refund_id'] = 0; + + // Create the refund + $refund = wc_create_refund( $data ); + + if ( ! $refund ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + // Refund via API + if ( $api_refund ) { + if ( WC()->payment_gateways() ) { + $payment_gateways = WC()->payment_gateways->payment_gateways(); + } + + $order = wc_get_order( $order_id ); + + if ( isset( $payment_gateways[ $order->get_payment_method() ] ) && $payment_gateways[ $order->get_payment_method() ]->supports( 'refunds' ) ) { + $result = $payment_gateways[ $order->get_payment_method() ]->process_refund( $order_id, $refund->get_amount(), $refund->get_reason() ); + + if ( is_wp_error( $result ) ) { + return $result; + } elseif ( ! $result ) { + throw new WC_API_Exception( 'woocommerce_api_create_order_refund_api_failed', __( 'An error occurred while attempting to create the refund using the payment gateway API.', 'woocommerce' ), 500 ); + } + } + } + + // HTTP 201 Created + $this->server->send_status( 201 ); + + do_action( 'woocommerce_api_create_order_refund', $refund->get_id(), $order_id, $this ); + + return $this->get_order_refund( $order_id, $refund->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit an order refund + * + * @since 2.2 + * @param string $order_id order ID + * @param string $id refund ID + * @param array $data parsed request data + * @return WP_Error|array error or edited refund response data + */ + public function edit_order_refund( $order_id, $id, $data ) { + try { + if ( ! isset( $data['order_refund'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_order_refund_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'order_refund' ), 400 ); + } + + $data = $data['order_refund']; + + // Validate order ID + $order_id = $this->validate_request( $order_id, $this->post_type, 'edit' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + // Validate refund ID + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 400 ); + } + + // Ensure order ID is valid + $refund = get_post( $id ); + + if ( ! $refund ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'An order refund with the provided ID could not be found.', 'woocommerce' ), 404 ); + } + + // Ensure refund ID is associated with given order + if ( $refund->post_parent != $order_id ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'The order refund ID provided is not associated with the order.', 'woocommerce' ), 400 ); + } + + $data = apply_filters( 'woocommerce_api_edit_order_refund_data', $data, $refund->ID, $order_id, $this ); + + // Update reason + if ( isset( $data['reason'] ) ) { + $updated_refund = wp_update_post( array( 'ID' => $refund->ID, 'post_excerpt' => $data['reason'] ) ); + + if ( is_wp_error( $updated_refund ) ) { + return $updated_refund; + } + } + + // Update refund amount + if ( isset( $data['amount'] ) && 0 < $data['amount'] ) { + update_post_meta( $refund->ID, '_refund_amount', wc_format_decimal( $data['amount'] ) ); + } + + do_action( 'woocommerce_api_edit_order_refund', $refund->ID, $order_id, $this ); + + return $this->get_order_refund( $order_id, $refund->ID ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete order refund + * + * @since 2.2 + * @param string $order_id order ID + * @param string $id refund ID + * @return WP_Error|array error or deleted message + */ + public function delete_order_refund( $order_id, $id ) { + try { + $order_id = $this->validate_request( $order_id, $this->post_type, 'delete' ); + + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + // Validate refund ID + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 400 ); + } + + // Ensure refund ID is valid + $refund = get_post( $id ); + + if ( ! $refund ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'An order refund with the provided ID could not be found.', 'woocommerce' ), 404 ); + } + + // Ensure refund ID is associated with given order + if ( $refund->post_parent != $order_id ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_order_refund_id', __( 'The order refund ID provided is not associated with the order.', 'woocommerce' ), 400 ); + } + + wc_delete_shop_order_transients( $order_id ); + + do_action( 'woocommerce_api_delete_order_refund', $refund->ID, $order_id, $this ); + + return $this->delete( $refund->ID, 'refund', true ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Bulk update or insert orders + * Accepts an array with orders in the formats supported by + * WC_API_Orders->create_order() and WC_API_Orders->edit_order() + * + * @since 2.4.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function bulk( $data ) { + + try { + if ( ! isset( $data['orders'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_orders_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'orders' ), 400 ); + } + + $data = $data['orders']; + $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'orders' ); + + // Limit bulk operation + if ( count( $data ) > $limit ) { + throw new WC_API_Exception( 'woocommerce_api_orders_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); + } + + $orders = array(); + + foreach ( $data as $_order ) { + $order_id = 0; + + // Try to get the order ID + if ( isset( $_order['id'] ) ) { + $order_id = intval( $_order['id'] ); + } + + if ( $order_id ) { + + // Order exists / edit order + $edit = $this->edit_order( $order_id, array( 'order' => $_order ) ); + + if ( is_wp_error( $edit ) ) { + $orders[] = array( + 'id' => $order_id, + 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ), + ); + } else { + $orders[] = $edit['order']; + } + } else { + + // Order don't exists / create order + $new = $this->create_order( array( 'order' => $_order ) ); + + if ( is_wp_error( $new ) ) { + $orders[] = array( + 'id' => $order_id, + 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ), + ); + } else { + $orders[] = $new['order']; + } + } + } + + return array( 'orders' => apply_filters( 'woocommerce_api_orders_bulk_response', $orders, $this ) ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-products.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-products.php new file mode 100644 index 0000000..cb224ff --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-products.php @@ -0,0 +1,3310 @@ + + * GET /products//reviews + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET/POST /products + $routes[ $this->base ] = array( + array( array( $this, 'get_products' ), WC_API_Server::READABLE ), + array( array( $this, 'create_product' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /products/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_products_count' ), WC_API_Server::READABLE ), + ); + + # GET/PUT/DELETE /products/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_product' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_product' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_product' ), WC_API_Server::DELETABLE ), + ); + + # GET /products//reviews + $routes[ $this->base . '/(?P\d+)/reviews' ] = array( + array( array( $this, 'get_product_reviews' ), WC_API_Server::READABLE ), + ); + + # GET /products//orders + $routes[ $this->base . '/(?P\d+)/orders' ] = array( + array( array( $this, 'get_product_orders' ), WC_API_Server::READABLE ), + ); + + # GET/POST /products/categories + $routes[ $this->base . '/categories' ] = array( + array( array( $this, 'get_product_categories' ), WC_API_Server::READABLE ), + array( array( $this, 'create_product_category' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET/PUT/DELETE /products/categories/ + $routes[ $this->base . '/categories/(?P\d+)' ] = array( + array( array( $this, 'get_product_category' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_product_category' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_product_category' ), WC_API_Server::DELETABLE ), + ); + + # GET/POST /products/tags + $routes[ $this->base . '/tags' ] = array( + array( array( $this, 'get_product_tags' ), WC_API_Server::READABLE ), + array( array( $this, 'create_product_tag' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET/PUT/DELETE /products/tags/ + $routes[ $this->base . '/tags/(?P\d+)' ] = array( + array( array( $this, 'get_product_tag' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_product_tag' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_product_tag' ), WC_API_Server::DELETABLE ), + ); + + # GET/POST /products/shipping_classes + $routes[ $this->base . '/shipping_classes' ] = array( + array( array( $this, 'get_product_shipping_classes' ), WC_API_Server::READABLE ), + array( array( $this, 'create_product_shipping_class' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET/PUT/DELETE /products/shipping_classes/ + $routes[ $this->base . '/shipping_classes/(?P\d+)' ] = array( + array( array( $this, 'get_product_shipping_class' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_product_shipping_class' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_product_shipping_class' ), WC_API_Server::DELETABLE ), + ); + + # GET/POST /products/attributes + $routes[ $this->base . '/attributes' ] = array( + array( array( $this, 'get_product_attributes' ), WC_API_Server::READABLE ), + array( array( $this, 'create_product_attribute' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET/PUT/DELETE /products/attributes/ + $routes[ $this->base . '/attributes/(?P\d+)' ] = array( + array( array( $this, 'get_product_attribute' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_product_attribute' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_product_attribute' ), WC_API_Server::DELETABLE ), + ); + + # GET/POST /products/attributes//terms + $routes[ $this->base . '/attributes/(?P\d+)/terms' ] = array( + array( array( $this, 'get_product_attribute_terms' ), WC_API_Server::READABLE ), + array( array( $this, 'create_product_attribute_term' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET/PUT/DELETE /products/attributes//terms/ + $routes[ $this->base . '/attributes/(?P\d+)/terms/(?P\d+)' ] = array( + array( array( $this, 'get_product_attribute_term' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_product_attribute_term' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_product_attribute_term' ), WC_API_Server::DELETABLE ), + ); + + # POST|PUT /products/bulk + $routes[ $this->base . '/bulk' ] = array( + array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + return $routes; + } + + /** + * Get all products + * + * @since 2.1 + * @param string $fields + * @param string $type + * @param array $filter + * @param int $page + * @return array + */ + public function get_products( $fields = null, $type = null, $filter = array(), $page = 1 ) { + + if ( ! empty( $type ) ) { + $filter['type'] = $type; + } + + $filter['page'] = $page; + + $query = $this->query_products( $filter ); + + $products = array(); + + foreach ( $query->posts as $product_id ) { + + if ( ! $this->is_readable( $product_id ) ) { + continue; + } + + $products[] = current( $this->get_product( $product_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query ); + + return array( 'products' => $products ); + } + + /** + * Get the product for the given ID + * + * @since 2.1 + * @param int $id the product ID + * @param string $fields + * @return array|WP_Error + */ + public function get_product( $id, $fields = null ) { + + $id = $this->validate_request( $id, 'product', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $product = wc_get_product( $id ); + + // add data that applies to every product type + $product_data = $this->get_product_data( $product ); + + // add variations to variable products + if ( $product->is_type( 'variable' ) && $product->has_child() ) { + $product_data['variations'] = $this->get_variation_data( $product ); + } + + // add the parent product data to an individual variation + if ( $product->is_type( 'variation' ) && $product->get_parent_id() ) { + $product_data['parent'] = $this->get_product_data( $product->get_parent_id() ); + } + + // Add grouped products data + if ( $product->is_type( 'grouped' ) && $product->has_child() ) { + $product_data['grouped_products'] = $this->get_grouped_products_data( $product ); + } + + if ( $product->is_type( 'simple' ) ) { + $parent_id = $product->get_parent_id(); + if ( ! empty( $parent_id ) ) { + $_product = wc_get_product( $parent_id ); + $product_data['parent'] = $this->get_product_data( $_product ); + } + } + + return array( 'product' => apply_filters( 'woocommerce_api_product_response', $product_data, $product, $fields, $this->server ) ); + } + + /** + * Get the total number of products + * + * @since 2.1 + * + * @param string $type + * @param array $filter + * + * @return array|WP_Error + */ + public function get_products_count( $type = null, $filter = array() ) { + try { + if ( ! current_user_can( 'read_private_products' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_products_count', __( 'You do not have permission to read the products count', 'woocommerce' ), 401 ); + } + + if ( ! empty( $type ) ) { + $filter['type'] = $type; + } + + $query = $this->query_products( $filter ); + + return array( 'count' => (int) $query->found_posts ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new product. + * + * @since 2.2 + * + * @param array $data posted data + * + * @return array|WP_Error + */ + public function create_product( $data ) { + $id = 0; + + try { + if ( ! isset( $data['product'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product' ), 400 ); + } + + $data = $data['product']; + + // Check permissions. + if ( ! current_user_can( 'publish_products' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_product', __( 'You do not have permission to create products', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_product_data', $data, $this ); + + // Check if product title is specified. + if ( ! isset( $data['title'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_title', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'title' ), 400 ); + } + + // Check product type. + if ( ! isset( $data['type'] ) ) { + $data['type'] = 'simple'; + } + + // Set visible visibility when not sent. + if ( ! isset( $data['catalog_visibility'] ) ) { + $data['catalog_visibility'] = 'visible'; + } + + // Validate the product type. + if ( ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_product_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_type', sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_product_types() ) ) ), 400 ); + } + + // Enable description html tags. + $post_content = isset( $data['description'] ) ? wc_clean( $data['description'] ) : ''; + if ( $post_content && isset( $data['enable_html_description'] ) && true === $data['enable_html_description'] ) { + + $post_content = wp_filter_post_kses( $data['description'] ); + } + + // Enable short description html tags. + $post_excerpt = isset( $data['short_description'] ) ? wc_clean( $data['short_description'] ) : ''; + if ( $post_excerpt && isset( $data['enable_html_short_description'] ) && true === $data['enable_html_short_description'] ) { + $post_excerpt = wp_filter_post_kses( $data['short_description'] ); + } + + $classname = WC_Product_Factory::get_classname_from_product_type( $data['type'] ); + if ( ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + $product = new $classname(); + + $product->set_name( wc_clean( $data['title'] ) ); + $product->set_status( isset( $data['status'] ) ? wc_clean( $data['status'] ) : 'publish' ); + $product->set_short_description( isset( $data['short_description'] ) ? $post_excerpt : '' ); + $product->set_description( isset( $data['description'] ) ? $post_content : '' ); + $product->set_menu_order( isset( $data['menu_order'] ) ? intval( $data['menu_order'] ) : 0 ); + + if ( ! empty( $data['name'] ) ) { + $product->set_slug( sanitize_title( $data['name'] ) ); + } + + // Attempts to create the new product. + $product->save(); + $id = $product->get_id(); + + // Checks for an error in the product creation. + if ( 0 >= $id ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_product', $id->get_error_message(), 400 ); + } + + // Check for featured/gallery images, upload it and set it. + if ( isset( $data['images'] ) ) { + $product = $this->save_product_images( $product, $data['images'] ); + } + + // Save product meta fields. + $product = $this->save_product_meta( $product, $data ); + $product->save(); + + // Save variations. + if ( isset( $data['type'] ) && 'variable' == $data['type'] && isset( $data['variations'] ) && is_array( $data['variations'] ) ) { + $this->save_variations( $product, $data ); + } + + do_action( 'woocommerce_api_create_product', $id, $data ); + + // Clear cache/transients. + wc_delete_product_transients( $id ); + + $this->server->send_status( 201 ); + + return $this->get_product( $id ); + } catch ( WC_Data_Exception $e ) { + $this->clear_product( $id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } catch ( WC_API_Exception $e ) { + $this->clear_product( $id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a product + * + * @since 2.2 + * + * @param int $id the product ID + * @param array $data + * + * @return array|WP_Error + */ + public function edit_product( $id, $data ) { + try { + if ( ! isset( $data['product'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product' ), 400 ); + } + + $data = $data['product']; + + $id = $this->validate_request( $id, 'product', 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $product = wc_get_product( $id ); + + $data = apply_filters( 'woocommerce_api_edit_product_data', $data, $this ); + + // Product title. + if ( isset( $data['title'] ) ) { + $product->set_name( wc_clean( $data['title'] ) ); + } + + // Product name (slug). + if ( isset( $data['name'] ) ) { + $product->set_slug( wc_clean( $data['name'] ) ); + } + + // Product status. + if ( isset( $data['status'] ) ) { + $product->set_status( wc_clean( $data['status'] ) ); + } + + // Product short description. + if ( isset( $data['short_description'] ) ) { + // Enable short description html tags. + $post_excerpt = ( isset( $data['enable_html_short_description'] ) && true === $data['enable_html_short_description'] ) ? wp_filter_post_kses( $data['short_description'] ) : wc_clean( $data['short_description'] ); + $product->set_short_description( $post_excerpt ); + } + + // Product description. + if ( isset( $data['description'] ) ) { + // Enable description html tags. + $post_content = ( isset( $data['enable_html_description'] ) && true === $data['enable_html_description'] ) ? wp_filter_post_kses( $data['description'] ) : wc_clean( $data['description'] ); + $product->set_description( $post_content ); + } + + // Validate the product type. + if ( isset( $data['type'] ) && ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_product_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_type', sprintf( __( 'Invalid product type - the product type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_product_types() ) ) ), 400 ); + } + + // Menu order. + if ( isset( $data['menu_order'] ) ) { + $product->set_menu_order( intval( $data['menu_order'] ) ); + } + + // Check for featured/gallery images, upload it and set it. + if ( isset( $data['images'] ) ) { + $product = $this->save_product_images( $product, $data['images'] ); + } + + // Save product meta fields. + $product = $this->save_product_meta( $product, $data ); + + // Save variations. + if ( $product->is_type( 'variable' ) ) { + if ( isset( $data['variations'] ) && is_array( $data['variations'] ) ) { + $this->save_variations( $product, $data ); + } else { + // Just sync variations. + $product = WC_Product_Variable::sync( $product, false ); + } + } + + $product->save(); + + do_action( 'woocommerce_api_edit_product', $id, $data ); + + // Clear cache/transients. + wc_delete_product_transients( $id ); + + return $this->get_product( $id ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a product. + * + * @since 2.2 + * + * @param int $id the product ID. + * @param bool $force true to permanently delete order, false to move to trash. + * + * @return array|WP_Error + */ + public function delete_product( $id, $force = false ) { + + $id = $this->validate_request( $id, 'product', 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $product = wc_get_product( $id ); + + do_action( 'woocommerce_api_delete_product', $id, $this ); + + // If we're forcing, then delete permanently. + if ( $force ) { + if ( $product->is_type( 'variable' ) ) { + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->delete( true ); + } + } + } else { + // For other product types, if the product has children, remove the relationship. + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->set_parent_id( 0 ); + $child->save(); + } + } + } + + $product->delete( true ); + $result = ! ( $product->get_id() > 0 ); + } else { + $product->delete(); + $result = 'trash' === $product->get_status(); + } + + if ( ! $result ) { + return new WP_Error( 'woocommerce_api_cannot_delete_product', sprintf( __( 'This %s cannot be deleted', 'woocommerce' ), 'product' ), array( 'status' => 500 ) ); + } + + // Delete parent product transients. + if ( $parent_id = wp_get_post_parent_id( $id ) ) { + wc_delete_product_transients( $parent_id ); + } + + if ( $force ) { + return array( 'message' => sprintf( __( 'Permanently deleted %s', 'woocommerce' ), 'product' ) ); + } else { + $this->server->send_status( '202' ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product' ) ); + } + } + + /** + * Get the reviews for a product + * + * @since 2.1 + * @param int $id the product ID to get reviews for + * @param string $fields fields to include in response + * @return array|WP_Error + */ + public function get_product_reviews( $id, $fields = null ) { + + $id = $this->validate_request( $id, 'product', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $comments = get_approved_comments( $id ); + $reviews = array(); + + foreach ( $comments as $comment ) { + + $reviews[] = array( + 'id' => intval( $comment->comment_ID ), + 'created_at' => $this->server->format_datetime( $comment->comment_date_gmt ), + 'review' => $comment->comment_content, + 'rating' => get_comment_meta( $comment->comment_ID, 'rating', true ), + 'reviewer_name' => $comment->comment_author, + 'reviewer_email' => $comment->comment_author_email, + 'verified' => wc_review_is_from_verified_owner( $comment->comment_ID ), + ); + } + + return array( 'product_reviews' => apply_filters( 'woocommerce_api_product_reviews_response', $reviews, $id, $fields, $comments, $this->server ) ); + } + + /** + * Get the orders for a product + * + * @since 2.4.0 + * @param int $id the product ID to get orders for + * @param string fields fields to retrieve + * @param array $filter filters to include in response + * @param string $status the order status to retrieve + * @param $page $page page to retrieve + * @return array|WP_Error + */ + public function get_product_orders( $id, $fields = null, $filter = array(), $status = null, $page = 1 ) { + global $wpdb; + + $id = $this->validate_request( $id, 'product', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $order_ids = $wpdb->get_col( $wpdb->prepare( " + SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items + WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) + AND order_item_type = 'line_item' + ", $id ) ); + + if ( empty( $order_ids ) ) { + return array( 'orders' => array() ); + } + + $filter = array_merge( $filter, array( + 'in' => implode( ',', $order_ids ), + ) ); + + $orders = WC()->api->WC_API_Orders->get_orders( $fields, $filter, $status, $page ); + + return array( 'orders' => apply_filters( 'woocommerce_api_product_orders_response', $orders['orders'], $id, $filter, $fields, $this->server ) ); + } + + /** + * Get a listing of product categories + * + * @since 2.2 + * + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_categories( $fields = null ) { + try { + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_categories', __( 'You do not have permission to read product categories', 'woocommerce' ), 401 ); + } + + $product_categories = array(); + + $terms = get_terms( 'product_cat', array( 'hide_empty' => false, 'fields' => 'ids' ) ); + + foreach ( $terms as $term_id ) { + $product_categories[] = current( $this->get_product_category( $term_id, $fields ) ); + } + + return array( 'product_categories' => apply_filters( 'woocommerce_api_product_categories_response', $product_categories, $terms, $fields, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the product category for the given ID + * + * @since 2.2 + * + * @param string $id product category term ID + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_category( $id, $fields = null ) { + try { + $id = absint( $id ); + + // Validate ID + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_category_id', __( 'Invalid product category ID', 'woocommerce' ), 400 ); + } + + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_categories', __( 'You do not have permission to read product categories', 'woocommerce' ), 401 ); + } + + $term = get_term( $id, 'product_cat' ); + + if ( is_wp_error( $term ) || is_null( $term ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_category_id', __( 'A product category with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $term_id = intval( $term->term_id ); + + // Get category display type + $display_type = get_term_meta( $term_id, 'display_type', true ); + + // Get category image + $image = ''; + if ( $image_id = get_term_meta( $term_id, 'thumbnail_id', true ) ) { + $image = wp_get_attachment_url( $image_id ); + } + + $product_category = array( + 'id' => $term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'parent' => $term->parent, + 'description' => $term->description, + 'display' => $display_type ? $display_type : 'default', + 'image' => $image ? esc_url( $image ) : '', + 'count' => intval( $term->count ), + ); + + return array( 'product_category' => apply_filters( 'woocommerce_api_product_category_response', $product_category, $id, $fields, $term, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new product category. + * + * @since 2.5.0 + * @param array $data Posted data + * @return array|WP_Error Product category if succeed, otherwise WP_Error + * will be returned + */ + public function create_product_category( $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_category'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_category_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product_category' ), 400 ); + } + + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_product_category', __( 'You do not have permission to create product categories', 'woocommerce' ), 401 ); + } + + $defaults = array( + 'name' => '', + 'slug' => '', + 'description' => '', + 'parent' => 0, + 'display' => 'default', + 'image' => '', + ); + + $data = wp_parse_args( $data['product_category'], $defaults ); + $data = apply_filters( 'woocommerce_api_create_product_category_data', $data, $this ); + + // Check parent. + $data['parent'] = absint( $data['parent'] ); + if ( $data['parent'] ) { + $parent = get_term_by( 'id', $data['parent'], 'product_cat' ); + if ( ! $parent ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_category_parent', __( 'Product category parent is invalid', 'woocommerce' ), 400 ); + } + } + + // If value of image is numeric, assume value as image_id. + $image = $data['image']; + $image_id = 0; + if ( is_numeric( $image ) ) { + $image_id = absint( $image ); + } elseif ( ! empty( $image ) ) { + $upload = $this->upload_product_category_image( esc_url_raw( $image ) ); + $image_id = $this->set_product_category_image_as_attachment( $upload ); + } + + $insert = wp_insert_term( $data['name'], 'product_cat', $data ); + if ( is_wp_error( $insert ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_product_category', $insert->get_error_message(), 400 ); + } + + $id = $insert['term_id']; + + update_term_meta( $id, 'display_type', 'default' === $data['display'] ? '' : sanitize_text_field( $data['display'] ) ); + + // Check if image_id is a valid image attachment before updating the term meta. + if ( $image_id && wp_attachment_is_image( $image_id ) ) { + update_term_meta( $id, 'thumbnail_id', $image_id ); + } + + do_action( 'woocommerce_api_create_product_category', $id, $data ); + + $this->server->send_status( 201 ); + + return $this->get_product_category( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a product category. + * + * @since 2.5.0 + * @param int $id Product category term ID + * @param array $data Posted data + * @return array|WP_Error Product category if succeed, otherwise WP_Error + * will be returned + */ + public function edit_product_category( $id, $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_category'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_category', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product_category' ), 400 ); + } + + $id = absint( $id ); + $data = $data['product_category']; + + // Check permissions. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_product_category', __( 'You do not have permission to edit product categories', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_edit_product_category_data', $data, $this ); + $category = $this->get_product_category( $id ); + + if ( is_wp_error( $category ) ) { + return $category; + } + + if ( isset( $data['image'] ) ) { + $image_id = 0; + + // If value of image is numeric, assume value as image_id. + $image = $data['image']; + if ( is_numeric( $image ) ) { + $image_id = absint( $image ); + } elseif ( ! empty( $image ) ) { + $upload = $this->upload_product_category_image( esc_url_raw( $image ) ); + $image_id = $this->set_product_category_image_as_attachment( $upload ); + } + + // In case client supplies invalid image or wants to unset category image. + if ( ! wp_attachment_is_image( $image_id ) ) { + $image_id = ''; + } + } + + $update = wp_update_term( $id, 'product_cat', $data ); + if ( is_wp_error( $update ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_edit_product_catgory', __( 'Could not edit the category', 'woocommerce' ), 400 ); + } + + if ( ! empty( $data['display'] ) ) { + update_term_meta( $id, 'display_type', 'default' === $data['display'] ? '' : sanitize_text_field( $data['display'] ) ); + } + + if ( isset( $image_id ) ) { + update_term_meta( $id, 'thumbnail_id', $image_id ); + } + + do_action( 'woocommerce_api_edit_product_category', $id, $data ); + + return $this->get_product_category( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a product category. + * + * @since 2.5.0 + * @param int $id Product category term ID + * @return array|WP_Error Success message if succeed, otherwise WP_Error + * will be returned + */ + public function delete_product_category( $id ) { + global $wpdb; + + try { + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_product_category', __( 'You do not have permission to delete product category', 'woocommerce' ), 401 ); + } + + $id = absint( $id ); + $deleted = wp_delete_term( $id, 'product_cat' ); + if ( ! $deleted || is_wp_error( $deleted ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_product_category', __( 'Could not delete the category', 'woocommerce' ), 401 ); + } + + do_action( 'woocommerce_api_delete_product_category', $id, $this ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product_category' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get a listing of product tags. + * + * @since 2.5.0 + * + * @param string|null $fields Fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_tags( $fields = null ) { + try { + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_tags', __( 'You do not have permission to read product tags', 'woocommerce' ), 401 ); + } + + $product_tags = array(); + + $terms = get_terms( 'product_tag', array( 'hide_empty' => false, 'fields' => 'ids' ) ); + + foreach ( $terms as $term_id ) { + $product_tags[] = current( $this->get_product_tag( $term_id, $fields ) ); + } + + return array( 'product_tags' => apply_filters( 'woocommerce_api_product_tags_response', $product_tags, $terms, $fields, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the product tag for the given ID. + * + * @since 2.5.0 + * + * @param string $id Product tag term ID + * @param string|null $fields Fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_tag( $id, $fields = null ) { + try { + $id = absint( $id ); + + // Validate ID + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_tag_id', __( 'Invalid product tag ID', 'woocommerce' ), 400 ); + } + + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_tags', __( 'You do not have permission to read product tags', 'woocommerce' ), 401 ); + } + + $term = get_term( $id, 'product_tag' ); + + if ( is_wp_error( $term ) || is_null( $term ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_tag_id', __( 'A product tag with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $term_id = intval( $term->term_id ); + + $tag = array( + 'id' => $term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'description' => $term->description, + 'count' => intval( $term->count ), + ); + + return array( 'product_tag' => apply_filters( 'woocommerce_api_product_tag_response', $tag, $id, $fields, $term, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new product tag. + * + * @since 2.5.0 + * @param array $data Posted data + * @return array|WP_Error Product tag if succeed, otherwise WP_Error + * will be returned + */ + public function create_product_tag( $data ) { + try { + if ( ! isset( $data['product_tag'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_tag_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product_tag' ), 400 ); + } + + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_product_tag', __( 'You do not have permission to create product tags', 'woocommerce' ), 401 ); + } + + $defaults = array( + 'name' => '', + 'slug' => '', + 'description' => '', + ); + + $data = wp_parse_args( $data['product_tag'], $defaults ); + $data = apply_filters( 'woocommerce_api_create_product_tag_data', $data, $this ); + + $insert = wp_insert_term( $data['name'], 'product_tag', $data ); + if ( is_wp_error( $insert ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_product_tag', $insert->get_error_message(), 400 ); + } + $id = $insert['term_id']; + + do_action( 'woocommerce_api_create_product_tag', $id, $data ); + + $this->server->send_status( 201 ); + + return $this->get_product_tag( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a product tag. + * + * @since 2.5.0 + * @param int $id Product tag term ID + * @param array $data Posted data + * @return array|WP_Error Product tag if succeed, otherwise WP_Error + * will be returned + */ + public function edit_product_tag( $id, $data ) { + try { + if ( ! isset( $data['product_tag'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_tag', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product_tag' ), 400 ); + } + + $id = absint( $id ); + $data = $data['product_tag']; + + // Check permissions. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_product_tag', __( 'You do not have permission to edit product tags', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_edit_product_tag_data', $data, $this ); + $tag = $this->get_product_tag( $id ); + + if ( is_wp_error( $tag ) ) { + return $tag; + } + + $update = wp_update_term( $id, 'product_tag', $data ); + if ( is_wp_error( $update ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_edit_product_tag', __( 'Could not edit the tag', 'woocommerce' ), 400 ); + } + + do_action( 'woocommerce_api_edit_product_tag', $id, $data ); + + return $this->get_product_tag( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a product tag. + * + * @since 2.5.0 + * @param int $id Product tag term ID + * @return array|WP_Error Success message if succeed, otherwise WP_Error + * will be returned + */ + public function delete_product_tag( $id ) { + try { + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_product_tag', __( 'You do not have permission to delete product tag', 'woocommerce' ), 401 ); + } + + $id = absint( $id ); + $deleted = wp_delete_term( $id, 'product_tag' ); + if ( ! $deleted || is_wp_error( $deleted ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_product_tag', __( 'Could not delete the tag', 'woocommerce' ), 401 ); + } + + do_action( 'woocommerce_api_delete_product_tag', $id, $this ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product_tag' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Helper method to get product post objects + * + * @since 2.1 + * @param array $args request arguments for filtering query + * @return WP_Query + */ + private function query_products( $args ) { + + // Set base query arguments + $query_args = array( + 'fields' => 'ids', + 'post_type' => 'product', + 'post_status' => 'publish', + 'meta_query' => array(), + ); + + // Taxonomy query to filter products by type, category, tag, shipping class, and + // attribute. + $tax_query = array(); + + // Map between taxonomy name and arg's key. + $taxonomies_arg_map = array( + 'product_type' => 'type', + 'product_cat' => 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Add attribute taxonomy names into the map. + foreach ( wc_get_attribute_taxonomy_names() as $attribute_name ) { + $taxonomies_arg_map[ $attribute_name ] = $attribute_name; + } + + // Set tax_query for each passed arg. + foreach ( $taxonomies_arg_map as $tax_name => $arg ) { + if ( ! empty( $args[ $arg ] ) ) { + $terms = explode( ',', $args[ $arg ] ); + + $tax_query[] = array( + 'taxonomy' => $tax_name, + 'field' => 'slug', + 'terms' => $terms, + ); + + unset( $args[ $arg ] ); + } + } + + if ( ! empty( $tax_query ) ) { + $query_args['tax_query'] = $tax_query; + } + + // Filter by specific sku + if ( ! empty( $args['sku'] ) ) { + if ( ! is_array( $query_args['meta_query'] ) ) { + $query_args['meta_query'] = array(); + } + + $query_args['meta_query'][] = array( + 'key' => '_sku', + 'value' => $args['sku'], + 'compare' => '=', + ); + + $query_args['post_type'] = array( 'product', 'product_variation' ); + } + + $query_args = $this->merge_query_args( $query_args, $args ); + + return new WP_Query( $query_args ); + } + + /** + * Get standard product data that applies to every product type + * + * @since 2.1 + * @param WC_Product|int $product + * + * @return array + */ + private function get_product_data( $product ) { + if ( is_numeric( $product ) ) { + $product = wc_get_product( $product ); + } + + if ( ! is_a( $product, 'WC_Product' ) ) { + return array(); + } + + return array( + 'title' => $product->get_name(), + 'id' => $product->get_id(), + 'created_at' => $this->server->format_datetime( $product->get_date_created(), false, true ), + 'updated_at' => $this->server->format_datetime( $product->get_date_modified(), false, true ), + 'type' => $product->get_type(), + 'status' => $product->get_status(), + 'downloadable' => $product->is_downloadable(), + 'virtual' => $product->is_virtual(), + 'permalink' => $product->get_permalink(), + 'sku' => $product->get_sku(), + 'price' => $product->get_price(), + 'regular_price' => $product->get_regular_price(), + 'sale_price' => $product->get_sale_price() ? $product->get_sale_price() : null, + 'price_html' => $product->get_price_html(), + 'taxable' => $product->is_taxable(), + 'tax_status' => $product->get_tax_status(), + 'tax_class' => $product->get_tax_class(), + 'managing_stock' => $product->managing_stock(), + 'stock_quantity' => $product->get_stock_quantity(), + 'in_stock' => $product->is_in_stock(), + 'backorders_allowed' => $product->backorders_allowed(), + 'backordered' => $product->is_on_backorder(), + 'sold_individually' => $product->is_sold_individually(), + 'purchaseable' => $product->is_purchasable(), + 'featured' => $product->is_featured(), + 'visible' => $product->is_visible(), + 'catalog_visibility' => $product->get_catalog_visibility(), + 'on_sale' => $product->is_on_sale(), + 'product_url' => $product->is_type( 'external' ) ? $product->get_product_url() : '', + 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text() : '', + 'weight' => $product->get_weight() ? $product->get_weight() : null, + 'dimensions' => array( + 'length' => $product->get_length(), + 'width' => $product->get_width(), + 'height' => $product->get_height(), + 'unit' => get_option( 'woocommerce_dimension_unit' ), + ), + 'shipping_required' => $product->needs_shipping(), + 'shipping_taxable' => $product->is_shipping_taxable(), + 'shipping_class' => $product->get_shipping_class(), + 'shipping_class_id' => ( 0 !== $product->get_shipping_class_id() ) ? $product->get_shipping_class_id() : null, + 'description' => wpautop( do_shortcode( $product->get_description() ) ), + 'short_description' => apply_filters( 'woocommerce_short_description', $product->get_short_description() ), + 'reviews_allowed' => $product->get_reviews_allowed(), + 'average_rating' => wc_format_decimal( $product->get_average_rating(), 2 ), + 'rating_count' => $product->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids() ), + 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids() ), + 'parent_id' => $product->get_parent_id(), + 'categories' => wc_get_object_terms( $product->get_id(), 'product_cat', 'name' ), + 'tags' => wc_get_object_terms( $product->get_id(), 'product_tag', 'name' ), + 'images' => $this->get_images( $product ), + 'featured_src' => wp_get_attachment_url( get_post_thumbnail_id( $product->get_id() ) ), + 'attributes' => $this->get_attributes( $product ), + 'downloads' => $this->get_downloads( $product ), + 'download_limit' => $product->get_download_limit(), + 'download_expiry' => $product->get_download_expiry(), + 'download_type' => 'standard', + 'purchase_note' => wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ), + 'total_sales' => $product->get_total_sales(), + 'variations' => array(), + 'parent' => array(), + 'grouped_products' => array(), + 'menu_order' => $this->get_product_menu_order( $product ), + ); + } + + /** + * Get product menu order. + * + * @since 2.5.3 + * @param WC_Product $product + * @return int + */ + private function get_product_menu_order( $product ) { + $menu_order = $product->get_menu_order(); + + return apply_filters( 'woocommerce_api_product_menu_order', $menu_order, $product ); + } + + /** + * Get an individual variation's data. + * + * @since 2.1 + * @param WC_Product $product + * @return array + */ + private function get_variation_data( $product ) { + $variations = array(); + + foreach ( $product->get_children() as $child_id ) { + $variation = wc_get_product( $child_id ); + + if ( ! $variation || ! $variation->exists() ) { + continue; + } + + $variations[] = array( + 'id' => $variation->get_id(), + 'created_at' => $this->server->format_datetime( $variation->get_date_created(), false, true ), + 'updated_at' => $this->server->format_datetime( $variation->get_date_modified(), false, true ), + 'downloadable' => $variation->is_downloadable(), + 'virtual' => $variation->is_virtual(), + 'permalink' => $variation->get_permalink(), + 'sku' => $variation->get_sku(), + 'price' => $variation->get_price(), + 'regular_price' => $variation->get_regular_price(), + 'sale_price' => $variation->get_sale_price() ? $variation->get_sale_price() : null, + 'taxable' => $variation->is_taxable(), + 'tax_status' => $variation->get_tax_status(), + 'tax_class' => $variation->get_tax_class(), + 'managing_stock' => $variation->managing_stock(), + 'stock_quantity' => $variation->get_stock_quantity(), + 'in_stock' => $variation->is_in_stock(), + 'backorders_allowed' => $variation->backorders_allowed(), + 'backordered' => $variation->is_on_backorder(), + 'purchaseable' => $variation->is_purchasable(), + 'visible' => $variation->variation_is_visible(), + 'on_sale' => $variation->is_on_sale(), + 'weight' => $variation->get_weight() ? $variation->get_weight() : null, + 'dimensions' => array( + 'length' => $variation->get_length(), + 'width' => $variation->get_width(), + 'height' => $variation->get_height(), + 'unit' => get_option( 'woocommerce_dimension_unit' ), + ), + 'shipping_class' => $variation->get_shipping_class(), + 'shipping_class_id' => ( 0 !== $variation->get_shipping_class_id() ) ? $variation->get_shipping_class_id() : null, + 'image' => $this->get_images( $variation ), + 'attributes' => $this->get_attributes( $variation ), + 'downloads' => $this->get_downloads( $variation ), + 'download_limit' => (int) $product->get_download_limit(), + 'download_expiry' => (int) $product->get_download_expiry(), + ); + } + + return $variations; + } + + /** + * Get grouped products data + * + * @since 2.5.0 + * @param WC_Product $product + * + * @return array + */ + private function get_grouped_products_data( $product ) { + $products = array(); + + foreach ( $product->get_children() as $child_id ) { + $_product = wc_get_product( $child_id ); + + if ( ! $_product || ! $_product->exists() ) { + continue; + } + + $products[] = $this->get_product_data( $_product ); + + } + + return $products; + } + + /** + * Save default attributes. + * + * @since 3.0.0 + * + * @param WC_Product $product + * @param WP_REST_Request $request + * @return WC_Product + */ + protected function save_default_attributes( $product, $request ) { + // Update default attributes options setting. + if ( isset( $request['default_attribute'] ) ) { + $request['default_attributes'] = $request['default_attribute']; + } + + if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { + $attributes = $product->get_attributes(); + $default_attributes = array(); + + foreach ( $request['default_attributes'] as $default_attr_key => $default_attr ) { + if ( ! isset( $default_attr['name'] ) ) { + continue; + } + + $taxonomy = sanitize_title( $default_attr['name'] ); + + if ( isset( $default_attr['slug'] ) ) { + $taxonomy = $this->get_attribute_taxonomy_by_slug( $default_attr['slug'] ); + } + + if ( isset( $attributes[ $taxonomy ] ) ) { + $_attribute = $attributes[ $taxonomy ]; + + if ( $_attribute['is_variation'] ) { + $value = ''; + + if ( isset( $default_attr['option'] ) ) { + if ( $_attribute['is_taxonomy'] ) { + // Don't use wc_clean as it destroys sanitized characters + $value = sanitize_title( trim( stripslashes( $default_attr['option'] ) ) ); + } else { + $value = wc_clean( trim( stripslashes( $default_attr['option'] ) ) ); + } + } + + if ( $value ) { + $default_attributes[ $taxonomy ] = $value; + } + } + } + } + + $product->set_default_attributes( $default_attributes ); + } + + return $product; + } + + /** + * Save product meta. + * + * @since 2.2 + * @param WC_Product $product + * @param array $data + * @return WC_Product + * @throws WC_API_Exception + */ + protected function save_product_meta( $product, $data ) { + global $wpdb; + + // Virtual. + if ( isset( $data['virtual'] ) ) { + $product->set_virtual( $data['virtual'] ); + } + + // Tax status. + if ( isset( $data['tax_status'] ) ) { + $product->set_tax_status( wc_clean( $data['tax_status'] ) ); + } + + // Tax Class. + if ( isset( $data['tax_class'] ) ) { + $product->set_tax_class( wc_clean( $data['tax_class'] ) ); + } + + // Catalog Visibility. + if ( isset( $data['catalog_visibility'] ) ) { + $product->set_catalog_visibility( wc_clean( $data['catalog_visibility'] ) ); + } + + // Purchase Note. + if ( isset( $data['purchase_note'] ) ) { + $product->set_purchase_note( wc_clean( $data['purchase_note'] ) ); + } + + // Featured Product. + if ( isset( $data['featured'] ) ) { + $product->set_featured( $data['featured'] ); + } + + // Shipping data. + $product = $this->save_product_shipping_data( $product, $data ); + + // SKU. + if ( isset( $data['sku'] ) ) { + $sku = $product->get_sku(); + $new_sku = wc_clean( $data['sku'] ); + + if ( '' == $new_sku ) { + $product->set_sku( '' ); + } elseif ( $new_sku !== $sku ) { + if ( ! empty( $new_sku ) ) { + $unique_sku = wc_product_has_unique_sku( $product->get_id(), $new_sku ); + if ( ! $unique_sku ) { + throw new WC_API_Exception( 'woocommerce_api_product_sku_already_exists', __( 'The SKU already exists on another product.', 'woocommerce' ), 400 ); + } else { + $product->set_sku( $new_sku ); + } + } else { + $product->set_sku( '' ); + } + } + } + + // Attributes. + if ( isset( $data['attributes'] ) ) { + $attributes = array(); + + foreach ( $data['attributes'] as $attribute ) { + $is_taxonomy = 0; + $taxonomy = 0; + + if ( ! isset( $attribute['name'] ) ) { + continue; + } + + $attribute_slug = sanitize_title( $attribute['name'] ); + + if ( isset( $attribute['slug'] ) ) { + $taxonomy = $this->get_attribute_taxonomy_by_slug( $attribute['slug'] ); + $attribute_slug = sanitize_title( $attribute['slug'] ); + } + + if ( $taxonomy ) { + $is_taxonomy = 1; + } + + if ( $is_taxonomy ) { + + $attribute_id = wc_attribute_taxonomy_id_by_name( $attribute['name'] ); + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + // Update post terms + if ( taxonomy_exists( $taxonomy ) ) { + wp_set_object_terms( $product->get_id(), $values, $taxonomy ); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $taxonomy ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? absint( $attribute['position'] ) : 0 ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Array based. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + + // Text based, separate by pipe. + } else { + $values = array_map( 'wc_clean', explode( WC_DELIMITER, $attribute['options'] ) ); + } + + // Custom attribute - Add attribute to array and set the values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute['name'] ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? absint( $attribute['position'] ) : 0 ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + + uasort( $attributes, 'wc_product_attribute_uasort_comparison' ); + + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ) ) ) { + + // Variable and grouped products have no prices. + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + + } else { + + // Regular Price. + if ( isset( $data['regular_price'] ) ) { + $regular_price = ( '' === $data['regular_price'] ) ? '' : $data['regular_price']; + $product->set_regular_price( $regular_price ); + } + + // Sale Price. + if ( isset( $data['sale_price'] ) ) { + $sale_price = ( '' === $data['sale_price'] ) ? '' : $data['sale_price']; + $product->set_sale_price( $sale_price ); + } + + if ( isset( $data['sale_price_dates_from'] ) ) { + $date_from = $data['sale_price_dates_from']; + } else { + $date_from = $product->get_date_on_sale_from() ? date( 'Y-m-d', $product->get_date_on_sale_from()->getTimestamp() ) : ''; + } + + if ( isset( $data['sale_price_dates_to'] ) ) { + $date_to = $data['sale_price_dates_to']; + } else { + $date_to = $product->get_date_on_sale_to() ? date( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ) : ''; + } + + if ( $date_to && ! $date_from ) { + $date_from = strtotime( 'NOW', current_time( 'timestamp', true ) ); + } + + $product->set_date_on_sale_to( $date_to ); + $product->set_date_on_sale_from( $date_from ); + + if ( $product->is_on_sale( 'edit' ) ) { + $product->set_price( $product->get_sale_price( 'edit' ) ); + } else { + $product->set_price( $product->get_regular_price( 'edit' ) ); + } + } + + // Product parent ID for groups. + if ( isset( $data['parent_id'] ) ) { + $product->set_parent_id( absint( $data['parent_id'] ) ); + } + + // Sold Individually. + if ( isset( $data['sold_individually'] ) ) { + $product->set_sold_individually( true === $data['sold_individually'] ? 'yes' : '' ); + } + + // Stock status. + if ( isset( $data['in_stock'] ) ) { + $stock_status = ( true === $data['in_stock'] ) ? 'instock' : 'outofstock'; + } else { + $stock_status = $product->get_stock_status(); + + if ( '' === $stock_status ) { + $stock_status = 'instock'; + } + } + + // Stock Data. + if ( 'yes' == get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock. + if ( isset( $data['managing_stock'] ) ) { + $managing_stock = ( true === $data['managing_stock'] ) ? 'yes' : 'no'; + $product->set_manage_stock( $managing_stock ); + } else { + $managing_stock = $product->get_manage_stock() ? 'yes' : 'no'; + } + + // Backorders. + if ( isset( $data['backorders'] ) ) { + if ( 'notify' === $data['backorders'] ) { + $backorders = 'notify'; + } else { + $backorders = ( true === $data['backorders'] ) ? 'yes' : 'no'; + } + + $product->set_backorders( $backorders ); + } else { + $backorders = $product->get_backorders(); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( 'yes' == $managing_stock ) { + $product->set_backorders( $backorders ); + + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity. + if ( isset( $data['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $data['stock_quantity'] ) ); + } elseif ( isset( $data['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $data['inventory_delta'] ); + $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_backorders( $backorders ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells. + if ( isset( $data['upsell_ids'] ) ) { + $upsells = array(); + $ids = $data['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + + $product->set_upsell_ids( $upsells ); + } else { + $product->set_upsell_ids( array() ); + } + } + + // Cross sells. + if ( isset( $data['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $data['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + + $product->set_cross_sell_ids( $crosssells ); + } else { + $product->set_cross_sell_ids( array() ); + } + } + + // Product categories. + if ( isset( $data['categories'] ) && is_array( $data['categories'] ) ) { + $product->set_category_ids( $data['categories'] ); + } + + // Product tags. + if ( isset( $data['tags'] ) && is_array( $data['tags'] ) ) { + $product->set_tag_ids( $data['tags'] ); + } + + // Downloadable. + if ( isset( $data['downloadable'] ) ) { + $is_downloadable = ( true === $data['downloadable'] ) ? 'yes' : 'no'; + $product->set_downloadable( $is_downloadable ); + } else { + $is_downloadable = $product->get_downloadable() ? 'yes' : 'no'; + } + + // Downloadable options. + if ( 'yes' == $is_downloadable ) { + + // Downloadable files. + if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $data['downloads'] ); + } + + // Download limit. + if ( isset( $data['download_limit'] ) ) { + $product->set_download_limit( $data['download_limit'] ); + } + + // Download expiry. + if ( isset( $data['download_expiry'] ) ) { + $product->set_download_expiry( $data['download_expiry'] ); + } + } + + // Product url. + if ( $product->is_type( 'external' ) ) { + if ( isset( $data['product_url'] ) ) { + $product->set_product_url( $data['product_url'] ); + } + + if ( isset( $data['button_text'] ) ) { + $product->set_button_text( $data['button_text'] ); + } + } + + // Reviews allowed. + if ( isset( $data['reviews_allowed'] ) ) { + $product->set_reviews_allowed( $data['reviews_allowed'] ); + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $data ); + } + + // Do action for product type + do_action( 'woocommerce_api_process_product_meta_' . $product->get_type(), $product->get_id(), $data ); + + return $product; + } + + /** + * Save variations. + * + * @since 2.2 + * + * @param WC_Product $product + * @param array $request + * + * @return bool + * @throws WC_API_Exception + */ + protected function save_variations( $product, $request ) { + global $wpdb; + + $id = $product->get_id(); + $variations = $request['variations']; + $attributes = $product->get_attributes(); + + foreach ( $variations as $menu_order => $data ) { + $variation_id = isset( $data['id'] ) ? absint( $data['id'] ) : 0; + $variation = new WC_Product_Variation( $variation_id ); + + // Create initial name and status. + if ( ! $variation->get_slug() ) { + /* translators: 1: variation id 2: product name */ + $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation->get_id(), $product->get_name() ) ); + $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); + } + + // Parent ID. + $variation->set_parent_id( $product->get_id() ); + + // Menu order. + $variation->set_menu_order( $menu_order ); + + // Status. + if ( isset( $data['visible'] ) ) { + $variation->set_status( false === $data['visible'] ? 'private' : 'publish' ); + } + + // SKU. + if ( isset( $data['sku'] ) ) { + $variation->set_sku( wc_clean( $data['sku'] ) ); + } + + // Thumbnail. + if ( isset( $data['image'] ) && is_array( $data['image'] ) ) { + $image = current( $data['image'] ); + if ( is_array( $image ) ) { + $image['position'] = 0; + } + + $variation = $this->save_product_images( $variation, array( $image ) ); + } + + // Virtual variation. + if ( isset( $data['virtual'] ) ) { + $variation->set_virtual( $data['virtual'] ); + } + + // Downloadable variation. + if ( isset( $data['downloadable'] ) ) { + $is_downloadable = $data['downloadable']; + $variation->set_downloadable( $is_downloadable ); + } else { + $is_downloadable = $variation->get_downloadable(); + } + + // Downloads. + if ( $is_downloadable ) { + // Downloadable files. + if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $data['downloads'] ); + } + + // Download limit. + if ( isset( $data['download_limit'] ) ) { + $variation->set_download_limit( $data['download_limit'] ); + } + + // Download expiry. + if ( isset( $data['download_expiry'] ) ) { + $variation->set_download_expiry( $data['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $data ); + + // Stock handling. + $manage_stock = (bool) $variation->get_manage_stock(); + if ( isset( $data['managing_stock'] ) ) { + $manage_stock = $data['managing_stock']; + } + $variation->set_manage_stock( $manage_stock ); + + $stock_status = $variation->get_stock_status(); + if ( isset( $data['in_stock'] ) ) { + $stock_status = true === $data['in_stock'] ? 'instock' : 'outofstock'; + } + $variation->set_stock_status( $stock_status ); + + $backorders = $variation->get_backorders(); + if ( isset( $data['backorders'] ) ) { + $backorders = $data['backorders']; + } + $variation->set_backorders( $backorders ); + + if ( $manage_stock ) { + if ( isset( $data['stock_quantity'] ) ) { + $variation->set_stock_quantity( $data['stock_quantity'] ); + } elseif ( isset( $data['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $data['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $data['regular_price'] ) ) { + $variation->set_regular_price( $data['regular_price'] ); + } + + // Sale Price. + if ( isset( $data['sale_price'] ) ) { + $variation->set_sale_price( $data['sale_price'] ); + } + + if ( isset( $data['sale_price_dates_from'] ) ) { + $variation->set_date_on_sale_from( $data['sale_price_dates_from'] ); + } + + if ( isset( $data['sale_price_dates_to'] ) ) { + $variation->set_date_on_sale_to( $data['sale_price_dates_to'] ); + } + + // Tax class. + if ( isset( $data['tax_class'] ) ) { + $variation->set_tax_class( $data['tax_class'] ); + } + + // Description. + if ( isset( $data['description'] ) ) { + $variation->set_description( wp_kses_post( $data['description'] ) ); + } + + // Update taxonomies. + if ( isset( $data['attributes'] ) ) { + $_attributes = array(); + + foreach ( $data['attributes'] as $attribute_key => $attribute ) { + if ( ! isset( $attribute['name'] ) ) { + continue; + } + + $taxonomy = 0; + $_attribute = array(); + + if ( isset( $attribute['slug'] ) ) { + $taxonomy = $this->get_attribute_taxonomy_by_slug( $attribute['slug'] ); + } + + if ( ! $taxonomy ) { + $taxonomy = sanitize_title( $attribute['name'] ); + } + + if ( isset( $attributes[ $taxonomy ] ) ) { + $_attribute = $attributes[ $taxonomy ]; + } + + if ( isset( $_attribute['is_variation'] ) && $_attribute['is_variation'] ) { + $_attribute_key = sanitize_title( $_attribute['name'] ); + + if ( isset( $_attribute['is_taxonomy'] ) && $_attribute['is_taxonomy'] ) { + // Don't use wc_clean as it destroys sanitized characters. + $_attribute_value = isset( $attribute['option'] ) ? sanitize_title( stripslashes( $attribute['option'] ) ) : ''; + } else { + $_attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + } + + $_attributes[ $_attribute_key ] = $_attribute_value; + } + } + + $variation->set_attributes( $_attributes ); + } + + $variation->save(); + + do_action( 'woocommerce_api_save_product_variation', $variation_id, $menu_order, $variation ); + } + + return true; + } + + /** + * Save product shipping data + * + * @since 2.2 + * @param WC_Product $product + * @param array $data + * @return WC_Product + */ + private function save_product_shipping_data( $product, $data ) { + if ( isset( $data['weight'] ) ) { + $product->set_weight( '' === $data['weight'] ? '' : wc_format_decimal( $data['weight'] ) ); + } + + // Product dimensions + if ( isset( $data['dimensions'] ) ) { + // Height + if ( isset( $data['dimensions']['height'] ) ) { + $product->set_height( '' === $data['dimensions']['height'] ? '' : wc_format_decimal( $data['dimensions']['height'] ) ); + } + + // Width + if ( isset( $data['dimensions']['width'] ) ) { + $product->set_width( '' === $data['dimensions']['width'] ? '' : wc_format_decimal( $data['dimensions']['width'] ) ); + } + + // Length + if ( isset( $data['dimensions']['length'] ) ) { + $product->set_length( '' === $data['dimensions']['length'] ? '' : wc_format_decimal( $data['dimensions']['length'] ) ); + } + } + + // Virtual + if ( isset( $data['virtual'] ) ) { + $virtual = ( true === $data['virtual'] ) ? 'yes' : 'no'; + + if ( 'yes' == $virtual ) { + $product->set_weight( '' ); + $product->set_height( '' ); + $product->set_length( '' ); + $product->set_width( '' ); + } + } + + // Shipping class + if ( isset( $data['shipping_class'] ) ) { + $data_store = $product->get_data_store(); + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + + return $product; + } + + /** + * Save downloadable files + * + * @since 2.2 + * @param WC_Product $product + * @param array $downloads + * @param int $deprecated Deprecated since 3.0. + * @return WC_Product + */ + private function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { + if ( $deprecated ) { + wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() does not require a variation_id anymore.' ); + } + + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( isset( $file['url'] ) ) { + $file['file'] = $file['url']; + } + + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); + $files[] = $download; + } + $product->set_downloads( $files ); + + return $product; + } + + /** + * Get attribute taxonomy by slug. + * + * @since 2.2 + * @param string $slug + * @return string|null + */ + private function get_attribute_taxonomy_by_slug( $slug ) { + $taxonomy = null; + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + foreach ( $attribute_taxonomies as $key => $tax ) { + if ( $slug == $tax->attribute_name ) { + $taxonomy = 'pa_' . $tax->attribute_name; + + break; + } + } + + return $taxonomy; + } + + /** + * Get the images for a product or product variation + * + * @since 2.1 + * @param WC_Product|WC_Product_Variation $product + * @return array + */ + private function get_images( $product ) { + $images = $attachment_ids = array(); + $product_image = $product->get_image_id(); + + // Add featured image. + if ( ! empty( $product_image ) ) { + $attachment_ids[] = $product_image; + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $position => $attachment_id ) { + + $attachment_post = get_post( $attachment_id ); + + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'created_at' => $this->server->format_datetime( $attachment_post->post_date_gmt ), + 'updated_at' => $this->server->format_datetime( $attachment_post->post_modified_gmt ), + 'src' => current( $attachment ), + 'title' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + 'position' => (int) $position, + ); + } + + // Set a placeholder image if the product has no images set. + if ( empty( $images ) ) { + + $images[] = array( + 'id' => 0, + 'created_at' => $this->server->format_datetime( time() ), // Default to now. + 'updated_at' => $this->server->format_datetime( time() ), + 'src' => wc_placeholder_img_src(), + 'title' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), + 'position' => 0, + ); + } + + return $images; + } + + /** + * Save product images. + * + * @since 2.2 + * @param WC_Product $product + * @param array $images + * @throws WC_API_Exception + * @return WC_Product + */ + protected function save_product_images( $product, $images ) { + if ( is_array( $images ) ) { + $gallery = array(); + + foreach ( $images as $image ) { + if ( isset( $image['position'] ) && 0 == $image['position'] ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = $this->upload_product_image( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_upload_product_image', $upload->get_error_message(), 400 ); + } + + $attachment_id = $this->set_product_image_as_attachment( $upload, $product->get_id() ); + } + + $product->set_image_id( $attachment_id ); + } else { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = $this->upload_product_image( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_upload_product_image', $upload->get_error_message(), 400 ); + } + + $attachment_id = $this->set_product_image_as_attachment( $upload, $product->get_id() ); + } + + $gallery[] = $attachment_id; + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) && $attachment_id ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image title if present. + if ( ! empty( $image['title'] ) && $attachment_id ) { + wp_update_post( array( 'ID' => $attachment_id, 'post_title' => $image['title'] ) ); + } + } + + if ( ! empty( $gallery ) ) { + $product->set_gallery_image_ids( $gallery ); + } + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Upload image from URL + * + * @since 2.2 + * @param string $image_url + * @return int|WP_Error attachment id + */ + public function upload_product_image( $image_url ) { + return $this->upload_image_from_url( $image_url, 'product_image' ); + } + + /** + * Upload product category image from URL. + * + * @since 2.5.0 + * @param string $image_url + * @return int|WP_Error attachment id + */ + public function upload_product_category_image( $image_url ) { + return $this->upload_image_from_url( $image_url, 'product_category_image' ); + } + + /** + * Upload image from URL. + * + * @throws WC_API_Exception + * + * @since 2.5.0 + * @param string $image_url + * @param string $upload_for + * @return array + */ + protected function upload_image_from_url( $image_url, $upload_for = 'product_image' ) { + $upload = wc_rest_upload_image_from_url( $image_url ); + if ( is_wp_error( $upload ) ) { + throw new WC_API_Exception( 'woocommerce_api_' . $upload_for . '_upload_error', $upload->get_error_message(), 400 ); + } + + do_action( 'woocommerce_api_uploaded_image_from_url', $upload, $image_url, $upload_for ); + + return $upload; + } + + /** + * Sets product image as attachment and returns the attachment ID. + * + * @since 2.2 + * @param array $upload + * @param int $id + * @return int + */ + protected function set_product_image_as_attachment( $upload, $id ) { + return $this->set_uploaded_image_as_attachment( $upload, $id ); + } + + /** + * Sets uploaded category image as attachment and returns the attachment ID. + * + * @since 2.5.0 + * @param integer $upload Upload information from wp_upload_bits + * @return int Attachment ID + */ + protected function set_product_category_image_as_attachment( $upload ) { + return $this->set_uploaded_image_as_attachment( $upload ); + } + + /** + * Set uploaded image as attachment. + * + * @since 2.5.0 + * @param array $upload Upload information from wp_upload_bits + * @param int $id Post ID. Default to 0. + * @return int Attachment ID + */ + protected function set_uploaded_image_as_attachment( $upload, $id = 0 ) { + $info = wp_check_filetype( $upload['file'] ); + $title = ''; + $content = ''; + + if ( $image_meta = @wp_read_image_metadata( $upload['file'] ) ) { + if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { + $title = wc_clean( $image_meta['title'] ); + } + if ( trim( $image_meta['caption'] ) ) { + $content = wc_clean( $image_meta['caption'] ); + } + } + + $attachment = array( + 'post_mime_type' => $info['type'], + 'guid' => $upload['url'], + 'post_parent' => $id, + 'post_title' => $title, + 'post_content' => $content, + ); + + $attachment_id = wp_insert_attachment( $attachment, $upload['file'], $id ); + if ( ! is_wp_error( $attachment_id ) ) { + wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $upload['file'] ) ); + } + + return $attachment_id; + } + + /** + * Get attribute options. + * + * @param int $product_id + * @param array $attribute + * @return array + */ + protected function get_attribute_options( $product_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( $product_id, $attribute['name'], array( 'fields' => 'names' ) ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation + * + * @since 2.1 + * @param WC_Product|WC_Product_Variation $product + * @return array + */ + private function get_attributes( $product ) { + + $attributes = array(); + + if ( $product->is_type( 'variation' ) ) { + + // variation attributes + foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { + + // taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_` + $attributes[] = array( + 'name' => wc_attribute_label( str_replace( 'attribute_', '', $attribute_name ), $product ), + 'slug' => str_replace( 'attribute_', '', wc_attribute_taxonomy_slug( $attribute_name ) ), + 'option' => $attribute, + ); + } + } else { + + foreach ( $product->get_attributes() as $attribute ) { + $attributes[] = array( + 'name' => wc_attribute_label( $attribute['name'], $product ), + 'slug' => wc_attribute_taxonomy_slug( $attribute['name'] ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } + } + + return $attributes; + } + + /** + * Get the downloads for a product or product variation + * + * @since 2.1 + * @param WC_Product|WC_Product_Variation $product + * @return array + */ + private function get_downloads( $product ) { + + $downloads = array(); + + if ( $product->is_downloadable() ) { + + foreach ( $product->get_downloads() as $file_id => $file ) { + + $downloads[] = array( + 'id' => $file_id, // do not cast as int as this is a hash + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get a listing of product attributes + * + * @since 2.5.0 + * + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_attributes( $fields = null ) { + try { + // Permissions check. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_attributes', __( 'You do not have permission to read product attributes', 'woocommerce' ), 401 ); + } + + $product_attributes = array(); + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + foreach ( $attribute_taxonomies as $attribute ) { + $product_attributes[] = array( + 'id' => intval( $attribute->attribute_id ), + 'name' => $attribute->attribute_label, + 'slug' => wc_attribute_taxonomy_name( $attribute->attribute_name ), + 'type' => $attribute->attribute_type, + 'order_by' => $attribute->attribute_orderby, + 'has_archives' => (bool) $attribute->attribute_public, + ); + } + + return array( 'product_attributes' => apply_filters( 'woocommerce_api_product_attributes_response', $product_attributes, $attribute_taxonomies, $fields, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the product attribute for the given ID + * + * @since 2.5.0 + * + * @param string $id product attribute term ID + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_product_attribute( $id, $fields = null ) { + global $wpdb; + + try { + $id = absint( $id ); + + // Validate ID + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'Invalid product attribute ID', 'woocommerce' ), 400 ); + } + + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_attributes', __( 'You do not have permission to read product attributes', 'woocommerce' ), 401 ); + } + + $attribute = $wpdb->get_row( $wpdb->prepare( " + SELECT * + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) ); + + if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $product_attribute = array( + 'id' => intval( $attribute->attribute_id ), + 'name' => $attribute->attribute_label, + 'slug' => wc_attribute_taxonomy_name( $attribute->attribute_name ), + 'type' => $attribute->attribute_type, + 'order_by' => $attribute->attribute_orderby, + 'has_archives' => (bool) $attribute->attribute_public, + ); + + return array( 'product_attribute' => apply_filters( 'woocommerce_api_product_attribute_response', $product_attribute, $id, $fields, $attribute, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Validate attribute data. + * + * @since 2.5.0 + * @param string $name + * @param string $slug + * @param string $type + * @param string $order_by + * @param bool $new_data + * @return bool + * @throws WC_API_Exception + */ + protected function validate_attribute_data( $name, $slug, $type, $order_by, $new_data = true ) { + if ( empty( $name ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_attribute_name', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'name' ), 400 ); + } + + if ( strlen( $slug ) >= 28 ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), 400 ); + } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), 400 ); + } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), 400 ); + } + + // Validate the attribute type + if ( ! in_array( wc_clean( $type ), array_keys( wc_get_attribute_types() ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_type', sprintf( __( 'Invalid product attribute type - the product attribute type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_attribute_types() ) ) ), 400 ); + } + + // Validate the attribute order by + if ( ! in_array( wc_clean( $order_by ), array( 'menu_order', 'name', 'name_num', 'id' ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_order_by', sprintf( __( 'Invalid product attribute order_by type - the product attribute order_by type must be any of these: %s', 'woocommerce' ), implode( ', ', array( 'menu_order', 'name', 'name_num', 'id' ) ) ), 400 ); + } + + return true; + } + + /** + * Create a new product attribute. + * + * @since 2.5.0 + * + * @param array $data Posted data. + * + * @return array|WP_Error + */ + public function create_product_attribute( $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_attribute'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_attribute_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product_attribute' ), 400 ); + } + + $data = $data['product_attribute']; + + // Check permissions. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_product_attribute', __( 'You do not have permission to create product attributes', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_product_attribute_data', $data, $this ); + + if ( ! isset( $data['name'] ) ) { + $data['name'] = ''; + } + + // Set the attribute slug. + if ( ! isset( $data['slug'] ) ) { + $data['slug'] = wc_sanitize_taxonomy_name( stripslashes( $data['name'] ) ); + } else { + $data['slug'] = preg_replace( '/^pa\_/', '', wc_sanitize_taxonomy_name( stripslashes( $data['slug'] ) ) ); + } + + // Set attribute type when not sent. + if ( ! isset( $data['type'] ) ) { + $data['type'] = 'select'; + } + + // Set order by when not sent. + if ( ! isset( $data['order_by'] ) ) { + $data['order_by'] = 'menu_order'; + } + + // Validate the attribute data. + $this->validate_attribute_data( $data['name'], $data['slug'], $data['type'], $data['order_by'], true ); + + $insert = $wpdb->insert( + $wpdb->prefix . 'woocommerce_attribute_taxonomies', + array( + 'attribute_label' => $data['name'], + 'attribute_name' => $data['slug'], + 'attribute_type' => $data['type'], + 'attribute_orderby' => $data['order_by'], + 'attribute_public' => isset( $data['has_archives'] ) && true === $data['has_archives'] ? 1 : 0, + ), + array( '%s', '%s', '%s', '%s', '%d' ) + ); + + // Checks for an error in the product creation. + if ( is_wp_error( $insert ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_product_attribute', $insert->get_error_message(), 400 ); + } + + $id = $wpdb->insert_id; + + do_action( 'woocommerce_api_create_product_attribute', $id, $data ); + + // Clear transients. + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); + delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); + + $this->server->send_status( 201 ); + + return $this->get_product_attribute( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a product attribute. + * + * @since 2.5.0 + * + * @param int $id the attribute ID. + * @param array $data + * + * @return array|WP_Error + */ + public function edit_product_attribute( $id, $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_attribute'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_attribute_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product_attribute' ), 400 ); + } + + $id = absint( $id ); + $data = $data['product_attribute']; + + // Check permissions. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_product_attribute', __( 'You do not have permission to edit product attributes', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_edit_product_attribute_data', $data, $this ); + $attribute = $this->get_product_attribute( $id ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $attribute_name = isset( $data['name'] ) ? $data['name'] : $attribute['product_attribute']['name']; + $attribute_type = isset( $data['type'] ) ? $data['type'] : $attribute['product_attribute']['type']; + $attribute_order_by = isset( $data['order_by'] ) ? $data['order_by'] : $attribute['product_attribute']['order_by']; + + if ( isset( $data['slug'] ) ) { + $attribute_slug = wc_sanitize_taxonomy_name( stripslashes( $data['slug'] ) ); + } else { + $attribute_slug = $attribute['product_attribute']['slug']; + } + $attribute_slug = preg_replace( '/^pa\_/', '', $attribute_slug ); + + if ( isset( $data['has_archives'] ) ) { + $attribute_public = true === $data['has_archives'] ? 1 : 0; + } else { + $attribute_public = $attribute['product_attribute']['has_archives']; + } + + // Validate the attribute data. + $this->validate_attribute_data( $attribute_name, $attribute_slug, $attribute_type, $attribute_order_by, false ); + + $update = $wpdb->update( + $wpdb->prefix . 'woocommerce_attribute_taxonomies', + array( + 'attribute_label' => $attribute_name, + 'attribute_name' => $attribute_slug, + 'attribute_type' => $attribute_type, + 'attribute_orderby' => $attribute_order_by, + 'attribute_public' => $attribute_public, + ), + array( 'attribute_id' => $id ), + array( '%s', '%s', '%s', '%s', '%d' ), + array( '%d' ) + ); + + // Checks for an error in the product creation. + if ( false === $update ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_edit_product_attribute', __( 'Could not edit the attribute', 'woocommerce' ), 400 ); + } + + do_action( 'woocommerce_api_edit_product_attribute', $id, $data ); + + // Clear transients. + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); + delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); + + return $this->get_product_attribute( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a product attribute. + * + * @since 2.5.0 + * + * @param int $id the product attribute ID. + * + * @return array|WP_Error + */ + public function delete_product_attribute( $id ) { + global $wpdb; + + try { + // Check permissions. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_product_attribute', __( 'You do not have permission to delete product attributes', 'woocommerce' ), 401 ); + } + + $id = absint( $id ); + + $attribute_name = $wpdb->get_var( $wpdb->prepare( " + SELECT attribute_name + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) ); + + if ( is_null( $attribute_name ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $deleted = $wpdb->delete( + $wpdb->prefix . 'woocommerce_attribute_taxonomies', + array( 'attribute_id' => $id ), + array( '%d' ) + ); + + if ( false === $deleted ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_product_attribute', __( 'Could not delete the attribute', 'woocommerce' ), 401 ); + } + + $taxonomy = wc_attribute_taxonomy_name( $attribute_name ); + + if ( taxonomy_exists( $taxonomy ) ) { + $terms = get_terms( $taxonomy, 'orderby=name&hide_empty=0' ); + foreach ( $terms as $term ) { + wp_delete_term( $term->term_id, $taxonomy ); + } + } + + do_action( 'woocommerce_attribute_deleted', $id, $attribute_name, $taxonomy ); + do_action( 'woocommerce_api_delete_product_attribute', $id, $this ); + + // Clear transients. + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); + delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product_attribute' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get a listing of product attribute terms. + * + * @since 2.5.0 + * + * @param int $attribute_id Attribute ID. + * @param string|null $fields Fields to limit response to. + * + * @return array|WP_Error + */ + public function get_product_attribute_terms( $attribute_id, $fields = null ) { + try { + // Permissions check. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_attribute_terms', __( 'You do not have permission to read product attribute terms', 'woocommerce' ), 401 ); + } + + $attribute_id = absint( $attribute_id ); + $taxonomy = wc_attribute_taxonomy_name_by_id( $attribute_id ); + + if ( ! $taxonomy ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) ); + $attribute_terms = array(); + + foreach ( $terms as $term ) { + $attribute_terms[] = array( + 'id' => $term->term_id, + 'slug' => $term->slug, + 'name' => $term->name, + 'count' => $term->count, + ); + } + + return array( 'product_attribute_terms' => apply_filters( 'woocommerce_api_product_attribute_terms_response', $attribute_terms, $terms, $fields, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the product attribute term for the given ID. + * + * @since 2.5.0 + * + * @param int $attribute_id Attribute ID. + * @param string $id Product attribute term ID. + * @param string|null $fields Fields to limit response to. + * + * @return array|WP_Error + */ + public function get_product_attribute_term( $attribute_id, $id, $fields = null ) { + global $wpdb; + + try { + $id = absint( $id ); + $attribute_id = absint( $attribute_id ); + + // Validate ID + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_term_id', __( 'Invalid product attribute ID', 'woocommerce' ), 400 ); + } + + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_attribute_terms', __( 'You do not have permission to read product attribute terms', 'woocommerce' ), 401 ); + } + + $taxonomy = wc_attribute_taxonomy_name_by_id( $attribute_id ); + + if ( ! $taxonomy ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $term = get_term( $id, $taxonomy ); + + if ( is_wp_error( $term ) || is_null( $term ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_term_id', __( 'A product attribute term with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $attribute_term = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'count' => $term->count, + ); + + return array( 'product_attribute_term' => apply_filters( 'woocommerce_api_product_attribute_response', $attribute_term, $id, $fields, $term, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new product attribute term. + * + * @since 2.5.0 + * + * @param int $attribute_id Attribute ID. + * @param array $data Posted data. + * + * @return array|WP_Error + */ + public function create_product_attribute_term( $attribute_id, $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_attribute_term'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_attribute_term_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product_attribute_term' ), 400 ); + } + + $data = $data['product_attribute_term']; + + // Check permissions. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_product_attribute', __( 'You do not have permission to create product attributes', 'woocommerce' ), 401 ); + } + + $taxonomy = wc_attribute_taxonomy_name_by_id( $attribute_id ); + + if ( ! $taxonomy ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $data = apply_filters( 'woocommerce_api_create_product_attribute_term_data', $data, $this ); + + // Check if attribute term name is specified. + if ( ! isset( $data['name'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_attribute_term_name', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'name' ), 400 ); + } + + $args = array(); + + // Set the attribute term slug. + if ( isset( $data['slug'] ) ) { + $args['slug'] = sanitize_title( wp_unslash( $data['slug'] ) ); + } + + $term = wp_insert_term( $data['name'], $taxonomy, $args ); + + // Checks for an error in the term creation. + if ( is_wp_error( $term ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_product_attribute', $term->get_error_message(), 400 ); + } + + $id = $term['term_id']; + + do_action( 'woocommerce_api_create_product_attribute_term', $id, $data ); + + $this->server->send_status( 201 ); + + return $this->get_product_attribute_term( $attribute_id, $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a product attribute term. + * + * @since 2.5.0 + * + * @param int $attribute_id Attribute ID. + * @param int $id the attribute ID. + * @param array $data + * + * @return array|WP_Error + */ + public function edit_product_attribute_term( $attribute_id, $id, $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_attribute_term'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_attribute_term_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product_attribute_term' ), 400 ); + } + + $id = absint( $id ); + $data = $data['product_attribute_term']; + + // Check permissions. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_product_attribute', __( 'You do not have permission to edit product attributes', 'woocommerce' ), 401 ); + } + + $taxonomy = wc_attribute_taxonomy_name_by_id( $attribute_id ); + + if ( ! $taxonomy ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $data = apply_filters( 'woocommerce_api_edit_product_attribute_term_data', $data, $this ); + + $args = array(); + + // Update name. + if ( isset( $data['name'] ) ) { + $args['name'] = wc_clean( wp_unslash( $data['name'] ) ); + } + + // Update slug. + if ( isset( $data['slug'] ) ) { + $args['slug'] = sanitize_title( wp_unslash( $data['slug'] ) ); + } + + $term = wp_update_term( $id, $taxonomy, $args ); + + if ( is_wp_error( $term ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_edit_product_attribute_term', $term->get_error_message(), 400 ); + } + + do_action( 'woocommerce_api_edit_product_attribute_term', $id, $data ); + + return $this->get_product_attribute_term( $attribute_id, $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a product attribute term. + * + * @since 2.5.0 + * + * @param int $attribute_id Attribute ID. + * @param int $id the product attribute ID. + * + * @return array|WP_Error + */ + public function delete_product_attribute_term( $attribute_id, $id ) { + global $wpdb; + + try { + // Check permissions. + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_product_attribute_term', __( 'You do not have permission to delete product attribute terms', 'woocommerce' ), 401 ); + } + + $taxonomy = wc_attribute_taxonomy_name_by_id( $attribute_id ); + + if ( ! $taxonomy ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_attribute_id', __( 'A product attribute with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $id = absint( $id ); + $term = wp_delete_term( $id, $taxonomy ); + + if ( ! $term ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_product_attribute_term', sprintf( __( 'This %s cannot be deleted', 'woocommerce' ), 'product_attribute_term' ), 500 ); + } elseif ( is_wp_error( $term ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_product_attribute_term', $term->get_error_message(), 400 ); + } + + do_action( 'woocommerce_api_delete_product_attribute_term', $id, $this ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product_attribute' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Clear product + * + * @param int $product_id + */ + protected function clear_product( $product_id ) { + if ( ! is_numeric( $product_id ) || 0 >= $product_id ) { + return; + } + + // Delete product attachments + $attachments = get_children( array( + 'post_parent' => $product_id, + 'post_status' => 'any', + 'post_type' => 'attachment', + ) ); + + foreach ( (array) $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + // Delete product + $product = wc_get_product( $product_id ); + $product->delete( true ); + } + + /** + * Bulk update or insert products + * Accepts an array with products in the formats supported by + * WC_API_Products->create_product() and WC_API_Products->edit_product() + * + * @since 2.4.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function bulk( $data ) { + + try { + if ( ! isset( $data['products'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_products_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'products' ), 400 ); + } + + $data = $data['products']; + $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'products' ); + + // Limit bulk operation + if ( count( $data ) > $limit ) { + throw new WC_API_Exception( 'woocommerce_api_products_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); + } + + $products = array(); + + foreach ( $data as $_product ) { + $product_id = 0; + $product_sku = ''; + + // Try to get the product ID + if ( isset( $_product['id'] ) ) { + $product_id = intval( $_product['id'] ); + } + + if ( ! $product_id && isset( $_product['sku'] ) ) { + $product_sku = wc_clean( $_product['sku'] ); + $product_id = wc_get_product_id_by_sku( $product_sku ); + } + + if ( $product_id ) { + + // Product exists / edit product + $edit = $this->edit_product( $product_id, array( 'product' => $_product ) ); + + if ( is_wp_error( $edit ) ) { + $products[] = array( + 'id' => $product_id, + 'sku' => $product_sku, + 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ), + ); + } else { + $products[] = $edit['product']; + } + } else { + + // Product don't exists / create product + $new = $this->create_product( array( 'product' => $_product ) ); + + if ( is_wp_error( $new ) ) { + $products[] = array( + 'id' => $product_id, + 'sku' => $product_sku, + 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ), + ); + } else { + $products[] = $new['product']; + } + } + } + + return array( 'products' => apply_filters( 'woocommerce_api_products_bulk_response', $products, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get a listing of product shipping classes. + * + * @since 2.5.0 + * @param string|null $fields Fields to limit response to + * @return array|WP_Error List of product shipping classes if succeed, + * otherwise WP_Error will be returned + */ + public function get_product_shipping_classes( $fields = null ) { + try { + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_shipping_classes', __( 'You do not have permission to read product shipping classes', 'woocommerce' ), 401 ); + } + + $product_shipping_classes = array(); + + $terms = get_terms( 'product_shipping_class', array( 'hide_empty' => false, 'fields' => 'ids' ) ); + + foreach ( $terms as $term_id ) { + $product_shipping_classes[] = current( $this->get_product_shipping_class( $term_id, $fields ) ); + } + + return array( 'product_shipping_classes' => apply_filters( 'woocommerce_api_product_shipping_classes_response', $product_shipping_classes, $terms, $fields, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the product shipping class for the given ID. + * + * @since 2.5.0 + * @param string $id Product shipping class term ID + * @param string|null $fields Fields to limit response to + * @return array|WP_Error Product shipping class if succeed, otherwise + * WP_Error will be returned + */ + public function get_product_shipping_class( $id, $fields = null ) { + try { + $id = absint( $id ); + if ( ! $id ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_shipping_class_id', __( 'Invalid product shipping class ID', 'woocommerce' ), 400 ); + } + + // Permissions check + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_product_shipping_classes', __( 'You do not have permission to read product shipping classes', 'woocommerce' ), 401 ); + } + + $term = get_term( $id, 'product_shipping_class' ); + + if ( is_wp_error( $term ) || is_null( $term ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_shipping_class_id', __( 'A product shipping class with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $term_id = intval( $term->term_id ); + + $product_shipping_class = array( + 'id' => $term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'parent' => $term->parent, + 'description' => $term->description, + 'count' => intval( $term->count ), + ); + + return array( 'product_shipping_class' => apply_filters( 'woocommerce_api_product_shipping_class_response', $product_shipping_class, $id, $fields, $term, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a new product shipping class. + * + * @since 2.5.0 + * @param array $data Posted data + * @return array|WP_Error Product shipping class if succeed, otherwise + * WP_Error will be returned + */ + public function create_product_shipping_class( $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_shipping_class'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_shipping_class_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'product_shipping_class' ), 400 ); + } + + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_product_shipping_class', __( 'You do not have permission to create product shipping classes', 'woocommerce' ), 401 ); + } + + $defaults = array( + 'name' => '', + 'slug' => '', + 'description' => '', + 'parent' => 0, + ); + + $data = wp_parse_args( $data['product_shipping_class'], $defaults ); + $data = apply_filters( 'woocommerce_api_create_product_shipping_class_data', $data, $this ); + + // Check parent. + $data['parent'] = absint( $data['parent'] ); + if ( $data['parent'] ) { + $parent = get_term_by( 'id', $data['parent'], 'product_shipping_class' ); + if ( ! $parent ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_product_shipping_class_parent', __( 'Product shipping class parent is invalid', 'woocommerce' ), 400 ); + } + } + + $insert = wp_insert_term( $data['name'], 'product_shipping_class', $data ); + if ( is_wp_error( $insert ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_create_product_shipping_class', $insert->get_error_message(), 400 ); + } + + $id = $insert['term_id']; + + do_action( 'woocommerce_api_create_product_shipping_class', $id, $data ); + + $this->server->send_status( 201 ); + + return $this->get_product_shipping_class( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a product shipping class. + * + * @since 2.5.0 + * @param int $id Product shipping class term ID + * @param array $data Posted data + * @return array|WP_Error Product shipping class if succeed, otherwise + * WP_Error will be returned + */ + public function edit_product_shipping_class( $id, $data ) { + global $wpdb; + + try { + if ( ! isset( $data['product_shipping_class'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_product_shipping_class', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'product_shipping_class' ), 400 ); + } + + $id = absint( $id ); + $data = $data['product_shipping_class']; + + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_product_shipping_class', __( 'You do not have permission to edit product shipping classes', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_edit_product_shipping_class_data', $data, $this ); + $shipping_class = $this->get_product_shipping_class( $id ); + + if ( is_wp_error( $shipping_class ) ) { + return $shipping_class; + } + + $update = wp_update_term( $id, 'product_shipping_class', $data ); + if ( is_wp_error( $update ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_edit_product_shipping_class', __( 'Could not edit the shipping class', 'woocommerce' ), 400 ); + } + + do_action( 'woocommerce_api_edit_product_shipping_class', $id, $data ); + + return $this->get_product_shipping_class( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a product shipping class. + * + * @since 2.5.0 + * @param int $id Product shipping class term ID + * @return array|WP_Error Success message if succeed, otherwise WP_Error + * will be returned + */ + public function delete_product_shipping_class( $id ) { + global $wpdb; + + try { + // Check permissions + if ( ! current_user_can( 'manage_product_terms' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_product_shipping_class', __( 'You do not have permission to delete product shipping classes', 'woocommerce' ), 401 ); + } + + $id = absint( $id ); + $deleted = wp_delete_term( $id, 'product_shipping_class' ); + if ( ! $deleted || is_wp_error( $deleted ) ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_product_shipping_class', __( 'Could not delete the shipping class', 'woocommerce' ), 401 ); + } + + do_action( 'woocommerce_api_delete_product_shipping_class', $id, $this ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product_shipping_class' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-reports.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-reports.php new file mode 100644 index 0000000..c5f5c66 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-reports.php @@ -0,0 +1,330 @@ +base ] = array( + array( array( $this, 'get_reports' ), WC_API_Server::READABLE ), + ); + + # GET /reports/sales + $routes[ $this->base . '/sales' ] = array( + array( array( $this, 'get_sales_report' ), WC_API_Server::READABLE ), + ); + + # GET /reports/sales/top_sellers + $routes[ $this->base . '/sales/top_sellers' ] = array( + array( array( $this, 'get_top_sellers_report' ), WC_API_Server::READABLE ), + ); + + return $routes; + } + + /** + * Get a simple listing of available reports + * + * @since 2.1 + * @return array + */ + public function get_reports() { + return array( 'reports' => array( 'sales', 'sales/top_sellers' ) ); + } + + /** + * Get the sales report + * + * @since 2.1 + * @param string $fields fields to include in response + * @param array $filter date filtering + * @return array|WP_Error + */ + public function get_sales_report( $fields = null, $filter = array() ) { + + // check user permissions + $check = $this->validate_request(); + + // check for WP_Error + if ( is_wp_error( $check ) ) { + return $check; + } + + // set date filtering + $this->setup_report( $filter ); + + // new customers + $users_query = new WP_User_Query( + array( + 'fields' => array( 'user_registered' ), + 'role' => 'customer', + ) + ); + + $customers = $users_query->get_results(); + + foreach ( $customers as $key => $customer ) { + if ( strtotime( $customer->user_registered ) < $this->report->start_date || strtotime( $customer->user_registered ) > $this->report->end_date ) { + unset( $customers[ $key ] ); + } + } + + $total_customers = count( $customers ); + $report_data = $this->report->get_report_data(); + $period_totals = array(); + + // setup period totals by ensuring each period in the interval has data + for ( $i = 0; $i <= $this->report->chart_interval; $i ++ ) { + + switch ( $this->report->chart_groupby ) { + case 'day' : + $time = date( 'Y-m-d', strtotime( "+{$i} DAY", $this->report->start_date ) ); + break; + default : + $time = date( 'Y-m', strtotime( "+{$i} MONTH", $this->report->start_date ) ); + break; + } + + // set the customer signups for each period + $customer_count = 0; + foreach ( $customers as $customer ) { + if ( date( ( 'day' == $this->report->chart_groupby ) ? 'Y-m-d' : 'Y-m', strtotime( $customer->user_registered ) ) == $time ) { + $customer_count++; + } + } + + $period_totals[ $time ] = array( + 'sales' => wc_format_decimal( 0.00, 2 ), + 'orders' => 0, + 'items' => 0, + 'tax' => wc_format_decimal( 0.00, 2 ), + 'shipping' => wc_format_decimal( 0.00, 2 ), + 'discount' => wc_format_decimal( 0.00, 2 ), + 'customers' => $customer_count, + ); + } + + // add total sales, total order count, total tax and total shipping for each period + foreach ( $report_data->orders as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['sales'] = wc_format_decimal( $order->total_sales, 2 ); + $period_totals[ $time ]['tax'] = wc_format_decimal( $order->total_tax + $order->total_shipping_tax, 2 ); + $period_totals[ $time ]['shipping'] = wc_format_decimal( $order->total_shipping, 2 ); + } + + foreach ( $report_data->order_counts as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['orders'] = (int) $order->count; + } + + // add total order items for each period + foreach ( $report_data->order_items as $order_item ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['items'] = (int) $order_item->order_item_count; + } + + // add total discount for each period + foreach ( $report_data->coupons as $discount ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['discount'] = wc_format_decimal( $discount->discount_amount, 2 ); + } + + $sales_data = array( + 'total_sales' => $report_data->total_sales, + 'net_sales' => $report_data->net_sales, + 'average_sales' => $report_data->average_sales, + 'total_orders' => $report_data->total_orders, + 'total_items' => $report_data->total_items, + 'total_tax' => wc_format_decimal( $report_data->total_tax + $report_data->total_shipping_tax, 2 ), + 'total_shipping' => $report_data->total_shipping, + 'total_refunds' => $report_data->total_refunds, + 'total_discount' => $report_data->total_coupons, + 'totals_grouped_by' => $this->report->chart_groupby, + 'totals' => $period_totals, + 'total_customers' => $total_customers, + ); + + return array( 'sales' => apply_filters( 'woocommerce_api_report_response', $sales_data, $this->report, $fields, $this->server ) ); + } + + /** + * Get the top sellers report + * + * @since 2.1 + * @param string $fields fields to include in response + * @param array $filter date filtering + * @return array|WP_Error + */ + public function get_top_sellers_report( $fields = null, $filter = array() ) { + + // check user permissions + $check = $this->validate_request(); + + if ( is_wp_error( $check ) ) { + return $check; + } + + // set date filtering + $this->setup_report( $filter ); + + $top_sellers = $this->report->get_order_report_data( array( + 'data' => array( + '_product_id' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => '', + 'name' => 'product_id', + ), + '_qty' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => 'SUM', + 'name' => 'order_item_qty', + ), + ), + 'order_by' => 'order_item_qty DESC', + 'group_by' => 'product_id', + 'limit' => isset( $filter['limit'] ) ? absint( $filter['limit'] ) : 12, + 'query_type' => 'get_results', + 'filter_range' => true, + ) ); + + $top_sellers_data = array(); + + foreach ( $top_sellers as $top_seller ) { + + $product = wc_get_product( $top_seller->product_id ); + + if ( $product ) { + $top_sellers_data[] = array( + 'title' => $product->get_name(), + 'product_id' => $top_seller->product_id, + 'quantity' => $top_seller->order_item_qty, + ); + } + } + + return array( 'top_sellers' => apply_filters( 'woocommerce_api_report_response', $top_sellers_data, $this->report, $fields, $this->server ) ); + } + + /** + * Setup the report object and parse any date filtering + * + * @since 2.1 + * @param array $filter date filtering + */ + private function setup_report( $filter ) { + + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' ); + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-report-sales-by-date.php' ); + + $this->report = new WC_Report_Sales_By_Date(); + + if ( empty( $filter['period'] ) ) { + + // custom date range + $filter['period'] = 'custom'; + + if ( ! empty( $filter['date_min'] ) || ! empty( $filter['date_max'] ) ) { + + // overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges + $_GET['start_date'] = $this->server->parse_datetime( $filter['date_min'] ); + $_GET['end_date'] = isset( $filter['date_max'] ) ? $this->server->parse_datetime( $filter['date_max'] ) : null; + + } else { + + // default custom range to today + $_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) ); + } + } else { + + // ensure period is valid + if ( ! in_array( $filter['period'], array( 'week', 'month', 'last_month', 'year' ) ) ) { + $filter['period'] = 'week'; + } + + // TODO: change WC_Admin_Report class to use "week" instead, as it's more consistent with other periods + // allow "week" for period instead of "7day" + if ( 'week' === $filter['period'] ) { + $filter['period'] = '7day'; + } + } + + $this->report->calculate_current_range( $filter['period'] ); + } + + /** + * Verify that the current user has permission to view reports + * + * @since 2.1 + * @see WC_API_Resource::validate_request() + * + * @param null $id unused + * @param null $type unused + * @param null $context unused + * + * @return true|WP_Error + */ + protected function validate_request( $id = null, $type = null, $context = null ) { + + if ( current_user_can( 'view_woocommerce_reports' ) ) { + return true; + } + + return new WP_Error( + 'woocommerce_api_user_cannot_read_report', + __( 'You do not have permission to read this report', 'woocommerce' ), + array( 'status' => 401 ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-resource.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-resource.php new file mode 100644 index 0000000..f321b9c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-resource.php @@ -0,0 +1,471 @@ +server = $server; + + // automatically register routes for sub-classes + add_filter( 'woocommerce_api_endpoints', array( $this, 'register_routes' ) ); + + // maybe add meta to top-level resource responses + foreach ( array( 'order', 'coupon', 'customer', 'product', 'report' ) as $resource ) { + add_filter( "woocommerce_api_{$resource}_response", array( $this, 'maybe_add_meta' ), 15, 2 ); + } + + $response_names = array( + 'order', + 'coupon', + 'customer', + 'product', + 'report', + 'customer_orders', + 'customer_downloads', + 'order_note', + 'order_refund', + 'product_reviews', + 'product_category', + 'tax', + 'tax_class', + ); + + foreach ( $response_names as $name ) { + + /** + * Remove fields from responses when requests specify certain fields + * note these are hooked at a later priority so data added via + * filters (e.g. customer data to the order response) still has the + * fields filtered properly + */ + add_filter( "woocommerce_api_{$name}_response", array( $this, 'filter_response_fields' ), 20, 3 ); + } + } + + /** + * Validate the request by checking: + * + * 1) the ID is a valid integer + * 2) the ID returns a valid post object and matches the provided post type + * 3) the current user has the proper permissions to read/edit/delete the post + * + * @since 2.1 + * @param string|int $id the post ID + * @param string $type the post type, either `shop_order`, `shop_coupon`, or `product` + * @param string $context the context of the request, either `read`, `edit` or `delete` + * @return int|WP_Error valid post ID or WP_Error if any of the checks fails + */ + protected function validate_request( $id, $type, $context ) { + + if ( 'shop_order' === $type || 'shop_coupon' === $type || 'shop_webhook' === $type ) { + $resource_name = str_replace( 'shop_', '', $type ); + } else { + $resource_name = $type; + } + + $id = absint( $id ); + + // Validate ID + if ( empty( $id ) ) { + return new WP_Error( "woocommerce_api_invalid_{$resource_name}_id", sprintf( __( 'Invalid %s ID', 'woocommerce' ), $type ), array( 'status' => 404 ) ); + } + + // Only custom post types have per-post type/permission checks + if ( 'customer' !== $type ) { + + $post = get_post( $id ); + + if ( null === $post ) { + return new WP_Error( "woocommerce_api_no_{$resource_name}_found", sprintf( __( 'No %1$s found with the ID equal to %2$s', 'woocommerce' ), $resource_name, $id ), array( 'status' => 404 ) ); + } + + // For checking permissions, product variations are the same as the product post type + $post_type = ( 'product_variation' === $post->post_type ) ? 'product' : $post->post_type; + + // Validate post type + if ( $type !== $post_type ) { + return new WP_Error( "woocommerce_api_invalid_{$resource_name}", sprintf( __( 'Invalid %s', 'woocommerce' ), $resource_name ), array( 'status' => 404 ) ); + } + + // Validate permissions + switch ( $context ) { + + case 'read': + if ( ! $this->is_readable( $post ) ) { + return new WP_Error( "woocommerce_api_user_cannot_read_{$resource_name}", sprintf( __( 'You do not have permission to read this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) ); + } + break; + + case 'edit': + if ( ! $this->is_editable( $post ) ) { + return new WP_Error( "woocommerce_api_user_cannot_edit_{$resource_name}", sprintf( __( 'You do not have permission to edit this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) ); + } + break; + + case 'delete': + if ( ! $this->is_deletable( $post ) ) { + return new WP_Error( "woocommerce_api_user_cannot_delete_{$resource_name}", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) ); + } + break; + } + } + + return $id; + } + + /** + * Add common request arguments to argument list before WP_Query is run + * + * @since 2.1 + * @param array $base_args required arguments for the query (e.g. `post_type`, etc) + * @param array $request_args arguments provided in the request + * @return array + */ + protected function merge_query_args( $base_args, $request_args ) { + + $args = array(); + + // date + if ( ! empty( $request_args['created_at_min'] ) || ! empty( $request_args['created_at_max'] ) || ! empty( $request_args['updated_at_min'] ) || ! empty( $request_args['updated_at_max'] ) ) { + + $args['date_query'] = array(); + + // resources created after specified date + if ( ! empty( $request_args['created_at_min'] ) ) { + $args['date_query'][] = array( 'column' => 'post_date_gmt', 'after' => $this->server->parse_datetime( $request_args['created_at_min'] ), 'inclusive' => true ); + } + + // resources created before specified date + if ( ! empty( $request_args['created_at_max'] ) ) { + $args['date_query'][] = array( 'column' => 'post_date_gmt', 'before' => $this->server->parse_datetime( $request_args['created_at_max'] ), 'inclusive' => true ); + } + + // resources updated after specified date + if ( ! empty( $request_args['updated_at_min'] ) ) { + $args['date_query'][] = array( 'column' => 'post_modified_gmt', 'after' => $this->server->parse_datetime( $request_args['updated_at_min'] ), 'inclusive' => true ); + } + + // resources updated before specified date + if ( ! empty( $request_args['updated_at_max'] ) ) { + $args['date_query'][] = array( 'column' => 'post_modified_gmt', 'before' => $this->server->parse_datetime( $request_args['updated_at_max'] ), 'inclusive' => true ); + } + } + + // search + if ( ! empty( $request_args['q'] ) ) { + $args['s'] = $request_args['q']; + } + + // resources per response + if ( ! empty( $request_args['limit'] ) ) { + $args['posts_per_page'] = $request_args['limit']; + } + + // resource offset + if ( ! empty( $request_args['offset'] ) ) { + $args['offset'] = $request_args['offset']; + } + + // order (ASC or DESC, ASC by default) + if ( ! empty( $request_args['order'] ) ) { + $args['order'] = $request_args['order']; + } + + // orderby + if ( ! empty( $request_args['orderby'] ) ) { + $args['orderby'] = $request_args['orderby']; + + // allow sorting by meta value + if ( ! empty( $request_args['orderby_meta_key'] ) ) { + $args['meta_key'] = $request_args['orderby_meta_key']; + } + } + + // allow post status change + if ( ! empty( $request_args['post_status'] ) ) { + $args['post_status'] = $request_args['post_status']; + unset( $request_args['post_status'] ); + } + + // filter by a list of post id + if ( ! empty( $request_args['in'] ) ) { + $args['post__in'] = explode( ',', $request_args['in'] ); + unset( $request_args['in'] ); + } + + // exclude by a list of post id + if ( ! empty( $request_args['not_in'] ) ) { + $args['post__not_in'] = explode( ',', $request_args['not_in'] ); + unset( $request_args['not_in'] ); + } + + // resource page + $args['paged'] = ( isset( $request_args['page'] ) ) ? absint( $request_args['page'] ) : 1; + + $args = apply_filters( 'woocommerce_api_query_args', $args, $request_args ); + + return array_merge( $base_args, $args ); + } + + /** + * Add meta to resources when requested by the client. Meta is added as a top-level + * `_meta` attribute (e.g. `order_meta`) as a list of key/value pairs + * + * @since 2.1 + * @param array $data the resource data + * @param object $resource the resource object (e.g WC_Order) + * @return mixed + */ + public function maybe_add_meta( $data, $resource ) { + + if ( isset( $this->server->params['GET']['filter']['meta'] ) && 'true' === $this->server->params['GET']['filter']['meta'] && is_object( $resource ) ) { + + // don't attempt to add meta more than once + if ( preg_grep( '/[a-z]+_meta/', array_keys( $data ) ) ) { + return $data; + } + + // define the top-level property name for the meta + switch ( get_class( $resource ) ) { + + case 'WC_Order': + $meta_name = 'order_meta'; + break; + + case 'WC_Coupon': + $meta_name = 'coupon_meta'; + break; + + case 'WP_User': + $meta_name = 'customer_meta'; + break; + + default: + $meta_name = 'product_meta'; + break; + } + + if ( is_a( $resource, 'WP_User' ) ) { + + // customer meta + $meta = (array) get_user_meta( $resource->ID ); + + } else { + + // coupon/order/product meta + $meta = (array) get_post_meta( $resource->get_id() ); + } + + foreach ( $meta as $meta_key => $meta_value ) { + + // don't add hidden meta by default + if ( ! is_protected_meta( $meta_key ) ) { + $data[ $meta_name ][ $meta_key ] = maybe_unserialize( $meta_value[0] ); + } + } + } + + return $data; + } + + /** + * Restrict the fields included in the response if the request specified certain only certain fields should be returned + * + * @since 2.1 + * @param array $data the response data + * @param object $resource the object that provided the response data, e.g. WC_Coupon or WC_Order + * @param array|string the requested list of fields to include in the response + * @return array response data + */ + public function filter_response_fields( $data, $resource, $fields ) { + + if ( ! is_array( $data ) || empty( $fields ) ) { + return $data; + } + + $fields = explode( ',', $fields ); + $sub_fields = array(); + + // get sub fields + foreach ( $fields as $field ) { + + if ( false !== strpos( $field, '.' ) ) { + + list( $name, $value ) = explode( '.', $field ); + + $sub_fields[ $name ] = $value; + } + } + + // iterate through top-level fields + foreach ( $data as $data_field => $data_value ) { + + // if a field has sub-fields and the top-level field has sub-fields to filter + if ( is_array( $data_value ) && in_array( $data_field, array_keys( $sub_fields ) ) ) { + + // iterate through each sub-field + foreach ( $data_value as $sub_field => $sub_field_value ) { + + // remove non-matching sub-fields + if ( ! in_array( $sub_field, $sub_fields ) ) { + unset( $data[ $data_field ][ $sub_field ] ); + } + } + } else { + + // remove non-matching top-level fields + if ( ! in_array( $data_field, $fields ) ) { + unset( $data[ $data_field ] ); + } + } + } + + return $data; + } + + /** + * Delete a given resource + * + * @since 2.1 + * @param int $id the resource ID + * @param string $type the resource post type, or `customer` + * @param bool $force true to permanently delete resource, false to move to trash (not supported for `customer`) + * @return array|WP_Error + */ + protected function delete( $id, $type, $force = false ) { + + if ( 'shop_order' === $type || 'shop_coupon' === $type ) { + $resource_name = str_replace( 'shop_', '', $type ); + } else { + $resource_name = $type; + } + + if ( 'customer' === $type ) { + + $result = wp_delete_user( $id ); + + if ( $result ) { + return array( 'message' => __( 'Permanently deleted customer', 'woocommerce' ) ); + } else { + return new WP_Error( 'woocommerce_api_cannot_delete_customer', __( 'The customer cannot be deleted', 'woocommerce' ), array( 'status' => 500 ) ); + } + } else { + + // delete order/coupon/product/webhook + $result = ( $force ) ? wp_delete_post( $id, true ) : wp_trash_post( $id ); + + if ( ! $result ) { + return new WP_Error( "woocommerce_api_cannot_delete_{$resource_name}", sprintf( __( 'This %s cannot be deleted', 'woocommerce' ), $resource_name ), array( 'status' => 500 ) ); + } + + if ( $force ) { + return array( 'message' => sprintf( __( 'Permanently deleted %s', 'woocommerce' ), $resource_name ) ); + + } else { + + $this->server->send_status( '202' ); + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), $resource_name ) ); + } + } + } + + + /** + * Checks if the given post is readable by the current user + * + * @since 2.1 + * @see WC_API_Resource::check_permission() + * @param WP_Post|int $post + * @return bool + */ + protected function is_readable( $post ) { + + return $this->check_permission( $post, 'read' ); + } + + /** + * Checks if the given post is editable by the current user + * + * @since 2.1 + * @see WC_API_Resource::check_permission() + * @param WP_Post|int $post + * @return bool + */ + protected function is_editable( $post ) { + + return $this->check_permission( $post, 'edit' ); + + } + + /** + * Checks if the given post is deletable by the current user + * + * @since 2.1 + * @see WC_API_Resource::check_permission() + * @param WP_Post|int $post + * @return bool + */ + protected function is_deletable( $post ) { + + return $this->check_permission( $post, 'delete' ); + } + + /** + * Checks the permissions for the current user given a post and context + * + * @since 2.1 + * @param WP_Post|int $post + * @param string $context the type of permission to check, either `read`, `write`, or `delete` + * @return bool true if the current user has the permissions to perform the context on the post + */ + private function check_permission( $post, $context ) { + $permission = false; + + if ( ! is_a( $post, 'WP_Post' ) ) { + $post = get_post( $post ); + } + + if ( is_null( $post ) ) { + return $permission; + } + + $post_type = get_post_type_object( $post->post_type ); + + if ( 'read' === $context ) { + $permission = 'revision' !== $post->post_type && current_user_can( $post_type->cap->read_private_posts, $post->ID ); + } elseif ( 'edit' === $context ) { + $permission = current_user_can( $post_type->cap->edit_post, $post->ID ); + } elseif ( 'delete' === $context ) { + $permission = current_user_can( $post_type->cap->delete_post, $post->ID ); + } + + return apply_filters( 'woocommerce_api_check_permission', $permission, $context, $post, $post_type ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-server.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-server.php new file mode 100644 index 0000000..44305dc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-server.php @@ -0,0 +1,777 @@ + self::METHOD_GET, + 'GET' => self::METHOD_GET, + 'POST' => self::METHOD_POST, + 'PUT' => self::METHOD_PUT, + 'PATCH' => self::METHOD_PATCH, + 'DELETE' => self::METHOD_DELETE, + ); + + /** + * Requested path (relative to the API root, wp-json.php) + * + * @var string + */ + public $path = ''; + + /** + * Requested method (GET/HEAD/POST/PUT/PATCH/DELETE) + * + * @var string + */ + public $method = 'HEAD'; + + /** + * Request parameters + * + * This acts as an abstraction of the superglobals + * (GET => $_GET, POST => $_POST) + * + * @var array + */ + public $params = array( 'GET' => array(), 'POST' => array() ); + + /** + * Request headers + * + * @var array + */ + public $headers = array(); + + /** + * Request files (matches $_FILES) + * + * @var array + */ + public $files = array(); + + /** + * Request/Response handler, either JSON by default + * or XML if requested by client + * + * @var WC_API_Handler + */ + public $handler; + + + /** + * Setup class and set request/response handler + * + * @since 2.1 + * @param $path + */ + public function __construct( $path ) { + + if ( empty( $path ) ) { + if ( isset( $_SERVER['PATH_INFO'] ) ) { + $path = $_SERVER['PATH_INFO']; + } else { + $path = '/'; + } + } + + $this->path = $path; + $this->method = $_SERVER['REQUEST_METHOD']; + $this->params['GET'] = $_GET; + $this->params['POST'] = $_POST; + $this->headers = $this->get_headers( $_SERVER ); + $this->files = $_FILES; + + // Compatibility for clients that can't use PUT/PATCH/DELETE + if ( isset( $_GET['_method'] ) ) { + $this->method = strtoupper( $_GET['_method'] ); + } elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) { + $this->method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']; + } + + // load response handler + $handler_class = apply_filters( 'woocommerce_api_default_response_handler', 'WC_API_JSON_Handler', $this->path, $this ); + + $this->handler = new $handler_class(); + } + + /** + * Check authentication for the request + * + * @since 2.1 + * @return WP_User|WP_Error WP_User object indicates successful login, WP_Error indicates unsuccessful login + */ + public function check_authentication() { + + // allow plugins to remove default authentication or add their own authentication + $user = apply_filters( 'woocommerce_api_check_authentication', null, $this ); + + if ( is_a( $user, 'WP_User' ) ) { + + // API requests run under the context of the authenticated user + wp_set_current_user( $user->ID ); + + } elseif ( ! is_wp_error( $user ) ) { + + // WP_Errors are handled in serve_request() + $user = new WP_Error( 'woocommerce_api_authentication_error', __( 'Invalid authentication method', 'woocommerce' ), array( 'code' => 500 ) ); + + } + + return $user; + } + + /** + * Convert an error to an array + * + * This iterates over all error codes and messages to change it into a flat + * array. This enables simpler client behaviour, as it is represented as a + * list in JSON rather than an object/map + * + * @since 2.1 + * @param WP_Error $error + * @return array List of associative arrays with code and message keys + */ + protected function error_to_array( $error ) { + $errors = array(); + foreach ( (array) $error->errors as $code => $messages ) { + foreach ( (array) $messages as $message ) { + $errors[] = array( 'code' => $code, 'message' => $message ); + } + } + + return array( 'errors' => $errors ); + } + + /** + * Handle serving an API request + * + * Matches the current server URI to a route and runs the first matching + * callback then outputs a JSON representation of the returned value. + * + * @since 2.1 + * @uses WC_API_Server::dispatch() + */ + public function serve_request() { + + do_action( 'woocommerce_api_server_before_serve', $this ); + + $this->header( 'Content-Type', $this->handler->get_content_type(), true ); + + // the API is enabled by default + if ( ! apply_filters( 'woocommerce_api_enabled', true, $this ) || ( 'no' === get_option( 'woocommerce_api_enabled' ) ) ) { + + $this->send_status( 404 ); + + echo $this->handler->generate_response( array( 'errors' => array( 'code' => 'woocommerce_api_disabled', 'message' => 'The WooCommerce API is disabled on this site' ) ) ); + + return; + } + + $result = $this->check_authentication(); + + // if authorization check was successful, dispatch the request + if ( ! is_wp_error( $result ) ) { + $result = $this->dispatch(); + } + + // handle any dispatch errors + if ( is_wp_error( $result ) ) { + $data = $result->get_error_data(); + if ( is_array( $data ) && isset( $data['status'] ) ) { + $this->send_status( $data['status'] ); + } + + $result = $this->error_to_array( $result ); + } + + // This is a filter rather than an action, since this is designed to be + // re-entrant if needed + $served = apply_filters( 'woocommerce_api_serve_request', false, $result, $this ); + + if ( ! $served ) { + + if ( 'HEAD' === $this->method ) { + return; + } + + echo $this->handler->generate_response( $result ); + } + } + + /** + * Retrieve the route map + * + * The route map is an associative array with path regexes as the keys. The + * value is an indexed array with the callback function/method as the first + * item, and a bitmask of HTTP methods as the second item (see the class + * constants). + * + * Each route can be mapped to more than one callback by using an array of + * the indexed arrays. This allows mapping e.g. GET requests to one callback + * and POST requests to another. + * + * Note that the path regexes (array keys) must have @ escaped, as this is + * used as the delimiter with preg_match() + * + * @since 2.1 + * @return array `'/path/regex' => array( $callback, $bitmask )` or `'/path/regex' => array( array( $callback, $bitmask ), ...)` + */ + public function get_routes() { + + // index added by default + $endpoints = array( + + '/' => array( array( $this, 'get_index' ), self::READABLE ), + ); + + $endpoints = apply_filters( 'woocommerce_api_endpoints', $endpoints ); + + // Normalise the endpoints + foreach ( $endpoints as $route => &$handlers ) { + if ( count( $handlers ) <= 2 && isset( $handlers[1] ) && ! is_array( $handlers[1] ) ) { + $handlers = array( $handlers ); + } + } + + return $endpoints; + } + + /** + * Match the request to a callback and call it + * + * @since 2.1 + * @return mixed The value returned by the callback, or a WP_Error instance + */ + public function dispatch() { + + switch ( $this->method ) { + + case 'HEAD' : + case 'GET' : + $method = self::METHOD_GET; + break; + + case 'POST' : + $method = self::METHOD_POST; + break; + + case 'PUT' : + $method = self::METHOD_PUT; + break; + + case 'PATCH' : + $method = self::METHOD_PATCH; + break; + + case 'DELETE' : + $method = self::METHOD_DELETE; + break; + + default : + return new WP_Error( 'woocommerce_api_unsupported_method', __( 'Unsupported request method', 'woocommerce' ), array( 'status' => 400 ) ); + } + + foreach ( $this->get_routes() as $route => $handlers ) { + foreach ( $handlers as $handler ) { + $callback = $handler[0]; + $supported = isset( $handler[1] ) ? $handler[1] : self::METHOD_GET; + + if ( ! ( $supported & $method ) ) { + continue; + } + + $match = preg_match( '@^' . $route . '$@i', urldecode( $this->path ), $args ); + + if ( ! $match ) { + continue; + } + + if ( ! is_callable( $callback ) ) { + return new WP_Error( 'woocommerce_api_invalid_handler', __( 'The handler for the route is invalid', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $args = array_merge( $args, $this->params['GET'] ); + if ( $method & self::METHOD_POST ) { + $args = array_merge( $args, $this->params['POST'] ); + } + if ( $supported & self::ACCEPT_DATA ) { + $data = $this->handler->parse_body( $this->get_raw_data() ); + $args = array_merge( $args, array( 'data' => $data ) ); + } elseif ( $supported & self::ACCEPT_RAW_DATA ) { + $data = $this->get_raw_data(); + $args = array_merge( $args, array( 'data' => $data ) ); + } + + $args['_method'] = $method; + $args['_route'] = $route; + $args['_path'] = $this->path; + $args['_headers'] = $this->headers; + $args['_files'] = $this->files; + + $args = apply_filters( 'woocommerce_api_dispatch_args', $args, $callback ); + + // Allow plugins to halt the request via this filter + if ( is_wp_error( $args ) ) { + return $args; + } + + $params = $this->sort_callback_params( $callback, $args ); + if ( is_wp_error( $params ) ) { + return $params; + } + + return call_user_func_array( $callback, $params ); + } + } + + return new WP_Error( 'woocommerce_api_no_route', __( 'No route was found matching the URL and request method', 'woocommerce' ), array( 'status' => 404 ) ); + } + + /** + * urldecode deep. + * + * @since 2.2 + * @param string|array $value Data to decode with urldecode. + * + * @return string|array Decoded data. + */ + protected function urldecode_deep( $value ) { + if ( is_array( $value ) ) { + return array_map( array( $this, 'urldecode_deep' ), $value ); + } else { + return urldecode( $value ); + } + } + + /** + * Sort parameters by order specified in method declaration + * + * Takes a callback and a list of available params, then filters and sorts + * by the parameters the method actually needs, using the Reflection API + * + * @since 2.2 + * + * @param callable|array $callback the endpoint callback + * @param array $provided the provided request parameters + * + * @return array|WP_Error + */ + protected function sort_callback_params( $callback, $provided ) { + if ( is_array( $callback ) ) { + $ref_func = new ReflectionMethod( $callback[0], $callback[1] ); + } else { + $ref_func = new ReflectionFunction( $callback ); + } + + $wanted = $ref_func->getParameters(); + $ordered_parameters = array(); + + foreach ( $wanted as $param ) { + if ( isset( $provided[ $param->getName() ] ) ) { + // We have this parameters in the list to choose from + if ( 'data' == $param->getName() ) { + $ordered_parameters[] = $provided[ $param->getName() ]; + continue; + } + + $ordered_parameters[] = $this->urldecode_deep( $provided[ $param->getName() ] ); + } elseif ( $param->isDefaultValueAvailable() ) { + // We don't have this parameter, but it's optional + $ordered_parameters[] = $param->getDefaultValue(); + } else { + // We don't have this parameter and it wasn't optional, abort! + return new WP_Error( 'woocommerce_api_missing_callback_param', sprintf( __( 'Missing parameter %s', 'woocommerce' ), $param->getName() ), array( 'status' => 400 ) ); + } + } + + return $ordered_parameters; + } + + /** + * Get the site index. + * + * This endpoint describes the capabilities of the site. + * + * @since 2.3 + * @return array Index entity + */ + public function get_index() { + + // General site data + $available = array( + 'store' => array( + 'name' => get_option( 'blogname' ), + 'description' => get_option( 'blogdescription' ), + 'URL' => get_option( 'siteurl' ), + 'wc_version' => WC()->version, + 'version' => WC_API::VERSION, + 'routes' => array(), + 'meta' => array( + 'timezone' => wc_timezone_string(), + 'currency' => get_woocommerce_currency(), + 'currency_format' => get_woocommerce_currency_symbol(), + 'currency_position' => get_option( 'woocommerce_currency_pos' ), + 'thousand_separator' => get_option( 'woocommerce_price_thousand_sep' ), + 'decimal_separator' => get_option( 'woocommerce_price_decimal_sep' ), + 'price_num_decimals' => wc_get_price_decimals(), + 'tax_included' => wc_prices_include_tax(), + 'weight_unit' => get_option( 'woocommerce_weight_unit' ), + 'dimension_unit' => get_option( 'woocommerce_dimension_unit' ), + 'ssl_enabled' => ( 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) || wc_site_is_https() ), + 'permalinks_enabled' => ( '' !== get_option( 'permalink_structure' ) ), + 'generate_password' => ( 'yes' === get_option( 'woocommerce_registration_generate_password' ) ), + 'links' => array( + 'help' => 'https://woocommerce.github.io/woocommerce-rest-api-docs/', + ), + ), + ), + ); + + // Find the available routes + foreach ( $this->get_routes() as $route => $callbacks ) { + $data = array(); + + $route = preg_replace( '#\(\?P(<\w+?>).*?\)#', '$1', $route ); + + foreach ( self::$method_map as $name => $bitmask ) { + foreach ( $callbacks as $callback ) { + // Skip to the next route if any callback is hidden + if ( $callback[1] & self::HIDDEN_ENDPOINT ) { + continue 3; + } + + if ( $callback[1] & $bitmask ) { + $data['supports'][] = $name; + } + + if ( $callback[1] & self::ACCEPT_DATA ) { + $data['accepts_data'] = true; + } + + // For non-variable routes, generate links + if ( strpos( $route, '<' ) === false ) { + $data['meta'] = array( + 'self' => get_woocommerce_api_url( $route ), + ); + } + } + } + + $available['store']['routes'][ $route ] = apply_filters( 'woocommerce_api_endpoints_description', $data ); + } + + return apply_filters( 'woocommerce_api_index', $available ); + } + + /** + * Send a HTTP status code + * + * @since 2.1 + * @param int $code HTTP status + */ + public function send_status( $code ) { + status_header( $code ); + } + + /** + * Send a HTTP header + * + * @since 2.1 + * @param string $key Header key + * @param string $value Header value + * @param boolean $replace Should we replace the existing header? + */ + public function header( $key, $value, $replace = true ) { + header( sprintf( '%s: %s', $key, $value ), $replace ); + } + + /** + * Send a Link header + * + * @internal The $rel parameter is first, as this looks nicer when sending multiple + * + * @link http://tools.ietf.org/html/rfc5988 + * @link http://www.iana.org/assignments/link-relations/link-relations.xml + * + * @since 2.1 + * @param string $rel Link relation. Either a registered type, or an absolute URL + * @param string $link Target IRI for the link + * @param array $other Other parameters to send, as an associative array + */ + public function link_header( $rel, $link, $other = array() ) { + + $header = sprintf( '<%s>; rel="%s"', $link, esc_attr( $rel ) ); + + foreach ( $other as $key => $value ) { + + if ( 'title' == $key ) { + + $value = '"' . $value . '"'; + } + + $header .= '; ' . $key . '=' . $value; + } + + $this->header( 'Link', $header, false ); + } + + /** + * Send pagination headers for resources + * + * @since 2.1 + * @param WP_Query|WP_User_Query|stdClass $query + */ + public function add_pagination_headers( $query ) { + + // WP_User_Query + if ( is_a( $query, 'WP_User_Query' ) ) { + + $single = count( $query->get_results() ) == 1; + $total = $query->get_total(); + + if ( $query->get( 'number' ) > 0 ) { + $page = ( $query->get( 'offset' ) / $query->get( 'number' ) ) + 1; + $total_pages = ceil( $total / $query->get( 'number' ) ); + } else { + $page = 1; + $total_pages = 1; + } + } elseif ( is_a( $query, 'stdClass' ) ) { + $page = $query->page; + $single = $query->is_single; + $total = $query->total; + $total_pages = $query->total_pages; + + // WP_Query + } else { + + $page = $query->get( 'paged' ); + $single = $query->is_single(); + $total = $query->found_posts; + $total_pages = $query->max_num_pages; + } + + if ( ! $page ) { + $page = 1; + } + + $next_page = absint( $page ) + 1; + + if ( ! $single ) { + + // first/prev + if ( $page > 1 ) { + $this->link_header( 'first', $this->get_paginated_url( 1 ) ); + $this->link_header( 'prev', $this->get_paginated_url( $page -1 ) ); + } + + // next + if ( $next_page <= $total_pages ) { + $this->link_header( 'next', $this->get_paginated_url( $next_page ) ); + } + + // last + if ( $page != $total_pages ) { + $this->link_header( 'last', $this->get_paginated_url( $total_pages ) ); + } + } + + $this->header( 'X-WC-Total', $total ); + $this->header( 'X-WC-TotalPages', $total_pages ); + + do_action( 'woocommerce_api_pagination_headers', $this, $query ); + } + + /** + * Returns the request URL with the page query parameter set to the specified page + * + * @since 2.1 + * @param int $page + * @return string + */ + private function get_paginated_url( $page ) { + + // remove existing page query param + $request = remove_query_arg( 'page' ); + + // add provided page query param + $request = urldecode( add_query_arg( 'page', $page, $request ) ); + + // get the home host + $host = parse_url( get_home_url(), PHP_URL_HOST ); + + return set_url_scheme( "http://{$host}{$request}" ); + } + + /** + * Retrieve the raw request entity (body) + * + * @since 2.1 + * @return string + */ + public function get_raw_data() { + // @codingStandardsIgnoreStart + // $HTTP_RAW_POST_DATA is deprecated on PHP 5.6. + if ( function_exists( 'phpversion' ) && version_compare( phpversion(), '5.6', '>=' ) ) { + return file_get_contents( 'php://input' ); + } + + global $HTTP_RAW_POST_DATA; + + // A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default, + // but we can do it ourself. + if ( ! isset( $HTTP_RAW_POST_DATA ) ) { + $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); + } + + return $HTTP_RAW_POST_DATA; + // @codingStandardsIgnoreEnd + } + + /** + * Parse an RFC3339 datetime into a MySQl datetime + * + * Invalid dates default to unix epoch + * + * @since 2.1 + * @param string $datetime RFC3339 datetime + * @return string MySQl datetime (YYYY-MM-DD HH:MM:SS) + */ + public function parse_datetime( $datetime ) { + + // Strip millisecond precision (a full stop followed by one or more digits) + if ( strpos( $datetime, '.' ) !== false ) { + $datetime = preg_replace( '/\.\d+/', '', $datetime ); + } + + // default timezone to UTC + $datetime = preg_replace( '/[+-]\d+:+\d+$/', '+00:00', $datetime ); + + try { + + $datetime = new DateTime( $datetime, new DateTimeZone( 'UTC' ) ); + + } catch ( Exception $e ) { + + $datetime = new DateTime( '@0' ); + + } + + return $datetime->format( 'Y-m-d H:i:s' ); + } + + /** + * Format a unix timestamp or MySQL datetime into an RFC3339 datetime + * + * @since 2.1 + * @param int|string $timestamp unix timestamp or MySQL datetime + * @param bool $convert_to_utc + * @param bool $convert_to_gmt Use GMT timezone. + * @return string RFC3339 datetime + */ + public function format_datetime( $timestamp, $convert_to_utc = false, $convert_to_gmt = false ) { + if ( $convert_to_gmt ) { + if ( is_numeric( $timestamp ) ) { + $timestamp = date( 'Y-m-d H:i:s', $timestamp ); + } + + $timestamp = get_gmt_from_date( $timestamp ); + } + + if ( $convert_to_utc ) { + $timezone = new DateTimeZone( wc_timezone_string() ); + } else { + $timezone = new DateTimeZone( 'UTC' ); + } + + try { + + if ( is_numeric( $timestamp ) ) { + $date = new DateTime( "@{$timestamp}" ); + } else { + $date = new DateTime( $timestamp, $timezone ); + } + + // convert to UTC by adjusting the time based on the offset of the site's timezone + if ( $convert_to_utc ) { + $date->modify( -1 * $date->getOffset() . ' seconds' ); + } + } catch ( Exception $e ) { + + $date = new DateTime( '@0' ); + } + + return $date->format( 'Y-m-d\TH:i:s\Z' ); + } + + /** + * Extract headers from a PHP-style $_SERVER array + * + * @since 2.1 + * @param array $server Associative array similar to $_SERVER + * @return array Headers extracted from the input + */ + public function get_headers( $server ) { + $headers = array(); + // CONTENT_* headers are not prefixed with HTTP_ + $additional = array( 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true ); + + foreach ( $server as $key => $value ) { + if ( strpos( $key, 'HTTP_' ) === 0 ) { + $headers[ substr( $key, 5 ) ] = $value; + } elseif ( isset( $additional[ $key ] ) ) { + $headers[ $key ] = $value; + } + } + + return $headers; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-taxes.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-taxes.php new file mode 100644 index 0000000..887a793 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-taxes.php @@ -0,0 +1,649 @@ + + * + * @since 2.1 + * @param array $routes + * @return array + */ + public function register_routes( $routes ) { + + # GET/POST /taxes + $routes[ $this->base ] = array( + array( array( $this, 'get_taxes' ), WC_API_Server::READABLE ), + array( array( $this, 'create_tax' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /taxes/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_taxes_count' ), WC_API_Server::READABLE ), + ); + + # GET/PUT/DELETE /taxes/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_tax' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_tax' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ), + array( array( $this, 'delete_tax' ), WC_API_SERVER::DELETABLE ), + ); + + # GET/POST /taxes/classes + $routes[ $this->base . '/classes' ] = array( + array( array( $this, 'get_tax_classes' ), WC_API_Server::READABLE ), + array( array( $this, 'create_tax_class' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /taxes/classes/count + $routes[ $this->base . '/classes/count' ] = array( + array( array( $this, 'get_tax_classes_count' ), WC_API_Server::READABLE ), + ); + + # GET /taxes/classes/ + $routes[ $this->base . '/classes/(?P\w[\w\s\-]*)' ] = array( + array( array( $this, 'delete_tax_class' ), WC_API_SERVER::DELETABLE ), + ); + + # POST|PUT /taxes/bulk + $routes[ $this->base . '/bulk' ] = array( + array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + ); + + return $routes; + } + + /** + * Get all taxes + * + * @since 2.5.0 + * + * @param string $fields + * @param array $filter + * @param string $class + * @param int $page + * + * @return array + */ + public function get_taxes( $fields = null, $filter = array(), $class = null, $page = 1 ) { + if ( ! empty( $class ) ) { + $filter['tax_rate_class'] = $class; + } + + $filter['page'] = $page; + + $query = $this->query_tax_rates( $filter ); + + $taxes = array(); + + foreach ( $query['results'] as $tax ) { + $taxes[] = current( $this->get_tax( $tax->tax_rate_id, $fields ) ); + } + + // Set pagination headers + $this->server->add_pagination_headers( $query['headers'] ); + + return array( 'taxes' => $taxes ); + } + + /** + * Get the tax for the given ID + * + * @since 2.5.0 + * + * @param int $id The tax ID + * @param string $fields fields to include in response + * + * @return array|WP_Error + */ + public function get_tax( $id, $fields = null ) { + global $wpdb; + + try { + $id = absint( $id ); + + // Permissions check + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_tax', __( 'You do not have permission to read tax rate', 'woocommerce' ), 401 ); + } + + // Get tax rate details + $tax = WC_Tax::_get_tax_rate( $id ); + + if ( is_wp_error( $tax ) || empty( $tax ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_tax_id', __( 'A tax rate with the provided ID could not be found', 'woocommerce' ), 404 ); + } + + $tax_data = array( + 'id' => (int) $tax['tax_rate_id'], + 'country' => $tax['tax_rate_country'], + 'state' => $tax['tax_rate_state'], + 'postcode' => '', + 'city' => '', + 'rate' => $tax['tax_rate'], + 'name' => $tax['tax_rate_name'], + 'priority' => (int) $tax['tax_rate_priority'], + 'compound' => (bool) $tax['tax_rate_compound'], + 'shipping' => (bool) $tax['tax_rate_shipping'], + 'order' => (int) $tax['tax_rate_order'], + 'class' => $tax['tax_rate_class'] ? $tax['tax_rate_class'] : 'standard', + ); + + // Get locales from a tax rate + $locales = $wpdb->get_results( $wpdb->prepare( " + SELECT location_code, location_type + FROM {$wpdb->prefix}woocommerce_tax_rate_locations + WHERE tax_rate_id = %d + ", $id ) ); + + if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) { + foreach ( $locales as $locale ) { + $tax_data[ $locale->location_type ] = $locale->location_code; + } + } + + return array( 'tax' => apply_filters( 'woocommerce_api_tax_response', $tax_data, $tax, $fields, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a tax + * + * @since 2.5.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function create_tax( $data ) { + try { + if ( ! isset( $data['tax'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_tax_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'tax' ), 400 ); + } + + // Check permissions + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_tax', __( 'You do not have permission to create tax rates', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_tax_data', $data['tax'], $this ); + + $tax_data = array( + 'tax_rate_country' => '', + 'tax_rate_state' => '', + 'tax_rate' => '', + 'tax_rate_name' => '', + 'tax_rate_priority' => 1, + 'tax_rate_compound' => 0, + 'tax_rate_shipping' => 1, + 'tax_rate_order' => 0, + 'tax_rate_class' => '', + ); + + foreach ( $tax_data as $key => $value ) { + $new_key = str_replace( 'tax_rate_', '', $key ); + $new_key = 'tax_rate' === $new_key ? 'rate' : $new_key; + + if ( isset( $data[ $new_key ] ) ) { + if ( in_array( $new_key, array( 'compound', 'shipping' ) ) ) { + $tax_data[ $key ] = $data[ $new_key ] ? 1 : 0; + } else { + $tax_data[ $key ] = $data[ $new_key ]; + } + } + } + + // Create tax rate + $id = WC_Tax::_insert_tax_rate( $tax_data ); + + // Add locales + if ( ! empty( $data['postcode'] ) ) { + WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $data['postcode'] ) ); + } + + if ( ! empty( $data['city'] ) ) { + WC_Tax::_update_tax_rate_cities( $id, wc_clean( $data['city'] ) ); + } + + do_action( 'woocommerce_api_create_tax', $id, $data ); + + $this->server->send_status( 201 ); + + return $this->get_tax( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a tax + * + * @since 2.5.0 + * + * @param int $id The tax ID + * @param array $data + * + * @return array|WP_Error + */ + public function edit_tax( $id, $data ) { + try { + if ( ! isset( $data['tax'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_tax_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'tax' ), 400 ); + } + + // Check permissions + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_tax', __( 'You do not have permission to edit tax rates', 'woocommerce' ), 401 ); + } + + $data = $data['tax']; + + // Get current tax rate data + $tax = $this->get_tax( $id ); + + if ( is_wp_error( $tax ) ) { + $error_data = $tax->get_error_data(); + throw new WC_API_Exception( $tax->get_error_code(), $tax->get_error_message(), $error_data['status'] ); + } + + $current_data = $tax['tax']; + $data = apply_filters( 'woocommerce_api_edit_tax_data', $data, $this ); + $tax_data = array(); + $default_fields = array( + 'tax_rate_country', + 'tax_rate_state', + 'tax_rate', + 'tax_rate_name', + 'tax_rate_priority', + 'tax_rate_compound', + 'tax_rate_shipping', + 'tax_rate_order', + 'tax_rate_class', + ); + + foreach ( $data as $key => $value ) { + $new_key = 'rate' === $key ? 'tax_rate' : 'tax_rate_' . $key; + + // Check if the key is valid + if ( ! in_array( $new_key, $default_fields ) ) { + continue; + } + + // Test new data against current data + if ( $value === $current_data[ $key ] ) { + continue; + } + + // Fix compound and shipping values + if ( in_array( $key, array( 'compound', 'shipping' ) ) ) { + $value = $value ? 1 : 0; + } + + $tax_data[ $new_key ] = $value; + } + + // Update tax rate + WC_Tax::_update_tax_rate( $id, $tax_data ); + + // Update locales + if ( ! empty( $data['postcode'] ) && $current_data['postcode'] != $data['postcode'] ) { + WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $data['postcode'] ) ); + } + + if ( ! empty( $data['city'] ) && $current_data['city'] != $data['city'] ) { + WC_Tax::_update_tax_rate_cities( $id, wc_clean( $data['city'] ) ); + } + + do_action( 'woocommerce_api_edit_tax_rate', $id, $data ); + + return $this->get_tax( $id ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a tax + * + * @since 2.5.0 + * + * @param int $id The tax ID + * + * @return array|WP_Error + */ + public function delete_tax( $id ) { + global $wpdb; + + try { + // Check permissions + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_tax', __( 'You do not have permission to delete tax rates', 'woocommerce' ), 401 ); + } + + $id = absint( $id ); + + WC_Tax::_delete_tax_rate( $id ); + + if ( 0 === $wpdb->rows_affected ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_tax', __( 'Could not delete the tax rate', 'woocommerce' ), 401 ); + } + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'tax' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the total number of taxes + * + * @since 2.5.0 + * + * @param string $class + * @param array $filter + * + * @return array|WP_Error + */ + public function get_taxes_count( $class = null, $filter = array() ) { + try { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_taxes_count', __( 'You do not have permission to read the taxes count', 'woocommerce' ), 401 ); + } + + if ( ! empty( $class ) ) { + $filter['tax_rate_class'] = $class; + } + + $query = $this->query_tax_rates( $filter, true ); + + return array( 'count' => (int) $query['headers']->total ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Helper method to get tax rates objects + * + * @since 2.5.0 + * + * @param array $args + * @param bool $count_only + * + * @return array + */ + protected function query_tax_rates( $args, $count_only = false ) { + global $wpdb; + + $results = ''; + + // Set args + $args = $this->merge_query_args( $args, array() ); + + $query = " + SELECT tax_rate_id + FROM {$wpdb->prefix}woocommerce_tax_rates + WHERE 1 = 1 + "; + + // Filter by tax class + if ( ! empty( $args['tax_rate_class'] ) ) { + $tax_rate_class = 'standard' !== $args['tax_rate_class'] ? sanitize_title( $args['tax_rate_class'] ) : ''; + $query .= " AND tax_rate_class = '$tax_rate_class'"; + } + + // Order tax rates + $order_by = ' ORDER BY tax_rate_order'; + + // Pagination + $per_page = isset( $args['posts_per_page'] ) ? $args['posts_per_page'] : get_option( 'posts_per_page' ); + $offset = 1 < $args['paged'] ? ( $args['paged'] - 1 ) * $per_page : 0; + $pagination = sprintf( ' LIMIT %d, %d', $offset, $per_page ); + + if ( ! $count_only ) { + $results = $wpdb->get_results( $query . $order_by . $pagination ); + } + + $wpdb->get_results( $query ); + $headers = new stdClass; + $headers->page = $args['paged']; + $headers->total = (int) $wpdb->num_rows; + $headers->is_single = $per_page > $headers->total; + $headers->total_pages = ceil( $headers->total / $per_page ); + + return array( + 'results' => $results, + 'headers' => $headers, + ); + } + + /** + * Bulk update or insert taxes + * Accepts an array with taxes in the formats supported by + * WC_API_Taxes->create_tax() and WC_API_Taxes->edit_tax() + * + * @since 2.5.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function bulk( $data ) { + try { + if ( ! isset( $data['taxes'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_taxes_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'taxes' ), 400 ); + } + + $data = $data['taxes']; + $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'taxes' ); + + // Limit bulk operation + if ( count( $data ) > $limit ) { + throw new WC_API_Exception( 'woocommerce_api_taxes_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); + } + + $taxes = array(); + + foreach ( $data as $_tax ) { + $tax_id = 0; + + // Try to get the tax rate ID + if ( isset( $_tax['id'] ) ) { + $tax_id = intval( $_tax['id'] ); + } + + if ( $tax_id ) { + + // Tax rate exists / edit tax rate + $edit = $this->edit_tax( $tax_id, array( 'tax' => $_tax ) ); + + if ( is_wp_error( $edit ) ) { + $taxes[] = array( + 'id' => $tax_id, + 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ), + ); + } else { + $taxes[] = $edit['tax']; + } + } else { + + // Tax rate don't exists / create tax rate + $new = $this->create_tax( array( 'tax' => $_tax ) ); + + if ( is_wp_error( $new ) ) { + $taxes[] = array( + 'id' => $tax_id, + 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ), + ); + } else { + $taxes[] = $new['tax']; + } + } + } + + return array( 'taxes' => apply_filters( 'woocommerce_api_taxes_bulk_response', $taxes, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get all tax classes + * + * @since 2.5.0 + * + * @param string $fields + * + * @return array|WP_Error + */ + public function get_tax_classes( $fields = null ) { + try { + // Permissions check + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_tax_classes', __( 'You do not have permission to read tax classes', 'woocommerce' ), 401 ); + } + + $tax_classes = array(); + + // Add standard class + $tax_classes[] = array( + 'slug' => 'standard', + 'name' => __( 'Standard rate', 'woocommerce' ), + ); + + $classes = WC_Tax::get_tax_classes(); + + foreach ( $classes as $class ) { + $tax_classes[] = apply_filters( 'woocommerce_api_tax_class_response', array( + 'slug' => sanitize_title( $class ), + 'name' => $class, + ), $class, $fields, $this ); + } + + return array( 'tax_classes' => apply_filters( 'woocommerce_api_tax_classes_response', $tax_classes, $classes, $fields, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a tax class. + * + * @since 2.5.0 + * + * @param array $data + * + * @return array|WP_Error + */ + public function create_tax_class( $data ) { + try { + if ( ! isset( $data['tax_class'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_tax_class_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'tax_class' ), 400 ); + } + + // Check permissions + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_tax_class', __( 'You do not have permission to create tax classes', 'woocommerce' ), 401 ); + } + + $data = $data['tax_class']; + + if ( empty( $data['name'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_tax_class_name', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'name' ), 400 ); + } + + $name = sanitize_text_field( $data['name'] ); + $tax_class = WC_Tax::create_tax_class( $name ); + + if ( is_wp_error( $tax_class ) ) { + return new WP_Error( 'woocommerce_api_' . $tax_class->get_error_code(), $tax_class->get_error_message(), 401 ); + } + + do_action( 'woocommerce_api_create_tax_class', $tax_class['slug'], $data ); + + $this->server->send_status( 201 ); + + return array( + 'tax_class' => $tax_class, + ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a tax class + * + * @since 2.5.0 + * + * @param int $slug The tax class slug + * + * @return array|WP_Error + */ + public function delete_tax_class( $slug ) { + global $wpdb; + + try { + // Check permissions + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_tax_class', __( 'You do not have permission to delete tax classes', 'woocommerce' ), 401 ); + } + + $slug = sanitize_title( $slug ); + $tax_class = WC_Tax::get_tax_class_by( 'slug', $slug ); + $deleted = WC_Tax::delete_tax_class_by( 'slug', $slug ); + + if ( is_wp_error( $deleted ) || ! $deleted ) { + throw new WC_API_Exception( 'woocommerce_api_cannot_delete_tax_class', __( 'Could not delete the tax class', 'woocommerce' ), 401 ); + } + + return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'tax_class' ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the total number of tax classes + * + * @since 2.5.0 + * + * @return array|WP_Error + */ + public function get_tax_classes_count() { + try { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_tax_classes_count', __( 'You do not have permission to read the tax classes count', 'woocommerce' ), 401 ); + } + + $total = count( WC_Tax::get_tax_classes() ) + 1; // +1 for Standard Rate + + return array( 'count' => $total ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-webhooks.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-webhooks.php new file mode 100644 index 0000000..98e14b5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-webhooks.php @@ -0,0 +1,509 @@ +base ] = array( + array( array( $this, 'get_webhooks' ), WC_API_Server::READABLE ), + array( array( $this, 'create_webhook' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ), + ); + + # GET /webhooks/count + $routes[ $this->base . '/count' ] = array( + array( array( $this, 'get_webhooks_count' ), WC_API_Server::READABLE ), + ); + + # GET|PUT|DELETE /webhooks/ + $routes[ $this->base . '/(?P\d+)' ] = array( + array( array( $this, 'get_webhook' ), WC_API_Server::READABLE ), + array( array( $this, 'edit_webhook' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ), + array( array( $this, 'delete_webhook' ), WC_API_Server::DELETABLE ), + ); + + # GET /webhooks//deliveries + $routes[ $this->base . '/(?P\d+)/deliveries' ] = array( + array( array( $this, 'get_webhook_deliveries' ), WC_API_Server::READABLE ), + ); + + # GET /webhooks//deliveries/ + $routes[ $this->base . '/(?P\d+)/deliveries/(?P\d+)' ] = array( + array( array( $this, 'get_webhook_delivery' ), WC_API_Server::READABLE ), + ); + + return $routes; + } + + /** + * Get all webhooks + * + * @since 2.2 + * + * @param array $fields + * @param array $filter + * @param string $status + * @param int $page + * + * @return array + */ + public function get_webhooks( $fields = null, $filter = array(), $status = null, $page = 1 ) { + + if ( ! empty( $status ) ) { + $filter['status'] = $status; + } + + $filter['page'] = $page; + + $query = $this->query_webhooks( $filter ); + + $webhooks = array(); + + foreach ( $query['results'] as $webhook_id ) { + $webhooks[] = current( $this->get_webhook( $webhook_id, $fields ) ); + } + + $this->server->add_pagination_headers( $query['headers'] ); + + return array( 'webhooks' => $webhooks ); + } + + /** + * Get the webhook for the given ID + * + * @since 2.2 + * @param int $id webhook ID + * @param array $fields + * @return array|WP_Error + */ + public function get_webhook( $id, $fields = null ) { + + // ensure webhook ID is valid & user has permission to read + $id = $this->validate_request( $id, 'shop_webhook', 'read' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $webhook = wc_get_webhook( $id ); + + $webhook_data = array( + 'id' => $webhook->get_id(), + 'name' => $webhook->get_name(), + 'status' => $webhook->get_status(), + 'topic' => $webhook->get_topic(), + 'resource' => $webhook->get_resource(), + 'event' => $webhook->get_event(), + 'hooks' => $webhook->get_hooks(), + 'delivery_url' => $webhook->get_delivery_url(), + 'created_at' => $this->server->format_datetime( $webhook->get_date_created() ? $webhook->get_date_created()->getTimestamp() : 0, false, false ), // API gives UTC times. + 'updated_at' => $this->server->format_datetime( $webhook->get_date_modified() ? $webhook->get_date_modified()->getTimestamp() : 0, false, false ), // API gives UTC times. + ); + + return array( 'webhook' => apply_filters( 'woocommerce_api_webhook_response', $webhook_data, $webhook, $fields, $this ) ); + } + + /** + * Get the total number of webhooks + * + * @since 2.2 + * + * @param string $status + * @param array $filter + * + * @return array|WP_Error + */ + public function get_webhooks_count( $status = null, $filter = array() ) { + try { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_webhooks_count', __( 'You do not have permission to read the webhooks count', 'woocommerce' ), 401 ); + } + + if ( ! empty( $status ) ) { + $filter['status'] = $status; + } + + $query = $this->query_webhooks( $filter ); + + return array( 'count' => $query['headers']->total ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create an webhook + * + * @since 2.2 + * + * @param array $data parsed webhook data + * + * @return array|WP_Error + */ + public function create_webhook( $data ) { + + try { + if ( ! isset( $data['webhook'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_webhook_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'webhook' ), 400 ); + } + + $data = $data['webhook']; + + // permission check + if ( ! current_user_can( 'manage_woocommerce' ) ) { + throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_webhooks', __( 'You do not have permission to create webhooks.', 'woocommerce' ), 401 ); + } + + $data = apply_filters( 'woocommerce_api_create_webhook_data', $data, $this ); + + // validate topic + if ( empty( $data['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $data['topic'] ) ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_topic', __( 'Webhook topic is required and must be valid.', 'woocommerce' ), 400 ); + } + + // validate delivery URL + if ( empty( $data['delivery_url'] ) || ! wc_is_valid_url( $data['delivery_url'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_url', __( 'Webhook delivery URL must be a valid URL starting with http:// or https://', 'woocommerce' ), 400 ); + } + + $webhook_data = apply_filters( 'woocommerce_new_webhook_data', array( + 'post_type' => 'shop_webhook', + 'post_status' => 'publish', + 'ping_status' => 'closed', + 'post_author' => get_current_user_id(), + 'post_password' => 'webhook_' . wp_generate_password(), + 'post_title' => ! empty( $data['name'] ) ? $data['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ), + ), $data, $this ); + + $webhook = new WC_Webhook(); + + $webhook->set_name( $webhook_data['post_title'] ); + $webhook->set_user_id( $webhook_data['post_author'] ); + $webhook->set_status( 'publish' === $webhook_data['post_status'] ? 'active' : 'disabled' ); + $webhook->set_topic( $data['topic'] ); + $webhook->set_delivery_url( $data['delivery_url'] ); + $webhook->set_secret( ! empty( $data['secret'] ) ? $data['secret'] : wp_generate_password( 50, true, true ) ); + $webhook->set_api_version( 'legacy_v3' ); + $webhook->save(); + + $webhook->deliver_ping(); + + // HTTP 201 Created + $this->server->send_status( 201 ); + + do_action( 'woocommerce_api_create_webhook', $webhook->get_id(), $this ); + + return $this->get_webhook( $webhook->get_id() ); + + } catch ( WC_API_Exception $e ) { + + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Edit a webhook + * + * @since 2.2 + * + * @param int $id webhook ID + * @param array $data parsed webhook data + * + * @return array|WP_Error + */ + public function edit_webhook( $id, $data ) { + + try { + if ( ! isset( $data['webhook'] ) ) { + throw new WC_API_Exception( 'woocommerce_api_missing_webhook_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'webhook' ), 400 ); + } + + $data = $data['webhook']; + + $id = $this->validate_request( $id, 'shop_webhook', 'edit' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + $data = apply_filters( 'woocommerce_api_edit_webhook_data', $data, $id, $this ); + + $webhook = wc_get_webhook( $id ); + + // update topic + if ( ! empty( $data['topic'] ) ) { + + if ( wc_is_webhook_valid_topic( strtolower( $data['topic'] ) ) ) { + + $webhook->set_topic( $data['topic'] ); + + } else { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_topic', __( 'Webhook topic must be valid.', 'woocommerce' ), 400 ); + } + } + + // update delivery URL + if ( ! empty( $data['delivery_url'] ) ) { + if ( wc_is_valid_url( $data['delivery_url'] ) ) { + + $webhook->set_delivery_url( $data['delivery_url'] ); + + } else { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_url', __( 'Webhook delivery URL must be a valid URL starting with http:// or https://', 'woocommerce' ), 400 ); + } + } + + // update secret + if ( ! empty( $data['secret'] ) ) { + $webhook->set_secret( $data['secret'] ); + } + + // update status + if ( ! empty( $data['status'] ) ) { + $webhook->set_status( $data['status'] ); + } + + // update name + if ( ! empty( $data['name'] ) ) { + $webhook->set_name( $data['name'] ); + } + + $webhook->save(); + + do_action( 'woocommerce_api_edit_webhook', $webhook->get_id(), $this ); + + return $this->get_webhook( $webhook->get_id() ); + + } catch ( WC_API_Exception $e ) { + + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a webhook + * + * @since 2.2 + * @param int $id webhook ID + * @return array|WP_Error + */ + public function delete_webhook( $id ) { + + $id = $this->validate_request( $id, 'shop_webhook', 'delete' ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + do_action( 'woocommerce_api_delete_webhook', $id, $this ); + + $webhook = wc_get_webhook( $id ); + + return $webhook->delete( true ); + } + + /** + * Helper method to get webhook post objects + * + * @since 2.2 + * @param array $args Request arguments for filtering query. + * @return array + */ + private function query_webhooks( $args ) { + $args = $this->merge_query_args( array(), $args ); + + $args['limit'] = isset( $args['posts_per_page'] ) ? intval( $args['posts_per_page'] ) : intval( get_option( 'posts_per_page' ) ); + + if ( empty( $args['offset'] ) ) { + $args['offset'] = 1 < $args['paged'] ? ( $args['paged'] - 1 ) * $args['limit'] : 0; + } + + $page = $args['paged']; + unset( $args['paged'], $args['posts_per_page'] ); + + if ( isset( $args['s'] ) ) { + $args['search'] = $args['s']; + unset( $args['s'] ); + } + + // Post type to webhook status. + if ( ! empty( $args['post_status'] ) ) { + $args['status'] = $args['post_status']; + unset( $args['post_status'] ); + } + + if ( ! empty( $args['post__in'] ) ) { + $args['include'] = $args['post__in']; + unset( $args['post__in'] ); + } + + if ( ! empty( $args['date_query'] ) ) { + foreach ( $args['date_query'] as $date_query ) { + if ( 'post_date_gmt' === $date_query['column'] ) { + $args['after'] = isset( $date_query['after'] ) ? $date_query['after'] : null; + $args['before'] = isset( $date_query['before'] ) ? $date_query['before'] : null; + } elseif ( 'post_modified_gmt' === $date_query['column'] ) { + $args['modified_after'] = isset( $date_query['after'] ) ? $date_query['after'] : null; + $args['modified_before'] = isset( $date_query['before'] ) ? $date_query['before'] : null; + } + } + + unset( $args['date_query'] ); + } + + $args['paginate'] = true; + + // Get the webhooks. + $data_store = WC_Data_Store::load( 'webhook' ); + $results = $data_store->search_webhooks( $args ); + + // Get total items. + $headers = new stdClass; + $headers->page = $page; + $headers->total = $results->total; + $headers->is_single = $args['limit'] > $headers->total; + $headers->total_pages = $results->max_num_pages; + + return array( + 'results' => $results->webhooks, + 'headers' => $headers, + ); + } + + /** + * Get deliveries for a webhook + * + * @since 2.2 + * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. + * @param string $webhook_id webhook ID + * @param string|null $fields fields to include in response + * @return array|WP_Error + */ + public function get_webhook_deliveries( $webhook_id, $fields = null ) { + + // Ensure ID is valid webhook ID + $webhook_id = $this->validate_request( $webhook_id, 'shop_webhook', 'read' ); + + if ( is_wp_error( $webhook_id ) ) { + return $webhook_id; + } + + return array( 'webhook_deliveries' => array() ); + } + + /** + * Get the delivery log for the given webhook ID and delivery ID + * + * @since 2.2 + * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. + * @param string $webhook_id webhook ID + * @param string $id delivery log ID + * @param string|null $fields fields to limit response to + * + * @return array|WP_Error + */ + public function get_webhook_delivery( $webhook_id, $id, $fields = null ) { + try { + // Validate webhook ID + $webhook_id = $this->validate_request( $webhook_id, 'shop_webhook', 'read' ); + + if ( is_wp_error( $webhook_id ) ) { + return $webhook_id; + } + + $id = absint( $id ); + + if ( empty( $id ) ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_id', __( 'Invalid webhook delivery ID.', 'woocommerce' ), 404 ); + } + + $webhook = new WC_Webhook( $webhook_id ); + + $log = 0; + + if ( ! $log ) { + throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_id', __( 'Invalid webhook delivery.', 'woocommerce' ), 400 ); + } + + return array( 'webhook_delivery' => apply_filters( 'woocommerce_api_webhook_delivery_response', array(), $id, $fields, $log, $webhook_id, $this ) ); + } catch ( WC_API_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Validate the request by checking: + * + * 1) the ID is a valid integer. + * 2) the ID returns a valid post object and matches the provided post type. + * 3) the current user has the proper permissions to read/edit/delete the post. + * + * @since 3.3.0 + * @param string|int $id The post ID + * @param string $type The post type, either `shop_order`, `shop_coupon`, or `product`. + * @param string $context The context of the request, either `read`, `edit` or `delete`. + * @return int|WP_Error Valid post ID or WP_Error if any of the checks fails. + */ + protected function validate_request( $id, $type, $context ) { + $id = absint( $id ); + + // Validate ID. + if ( empty( $id ) ) { + return new WP_Error( "woocommerce_api_invalid_webhook_id", sprintf( __( 'Invalid %s ID', 'woocommerce' ), $type ), array( 'status' => 404 ) ); + } + + $webhook = wc_get_webhook( $id ); + + if ( null === $webhook ) { + return new WP_Error( "woocommerce_api_no_webhook_found", sprintf( __( 'No %1$s found with the ID equal to %2$s', 'woocommerce' ), 'webhook', $id ), array( 'status' => 404 ) ); + } + + // Validate permissions. + switch ( $context ) { + + case 'read': + if ( ! current_user_can( 'manage_woocommerce' ) ) { + return new WP_Error( "woocommerce_api_user_cannot_read_webhook", sprintf( __( 'You do not have permission to read this %s', 'woocommerce' ), 'webhook' ), array( 'status' => 401 ) ); + } + break; + + case 'edit': + if ( ! current_user_can( 'manage_woocommerce' ) ) { + return new WP_Error( "woocommerce_api_user_cannot_edit_webhook", sprintf( __( 'You do not have permission to edit this %s', 'woocommerce' ), 'webhook' ), array( 'status' => 401 ) ); + } + break; + + case 'delete': + if ( ! current_user_can( 'manage_woocommerce' ) ) { + return new WP_Error( "woocommerce_api_user_cannot_delete_webhook", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce' ), 'webhook' ), array( 'status' => 401 ) ); + } + break; + } + + return $id; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/interface-wc-api-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/interface-wc-api-handler.php new file mode 100644 index 0000000..94ce87d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/api/v3/interface-wc-api-handler.php @@ -0,0 +1,47 @@ +query_vars['wc-api-version'] = $_GET['wc-api-version']; + } + + if ( ! empty( $_GET['wc-api-route'] ) ) { + $wp->query_vars['wc-api-route'] = $_GET['wc-api-route']; + } + + // REST API request. + if ( ! empty( $wp->query_vars['wc-api-version'] ) && ! empty( $wp->query_vars['wc-api-route'] ) ) { + + wc_maybe_define_constant( 'WC_API_REQUEST', true ); + wc_maybe_define_constant( 'WC_API_REQUEST_VERSION', absint( $wp->query_vars['wc-api-version'] ) ); + + // Legacy v1 API request. + if ( 1 === WC_API_REQUEST_VERSION ) { + $this->handle_v1_rest_api_request(); + } elseif ( 2 === WC_API_REQUEST_VERSION ) { + $this->handle_v2_rest_api_request(); + } else { + $this->includes(); + + $this->server = new WC_API_Server( $wp->query_vars['wc-api-route'] ); + + // load API resource classes. + $this->register_resources( $this->server ); + + // Fire off the request. + $this->server->serve_request(); + } + + exit; + } + } + + /** + * Include required files for REST API request. + * + * @since 2.1 + * @deprecated 2.6.0 + */ + public function includes() { + + // API server / response handlers. + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-exception.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-server.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/interface-wc-api-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-json-handler.php' ); + + // Authentication. + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-authentication.php' ); + $this->authentication = new WC_API_Authentication(); + + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-resource.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-coupons.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-customers.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-orders.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-products.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-reports.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-taxes.php' ); + include_once( dirname( __FILE__ ) . '/api/v3/class-wc-api-webhooks.php' ); + + // Allow plugins to load other response handlers or resource classes. + do_action( 'woocommerce_api_loaded' ); + } + + /** + * Register available API resources. + * + * @since 2.1 + * @deprecated 2.6.0 + * @param WC_API_Server $server the REST server. + */ + public function register_resources( $server ) { + + $api_classes = apply_filters( 'woocommerce_api_classes', + array( + 'WC_API_Coupons', + 'WC_API_Customers', + 'WC_API_Orders', + 'WC_API_Products', + 'WC_API_Reports', + 'WC_API_Taxes', + 'WC_API_Webhooks', + ) + ); + + foreach ( $api_classes as $api_class ) { + $this->$api_class = new $api_class( $server ); + } + } + + + /** + * Handle legacy v1 REST API requests. + * + * @since 2.2 + * @deprecated 2.6.0 + */ + private function handle_v1_rest_api_request() { + + // Include legacy required files for v1 REST API request. + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-server.php' ); + include_once( dirname( __FILE__ ) . '/api/v1/interface-wc-api-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-json-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-xml-handler.php' ); + + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-authentication.php' ); + $this->authentication = new WC_API_Authentication(); + + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-resource.php' ); + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-coupons.php' ); + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-customers.php' ); + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-orders.php' ); + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-products.php' ); + include_once( dirname( __FILE__ ) . '/api/v1/class-wc-api-reports.php' ); + + // Allow plugins to load other response handlers or resource classes. + do_action( 'woocommerce_api_loaded' ); + + $this->server = new WC_API_Server( $GLOBALS['wp']->query_vars['wc-api-route'] ); + + // Register available resources for legacy v1 REST API request. + $api_classes = apply_filters( 'woocommerce_api_classes', + array( + 'WC_API_Customers', + 'WC_API_Orders', + 'WC_API_Products', + 'WC_API_Coupons', + 'WC_API_Reports', + ) + ); + + foreach ( $api_classes as $api_class ) { + $this->$api_class = new $api_class( $this->server ); + } + + // Fire off the request. + $this->server->serve_request(); + } + + /** + * Handle legacy v2 REST API requests. + * + * @since 2.4 + * @deprecated 2.6.0 + */ + private function handle_v2_rest_api_request() { + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-exception.php' ); + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-server.php' ); + include_once( dirname( __FILE__ ) . '/api/v2/interface-wc-api-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-json-handler.php' ); + + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-authentication.php' ); + $this->authentication = new WC_API_Authentication(); + + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-resource.php' ); + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-coupons.php' ); + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-customers.php' ); + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-orders.php' ); + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-products.php' ); + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-reports.php' ); + include_once( dirname( __FILE__ ) . '/api/v2/class-wc-api-webhooks.php' ); + + // allow plugins to load other response handlers or resource classes. + do_action( 'woocommerce_api_loaded' ); + + $this->server = new WC_API_Server( $GLOBALS['wp']->query_vars['wc-api-route'] ); + + // Register available resources for legacy v2 REST API request. + $api_classes = apply_filters( 'woocommerce_api_classes', + array( + 'WC_API_Customers', + 'WC_API_Orders', + 'WC_API_Products', + 'WC_API_Coupons', + 'WC_API_Reports', + 'WC_API_Webhooks', + ) + ); + + foreach ( $api_classes as $api_class ) { + $this->$api_class = new $api_class( $this->server ); + } + + // Fire off the request. + $this->server->serve_request(); + } + + /** + * Rest API Init. + * + * @deprecated 3.7.0 - REST API clases autoload. + */ + public function rest_api_init() {} + + /** + * Include REST API classes. + * + * @deprecated 3.7.0 - REST API clases autoload. + */ + public function rest_api_includes() { + $this->rest_api_init(); + } + /** + * Register REST API routes. + * + * @deprecated 3.7.0 + */ + public function register_rest_routes() { + wc_deprecated_function( 'WC_Legacy_API::register_rest_routes', '3.7.0', '' ); + $this->register_wp_admin_settings(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-cart.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-cart.php new file mode 100644 index 0000000..94a6544 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-cart.php @@ -0,0 +1,446 @@ + 0, + 'total' => 0, + 'subtotal' => 0, + 'subtotal_ex_tax' => 0, + 'tax_total' => 0, + 'taxes' => array(), + 'shipping_taxes' => array(), + 'discount_cart' => 0, + 'discount_cart_tax' => 0, + 'shipping_total' => 0, + 'shipping_tax_total' => 0, + 'coupon_discount_amounts' => array(), + 'coupon_discount_tax_amounts' => array(), + 'fee_total' => 0, + 'fees' => array(), + ); + + /** + * Contains an array of coupon usage counts after they have been applied. + * + * @deprecated 3.2.0 + * @var array + */ + public $coupon_applied_count = array(); + + /** + * Map legacy variables. + * + * @param string $name Property name. + * @param mixed $value Value to set. + */ + public function __isset( $name ) { + $legacy_keys = array_merge( + array( + 'dp', + 'prices_include_tax', + 'round_at_subtotal', + 'cart_contents_total', + 'total', + 'subtotal', + 'subtotal_ex_tax', + 'tax_total', + 'fee_total', + 'discount_cart', + 'discount_cart_tax', + 'shipping_total', + 'shipping_tax_total', + 'display_totals_ex_tax', + 'display_cart_ex_tax', + 'cart_contents_weight', + 'cart_contents_count', + 'coupons', + 'taxes', + 'shipping_taxes', + 'coupon_discount_amounts', + 'coupon_discount_tax_amounts', + 'fees', + 'tax', + 'discount_total', + 'tax_display_cart', + ), + is_array( $this->cart_session_data ) ? array_keys( $this->cart_session_data ) : array() + ); + + if ( in_array( $name, $legacy_keys, true ) ) { + return true; + } + + return false; + } + + /** + * Magic getters. + * + * If you add/remove cases here please update $legacy_keys in __isset accordingly. + * + * @param string $name Property name. + * @return mixed + */ + public function &__get( $name ) { + $value = ''; + + switch ( $name ) { + case 'dp' : + $value = wc_get_price_decimals(); + break; + case 'prices_include_tax' : + $value = wc_prices_include_tax(); + break; + case 'round_at_subtotal' : + $value = 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' ); + break; + case 'cart_contents_total' : + $value = $this->get_cart_contents_total(); + break; + case 'total' : + $value = $this->get_total( 'edit' ); + break; + case 'subtotal' : + $value = $this->get_subtotal() + $this->get_subtotal_tax(); + break; + case 'subtotal_ex_tax' : + $value = $this->get_subtotal(); + break; + case 'tax_total' : + $value = $this->get_fee_tax() + $this->get_cart_contents_tax(); + break; + case 'fee_total' : + $value = $this->get_fee_total(); + break; + case 'discount_cart' : + $value = $this->get_discount_total(); + break; + case 'discount_cart_tax' : + $value = $this->get_discount_tax(); + break; + case 'shipping_total' : + $value = $this->get_shipping_total(); + break; + case 'shipping_tax_total' : + $value = $this->get_shipping_tax(); + break; + case 'display_totals_ex_tax' : + case 'display_cart_ex_tax' : + $value = ! $this->display_prices_including_tax(); + break; + case 'cart_contents_weight' : + $value = $this->get_cart_contents_weight(); + break; + case 'cart_contents_count' : + $value = $this->get_cart_contents_count(); + break; + case 'coupons' : + $value = $this->get_coupons(); + break; + + // Arrays returned by reference to allow modification without notices. TODO: Remove in 4.0. + case 'taxes' : + wc_deprecated_function( 'WC_Cart->taxes', '3.2', sprintf( 'getters (%s) and setters (%s)', 'WC_Cart::get_cart_contents_taxes()', 'WC_Cart::set_cart_contents_taxes()' ) ); + $value = &$this->totals[ 'cart_contents_taxes' ]; + break; + case 'shipping_taxes' : + wc_deprecated_function( 'WC_Cart->shipping_taxes', '3.2', sprintf( 'getters (%s) and setters (%s)', 'WC_Cart::get_shipping_taxes()', 'WC_Cart::set_shipping_taxes()' ) ); + $value = &$this->totals[ 'shipping_taxes' ]; + break; + case 'coupon_discount_amounts' : + $value = &$this->coupon_discount_totals; + break; + case 'coupon_discount_tax_amounts' : + $value = &$this->coupon_discount_tax_totals; + break; + case 'fees' : + wc_deprecated_function( 'WC_Cart->fees', '3.2', sprintf( 'the fees API (%s)', 'WC_Cart::get_fees' ) ); + + // Grab fees from the new API. + $new_fees = $this->fees_api()->get_fees(); + + // Add new fees to the legacy prop so it can be adjusted via legacy property. + $this->fees = $new_fees; + + // Return by reference. + $value = &$this->fees; + break; + // Deprecated args. TODO: Remove in 4.0. + case 'tax' : + wc_deprecated_argument( 'WC_Cart->tax', '2.3', 'Use WC_Tax directly' ); + $this->tax = new WC_Tax(); + $value = $this->tax; + break; + case 'discount_total': + wc_deprecated_argument( 'WC_Cart->discount_total', '2.3', 'After tax coupons are no longer supported. For more information see: https://woocommerce.wordpress.com/2014/12/upcoming-coupon-changes-in-woocommerce-2-3/' ); + $value = 0; + break; + case 'tax_display_cart': + wc_deprecated_argument( 'WC_Cart->tax_display_cart', '4.4', 'Use WC_Cart->get_tax_price_display_mode() instead.' ); + $value = $this->get_tax_price_display_mode(); + break; + } + return $value; + } + + /** + * Map legacy variables to setters. + * + * @param string $name Property name. + * @param mixed $value Value to set. + */ + public function __set( $name, $value ) { + switch ( $name ) { + case 'cart_contents_total' : + $this->set_cart_contents_total( $value ); + break; + case 'total' : + $this->set_total( $value ); + break; + case 'subtotal' : + $this->set_subtotal( $value ); + break; + case 'subtotal_ex_tax' : + $this->set_subtotal( $value ); + break; + case 'tax_total' : + $this->set_cart_contents_tax( $value ); + $this->set_fee_tax( 0 ); + break; + case 'taxes' : + $this->set_cart_contents_taxes( $value ); + break; + case 'shipping_taxes' : + $this->set_shipping_taxes( $value ); + break; + case 'fee_total' : + $this->set_fee_total( $value ); + break; + case 'discount_cart' : + $this->set_discount_total( $value ); + break; + case 'discount_cart_tax' : + $this->set_discount_tax( $value ); + break; + case 'shipping_total' : + $this->set_shipping_total( $value ); + break; + case 'shipping_tax_total' : + $this->set_shipping_tax( $value ); + break; + case 'coupon_discount_amounts' : + $this->set_coupon_discount_totals( $value ); + break; + case 'coupon_discount_tax_amounts' : + $this->set_coupon_discount_tax_totals( $value ); + break; + case 'fees' : + wc_deprecated_function( 'WC_Cart->fees', '3.2', sprintf( 'the fees API (%s)', 'WC_Cart::add_fee' ) ); + $this->fees = $value; + break; + default : + $this->$name = $value; + break; + } + } + + /** + * Methods moved to session class in 3.2.0. + */ + public function get_cart_from_session() { $this->session->get_cart_from_session(); } + public function maybe_set_cart_cookies() { $this->session->maybe_set_cart_cookies(); } + public function set_session() { $this->session->set_session(); } + public function get_cart_for_session() { return $this->session->get_cart_for_session(); } + public function persistent_cart_update() { $this->session->persistent_cart_update(); } + public function persistent_cart_destroy() { $this->session->persistent_cart_destroy(); } + + /** + * Get the total of all cart discounts. + * + * @return float + */ + public function get_cart_discount_total() { + return $this->get_discount_total(); + } + + /** + * Get the total of all cart tax discounts (used for discounts on tax inclusive prices). + * + * @return float + */ + public function get_cart_discount_tax_total() { + return $this->get_discount_tax(); + } + + /** + * Renamed for consistency. + * + * @param string $coupon_code + * @return bool True if the coupon is applied, false if it does not exist or cannot be applied. + */ + public function add_discount( $coupon_code ) { + return $this->apply_coupon( $coupon_code ); + } + /** + * Remove taxes. + * + * @deprecated 3.2.0 Taxes are never calculated if customer is tax except making this function unused. + */ + public function remove_taxes() { + wc_deprecated_function( 'WC_Cart::remove_taxes', '3.2', '' ); + } + /** + * Init. + * + * @deprecated 3.2.0 Session is loaded via hooks rather than directly. + */ + public function init() { + wc_deprecated_function( 'WC_Cart::init', '3.2', '' ); + $this->get_cart_from_session(); + } + + /** + * Function to apply discounts to a product and get the discounted price (before tax is applied). + * + * @deprecated 3.2.0 Calculation and coupon logic is handled in WC_Cart_Totals. + * @param mixed $values Cart item. + * @param mixed $price Price of item. + * @param bool $add_totals Legacy. + * @return float price + */ + public function get_discounted_price( $values, $price, $add_totals = false ) { + wc_deprecated_function( 'WC_Cart::get_discounted_price', '3.2', '' ); + + $cart_item_key = $values['key']; + $cart_item = $this->cart_contents[ $cart_item_key ]; + + return $cart_item['line_total']; + } + + /** + * Gets the url to the cart page. + * + * @deprecated 2.5.0 in favor to wc_get_cart_url() + * @return string url to page + */ + public function get_cart_url() { + wc_deprecated_function( 'WC_Cart::get_cart_url', '2.5', 'wc_get_cart_url' ); + return wc_get_cart_url(); + } + + /** + * Gets the url to the checkout page. + * + * @deprecated 2.5.0 in favor to wc_get_checkout_url() + * @return string url to page + */ + public function get_checkout_url() { + wc_deprecated_function( 'WC_Cart::get_checkout_url', '2.5', 'wc_get_checkout_url' ); + return wc_get_checkout_url(); + } + + /** + * Sees if we need a shipping address. + * + * @deprecated 2.5.0 in favor to wc_ship_to_billing_address_only() + * @return bool + */ + public function ship_to_billing_address_only() { + wc_deprecated_function( 'WC_Cart::ship_to_billing_address_only', '2.5', 'wc_ship_to_billing_address_only' ); + return wc_ship_to_billing_address_only(); + } + + /** + * Coupons enabled function. Filterable. + * + * @deprecated 2.5.0 + * @return bool + */ + public function coupons_enabled() { + wc_deprecated_function( 'WC_Legacy_Cart::coupons_enabled', '2.5.0', 'wc_coupons_enabled' ); + return wc_coupons_enabled(); + } + + /** + * Gets the total (product) discount amount - these are applied before tax. + * + * @deprecated 2.3.0 Order discounts (after tax) removed in 2.3 so multiple methods for discounts are no longer required. + * @return mixed formatted price or false if there are none. + */ + public function get_discounts_before_tax() { + wc_deprecated_function( 'get_discounts_before_tax', '2.3', 'get_total_discount' ); + if ( $this->get_cart_discount_total() ) { + $discounts_before_tax = wc_price( $this->get_cart_discount_total() ); + } else { + $discounts_before_tax = false; + } + return apply_filters( 'woocommerce_cart_discounts_before_tax', $discounts_before_tax, $this ); + } + + /** + * Get the total of all order discounts (after tax discounts). + * + * @deprecated 2.3.0 Order discounts (after tax) removed in 2.3. + * @return int + */ + public function get_order_discount_total() { + wc_deprecated_function( 'get_order_discount_total', '2.3' ); + return 0; + } + + /** + * Function to apply cart discounts after tax. + * + * @deprecated 2.3.0 Coupons can not be applied after tax. + * @param $values + * @param $price + */ + public function apply_cart_discounts_after_tax( $values, $price ) { + wc_deprecated_function( 'apply_cart_discounts_after_tax', '2.3' ); + } + + /** + * Function to apply product discounts after tax. + * + * @deprecated 2.3.0 Coupons can not be applied after tax. + * + * @param $values + * @param $price + */ + public function apply_product_discounts_after_tax( $values, $price ) { + wc_deprecated_function( 'apply_product_discounts_after_tax', '2.3' ); + } + + /** + * Gets the order discount amount - these are applied after tax. + * + * @deprecated 2.3.0 Coupons can not be applied after tax. + */ + public function get_discounts_after_tax() { + wc_deprecated_function( 'get_discounts_after_tax', '2.3' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-coupon.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-coupon.php new file mode 100644 index 0000000..95b3be4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-coupon.php @@ -0,0 +1,204 @@ +get_id(); + break; + case 'exists' : + $value = $this->get_id() > 0; + break; + case 'coupon_custom_fields' : + $legacy_custom_fields = array(); + $custom_fields = $this->get_id() ? $this->get_meta_data() : array(); + if ( ! empty( $custom_fields ) ) { + foreach ( $custom_fields as $cf_value ) { + // legacy only supports 1 key + $legacy_custom_fields[ $cf_value->key ][0] = $cf_value->value; + } + } + $value = $legacy_custom_fields; + break; + case 'type' : + case 'discount_type' : + $value = $this->get_discount_type(); + break; + case 'amount' : + case 'coupon_amount' : + $value = $this->get_amount(); + break; + case 'code' : + $value = $this->get_code(); + break; + case 'individual_use' : + $value = ( true === $this->get_individual_use() ) ? 'yes' : 'no'; + break; + case 'product_ids' : + $value = $this->get_product_ids(); + break; + case 'exclude_product_ids' : + $value = $this->get_excluded_product_ids(); + break; + case 'usage_limit' : + $value = $this->get_usage_limit(); + break; + case 'usage_limit_per_user' : + $value = $this->get_usage_limit_per_user(); + break; + case 'limit_usage_to_x_items' : + $value = $this->get_limit_usage_to_x_items(); + break; + case 'usage_count' : + $value = $this->get_usage_count(); + break; + case 'expiry_date' : + $value = ( $this->get_date_expires() ? $this->get_date_expires()->date( 'Y-m-d' ) : '' ); + break; + case 'product_categories' : + $value = $this->get_product_categories(); + break; + case 'exclude_product_categories' : + $value = $this->get_excluded_product_categories(); + break; + case 'minimum_amount' : + $value = $this->get_minimum_amount(); + break; + case 'maximum_amount' : + $value = $this->get_maximum_amount(); + break; + case 'customer_email' : + $value = $this->get_email_restrictions(); + break; + default : + $value = ''; + break; + } + + return $value; + } + + /** + * Format loaded data as array. + * @param string|array $array + * @return array + */ + public function format_array( $array ) { + wc_deprecated_function( 'WC_Coupon::format_array', '3.0' ); + if ( ! is_array( $array ) ) { + if ( is_serialized( $array ) ) { + $array = maybe_unserialize( $array ); + } else { + $array = explode( ',', $array ); + } + } + return array_filter( array_map( 'trim', array_map( 'strtolower', $array ) ) ); + } + + + /** + * Check if coupon needs applying before tax. + * + * @return bool + */ + public function apply_before_tax() { + wc_deprecated_function( 'WC_Coupon::apply_before_tax', '3.0' ); + return true; + } + + /** + * Check if a coupon enables free shipping. + * + * @return bool + */ + public function enable_free_shipping() { + wc_deprecated_function( 'WC_Coupon::enable_free_shipping', '3.0', 'WC_Coupon::get_free_shipping' ); + return $this->get_free_shipping(); + } + + /** + * Check if a coupon excludes sale items. + * + * @return bool + */ + public function exclude_sale_items() { + wc_deprecated_function( 'WC_Coupon::exclude_sale_items', '3.0', 'WC_Coupon::get_exclude_sale_items' ); + return $this->get_exclude_sale_items(); + } + + /** + * Increase usage count for current coupon. + * + * @param string $used_by Either user ID or billing email + */ + public function inc_usage_count( $used_by = '' ) { + $this->increase_usage_count( $used_by ); + } + + /** + * Decrease usage count for current coupon. + * + * @param string $used_by Either user ID or billing email + */ + public function dcr_usage_count( $used_by = '' ) { + $this->decrease_usage_count( $used_by ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-customer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-customer.php new file mode 100644 index 0000000..37ed592 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-customer.php @@ -0,0 +1,286 @@ +filter_legacy_key( $key ); + return in_array( $key, $legacy_keys ); + } + + /** + * __get function. + * @param string $key + * @return string + */ + public function __get( $key ) { + wc_doing_it_wrong( $key, 'Customer properties should not be accessed directly.', '3.0' ); + $key = $this->filter_legacy_key( $key ); + if ( in_array( $key, array( 'country', 'state', 'postcode', 'city', 'address_1', 'address', 'address_2' ) ) ) { + $key = 'billing_' . $key; + } + return is_callable( array( $this, "get_{$key}" ) ) ? $this->{"get_{$key}"}() : ''; + } + + /** + * __set function. + * + * @param string $key + * @param mixed $value + */ + public function __set( $key, $value ) { + wc_doing_it_wrong( $key, 'Customer properties should not be set directly.', '3.0' ); + $key = $this->filter_legacy_key( $key ); + + if ( is_callable( array( $this, "set_{$key}" ) ) ) { + $this->{"set_{$key}"}( $value ); + } + } + + /** + * Address and shipping_address are aliased, so we want to get the 'real' key name. + * For all other keys, we can just return it. + * @since 3.0.0 + * @param string $key + * @return string + */ + private function filter_legacy_key( $key ) { + if ( 'address' === $key ) { + $key = 'address_1'; + } + if ( 'shipping_address' === $key ) { + $key = 'shipping_address_1'; + } + + return $key; + } + + /** + * Sets session data for the location. + * + * @param string $country + * @param string $state + * @param string $postcode (default: '') + * @param string $city (default: '') + */ + public function set_location( $country, $state, $postcode = '', $city = '' ) { + $this->set_billing_location( $country, $state, $postcode, $city ); + $this->set_shipping_location( $country, $state, $postcode, $city ); + } + + /** + * Get default country for a customer. + * @return string + */ + public function get_default_country() { + wc_deprecated_function( 'WC_Customer::get_default_country', '3.0', 'wc_get_customer_default_location' ); + $default = wc_get_customer_default_location(); + return $default['country']; + } + + /** + * Get default state for a customer. + * @return string + */ + public function get_default_state() { + wc_deprecated_function( 'WC_Customer::get_default_state', '3.0', 'wc_get_customer_default_location' ); + $default = wc_get_customer_default_location(); + return $default['state']; + } + + /** + * Set customer address to match shop base address. + */ + public function set_to_base() { + wc_deprecated_function( 'WC_Customer::set_to_base', '3.0', 'WC_Customer::set_billing_address_to_base' ); + $this->set_billing_address_to_base(); + } + + /** + * Set customer shipping address to base address. + */ + public function set_shipping_to_base() { + wc_deprecated_function( 'WC_Customer::set_shipping_to_base', '3.0', 'WC_Customer::set_shipping_address_to_base' ); + $this->set_shipping_address_to_base(); + } + + /** + * Calculated shipping. + * @param boolean $calculated + */ + public function calculated_shipping( $calculated = true ) { + wc_deprecated_function( 'WC_Customer::calculated_shipping', '3.0', 'WC_Customer::set_calculated_shipping' ); + $this->set_calculated_shipping( $calculated ); + } + + /** + * Set default data for a customer. + */ + public function set_default_data() { + wc_deprecated_function( 'WC_Customer::set_default_data', '3.0' ); + } + + /** + * Save data function. + */ + public function save_data() { + $this->save(); + } + + /** + * Is the user a paying customer? + * + * @param int $user_id + * + * @return bool + */ + function is_paying_customer( $user_id = '' ) { + wc_deprecated_function( 'WC_Customer::is_paying_customer', '3.0', 'WC_Customer::get_is_paying_customer' ); + if ( ! empty( $user_id ) ) { + $user_id = get_current_user_id(); + } + return '1' === get_user_meta( $user_id, 'paying_customer', true ); + } + + /** + * Legacy get address. + */ + function get_address() { + wc_deprecated_function( 'WC_Customer::get_address', '3.0', 'WC_Customer::get_billing_address_1' ); + return $this->get_billing_address_1(); + } + + /** + * Legacy get address 2. + */ + function get_address_2() { + wc_deprecated_function( 'WC_Customer::get_address_2', '3.0', 'WC_Customer::get_billing_address_2' ); + return $this->get_billing_address_2(); + } + + /** + * Legacy get country. + */ + function get_country() { + wc_deprecated_function( 'WC_Customer::get_country', '3.0', 'WC_Customer::get_billing_country' ); + return $this->get_billing_country(); + } + + /** + * Legacy get state. + */ + function get_state() { + wc_deprecated_function( 'WC_Customer::get_state', '3.0', 'WC_Customer::get_billing_state' ); + return $this->get_billing_state(); + } + + /** + * Legacy get postcode. + */ + function get_postcode() { + wc_deprecated_function( 'WC_Customer::get_postcode', '3.0', 'WC_Customer::get_billing_postcode' ); + return $this->get_billing_postcode(); + } + + /** + * Legacy get city. + */ + function get_city() { + wc_deprecated_function( 'WC_Customer::get_city', '3.0', 'WC_Customer::get_billing_city' ); + return $this->get_billing_city(); + } + + /** + * Legacy set country. + * + * @param string $country + */ + function set_country( $country ) { + wc_deprecated_function( 'WC_Customer::set_country', '3.0', 'WC_Customer::set_billing_country' ); + $this->set_billing_country( $country ); + } + + /** + * Legacy set state. + * + * @param string $state + */ + function set_state( $state ) { + wc_deprecated_function( 'WC_Customer::set_state', '3.0', 'WC_Customer::set_billing_state' ); + $this->set_billing_state( $state ); + } + + /** + * Legacy set postcode. + * + * @param string $postcode + */ + function set_postcode( $postcode ) { + wc_deprecated_function( 'WC_Customer::set_postcode', '3.0', 'WC_Customer::set_billing_postcode' ); + $this->set_billing_postcode( $postcode ); + } + + /** + * Legacy set city. + * + * @param string $city + */ + function set_city( $city ) { + wc_deprecated_function( 'WC_Customer::set_city', '3.0', 'WC_Customer::set_billing_city' ); + $this->set_billing_city( $city ); + } + + /** + * Legacy set address. + * + * @param string $address + */ + function set_address( $address ) { + wc_deprecated_function( 'WC_Customer::set_address', '3.0', 'WC_Customer::set_billing_address' ); + $this->set_billing_address( $address ); + } + + /** + * Legacy set address. + * + * @param string $address + */ + function set_address_2( $address ) { + wc_deprecated_function( 'WC_Customer::set_address_2', '3.0', 'WC_Customer::set_billing_address_2' ); + $this->set_billing_address_2( $address ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-shipping-zone.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-shipping-zone.php new file mode 100644 index 0000000..3c1c3a0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-shipping-zone.php @@ -0,0 +1,68 @@ +get_id(); + } + + /** + * Read a shipping zone by ID. + * @deprecated 3.0.0 - Init a shipping zone with an ID. + * + * @param int $zone_id + */ + public function read( $zone_id ) { + wc_deprecated_function( 'WC_Shipping_Zone::read', '3.0', 'a shipping zone initialized with an ID.' ); + $this->set_id( $zone_id ); + $data_store = WC_Data_Store::load( 'shipping-zone' ); + $data_store->read( $this ); + } + + /** + * Update a zone. + * @deprecated 3.0.0 - Use ::save instead. + */ + public function update() { + wc_deprecated_function( 'WC_Shipping_Zone::update', '3.0', 'WC_Shipping_Zone::save instead.' ); + $data_store = WC_Data_Store::load( 'shipping-zone' ); + try { + $data_store->update( $this ); + } catch ( Exception $e ) { + return false; + } + } + + /** + * Create a zone. + * @deprecated 3.0.0 - Use ::save instead. + */ + public function create() { + wc_deprecated_function( 'WC_Shipping_Zone::create', '3.0', 'WC_Shipping_Zone::save instead.' ); + $data_store = WC_Data_Store::load( 'shipping-zone' ); + try { + $data_store->create( $this ); + } catch ( Exception $e ) { + return false; + } + } + + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-webhook.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-webhook.php new file mode 100644 index 0000000..d1e7034 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/legacy/class-wc-legacy-webhook.php @@ -0,0 +1,129 @@ +get_id(); + break; + case 'status' : + $value = $this->get_status(); + break; + case 'post_data' : + $value = null; + break; + case 'delivery_url' : + $value = $this->get_delivery_url(); + break; + case 'secret' : + $value = $this->get_secret(); + break; + case 'topic' : + $value = $this->get_topic(); + break; + case 'hooks' : + $value = $this->get_hooks(); + break; + case 'resource' : + $value = $this->get_resource(); + break; + case 'event' : + $value = $this->get_event(); + break; + case 'failure_count' : + $value = $this->get_failure_count(); + break; + case 'api_version' : + $value = $this->get_api_version(); + break; + + default : + $value = ''; + break; + } // End switch(). + + return $value; + } + + /** + * Get the post data for the webhook. + * + * @deprecated 3.2.0 + * @since 2.2 + * @return null|WP_Post + */ + public function get_post_data() { + wc_deprecated_function( 'WC_Webhook::get_post_data', '3.2' ); + + return null; + } + + /** + * Update the webhook status. + * + * @deprecated 3.2.0 + * @since 2.2.0 + * @param string $status Status to set. + */ + public function update_status( $status ) { + wc_deprecated_function( 'WC_Webhook::update_status', '3.2', 'WC_Webhook::set_status' ); + + $this->set_status( $status ); + $this->save(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/libraries/class-wc-eval-math.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/libraries/class-wc-eval-math.php new file mode 100644 index 0000000..11d8509 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/libraries/class-wc-eval-math.php @@ -0,0 +1,405 @@ + 2.71, 'pi' => 3.14 ); + + /** + * User-defined functions. + * + * @var array + */ + public static $f = array(); + + /** + * Constants. + * + * @var array + */ + public static $vb = array( 'e', 'pi' ); + + /** + * Built-in functions. + * + * @var array + */ + public static $fb = array(); + + /** + * Evaluate maths string. + * + * @param string $expr + * @return mixed + */ + public static function evaluate( $expr ) { + self::$last_error = null; + $expr = trim( $expr ); + if ( substr( $expr, -1, 1 ) == ';' ) { + $expr = substr( $expr, 0, strlen( $expr ) -1 ); // strip semicolons at the end + } + // =============== + // is it a variable assignment? + if ( preg_match( '/^\s*([a-z]\w*)\s*=\s*(.+)$/', $expr, $matches ) ) { + if ( in_array( $matches[1], self::$vb ) ) { // make sure we're not assigning to a constant + return self::trigger( "cannot assign to constant '$matches[1]'" ); + } + if ( ( $tmp = self::pfx( self::nfx( $matches[2] ) ) ) === false ) { + return false; // get the result and make sure it's good + } + self::$v[ $matches[1] ] = $tmp; // if so, stick it in the variable array + return self::$v[ $matches[1] ]; // and return the resulting value + // =============== + // is it a function assignment? + } elseif ( preg_match( '/^\s*([a-z]\w*)\s*\(\s*([a-z]\w*(?:\s*,\s*[a-z]\w*)*)\s*\)\s*=\s*(.+)$/', $expr, $matches ) ) { + $fnn = $matches[1]; // get the function name + if ( in_array( $matches[1], self::$fb ) ) { // make sure it isn't built in + return self::trigger( "cannot redefine built-in function '$matches[1]()'" ); + } + $args = explode( ",", preg_replace( "/\s+/", "", $matches[2] ) ); // get the arguments + if ( ( $stack = self::nfx( $matches[3] ) ) === false ) { + return false; // see if it can be converted to postfix + } + $stack_size = count( $stack ); + for ( $i = 0; $i < $stack_size; $i++ ) { // freeze the state of the non-argument variables + $token = $stack[ $i ]; + if ( preg_match( '/^[a-z]\w*$/', $token ) and ! in_array( $token, $args ) ) { + if ( array_key_exists( $token, self::$v ) ) { + $stack[ $i ] = self::$v[ $token ]; + } else { + return self::trigger( "undefined variable '$token' in function definition" ); + } + } + } + self::$f[ $fnn ] = array( 'args' => $args, 'func' => $stack ); + return true; + // =============== + } else { + return self::pfx( self::nfx( $expr ) ); // straight up evaluation, woo + } + } + + /** + * Convert infix to postfix notation. + * + * @param string $expr + * + * @return array|string + */ + private static function nfx( $expr ) { + + $index = 0; + $stack = new WC_Eval_Math_Stack; + $output = array(); // postfix form of expression, to be passed to pfx() + $expr = trim( $expr ); + + $ops = array( '+', '-', '*', '/', '^', '_' ); + $ops_r = array( '+' => 0, '-' => 0, '*' => 0, '/' => 0, '^' => 1 ); // right-associative operator? + $ops_p = array( '+' => 0, '-' => 0, '*' => 1, '/' => 1, '_' => 1, '^' => 2 ); // operator precedence + + $expecting_op = false; // we use this in syntax-checking the expression + // and determining when a - is a negation + if ( preg_match( "/[^\w\s+*^\/()\.,-]/", $expr, $matches ) ) { // make sure the characters are all good + return self::trigger( "illegal character '{$matches[0]}'" ); + } + + while ( 1 ) { // 1 Infinite Loop ;) + $op = substr( $expr, $index, 1 ); // get the first character at the current index + // find out if we're currently at the beginning of a number/variable/function/parenthesis/operand + $ex = preg_match( '/^([A-Za-z]\w*\(?|\d+(?:\.\d*)?|\.\d+|\()/', substr( $expr, $index ), $match ); + // =============== + if ( '-' === $op and ! $expecting_op ) { // is it a negation instead of a minus? + $stack->push( '_' ); // put a negation on the stack + $index++; + } elseif ( '_' === $op ) { // we have to explicitly deny this, because it's legal on the stack + return self::trigger( "illegal character '_'" ); // but not in the input expression + // =============== + } elseif ( ( in_array( $op, $ops ) or $ex ) and $expecting_op ) { // are we putting an operator on the stack? + if ( $ex ) { // are we expecting an operator but have a number/variable/function/opening parenthesis? + $op = '*'; + $index--; // it's an implicit multiplication + } + // heart of the algorithm: + while ( $stack->count > 0 and ( $o2 = $stack->last() ) and in_array( $o2, $ops ) and ( $ops_r[ $op ] ? $ops_p[ $op ] < $ops_p[ $o2 ] : $ops_p[ $op ] <= $ops_p[ $o2 ] ) ) { + $output[] = $stack->pop(); // pop stuff off the stack into the output + } + // many thanks: https://en.wikipedia.org/wiki/Reverse_Polish_notation#The_algorithm_in_detail + $stack->push( $op ); // finally put OUR operator onto the stack + $index++; + $expecting_op = false; + // =============== + } elseif ( ')' === $op && $expecting_op ) { // ready to close a parenthesis? + while ( ( $o2 = $stack->pop() ) != '(' ) { // pop off the stack back to the last ( + if ( is_null( $o2 ) ) { + return self::trigger( "unexpected ')'" ); + } else { + $output[] = $o2; + } + } + if ( preg_match( "/^([A-Za-z]\w*)\($/", $stack->last( 2 ), $matches ) ) { // did we just close a function? + $fnn = $matches[1]; // get the function name + $arg_count = $stack->pop(); // see how many arguments there were (cleverly stored on the stack, thank you) + $output[] = $stack->pop(); // pop the function and push onto the output + if ( in_array( $fnn, self::$fb ) ) { // check the argument count + if ( $arg_count > 1 ) { + return self::trigger( "too many arguments ($arg_count given, 1 expected)" ); + } + } elseif ( array_key_exists( $fnn, self::$f ) ) { + if ( count( self::$f[ $fnn ]['args'] ) != $arg_count ) { + return self::trigger( "wrong number of arguments ($arg_count given, " . count( self::$f[ $fnn ]['args'] ) . " expected)" ); + } + } else { // did we somehow push a non-function on the stack? this should never happen + return self::trigger( "internal error" ); + } + } + $index++; + // =============== + } elseif ( ',' === $op and $expecting_op ) { // did we just finish a function argument? + while ( ( $o2 = $stack->pop() ) != '(' ) { + if ( is_null( $o2 ) ) { + return self::trigger( "unexpected ','" ); // oops, never had a ( + } else { + $output[] = $o2; // pop the argument expression stuff and push onto the output + } + } + // make sure there was a function + if ( ! preg_match( "/^([A-Za-z]\w*)\($/", $stack->last( 2 ), $matches ) ) { + return self::trigger( "unexpected ','" ); + } + $stack->push( $stack->pop() + 1 ); // increment the argument count + $stack->push( '(' ); // put the ( back on, we'll need to pop back to it again + $index++; + $expecting_op = false; + // =============== + } elseif ( '(' === $op and ! $expecting_op ) { + $stack->push( '(' ); // that was easy + $index++; + // =============== + } elseif ( $ex and ! $expecting_op ) { // do we now have a function/variable/number? + $expecting_op = true; + $val = $match[1]; + if ( preg_match( "/^([A-Za-z]\w*)\($/", $val, $matches ) ) { // may be func, or variable w/ implicit multiplication against parentheses... + if ( in_array( $matches[1], self::$fb ) or array_key_exists( $matches[1], self::$f ) ) { // it's a func + $stack->push( $val ); + $stack->push( 1 ); + $stack->push( '(' ); + $expecting_op = false; + } else { // it's a var w/ implicit multiplication + $val = $matches[1]; + $output[] = $val; + } + } else { // it's a plain old var or num + $output[] = $val; + } + $index += strlen( $val ); + // =============== + } elseif ( ')' === $op ) { // miscellaneous error checking + return self::trigger( "unexpected ')'" ); + } elseif ( in_array( $op, $ops ) and ! $expecting_op ) { + return self::trigger( "unexpected operator '$op'" ); + } else { // I don't even want to know what you did to get here + return self::trigger( "an unexpected error occurred" ); + } + if ( strlen( $expr ) == $index ) { + if ( in_array( $op, $ops ) ) { // did we end with an operator? bad. + return self::trigger( "operator '$op' lacks operand" ); + } else { + break; + } + } + while ( substr( $expr, $index, 1 ) == ' ' ) { // step the index past whitespace (pretty much turns whitespace + $index++; // into implicit multiplication if no operator is there) + } + } + while ( ! is_null( $op = $stack->pop() ) ) { // pop everything off the stack and push onto output + if ( '(' === $op ) { + return self::trigger( "expecting ')'" ); // if there are (s on the stack, ()s were unbalanced + } + $output[] = $op; + } + return $output; + } + + /** + * Evaluate postfix notation. + * + * @param mixed $tokens + * @param array $vars + * + * @return mixed + */ + private static function pfx( $tokens, $vars = array() ) { + if ( false == $tokens ) { + return false; + } + $stack = new WC_Eval_Math_Stack; + + foreach ( $tokens as $token ) { // nice and easy + // if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on + if ( in_array( $token, array( '+', '-', '*', '/', '^' ) ) ) { + if ( is_null( $op2 = $stack->pop() ) ) { + return self::trigger( "internal error" ); + } + if ( is_null( $op1 = $stack->pop() ) ) { + return self::trigger( "internal error" ); + } + switch ( $token ) { + case '+': + $stack->push( $op1 + $op2 ); + break; + case '-': + $stack->push( $op1 - $op2 ); + break; + case '*': + $stack->push( $op1 * $op2 ); + break; + case '/': + if ( 0 == $op2 ) { + return self::trigger( 'division by zero' ); + } + $stack->push( $op1 / $op2 ); + break; + case '^': + $stack->push( pow( $op1, $op2 ) ); + break; + } + // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on + } elseif ( '_' === $token ) { + $stack->push( -1 * $stack->pop() ); + // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on + } elseif ( ! preg_match( "/^([a-z]\w*)\($/", $token, $matches ) ) { + if ( is_numeric( $token ) ) { + $stack->push( $token ); + } elseif ( array_key_exists( $token, self::$v ) ) { + $stack->push( self::$v[ $token ] ); + } elseif ( array_key_exists( $token, $vars ) ) { + $stack->push( $vars[ $token ] ); + } else { + return self::trigger( "undefined variable '$token'" ); + } + } + } + // when we're out of tokens, the stack should have a single element, the final result + if ( 1 != $stack->count ) { + return self::trigger( "internal error" ); + } + return $stack->pop(); + } + + /** + * Trigger an error, but nicely, if need be. + * + * @param string $msg + * + * @return bool + */ + private static function trigger( $msg ) { + self::$last_error = $msg; + if ( ! Constants::is_true( 'DOING_AJAX' ) && Constants::is_true( 'WP_DEBUG' ) ) { + echo "\nError found in:"; + self::debugPrintCallingFunction(); + trigger_error( $msg, E_USER_WARNING ); + } + return false; + } + + /** + * Prints the file name, function name, and + * line number which called your function + * (not this function, then one that called + * it to begin with) + */ + private static function debugPrintCallingFunction() { + $file = 'n/a'; + $func = 'n/a'; + $line = 'n/a'; + $debugTrace = debug_backtrace(); + if ( isset( $debugTrace[1] ) ) { + $file = $debugTrace[1]['file'] ? $debugTrace[1]['file'] : 'n/a'; + $line = $debugTrace[1]['line'] ? $debugTrace[1]['line'] : 'n/a'; + } + if ( isset( $debugTrace[2] ) ) { + $func = $debugTrace[2]['function'] ? $debugTrace[2]['function'] : 'n/a'; + } + echo "\n$file, $func, $line\n"; + } + } + + /** + * Class WC_Eval_Math_Stack. + */ + class WC_Eval_Math_Stack { + + /** + * Stack array. + * + * @var array + */ + public $stack = array(); + + /** + * Stack counter. + * + * @var integer + */ + public $count = 0; + + /** + * Push value into stack. + * + * @param mixed $val + */ + public function push( $val ) { + $this->stack[ $this->count ] = $val; + $this->count++; + } + + /** + * Pop value from stack. + * + * @return mixed + */ + public function pop() { + if ( $this->count > 0 ) { + $this->count--; + return $this->stack[ $this->count ]; + } + return null; + } + + /** + * Get last value from stack. + * + * @param int $n + * + * @return mixed + */ + public function last( $n=1 ) { + $key = $this->count - $n; + return array_key_exists( $key, $this->stack ) ? $this->stack[ $key ] : null; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/libraries/wp-async-request.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/libraries/wp-async-request.php new file mode 100644 index 0000000..320c93d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/libraries/wp-async-request.php @@ -0,0 +1,160 @@ +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(); + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/libraries/wp-background-process.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/libraries/wp-background-process.php new file mode 100644 index 0000000..7e3f101 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/libraries/wp-background-process.php @@ -0,0 +1,503 @@ +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 = $this->identifier . '_batch_%'; + + $count = $wpdb->get_var( $wpdb->prepare( " + SELECT COUNT(*) + FROM {$table} + WHERE {$column} LIKE %s + ", $key ) ); + + return ! ( $count > 0 ); + } + + /** + * 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 = $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 === $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', 'woocommerce' ), $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 ); + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-db.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-db.php new file mode 100644 index 0000000..ef96133 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-db.php @@ -0,0 +1,189 @@ +get_log_source(); + } + + return $this->add( $timestamp, $level, $message, $source, $context ); + } + + /** + * Add a log entry to chosen file. + * + * @param int $timestamp Log timestamp. + * @param string $level emergency|alert|critical|error|warning|notice|info|debug. + * @param string $message Log message. + * @param string $source Log source. Useful for filtering and sorting. + * @param array $context Context will be serialized and stored in database. + * + * @return bool True if write was successful. + */ + protected static function add( $timestamp, $level, $message, $source, $context ) { + global $wpdb; + + $insert = array( + 'timestamp' => date( 'Y-m-d H:i:s', $timestamp ), + 'level' => WC_Log_Levels::get_level_severity( $level ), + 'message' => $message, + 'source' => $source, + ); + + $format = array( + '%s', + '%d', + '%s', + '%s', + '%s', // possible serialized context. + ); + + if ( ! empty( $context ) ) { + $insert['context'] = serialize( $context ); // @codingStandardsIgnoreLine. + } + + return false !== $wpdb->insert( "{$wpdb->prefix}woocommerce_log", $insert, $format ); + } + + /** + * Clear all logs from the DB. + * + * @return bool True if flush was successful. + */ + public static function flush() { + global $wpdb; + + return $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_log" ); + } + + /** + * Clear entries for a chosen handle/source. + * + * @param string $source Log source. + * @return bool + */ + public function clear( $source ) { + global $wpdb; + + return $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_log WHERE source = %s", + $source + ) + ); + } + + /** + * Delete selected logs from DB. + * + * @param int|string|array $log_ids Log ID or array of Log IDs to be deleted. + * + * @return bool + */ + public static function delete( $log_ids ) { + global $wpdb; + + if ( ! is_array( $log_ids ) ) { + $log_ids = array( $log_ids ); + } + + $format = array_fill( 0, count( $log_ids ), '%d' ); + $query_in = '(' . implode( ',', $format ) . ')'; + return $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_log WHERE log_id IN {$query_in}", $log_ids ) ); // @codingStandardsIgnoreLine. + } + + /** + * Delete all logs older than a defined timestamp. + * + * @since 3.4.0 + * @param integer $timestamp Timestamp to delete logs before. + */ + public static function delete_logs_before_timestamp( $timestamp = 0 ) { + if ( ! $timestamp ) { + return; + } + + global $wpdb; + + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_log WHERE timestamp < %s", + date( 'Y-m-d H:i:s', $timestamp ) + ) + ); + } + + /** + * Get appropriate source based on file name. + * + * Try to provide an appropriate source in case none is provided. + * + * @return string Text to use as log source. "" (empty string) if none is found. + */ + protected static function get_log_source() { + static $ignore_files = array( 'class-wc-log-handler-db', 'class-wc-logger' ); + + /** + * PHP < 5.3.6 correct behavior + * + * @see http://php.net/manual/en/function.debug-backtrace.php#refsect1-function.debug-backtrace-parameters + */ + if ( Constants::is_defined( 'DEBUG_BACKTRACE_IGNORE_ARGS' ) ) { + $debug_backtrace_arg = DEBUG_BACKTRACE_IGNORE_ARGS; // phpcs:ignore PHPCompatibility.Constants.NewConstants.debug_backtrace_ignore_argsFound + } else { + $debug_backtrace_arg = false; + } + + $trace = debug_backtrace( $debug_backtrace_arg ); // @codingStandardsIgnoreLine. + foreach ( $trace as $t ) { + if ( isset( $t['file'] ) ) { + $filename = pathinfo( $t['file'], PATHINFO_FILENAME ); + if ( ! in_array( $filename, $ignore_files, true ) ) { + return $filename; + } + } + } + + return ''; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-email.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-email.php new file mode 100644 index 0000000..d3d6a68 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-email.php @@ -0,0 +1,226 @@ +add_email( $recipient ); + } + } else { + $this->add_email( $recipients ); + } + + $this->set_threshold( $threshold ); + add_action( 'shutdown', array( $this, 'send_log_email' ) ); + } + + /** + * Set handler severity threshold. + * + * @param string $level emergency|alert|critical|error|warning|notice|info|debug. + */ + public function set_threshold( $level ) { + $this->threshold = WC_Log_Levels::get_level_severity( $level ); + } + + /** + * Determine whether handler should handle log. + * + * @param string $level emergency|alert|critical|error|warning|notice|info|debug. + * @return bool True if the log should be handled. + */ + protected function should_handle( $level ) { + return $this->threshold <= WC_Log_Levels::get_level_severity( $level ); + } + + /** + * Handle a log entry. + * + * @param int $timestamp Log timestamp. + * @param string $level emergency|alert|critical|error|warning|notice|info|debug. + * @param string $message Log message. + * @param array $context Optional. Additional information for log handlers. + * + * @return bool False if value was not handled and true if value was handled. + */ + public function handle( $timestamp, $level, $message, $context ) { + + if ( $this->should_handle( $level ) ) { + $this->add_log( $timestamp, $level, $message, $context ); + return true; + } + + return false; + } + + /** + * Send log email. + * + * @return bool True if email is successfully sent otherwise false. + */ + public function send_log_email() { + $result = false; + + if ( ! empty( $this->logs ) ) { + $subject = $this->get_subject(); + $body = $this->get_body(); + $result = wp_mail( $this->recipients, $subject, $body ); + $this->clear_logs(); + } + + return $result; + } + + /** + * Build subject for log email. + * + * @return string subject + */ + protected function get_subject() { + $site_name = get_bloginfo( 'name' ); + $max_level = strtoupper( WC_Log_Levels::get_severity_level( $this->max_severity ) ); + $log_count = count( $this->logs ); + + return sprintf( + /* translators: 1: Site name 2: Maximum level 3: Log count */ + _n( + '[%1$s] %2$s: %3$s WooCommerce log message', + '[%1$s] %2$s: %3$s WooCommerce log messages', + $log_count, + 'woocommerce' + ), + $site_name, + $max_level, + $log_count + ); + } + + /** + * Build body for log email. + * + * @return string body + */ + protected function get_body() { + $site_name = get_bloginfo( 'name' ); + $entries = implode( PHP_EOL, $this->logs ); + $log_count = count( $this->logs ); + return _n( + 'You have received the following WooCommerce log message:', + 'You have received the following WooCommerce log messages:', + $log_count, + 'woocommerce' + ) . PHP_EOL + . PHP_EOL + . $entries + . PHP_EOL + . PHP_EOL + /* translators: %s: Site name */ + . sprintf( __( 'Visit %s admin area:', 'woocommerce' ), $site_name ) + . PHP_EOL + . admin_url(); + } + + /** + * Adds an email to the list of recipients. + * + * @param string $email Email address to add. + */ + public function add_email( $email ) { + array_push( $this->recipients, $email ); + } + + /** + * Add log message. + * + * @param int $timestamp Log timestamp. + * @param string $level emergency|alert|critical|error|warning|notice|info|debug. + * @param string $message Log message. + * @param array $context Additional information for log handlers. + */ + protected function add_log( $timestamp, $level, $message, $context ) { + $this->logs[] = $this->format_entry( $timestamp, $level, $message, $context ); + + $log_severity = WC_Log_Levels::get_level_severity( $level ); + if ( $this->max_severity < $log_severity ) { + $this->max_severity = $log_severity; + } + } + + /** + * Clear log messages. + */ + protected function clear_logs() { + $this->logs = array(); + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php new file mode 100644 index 0000000..0fc59a3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php @@ -0,0 +1,444 @@ +log_size_limit = apply_filters( 'woocommerce_log_file_size_limit', $log_size_limit ); + + add_action( 'plugins_loaded', array( $this, 'write_cached_logs' ) ); + } + + /** + * Destructor. + * + * Cleans up open file handles. + */ + public function __destruct() { + foreach ( $this->handles as $handle ) { + if ( is_resource( $handle ) ) { + fclose( $handle ); // @codingStandardsIgnoreLine. + } + } + } + + /** + * Handle a log entry. + * + * @param int $timestamp Log timestamp. + * @param string $level emergency|alert|critical|error|warning|notice|info|debug. + * @param string $message Log message. + * @param array $context { + * Additional information for log handlers. + * + * @type string $source Optional. Determines log file to write to. Default 'log'. + * @type bool $_legacy Optional. Default false. True to use outdated log format + * originally used in deprecated WC_Logger::add calls. + * } + * + * @return bool False if value was not handled and true if value was handled. + */ + public function handle( $timestamp, $level, $message, $context ) { + + if ( isset( $context['source'] ) && $context['source'] ) { + $handle = $context['source']; + } else { + $handle = 'log'; + } + + $entry = self::format_entry( $timestamp, $level, $message, $context ); + + return $this->add( $entry, $handle ); + } + + /** + * Builds a log entry text from timestamp, level and message. + * + * @param int $timestamp Log timestamp. + * @param string $level emergency|alert|critical|error|warning|notice|info|debug. + * @param string $message Log message. + * @param array $context Additional information for log handlers. + * + * @return string Formatted log entry. + */ + protected static function format_entry( $timestamp, $level, $message, $context ) { + + if ( isset( $context['_legacy'] ) && true === $context['_legacy'] ) { + if ( isset( $context['source'] ) && $context['source'] ) { + $handle = $context['source']; + } else { + $handle = 'log'; + } + $message = apply_filters( 'woocommerce_logger_add_message', $message, $handle ); + $time = date_i18n( 'm-d-Y @ H:i:s' ); + $entry = "{$time} - {$message}"; + } else { + $entry = parent::format_entry( $timestamp, $level, $message, $context ); + } + + return $entry; + } + + /** + * Open log file for writing. + * + * @param string $handle Log handle. + * @param string $mode Optional. File mode. Default 'a'. + * @return bool Success. + */ + protected function open( $handle, $mode = 'a' ) { + if ( $this->is_open( $handle ) ) { + return true; + } + + $file = self::get_log_file_path( $handle ); + + if ( $file ) { + if ( ! file_exists( $file ) ) { + $temphandle = @fopen( $file, 'w+' ); // @codingStandardsIgnoreLine. + @fclose( $temphandle ); // @codingStandardsIgnoreLine. + + if ( Constants::is_defined( 'FS_CHMOD_FILE' ) ) { + @chmod( $file, FS_CHMOD_FILE ); // @codingStandardsIgnoreLine. + } + } + + $resource = @fopen( $file, $mode ); // @codingStandardsIgnoreLine. + + if ( $resource ) { + $this->handles[ $handle ] = $resource; + return true; + } + } + + return false; + } + + /** + * Check if a handle is open. + * + * @param string $handle Log handle. + * @return bool True if $handle is open. + */ + protected function is_open( $handle ) { + return array_key_exists( $handle, $this->handles ) && is_resource( $this->handles[ $handle ] ); + } + + /** + * Close a handle. + * + * @param string $handle Log handle. + * @return bool success + */ + protected function close( $handle ) { + $result = false; + + if ( $this->is_open( $handle ) ) { + $result = fclose( $this->handles[ $handle ] ); // @codingStandardsIgnoreLine. + unset( $this->handles[ $handle ] ); + } + + return $result; + } + + /** + * Add a log entry to chosen file. + * + * @param string $entry Log entry text. + * @param string $handle Log entry handle. + * + * @return bool True if write was successful. + */ + protected function add( $entry, $handle ) { + $result = false; + + if ( $this->should_rotate( $handle ) ) { + $this->log_rotate( $handle ); + } + + if ( $this->open( $handle ) && is_resource( $this->handles[ $handle ] ) ) { + $result = fwrite( $this->handles[ $handle ], $entry . PHP_EOL ); // @codingStandardsIgnoreLine. + } else { + $this->cache_log( $entry, $handle ); + } + + return false !== $result; + } + + /** + * Clear entries from chosen file. + * + * @param string $handle Log handle. + * + * @return bool + */ + public function clear( $handle ) { + $result = false; + + // Close the file if it's already open. + $this->close( $handle ); + + /** + * $this->open( $handle, 'w' ) == Open the file for writing only. Place the file pointer at + * the beginning of the file, and truncate the file to zero length. + */ + if ( $this->open( $handle, 'w' ) && is_resource( $this->handles[ $handle ] ) ) { + $result = true; + } + + do_action( 'woocommerce_log_clear', $handle ); + + return $result; + } + + /** + * Remove/delete the chosen file. + * + * @param string $handle Log handle. + * + * @return bool + */ + public function remove( $handle ) { + $removed = false; + $logs = $this->get_log_files(); + $handle = sanitize_title( $handle ); + + if ( isset( $logs[ $handle ] ) && $logs[ $handle ] ) { + $file = realpath( trailingslashit( WC_LOG_DIR ) . $logs[ $handle ] ); + if ( 0 === stripos( $file, realpath( trailingslashit( WC_LOG_DIR ) ) ) && is_file( $file ) && is_writable( $file ) ) { // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writable + $this->close( $file ); // Close first to be certain no processes keep it alive after it is unlinked. + $removed = unlink( $file ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink + } + do_action( 'woocommerce_log_remove', $handle, $removed ); + } + return $removed; + } + + /** + * Check if log file should be rotated. + * + * Compares the size of the log file to determine whether it is over the size limit. + * + * @param string $handle Log handle. + * @return bool True if if should be rotated. + */ + protected function should_rotate( $handle ) { + $file = self::get_log_file_path( $handle ); + if ( $file ) { + if ( $this->is_open( $handle ) ) { + $file_stat = fstat( $this->handles[ $handle ] ); + return $file_stat['size'] > $this->log_size_limit; + } elseif ( file_exists( $file ) ) { + return filesize( $file ) > $this->log_size_limit; + } else { + return false; + } + } else { + return false; + } + } + + /** + * Rotate log files. + * + * Logs are rotated by prepending '.x' to the '.log' suffix. + * The current log plus 10 historical logs are maintained. + * For example: + * base.9.log -> [ REMOVED ] + * base.8.log -> base.9.log + * ... + * base.0.log -> base.1.log + * base.log -> base.0.log + * + * @param string $handle Log handle. + */ + protected function log_rotate( $handle ) { + for ( $i = 8; $i >= 0; $i-- ) { + $this->increment_log_infix( $handle, $i ); + } + $this->increment_log_infix( $handle ); + } + + /** + * Increment a log file suffix. + * + * @param string $handle Log handle. + * @param null|int $number Optional. Default null. Log suffix number to be incremented. + * @return bool True if increment was successful, otherwise false. + */ + protected function increment_log_infix( $handle, $number = null ) { + if ( null === $number ) { + $suffix = ''; + $next_suffix = '.0'; + } else { + $suffix = '.' . $number; + $next_suffix = '.' . ( $number + 1 ); + } + + $rename_from = self::get_log_file_path( "{$handle}{$suffix}" ); + $rename_to = self::get_log_file_path( "{$handle}{$next_suffix}" ); + + if ( $this->is_open( $rename_from ) ) { + $this->close( $rename_from ); + } + + if ( is_writable( $rename_from ) ) { // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writable + return rename( $rename_from, $rename_to ); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_rename + } else { + return false; + } + + } + + /** + * Get a log file path. + * + * @param string $handle Log name. + * @return bool|string The log file path or false if path cannot be determined. + */ + public static function get_log_file_path( $handle ) { + if ( function_exists( 'wp_hash' ) ) { + return trailingslashit( WC_LOG_DIR ) . self::get_log_file_name( $handle ); + } else { + wc_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woocommerce' ), '3.0' ); + return false; + } + } + + /** + * Get a log file name. + * + * File names consist of the handle, followed by the date, followed by a hash, .log. + * + * @since 3.3 + * @param string $handle Log name. + * @return bool|string The log file name or false if cannot be determined. + */ + public static function get_log_file_name( $handle ) { + if ( function_exists( 'wp_hash' ) ) { + $date_suffix = date( 'Y-m-d', time() ); + $hash_suffix = wp_hash( $handle ); + return sanitize_file_name( implode( '-', array( $handle, $date_suffix, $hash_suffix ) ) . '.log' ); + } else { + wc_doing_it_wrong( __METHOD__, __( 'This method should not be called before plugins_loaded.', 'woocommerce' ), '3.3' ); + return false; + } + } + + /** + * Cache log to write later. + * + * @param string $entry Log entry text. + * @param string $handle Log entry handle. + */ + protected function cache_log( $entry, $handle ) { + $this->cached_logs[] = array( + 'entry' => $entry, + 'handle' => $handle, + ); + } + + /** + * Write cached logs. + */ + public function write_cached_logs() { + foreach ( $this->cached_logs as $log ) { + $this->add( $log['entry'], $log['handle'] ); + } + } + + /** + * Delete all logs older than a defined timestamp. + * + * @since 3.4.0 + * @param integer $timestamp Timestamp to delete logs before. + */ + public static function delete_logs_before_timestamp( $timestamp = 0 ) { + if ( ! $timestamp ) { + return; + } + + $log_files = self::get_log_files(); + + foreach ( $log_files as $log_file ) { + $last_modified = filemtime( trailingslashit( WC_LOG_DIR ) . $log_file ); + + if ( $last_modified < $timestamp ) { + @unlink( trailingslashit( WC_LOG_DIR ) . $log_file ); // @codingStandardsIgnoreLine. + } + } + } + + /** + * Get all log files in the log directory. + * + * @since 3.4.0 + * @return array + */ + public static function get_log_files() { + $files = @scandir( WC_LOG_DIR ); // @codingStandardsIgnoreLine. + $result = array(); + + if ( ! empty( $files ) ) { + foreach ( $files as $key => $value ) { + if ( ! in_array( $value, array( '.', '..' ), true ) ) { + if ( ! is_dir( $value ) && strstr( $value, '.log' ) ) { + $result[ sanitize_title( $value ) ] = $value; + } + } + } + } + + return $result; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/payment-tokens/class-wc-payment-token-cc.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/payment-tokens/class-wc-payment-token-cc.php new file mode 100644 index 0000000..f658389 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/payment-tokens/class-wc-payment-token-cc.php @@ -0,0 +1,198 @@ + '', + 'expiry_year' => '', + 'expiry_month' => '', + 'card_type' => '', + ); + + /** + * Get type to display to user. + * + * @since 2.6.0 + * @param string $deprecated Deprecated since WooCommerce 3.0. + * @return string + */ + public function get_display_name( $deprecated = '' ) { + $display = sprintf( + /* translators: 1: credit card type 2: last 4 digits 3: expiry month 4: expiry year */ + __( '%1$s ending in %2$s (expires %3$s/%4$s)', 'woocommerce' ), + wc_get_credit_card_type_label( $this->get_card_type() ), + $this->get_last4(), + $this->get_expiry_month(), + substr( $this->get_expiry_year(), 2 ) + ); + return $display; + } + + /** + * Hook prefix + * + * @since 3.0.0 + */ + protected function get_hook_prefix() { + return 'woocommerce_payment_token_cc_get_'; + } + + /** + * Validate credit card payment tokens. + * + * These fields are required by all credit card payment tokens: + * expiry_month - string Expiration date (MM) for the card + * expiry_year - string Expiration date (YYYY) for the card + * last4 - string Last 4 digits of the card + * card_type - string Card type (visa, mastercard, etc) + * + * @since 2.6.0 + * @return boolean True if the passed data is valid + */ + public function validate() { + if ( false === parent::validate() ) { + return false; + } + + if ( ! $this->get_last4( 'edit' ) ) { + return false; + } + + if ( ! $this->get_expiry_year( 'edit' ) ) { + return false; + } + + if ( ! $this->get_expiry_month( 'edit' ) ) { + return false; + } + + if ( ! $this->get_card_type( 'edit' ) ) { + return false; + } + + if ( 4 !== strlen( $this->get_expiry_year( 'edit' ) ) ) { + return false; + } + + if ( 2 !== strlen( $this->get_expiry_month( 'edit' ) ) ) { + return false; + } + + return true; + } + + /** + * Returns the card type (mastercard, visa, ...). + * + * @since 2.6.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return string Card type + */ + public function get_card_type( $context = 'view' ) { + return $this->get_prop( 'card_type', $context ); + } + + /** + * Set the card type (mastercard, visa, ...). + * + * @since 2.6.0 + * @param string $type Credit card type (mastercard, visa, ...). + */ + public function set_card_type( $type ) { + $this->set_prop( 'card_type', $type ); + } + + /** + * Returns the card expiration year (YYYY). + * + * @since 2.6.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return string Expiration year + */ + public function get_expiry_year( $context = 'view' ) { + return $this->get_prop( 'expiry_year', $context ); + } + + /** + * Set the expiration year for the card (YYYY format). + * + * @since 2.6.0 + * @param string $year Credit card expiration year. + */ + public function set_expiry_year( $year ) { + $this->set_prop( 'expiry_year', $year ); + } + + /** + * Returns the card expiration month (MM). + * + * @since 2.6.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return string Expiration month + */ + public function get_expiry_month( $context = 'view' ) { + return $this->get_prop( 'expiry_month', $context ); + } + + /** + * Set the expiration month for the card (formats into MM format). + * + * @since 2.6.0 + * @param string $month Credit card expiration month. + */ + public function set_expiry_month( $month ) { + $this->set_prop( 'expiry_month', str_pad( $month, 2, '0', STR_PAD_LEFT ) ); + } + + /** + * Returns the last four digits. + * + * @since 2.6.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return string Last 4 digits + */ + public function get_last4( $context = 'view' ) { + return $this->get_prop( 'last4', $context ); + } + + /** + * Set the last four digits. + * + * @since 2.6.0 + * @param string $last4 Credit card last four digits. + */ + public function set_last4( $last4 ) { + $this->set_prop( 'last4', $last4 ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/payment-tokens/class-wc-payment-token-echeck.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/payment-tokens/class-wc-payment-token-echeck.php new file mode 100644 index 0000000..4e1e21e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/payment-tokens/class-wc-payment-token-echeck.php @@ -0,0 +1,105 @@ + '', + ); + + /** + * Get type to display to user. + * + * @since 2.6.0 + * @param string $deprecated Deprecated since WooCommerce 3.0. + * @return string + */ + public function get_display_name( $deprecated = '' ) { + $display = sprintf( + /* translators: 1: last 4 digits */ + __( 'eCheck ending in %1$s', 'woocommerce' ), + $this->get_last4() + ); + return $display; + } + + /** + * Hook prefix + * + * @since 3.0.0 + */ + protected function get_hook_prefix() { + return 'woocommerce_payment_token_echeck_get_'; + } + + /** + * Validate eCheck payment tokens. + * + * These fields are required by all eCheck payment tokens: + * last4 - string Last 4 digits of the check + * + * @since 2.6.0 + * @return boolean True if the passed data is valid + */ + public function validate() { + if ( false === parent::validate() ) { + return false; + } + + if ( ! $this->get_last4( 'edit' ) ) { + return false; + } + return true; + } + + /** + * Returns the last four digits. + * + * @since 2.6.0 + * @param string $context What the value is for. Valid values are view and edit. + * @return string Last 4 digits + */ + public function get_last4( $context = 'view' ) { + return $this->get_prop( 'last4', $context ); + } + + /** + * Set the last four digits. + * + * @since 2.6.0 + * @param string $last4 eCheck last four digits. + */ + public function set_last4( $last4 ) { + $this->set_prop( 'last4', $last4 ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/queue/class-wc-action-queue.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/queue/class-wc-action-queue.php new file mode 100644 index 0000000..702861f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/queue/class-wc-action-queue.php @@ -0,0 +1,160 @@ +schedule_single( time(), $hook, $args, $group ); + } + + /** + * Schedule an action to run once at some time in the future + * + * @param int $timestamp When the job will run. + * @param string $hook The hook to trigger. + * @param array $args Arguments to pass when the hook triggers. + * @param string $group The group to assign this job to. + * @return string The action ID. + */ + public function schedule_single( $timestamp, $hook, $args = array(), $group = '' ) { + return as_schedule_single_action( $timestamp, $hook, $args, $group ); + } + + /** + * Schedule a recurring action + * + * @param int $timestamp When the first instance of the job will run. + * @param int $interval_in_seconds How long to wait between runs. + * @param string $hook The hook to trigger. + * @param array $args Arguments to pass when the hook triggers. + * @param string $group The group to assign this job to. + * @return string The action ID. + */ + public function schedule_recurring( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '' ) { + return as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args, $group ); + } + + /** + * Schedule an action that recurs on a cron-like schedule. + * + * @param int $timestamp The schedule will start on or after this time. + * @param string $cron_schedule A cron-link schedule string. + * @see http://en.wikipedia.org/wiki/Cron + * * * * * * * + * ┬ ┬ ┬ ┬ ┬ ┬ + * | | | | | | + * | | | | | + year [optional] + * | | | | +----- day of week (0 - 7) (Sunday=0 or 7) + * | | | +---------- month (1 - 12) + * | | +--------------- day of month (1 - 31) + * | +-------------------- hour (0 - 23) + * +------------------------- min (0 - 59) + * @param string $hook The hook to trigger. + * @param array $args Arguments to pass when the hook triggers. + * @param string $group The group to assign this job to. + * @return string The action ID + */ + public function schedule_cron( $timestamp, $cron_schedule, $hook, $args = array(), $group = '' ) { + return as_schedule_cron_action( $timestamp, $cron_schedule, $hook, $args, $group ); + } + + /** + * Dequeue the next scheduled instance of an action with a matching hook (and optionally matching args and group). + * + * Any recurring actions with a matching hook should also be cancelled, not just the next scheduled action. + * + * While technically only the next instance of a recurring or cron action is unscheduled by this method, that will also + * prevent all future instances of that recurring or cron action from being run. Recurring and cron actions are scheduled + * in a sequence instead of all being scheduled at once. Each successive occurrence of a recurring action is scheduled + * only after the former action is run. As the next instance is never run, because it's unscheduled by this function, + * then the following instance will never be scheduled (or exist), which is effectively the same as being unscheduled + * by this method also. + * + * @param string $hook The hook that the job will trigger. + * @param array $args Args that would have been passed to the job. + * @param string $group The group the job is assigned to (if any). + */ + public function cancel( $hook, $args = array(), $group = '' ) { + as_unschedule_action( $hook, $args, $group ); + } + + /** + * Dequeue all actions with a matching hook (and optionally matching args and group) so no matching actions are ever run. + * + * @param string $hook The hook that the job will trigger. + * @param array $args Args that would have been passed to the job. + * @param string $group The group the job is assigned to (if any). + */ + public function cancel_all( $hook, $args = array(), $group = '' ) { + as_unschedule_all_actions( $hook, $args, $group ); + } + + /** + * Get the date and time for the next scheduled occurence of an action with a given hook + * (an optionally that matches certain args and group), if any. + * + * @param string $hook The hook that the job will trigger. + * @param array $args Filter to a hook with matching args that will be passed to the job when it runs. + * @param string $group Filter to only actions assigned to a specific group. + * @return WC_DateTime|null The date and time for the next occurrence, or null if there is no pending, scheduled action for the given hook. + */ + public function get_next( $hook, $args = null, $group = '' ) { + + $next_timestamp = as_next_scheduled_action( $hook, $args, $group ); + + if ( $next_timestamp ) { + return new WC_DateTime( "@{$next_timestamp}", new DateTimeZone( 'UTC' ) ); + } + + return null; + } + + /** + * Find scheduled actions + * + * @param array $args Possible arguments, with their default values: + * 'hook' => '' - the name of the action that will be triggered + * 'args' => null - the args array that will be passed with the action + * 'date' => null - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. + * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '=' + * 'modified' => null - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. + * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '=' + * 'group' => '' - the group the action belongs to + * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING + * 'claimed' => null - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID + * 'per_page' => 5 - Number of results to return + * 'offset' => 0 + * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date' + * 'order' => 'ASC'. + * + * @param string $return_format OBJECT, ARRAY_A, or ids. + * @return array + */ + public function search( $args = array(), $return_format = OBJECT ) { + return as_get_scheduled_actions( $args, $return_format ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/queue/class-wc-queue.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/queue/class-wc-queue.php new file mode 100644 index 0000000..80dd4b6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/queue/class-wc-queue.php @@ -0,0 +1,82 @@ +post_type}_query", array( $this, 'query_args' ), 10, 2 ); + } + + /** + * Register the routes for coupons. + */ + 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' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'required' => true, + 'type' => 'string', + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Query args. + * + * @param array $args Query args + * @param WP_REST_Request $request Request data. + * @return array + */ + public function query_args( $args, $request ) { + if ( ! empty( $request['code'] ) ) { + $id = wc_get_coupon_id_by_code( $request['code'] ); + $args['post__in'] = array( $id ); + } + + return $args; + } + + /** + * Prepare a single coupon output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $data + */ + public function prepare_item_for_response( $post, $request ) { + $coupon = new WC_Coupon( (int) $post->ID ); + $_data = $coupon->get_data(); + + $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); + $format_date = array( 'date_created', 'date_modified' ); + $format_date_utc = array( 'date_expires' ); + $format_null = array( 'usage_limit', 'usage_limit_per_user' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $_data[ $key ] = wc_format_decimal( $_data[ $key ], 2 ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ], false ) : null; + } + foreach ( $format_date_utc as $key ) { + $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; + } + + // Format null values. + foreach ( $format_null as $key ) { + $_data[ $key ] = $_data[ $key ] ? $_data[ $key ] : null; + } + + $data = array( + 'id' => $_data['id'], + 'code' => $_data['code'], + 'date_created' => $_data['date_created'], + 'date_modified' => $_data['date_modified'], + 'discount_type' => $_data['discount_type'], + 'description' => $_data['description'], + 'amount' => $_data['amount'], + 'expiry_date' => $_data['date_expires'], + 'usage_count' => $_data['usage_count'], + 'individual_use' => $_data['individual_use'], + 'product_ids' => $_data['product_ids'], + 'exclude_product_ids' => $_data['excluded_product_ids'], + 'usage_limit' => $_data['usage_limit'], + 'usage_limit_per_user' => $_data['usage_limit_per_user'], + 'limit_usage_to_x_items' => $_data['limit_usage_to_x_items'], + 'free_shipping' => $_data['free_shipping'], + 'product_categories' => $_data['product_categories'], + 'excluded_product_categories' => $_data['excluded_product_categories'], + 'exclude_sale_items' => $_data['exclude_sale_items'], + 'minimum_amount' => $_data['minimum_amount'], + 'maximum_amount' => $_data['maximum_amount'], + 'email_restrictions' => $_data['email_restrictions'], + 'used_by' => $_data['used_by'], + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $post, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Only return writable props from schema. + * @param array $schema + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Prepare a single coupon for create or update. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $coupon = new WC_Coupon( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Update to schema to make compatible with CRUD schema. + if ( $request['exclude_product_ids'] ) { + $request['excluded_product_ids'] = $request['exclude_product_ids']; + } + if ( $request['expiry_date'] ) { + $request['date_expires'] = $request['expiry_date']; + } + + // Validate required POST fields. + if ( 'POST' === $request->get_method() && 0 === $coupon->get_id() ) { + if ( empty( $request['code'] ) ) { + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + } + } + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'code' : + $coupon_code = wc_format_coupon_code( $value ); + $id = $coupon->get_id() ? $coupon->get_id() : 0; + $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); + + if ( $id_from_code ) { + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon->set_code( $coupon_code ); + break; + case 'description' : + $coupon->set_description( wp_filter_post_kses( $value ) ); + break; + case 'expiry_date' : + $coupon->set_date_expires( $value ); + break; + default : + if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { + $coupon->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param WC_Coupon $coupon The coupon object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $coupon, $request ); + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $coupon_id = $this->save_coupon( $request ); + if ( is_wp_error( $coupon_id ) ) { + return $coupon_id; + } + + $post = get_post( $coupon_id ); + $this->update_additional_fields_for_object( $post, $request ); + + $this->add_post_meta_fields( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } + + /** + * Update a single coupon. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + try { + $post_id = (int) $request['id']; + + if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon_id = $this->save_coupon( $request ); + if ( is_wp_error( $coupon_id ) ) { + return $coupon_id; + } + + $post = get_post( $coupon_id ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Saves a coupon to the database. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|int + */ + protected function save_coupon( $request ) { + try { + $coupon = $this->prepare_item_for_database( $request ); + + if ( is_wp_error( $coupon ) ) { + return $coupon; + } + + $coupon->save(); + return $coupon->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the Coupon's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Coupon description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'discount_type' => array( + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'fixed_cart', + 'enum' => array_keys( wc_get_coupon_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'amount' => array( + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'expiry_date' => array( + 'description' => __( 'UTC DateTime when the coupon expires.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'usage_count' => array( + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'individual_use' => array( + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_ids' => array( + 'description' => __( "List of product IDs the coupon can be used on.", 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'exclude_product_ids' => array( + 'description' => __( "List of product IDs the coupon cannot be used on.", 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit' => array( + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit_per_user' => array( + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'limit_usage_to_x_items' => array( + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'free_shipping' => array( + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_categories' => array( + 'description' => __( "List of category IDs the coupon applies to.", 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'excluded_product_categories' => array( + 'description' => __( "List of category IDs the coupon does not apply to.", 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'exclude_sale_items' => array( + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'minimum_amount' => array( + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'maximum_amount' => array( + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email_restrictions' => array( + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'context' => array( 'view', 'edit' ), + ), + 'used_by' => array( + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['code'] = array( + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php new file mode 100644 index 0000000..6b0511f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php @@ -0,0 +1,252 @@ +/downloads endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Customers controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Controller + */ +class WC_REST_Customer_Downloads_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'customers/(?P[\d]+)/downloads'; + + /** + * Register the routes for customers. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'customer_id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read customers. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $customer = get_user_by( 'id', (int) $request['customer_id'] ); + + if ( ! $customer ) { + return new WP_Error( 'woocommerce_rest_customer_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_user_permissions( 'read', $customer->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all customer downloads. + * + * @param WP_REST_Request $request + * @return array + */ + public function get_items( $request ) { + $downloads = wc_get_customer_available_downloads( (int) $request['customer_id'] ); + + $data = array(); + foreach ( $downloads as $download_data ) { + $download = $this->prepare_item_for_response( (object) $download_data, $request ); + $download = $this->prepare_response_for_collection( $download ); + $data[] = $download; + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a single download output for response. + * + * @param stdObject $download Download object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $download, $request ) { + $data = (array) $download; + $data['access_expires'] = $data['access_expires'] ? wc_rest_prepare_date_response( $data['access_expires'] ) : 'never'; + $data['downloads_remaining'] = '' === $data['downloads_remaining'] ? 'unlimited' : $data['downloads_remaining']; + + // Remove "product_name" since it's new in 3.0. + unset( $data['product_name'] ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $download, $request ) ); + + /** + * Filter customer download data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdObject $download Download object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); + } + + /** + * Prepare links for the request. + * + * @param stdClass $download Download object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given customer download. + */ + protected function prepare_links( $download, $request ) { + $base = str_replace( '(?P[\d]+)', $request['customer_id'], $this->rest_base ); + $links = array( + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'product' => array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $download->product_id ) ), + ), + 'order' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $download->order_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Customer Download's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer_download', + 'type' => 'object', + 'properties' => array( + 'download_url' => array( + 'description' => __( 'Download file URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_id' => array( + 'description' => __( 'Download ID (MD5).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Downloadable product ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_name' => array( + 'description' => __( 'Downloadable file name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_id' => array( + 'description' => __( 'Order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'downloads_remaining' => array( + 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'access_expires' => array( + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File details.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php new file mode 100644 index 0000000..8a07bb3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php @@ -0,0 +1,924 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'New user email address.', 'woocommerce' ), + ), + 'username' => array( + 'required' => 'no' === get_option( 'woocommerce_registration_generate_username', 'yes' ), + 'description' => __( 'New user username.', 'woocommerce' ), + 'type' => 'string', + ), + 'password' => array( + 'required' => 'no' === get_option( 'woocommerce_registration_generate_password', 'no' ), + 'description' => __( 'New user password.', 'woocommerce' ), + 'type' => 'string', + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + 'reassign' => array( + 'default' => 0, + 'type' => 'integer', + 'description' => __( 'ID to reassign posts to.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read customers. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_user_permissions( 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create customers. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_user_permissions( 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $id = (int) $request['id']; + + if ( ! wc_rest_check_user_permissions( 'read', $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access update a customer. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function update_item_permissions_check( $request ) { + $id = (int) $request['id']; + + if ( ! wc_rest_check_user_permissions( 'edit', $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a customer. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $id = (int) $request['id']; + + if ( ! wc_rest_check_user_permissions( 'delete', $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_user_permissions( 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all customers. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $prepared_args = array(); + $prepared_args['exclude'] = $request['exclude']; + $prepared_args['include'] = $request['include']; + $prepared_args['order'] = $request['order']; + $prepared_args['number'] = $request['per_page']; + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + $orderby_possibles = array( + 'id' => 'ID', + 'include' => 'include', + 'name' => 'display_name', + 'registered_date' => 'registered', + ); + $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; + $prepared_args['search'] = $request['search']; + + if ( '' !== $prepared_args['search'] ) { + $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; + } + + // Filter by email. + if ( ! empty( $request['email'] ) ) { + $prepared_args['search'] = $request['email']; + $prepared_args['search_columns'] = array( 'user_email' ); + } + + // Filter by role. + if ( 'all' !== $request['role'] ) { + $prepared_args['role'] = $request['role']; + } + + /** + * Filter arguments, before passing to WP_User_Query, when querying users via the REST API. + * + * @see https://developer.wordpress.org/reference/classes/wp_user_query/ + * + * @param array $prepared_args Array of arguments for WP_User_Query. + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_customer_query', $prepared_args, $request ); + + $query = new WP_User_Query( $prepared_args ); + + $users = array(); + foreach ( $query->results as $user ) { + $data = $this->prepare_item_for_response( $user, $request ); + $users[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $users ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + $prepared_args['fields'] = 'ID'; + + $total_users = $query->get_total(); + if ( $total_users < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $prepared_args['number'] ); + unset( $prepared_args['offset'] ); + $count_query = new WP_User_Query( $prepared_args ); + $total_users = $count_query->get_total(); + } + $response->header( 'X-WP-Total', (int) $total_users ); + $max_pages = ceil( $total_users / $per_page ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); + if ( $page > 1 ) { + $prev_page = $page - 1; + if ( $prev_page > $max_pages ) { + $prev_page = $max_pages; + } + $prev_link = add_query_arg( 'page', $prev_page, $base ); + $response->link_header( 'prev', $prev_link ); + } + if ( $max_pages > $page ) { + $next_page = $page + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Create a single customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + try { + if ( ! empty( $request['id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_customer_exists', __( 'Cannot create existing resource.', 'woocommerce' ), 400 ); + } + + // Sets the username. + $request['username'] = ! empty( $request['username'] ) ? $request['username'] : ''; + + // Sets the password. + $request['password'] = ! empty( $request['password'] ) ? $request['password'] : ''; + + // Create customer. + $customer = new WC_Customer; + $customer->set_username( $request['username'] ); + $customer->set_password( $request['password'] ); + $customer->set_email( $request['email'] ); + $this->update_customer_meta_fields( $customer, $request ); + $customer->save(); + + if ( ! $customer->get_id() ) { + throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); + } + + $user_data = get_userdata( $customer->get_id() ); + $this->update_additional_fields_for_object( $user_data, $request ); + + /** + * Fires after a customer is created or updated via the REST API. + * + * @param WP_User $user_data Data used to create the customer. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating customer, false when updating customer. + */ + do_action( 'woocommerce_rest_insert_customer', $user_data, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $user_data, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->get_id() ) ) ); + + return $response; + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get a single customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $user_data = get_userdata( $id ); + + if ( empty( $id ) || empty( $user_data->ID ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $customer = $this->prepare_item_for_response( $user_data, $request ); + $response = rest_ensure_response( $customer ); + + return $response; + } + + /** + * Update a single user. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + try { + $id = (int) $request['id']; + $customer = new WC_Customer( $id ); + + if ( ! $customer->get_id() ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), 400 ); + } + + if ( ! empty( $request['email'] ) && email_exists( $request['email'] ) && $request['email'] !== $customer->get_email() ) { + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_email', __( 'Email address is invalid.', 'woocommerce' ), 400 ); + } + + if ( ! empty( $request['username'] ) && $request['username'] !== $customer->get_username() ) { + throw new WC_REST_Exception( 'woocommerce_rest_customer_invalid_argument', __( "Username isn't editable.", 'woocommerce' ), 400 ); + } + + // Customer email. + if ( isset( $request['email'] ) ) { + $customer->set_email( sanitize_email( $request['email'] ) ); + } + + // Customer password. + if ( isset( $request['password'] ) ) { + $customer->set_password( $request['password'] ); + } + + $this->update_customer_meta_fields( $customer, $request ); + $customer->save(); + + $user_data = get_userdata( $customer->get_id() ); + $this->update_additional_fields_for_object( $user_data, $request ); + + if ( ! is_user_member_of_blog( $user_data->ID ) ) { + $user_data->add_role( 'customer' ); + } + + /** + * Fires after a customer is created or updated via the REST API. + * + * @param WP_User $customer Data used to create the customer. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating customer, false when updating customer. + */ + do_action( 'woocommerce_rest_insert_customer', $user_data, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $user_data, $request ); + $response = rest_ensure_response( $response ); + return $response; + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Delete a single customer. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $reassign = isset( $request['reassign'] ) ? absint( $request['reassign'] ) : null; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Customers do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $user_data = get_userdata( $id ); + if ( ! $user_data ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + if ( ! empty( $reassign ) ) { + if ( $reassign === $id || ! get_userdata( $reassign ) ) { + return new WP_Error( 'woocommerce_rest_customer_invalid_reassign', __( 'Invalid resource id for reassignment.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $user_data, $request ); + + /** Include admin customer functions to get access to wp_delete_user() */ + require_once ABSPATH . 'wp-admin/includes/user.php'; + + $customer = new WC_Customer( $id ); + + if ( ! is_null( $reassign ) ) { + $result = $customer->delete_and_reassign( $reassign ); + } else { + $result = $customer->delete(); + } + + if ( ! $result ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a customer is deleted via the REST API. + * + * @param WP_User $user_data User data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_customer', $user_data, $response, $request ); + + return $response; + } + + /** + * Prepare a single customer output for response. + * + * @param WP_User $user_data User object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $user_data, $request ) { + $customer = new WC_Customer( $user_data->ID ); + $_data = $customer->get_data(); + $last_order = wc_get_customer_last_order( $customer->get_id() ); + $format_date = array( 'date_created', 'date_modified' ); + + // Format date values. + foreach ( $format_date as $key ) { + $_data[ $key ] = $_data[ $key ] ? wc_rest_prepare_date_response( $_data[ $key ] ) : null; // v1 API used UTC. + } + + $data = array( + 'id' => $_data['id'], + 'date_created' => $_data['date_created'], + 'date_modified' => $_data['date_modified'], + 'email' => $_data['email'], + 'first_name' => $_data['first_name'], + 'last_name' => $_data['last_name'], + 'username' => $_data['username'], + 'last_order' => array( + 'id' => is_object( $last_order ) ? $last_order->get_id() : null, + 'date' => is_object( $last_order ) ? wc_rest_prepare_date_response( $last_order->get_date_created() ) : null, // v1 API used UTC. + ), + 'orders_count' => $customer->get_order_count(), + 'total_spent' => $customer->get_total_spent(), + 'avatar_url' => $customer->get_avatar_url(), + 'billing' => $_data['billing'], + 'shipping' => $_data['shipping'], + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $user_data ) ); + + /** + * Filter customer data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_User $user_data User object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); + } + + /** + * Update customer meta fields. + * + * @param WC_Customer $customer + * @param WP_REST_Request $request + */ + protected function update_customer_meta_fields( $customer, $request ) { + $schema = $this->get_item_schema(); + + // Customer first name. + if ( isset( $request['first_name'] ) ) { + $customer->set_first_name( wc_clean( $request['first_name'] ) ); + } + + // Customer last name. + if ( isset( $request['last_name'] ) ) { + $customer->set_last_name( wc_clean( $request['last_name'] ) ); + } + + // Customer billing address. + if ( isset( $request['billing'] ) ) { + foreach ( array_keys( $schema['properties']['billing']['properties'] ) as $field ) { + if ( isset( $request['billing'][ $field ] ) && is_callable( array( $customer, "set_billing_{$field}" ) ) ) { + $customer->{"set_billing_{$field}"}( $request['billing'][ $field ] ); + } + } + } + + // Customer shipping address. + if ( isset( $request['shipping'] ) ) { + foreach ( array_keys( $schema['properties']['shipping']['properties'] ) as $field ) { + if ( isset( $request['shipping'][ $field ] ) && is_callable( array( $customer, "set_shipping_{$field}" ) ) ) { + $customer->{"set_shipping_{$field}"}( $request['shipping'][ $field ] ); + } + } + } + } + + /** + * Prepare links for the request. + * + * @param WP_User $customer Customer object. + * @return array Links for the given customer. + */ + protected function prepare_links( $customer ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $customer->ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Customer's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'email' => array( + 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'first_name' => array( + 'description' => __( 'Customer first name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'last_name' => array( + 'description' => __( 'Customer last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'username' => array( + 'description' => __( 'Customer login name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_user', + ), + ), + 'password' => array( + 'description' => __( 'Customer password.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'last_order' => array( + 'description' => __( 'Last order data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => array( + 'id' => array( + 'description' => __( 'Last order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date' => array( + 'description' => __( 'The date of the customer last order, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + 'orders_count' => array( + 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_spent' => array( + 'description' => __( 'Total amount spent.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avatar_url' => array( + 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'billing' => array( + 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get role names. + * + * @return array + */ + protected function get_role_names() { + global $wp_roles; + + return array_keys( $wp_roles->role_names ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + $params['include'] = array( + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'default' => 'asc', + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'enum' => array( 'asc', 'desc' ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'default' => 'name', + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'enum' => array( + 'id', + 'include', + 'name', + 'registered_date', + ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['email'] = array( + 'description' => __( 'Limit result set to resources with a specific email.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['role'] = array( + 'description' => __( 'Limit result set to resources with a specific role.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'customer', + 'enum' => array_merge( array( 'all' ), $this->get_role_names() ), + 'validate_callback' => 'rest_validate_request_arg', + ); + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php new file mode 100644 index 0000000..b057cfd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php @@ -0,0 +1,439 @@ +/notes endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Order Notes controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Controller + */ +class WC_REST_Order_Notes_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'orders/(?P[\d]+)/notes'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'shop_order'; + + /** + * Register the routes for order notes. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'note' => array( + 'type' => 'string', + 'description' => __( 'Order note content.', 'woocommerce' ), + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read order notes. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create order notes. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'read', $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a order note. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get order notes from an order. + * + * @param WP_REST_Request $request + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $args = array( + 'post_id' => $order->get_id(), + 'approve' => 'approve', + 'type' => 'order_note', + ); + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $notes = get_comments( $args ); + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $data = array(); + foreach ( $notes as $note ) { + $order_note = $this->prepare_item_for_response( $note, $request ); + $order_note = $this->prepare_response_for_collection( $order_note ); + $data[] = $order_note; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Create the note. + $note_id = $order->add_order_note( $request['note'], $request['customer_note'] ); + + if ( ! $note_id ) { + return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $note = get_comment( $note_id ); + $this->update_additional_fields_for_object( $note, $request ); + + /** + * Fires after a order note is created or updated via the REST API. + * + * @param WP_Comment $note New order note object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $note, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, str_replace( '(?P[\d]+)', $order->get_id(), $this->rest_base ), $note_id ) ) ); + + return $response; + } + + /** + * Get a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $note = get_comment( $id ); + + if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $order_note = $this->prepare_item_for_response( $note, $request ); + $response = rest_ensure_response( $order_note ); + + return $response; + } + + /** + * Delete a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $note = get_comment( $id ); + + if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $note, $request ); + + $result = wc_delete_order_note( $note->comment_ID ); + + if ( ! $result ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a order note is deleted or trashed via the REST API. + * + * @param WP_Comment $note The deleted or trashed order note. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_order_note', $note, $response, $request ); + + return $response; + } + + /** + * Prepare a single order note output for response. + * + * @param WP_Comment $note Order note object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $note, $request ) { + $data = array( + 'id' => (int) $note->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $note ) ); + + /** + * Filter order note object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $note Order note object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); + } + + /** + * Prepare links for the request. + * + * @param WP_Comment $note Delivery order_note object. + * @return array Links for the given order note. + */ + protected function prepare_links( $note ) { + $order_id = (int) $note->comment_post_ID; + $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $note->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Order Notes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'order_note', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'note' => array( + 'description' => __( 'Order note.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_note' => array( + 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php new file mode 100644 index 0000000..550aef9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php @@ -0,0 +1,530 @@ +/refunds endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Order Refunds controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Orders_V1_Controller + */ +class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'orders/(?P[\d]+)/refunds'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'shop_order_refund'; + + /** + * Order refunds actions. + */ + public function __construct() { + add_filter( "woocommerce_rest_{$this->post_type}_trashable", '__return_false' ); + add_filter( "woocommerce_rest_{$this->post_type}_query", array( $this, 'query_args' ), 10, 2 ); + } + + /** + * Register the routes for order refunds. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Prepare a single order refund output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * + * @return WP_Error|WP_REST_Response + */ + public function prepare_item_for_response( $post, $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + $refund = wc_get_order( $post ); + + if ( ! $refund || $refund->get_parent_id() !== $order->get_id() ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + } + + $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); + + $data = array( + 'id' => $refund->get_id(), + 'date_created' => wc_rest_prepare_date_response( $refund->get_date_created() ), + 'amount' => wc_format_decimal( $refund->get_amount(), $dp ), + 'reason' => $refund->get_reason(), + 'line_items' => array(), + ); + + // Add line items. + foreach ( $refund->get_items() as $item_id => $item ) { + $product = $item->get_product(); + $product_id = 0; + $variation_id = 0; + $product_sku = null; + + // Check if the product exists. + if ( is_object( $product ) ) { + $product_id = $item->get_product_id(); + $variation_id = $item->get_variation_id(); + $product_sku = $product->get_sku(); + } + + $item_meta = array(); + + $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; + + foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { + $item_meta[] = array( + 'key' => $formatted_meta->key, + 'label' => $formatted_meta->display_key, + 'value' => wc_clean( $formatted_meta->display_value ), + ); + } + + $line_item = array( + 'id' => $item_id, + 'name' => $item['name'], + 'sku' => $product_sku, + 'product_id' => (int) $product_id, + 'variation_id' => (int) $variation_id, + 'quantity' => wc_stock_amount( $item['qty'] ), + 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', + 'price' => wc_format_decimal( $refund->get_item_total( $item, false, false ), $dp ), + 'subtotal' => wc_format_decimal( $refund->get_line_subtotal( $item, false, false ), $dp ), + 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), + 'total' => wc_format_decimal( $refund->get_line_total( $item, false, false ), $dp ), + 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), + 'taxes' => array(), + 'meta' => $item_meta, + ); + + $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); + if ( isset( $item_line_taxes['total'] ) ) { + $line_tax = array(); + + foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => '', + ); + } + + foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ]['subtotal'] = $tax; + } + + $line_item['taxes'] = array_values( $line_tax ); + } + + $data['line_items'][] = $line_item; + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $refund, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Order_Refund $refund Comment object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given order refund. + */ + protected function prepare_links( $refund, $request ) { + $order_id = $refund->get_parent_id(); + $base = str_replace( '(?P[\d]+)', $order_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $refund->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ), + ), + ); + + return $links; + } + + /** + * Query args. + * + * @param array $args Request args. + * @param WP_REST_Request $request Request object. + * @return array + */ + public function query_args( $args, $request ) { + $args['post_status'] = array_keys( wc_get_order_statuses() ); + $args['post_parent__in'] = array( absint( $request['order_id'] ) ); + + return $args; + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order_data = get_post( (int) $request['order_id'] ); + + if ( empty( $order_data ) ) { + return new WP_Error( 'woocommerce_rest_invalid_order', __( 'Order is invalid', 'woocommerce' ), 400 ); + } + + if ( 0 > $request['amount'] ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + } + + // Create the refund. + $refund = wc_create_refund( array( + 'order_id' => $order_data->ID, + 'amount' => $request['amount'], + 'reason' => empty( $request['reason'] ) ? null : $request['reason'], + 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, + 'restock_items' => true, + ) ); + + if ( is_wp_error( $refund ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + } + + if ( ! $refund ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + $post = get_post( $refund->get_id() ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'amount' => array( + 'description' => __( 'Refund amount.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'reason' => array( + 'description' => __( 'Reason for refund.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta' => array( + 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Meta label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['dp'] = array( + 'default' => wc_get_price_decimals(), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php new file mode 100644 index 0000000..51fffe1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php @@ -0,0 +1,1631 @@ +post_type}_query", array( $this, 'query_args' ), 10, 2 ); + } + + /** + * Register the routes for orders. + */ + 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' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Prepare a single order output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $data + */ + public function prepare_item_for_response( $post, $request ) { + $order = wc_get_order( $post ); + $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] ); + + $data = array( + 'id' => $order->get_id(), + 'parent_id' => $order->get_parent_id(), + 'status' => $order->get_status(), + 'order_key' => $order->get_order_key(), + 'number' => $order->get_order_number(), + 'currency' => $order->get_currency(), + 'version' => $order->get_version(), + 'prices_include_tax' => $order->get_prices_include_tax(), + 'date_created' => wc_rest_prepare_date_response( $order->get_date_created() ), // v1 API used UTC. + 'date_modified' => wc_rest_prepare_date_response( $order->get_date_modified() ), // v1 API used UTC. + 'customer_id' => $order->get_customer_id(), + 'discount_total' => wc_format_decimal( $order->get_total_discount(), $dp ), + 'discount_tax' => wc_format_decimal( $order->get_discount_tax(), $dp ), + 'shipping_total' => wc_format_decimal( $order->get_shipping_total(), $dp ), + 'shipping_tax' => wc_format_decimal( $order->get_shipping_tax(), $dp ), + 'cart_tax' => wc_format_decimal( $order->get_cart_tax(), $dp ), + 'total' => wc_format_decimal( $order->get_total(), $dp ), + 'total_tax' => wc_format_decimal( $order->get_total_tax(), $dp ), + 'billing' => array(), + 'shipping' => array(), + 'payment_method' => $order->get_payment_method(), + 'payment_method_title' => $order->get_payment_method_title(), + 'transaction_id' => $order->get_transaction_id(), + 'customer_ip_address' => $order->get_customer_ip_address(), + 'customer_user_agent' => $order->get_customer_user_agent(), + 'created_via' => $order->get_created_via(), + 'customer_note' => $order->get_customer_note(), + 'date_completed' => wc_rest_prepare_date_response( $order->get_date_completed(), false ), // v1 API used local time. + 'date_paid' => wc_rest_prepare_date_response( $order->get_date_paid(), false ), // v1 API used local time. + 'cart_hash' => $order->get_cart_hash(), + 'line_items' => array(), + 'tax_lines' => array(), + 'shipping_lines' => array(), + 'fee_lines' => array(), + 'coupon_lines' => array(), + 'refunds' => array(), + ); + + // Add addresses. + $data['billing'] = $order->get_address( 'billing' ); + $data['shipping'] = $order->get_address( 'shipping' ); + + // Add line items. + foreach ( $order->get_items() as $item_id => $item ) { + $product = $item->get_product(); + $product_id = 0; + $variation_id = 0; + $product_sku = null; + + // Check if the product exists. + if ( is_object( $product ) ) { + $product_id = $item->get_product_id(); + $variation_id = $item->get_variation_id(); + $product_sku = $product->get_sku(); + } + + $item_meta = array(); + + $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; + + foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { + $item_meta[] = array( + 'key' => $formatted_meta->key, + 'label' => $formatted_meta->display_key, + 'value' => wc_clean( $formatted_meta->display_value ), + ); + } + + $line_item = array( + 'id' => $item_id, + 'name' => $item['name'], + 'sku' => $product_sku, + 'product_id' => (int) $product_id, + 'variation_id' => (int) $variation_id, + 'quantity' => wc_stock_amount( $item['qty'] ), + 'tax_class' => ! empty( $item['tax_class'] ) ? $item['tax_class'] : '', + 'price' => wc_format_decimal( $order->get_item_total( $item, false, false ), $dp ), + 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item, false, false ), $dp ), + 'subtotal_tax' => wc_format_decimal( $item['line_subtotal_tax'], $dp ), + 'total' => wc_format_decimal( $order->get_line_total( $item, false, false ), $dp ), + 'total_tax' => wc_format_decimal( $item['line_tax'], $dp ), + 'taxes' => array(), + 'meta' => $item_meta, + ); + + $item_line_taxes = maybe_unserialize( $item['line_tax_data'] ); + if ( isset( $item_line_taxes['total'] ) ) { + $line_tax = array(); + + foreach ( $item_line_taxes['total'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => '', + ); + } + + foreach ( $item_line_taxes['subtotal'] as $tax_rate_id => $tax ) { + $line_tax[ $tax_rate_id ]['subtotal'] = $tax; + } + + $line_item['taxes'] = array_values( $line_tax ); + } + + $data['line_items'][] = $line_item; + } + + // Add taxes. + foreach ( $order->get_items( 'tax' ) as $key => $tax ) { + $tax_line = array( + 'id' => $key, + 'rate_code' => $tax['name'], + 'rate_id' => $tax['rate_id'], + 'label' => isset( $tax['label'] ) ? $tax['label'] : $tax['name'], + 'compound' => (bool) $tax['compound'], + 'tax_total' => wc_format_decimal( $tax['tax_amount'], $dp ), + 'shipping_tax_total' => wc_format_decimal( $tax['shipping_tax_amount'], $dp ), + ); + + $data['tax_lines'][] = $tax_line; + } + + // Add shipping. + foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) { + $shipping_line = array( + 'id' => $shipping_item_id, + 'method_title' => $shipping_item['name'], + 'method_id' => $shipping_item['method_id'], + 'total' => wc_format_decimal( $shipping_item['cost'], $dp ), + 'total_tax' => wc_format_decimal( '', $dp ), + 'taxes' => array(), + ); + + $shipping_taxes = $shipping_item->get_taxes(); + + if ( ! empty( $shipping_taxes['total'] ) ) { + $shipping_line['total_tax'] = wc_format_decimal( array_sum( $shipping_taxes['total'] ), $dp ); + + foreach ( $shipping_taxes['total'] as $tax_rate_id => $tax ) { + $shipping_line['taxes'][] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + ); + } + } + + $data['shipping_lines'][] = $shipping_line; + } + + // Add fees. + foreach ( $order->get_fees() as $fee_item_id => $fee_item ) { + $fee_line = array( + 'id' => $fee_item_id, + 'name' => $fee_item['name'], + 'tax_class' => ! empty( $fee_item['tax_class'] ) ? $fee_item['tax_class'] : '', + 'tax_status' => 'taxable', + 'total' => wc_format_decimal( $order->get_line_total( $fee_item ), $dp ), + 'total_tax' => wc_format_decimal( $order->get_line_tax( $fee_item ), $dp ), + 'taxes' => array(), + ); + + $fee_line_taxes = maybe_unserialize( $fee_item['line_tax_data'] ); + if ( isset( $fee_line_taxes['total'] ) ) { + $fee_tax = array(); + + foreach ( $fee_line_taxes['total'] as $tax_rate_id => $tax ) { + $fee_tax[ $tax_rate_id ] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => '', + ); + } + + if ( isset( $fee_line_taxes['subtotal'] ) ) { + foreach ( $fee_line_taxes['subtotal'] as $tax_rate_id => $tax ) { + $fee_tax[ $tax_rate_id ]['subtotal'] = $tax; + } + } + + $fee_line['taxes'] = array_values( $fee_tax ); + } + + $data['fee_lines'][] = $fee_line; + } + + // Add coupons. + foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) { + $coupon_line = array( + 'id' => $coupon_item_id, + 'code' => $coupon_item['name'], + 'discount' => wc_format_decimal( $coupon_item['discount_amount'], $dp ), + 'discount_tax' => wc_format_decimal( $coupon_item['discount_amount_tax'], $dp ), + ); + + $data['coupon_lines'][] = $coupon_line; + } + + // Add refunds. + foreach ( $order->get_refunds() as $refund ) { + $data['refunds'][] = array( + 'id' => $refund->get_id(), + 'refund' => $refund->get_reason() ? $refund->get_reason() : '', + 'total' => '-' . wc_format_decimal( $refund->get_amount(), $dp ), + ); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $order, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Order $order Order object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given order. + */ + protected function prepare_links( $order, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $order->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + if ( 0 !== (int) $order->get_user_id() ) { + $links['customer'] = array( + 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $order->get_user_id() ) ), + ); + } + if ( 0 !== (int) $order->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order->get_parent_id() ) ), + ); + } + return $links; + } + + /** + * Query args. + * + * @param array $args + * @param WP_REST_Request $request + * @return array + */ + public function query_args( $args, $request ) { + global $wpdb; + + // Set post_status. + if ( 'any' !== $request['status'] ) { + $args['post_status'] = 'wc-' . $request['status']; + } else { + $args['post_status'] = 'any'; + } + + if ( isset( $request['customer'] ) ) { + if ( ! empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); + } + + $args['meta_query'][] = array( + 'key' => '_customer_user', + 'value' => $request['customer'], + 'type' => 'NUMERIC', + ); + } + + // Search by product. + if ( ! empty( $request['product'] ) ) { + $order_ids = $wpdb->get_col( $wpdb->prepare( " + SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items + WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) + AND order_item_type = 'line_item' + ", $request['product'] ) ); + + // Force WP_Query return empty if don't found any order. + $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); + + $args['post__in'] = $order_ids; + } + + // Search. + if ( ! empty( $args['s'] ) ) { + $order_ids = wc_order_search( $args['s'] ); + + if ( ! empty( $order_ids ) ) { + unset( $args['s'] ); + $args['post__in'] = array_merge( $order_ids, array( 0 ) ); + } + } + + return $args; + } + + /** + * Prepare a single order for create. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|WC_Order $data Object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $order = new WC_Order( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Handle all writable props + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'billing' : + case 'shipping' : + $this->update_address( $order, $value, $key ); + break; + case 'line_items' : + case 'shipping_lines' : + case 'fee_lines' : + case 'coupon_lines' : + if ( is_array( $value ) ) { + foreach ( $value as $item ) { + if ( is_array( $item ) ) { + if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { + $order->remove_item( $item['id'] ); + } else { + $this->set_item( $order, $key, $item ); + } + } + } + } + break; + default : + if ( is_callable( array( $order, "set_{$key}" ) ) ) { + $order->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filter the data for the insert. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WC_Order $order The order object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $order, $request ); + } + + /** + * Create base WC Order object. + * @deprecated 3.0.0 + * @param array $data + * @return WC_Order + */ + protected function create_base_order( $data ) { + return wc_create_order( $data ); + } + + /** + * Only return writable props from schema. + * @param array $schema + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Create order. + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function create_order( $request ) { + try { + // Make sure customer exists. + if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] && false === get_user_by( 'id', $request['customer_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id',__( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { + add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + } + + $order = $this->prepare_item_for_database( $request ); + $order->set_created_via( 'rest-api' ); + $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $order->calculate_totals(); + $order->save(); + + // Handle set paid. + if ( true === $request['set_paid'] ) { + $order->payment_complete( $request['transaction_id'] ); + } + + return $order->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update order. + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function update_order( $request ) { + try { + $order = $this->prepare_item_for_database( $request ); + $order->save(); + + // Handle set paid. + if ( $order->needs_payment() && true === $request['set_paid'] ) { + $order->payment_complete( $request['transaction_id'] ); + } + + // If items have changed, recalculate order totals. + if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { + $order->calculate_totals( true ); + } + + return $order->get_id(); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update address. + * + * @param WC_Order $order + * @param array $posted + * @param string $type + */ + protected function update_address( $order, $posted, $type = 'billing' ) { + foreach ( $posted as $key => $value ) { + if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { + $order->{"set_{$type}_{$key}"}( $value ); + } + } + } + + /** + * Gets the product ID from the SKU or posted ID. + * + * @throws WC_REST_Exception When SKU or ID is not valid. + * @param array $posted Request data. + * @param string $action 'create' to add line item or 'update' to update it. + * @return int + */ + protected function get_product_id( $posted, $action = 'create' ) { + if ( ! empty( $posted['sku'] ) ) { + $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); + } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['product_id']; + } elseif ( ! empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['variation_id']; + } elseif ( 'update' === $action ) { + $product_id = 0; + } else { + throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + } + return $product_id; + } + + /** + * Maybe set an item prop if the value was posted. + * @param WC_Order_Item $item + * @param string $prop + * @param array $posted Request data. + */ + protected function maybe_set_item_prop( $item, $prop, $posted ) { + if ( isset( $posted[ $prop ] ) ) { + $item->{"set_$prop"}( $posted[ $prop ] ); + } + } + + /** + * Maybe set item props if the values were posted. + * @param WC_Order_Item $item + * @param string[] $props + * @param array $posted Request data. + */ + protected function maybe_set_item_props( $item, $props, $posted ) { + foreach ( $props as $prop ) { + $this->maybe_set_item_prop( $item, $prop, $posted ); + } + } + + /** + * Create or update a line item. + * + * @param array $posted Line item data. + * @param string $action 'create' to add line item or 'update' to update it. + * + * @return WC_Order_Item_Product + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_line_items( $posted, $action = 'create' ) { + $item = new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + $product = wc_get_product( $this->get_product_id( $posted, $action ) ); + + if ( $product && $product !== $item->get_product() ) { + $item->set_product( $product ); + + if ( 'create' === $action ) { + $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; + $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); + $item->set_total( $total ); + $item->set_subtotal( $total ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); + + return $item; + } + + /** + * Create or update an order shipping method. + * + * @param $posted $shipping Item data. + * @param string $action 'create' to add shipping or 'update' to update it. + * + * @return WC_Order_Item_Shipping + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_shipping_lines( $posted, $action ) { + $item = new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + + if ( 'create' === $action ) { + if ( empty( $posted['method_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total' ), $posted ); + + return $item; + } + + /** + * Create or update an order fee. + * + * @param array $posted Item data. + * @param string $action 'create' to add fee or 'update' to update it. + * + * @return WC_Order_Item_Fee + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_fee_lines( $posted, $action ) { + $item = new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + + if ( 'create' === $action ) { + if ( empty( $posted['name'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); + + return $item; + } + + /** + * Create or update an order coupon. + * + * @param array $posted Item data. + * @param string $action 'create' to add coupon or 'update' to update it. + * + * @return WC_Order_Item_Coupon + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_coupon_lines( $posted, $action ) { + $item = new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ); + + if ( 'create' === $action ) { + if ( empty( $posted['code'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted ); + + return $item; + } + + /** + * Wrapper method to create/update order items. + * When updating, the item ID provided is checked to ensure it is associated + * with the order. + * + * @param WC_Order $order order + * @param string $item_type + * @param array $posted item provided in the request body + * @throws WC_REST_Exception If item ID is not associated with order + */ + protected function set_item( $order, $item_type, $posted ) { + global $wpdb; + + if ( ! empty( $posted['id'] ) ) { + $action = 'update'; + } else { + $action = 'create'; + } + + $method = 'prepare_' . $item_type; + + // Verify provided line item ID is associated with order. + if ( 'update' === $action ) { + $result = $wpdb->get_row( + $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d AND order_id = %d", + absint( $posted['id'] ), + absint( $order->get_id() ) + ) ); + if ( is_null( $result ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + } + } + + // Prepare item data + $item = $this->$method( $posted, $action ); + + /** + * Action hook to adjust item before save. + * @since 3.0.0 + */ + do_action( 'woocommerce_rest_set_order_item', $item, $posted ); + + // Save or add to order + if ( 'create' === $action ) { + $order->add_item( $item ); + } else { + $item->save(); + } + } + + /** + * Helper method to check if the resource ID associated with the provided item is null. + * Items can be deleted by setting the resource ID to null. + * + * @param array $item Item provided in the request body. + * @return bool True if the item resource ID is null, false otherwise. + */ + protected function item_is_null( $item ) { + $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); + + foreach ( $keys as $key ) { + if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { + return true; + } + } + + return false; + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order_id = $this->create_order( $request ); + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $post = get_post( $order_id ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } + + /** + * Update a single order. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + try { + $post_id = (int) $request['id']; + + if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $order_id = $this->update_order( $request ); + if ( is_wp_error( $order_id ) ) { + return $order_id; + } + + $post = get_post( $order_id ); + $this->update_additional_fields_for_object( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + + } catch ( Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get order statuses without prefixes. + * @return array + */ + protected function get_order_statuses() { + $order_statuses = array(); + + foreach ( array_keys( wc_get_order_statuses() ) as $status ) { + $order_statuses[] = str_replace( 'wc-', '', $status ); + } + + return $order_statuses; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'parent_id' => array( + 'description' => __( 'Parent order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Order status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'pending', + 'enum' => $this->get_order_statuses(), + 'context' => array( 'view', 'edit' ), + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'number' => array( + 'description' => __( 'Order number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'currency' => array( + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), + 'type' => 'string', + 'default' => get_woocommerce_currency(), + 'enum' => array_keys( get_woocommerce_currencies() ), + 'context' => array( 'view', 'edit' ), + ), + 'version' => array( + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'prices_include_tax' => array( + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order was created, as GMT.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the order was last modified, as GMT.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_id' => array( + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 0, + 'context' => array( 'view', 'edit' ), + ), + 'discount_total' => array( + 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_tax' => array( + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_total' => array( + 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax' => array( + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_tax' => array( + 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Grand total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Sum of all taxes.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'billing' => array( + 'description' => __( 'Billing address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'Shipping address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'payment_method' => array( + 'description' => __( 'Payment method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'payment_method_title' => array( + 'description' => __( 'Payment method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'set_paid' => array( + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'edit' ), + ), + 'transaction_id' => array( + 'description' => __( 'Unique transaction ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_ip_address' => array( + 'description' => __( "Customer's IP address.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_user_agent' => array( + 'description' => __( 'User agent of the customer.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'created_via' => array( + 'description' => __( 'Shows where the order was created.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_note' => array( + 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_completed' => array( + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_paid' => array( + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_hash' => array( + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta' => array( + 'description' => __( 'Line item meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Meta label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + 'tax_lines' => array( + 'description' => __( 'Tax lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_code' => array( + 'description' => __( 'Tax rate code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Tax rate label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'compound' => array( + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_total' => array( + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax_total' => array( + 'description' => __( 'Shipping tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'shipping_lines' => array( + 'description' => __( 'Shipping lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_title' => array( + 'description' => __( 'Shipping method name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'method_id' => array( + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + 'fee_lines' => array( + 'description' => __( 'Fee lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Fee name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'taxable', 'none' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ), + ), + 'coupon_lines' => array( + 'description' => __( 'Coupons line data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'discount' => array( + 'description' => __( 'Discount total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'discount_tax' => array( + 'description' => __( 'Discount total tax.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'refunds' => array( + 'description' => __( 'List of refunds.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Refund ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reason' => array( + 'description' => __( 'Refund reason.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Refund total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any' ), $this->get_order_statuses() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['customer'] = array( + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['product'] = array( + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['dp'] = array( + 'default' => wc_get_price_decimals(), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php new file mode 100644 index 0000000..244530b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php @@ -0,0 +1,241 @@ +/terms endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Product Attribute Terms controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Terms_Controller + */ +class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/attributes/(?P[\d]+)/terms'; + + /** + * Register the routes for terms. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, + array( + 'args' => array( + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'name' => array( + 'type' => 'string', + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + )); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Prepare a single product attribute term output for response. + * + * @param WP_Term $item Term object. + * @param WP_REST_Request $request + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + // Get term order. + $menu_order = get_term_meta( $item->term_id, 'order_' . $this->taxonomy, true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'description' => $item->description, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Update term meta fields. + * + * @param WP_Term $term + * @param WP_REST_Request $request + * @return bool|WP_Error + */ + protected function update_term_meta_fields( $term, $request ) { + $id = (int) $term->term_id; + + update_term_meta( $id, 'order_' . $this->taxonomy, $request['menu_order'] ); + + return true; + } + + /** + * Get the Attribute Term's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_attribute_term', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php new file mode 100644 index 0000000..b4d5df4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php @@ -0,0 +1,592 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'name' => array( + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'type' => 'string', + 'required' => true, + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + )); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check if a given request has access to read the attributes. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'attributes', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! $this->get_taxonomy( $request ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'attributes', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + if ( ! $this->get_taxonomy( $request ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'attributes', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete a attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + if ( ! $this->get_taxonomy( $request ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'attributes', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'attributes', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all attributes. + * + * @param WP_REST_Request $request + * @return array + */ + public function get_items( $request ) { + $attributes = wc_get_attribute_taxonomies(); + $data = array(); + foreach ( $attributes as $attribute_obj ) { + $attribute = $this->prepare_item_for_response( $attribute_obj, $request ); + $attribute = $this->prepare_response_for_collection( $attribute ); + $data[] = $attribute; + } + + $response = rest_ensure_response( $data ); + + // This API call always returns all product attributes due to retrieval from the object cache. + $response->header( 'X-WP-Total', count( $data ) ); + $response->header( 'X-WP-TotalPages', 1 ); + + return $response; + } + + /** + * Create a single attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + global $wpdb; + + $id = wc_create_attribute( array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => ! empty( $request['type'] ) ? $request['type'] : 'select', + 'order_by' => ! empty( $request['order_by'] ) ? $request['order_by'] : 'menu_order', + 'has_archives' => true === $request['has_archives'], + ) ); + + // Checks for errors. + if ( is_wp_error( $id ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', $id->get_error_message(), array( 'status' => 400 ) ); + } + + $attribute = $this->get_attribute( $id ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $this->update_additional_fields_for_object( $attribute, $request ); + + /** + * Fires after a single product attribute is created or updated via the REST API. + * + * @param stdObject $attribute Inserted attribute object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating attribute, false when updating. + */ + do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $attribute, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( '/' . $this->namespace . '/' . $this->rest_base . '/' . $attribute->attribute_id ) ); + + return $response; + } + + /** + * Get a single attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function get_item( $request ) { + $attribute = $this->get_attribute( (int) $request['id'] ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $response = $this->prepare_item_for_response( $attribute, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Update a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + global $wpdb; + + $id = (int) $request['id']; + $edited = wc_update_attribute( $id, array( + 'name' => $request['name'], + 'slug' => wc_sanitize_taxonomy_name( stripslashes( $request['slug'] ) ), + 'type' => $request['type'], + 'order_by' => $request['order_by'], + 'has_archives' => $request['has_archives'], + ) ); + + // Checks for errors. + if ( is_wp_error( $edited ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', $edited->get_error_message(), array( 'status' => 400 ) ); + } + + $attribute = $this->get_attribute( $id ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $this->update_additional_fields_for_object( $attribute, $request ); + + /** + * Fires after a single product attribute is created or updated via the REST API. + * + * @param stdObject $attribute Inserted attribute object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating attribute, false when updating. + */ + do_action( 'woocommerce_rest_insert_product_attribute', $attribute, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $attribute, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a single attribute. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $attribute = $this->get_attribute( (int) $request['id'] ); + + if ( is_wp_error( $attribute ) ) { + return $attribute; + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $attribute, $request ); + + $deleted = wc_delete_attribute( $attribute->attribute_id ); + + if ( false === $deleted ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single attribute is deleted via the REST API. + * + * @param stdObject $attribute The deleted attribute. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_product_attribute', $attribute, $response, $request ); + + return $response; + } + + /** + * Prepare a single product attribute output for response. + * + * @param obj $item Term object. + * @param WP_REST_Request $request + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $data = array( + 'id' => (int) $item->attribute_id, + 'name' => $item->attribute_label, + 'slug' => wc_attribute_taxonomy_name( $item->attribute_name ), + 'type' => $item->attribute_type, + 'order_by' => $item->attribute_orderby, + 'has_archives' => (bool) $item->attribute_public, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter a attribute item returned from the API. + * + * Allows modification of the product attribute data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original attribute object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_product_attribute', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $attribute Attribute object. + * @return array Links for the given attribute. + */ + protected function prepare_links( $attribute ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $attribute->attribute_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + + /** + * Get the Attribute's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_attribute', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'type' => array( + 'description' => __( 'Type of attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'select', + 'enum' => array_keys( wc_get_attribute_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'order_by' => array( + 'description' => __( 'Default sort order.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'menu_order', + 'enum' => array( 'menu_order', 'name', 'name_num', 'id' ), + 'context' => array( 'view', 'edit' ), + ), + 'has_archives' => array( + 'description' => __( 'Enable/Disable attribute archives.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections + * + * @return array + */ + public function get_collection_params() { + $params = array(); + $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); + + return $params; + } + + /** + * Get attribute name. + * + * @param WP_REST_Request $request Full details about the request. + * @return string + */ + protected function get_taxonomy( $request ) { + if ( '' !== $this->attribute ) { + return $this->attribute; + } + + if ( $request['id'] ) { + $name = wc_attribute_taxonomy_name_by_id( (int) $request['id'] ); + + $this->attribute = $name; + } + + return $this->attribute; + } + + /** + * Get attribute data. + * + * @param int $id Attribute ID. + * @return stdClass|WP_Error + */ + protected function get_attribute( $id ) { + global $wpdb; + + $attribute = $wpdb->get_row( $wpdb->prepare( " + SELECT * + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", $id ) ); + + if ( is_wp_error( $attribute ) || is_null( $attribute ) ) { + return new WP_Error( 'woocommerce_rest_attribute_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return $attribute; + } + + /** + * Validate attribute slug. + * + * @deprecated 3.2.0 + * @param string $slug + * @param bool $new_data + * @return bool|WP_Error + */ + protected function validate_attribute_slug( $slug, $new_data = true ) { + if ( strlen( $slug ) >= 28 ) { + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } elseif ( $new_data && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) { + return new WP_Error( 'woocommerce_rest_invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } + + return true; + } + + /** + * Schedule to flush rewrite rules. + * + * @deprecated 3.2.0 + * @since 3.0.0 + */ + protected function flush_rewrite_rules() { + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php new file mode 100644 index 0000000..4d19661 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php @@ -0,0 +1,271 @@ +term_id, 'display_type', true ); + + // Get category order. + $menu_order = get_term_meta( $item->term_id, 'order', true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'parent' => (int) $item->parent, + 'description' => $item->description, + 'display' => $display_type ? $display_type : 'default', + 'image' => null, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + // Get category image. + $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); + if ( $image_id ) { + $attachment = get_post( $image_id ); + + $data['image'] = array( + 'id' => (int) $image_id, + 'date_created' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), + 'src' => wp_get_attachment_url( $image_id ), + 'title' => get_the_title( $attachment ), + 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), + ); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Update term meta fields. + * + * @param WP_Term $term Term object. + * @param WP_REST_Request $request Request instance. + * @return bool|WP_Error + */ + protected function update_term_meta_fields( $term, $request ) { + $id = (int) $term->term_id; + + if ( isset( $request['display'] ) ) { + update_term_meta( $id, 'display_type', 'default' === $request['display'] ? '' : $request['display'] ); + } + + if ( isset( $request['menu_order'] ) ) { + update_term_meta( $id, 'order', $request['menu_order'] ); + } + + if ( isset( $request['image'] ) ) { + if ( empty( $request['image']['id'] ) && ! empty( $request['image']['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $request['image']['src'] ) ); + + if ( is_wp_error( $upload ) ) { + return $upload; + } + + $image_id = wc_rest_set_uploaded_image_as_attachment( $upload ); + } else { + $image_id = isset( $request['image']['id'] ) ? absint( $request['image']['id'] ) : 0; + } + + // Check if image_id is a valid image attachment before updating the term meta. + if ( $image_id && wp_attachment_is_image( $image_id ) ) { + update_term_meta( $id, 'thumbnail_id', $image_id ); + + // Set the image alt. + if ( ! empty( $request['image']['alt'] ) ) { + update_post_meta( $image_id, '_wp_attachment_image_alt', wc_clean( $request['image']['alt'] ) ); + } + + // Set the image title. + if ( ! empty( $request['image']['title'] ) ) { + wp_update_post( array( + 'ID' => $image_id, + 'post_title' => wc_clean( $request['image']['title'] ), + ) ); + } + } else { + delete_term_meta( $id, 'thumbnail_id' ); + } + } + + return true; + } + + /** + * Get the Category schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'parent' => array( + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'display' => array( + 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'default', + 'enum' => array( 'default', 'products', 'subcategories', 'both' ), + 'context' => array( 'view', 'edit' ), + ), + 'image' => array( + 'description' => __( 'Image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'title' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php new file mode 100644 index 0000000..d8b0f77 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php @@ -0,0 +1,578 @@ +/reviews. + * + * @author WooThemes + * @category API + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Product Reviews Controller Class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Controller + */ +class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/(?P[\d]+)/reviews'; + + /** + * Register the routes for product reviews. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'review' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Review content.', 'woocommerce' ), + ), + 'name' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Name of the reviewer.', 'woocommerce' ), + ), + 'email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Email of the reviewer.', 'woocommerce' ), + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read webhook deliveries. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( 'product', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + + if ( $post && ! wc_rest_check_post_permissions( 'product', 'read', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a new product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'create', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to update a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'edit', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to delete a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'delete', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get all reviews from a product. + * + * @param WP_REST_Request $request + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $reviews = get_approved_comments( $product_id ); + $data = array(); + foreach ( $reviews as $review_data ) { + $review = $this->prepare_item_for_response( $review_data, $request ); + $review = $this->prepare_response_for_collection( $review ); + $data[] = $review; + } + + return rest_ensure_response( $data ); + } + + /** + * Get a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $review = get_comment( $id ); + + if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $delivery = $this->prepare_item_for_response( $review, $request ); + $response = rest_ensure_response( $delivery ); + + return $response; + } + + + /** + * Create a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_review = $this->prepare_item_for_database( $request ); + + /** + * Filter a product review (comment) before it is inserted via the REST API. + * + * Allows modification of the comment right before it is inserted via `wp_insert_comment`. + * + * @param array $prepared_review The prepared comment data for `wp_insert_comment`. + * @param WP_REST_Request $request Request used to insert the comment. + */ + $prepared_review = apply_filters( 'rest_pre_insert_product_review', $prepared_review, $request ); + + $product_review_id = wp_insert_comment( $prepared_review ); + if ( ! $product_review_id ) { + return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); + + $product_review = get_comment( $product_review_id ); + $this->update_additional_fields_for_object( $product_review, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Comment $product_review Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $product_review_id ) ) ); + + return $response; + } + + /** + * Update a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $product_review_id = (int) $request['id']; + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $review = get_comment( $product_review_id ); + + if ( empty( $product_review_id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_review = $this->prepare_item_for_database( $request ); + + $updated = wp_update_comment( $prepared_review ); + if ( 0 === $updated ) { + return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + if ( ! empty( $request['rating'] ) ) { + update_comment_meta( $product_review_id, 'rating', $request['rating'] ); + } + + $product_review = get_comment( $product_review_id ); + $this->update_additional_fields_for_object( $product_review, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Comment $comment Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a product review. + * + * @param WP_REST_Request $request Full details about the request + * + * @return bool|WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $product_review_id = absint( is_array( $request['id'] ) ? $request['id']['id'] : $request['id'] ); + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + $product_review = get_comment( $product_review_id ); + if ( empty( $product_review_id ) || empty( $product_review->comment_ID ) || empty( $product_review->comment_post_ID ) ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + /** + * Filter whether a product review is trashable. + * + * Return false to disable trash support for the product review. + * + * @param boolean $supports_trash Whether the object supports trashing. + * @param WP_Post $product_review The object being considered for trashing support. + */ + $supports_trash = apply_filters( 'rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $product_review ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + + if ( $force ) { + $result = wp_delete_comment( $product_review_id, true ); + } else { + if ( ! $supports_trash ) { + return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + if ( 'trash' === $product_review->comment_approved ) { + return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + } + + $result = wp_trash_comment( $product_review->comment_ID ); + } + + if ( ! $result ) { + return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a product review is deleted via the REST API. + * + * @param object $product_review The deleted item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'rest_delete_product_review', $product_review, $response, $request ); + + return $response; + } + + /** + * Prepare a single product review output for response. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $review, $request ) { + $data = array( + 'id' => (int) $review->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $review->comment_date_gmt ), + 'review' => $review->comment_content, + 'rating' => (int) get_comment_meta( $review->comment_ID, 'rating', true ), + 'name' => $review->comment_author, + 'email' => $review->comment_author_email, + 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $review, $request ) ); + + /** + * Filter product reviews object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $review Product review object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); + } + + /** + * Prepare a single product review to be inserted into the database. + * + * @param WP_REST_Request $request Request object. + * @return array|WP_Error $prepared_review + */ + protected function prepare_item_for_database( $request ) { + $prepared_review = array( 'comment_approved' => 1, 'comment_type' => 'review' ); + + if ( isset( $request['id'] ) ) { + $prepared_review['comment_ID'] = (int) $request['id']; + } + + if ( isset( $request['review'] ) ) { + $prepared_review['comment_content'] = $request['review']; + } + + if ( isset( $request['product_id'] ) ) { + $prepared_review['comment_post_ID'] = (int) $request['product_id']; + } + + if ( isset( $request['name'] ) ) { + $prepared_review['comment_author'] = $request['name']; + } + + if ( isset( $request['email'] ) ) { + $prepared_review['comment_author_email'] = $request['email']; + } + + if ( isset( $request['date_created'] ) ) { + $prepared_review['comment_date'] = $request['date_created']; + } + + if ( isset( $request['date_created_gmt'] ) ) { + $prepared_review['comment_date_gmt'] = $request['date_created_gmt']; + } + + return apply_filters( 'rest_preprocess_product_review', $prepared_review, $request ); + } + + /** + * Prepare links for the request. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given product review. + */ + protected function prepare_links( $review, $request ) { + $product_id = (int) $request['product_id']; + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $review->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Product Review's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_review', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'review' => array( + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'rating' => array( + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'verified' => array( + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php new file mode 100644 index 0000000..5de129c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php @@ -0,0 +1,134 @@ + (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'description' => $item->description, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Shipping Class schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Shipping class name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php new file mode 100644 index 0000000..121f101 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php @@ -0,0 +1,134 @@ + (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'description' => $item->description, + 'count' => (int) $item->count, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Tag's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php new file mode 100644 index 0000000..64e9442 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php @@ -0,0 +1,2641 @@ +post_type}_query", array( $this, 'query_args' ), 10, 2 ); + add_action( "woocommerce_rest_insert_{$this->post_type}", array( $this, 'clear_transients' ) ); + } + + /** + * Register the routes for products. + */ + 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' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'type' => 'boolean', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Get post types. + * + * @return array + */ + protected function get_post_types() { + return array( 'product', 'product_variation' ); + } + + /** + * Query args. + * + * @param array $args Request args. + * @param WP_REST_Request $request Request data. + * @return array + */ + public function query_args( $args, $request ) { + // Set post_status. + $args['post_status'] = $request['status']; + + // Taxonomy query to filter products by type, category, + // tag, shipping class, and attribute. + $tax_query = array(); + + // Map between taxonomy name and arg's key. + $taxonomies = array( + 'product_cat' => 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) && is_array( $request[ $key ] ) ) { + $request[ $key ] = array_filter( $request[ $key ] ); + } + + if ( ! empty( $request[ $key ] ) ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + ); + } + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ); + } + + // Filter by attribute and term. + if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { + if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $tax_query[] = array( + 'taxonomy' => $request['attribute'], + 'field' => 'term_id', + 'terms' => $request['attribute_term'], + ); + } + } + + if ( ! empty( $tax_query ) ) { + $args['tax_query'] = $tax_query; + } + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( $args, array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) ); + } + + // Apply all WP_Query filters again. + if ( is_array( $request['filter'] ) ) { + $args = array_merge( $args, $request['filter'] ); + unset( $args['filter'] ); + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + return $args; + } + + /** + * Get the downloads for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_downloads( $product ) { + $downloads = array(); + + if ( $product->is_downloadable() ) { + foreach ( $product->get_downloads() as $file_id => $file ) { + $downloads[] = array( + 'id' => $file_id, // MD5 hash. + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param string $taxonomy Taxonomy slug. + * @return array + */ + protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { + $terms = array(); + + foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { + $terms[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + ); + } + + return $terms; + } + + /** + * Get the images for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_images( $product ) { + $images = array(); + $attachment_ids = array(); + + // Add featured image. + if ( $product->get_image_id() ) { + $attachment_ids[] = $product->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $position => $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified_gmt ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + 'position' => (int) $position, + ); + } + + // Set a placeholder image if the product has no images set. + if ( empty( $images ) ) { + $images[] = array( + 'id' => 0, + 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), // Default to now. + 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ) ), + 'src' => wc_placeholder_img_src(), + 'name' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), + 'position' => 0, + ); + } + + return $images; + } + + /** + * Get attribute taxonomy label. + * + * @param string $name Taxonomy name. + * @return string + */ + protected function get_attribute_taxonomy_label( $name ) { + $tax = get_taxonomy( $name ); + $labels = get_taxonomy_labels( $tax ); + + return $labels->singular_name; + } + + /** + * Get default attributes. + * + * @param WC_Product $product Product instance. + * @return array + */ + protected function get_default_attributes( $product ) { + $default = array(); + + if ( $product->is_type( 'variable' ) ) { + foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { + if ( 0 === strpos( $key, 'pa_' ) ) { + $default[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $key ), + 'name' => $this->get_attribute_taxonomy_label( $key ), + 'option' => $value, + ); + } else { + $default[] = array( + 'id' => 0, + 'name' => wc_attribute_taxonomy_slug( $key ), + 'option' => $value, + ); + } + } + } + + return $default; + } + + /** + * Get attribute options. + * + * @param int $product_id Product ID. + * @param array $attribute Attribute data. + * @return array + */ + protected function get_attribute_options( $product_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( $product_id, $attribute['name'], array( 'fields' => 'names' ) ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * @return array + */ + protected function get_attributes( $product ) { + $attributes = array(); + + if ( $product->is_type( 'variation' ) ) { + // Variation attributes. + foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { + $name = str_replace( 'attribute_', '', $attribute_name ); + + if ( ! $attribute ) { + continue; + } + + // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. + if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { + $option_term = get_term_by( 'slug', $attribute, $name ); + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $name ), + 'name' => $this->get_attribute_taxonomy_label( $name ), + 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $name, + 'option' => $attribute, + ); + } + } + } else { + foreach ( $product->get_attributes() as $attribute ) { + if ( $attribute['is_taxonomy'] ) { + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $attribute['name'] ), + 'name' => $this->get_attribute_taxonomy_label( $attribute['name'] ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $attribute['name'], + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } + } + } + + return $attributes; + } + + /** + * Get product menu order. + * + * @deprecated 3.0.0 + * @param WC_Product $product Product instance. + * @return int + */ + protected function get_product_menu_order( $product ) { + return $product->get_menu_order(); + } + + /** + * Get product data. + * + * @param WC_Product $product Product instance. + * @return array + */ + protected function get_product_data( $product ) { + $data = array( + 'id' => $product->get_id(), + 'name' => $product->get_name(), + 'slug' => $product->get_slug(), + 'permalink' => $product->get_permalink(), + 'date_created' => wc_rest_prepare_date_response( $product->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified() ), + 'type' => $product->get_type(), + 'status' => $product->get_status(), + 'featured' => $product->is_featured(), + 'catalog_visibility' => $product->get_catalog_visibility(), + 'description' => wpautop( do_shortcode( $product->get_description() ) ), + 'short_description' => apply_filters( 'woocommerce_short_description', $product->get_short_description() ), + 'sku' => $product->get_sku(), + 'price' => $product->get_price(), + 'regular_price' => $product->get_regular_price(), + 'sale_price' => $product->get_sale_price() ? $product->get_sale_price() : '', + 'date_on_sale_from' => $product->get_date_on_sale_from() ? date( 'Y-m-d', $product->get_date_on_sale_from()->getTimestamp() ) : '', + 'date_on_sale_to' => $product->get_date_on_sale_to() ? date( 'Y-m-d', $product->get_date_on_sale_to()->getTimestamp() ) : '', + 'price_html' => $product->get_price_html(), + 'on_sale' => $product->is_on_sale(), + 'purchasable' => $product->is_purchasable(), + 'total_sales' => $product->get_total_sales(), + 'virtual' => $product->is_virtual(), + 'downloadable' => $product->is_downloadable(), + 'downloads' => $this->get_downloads( $product ), + 'download_limit' => $product->get_download_limit(), + 'download_expiry' => $product->get_download_expiry(), + 'download_type' => 'standard', + 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url() : '', + 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text() : '', + 'tax_status' => $product->get_tax_status(), + 'tax_class' => $product->get_tax_class(), + 'manage_stock' => $product->managing_stock(), + 'stock_quantity' => $product->get_stock_quantity(), + 'in_stock' => $product->is_in_stock(), + 'backorders' => $product->get_backorders(), + 'backorders_allowed' => $product->backorders_allowed(), + 'backordered' => $product->is_on_backorder(), + 'sold_individually' => $product->is_sold_individually(), + 'weight' => $product->get_weight(), + 'dimensions' => array( + 'length' => $product->get_length(), + 'width' => $product->get_width(), + 'height' => $product->get_height(), + ), + 'shipping_required' => $product->needs_shipping(), + 'shipping_taxable' => $product->is_shipping_taxable(), + 'shipping_class' => $product->get_shipping_class(), + 'shipping_class_id' => $product->get_shipping_class_id(), + 'reviews_allowed' => $product->get_reviews_allowed(), + 'average_rating' => wc_format_decimal( $product->get_average_rating(), 2 ), + 'rating_count' => $product->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids() ), + 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids() ), + 'parent_id' => $product->get_parent_id(), + 'purchase_note' => wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ), + 'categories' => $this->get_taxonomy_terms( $product ), + 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), + 'images' => $this->get_images( $product ), + 'attributes' => $this->get_attributes( $product ), + 'default_attributes' => $this->get_default_attributes( $product ), + 'variations' => array(), + 'grouped_products' => array(), + 'menu_order' => $product->get_menu_order(), + ); + + return $data; + } + + /** + * Get an individual variation's data. + * + * @param WC_Product $product Product instance. + * @return array + */ + protected function get_variation_data( $product ) { + $variations = array(); + + foreach ( $product->get_children() as $child_id ) { + $variation = wc_get_product( $child_id ); + if ( ! $variation || ! $variation->exists() ) { + continue; + } + + $variations[] = array( + 'id' => $variation->get_id(), + 'date_created' => wc_rest_prepare_date_response( $variation->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $variation->get_date_modified() ), + 'permalink' => $variation->get_permalink(), + 'sku' => $variation->get_sku(), + 'price' => $variation->get_price(), + 'regular_price' => $variation->get_regular_price(), + 'sale_price' => $variation->get_sale_price(), + 'date_on_sale_from' => $variation->get_date_on_sale_from() ? date( 'Y-m-d', $variation->get_date_on_sale_from()->getTimestamp() ) : '', + 'date_on_sale_to' => $variation->get_date_on_sale_to() ? date( 'Y-m-d', $variation->get_date_on_sale_to()->getTimestamp() ) : '', + 'on_sale' => $variation->is_on_sale(), + 'purchasable' => $variation->is_purchasable(), + 'visible' => $variation->is_visible(), + 'virtual' => $variation->is_virtual(), + 'downloadable' => $variation->is_downloadable(), + 'downloads' => $this->get_downloads( $variation ), + 'download_limit' => '' !== $variation->get_download_limit() ? (int) $variation->get_download_limit() : -1, + 'download_expiry' => '' !== $variation->get_download_expiry() ? (int) $variation->get_download_expiry() : -1, + 'tax_status' => $variation->get_tax_status(), + 'tax_class' => $variation->get_tax_class(), + 'manage_stock' => $variation->managing_stock(), + 'stock_quantity' => $variation->get_stock_quantity(), + 'in_stock' => $variation->is_in_stock(), + 'backorders' => $variation->get_backorders(), + 'backorders_allowed' => $variation->backorders_allowed(), + 'backordered' => $variation->is_on_backorder(), + 'weight' => $variation->get_weight(), + 'dimensions' => array( + 'length' => $variation->get_length(), + 'width' => $variation->get_width(), + 'height' => $variation->get_height(), + ), + 'shipping_class' => $variation->get_shipping_class(), + 'shipping_class_id' => $variation->get_shipping_class_id(), + 'image' => $this->get_images( $variation ), + 'attributes' => $this->get_attributes( $variation ), + ); + } + + return $variations; + } + + /** + * Prepare a single product output for response. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $post, $request ) { + $product = wc_get_product( $post ); + $data = $this->get_product_data( $product ); + + // Add variations to variable products. + if ( $product->is_type( 'variable' ) && $product->has_child() ) { + $data['variations'] = $this->get_variation_data( $product ); + } + + // Add grouped products data. + if ( $product->is_type( 'grouped' ) && $product->has_child() ) { + $data['grouped_products'] = $product->get_children(); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $product, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $post, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Product $product Product object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given product. + */ + protected function prepare_links( $product, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $product->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + if ( $product->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product->get_parent_id() ) ), + ); + } + + return $links; + } + + /** + * Prepare a single product for create or update. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + + // Type is the most important part here because we need to be using the correct class and methods. + if ( isset( $request['type'] ) ) { + $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); + + if ( ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + + $product = new $classname( $id ); + } elseif ( isset( $request['id'] ) ) { + $product = wc_get_product( $id ); + } else { + $product = new WC_Product_Simple(); + } + + // Post title. + if ( isset( $request['name'] ) ) { + $product->set_name( wp_filter_post_kses( $request['name'] ) ); + } + + // Post content. + if ( isset( $request['description'] ) ) { + $product->set_description( wp_filter_post_kses( $request['description'] ) ); + } + + // Post excerpt. + if ( isset( $request['short_description'] ) ) { + $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); + } + + // Post status. + if ( isset( $request['status'] ) ) { + $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // Post slug. + if ( isset( $request['slug'] ) ) { + $product->set_slug( $request['slug'] ); + } + + // Menu order. + if ( isset( $request['menu_order'] ) ) { + $product->set_menu_order( $request['menu_order'] ); + } + + // Comment status. + if ( isset( $request['reviews_allowed'] ) ) { + $product->set_reviews_allowed( $request['reviews_allowed'] ); + } + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param WC_Product $product An object representing a single item prepared + * for inserting or updating the database. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $product, $request ); + } + + /** + * Create a single product. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $product_id = 0; + + try { + $product_id = $this->save_product( $request ); + $post = get_post( $product_id ); + $this->update_additional_fields_for_object( $post, $request ); + $this->update_post_meta_fields( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_product', $post, $request, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ) ); + + return $response; + } catch ( WC_Data_Exception $e ) { + $this->delete_post( $product_id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + $this->delete_post( $product_id ); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update a single product. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $post_id = (int) $request['id']; + + if ( empty( $post_id ) || get_post_type( $post_id ) !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + try { + $product_id = $this->save_product( $request ); + $post = get_post( $product_id ); + $this->update_additional_fields_for_object( $post, $request ); + $this->update_post_meta_fields( $post, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_product', $post, $request, false ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + + return rest_ensure_response( $response ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Saves a product to the database. + * + * @param WP_REST_Request $request Full details about the request. + * @return int + */ + public function save_product( $request ) { + $product = $this->prepare_item_for_database( $request ); + return $product->save(); + } + + /** + * Save product images. + * + * @deprecated 3.0.0 + * @param int $product_id + * @param array $images + * @throws WC_REST_Exception + */ + protected function save_product_images( $product_id, $images ) { + $product = wc_get_product( $product_id ); + + return set_product_images( $product, $images ); + } + + /** + * Set product images. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param array $images Images data. + * @return WC_Product + */ + protected function set_product_images( $product, $images ) { + if ( is_array( $images ) ) { + $gallery = array(); + + foreach ( $images as $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { + throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + if ( isset( $image['position'] ) && 0 === absint( $image['position'] ) ) { + $product->set_image_id( $attachment_id ); + } else { + $gallery[] = $attachment_id; + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( array( 'ID' => $attachment_id, 'post_title' => $image['name'] ) ); + } + } + + if ( ! empty( $gallery ) ) { + $product->set_gallery_image_ids( $gallery ); + } + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Save product shipping data. + * + * @param WC_Product $product Product instance. + * @param array $data Shipping data. + * @return WC_Product + */ + protected function save_product_shipping_data( $product, $data ) { + // Virtual. + if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { + $product->set_weight( '' ); + $product->set_height( '' ); + $product->set_length( '' ); + $product->set_width( '' ); + } else { + if ( isset( $data['weight'] ) ) { + $product->set_weight( $data['weight'] ); + } + + // Height. + if ( isset( $data['dimensions']['height'] ) ) { + $product->set_height( $data['dimensions']['height'] ); + } + + // Width. + if ( isset( $data['dimensions']['width'] ) ) { + $product->set_width( $data['dimensions']['width'] ); + } + + // Length. + if ( isset( $data['dimensions']['length'] ) ) { + $product->set_length( $data['dimensions']['length'] ); + } + } + + // Shipping class. + if ( isset( $data['shipping_class'] ) ) { + $data_store = $product->get_data_store(); + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + + return $product; + } + + /** + * Save downloadable files. + * + * @param WC_Product $product Product instance. + * @param array $downloads Downloads data. + * @param int $deprecated Deprecated since 3.0. + * @return WC_Product + */ + protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { + if ( $deprecated ) { + wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); + } + + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); + $files[] = $download; + } + $product->set_downloads( $files ); + + return $product; + } + + /** + * Save taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param array $terms Terms data. + * @param string $taxonomy Taxonomy name. + * @return WC_Product + */ + protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { + $term_ids = wp_list_pluck( $terms, 'id' ); + + if ( 'cat' === $taxonomy ) { + $product->set_category_ids( $term_ids ); + } elseif ( 'tag' === $taxonomy ) { + $product->set_tag_ids( $term_ids ); + } + + return $product; + } + + /** + * Save default attributes. + * + * @since 3.0.0 + * + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return WC_Product + */ + protected function save_default_attributes( $product, $request ) { + if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { + $attributes = $product->get_attributes(); + $default_attributes = array(); + + foreach ( $request['default_attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( isset( $attributes[ $attribute_name ] ) ) { + $_attribute = $attributes[ $attribute_name ]; + + if ( $_attribute['is_variation'] ) { + $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( ! empty( $_attribute['is_taxonomy'] ) ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $value = $term->slug; + } else { + $value = sanitize_title( $value ); + } + } + + if ( $value ) { + $default_attributes[ $attribute_name ] = $value; + } + } + } + } + + $product->set_default_attributes( $default_attributes ); + } + + return $product; + } + + /** + * Save product meta. + * + * @deprecated 3.0.0 + * @param WC_Product $product + * @param WP_REST_Request $request + * @return bool + * @throws WC_REST_Exception + */ + protected function save_product_meta( $product, $request ) { + $product = $this->set_product_meta( $product, $request ); + $product->save(); + + return true; + } + + /** + * Set product meta. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return WC_Product + */ + protected function set_product_meta( $product, $request ) { + // Virtual. + if ( isset( $request['virtual'] ) ) { + $product->set_virtual( $request['virtual'] ); + } + + // Tax status. + if ( isset( $request['tax_status'] ) ) { + $product->set_tax_status( $request['tax_status'] ); + } + + // Tax Class. + if ( isset( $request['tax_class'] ) ) { + $product->set_tax_class( $request['tax_class'] ); + } + + // Catalog Visibility. + if ( isset( $request['catalog_visibility'] ) ) { + $product->set_catalog_visibility( $request['catalog_visibility'] ); + } + + // Purchase Note. + if ( isset( $request['purchase_note'] ) ) { + $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); + } + + // Featured Product. + if ( isset( $request['featured'] ) ) { + $product->set_featured( $request['featured'] ); + } + + // Shipping data. + $product = $this->save_product_shipping_data( $product, $request ); + + // SKU. + if ( isset( $request['sku'] ) ) { + $product->set_sku( wc_clean( $request['sku'] ) ); + } + + // Attributes. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + } else { + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $product->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $product->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + } + + // Product parent ID for groups. + if ( isset( $request['parent_id'] ) ) { + $product->set_parent_id( $request['parent_id'] ); + } + + // Sold individually. + if ( isset( $request['sold_individually'] ) ) { + $product->set_sold_individually( $request['sold_individually'] ); + } + + // Stock status. + if ( isset( $request['in_stock'] ) ) { + $stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock'; + } else { + $stock_status = $product->get_stock_status(); + } + + // Stock data. + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock. + if ( isset( $request['manage_stock'] ) ) { + $product->set_manage_stock( $request['manage_stock'] ); + } + + // Backorders. + if ( isset( $request['backorders'] ) ) { + $product->set_backorders( $request['backorders'] ); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( $product->get_manage_stock() ) { + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity. + if ( isset( $request['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells. + if ( isset( $request['upsell_ids'] ) ) { + $upsells = array(); + $ids = $request['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + } + + $product->set_upsell_ids( $upsells ); + } + + // Cross sells. + if ( isset( $request['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $request['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + } + + $product->set_cross_sell_ids( $crosssells ); + } + + // Product categories. + if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['categories'] ); + } + + // Product tags. + if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); + } + + // Downloadable. + if ( isset( $request['downloadable'] ) ) { + $product->set_downloadable( $request['downloadable'] ); + } + + // Downloadable options. + if ( $product->get_downloadable() ) { + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $product->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $product->set_download_expiry( $request['download_expiry'] ); + } + } + + // Product url and button text for external products. + if ( $product->is_type( 'external' ) ) { + if ( isset( $request['external_url'] ) ) { + $product->set_product_url( $request['external_url'] ); + } + + if ( isset( $request['button_text'] ) ) { + $product->set_button_text( $request['button_text'] ); + } + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $request ); + } + + return $product; + } + + /** + * Save variations. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * @return bool + */ + protected function save_variations_data( $product, $request ) { + foreach ( $request['variations'] as $menu_order => $data ) { + $variation = new WC_Product_Variation( isset( $data['id'] ) ? absint( $data['id'] ) : 0 ); + + // Create initial name and status. + if ( ! $variation->get_slug() ) { + /* translators: 1: variation id 2: product name */ + $variation->set_name( sprintf( __( 'Variation #%1$s of %2$s', 'woocommerce' ), $variation->get_id(), $product->get_name() ) ); + $variation->set_status( isset( $data['visible'] ) && false === $data['visible'] ? 'private' : 'publish' ); + } + + // Parent ID. + $variation->set_parent_id( $product->get_id() ); + + // Menu order. + $variation->set_menu_order( $menu_order ); + + // Status. + if ( isset( $data['visible'] ) ) { + $variation->set_status( false === $data['visible'] ? 'private' : 'publish' ); + } + + // SKU. + if ( isset( $data['sku'] ) ) { + $variation->set_sku( wc_clean( $data['sku'] ) ); + } + + // Thumbnail. + if ( isset( $data['image'] ) && is_array( $data['image'] ) ) { + $image = $data['image']; + $image = current( $image ); + if ( is_array( $image ) ) { + $image['position'] = 0; + } + + $variation = $this->set_product_images( $variation, array( $image ) ); + } + + // Virtual variation. + if ( isset( $data['virtual'] ) ) { + $variation->set_virtual( $data['virtual'] ); + } + + // Downloadable variation. + if ( isset( $data['downloadable'] ) ) { + $variation->set_downloadable( $data['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $data['downloads'] ) && is_array( $data['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $data['downloads'] ); + } + + // Download limit. + if ( isset( $data['download_limit'] ) ) { + $variation->set_download_limit( $data['download_limit'] ); + } + + // Download expiry. + if ( isset( $data['download_expiry'] ) ) { + $variation->set_download_expiry( $data['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $data ); + + // Stock handling. + if ( isset( $data['manage_stock'] ) ) { + $variation->set_manage_stock( $data['manage_stock'] ); + } + + if ( isset( $data['in_stock'] ) ) { + $variation->set_stock_status( true === $data['in_stock'] ? 'instock' : 'outofstock' ); + } + + if ( isset( $data['backorders'] ) ) { + $variation->set_backorders( $data['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $data['stock_quantity'] ) ) { + $variation->set_stock_quantity( $data['stock_quantity'] ); + } elseif ( isset( $data['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $data['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $data['regular_price'] ) ) { + $variation->set_regular_price( $data['regular_price'] ); + } + + // Sale Price. + if ( isset( $data['sale_price'] ) ) { + $variation->set_sale_price( $data['sale_price'] ); + } + + if ( isset( $data['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $data['date_on_sale_from'] ); + } + + if ( isset( $data['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $data['date_on_sale_to'] ); + } + + // Tax class. + if ( isset( $data['tax_class'] ) ) { + $variation->set_tax_class( $data['tax_class'] ); + } + + // Description. + if ( isset( $data['description'] ) ) { + $variation->set_description( wp_kses_post( $data['description'] ) ); + } + + // Update taxonomies. + if ( isset( $data['attributes'] ) ) { + $attributes = array(); + $parent_attributes = $product->get_attributes(); + + foreach ( $data['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + $variation->save(); + + do_action( 'woocommerce_rest_save_product_variation', $variation->get_id(), $menu_order, $data ); + } + + return true; + } + + /** + * Add post meta fields. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request data. + * @return bool|WP_Error + */ + protected function add_post_meta_fields( $post, $request ) { + return $this->update_post_meta_fields( $post, $request ); + } + + /** + * Update post meta fields. + * + * @param WP_Post $post Post data. + * @param WP_REST_Request $request Request data. + * @return bool|WP_Error + */ + protected function update_post_meta_fields( $post, $request ) { + $product = wc_get_product( $post ); + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['images'] ) ) { + $product = $this->set_product_images( $product, $request['images'] ); + } + + // Save product meta fields. + $product = $this->set_product_meta( $product, $request ); + + // Save the product data. + $product->save(); + + // Save variations. + if ( $product->is_type( 'variable' ) ) { + if ( isset( $request['variations'] ) && is_array( $request['variations'] ) ) { + $this->save_variations_data( $product, $request ); + } + } + + // Clear caches here so in sync with any new variations/children. + wc_delete_product_transients( $product->get_id() ); + wp_cache_delete( 'product-' . $product->get_id(), 'products' ); + + return true; + } + + /** + * Clear cache/transients. + * + * @param WP_Post $post Post data. + */ + public function clear_transients( $post ) { + wc_delete_product_transients( $post->ID ); + } + + /** + * Delete post. + * + * @param int|WP_Post $id Post ID or WP_Post instance. + */ + protected function delete_post( $id ) { + if ( ! empty( $id->ID ) ) { + $id = $id->ID; + } elseif ( ! is_numeric( $id ) || 0 >= $id ) { + return; + } + + // Delete product attachments. + $attachments = get_posts( array( + 'post_parent' => $id, + 'post_status' => 'any', + 'post_type' => 'attachment', + ) ); + + foreach ( (array) $attachments as $attachment ) { + wp_delete_attachment( $attachment->ID, true ); + } + + // Delete product. + $product = wc_get_product( $id ); + $product->delete( true ); + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = (bool) $request['force']; + $post = get_post( $id ); + $product = wc_get_product( $id ); + + if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0; + + /** + * Filter whether an item is trashable. + * + * Return false to disable trash support for the item. + * + * @param boolean $supports_trash Whether the item type support trashing. + * @param WP_Post $post The Post object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + if ( $product->is_type( 'variable' ) ) { + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->delete( true ); + } + } + } else { + // For other product types, if the product has children, remove the relationship. + foreach ( $product->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->set_parent_id( 0 ); + $child->save(); + } + } + } + + $product->delete( true ); + $result = ! ( $product->get_id() > 0 ); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + } + + // Otherwise, only trash if we haven't already. + if ( 'trash' === $post->post_status ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } + + // (Note that internally this falls through to `wp_delete_post` if + // the trash is disabled.) + $product->delete(); + $result = 'trash' === $product->get_status(); + } + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + // Delete parent product transients. + if ( $parent_id = wp_get_post_parent_id( $id ) ) { + wc_delete_product_transients( $parent_id ); + } + + /** + * Fires after a single item is deleted or trashed via the REST API. + * + * @param object $post The deleted or trashed item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); + + return $response; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'slug' => array( + 'description' => __( 'Product slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'simple', + 'enum' => array_keys( wc_get_product_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), + 'context' => array( 'view', 'edit' ), + ), + 'featured' => array( + 'description' => __( 'Featured product.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'catalog_visibility' => array( + 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'visible', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Product description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'short_description' => array( + 'description' => __( 'Product short description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Product regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Product sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( 'Start date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( 'End date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'on_sale' => array( + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_type' => array( + 'description' => __( 'Download type, this controls the schema on the front-end.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'standard', + 'enum' => array( 'standard' ), + 'context' => array( 'view', 'edit' ), + ), + 'external_url' => array( + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'button_text' => array( + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sold_individually' => array( + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_required' => array( + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_taxable' => array( + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reviews_allowed' => array( + 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'average_rating' => array( + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rating_count' => array( + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'related_ids' => array( + 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'upsell_ids' => array( + 'description' => __( 'List of upsell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'cross_sell_ids' => array( + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'purchase_note' => array( + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'categories' => array( + 'description' => __( 'List of categories.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Category ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Category slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tags' => array( + 'description' => __( 'List of tags.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tag ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Tag slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'images' => array( + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Attribute position.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'visible' => array( + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'variation' => array( + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'options' => array( + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'default_attributes' => array( + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'variations' => array( + 'description' => __( 'List of variations.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Variation ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( 'Start date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( 'End date of sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'visible' => array( + 'description' => __( 'If the variation is visible.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => null, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => null, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['slug'] = array( + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'future' ), array_keys( get_post_statuses() ) ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['type'] = array( + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_types() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['category'] = array( + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['tag'] = array( + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['shipping_class'] = array( + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute'] = array( + 'description' => __( 'Limit result set to products with a specific attribute.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute_term'] = array( + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['sku'] = array( + 'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php new file mode 100644 index 0000000..cc6bb03 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php @@ -0,0 +1,397 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read report. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'reports', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get sales reports. + * + * @param WP_REST_Request $request + * @return array|WP_Error + */ + public function get_items( $request ) { + $data = array(); + $item = $this->prepare_item_for_response( null, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + + return rest_ensure_response( $data ); + } + + /** + * Prepare a report sales object for serialization. + * + * @param null $_ + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $_, $request ) { + // Set date filtering. + $filter = array( + 'period' => $request['period'], + 'date_min' => $request['date_min'], + 'date_max' => $request['date_max'], + ); + $this->setup_report( $filter ); + + // New customers. + $users_query = new WP_User_Query( + array( + 'fields' => array( 'user_registered' ), + 'role' => 'customer', + ) + ); + + $customers = $users_query->get_results(); + + foreach ( $customers as $key => $customer ) { + if ( strtotime( $customer->user_registered ) < $this->report->start_date || strtotime( $customer->user_registered ) > $this->report->end_date ) { + unset( $customers[ $key ] ); + } + } + + $total_customers = count( $customers ); + $report_data = $this->report->get_report_data(); + $period_totals = array(); + + // Setup period totals by ensuring each period in the interval has data. + for ( $i = 0; $i <= $this->report->chart_interval; $i++ ) { + + switch ( $this->report->chart_groupby ) { + case 'day' : + $time = date( 'Y-m-d', strtotime( "+{$i} DAY", $this->report->start_date ) ); + break; + default : + $time = date( 'Y-m', strtotime( "+{$i} MONTH", $this->report->start_date ) ); + break; + } + + // Set the customer signups for each period. + $customer_count = 0; + foreach ( $customers as $customer ) { + if ( date( ( 'day' == $this->report->chart_groupby ) ? 'Y-m-d' : 'Y-m', strtotime( $customer->user_registered ) ) == $time ) { + $customer_count++; + } + } + + $period_totals[ $time ] = array( + 'sales' => wc_format_decimal( 0.00, 2 ), + 'orders' => 0, + 'items' => 0, + 'tax' => wc_format_decimal( 0.00, 2 ), + 'shipping' => wc_format_decimal( 0.00, 2 ), + 'discount' => wc_format_decimal( 0.00, 2 ), + 'customers' => $customer_count, + ); + } + + // add total sales, total order count, total tax and total shipping for each period + foreach ( $report_data->orders as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['sales'] = wc_format_decimal( $order->total_sales, 2 ); + $period_totals[ $time ]['tax'] = wc_format_decimal( $order->total_tax + $order->total_shipping_tax, 2 ); + $period_totals[ $time ]['shipping'] = wc_format_decimal( $order->total_shipping, 2 ); + } + + foreach ( $report_data->order_counts as $order ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['orders'] = (int) $order->count; + } + + // Add total order items for each period. + foreach ( $report_data->order_items as $order_item ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['items'] = (int) $order_item->order_item_count; + } + + // Add total discount for each period. + foreach ( $report_data->coupons as $discount ) { + $time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) ); + + if ( ! isset( $period_totals[ $time ] ) ) { + continue; + } + + $period_totals[ $time ]['discount'] = wc_format_decimal( $discount->discount_amount, 2 ); + } + + $sales_data = array( + 'total_sales' => $report_data->total_sales, + 'net_sales' => $report_data->net_sales, + 'average_sales' => $report_data->average_sales, + 'total_orders' => $report_data->total_orders, + 'total_items' => $report_data->total_items, + 'total_tax' => wc_format_decimal( $report_data->total_tax + $report_data->total_shipping_tax, 2 ), + 'total_shipping' => $report_data->total_shipping, + 'total_refunds' => $report_data->total_refunds, + 'total_discount' => $report_data->total_coupons, + 'totals_grouped_by' => $this->report->chart_groupby, + 'totals' => $period_totals, + 'total_customers' => $total_customers, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $sales_data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + $response->add_links( array( + 'about' => array( + 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), + ), + ) ); + + /** + * Filter a report sales returned from the API. + * + * Allows modification of the report sales data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $data The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_sales', $response, (object) $sales_data, $request ); + } + + /** + * Setup the report object and parse any date filtering. + * + * @param array $filter date filtering + */ + protected function setup_report( $filter ) { + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' ); + include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-report-sales-by-date.php' ); + + $this->report = new WC_Report_Sales_By_Date(); + + if ( empty( $filter['period'] ) ) { + // Custom date range. + $filter['period'] = 'custom'; + + if ( ! empty( $filter['date_min'] ) || ! empty( $filter['date_max'] ) ) { + + // Overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges. + $_GET['start_date'] = $filter['date_min']; + $_GET['end_date'] = isset( $filter['date_max'] ) ? $filter['date_max'] : null; + + } else { + + // Default custom range to today. + $_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) ); + } + } else { + $filter['period'] = empty( $filter['period'] ) ? 'week' : $filter['period']; + + // Change "week" period to "7day". + if ( 'week' === $filter['period'] ) { + $filter['period'] = '7day'; + } + } + + $this->report->calculate_current_range( $filter['period'] ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'sales_report', + 'type' => 'object', + 'properties' => array( + 'total_sales' => array( + 'description' => __( 'Gross sales in the period.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'net_sales' => array( + 'description' => __( 'Net sales in the period.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'average_sales' => array( + 'description' => __( 'Average net daily sales.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_orders' => array( + 'description' => __( 'Total of orders placed.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_items' => array( + 'description' => __( 'Total of items purchased.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Total charged for taxes.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_shipping' => array( + 'description' => __( 'Total charged for shipping.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_refunds' => array( + 'description' => __( 'Total of refunded orders.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total_discount' => array( + 'description' => __( 'Total of coupons used.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'totals_grouped_by' => array( + 'description' => __( 'Group type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'totals' => array( + 'description' => __( 'Totals.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'array', + ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + 'period' => array( + 'description' => __( 'Report period.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'week', 'month', 'last_month', 'year' ), + 'validate_callback' => 'rest_validate_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'date_min' => array( + /* translators: %s: date format */ + 'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), + 'type' => 'string', + 'format' => 'date', + 'validate_callback' => 'wc_rest_validate_reports_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'date_max' => array( + /* translators: %s: date format */ + 'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ), + 'type' => 'string', + 'format' => 'date', + 'validate_callback' => 'wc_rest_validate_reports_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php new file mode 100644 index 0000000..37d2114 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php @@ -0,0 +1,174 @@ + $request['period'], + 'date_min' => $request['date_min'], + 'date_max' => $request['date_max'], + ); + $this->setup_report( $filter ); + + $report_data = $this->report->get_order_report_data( array( + 'data' => array( + '_product_id' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => '', + 'name' => 'product_id', + ), + '_qty' => array( + 'type' => 'order_item_meta', + 'order_item_type' => 'line_item', + 'function' => 'SUM', + 'name' => 'order_item_qty', + ), + ), + 'order_by' => 'order_item_qty DESC', + 'group_by' => 'product_id', + 'limit' => isset( $filter['limit'] ) ? absint( $filter['limit'] ) : 12, + 'query_type' => 'get_results', + 'filter_range' => true, + ) ); + + $top_sellers = array(); + + foreach ( $report_data as $item ) { + $product = wc_get_product( $item->product_id ); + + if ( $product ) { + $top_sellers[] = array( + 'name' => $product->get_name(), + 'product_id' => (int) $item->product_id, + 'quantity' => wc_stock_amount( $item->order_item_qty ), + ); + } + } + + $data = array(); + foreach ( $top_sellers as $top_seller ) { + $item = $this->prepare_item_for_response( (object) $top_seller, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a report sales object for serialization. + * + * @param stdClass $top_seller + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $top_seller, $request ) { + $data = array( + 'name' => $top_seller->name, + 'product_id' => $top_seller->product_id, + 'quantity' => $top_seller->quantity, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + $response->add_links( array( + 'about' => array( + 'href' => rest_url( sprintf( '%s/reports', $this->namespace ) ), + ), + 'product' => array( + 'href' => rest_url( sprintf( '/%s/products/%s', $this->namespace, $top_seller->product_id ) ), + ), + ) ); + + /** + * Filter a report top sellers returned from the API. + * + * Allows modification of the report top sellers data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $top_seller The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_top_sellers', $response, $top_seller, $request ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'top_sellers_report', + 'type' => 'object', + 'properties' => array( + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'quantity' => array( + 'description' => __( 'Total number of purchases.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php new file mode 100644 index 0000000..37b87b7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php @@ -0,0 +1,184 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read reports. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'reports', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get reports list. + * + * @since 3.5.0 + * @return array + */ + protected function get_reports() { + return array( + array( + 'slug' => 'sales', + 'description' => __( 'List of sales reports.', 'woocommerce' ), + ), + array( + 'slug' => 'top_sellers', + 'description' => __( 'List of top sellers products.', 'woocommerce' ), + ), + ); + } + + /** + * Get all reports. + * + * @param WP_REST_Request $request + * @return array|WP_Error + */ + public function get_items( $request ) { + $data = array(); + $reports = $this->get_reports(); + + foreach ( $reports as $report ) { + $item = $this->prepare_item_for_response( (object) $report, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'description' => $report->description, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + $response->add_links( array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $report->slug ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), + ), + ) ); + + /** + * Filter a report returned from the API. + * + * Allows modification of the report data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $report The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report', $response, $report, $request ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'report', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human-readable description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php new file mode 100644 index 0000000..71a9e2d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php @@ -0,0 +1,327 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', + array( + 'args' => array( + 'slug' => array( + 'description' => __( 'Unique slug for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to read tax classes. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create tax classes. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a tax. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all tax classes. + * + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + public function get_items( $request ) { + $tax_classes = array(); + + // Add standard class. + $tax_classes[] = array( + 'slug' => 'standard', + 'name' => __( 'Standard rate', 'woocommerce' ), + ); + + $classes = WC_Tax::get_tax_classes(); + + foreach ( $classes as $class ) { + $tax_classes[] = array( + 'slug' => sanitize_title( $class ), + 'name' => $class, + ); + } + + $data = array(); + foreach ( $tax_classes as $tax_class ) { + $class = $this->prepare_item_for_response( $tax_class, $request ); + $class = $this->prepare_response_for_collection( $class ); + $data[] = $class; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single tax class. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + $tax_class = WC_Tax::create_tax_class( $request['name'] ); + + if ( is_wp_error( $tax_class ) ) { + return new WP_Error( 'woocommerce_rest_' . $tax_class->get_error_code(), $tax_class->get_error_message(), array( 'status' => 400 ) ); + } + + $this->update_additional_fields_for_object( $tax_class, $request ); + + /** + * Fires after a tax class is created or updated via the REST API. + * + * @param stdClass $tax_class Data used to create the tax class. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating tax class, false when updating tax class. + */ + do_action( 'woocommerce_rest_insert_tax_class', (object) $tax_class, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax_class, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $tax_class['slug'] ) ) ); + + return $response; + } + + /** + * Delete a single tax class. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + global $wpdb; + + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $tax_class = WC_Tax::get_tax_class_by( 'slug', sanitize_title( $request['slug'] ) ); + $deleted = WC_Tax::delete_tax_class_by( 'slug', sanitize_title( $request['slug'] ) ); + + if ( ! $deleted ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + if ( is_wp_error( $deleted ) ) { + return new WP_Error( 'woocommerce_rest_' . $deleted->get_error_code(), $deleted->get_error_message(), array( 'status' => 400 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax_class, $request ); + + /** + * Fires after a tax class is deleted via the REST API. + * + * @param stdClass $tax_class The tax data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_tax', (object) $tax_class, $response, $request ); + + return $response; + } + + /** + * Prepare a single tax class output for response. + * + * @param array $tax_class Tax class data. + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $tax_class, $request ) { + $data = $tax_class; + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links() ); + + /** + * Filter tax object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $tax_class Tax object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_tax', $response, (object) $tax_class, $request ); + } + + /** + * Prepare links for the request. + * + * @return array Links for the given tax class. + */ + protected function prepare_links() { + $links = array( + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Tax Classes schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'tax_class', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Tax class name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'required' => true, + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php new file mode 100644 index 0000000..add7876 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php @@ -0,0 +1,709 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read taxes. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create taxes. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access update a tax. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function update_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a tax. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all taxes. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + global $wpdb; + + $prepared_args = array(); + $prepared_args['order'] = $request['order']; + $prepared_args['number'] = $request['per_page']; + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + $orderby_possibles = array( + 'id' => 'tax_rate_id', + 'order' => 'tax_rate_order', + ); + $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; + $prepared_args['class'] = $request['class']; + + /** + * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API. + * + * @param array $prepared_args Array of arguments for $wpdb->get_results(). + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request ); + + $query = " + SELECT * + FROM {$wpdb->prefix}woocommerce_tax_rates + WHERE 1 = 1 + "; + + // Filter by tax class. + if ( ! empty( $prepared_args['class'] ) ) { + $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : ''; + $query .= " AND tax_rate_class = '$class'"; + } + + // Order tax rates. + $order_by = sprintf( ' ORDER BY %s', sanitize_key( $prepared_args['orderby'] ) ); + + // Pagination. + $pagination = sprintf( ' LIMIT %d, %d', $prepared_args['offset'], $prepared_args['number'] ); + + // Query taxes. + $results = $wpdb->get_results( $query . $order_by . $pagination ); + + $taxes = array(); + foreach ( $results as $tax ) { + $data = $this->prepare_item_for_response( $tax, $request ); + $taxes[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $taxes ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + // Query only for ids. + $wpdb->get_results( str_replace( 'SELECT *', 'SELECT tax_rate_id', $query ) ); + + // Calculate totals. + $total_taxes = (int) $wpdb->num_rows; + $response->header( 'X-WP-Total', (int) $total_taxes ); + $max_pages = ceil( $total_taxes / $per_page ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); + if ( $page > 1 ) { + $prev_page = $page - 1; + if ( $prev_page > $max_pages ) { + $prev_page = $max_pages; + } + $prev_link = add_query_arg( 'page', $prev_page, $base ); + $response->link_header( 'prev', $prev_link ); + } + if ( $max_pages > $page ) { + $next_page = $page + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Take tax data from the request and return the updated or newly created rate. + * + * @param WP_REST_Request $request Full details about the request. + * @param stdClass|null $current Existing tax object. + * @return object + */ + protected function create_or_update_tax( $request, $current = null ) { + $id = absint( isset( $request['id'] ) ? $request['id'] : 0 ); + $data = array(); + $fields = array( + 'tax_rate_country', + 'tax_rate_state', + 'tax_rate', + 'tax_rate_name', + 'tax_rate_priority', + 'tax_rate_compound', + 'tax_rate_shipping', + 'tax_rate_order', + 'tax_rate_class', + ); + + foreach ( $fields as $field ) { + // Keys via API differ from the stored names returned by _get_tax_rate. + $key = 'tax_rate' === $field ? 'rate' : str_replace( 'tax_rate_', '', $field ); + + // Remove data that was not posted. + if ( ! isset( $request[ $key ] ) ) { + continue; + } + + // Test new data against current data. + if ( $current && $current->$field === $request[ $key ] ) { + continue; + } + + // Add to data array. + switch ( $key ) { + case 'tax_rate_priority' : + case 'tax_rate_compound' : + case 'tax_rate_shipping' : + case 'tax_rate_order' : + $data[ $field ] = absint( $request[ $key ] ); + break; + case 'tax_rate_class' : + $data[ $field ] = 'standard' !== $request['tax_rate_class'] ? $request['tax_rate_class'] : ''; + break; + default : + $data[ $field ] = wc_clean( $request[ $key ] ); + break; + } + } + + if ( $id ) { + WC_Tax::_update_tax_rate( $id, $data ); + } else { + $id = WC_Tax::_insert_tax_rate( $data ); + } + + // Add locales. + if ( ! empty( $request['postcode'] ) ) { + WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $request['postcode'] ) ); + } + if ( ! empty( $request['city'] ) ) { + WC_Tax::_update_tax_rate_cities( $id, wc_clean( $request['city'] ) ); + } + + return WC_Tax::_get_tax_rate( $id, OBJECT ); + } + + /** + * Create a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $tax = $this->create_or_update_tax( $request ); + + $this->update_additional_fields_for_object( $tax, $request ); + + /** + * Fires after a tax is created or updated via the REST API. + * + * @param stdClass $tax Data used to create the tax. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating tax, false when updating tax. + */ + do_action( 'woocommerce_rest_insert_tax', $tax, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ) ); + + return $response; + } + + /** + * Get a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); + + if ( empty( $id ) || empty( $tax_obj ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $tax = $this->prepare_item_for_response( $tax_obj, $request ); + $response = rest_ensure_response( $tax ); + + return $response; + } + + /** + * Update a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); + + if ( empty( $id ) || empty( $tax_obj ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $tax = $this->create_or_update_tax( $request, $tax_obj ); + + $this->update_additional_fields_for_object( $tax, $request ); + + /** + * Fires after a tax is created or updated via the REST API. + * + * @param stdClass $tax Data used to create the tax. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating tax, false when updating tax. + */ + do_action( 'woocommerce_rest_insert_tax', $tax, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax, $request ); + $response = rest_ensure_response( $response ); + + return $response; + } + + /** + * Delete a single tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + global $wpdb; + + $id = (int) $request['id']; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $tax = WC_Tax::_get_tax_rate( $id, OBJECT ); + + if ( empty( $id ) || empty( $tax ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tax, $request ); + + WC_Tax::_delete_tax_rate( $id ); + + if ( 0 === $wpdb->rows_affected ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a tax is deleted via the REST API. + * + * @param stdClass $tax The tax data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_tax', $tax, $response, $request ); + + return $response; + } + + /** + * Prepare a single tax output for response. + * + * @param stdClass $tax Tax object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $tax, $request ) { + global $wpdb; + + $id = (int) $tax->tax_rate_id; + $data = array( + 'id' => $id, + 'country' => $tax->tax_rate_country, + 'state' => $tax->tax_rate_state, + 'postcode' => '', + 'city' => '', + 'rate' => $tax->tax_rate, + 'name' => $tax->tax_rate_name, + 'priority' => (int) $tax->tax_rate_priority, + 'compound' => (bool) $tax->tax_rate_compound, + 'shipping' => (bool) $tax->tax_rate_shipping, + 'order' => (int) $tax->tax_rate_order, + 'class' => $tax->tax_rate_class ? $tax->tax_rate_class : 'standard', + ); + + // Get locales from a tax rate. + $locales = $wpdb->get_results( $wpdb->prepare( " + SELECT location_code, location_type + FROM {$wpdb->prefix}woocommerce_tax_rate_locations + WHERE tax_rate_id = %d + ", $id ) ); + + if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) { + foreach ( $locales as $locale ) { + $data[ $locale->location_type ] = $locale->location_code; + } + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $tax ) ); + + /** + * Filter tax object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $tax Tax object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_tax', $response, $tax, $request ); + } + + /** + * Prepare links for the request. + * + * @param stdClass $tax Tax object. + * @return array Links for the given tax. + */ + protected function prepare_links( $tax ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Taxes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'tax', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'country' => array( + 'description' => __( 'Country ISO 3166 code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'State code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postcode / ZIP.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'rate' => array( + 'description' => __( 'Tax rate.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tax rate name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'priority' => array( + 'description' => __( 'Tax priority.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 1, + 'context' => array( 'view', 'edit' ), + ), + 'compound' => array( + 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'shipping' => array( + 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'order' => array( + 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'standard', + 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = array(); + $params['context'] = $this->get_context_param(); + $params['context']['default'] = 'view'; + + $params['page'] = array( + 'description' => __( 'Current page of the collection.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'default' => 'asc', + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'enum' => array( 'asc', 'desc' ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'default' => 'order', + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'enum' => array( + 'id', + 'order', + ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['class'] = array( + 'description' => __( 'Sort by tax class.', 'woocommerce' ), + 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'sanitize_callback' => 'sanitize_title', + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php new file mode 100644 index 0000000..638e8b2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php @@ -0,0 +1,314 @@ +/deliveries endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Webhook Deliveries controller class. + * + * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. + * @package WooCommerce\RestApi + * @extends WC_REST_Controller + */ +class WC_REST_Webhook_Deliveries_V1_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'webhooks/(?P[\d]+)/deliveries'; + + /** + * Register the routes for webhook deliveries. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'webhook_id' => array( + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'webhook_id' => array( + 'description' => __( 'Unique identifier for the webhook.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read taxes. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a tax. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all webhook deliveries. + * + * @param WP_REST_Request $request + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $webhook = wc_get_webhook( (int) $request['webhook_id'] ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $logs = array(); + $data = array(); + foreach ( $logs as $log ) { + $delivery = $this->prepare_item_for_response( (object) $log, $request ); + $delivery = $this->prepare_response_for_collection( $delivery ); + $data[] = $delivery; + } + + return rest_ensure_response( $data ); + } + + /** + * Get a single webhook delivery. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $webhook = wc_get_webhook( (int) $request['webhook_id'] ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $log = array(); + + if ( empty( $id ) || empty( $log ) ) { + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $delivery = $this->prepare_item_for_response( (object) $log, $request ); + $response = rest_ensure_response( $delivery ); + + return $response; + } + + /** + * Prepare a single webhook delivery output for response. + * + * @param stdClass $log Delivery log object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $log, $request ) { + $data = (array) $log; + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $log ) ); + + /** + * Filter webhook delivery object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $log Delivery log object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_webhook_delivery', $response, $log, $request ); + } + + /** + * Prepare links for the request. + * + * @param stdClass $log Delivery log object. + * @return array Links for the given webhook delivery. + */ + protected function prepare_links( $log ) { + $webhook_id = (int) $log->request_headers['X-WC-Webhook-ID']; + $base = str_replace( '(?P[\d]+)', $webhook_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $log->id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/webhooks/%d', $this->namespace, $webhook_id ) ), + ), + ); + + return $links; + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook_delivery', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'duration' => array( + 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'summary' => array( + 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_url' => array( + 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_headers' => array( + 'description' => __( 'Request headers.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'request_body' => array( + 'description' => __( 'Request body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_code' => array( + 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_message' => array( + 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_headers' => array( + 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'response_body' => array( + 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php new file mode 100644 index 0000000..4a2463a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php @@ -0,0 +1,763 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'topic' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook topic.', 'woocommerce' ), + ), + 'delivery_url' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Webhook delivery URL.', 'woocommerce' ), + ), + ) ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read webhooks. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access create webhooks. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access update a webhook. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function update_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access delete a webhook. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'webhooks', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get the default REST API version. + * + * @since 3.0.0 + * @return string + */ + protected function get_default_api_version() { + return 'wp_api_v1'; + } + + /** + * Get all webhooks. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $args = array(); + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['status'] = 'all' === $request['status'] ? '' : $request['status']; + $args['include'] = implode( ',', $request['include'] ); + $args['exclude'] = implode( ',', $request['exclude'] ); + $args['limit'] = $request['per_page']; + $args['search'] = $request['search']; + $args['before'] = $request['before']; + $args['after'] = $request['after']; + + if ( empty( $request['offset'] ) ) { + $args['offset'] = 1 < $request['page'] ? ( $request['page'] - 1 ) * $args['limit'] : 0; + } + + /** + * Filter arguments, before passing to WC_Webhook_Data_Store->search_webhooks, when querying webhooks via the REST API. + * + * @param array $args Array of arguments for $wpdb->get_results(). + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_webhook_query', $args, $request ); + unset( $prepared_args['page'] ); + $prepared_args['paginate'] = true; + + // Get the webhooks. + $webhooks = array(); + $data_store = WC_Data_Store::load( 'webhook' ); + $results = $data_store->search_webhooks( $prepared_args ); + $webhook_ids = $results->webhooks; + + foreach ( $webhook_ids as $webhook_id ) { + $data = $this->prepare_item_for_response( $webhook_id, $request ); + $webhooks[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $webhooks ); + $per_page = (int) $prepared_args['limit']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + $total_webhooks = $results->total; + $max_pages = $results->max_num_pages; + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); + + $response->header( 'X-WP-Total', $total_webhooks ); + $response->header( 'X-WP-TotalPages', $max_pages ); + + if ( $page > 1 ) { + $prev_page = $page - 1; + if ( $prev_page > $max_pages ) { + $prev_page = $max_pages; + } + $prev_link = add_query_arg( 'page', $prev_page, $base ); + $response->link_header( 'prev', $prev_link ); + } + if ( $max_pages > $page ) { + $next_page = $page + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Get a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + + if ( empty( $id ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $id, $request ); + $response = rest_ensure_response( $data ); + + return $response; + } + + /** + * Create a single webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + // Validate topic. + if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Validate delivery URL. + if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + + $webhook = new WC_Webhook(); + $webhook->set_name( $post->post_title ); + $webhook->set_user_id( $post->post_author ); + $webhook->set_status( 'publish' === $post->post_status ? 'active' : 'disabled' ); + $webhook->set_topic( $request['topic'] ); + $webhook->set_delivery_url( $request['delivery_url'] ); + $webhook->set_secret( ! empty( $request['secret'] ) ? $request['secret'] : wp_generate_password( 50, true, true ) ); + $webhook->set_api_version( $this->get_default_api_version() ); + $webhook->save(); + + $this->update_additional_fields_for_object( $webhook, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WC_Webhook $webhook Webhook data. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $webhook->get_id() ) ) ); + + // Send ping. + $webhook->deliver_ping(); + + return $response; + } + + /** + * Update a single webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Update topic. + if ( ! empty( $request['topic'] ) ) { + if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) { + $webhook->set_topic( $request['topic'] ); + } else { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + // Update delivery URL. + if ( ! empty( $request['delivery_url'] ) ) { + if ( wc_is_valid_url( $request['delivery_url'] ) ) { + $webhook->set_delivery_url( $request['delivery_url'] ); + } else { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + // Update secret. + if ( ! empty( $request['secret'] ) ) { + $webhook->set_secret( $request['secret'] ); + } + + // Update status. + if ( ! empty( $request['status'] ) ) { + if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) { + $webhook->set_status( $request['status'] ); + } else { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + + if ( isset( $post->post_title ) ) { + $webhook->set_name( $post->post_title ); + } + + $webhook->save(); + + $this->update_additional_fields_for_object( $webhook, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WC_Webhook $webhook Webhook data. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_webhook_object", $webhook, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $webhook->get_id(), $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a single webhook. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $webhook, $request ); + $result = $webhook->delete( true ); + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single item is deleted or trashed via the REST API. + * + * @param WC_Webhook $webhook The deleted or trashed item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_webhook_object", $webhook, $response, $request ); + + return $response; + } + + /** + * Prepare a single webhook for create or update. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|stdClass $data Post object. + */ + protected function prepare_item_for_database( $request ) { + $data = new stdClass; + + // Post ID. + if ( isset( $request['id'] ) ) { + $data->ID = absint( $request['id'] ); + } + + // Validate required POST fields. + if ( 'POST' === $request->get_method() && empty( $data->ID ) ) { + $data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ); // @codingStandardsIgnoreLine + + // Post author. + $data->post_author = get_current_user_id(); + + // Post password. + $data->post_password = 'webhook_' . wp_generate_password(); + + // Post status. + $data->post_status = 'publish'; + } else { + + // Allow edit post title. + if ( ! empty( $request['name'] ) ) { + $data->post_title = $request['name']; + } + } + + // Comment status. + $data->comment_status = 'closed'; + + // Ping status. + $data->ping_status = 'closed'; + + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being + * prepared for insertion. + * + * @param stdClass $data An object representing a single item prepared + * for inserting or updating the database. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $data, $request ); + } + + /** + * Prepare a single webhook output for response. + * + * @param int $id Webhook ID or object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $id, $request ) { + $webhook = wc_get_webhook( $id ); + + if ( empty( $webhook ) || is_null( $webhook ) ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $data = array( + 'id' => $webhook->get_id(), + 'name' => $webhook->get_name(), + 'status' => $webhook->get_status(), + 'topic' => $webhook->get_topic(), + 'resource' => $webhook->get_resource(), + 'event' => $webhook->get_event(), + 'hooks' => $webhook->get_hooks(), + 'delivery_url' => $webhook->get_delivery_url(), + 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $webhook->get_id() ) ); + + /** + * Filter webhook object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Webhook $webhook Webhook object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request ); + } + + /** + * Prepare links for the request. + * + * @param int $id Webhook ID. + * @return array + */ + protected function prepare_links( $id ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Webhook status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'active', + 'enum' => array_keys( wc_get_webhook_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'topic' => array( + 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'resource' => array( + 'description' => __( 'Webhook resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'event' => array( + 'description' => __( 'Webhook event.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'hooks' => array( + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'delivery_url' => array( + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'secret' => array( + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['before'] = array( + 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + $params['include'] = array( + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( + 'date', + 'id', + 'title', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['status'] = array( + 'default' => 'all', + 'description' => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'all', 'active', 'paused', 'disabled' ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php new file mode 100644 index 0000000..f8598fc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php @@ -0,0 +1,542 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'required' => true, + 'type' => 'string', + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data + */ + protected function get_object( $id ) { + return new WC_Coupon( $id ); + } + + /** + * Get formatted item data. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data instance. + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + + $format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' ); + $format_date = array( 'date_created', 'date_modified', 'date_expires' ); + $format_null = array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], 2 ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format null values. + foreach ( $format_null as $key ) { + $data[ $key ] = $data[ $key ] ? $data[ $key ] : null; + } + + return array( + 'id' => $object->get_id(), + 'code' => $data['code'], + 'amount' => $data['amount'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'discount_type' => $data['discount_type'], + 'description' => $data['description'], + 'date_expires' => $data['date_expires'], + 'date_expires_gmt' => $data['date_expires_gmt'], + 'usage_count' => $data['usage_count'], + 'individual_use' => $data['individual_use'], + 'product_ids' => $data['product_ids'], + 'excluded_product_ids' => $data['excluded_product_ids'], + 'usage_limit' => $data['usage_limit'], + 'usage_limit_per_user' => $data['usage_limit_per_user'], + 'limit_usage_to_x_items' => $data['limit_usage_to_x_items'], + 'free_shipping' => $data['free_shipping'], + 'product_categories' => $data['product_categories'], + 'excluded_product_categories' => $data['excluded_product_categories'], + 'exclude_sale_items' => $data['exclude_sale_items'], + 'minimum_amount' => $data['minimum_amount'], + 'maximum_amount' => $data['maximum_amount'], + 'email_restrictions' => $data['email_restrictions'], + 'used_by' => $data['used_by'], + 'meta_data' => $data['meta_data'], + ); + } + + /** + * Prepare a single coupon output for response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $data = $this->get_formatted_item_data( $object ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + if ( ! empty( $request['code'] ) ) { + $id = wc_get_coupon_id_by_code( $request['code'] ); + $args['post__in'] = array( $id ); + } + + // Get only ids. + $args['fields'] = 'ids'; + + return $args; + } + + /** + * Only return writable props from schema. + * + * @param array $schema Schema. + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Prepare a single coupon for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $coupon = new WC_Coupon( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Validate required POST fields. + if ( $creating && empty( $request['code'] ) ) { + return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) ); + } + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'code': + $coupon_code = wc_format_coupon_code( $value ); + $id = $coupon->get_id() ? $coupon->get_id() : 0; + $id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id ); + + if ( $id_from_code ) { + return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $coupon->set_code( $coupon_code ); + break; + case 'meta_data': + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + case 'description': + $coupon->set_description( wp_filter_post_kses( $value ) ); + break; + default: + if ( is_callable( array( $coupon, "set_{$key}" ) ) ) { + $coupon->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $coupon Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $coupon, $request, $creating ); + } + + /** + * Get the Coupon's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the object.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'amount' => array( + 'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_type' => array( + 'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'fixed_cart', + 'enum' => array_keys( wc_get_coupon_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Coupon description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_expires' => array( + 'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_expires_gmt' => array( + 'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'usage_count' => array( + 'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'individual_use' => array( + 'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_ids' => array( + 'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'excluded_product_ids' => array( + 'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit' => array( + 'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'usage_limit_per_user' => array( + 'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'limit_usage_to_x_items' => array( + 'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'free_shipping' => array( + 'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'product_categories' => array( + 'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'excluded_product_categories' => array( + 'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'exclude_sale_items' => array( + 'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'minimum_amount' => array( + 'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'maximum_amount' => array( + 'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email_restrictions' => array( + 'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'context' => array( 'view', 'edit' ), + ), + 'used_by' => array( + 'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['code'] = array( + 'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php new file mode 100644 index 0000000..fd48b05 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php @@ -0,0 +1,165 @@ +/downloads endpoint. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Customers controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Customer_Downloads_V1_Controller + */ +class WC_REST_Customer_Downloads_V2_Controller extends WC_REST_Customer_Downloads_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Prepare a single download output for response. + * + * @param stdClass $download Download object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $download, $request ) { + $data = array( + 'download_id' => $download->download_id, + 'download_url' => $download->download_url, + 'product_id' => $download->product_id, + 'product_name' => $download->product_name, + 'download_name' => $download->download_name, + 'order_id' => $download->order_id, + 'order_key' => $download->order_key, + 'downloads_remaining' => '' === $download->downloads_remaining ? 'unlimited' : $download->downloads_remaining, + 'access_expires' => $download->access_expires ? wc_rest_prepare_date_response( $download->access_expires ) : 'never', + 'access_expires_gmt' => $download->access_expires ? wc_rest_prepare_date_response( get_gmt_from_date( $download->access_expires ) ) : 'never', + 'file' => $download->file, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $download, $request ) ); + + /** + * Filter customer download data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $download Download object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); + } + + /** + * Get the Customer Download's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer_download', + 'type' => 'object', + 'properties' => array( + 'download_id' => array( + 'description' => __( 'Download ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_url' => array( + 'description' => __( 'Download file URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Downloadable product ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'product_name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'download_name' => array( + 'description' => __( 'Downloadable file name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_id' => array( + 'description' => __( 'Order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'downloads_remaining' => array( + 'description' => __( 'Number of downloads remaining.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'access_expires' => array( + 'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'access_expires_gmt' => array( + 'description' => __( 'The date when download access expires, as GMT.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File details.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php new file mode 100644 index 0000000..b7e023b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php @@ -0,0 +1,364 @@ +get_data(); + $format_date = array( 'date_created', 'date_modified' ); + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + return array( + 'id' => $object->get_id(), + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => $data['email'], + 'first_name' => $data['first_name'], + 'last_name' => $data['last_name'], + 'role' => $data['role'], + 'username' => $data['username'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'is_paying_customer' => $data['is_paying_customer'], + 'orders_count' => $object->get_order_count(), + 'total_spent' => $object->get_total_spent(), + 'avatar_url' => $object->get_avatar_url(), + 'meta_data' => $data['meta_data'], + ); + } + + /** + * Prepare a single customer output for response. + * + * @param WP_User $user_data User object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $user_data, $request ) { + $customer = new WC_Customer( $user_data->ID ); + $data = $this->get_formatted_item_data( $customer ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $user_data ) ); + + /** + * Filter customer data returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_User $user_data User object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request ); + } + + /** + * Update customer meta fields. + * + * @param WC_Customer $customer Customer data. + * @param WP_REST_Request $request Request data. + */ + protected function update_customer_meta_fields( $customer, $request ) { + parent::update_customer_meta_fields( $customer, $request ); + + // Meta data. + if ( isset( $request['meta_data'] ) ) { + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $customer->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + } + } + + /** + * Get the Customer's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'email' => array( + 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'first_name' => array( + 'description' => __( 'Customer first name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'last_name' => array( + 'description' => __( 'Customer last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'role' => array( + 'description' => __( 'Customer role.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'username' => array( + 'description' => __( 'Customer login name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_user', + ), + ), + 'password' => array( + 'description' => __( 'Customer password.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'billing' => array( + 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'is_paying_customer' => array( + 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), + 'type' => 'bool', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'orders_count' => array( + 'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_spent' => array( + 'description' => __( 'Total amount spent.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avatar_url' => array( + 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php new file mode 100644 index 0000000..b6a0538 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php @@ -0,0 +1,174 @@ +namespace, + '/' . $this->rest_base . '/network', + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'network_orders' ), + 'permission_callback' => array( $this, 'network_orders_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + } + + /** + * Retrieves the item's schema for display / public consumption purposes. + * + * @return array Public item schema data. + */ + public function get_public_item_schema() { + $schema = parent::get_public_item_schema(); + + $schema['properties']['blog'] = array( + 'description' => __( 'Blog id of the record on the multisite.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['edit_url'] = array( + 'description' => __( 'URL to edit the order', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['customer'][] = array( + 'description' => __( 'Name of the customer for the order', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['status_name'][] = array( + 'description' => __( 'Order Status', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + $schema['properties']['formatted_total'][] = array( + 'description' => __( 'Order total formatted for locale', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ); + + return $schema; + } + + /** + * Does a permissions check for the proper requested blog + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool $permission + */ + public function network_orders_permissions_check( $request ) { + $blog_id = $request->get_param( 'blog_id' ); + $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); + + switch_to_blog( $blog_id ); + + $permission = $this->get_items_permissions_check( $request ); + + restore_current_blog(); + + return $permission; + } + + /** + * Get a collection of orders from the requested blog id + * + * @param WP_REST_Request $request Full details about the request. + * + * @return WP_REST_Response + */ + public function network_orders( $request ) { + $blog_id = $request->get_param( 'blog_id' ); + $blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id(); + $active_plugins = get_blog_option( $blog_id, 'active_plugins', array() ); + $network_active_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + + $plugins = array_merge( $active_plugins, $network_active_plugins ); + $wc_active = false; + foreach ( $plugins as $plugin ) { + if ( substr_compare( $plugin, '/woocommerce.php', strlen( $plugin ) - strlen( '/woocommerce.php' ), strlen( '/woocommerce.php' ) ) === 0 ) { + $wc_active = true; + } + } + + // If WooCommerce not active for site, return an empty response. + if ( ! $wc_active ) { + $response = rest_ensure_response( array() ); + return $response; + } + + switch_to_blog( $blog_id ); + add_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); + $items = $this->get_items( $request ); + remove_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) ); + + foreach ( $items->data as &$current_order ) { + $order = wc_get_order( $current_order['id'] ); + + $current_order['blog'] = get_blog_details( get_current_blog_id() ); + $current_order['edit_url'] = get_admin_url( $blog_id, 'post.php?post=' . absint( $order->get_id() ) . '&action=edit' ); + /* translators: 1: first name 2: last name */ + $current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) ); + $current_order['status_name'] = wc_get_order_status_name( $order->get_status() ); + $current_order['formatted_total'] = $order->get_formatted_order_total(); + } + + restore_current_blog(); + + return $items; + } + + /** + * Filters the post statuses to on hold and processing for the network order query. + * + * @param array $args Query args. + * + * @return array + */ + public function network_orders_filter_args( $args ) { + $args['post_status'] = array( + 'wc-on-hold', + 'wc-processing', + ); + + return $args; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php new file mode 100644 index 0000000..2861539 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php @@ -0,0 +1,182 @@ +/notes endpoint. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Order Notes controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Order_Notes_V1_Controller + */ +class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Get order notes from an order. + * + * @param WP_REST_Request $request Request data. + * + * @return array|WP_Error + */ + public function get_items( $request ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $args = array( + 'post_id' => $order->get_id(), + 'approve' => 'approve', + 'type' => 'order_note', + ); + + // Allow filter by order note type. + if ( 'customer' === $request['type'] ) { + $args['meta_query'] = array( // WPCS: slow query ok. + array( + 'key' => 'is_customer_note', + 'value' => 1, + 'compare' => '=', + ), + ); + } elseif ( 'internal' === $request['type'] ) { + $args['meta_query'] = array( // WPCS: slow query ok. + array( + 'key' => 'is_customer_note', + 'compare' => 'NOT EXISTS', + ), + ); + } + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $notes = get_comments( $args ); + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $data = array(); + foreach ( $notes as $note ) { + $order_note = $this->prepare_item_for_response( $note, $request ); + $order_note = $this->prepare_response_for_collection( $order_note ); + $data[] = $order_note; + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a single order note output for response. + * + * @param WP_Comment $note Order note object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $note, $request ) { + $data = array( + 'id' => (int) $note->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $note ) ); + + /** + * Filter order note object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $note Order note object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); + } + + /** + * Get the Order Notes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'order_note', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'note' => array( + 'description' => __( 'Order note content.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_note' => array( + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = array(); + $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); + $params['type'] = array( + 'default' => 'any', + 'description' => __( 'Limit result to customers or internal notes.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'any', 'customer', 'internal' ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php new file mode 100644 index 0000000..d08e86b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php @@ -0,0 +1,591 @@ +/refunds endpoint. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Order Refunds controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Orders_V2_Controller + */ +class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'orders/(?P[\d]+)/refunds'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'shop_order_refund'; + + /** + * Stores the request. + * + * @var array + */ + protected $request = array(); + + /** + * Order refunds actions. + */ + public function __construct() { + add_filter( "woocommerce_rest_{$this->post_type}_object_trashable", '__return_false' ); + } + + /** + * Register the routes for order refunds. + */ + public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'order_id' => array( + 'description' => __( 'The order ID.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => true, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get object. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data + */ + protected function get_object( $id ) { + return wc_get_order( $id ); + } + + /** + * Get formatted item data. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data instance. + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + $format_decimal = array( 'amount' ); + $format_date = array( 'date_created' ); + $format_line_items = array( 'line_items', 'shipping_lines', 'tax_lines', 'fee_lines' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format line items. + foreach ( $format_line_items as $key ) { + $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); + } + + return array( + 'id' => $object->get_id(), + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'amount' => $data['amount'], + 'reason' => $data['reason'], + 'refunded_by' => $data['refunded_by'], + 'refunded_payment' => $data['refunded_payment'], + 'meta_data' => $data['meta_data'], + 'line_items' => $data['line_items'], + 'shipping_lines' => $data['shipping_lines'], + 'tax_lines' => $data['tax_lines'], + 'fee_lines' => $data['fee_lines'], + ); + } + + /** + * Prepare a single order output for response. + * + * @since 3.0.0 + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * + * @return WP_Error|WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $this->request = $request; + $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + if ( ! $object || $object->get_parent_id() !== $order->get_id() ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 ); + } + + $data = $this->get_formatted_item_data( $object ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $base = str_replace( '(?P[\d]+)', $object->get_parent_id(), $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), + ), + ); + + return $links; + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + $args['post_status'] = array_keys( wc_get_order_statuses() ); + $args['post_parent__in'] = array( absint( $request['order_id'] ) ); + + return $args; + } + + /** + * Prepares one object for create or update operation. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + if ( 0 > $request['amount'] ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + } + + // Create the refund. + $refund = wc_create_refund( + array( + 'order_id' => $order->get_id(), + 'amount' => $request['amount'], + 'reason' => empty( $request['reason'] ) ? null : $request['reason'], + 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, + 'restock_items' => true, + ) + ); + + if ( is_wp_error( $refund ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + } + + if ( ! $refund ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $refund->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + $refund->save_meta_data(); + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $coupon Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating ); + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'amount' => array( + 'description' => __( 'Refund amount.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'reason' => array( + 'description' => __( 'Reason for refund.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'refunded_by' => array( + 'description' => __( 'User ID of user who created the refund.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'refunded_payment' => array( + 'description' => __( 'If the payment was refunded via the API.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'api_refund' => array( + 'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'edit' ), + 'default' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + unset( $params['status'], $params['customer'], $params['product'] ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php new file mode 100644 index 0000000..5126619 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -0,0 +1,1774 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. Return false if object is not of required type. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data|bool + */ + protected function get_object( $id ) { + $order = wc_get_order( $id ); + // In case id is a refund's id (or it's not an order at all), don't expose it via /orders/ path. + if ( ! $order || 'shop_order_refund' === $order->get_type() ) { + return false; + } + + return $order; + } + + /** + * Expands an order item to get its data. + * + * @param WC_Order_item $item Order item data. + * @return array + */ + protected function get_order_item_data( $item ) { + $data = $item->get_data(); + $format_decimal = array( 'subtotal', 'subtotal_tax', 'total', 'total_tax', 'tax_total', 'shipping_tax_total' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + if ( isset( $data[ $key ] ) ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + } + + // Add SKU and PRICE to products. + if ( is_callable( array( $item, 'get_product' ) ) ) { + $data['sku'] = $item->get_product() ? $item->get_product()->get_sku() : null; + $data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0; + } + + // Add parent_name if the product is a variation. + if ( is_callable( array( $item, 'get_product' ) ) ) { + $product = $item->get_product(); + + if ( is_callable( array( $product, 'get_parent_data' ) ) ) { + $data['parent_name'] = $product->get_title(); + } else { + $data['parent_name'] = null; + } + } + + // Format taxes. + if ( ! empty( $data['taxes']['total'] ) ) { + $taxes = array(); + + foreach ( $data['taxes']['total'] as $tax_rate_id => $tax ) { + $taxes[] = array( + 'id' => $tax_rate_id, + 'total' => $tax, + 'subtotal' => isset( $data['taxes']['subtotal'][ $tax_rate_id ] ) ? $data['taxes']['subtotal'][ $tax_rate_id ] : '', + ); + } + $data['taxes'] = $taxes; + } elseif ( isset( $data['taxes'] ) ) { + $data['taxes'] = array(); + } + + // Remove names for coupons, taxes and shipping. + if ( isset( $data['code'] ) || isset( $data['rate_code'] ) || isset( $data['method_title'] ) ) { + unset( $data['name'] ); + } + + // Remove props we don't want to expose. + unset( $data['order_id'] ); + unset( $data['type'] ); + + // Expand meta_data to include user-friendly values. + $formatted_meta_data = $item->get_formatted_meta_data( null, true ); + $data['meta_data'] = array_map( + array( $this, 'merge_meta_item_with_formatted_meta_display_attributes' ), + $data['meta_data'], + array_fill( 0, count( $data['meta_data'] ), $formatted_meta_data ) + ); + + return $data; + } + + /** + * Merge the `$formatted_meta_data` `display_key` and `display_value` attribute values into the corresponding + * {@link WC_Meta_Data}. Returns the merged array. + * + * @param WC_Meta_Data $meta_item An object from {@link WC_Order_Item::get_meta_data()}. + * @param array $formatted_meta_data An object result from {@link WC_Order_Item::get_formatted_meta_data}. + * The keys are the IDs of {@link WC_Meta_Data}. + * + * @return array + */ + private function merge_meta_item_with_formatted_meta_display_attributes( $meta_item, $formatted_meta_data ) { + $result = array( + 'id' => $meta_item->id, + 'key' => $meta_item->key, + 'value' => $meta_item->value, + 'display_key' => $meta_item->key, // Default to original key, in case a formatted key is not available. + 'display_value' => $meta_item->value, // Default to original value, in case a formatted value is not available. + ); + + if ( array_key_exists( $meta_item->id, $formatted_meta_data ) ) { + $formatted_meta_item = $formatted_meta_data[ $meta_item->id ]; + + $result['display_key'] = wc_clean( $formatted_meta_item->display_key ); + $result['display_value'] = wc_clean( $formatted_meta_item->display_value ); + } + + return $result; + } + + /** + * Get formatted item data. + * + * @since 3.0.0 + * @param WC_Data $object WC_Data instance. + * @return array + */ + protected function get_formatted_item_data( $object ) { + $data = $object->get_data(); + $format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' ); + $format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' ); + $format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' ); + + // Format decimal values. + foreach ( $format_decimal as $key ) { + $data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] ); + } + + // Format date values. + foreach ( $format_date as $key ) { + $datetime = $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + // Format the order status. + $data['status'] = 'wc-' === substr( $data['status'], 0, 3 ) ? substr( $data['status'], 3 ) : $data['status']; + + // Format line items. + foreach ( $format_line_items as $key ) { + $data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) ); + } + + // Refunds. + $data['refunds'] = array(); + foreach ( $object->get_refunds() as $refund ) { + $data['refunds'][] = array( + 'id' => $refund->get_id(), + 'reason' => $refund->get_reason() ? $refund->get_reason() : '', + 'total' => '-' . wc_format_decimal( $refund->get_amount(), $this->request['dp'] ), + ); + } + + return array( + 'id' => $object->get_id(), + 'parent_id' => $data['parent_id'], + 'number' => $data['number'], + 'order_key' => $data['order_key'], + 'created_via' => $data['created_via'], + 'version' => $data['version'], + 'status' => $data['status'], + 'currency' => $data['currency'], + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'discount_total' => $data['discount_total'], + 'discount_tax' => $data['discount_tax'], + 'shipping_total' => $data['shipping_total'], + 'shipping_tax' => $data['shipping_tax'], + 'cart_tax' => $data['cart_tax'], + 'total' => $data['total'], + 'total_tax' => $data['total_tax'], + 'prices_include_tax' => $data['prices_include_tax'], + 'customer_id' => $data['customer_id'], + 'customer_ip_address' => $data['customer_ip_address'], + 'customer_user_agent' => $data['customer_user_agent'], + 'customer_note' => $data['customer_note'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'payment_method' => $data['payment_method'], + 'payment_method_title' => $data['payment_method_title'], + 'transaction_id' => $data['transaction_id'], + 'date_paid' => $data['date_paid'], + 'date_paid_gmt' => $data['date_paid_gmt'], + 'date_completed' => $data['date_completed'], + 'date_completed_gmt' => $data['date_completed_gmt'], + 'cart_hash' => $data['cart_hash'], + 'meta_data' => $data['meta_data'], + 'line_items' => $data['line_items'], + 'tax_lines' => $data['tax_lines'], + 'shipping_lines' => $data['shipping_lines'], + 'fee_lines' => $data['fee_lines'], + 'coupon_lines' => $data['coupon_lines'], + 'refunds' => $data['refunds'], + ); + } + + /** + * Prepare a single order output for response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $this->request = $request; + $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] ); + $data = $this->get_formatted_item_data( $object ); + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + if ( 0 !== (int) $object->get_customer_id() ) { + $links['customer'] = array( + 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $object->get_customer_id() ) ), + ); + } + + if ( 0 !== (int) $object->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ), + ); + } + + return $links; + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + global $wpdb; + + $args = parent::prepare_objects_query( $request ); + + // Set post_status. + if ( in_array( $request['status'], $this->get_order_statuses(), true ) ) { + $args['post_status'] = 'wc-' . $request['status']; + } elseif ( 'any' === $request['status'] ) { + $args['post_status'] = 'any'; + } else { + $args['post_status'] = $request['status']; + } + + if ( isset( $request['customer'] ) ) { + if ( ! empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + } + + $args['meta_query'][] = array( + 'key' => '_customer_user', + 'value' => $request['customer'], + 'type' => 'NUMERIC', + ); + } + + // Search by product. + if ( ! empty( $request['product'] ) ) { + $order_ids = $wpdb->get_col( + $wpdb->prepare( + "SELECT order_id + FROM {$wpdb->prefix}woocommerce_order_items + WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value = %d ) + AND order_item_type = 'line_item'", + $request['product'] + ) + ); + + // Force WP_Query return empty if don't found any order. + $order_ids = ! empty( $order_ids ) ? $order_ids : array( 0 ); + + $args['post__in'] = $order_ids; + } + + // Search. + if ( ! empty( $args['s'] ) ) { + $order_ids = wc_order_search( $args['s'] ); + + if ( ! empty( $order_ids ) ) { + unset( $args['s'] ); + $args['post__in'] = array_merge( $order_ids, array( 0 ) ); + } + } + + /** + * Filter the query arguments for a request. + * + * Enables adding extra arguments or setting defaults for an order collection request. + * + * @param array $args Key value array of query var to query value. + * @param WP_REST_Request $request The request used. + */ + $args = apply_filters( 'woocommerce_rest_orders_prepare_object_query', $args, $request ); + + return $args; + } + + /** + * Only return writable props from schema. + * + * @param array $schema Schema. + * @return bool + */ + protected function filter_writable_props( $schema ) { + return empty( $schema['readonly'] ); + } + + /** + * Prepare a single order for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $order = new WC_Order( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'status': + // Status change should be done later so transitions have new data. + break; + case 'billing': + case 'shipping': + $this->update_address( $order, $value, $key ); + break; + case 'line_items': + case 'shipping_lines': + case 'fee_lines': + case 'coupon_lines': + if ( is_array( $value ) ) { + foreach ( $value as $item ) { + if ( is_array( $item ) ) { + if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { + $order->remove_item( $item['id'] ); + } else { + $this->set_item( $order, $key, $item ); + } + } + } + } + break; + case 'meta_data': + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + default: + if ( is_callable( array( $order, "set_{$key}" ) ) ) { + $order->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $order Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @throws WC_REST_Exception But all errors are validated before returning any data. + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + // Make sure gateways are loaded so hooks from gateways fire on save/create. + WC()->payment_gateways(); + + if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { + // Make sure customer exists. + if ( false === get_user_by( 'id', $request['customer_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { + add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + } + } + + if ( $creating ) { + $object->set_created_via( 'rest-api' ); + $object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $object->calculate_totals(); + } else { + // If items have changed, recalculate order totals. + if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { + $object->calculate_totals( true ); + } + } + + // Set status. + if ( ! empty( $request['status'] ) ) { + $object->set_status( $request['status'] ); + } + + $object->save(); + + // Actions for after the order is saved. + if ( true === $request['set_paid'] ) { + if ( $creating || $object->needs_payment() ) { + $object->payment_complete( $request['transaction_id'] ); + } + } + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Update address. + * + * @param WC_Order $order Order data. + * @param array $posted Posted data. + * @param string $type Address type. + */ + protected function update_address( $order, $posted, $type = 'billing' ) { + foreach ( $posted as $key => $value ) { + if ( is_callable( array( $order, "set_{$type}_{$key}" ) ) ) { + $order->{"set_{$type}_{$key}"}( $value ); + } + } + } + + /** + * Gets the product ID from the SKU or posted ID. + * + * @throws WC_REST_Exception When SKU or ID is not valid. + * @param array $posted Request data. + * @param string $action 'create' to add line item or 'update' to update it. + * @return int + */ + protected function get_product_id( $posted, $action = 'create' ) { + if ( ! empty( $posted['sku'] ) ) { + $product_id = (int) wc_get_product_id_by_sku( $posted['sku'] ); + } elseif ( ! empty( $posted['product_id'] ) && empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['product_id']; + } elseif ( ! empty( $posted['variation_id'] ) ) { + $product_id = (int) $posted['variation_id']; + } elseif ( 'update' === $action ) { + $product_id = 0; + } else { + throw new WC_REST_Exception( 'woocommerce_rest_required_product_reference', __( 'Product ID or SKU is required.', 'woocommerce' ), 400 ); + } + return $product_id; + } + + /** + * Maybe set an item prop if the value was posted. + * + * @param WC_Order_Item $item Order item. + * @param string $prop Order property. + * @param array $posted Request data. + */ + protected function maybe_set_item_prop( $item, $prop, $posted ) { + if ( isset( $posted[ $prop ] ) ) { + $item->{"set_$prop"}( $posted[ $prop ] ); + } + } + + /** + * Maybe set item props if the values were posted. + * + * @param WC_Order_Item $item Order item data. + * @param string[] $props Properties. + * @param array $posted Request data. + */ + protected function maybe_set_item_props( $item, $props, $posted ) { + foreach ( $props as $prop ) { + $this->maybe_set_item_prop( $item, $prop, $posted ); + } + } + + /** + * Maybe set item meta if posted. + * + * @param WC_Order_Item $item Order item data. + * @param array $posted Request data. + */ + protected function maybe_set_item_meta_data( $item, $posted ) { + if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) { + foreach ( $posted['meta_data'] as $meta ) { + if ( isset( $meta['key'] ) ) { + $value = isset( $meta['value'] ) ? $meta['value'] : null; + $item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + } + } + + /** + * Create or update a line item. + * + * @param array $posted Line item data. + * @param string $action 'create' to add line item or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return WC_Order_Item_Product + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_line_items( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + $product = wc_get_product( $this->get_product_id( $posted, $action ) ); + + if ( $product && $product !== $item->get_product() ) { + $item->set_product( $product ); + + if ( 'create' === $action ) { + $quantity = isset( $posted['quantity'] ) ? $posted['quantity'] : 1; + $total = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) ); + $item->set_total( $total ); + $item->set_subtotal( $total ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'quantity', 'total', 'subtotal', 'tax_class' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Create or update an order shipping method. + * + * @param array $posted $shipping Item data. + * @param string $action 'create' to add shipping or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return WC_Order_Item_Shipping + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + + if ( 'create' === $action ) { + if ( empty( $posted['method_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_shipping_item', __( 'Shipping method ID is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'method_id', 'method_title', 'total', 'instance_id' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Create or update an order fee. + * + * @param array $posted Item data. + * @param string $action 'create' to add fee or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return WC_Order_Item_Fee + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + + if ( 'create' === $action ) { + if ( empty( $posted['name'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_fee_item', __( 'Fee name is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'name', 'tax_class', 'tax_status', 'total' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Create or update an order coupon. + * + * @param array $posted Item data. + * @param string $action 'create' to add coupon or 'update' to update it. + * @param object $item Passed when updating an item. Null during creation. + * @return WC_Order_Item_Coupon + * @throws WC_REST_Exception Invalid data, server error. + */ + protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) { + $item = is_null( $item ) ? new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item; + + if ( 'create' === $action ) { + if ( empty( $posted['code'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + } + + $this->maybe_set_item_props( $item, array( 'code', 'discount' ), $posted ); + $this->maybe_set_item_meta_data( $item, $posted ); + + return $item; + } + + /** + * Wrapper method to create/update order items. + * When updating, the item ID provided is checked to ensure it is associated + * with the order. + * + * @param WC_Order $order order object. + * @param string $item_type The item type. + * @param array $posted item provided in the request body. + * @throws WC_REST_Exception If item ID is not associated with order. + */ + protected function set_item( $order, $item_type, $posted ) { + global $wpdb; + + if ( ! empty( $posted['id'] ) ) { + $action = 'update'; + } else { + $action = 'create'; + } + + $method = 'prepare_' . $item_type; + $item = null; + + // Verify provided line item ID is associated with order. + if ( 'update' === $action ) { + $item = $order->get_item( absint( $posted['id'] ), false ); + + if ( ! $item ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); + } + } + + // Prepare item data. + $item = $this->$method( $posted, $action, $item ); + + do_action( 'woocommerce_rest_set_order_item', $item, $posted ); + + // If creating the order, add the item to it. + if ( 'create' === $action ) { + $order->add_item( $item ); + } else { + $item->save(); + } + } + + /** + * Helper method to check if the resource ID associated with the provided item is null. + * Items can be deleted by setting the resource ID to null. + * + * @param array $item Item provided in the request body. + * @return bool True if the item resource ID is null, false otherwise. + */ + protected function item_is_null( $item ) { + $keys = array( 'product_id', 'method_id', 'method_title', 'name', 'code' ); + + foreach ( $keys as $key ) { + if ( array_key_exists( $key, $item ) && is_null( $item[ $key ] ) ) { + return true; + } + } + + return false; + } + + /** + * Get order statuses without prefixes. + * + * @return array + */ + protected function get_order_statuses() { + $order_statuses = array(); + + foreach ( array_keys( wc_get_order_statuses() ) as $status ) { + $order_statuses[] = str_replace( 'wc-', '', $status ); + } + + return $order_statuses; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'parent_id' => array( + 'description' => __( 'Parent order ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'number' => array( + 'description' => __( 'Order number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order_key' => array( + 'description' => __( 'Order key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'created_via' => array( + 'description' => __( 'Shows where the order was created.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'version' => array( + 'description' => __( 'Version of WooCommerce which last updated the order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Order status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'pending', + 'enum' => $this->get_order_statuses(), + 'context' => array( 'view', 'edit' ), + ), + 'currency' => array( + 'description' => __( 'Currency the order was created with, in ISO format.', 'woocommerce' ), + 'type' => 'string', + 'default' => get_woocommerce_currency(), + 'enum' => array_keys( get_woocommerce_currencies() ), + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the order was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the order was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the order was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_total' => array( + 'description' => __( 'Total discount amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'discount_tax' => array( + 'description' => __( 'Total discount tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_total' => array( + 'description' => __( 'Total shipping amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax' => array( + 'description' => __( 'Total shipping tax amount for the order.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_tax' => array( + 'description' => __( 'Sum of line item taxes only.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Grand total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_tax' => array( + 'description' => __( 'Sum of all taxes.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'prices_include_tax' => array( + 'description' => __( 'True the prices included tax during checkout.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_id' => array( + 'description' => __( 'User ID who owns the order. 0 for guests.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 0, + 'context' => array( 'view', 'edit' ), + ), + 'customer_ip_address' => array( + 'description' => __( "Customer's IP address.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_user_agent' => array( + 'description' => __( 'User agent of the customer.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_note' => array( + 'description' => __( 'Note left by customer during checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'billing' => array( + 'description' => __( 'Billing address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'Shipping address.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'Country code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'payment_method' => array( + 'description' => __( 'Payment method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'payment_method_title' => array( + 'description' => __( 'Payment method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'transaction_id' => array( + 'description' => __( 'Unique transaction ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_paid' => array( + 'description' => __( "The date the order was paid, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_paid_gmt' => array( + 'description' => __( 'The date the order was paid, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_completed' => array( + 'description' => __( "The date the order was completed, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_completed_gmt' => array( + 'description' => __( 'The date the order was completed, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'cart_hash' => array( + 'description' => __( 'MD5 hash of cart items to ensure orders are not modified.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'line_items' => array( + 'description' => __( 'Line items data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'parent_name' => array( + 'description' => __( 'Parent product name if the product is a variation.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'product_id' => array( + 'description' => __( 'Product ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'variation_id' => array( + 'description' => __( 'Variation ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'quantity' => array( + 'description' => __( 'Quantity ordered.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of product.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'subtotal' => array( + 'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'subtotal_tax' => array( + 'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'display_key' => array( + 'description' => __( 'Meta key for UI display.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'display_value' => array( + 'description' => __( 'Meta value for UI display.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'sku' => array( + 'description' => __( 'Product SKU.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'price' => array( + 'description' => __( 'Product price.', 'woocommerce' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tax_lines' => array( + 'description' => __( 'Tax lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_code' => array( + 'description' => __( 'Tax rate code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rate_id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'Tax rate label.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'compound' => array( + 'description' => __( 'Show if is a compound tax rate.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tax_total' => array( + 'description' => __( 'Tax total (not including shipping taxes).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_tax_total' => array( + 'description' => __( 'Shipping tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'shipping_lines' => array( + 'description' => __( 'Shipping lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_title' => array( + 'description' => __( 'Shipping method name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'method_id' => array( + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'instance_id' => array( + 'description' => __( 'Shipping instance ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'fee_lines' => array( + 'description' => __( 'Fee lines data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Fee name.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status of fee.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'taxable', 'none' ), + ), + 'total' => array( + 'description' => __( 'Line total (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'total_tax' => array( + 'description' => __( 'Line total tax (after discounts).', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxes' => array( + 'description' => __( 'Line taxes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tax rate ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Tax total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotal' => array( + 'description' => __( 'Tax subtotal.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'coupon_lines' => array( + 'description' => __( 'Coupons line data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Item ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'code' => array( + 'description' => __( 'Coupon code.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'discount' => array( + 'description' => __( 'Discount total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'discount_tax' => array( + 'description' => __( 'Discount total tax.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ), + ), + 'refunds' => array( + 'description' => __( 'List of refunds.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Refund ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reason' => array( + 'description' => __( 'Refund reason.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Refund total.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'set_paid' => array( + 'description' => __( 'Define if the order is paid. It will set the status to processing and reduce stock items.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to orders assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['customer'] = array( + 'description' => __( 'Limit result set to orders assigned a specific customer.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['product'] = array( + 'description' => __( 'Limit result set to orders assigned a specific product.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['dp'] = array( + 'default' => wc_get_price_decimals(), + 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php new file mode 100644 index 0000000..eefffa5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php @@ -0,0 +1,466 @@ + + */ + 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' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view payment gateways. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to read a payment gateway. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check whether a given request has permission to edit payment gateways. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get payment gateways. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $payment_gateways = WC()->payment_gateways->payment_gateways(); + $response = array(); + foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { + $payment_gateway->id = $payment_gateway_id; + $gateway = $this->prepare_item_for_response( $payment_gateway, $request ); + $gateway = $this->prepare_response_for_collection( $gateway ); + $response[] = $gateway; + } + return rest_ensure_response( $response ); + } + + /** + * Get a single payment gateway. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $gateway = $this->get_gateway( $request ); + + if ( is_null( $gateway ) ) { + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $gateway = $this->prepare_item_for_response( $gateway, $request ); + return rest_ensure_response( $gateway ); + } + + /** + * Update A Single Payment Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function update_item( $request ) { + $gateway = $this->get_gateway( $request ); + + if ( is_null( $gateway ) ) { + return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Get settings. + $gateway->init_form_fields(); + $settings = $gateway->settings; + + // Update settings. + if ( isset( $request['settings'] ) ) { + $errors_found = false; + foreach ( $gateway->form_fields as $key => $field ) { + if ( isset( $request['settings'][ $key ] ) ) { + if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { + $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); + } else { + $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); + } + if ( is_wp_error( $value ) ) { + $errors_found = true; + break; + } + $settings[ $key ] = $value; + } + } + + if ( $errors_found ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + // Update if this method is enabled or not. + if ( isset( $request['enabled'] ) ) { + $settings['enabled'] = wc_bool_to_string( $request['enabled'] ); + $gateway->enabled = $settings['enabled']; + } + + // Update title. + if ( isset( $request['title'] ) ) { + $settings['title'] = $request['title']; + $gateway->title = $settings['title']; + } + + // Update description. + if ( isset( $request['description'] ) ) { + $settings['description'] = $request['description']; + $gateway->description = $settings['description']; + } + + // Update options. + $gateway->settings = $settings; + update_option( $gateway->get_option_key(), apply_filters( 'woocommerce_gateway_' . $gateway->id . '_settings_values', $settings, $gateway ) ); + + // Update order. + if ( isset( $request['order'] ) ) { + $order = (array) get_option( 'woocommerce_gateway_order' ); + $order[ $gateway->id ] = $request['order']; + update_option( 'woocommerce_gateway_order', $order ); + $gateway->order = absint( $request['order'] ); + } + + $gateway = $this->prepare_item_for_response( $gateway, $request ); + return rest_ensure_response( $gateway ); + } + + /** + * Get a gateway based on the current request object. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|null + */ + public function get_gateway( $request ) { + $gateway = null; + $payment_gateways = WC()->payment_gateways->payment_gateways(); + foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) { + if ( $request['id'] !== $payment_gateway_id ) { + continue; + } + $payment_gateway->id = $payment_gateway_id; + $gateway = $payment_gateway; + } + return $gateway; + } + + /** + * Prepare a payment gateway for response. + * + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $gateway, $request ) { + $order = (array) get_option( 'woocommerce_gateway_order' ); + $item = array( + 'id' => $gateway->id, + 'title' => $gateway->title, + 'description' => $gateway->description, + 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', + 'enabled' => ( 'yes' === $gateway->enabled ), + 'method_title' => $gateway->get_method_title(), + 'method_description' => $gateway->get_method_description(), + 'settings' => $this->get_settings( $gateway ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $gateway, $request ) ); + + /** + * Filter payment gateway objects returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); + } + + /** + * Return settings associated with this payment gateway. + * + * @param WC_Payment_Gateway $gateway Gateway data. + * + * @return array + */ + public function get_settings( $gateway ) { + $settings = array(); + $gateway->init_form_fields(); + foreach ( $gateway->form_fields as $id => $field ) { + // Make sure we at least have a title and type. + if ( empty( $field['title'] ) || empty( $field['type'] ) ) { + continue; + } + // Ignore 'title' settings/fields -- they are UI only. + if ( 'title' === $field['type'] ) { + continue; + } + // Ignore 'enabled' and 'description' which get included elsewhere. + if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { + continue; + } + $data = array( + 'id' => $id, + 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + + /** + * Prepare links for the request. + * + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $gateway, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $gateway->id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the payment gateway schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'payment_gateway', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Payment gateway ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'order' => array( + 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'absint', + ), + ), + 'enabled' => array( + 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'method_title' => array( + 'description' => __( 'Payment gateway method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_description' => array( + 'description' => __( 'Payment gateway method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'settings' => array( + 'description' => __( 'Payment gateway settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php new file mode 100644 index 0000000..09b72eb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php @@ -0,0 +1,27 @@ +/terms endpoint. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Product Attribute Terms controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Product_Attribute_Terms_V1_Controller + */ +class WC_REST_Product_Attribute_Terms_V2_Controller extends WC_REST_Product_Attribute_Terms_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php new file mode 100644 index 0000000..35d8237 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php @@ -0,0 +1,27 @@ +term_id, 'display_type', true ); + + // Get category order. + $menu_order = get_term_meta( $item->term_id, 'order', true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'parent' => (int) $item->parent, + 'description' => $item->description, + 'display' => $display_type ? $display_type : 'default', + 'image' => null, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + // Get category image. + $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); + if ( $image_id ) { + $attachment = get_post( $image_id ); + + $data['image'] = array( + 'id' => (int) $image_id, + 'date_created' => wc_rest_prepare_date_response( $attachment->post_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), + 'src' => wp_get_attachment_url( $image_id ), + 'title' => get_the_title( $attachment ), + 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), + ); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Category schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'parent' => array( + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'display' => array( + 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'default', + 'enum' => array( 'default', 'products', 'subcategories', 'both' ), + 'context' => array( 'view', 'edit' ), + ), + 'image' => array( + 'description' => __( 'Image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'title' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php new file mode 100644 index 0000000..cc34809 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php @@ -0,0 +1,199 @@ +/reviews. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Product Reviews Controller Class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Product_Reviews_V1_Controller + */ +class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/(?P[\d]+)/reviews'; + + /** + * Register the routes for product reviews. + */ + public function register_routes() { + parent::register_routes(); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Check if a given request has access to batch manage product reviews. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( 'product', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Prepare a single product review output for response. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $review, $request ) { + $data = array( + 'id' => (int) $review->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $review->comment_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $review->comment_date_gmt ), + 'review' => $review->comment_content, + 'rating' => (int) get_comment_meta( $review->comment_ID, 'rating', true ), + 'name' => $review->comment_author, + 'email' => $review->comment_author_email, + 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $review, $request ) ); + + /** + * Filter product reviews object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $review Product review object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); + } + + + /** + * Bulk create, update and delete items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + $items = array_filter( $request->get_params() ); + $params = $request->get_url_params(); + $product_id = $params['product_id']; + $body_params = array(); + + foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) { + if ( ! empty( $items[ $batch_type ] ) ) { + $injected_items = array(); + foreach ( $items[ $batch_type ] as $item ) { + $injected_items[] = is_array( $item ) ? array_merge( array( 'product_id' => $product_id ), $item ) : $item; + } + $body_params[ $batch_type ] = $injected_items; + } + } + + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( $body_params ); + + return parent::batch_items( $request ); + } + + /** + * Get the Product Review's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_review', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'review' => array( + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'rating' => array( + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'verified' => array( + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php new file mode 100644 index 0000000..c4db401 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php @@ -0,0 +1,27 @@ +/variations endpoints. + * + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API variations controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Products_V2_Controller + */ +class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'products/(?P[\d]+)/variations'; + + /** + * Post type. + * + * @var string + */ + protected $post_type = 'product_variation'; + + /** + * Register the routes for products. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the variation.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'product_id' => array( + 'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. + * + * @since 3.0.0 + * @param int $id Object ID. + * @return WC_Data + */ + protected function get_object( $id ) { + return wc_get_product( $id ); + } + + /** + * Check if a given request has access to update an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + // Check if variation belongs to the correct parent product. + if ( $object && 0 !== $object->get_parent_id() && absint( $request['product_id'] ) !== $object->get_parent_id() ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Parent product does not match current variation.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Prepare a single variation output for response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $data = array( + 'id' => $object->get_id(), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), + 'description' => wc_format_content( $object->get_description() ), + 'permalink' => $object->get_permalink(), + 'sku' => $object->get_sku(), + 'price' => $object->get_price(), + 'regular_price' => $object->get_regular_price(), + 'sale_price' => $object->get_sale_price(), + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), + 'on_sale' => $object->is_on_sale(), + 'visible' => $object->is_visible(), + 'purchasable' => $object->is_purchasable(), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => $this->get_downloads( $object ), + 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, + 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, + 'tax_status' => $object->get_tax_status(), + 'tax_class' => $object->get_tax_class(), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity(), + 'in_stock' => $object->is_in_stock(), + 'backorders' => $object->get_backorders(), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'weight' => $object->get_weight(), + 'dimensions' => array( + 'length' => $object->get_length(), + 'width' => $object->get_width(), + 'height' => $object->get_height(), + ), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id(), + 'image' => current( $this->get_images( $object ) ), + 'attributes' => $this->get_attributes( $object ), + 'menu_order' => $object->get_menu_order(), + 'meta_data' => $object->get_meta_data(), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + $args['post_parent'] = $request['product_id']; + + return $args; + } + + /** + * Prepare a single variation for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + if ( isset( $request['id'] ) ) { + $variation = wc_get_product( absint( $request['id'] ) ); + } else { + $variation = new WC_Product_Variation(); + } + + // Update parent ID just once. + if ( 0 === $variation->get_parent_id() ) { + $variation->set_parent_id( absint( $request['product_id'] ) ); + } + + // Status. + if ( isset( $request['visible'] ) ) { + $variation->set_status( false === $request['visible'] ? 'private' : 'publish' ); + } + + // SKU. + if ( isset( $request['sku'] ) ) { + $variation->set_sku( wc_clean( $request['sku'] ) ); + } + + // Thumbnail. + if ( isset( $request['image'] ) ) { + if ( is_array( $request['image'] ) && ! empty( $request['image'] ) ) { + $image = $request['image']; + if ( is_array( $image ) ) { + $image['position'] = 0; + } + + $variation = $this->set_product_images( $variation, array( $image ) ); + } else { + $variation->set_image_id( '' ); + } + } + + // Virtual variation. + if ( isset( $request['virtual'] ) ) { + $variation->set_virtual( $request['virtual'] ); + } + + // Downloadable variation. + if ( isset( $request['downloadable'] ) ) { + $variation->set_downloadable( $request['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $variation->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $variation->set_download_expiry( $request['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $request ); + + // Stock handling. + if ( isset( $request['manage_stock'] ) ) { + if ( 'parent' === $request['manage_stock'] ) { + $variation->set_manage_stock( false ); // This just indicates the variation does not manage stock, but the parent does. + } else { + $variation->set_manage_stock( wc_string_to_bool( $request['manage_stock'] ) ); + } + } + + if ( isset( $request['in_stock'] ) ) { + $variation->set_stock_status( true === $request['in_stock'] ? 'instock' : 'outofstock' ); + } + + if ( isset( $request['backorders'] ) ) { + $variation->set_backorders( $request['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $request['stock_quantity'] ) ) { + $variation->set_stock_quantity( $request['stock_quantity'] ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $variation->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $variation->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + + // Tax class. + if ( isset( $request['tax_class'] ) ) { + $variation->set_tax_class( $request['tax_class'] ); + } + + // Description. + if ( isset( $request['description'] ) ) { + $variation->set_description( wp_kses_post( $request['description'] ) ); + } + + // Update taxonomies. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + $parent = wc_get_product( $variation->get_parent_id() ); + $parent_attributes = $parent->get_attributes(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $raw_attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $raw_attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $raw_attribute_name ) { + continue; + } + + $attribute_name = sanitize_title( $raw_attribute_name ); + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $raw_attribute_name ); // @codingStandardsIgnoreLine + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + // Menu order. + if ( $request['menu_order'] ) { + $variation->set_menu_order( $request['menu_order'] ); + } + + // Meta data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $variation Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); + } + + /** + * Clear caches here so in sync with any new variations. + * + * @param WC_Data $object Object data. + */ + public function clear_transients( $object ) { + wc_delete_product_transients( $object->get_parent_id() ); + wp_cache_delete( 'product-' . $object->get_parent_id(), 'products' ); + } + + /** + * Delete a variation. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return bool|WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $force = (bool) $request['force']; + $object = $this->get_object( (int) $request['id'] ); + $result = false; + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( + "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( + 'status' => 404, + ) + ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); + + /** + * Filter whether an object is trashable. + * + * Return false to disable trash support for the object. + * + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + return new WP_Error( + /* translators: %s: post type */ + "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( + 'status' => rest_authorization_required_code(), + ) + ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + $object->delete( true ); + $result = 0 === $object->get_id(); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + return new WP_Error( + /* translators: %s: post type */ + 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( + 'status' => 501, + ) + ); + } + + // Otherwise, only trash if we haven't already. + if ( is_callable( array( $object, 'get_status' ) ) ) { + if ( 'trash' === $object->get_status() ) { + return new WP_Error( + /* translators: %s: post type */ + 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( + 'status' => 410, + ) + ); + } + + $object->delete(); + $result = 'trash' === $object->get_status(); + } + } + + if ( ! $result ) { + return new WP_Error( + /* translators: %s: post type */ + 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( + 'status' => 500, + ) + ); + } + + // Delete parent product transients. + if ( 0 !== $object->get_parent_id() ) { + wc_delete_product_transients( $object->get_parent_id() ); + } + + /** + * Fires after a single object is deleted or trashed via the REST API. + * + * @param WC_Data $object The deleted or trashed object. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); + + return $response; + } + + /** + * Bulk create, update and delete items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + $items = array_filter( $request->get_params() ); + $params = $request->get_url_params(); + $query = $request->get_query_params(); + $product_id = $params['product_id']; + $body_params = array(); + + foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) { + if ( ! empty( $items[ $batch_type ] ) ) { + $injected_items = array(); + foreach ( $items[ $batch_type ] as $item ) { + $injected_items[] = is_array( $item ) ? array_merge( + array( + 'product_id' => $product_id, + ), $item + ) : $item; + } + $body_params[ $batch_type ] = $injected_items; + } + } + + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( $body_params ); + $request->set_query_params( $query ); + + return parent::batch_items( $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $product_id = (int) $request['product_id']; + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + 'up' => array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $product_id ) ), + ), + ); + return $links; + } + + /** + * Get the Variation's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Variation description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'visible' => array( + 'description' => __( "Define if the variation is visible on the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'mixed', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the variation is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php new file mode 100644 index 0000000..ebb4a2f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php @@ -0,0 +1,2209 @@ +post_type}_object", array( $this, 'clear_transients' ) ); + } + + /** + * Register the routes for products. + */ + 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' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + 'type' => 'boolean', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Get object. + * + * @param int $id Object ID. + * + * @since 3.0.0 + * @return WC_Data + */ + protected function get_object( $id ) { + return wc_get_product( $id ); + } + + /** + * Prepare a single product output for response. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * + * @since 3.0.0 + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->get_product_data( $object, $context ); + + // Add variations to variable products. + if ( $object->is_type( 'variable' ) && $object->has_child() ) { + $data['variations'] = $object->get_children(); + } + + // Add grouped products data. + if ( $object->is_type( 'grouped' ) && $object->has_child() ) { + $data['grouped_products'] = $object->get_children(); + } + + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare objects query. + * + * @param WP_REST_Request $request Full details about the request. + * + * @since 3.0.0 + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = parent::prepare_objects_query( $request ); + + // Set post_status. + $args['post_status'] = $request['status']; + + // Taxonomy query to filter products by type, category, + // tag, shipping class, and attribute. + $tax_query = array(); + + // Map between taxonomy name and arg's key. + $taxonomies = array( + 'product_cat' => 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + ); + } + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ); + } + + // Filter by attribute and term. + if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { + if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $tax_query[] = array( + 'taxonomy' => $request['attribute'], + 'field' => 'term_id', + 'terms' => $request['attribute_term'], + ); + } + } + + if ( ! empty( $tax_query ) ) { + $args['tax_query'] = $tax_query; // WPCS: slow query ok. + } + + // Filter featured. + if ( is_bool( $request['featured'] ) ) { + $args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => 'featured', + 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', + ); + } + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) + ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) + ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. + } + + // Filter product in stock or out of stock. + if ( is_bool( $request['in_stock'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_stock_status', + 'value' => true === $request['in_stock'] ? 'instock' : 'outofstock', + ) + ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + return $args; + } + + /** + * Get the downloads for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * + * @return array + */ + protected function get_downloads( $product ) { + $downloads = array(); + + if ( $product->is_downloadable() ) { + foreach ( $product->get_downloads() as $file_id => $file ) { + $downloads[] = array( + 'id' => $file_id, // MD5 hash. + 'name' => $file['name'], + 'file' => $file['file'], + ); + } + } + + return $downloads; + } + + /** + * Get taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param string $taxonomy Taxonomy slug. + * + * @return array + */ + protected function get_taxonomy_terms( $product, $taxonomy = 'cat' ) { + $terms = array(); + + foreach ( wc_get_object_terms( $product->get_id(), 'product_' . $taxonomy ) as $term ) { + $terms[] = array( + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + ); + } + + return $terms; + } + + /** + * Get the images for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * + * @return array + */ + protected function get_images( $product ) { + $images = array(); + $attachment_ids = array(); + + // Add featured image. + if ( $product->get_image_id() ) { + $attachment_ids[] = $product->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $position => $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + 'position' => (int) $position, + ); + } + + // Set a placeholder image if the product has no images set. + if ( empty( $images ) ) { + $images[] = array( + 'id' => 0, + 'date_created' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), // Default to now. + 'date_created_gmt' => wc_rest_prepare_date_response( time() ), // Default to now. + 'date_modified' => wc_rest_prepare_date_response( current_time( 'mysql' ), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( time() ), + 'src' => wc_placeholder_img_src(), + 'name' => __( 'Placeholder', 'woocommerce' ), + 'alt' => __( 'Placeholder', 'woocommerce' ), + 'position' => 0, + ); + } + + return $images; + } + + /** + * Get attribute taxonomy label. + * + * @param string $name Taxonomy name. + * + * @deprecated 3.0.0 + * @return string + */ + protected function get_attribute_taxonomy_label( $name ) { + $tax = get_taxonomy( $name ); + $labels = get_taxonomy_labels( $tax ); + + return $labels->singular_name; + } + + /** + * Get product attribute taxonomy name. + * + * @param string $slug Taxonomy name. + * @param WC_Product $product Product data. + * + * @since 3.0.0 + * @return string + */ + protected function get_attribute_taxonomy_name( $slug, $product ) { + // Format slug so it matches attributes of the product. + $slug = wc_attribute_taxonomy_slug( $slug ); + $attributes = $product->get_attributes(); + $attribute = false; + + // pa_ attributes. + if ( isset( $attributes[ wc_attribute_taxonomy_name( $slug ) ] ) ) { + $attribute = $attributes[ wc_attribute_taxonomy_name( $slug ) ]; + } elseif ( isset( $attributes[ $slug ] ) ) { + $attribute = $attributes[ $slug ]; + } + + if ( ! $attribute ) { + return $slug; + } + + // Taxonomy attribute name. + if ( $attribute->is_taxonomy() ) { + $taxonomy = $attribute->get_taxonomy_object(); + return $taxonomy->attribute_label; + } + + // Custom product attribute name. + return $attribute->get_name(); + } + + /** + * Get default attributes. + * + * @param WC_Product $product Product instance. + * + * @return array + */ + protected function get_default_attributes( $product ) { + $default = array(); + + if ( $product->is_type( 'variable' ) ) { + foreach ( array_filter( (array) $product->get_default_attributes(), 'strlen' ) as $key => $value ) { + if ( 0 === strpos( $key, 'pa_' ) ) { + $default[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $key ), + 'name' => $this->get_attribute_taxonomy_name( $key, $product ), + 'option' => $value, + ); + } else { + $default[] = array( + 'id' => 0, + 'name' => $this->get_attribute_taxonomy_name( $key, $product ), + 'option' => $value, + ); + } + } + } + + return $default; + } + + /** + * Get attribute options. + * + * @param int $product_id Product ID. + * @param array $attribute Attribute data. + * + * @return array + */ + protected function get_attribute_options( $product_id, $attribute ) { + if ( isset( $attribute['is_taxonomy'] ) && $attribute['is_taxonomy'] ) { + return wc_get_product_terms( + $product_id, + $attribute['name'], + array( + 'fields' => 'names', + ) + ); + } elseif ( isset( $attribute['value'] ) ) { + return array_map( 'trim', explode( '|', $attribute['value'] ) ); + } + + return array(); + } + + /** + * Get the attributes for a product or product variation. + * + * @param WC_Product|WC_Product_Variation $product Product instance. + * + * @return array + */ + protected function get_attributes( $product ) { + $attributes = array(); + + if ( $product->is_type( 'variation' ) ) { + $_product = wc_get_product( $product->get_parent_id() ); + foreach ( $product->get_variation_attributes() as $attribute_name => $attribute ) { + $name = str_replace( 'attribute_', '', $attribute_name ); + + if ( empty( $attribute ) && '0' !== $attribute ) { + continue; + } + + // Taxonomy-based attributes are prefixed with `pa_`, otherwise simply `attribute_`. + if ( 0 === strpos( $attribute_name, 'attribute_pa_' ) ) { + $option_term = get_term_by( 'slug', $attribute, $name ); + $attributes[] = array( + 'id' => wc_attribute_taxonomy_id_by_name( $name ), + 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), + 'option' => $option_term && ! is_wp_error( $option_term ) ? $option_term->name : $attribute, + ); + } else { + $attributes[] = array( + 'id' => 0, + 'name' => $this->get_attribute_taxonomy_name( $name, $_product ), + 'option' => $attribute, + ); + } + } + } else { + foreach ( $product->get_attributes() as $attribute ) { + $attributes[] = array( + 'id' => $attribute['is_taxonomy'] ? wc_attribute_taxonomy_id_by_name( $attribute['name'] ) : 0, + 'name' => $this->get_attribute_taxonomy_name( $attribute['name'], $product ), + 'position' => (int) $attribute['position'], + 'visible' => (bool) $attribute['is_visible'], + 'variation' => (bool) $attribute['is_variation'], + 'options' => $this->get_attribute_options( $product->get_id(), $attribute ), + ); + } + } + + return $attributes; + } + + /** + * Get product data. + * + * @param WC_Product $product Product instance. + * @param string $context Request context. + * Options: 'view' and 'edit'. + * + * @return array + */ + protected function get_product_data( $product, $context = 'view' ) { + $data = array( + 'id' => $product->get_id(), + 'name' => $product->get_name( $context ), + 'slug' => $product->get_slug( $context ), + 'permalink' => $product->get_permalink(), + 'date_created' => wc_rest_prepare_date_response( $product->get_date_created( $context ), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $product->get_date_created( $context ) ), + 'date_modified' => wc_rest_prepare_date_response( $product->get_date_modified( $context ), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $product->get_date_modified( $context ) ), + 'type' => $product->get_type(), + 'status' => $product->get_status( $context ), + 'featured' => $product->is_featured(), + 'catalog_visibility' => $product->get_catalog_visibility( $context ), + 'description' => 'view' === $context ? wpautop( do_shortcode( $product->get_description() ) ) : $product->get_description( $context ), + 'short_description' => 'view' === $context ? apply_filters( 'woocommerce_short_description', $product->get_short_description() ) : $product->get_short_description( $context ), + 'sku' => $product->get_sku( $context ), + 'price' => $product->get_price( $context ), + 'regular_price' => $product->get_regular_price( $context ), + 'sale_price' => $product->get_sale_price( $context ) ? $product->get_sale_price( $context ) : '', + 'date_on_sale_from' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_from( $context ) ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $product->get_date_on_sale_to( $context ) ), + 'price_html' => $product->get_price_html(), + 'on_sale' => $product->is_on_sale( $context ), + 'purchasable' => $product->is_purchasable(), + 'total_sales' => $product->get_total_sales( $context ), + 'virtual' => $product->is_virtual(), + 'downloadable' => $product->is_downloadable(), + 'downloads' => $this->get_downloads( $product ), + 'download_limit' => $product->get_download_limit( $context ), + 'download_expiry' => $product->get_download_expiry( $context ), + 'external_url' => $product->is_type( 'external' ) ? $product->get_product_url( $context ) : '', + 'button_text' => $product->is_type( 'external' ) ? $product->get_button_text( $context ) : '', + 'tax_status' => $product->get_tax_status( $context ), + 'tax_class' => $product->get_tax_class( $context ), + 'manage_stock' => $product->managing_stock(), + 'stock_quantity' => $product->get_stock_quantity( $context ), + 'in_stock' => $product->is_in_stock(), + 'backorders' => $product->get_backorders( $context ), + 'backorders_allowed' => $product->backorders_allowed(), + 'backordered' => $product->is_on_backorder(), + 'sold_individually' => $product->is_sold_individually(), + 'weight' => $product->get_weight( $context ), + 'dimensions' => array( + 'length' => $product->get_length( $context ), + 'width' => $product->get_width( $context ), + 'height' => $product->get_height( $context ), + ), + 'shipping_required' => $product->needs_shipping(), + 'shipping_taxable' => $product->is_shipping_taxable(), + 'shipping_class' => $product->get_shipping_class(), + 'shipping_class_id' => $product->get_shipping_class_id( $context ), + 'reviews_allowed' => $product->get_reviews_allowed( $context ), + 'average_rating' => 'view' === $context ? wc_format_decimal( $product->get_average_rating(), 2 ) : $product->get_average_rating( $context ), + 'rating_count' => $product->get_rating_count(), + 'related_ids' => array_map( 'absint', array_values( wc_get_related_products( $product->get_id() ) ) ), + 'upsell_ids' => array_map( 'absint', $product->get_upsell_ids( $context ) ), + 'cross_sell_ids' => array_map( 'absint', $product->get_cross_sell_ids( $context ) ), + 'parent_id' => $product->get_parent_id( $context ), + 'purchase_note' => 'view' === $context ? wpautop( do_shortcode( wp_kses_post( $product->get_purchase_note() ) ) ) : $product->get_purchase_note( $context ), + 'categories' => $this->get_taxonomy_terms( $product ), + 'tags' => $this->get_taxonomy_terms( $product, 'tag' ), + 'images' => $this->get_images( $product ), + 'attributes' => $this->get_attributes( $product ), + 'default_attributes' => $this->get_default_attributes( $product ), + 'variations' => array(), + 'grouped_products' => array(), + 'menu_order' => $product->get_menu_order( $context ), + 'meta_data' => $product->get_meta_data(), + ); + + return $data; + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), // @codingStandardsIgnoreLine. + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), // @codingStandardsIgnoreLine. + ), + ); + + if ( $object->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $object->get_parent_id() ) ), // @codingStandardsIgnoreLine. + ); + } + + return $links; + } + + /** + * Prepare a single product for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + + // Type is the most important part here because we need to be using the correct class and methods. + if ( isset( $request['type'] ) ) { + $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); + + if ( ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + + $product = new $classname( $id ); + } elseif ( isset( $request['id'] ) ) { + $product = wc_get_product( $id ); + } else { + $product = new WC_Product_Simple(); + } + + if ( 'variation' === $product->get_type() ) { + return new WP_Error( + "woocommerce_rest_invalid_{$this->post_type}_id", + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); + } + + // Post title. + if ( isset( $request['name'] ) ) { + $product->set_name( wp_filter_post_kses( $request['name'] ) ); + } + + // Post content. + if ( isset( $request['description'] ) ) { + $product->set_description( wp_filter_post_kses( $request['description'] ) ); + } + + // Post excerpt. + if ( isset( $request['short_description'] ) ) { + $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); + } + + // Post status. + if ( isset( $request['status'] ) ) { + $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // Post slug. + if ( isset( $request['slug'] ) ) { + $product->set_slug( $request['slug'] ); + } + + // Menu order. + if ( isset( $request['menu_order'] ) ) { + $product->set_menu_order( $request['menu_order'] ); + } + + // Comment status. + if ( isset( $request['reviews_allowed'] ) ) { + $product->set_reviews_allowed( $request['reviews_allowed'] ); + } + + // Virtual. + if ( isset( $request['virtual'] ) ) { + $product->set_virtual( $request['virtual'] ); + } + + // Tax status. + if ( isset( $request['tax_status'] ) ) { + $product->set_tax_status( $request['tax_status'] ); + } + + // Tax Class. + if ( isset( $request['tax_class'] ) ) { + $product->set_tax_class( $request['tax_class'] ); + } + + // Catalog Visibility. + if ( isset( $request['catalog_visibility'] ) ) { + $product->set_catalog_visibility( $request['catalog_visibility'] ); + } + + // Purchase Note. + if ( isset( $request['purchase_note'] ) ) { + $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); + } + + // Featured Product. + if ( isset( $request['featured'] ) ) { + $product->set_featured( $request['featured'] ); + } + + // Shipping data. + $product = $this->save_product_shipping_data( $product, $request ); + + // SKU. + if ( isset( $request['sku'] ) ) { + $product->set_sku( wc_clean( $request['sku'] ) ); + } + + // Attributes. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + } else { + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $product->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $product->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + } + + // Product parent ID. + if ( isset( $request['parent_id'] ) ) { + $product->set_parent_id( $request['parent_id'] ); + } + + // Sold individually. + if ( isset( $request['sold_individually'] ) ) { + $product->set_sold_individually( $request['sold_individually'] ); + } + + // Stock status. + if ( isset( $request['in_stock'] ) ) { + $stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock'; + } else { + $stock_status = $product->get_stock_status(); + } + + // Stock data. + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock. + if ( isset( $request['manage_stock'] ) ) { + $product->set_manage_stock( $request['manage_stock'] ); + } + + // Backorders. + if ( isset( $request['backorders'] ) ) { + $product->set_backorders( $request['backorders'] ); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( $product->get_manage_stock() ) { + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity. + if ( isset( $request['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells. + if ( isset( $request['upsell_ids'] ) ) { + $upsells = array(); + $ids = $request['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + } + + $product->set_upsell_ids( $upsells ); + } + + // Cross sells. + if ( isset( $request['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $request['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + } + + $product->set_cross_sell_ids( $crosssells ); + } + + // Product categories. + if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['categories'] ); + } + + // Product tags. + if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); + } + + // Downloadable. + if ( isset( $request['downloadable'] ) ) { + $product->set_downloadable( $request['downloadable'] ); + } + + // Downloadable options. + if ( $product->get_downloadable() ) { + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $product->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $product->set_download_expiry( $request['download_expiry'] ); + } + } + + // Product url and button text for external products. + if ( $product->is_type( 'external' ) ) { + if ( isset( $request['external_url'] ) ) { + $product->set_product_url( $request['external_url'] ); + } + + if ( isset( $request['button_text'] ) ) { + $product->set_button_text( $request['button_text'] ); + } + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $request ); + } + + // Set children for a grouped product. + if ( $product->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { + $product->set_children( $request['grouped_products'] ); + } + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['images'] ) ) { + $product = $this->set_product_images( $product, $request['images'] ); + } + + // Allow set meta_data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $product->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $product Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating ); + } + + /** + * Set product images. + * + * @param WC_Product $product Product instance. + * @param array $images Images data. + * + * @throws WC_REST_Exception REST API exceptions. + * @return WC_Product + */ + protected function set_product_images( $product, $images ) { + $images = is_array( $images ) ? array_filter( $images ) : array(); + + if ( ! empty( $images ) ) { + $gallery_positions = array(); + + foreach ( $images as $index => $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { + throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: attachment id */ + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $gallery_positions[ $attachment_id ] = absint( isset( $image['position'] ) ? $image['position'] : $index ); + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + + // Set the image source if present, for future reference. + if ( ! empty( $image['src'] ) ) { + update_post_meta( $attachment_id, '_wc_attachment_source', esc_url_raw( $image['src'] ) ); + } + } + + // Sort images and get IDs in correct order. + asort( $gallery_positions ); + + // Get gallery in correct order. + $gallery = array_keys( $gallery_positions ); + + // Featured image is in position 0. + $image_id = array_shift( $gallery ); + + // Set images. + $product->set_image_id( $image_id ); + $product->set_gallery_image_ids( $gallery ); + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Save product shipping data. + * + * @param WC_Product $product Product instance. + * @param array $data Shipping data. + * + * @return WC_Product + */ + protected function save_product_shipping_data( $product, $data ) { + // Virtual. + if ( isset( $data['virtual'] ) && true === $data['virtual'] ) { + $product->set_weight( '' ); + $product->set_height( '' ); + $product->set_length( '' ); + $product->set_width( '' ); + } else { + if ( isset( $data['weight'] ) ) { + $product->set_weight( $data['weight'] ); + } + + // Height. + if ( isset( $data['dimensions']['height'] ) ) { + $product->set_height( $data['dimensions']['height'] ); + } + + // Width. + if ( isset( $data['dimensions']['width'] ) ) { + $product->set_width( $data['dimensions']['width'] ); + } + + // Length. + if ( isset( $data['dimensions']['length'] ) ) { + $product->set_length( $data['dimensions']['length'] ); + } + } + + // Shipping class. + if ( isset( $data['shipping_class'] ) ) { + $data_store = $product->get_data_store(); + $shipping_class_id = $data_store->get_shipping_class_id_by_slug( wc_clean( $data['shipping_class'] ) ); + $product->set_shipping_class_id( $shipping_class_id ); + } + + return $product; + } + + /** + * Save downloadable files. + * + * @param WC_Product $product Product instance. + * @param array $downloads Downloads data. + * @param int $deprecated Deprecated since 3.0. + * + * @return WC_Product + */ + protected function save_downloadable_files( $product, $downloads, $deprecated = 0 ) { + if ( $deprecated ) { + wc_deprecated_argument( 'variation_id', '3.0', 'save_downloadable_files() not requires a variation_id anymore.' ); + } + + $files = array(); + foreach ( $downloads as $key => $file ) { + if ( empty( $file['file'] ) ) { + continue; + } + + $download = new WC_Product_Download(); + $download->set_id( ! empty( $file['id'] ) ? $file['id'] : wp_generate_uuid4() ); + $download->set_name( $file['name'] ? $file['name'] : wc_get_filename_from_url( $file['file'] ) ); + $download->set_file( apply_filters( 'woocommerce_file_download_path', $file['file'], $product, $key ) ); + $files[] = $download; + } + $product->set_downloads( $files ); + + return $product; + } + + /** + * Save taxonomy terms. + * + * @param WC_Product $product Product instance. + * @param array $terms Terms data. + * @param string $taxonomy Taxonomy name. + * + * @return WC_Product + */ + protected function save_taxonomy_terms( $product, $terms, $taxonomy = 'cat' ) { + $term_ids = wp_list_pluck( $terms, 'id' ); + + if ( 'cat' === $taxonomy ) { + $product->set_category_ids( $term_ids ); + } elseif ( 'tag' === $taxonomy ) { + $product->set_tag_ids( $term_ids ); + } + + return $product; + } + + /** + * Save default attributes. + * + * @param WC_Product $product Product instance. + * @param WP_REST_Request $request Request data. + * + * @since 3.0.0 + * @return WC_Product + */ + protected function save_default_attributes( $product, $request ) { + if ( isset( $request['default_attributes'] ) && is_array( $request['default_attributes'] ) ) { + + $attributes = $product->get_attributes(); + $default_attributes = array(); + + foreach ( $request['default_attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( isset( $attributes[ $attribute_name ] ) ) { + $_attribute = $attributes[ $attribute_name ]; + + if ( $_attribute['is_variation'] ) { + $value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( ! empty( $_attribute['is_taxonomy'] ) ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $value = $term->slug; + } else { + $value = sanitize_title( $value ); + } + } + + if ( $value ) { + $default_attributes[ $attribute_name ] = $value; + } + } + } + } + + $product->set_default_attributes( $default_attributes ); + } + + return $product; + } + + /** + * Clear caches here so in sync with any new variations/children. + * + * @param WC_Data $object Object data. + */ + public function clear_transients( $object ) { + wc_delete_product_transients( $object->get_id() ); + wp_cache_delete( 'product-' . $object->get_id(), 'products' ); + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = (bool) $request['force']; + $object = $this->get_object( (int) $request['id'] ); + $result = false; + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( + "woocommerce_rest_{$this->post_type}_invalid_id", + __( 'Invalid ID.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); + } + + if ( 'variation' === $object->get_type() ) { + return new WP_Error( + "woocommerce_rest_invalid_{$this->post_type}_id", + __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), + array( + 'status' => 404, + ) + ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); + + /** + * Filter whether an object is trashable. + * + * Return false to disable trash support for the object. + * + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + return new WP_Error( + "woocommerce_rest_user_cannot_delete_{$this->post_type}", + /* translators: %s: post type */ + sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), + array( + 'status' => rest_authorization_required_code(), + ) + ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + if ( $object->is_type( 'variable' ) ) { + foreach ( $object->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->delete( true ); + } + } + } else { + // For other product types, if the product has children, remove the relationship. + foreach ( $object->get_children() as $child_id ) { + $child = wc_get_product( $child_id ); + if ( ! empty( $child ) ) { + $child->set_parent_id( 0 ); + $child->save(); + } + } + } + + $object->delete( true ); + $result = 0 === $object->get_id(); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + return new WP_Error( + 'woocommerce_rest_trash_not_supported', + /* translators: %s: post type */ + sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), + array( + 'status' => 501, + ) + ); + } + + // Otherwise, only trash if we haven't already. + if ( is_callable( array( $object, 'get_status' ) ) ) { + if ( 'trash' === $object->get_status() ) { + return new WP_Error( + 'woocommerce_rest_already_trashed', + /* translators: %s: post type */ + sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), + array( + 'status' => 410, + ) + ); + } + + $object->delete(); + $result = 'trash' === $object->get_status(); + } + } + + if ( ! $result ) { + return new WP_Error( + 'woocommerce_rest_cannot_delete', + /* translators: %s: post type */ + sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), + array( + 'status' => 500, + ) + ); + } + + // Delete parent product transients. + if ( 0 !== $object->get_parent_id() ) { + wc_delete_product_transients( $object->get_parent_id() ); + } + + /** + * Fires after a single object is deleted or trashed via the REST API. + * + * @param WC_Data $object The deleted or trashed object. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); + + return $response; + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'slug' => array( + 'description' => __( 'Product slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'simple', + 'enum' => array_keys( wc_get_product_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), + 'context' => array( 'view', 'edit' ), + ), + 'featured' => array( + 'description' => __( 'Featured product.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'catalog_visibility' => array( + 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'visible', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Product description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'short_description' => array( + 'description' => __( 'Product short description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Product regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Product sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( 'End date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'on_sale' => array( + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'external_url' => array( + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'button_text' => array( + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'in_stock' => array( + 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sold_individually' => array( + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_required' => array( + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_taxable' => array( + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reviews_allowed' => array( + 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'average_rating' => array( + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rating_count' => array( + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'related_ids' => array( + 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'upsell_ids' => array( + 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'cross_sell_ids' => array( + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'purchase_note' => array( + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'categories' => array( + 'description' => __( 'List of categories.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Category ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Category slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tags' => array( + 'description' => __( 'List of tags.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tag ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Tag slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'images' => array( + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Image position. 0 means that the image is featured.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Attribute position.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'visible' => array( + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'variation' => array( + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'options' => array( + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + 'default_attributes' => array( + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'variations' => array( + 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + 'readonly' => true, + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'menu_order' ) ); + + $params['slug'] = array( + 'description' => __( 'Limit result set to products with a specific slug.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'future', 'trash' ), array_keys( get_post_statuses() ) ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['type'] = array( + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_types() ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['sku'] = array( + 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['featured'] = array( + 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['category'] = array( + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['tag'] = array( + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['shipping_class'] = array( + 'description' => __( 'Limit result set to products assigned a specific shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute'] = array( + 'description' => __( 'Limit result set to products with a specific attribute. Use the taxonomy name/attribute slug.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['attribute_term'] = array( + 'description' => __( 'Limit result set to products with a specific attribute term ID (required an assigned attribute).', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + if ( wc_tax_enabled() ) { + $params['tax_class'] = array( + 'description' => __( 'Limit result set to products with a specific tax class.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + } + + $params['in_stock'] = array( + 'description' => __( 'Limit result set to products in stock or out of stock.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['on_sale'] = array( + 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['min_price'] = array( + 'description' => __( 'Limit result set to products based on a minimum price.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['max_price'] = array( + 'description' => __( 'Limit result set to products based on a maximum price.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php new file mode 100644 index 0000000..1ba6041 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php @@ -0,0 +1,27 @@ +[\w-]+)'; + + /** + * Register routes. + * + * @since 3.0.0 + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base, array( + 'args' => array( + 'group' => array( + 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + 'args' => array( + 'group' => array( + 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + 'args' => array( + 'group' => array( + 'description' => __( 'Settings group ID.', 'woocommerce' ), + 'type' => 'string', + ), + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Return a single setting. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $setting = $this->get_setting( $request['group_id'], $request['id'] ); + + if ( is_wp_error( $setting ) ) { + return $setting; + } + + $response = $this->prepare_item_for_response( $setting, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Return all settings in a group. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $settings = $this->get_group_settings( $request['group_id'] ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + + $data = array(); + + foreach ( $settings as $setting_obj ) { + $setting = $this->prepare_item_for_response( $setting_obj, $request ); + $setting = $this->prepare_response_for_collection( $setting ); + if ( $this->is_setting_type_valid( $setting['type'] ) ) { + $data[] = $setting; + } + } + + return rest_ensure_response( $data ); + } + + /** + * Get all settings in a group. + * + * @since 3.0.0 + * @param string $group_id Group ID. + * @return array|WP_Error + */ + public function get_group_settings( $group_id ) { + if ( empty( $group_id ) ) { + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); + + if ( empty( $settings ) ) { + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_settings = array(); + foreach ( $settings as $setting ) { + $option_key = $setting['option_key']; + $setting = $this->filter_setting( $setting ); + $default = isset( $setting['default'] ) ? $setting['default'] : ''; + // Get the option value. + if ( is_array( $option_key ) ) { + $option = get_option( $option_key[0] ); + $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; + } else { + $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); + $setting['value'] = $admin_setting_value; + } + + if ( 'multi_select_countries' === $setting['type'] ) { + $setting['options'] = WC()->countries->get_countries(); + $setting['type'] = 'multiselect'; + } elseif ( 'single_select_country' === $setting['type'] ) { + $setting['type'] = 'select'; + $setting['options'] = $this->get_countries_and_states(); + } + + $filtered_settings[] = $setting; + } + + return $filtered_settings; + } + + /** + * Returns a list of countries and states for use in the base location setting. + * + * @since 3.0.7 + * @return array Array of states and countries. + */ + private function get_countries_and_states() { + $countries = WC()->countries->get_countries(); + if ( ! $countries ) { + return array(); + } + + $output = array(); + + foreach ( $countries as $key => $value ) { + $states = WC()->countries->get_states( $key ); + if ( $states ) { + foreach ( $states as $state_key => $state_value ) { + $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; + } + } else { + $output[ $key ] = $value; + } + } + + return $output; + } + + /** + * Get setting data. + * + * @since 3.0.0 + * @param string $group_id Group ID. + * @param string $setting_id Setting ID. + * @return stdClass|WP_Error + */ + public function get_setting( $group_id, $setting_id ) { + if ( empty( $setting_id ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $settings = $this->get_group_settings( $group_id ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + + $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); + + if ( empty( $array_key ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $setting = $settings[ $array_key[0] ]; + + if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return $setting; + } + + /** + * Bulk create, update and delete items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + // Get the request params. + $items = array_filter( $request->get_params() ); + + /* + * Since our batch settings update is group-specific and matches based on the route, + * we inject the URL parameters (containing group) into the batch items + */ + if ( ! empty( $items['update'] ) ) { + $to_update = array(); + foreach ( $items['update'] as $item ) { + $to_update[] = array_merge( $request->get_url_params(), $item ); + } + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( array( 'update' => $to_update ) ); + } + + return parent::batch_items( $request ); + } + + /** + * Update a single setting in a group. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $setting = $this->get_setting( $request['group_id'], $request['id'] ); + + if ( is_wp_error( $setting ) ) { + return $setting; + } + + if ( is_callable( array( $this, 'validate_setting_' . $setting['type'] . '_field' ) ) ) { + $value = $this->{'validate_setting_' . $setting['type'] . '_field'}( $request['value'], $setting ); + } else { + $value = $this->validate_setting_text_field( $request['value'], $setting ); + } + + if ( is_wp_error( $value ) ) { + return $value; + } + + if ( is_array( $setting['option_key'] ) ) { + $setting['value'] = $value; + $option_key = $setting['option_key']; + $prev = get_option( $option_key[0] ); + $prev[ $option_key[1] ] = $request['value']; + update_option( $option_key[0], $prev ); + } else { + $update_data = array(); + $update_data[ $setting['option_key'] ] = $value; + $setting['value'] = $value; + WC_Admin_Settings::save_fields( array( $setting ), $update_data ); + } + + $response = $this->prepare_item_for_response( $setting, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Prepare a single setting object for response. + * + * @since 3.0.0 + * @param object $item Setting object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + unset( $item['option_key'] ); + $data = $this->filter_setting( $item ); + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, empty( $request['context'] ) ? 'view' : $request['context'] ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $data['id'], $request['group_id'] ) ); + return $response; + } + + /** + * Prepare links for the request. + * + * @since 3.0.0 + * @param string $setting_id Setting ID. + * @param string $group_id Group ID. + * @return array Links for the given setting. + */ + protected function prepare_links( $setting_id, $group_id ) { + $base = str_replace( '(?P[\w-]+)', $group_id, $this->rest_base ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $base, $setting_id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), + ), + ); + + return $links; + } + + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Makes sure the current user has access to WRITE the settings APIs. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * + * @since 3.0.0 + * @param array $setting Settings. + * @return array + */ + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); + } + + if ( 'image_width' === $setting['type'] ) { + $setting = $this->cast_image_width( $setting ); + } + + return $setting; + } + + /** + * For image_width, Crop can return "0" instead of false -- so we want + * to make sure we return these consistently the same we accept them. + * + * @todo remove in 4.0 + * @since 3.0.0 + * @param array $setting Settings. + * @return array + */ + public function cast_image_width( $setting ) { + foreach ( array( 'default', 'value' ) as $key ) { + if ( isset( $setting[ $key ] ) ) { + $setting[ $key ]['width'] = intval( $setting[ $key ]['width'] ); + $setting[ $key ]['height'] = intval( $setting[ $key ]['height'] ); + $setting[ $key ]['crop'] = (bool) $setting[ $key ]['crop']; + } + } + return $setting; + } + + /** + * Callback for allowed keys for each setting response. + * + * @since 3.0.0 + * @param string $key Key to check. + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( + $key, array( + 'id', + 'label', + 'description', + 'default', + 'tip', + 'placeholder', + 'type', + 'options', + 'value', + 'option_key', + ) + ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * + * @since 3.0.0 + * @param string $type Type. + * @return bool + */ + public function is_setting_type_valid( $type ) { + return in_array( + $type, array( + 'text', // Validates with validate_setting_text_field. + 'email', // Validates with validate_setting_text_field. + 'number', // Validates with validate_setting_text_field. + 'color', // Validates with validate_setting_text_field. + 'password', // Validates with validate_setting_text_field. + 'textarea', // Validates with validate_setting_textarea_field. + 'select', // Validates with validate_setting_select_field. + 'multiselect', // Validates with validate_setting_multiselect_field. + 'radio', // Validates with validate_setting_radio_field (-> validate_setting_select_field). + 'checkbox', // Validates with validate_setting_checkbox_field. + 'image_width', // Validates with validate_setting_image_width_field. + 'thumbnail_cropping', // Validates with validate_setting_text_field. + ) + ); + } + + /** + * Get the settings schema, conforming to JSON Schema. + * + * @since 3.0.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox', 'thumbnail_cropping' ), + 'readonly' => true, + ), + 'options' => array( + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php new file mode 100644 index 0000000..cc05d9b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php @@ -0,0 +1,232 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get all settings groups items. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $defaults = $this->group_defaults(); + $filtered_groups = array(); + foreach ( $groups as $group ) { + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + $group['sub_groups'] = $sub_groups; + + $group = wp_parse_args( $group, $defaults ); + if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { + $group_obj = $this->filter_group( $group ); + $group_data = $this->prepare_item_for_response( $group_obj, $request ); + $group_data = $this->prepare_response_for_collection( $group_data ); + + $filtered_groups[] = $group_data; + } + } + + $response = rest_ensure_response( $filtered_groups ); + return $response; + } + + /** + * Prepare links for the request. + * + * @param string $group_id Group ID. + * @return array Links for the given group. + */ + protected function prepare_links( $group_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'options' => array( + 'href' => rest_url( trailingslashit( $base ) . $group_id ), + ), + ); + + return $links; + } + + /** + * Prepare a report sales object for serialization. + * + * @since 3.0.0 + * @param array $item Group object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item['id'] ) ); + + return $response; + } + + /** + * Filters out bad values from the groups array/filter so we + * only return known values via the API. + * + * @since 3.0.0 + * @param array $group Group. + * @return array + */ + public function filter_group( $group ) { + return array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) + ); + } + + /** + * Callback for allowed keys for each group response. + * + * @since 3.0.0 + * @param string $key Key to check. + * @return boolean + */ + public function allowed_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); + } + + /** + * Returns default settings for groups. null means the field is required. + * + * @since 3.0.0 + * @return array + */ + protected function group_defaults() { + return array( + 'id' => null, + 'label' => null, + 'description' => '', + 'parent_id' => '', + 'sub_groups' => array(), + ); + } + + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get the groups schema, conforming to JSON Schema. + * + * @since 3.0.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting_group', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php new file mode 100644 index 0000000..4265e10 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php @@ -0,0 +1,231 @@ + + */ + 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' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view shipping methods. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to read a shipping method. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get shipping methods. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $wc_shipping = WC_Shipping::instance(); + $response = array(); + foreach ( $wc_shipping->get_shipping_methods() as $id => $shipping_method ) { + $method = $this->prepare_item_for_response( $shipping_method, $request ); + $method = $this->prepare_response_for_collection( $method ); + $response[] = $method; + } + return rest_ensure_response( $response ); + } + + /** + * Get a single Shipping Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $wc_shipping = WC_Shipping::instance(); + $methods = $wc_shipping->get_shipping_methods(); + if ( empty( $methods[ $request['id'] ] ) ) { + return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $method = $methods[ $request['id'] ]; + $response = $this->prepare_item_for_response( $method, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Prepare a shipping method for response. + * + * @param WC_Shipping_Method $method Shipping method object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $method, $request ) { + $data = array( + 'id' => $method->id, + 'title' => $method->method_title, + 'description' => $method->method_description, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $method, $request ) ); + + /** + * Filter shipping methods object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Shipping_Method $method Shipping method object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_shipping_method', $response, $method, $request ); + } + + /** + * Prepare links for the request. + * + * @param WC_Shipping_Method $method Shipping method object. + * @param WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $method, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $method->id ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the shipping method schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_method', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php new file mode 100644 index 0000000..ca0e54b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php @@ -0,0 +1,190 @@ +/locations endpoint. + * + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Locations class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Shipping_Zones_Controller_Base + */ +class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { + + /** + * Register the routes for Shipping Zone Locations. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/locations', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get all Shipping Zone Locations. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $zone = $this->get_zone( (int) $request['id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $locations = $zone->get_zone_locations(); + $data = array(); + + foreach ( $locations as $location_obj ) { + $location = $this->prepare_item_for_response( $location_obj, $request ); + $location = $this->prepare_response_for_collection( $location ); + $data[] = $location; + } + + return rest_ensure_response( $data ); + } + + /** + * Update all Shipping Zone Locations. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function update_items( $request ) { + $zone = $this->get_zone( (int) $request['id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + if ( 0 === $zone->get_id() ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + } + + $raw_locations = $request->get_json_params(); + $locations = array(); + + foreach ( (array) $raw_locations as $raw_location ) { + if ( empty( $raw_location['code'] ) ) { + continue; + } + + $type = ! empty( $raw_location['type'] ) ? sanitize_text_field( $raw_location['type'] ) : 'country'; + + if ( ! in_array( $type, array( 'postcode', 'state', 'country', 'continent' ), true ) ) { + continue; + } + + $locations[] = array( + 'code' => sanitize_text_field( $raw_location['code'] ), + 'type' => sanitize_text_field( $type ), + ); + } + + $zone->set_locations( $locations ); + $zone->save(); + + return $this->get_items( $request ); + } + + /** + * Prepare the Shipping Zone Location for the REST response. + * + * @param array $item Shipping Zone Location. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( (int) $request['id'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @return array Links for the given Shipping Zone Location. + */ + protected function prepare_links( $zone_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + $links = array( + 'collection' => array( + 'href' => rest_url( $base . '/locations' ), + ), + 'describes' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + + /** + * Get the Shipping Zone Locations schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_location', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'description' => __( 'Shipping zone location code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'type' => array( + 'description' => __( 'Shipping zone location type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'country', + 'enum' => array( + 'postcode', + 'state', + 'country', + 'continent', + ), + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php new file mode 100644 index 0000000..e153ba4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php @@ -0,0 +1,541 @@ +/methods endpoint. + * + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Methods class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Shipping_Zones_Controller_Base + */ +class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base { + + /** + * Register the routes for Shipping Zone Methods. + */ + public function register_routes() { + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods', array( + 'args' => array( + 'zone_id' => array( + 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'method_id' => array( + 'required' => true, + 'readonly' => false, + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/methods/(?P[\d]+)', array( + 'args' => array( + 'zone_id' => array( + 'description' => __( 'Unique ID for the zone.', 'woocommerce' ), + 'type' => 'integer', + ), + 'instance_id' => array( + 'description' => __( 'Unique ID for the instance.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_items_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get a single Shipping Zone Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $method, $request ); + + return rest_ensure_response( $data ); + } + + /** + * Get all Shipping Zone Methods. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $methods = $zone->get_shipping_methods(); + $data = array(); + + foreach ( $methods as $method_obj ) { + $method = $this->prepare_item_for_response( $method_obj, $request ); + $data[] = $method; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a new shipping zone method instance. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $method_id = $request['method_id']; + $zone = $this->get_zone( $request['zone_id'] ); + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = $zone->add_shipping_method( $method_id ); + $methods = $zone->get_shipping_methods(); + $method = false; + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $method = $this->update_fields( $instance_id, $method, $request ); + if ( is_wp_error( $method ) ) { + return $method; + } + + $data = $this->prepare_item_for_response( $method, $request ); + return rest_ensure_response( $data ); + } + + /** + * Delete a shipping method instance. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $force = $request['force']; + + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $method = $this->update_fields( $instance_id, $method, $request ); + if ( is_wp_error( $method ) ) { + return $method; + } + + $request->set_param( 'context', 'view' ); + $response = $this->prepare_item_for_response( $method, $request ); + + // Actually delete. + if ( $force ) { + $zone->delete_shipping_method( $instance_id ); + } else { + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + /** + * Fires after a product review is deleted via the REST API. + * + * @param object $method + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'rest_delete_product_review', $method, $response, $request ); + + return $response; + } + + /** + * Update A Single Shipping Zone Method. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function update_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $method = $this->update_fields( $instance_id, $method, $request ); + if ( is_wp_error( $method ) ) { + return $method; + } + + $data = $this->prepare_item_for_response( $method, $request ); + return rest_ensure_response( $data ); + } + + /** + * Updates settings, order, and enabled status on create. + * + * @param int $instance_id Instance ID. + * @param WC_Shipping_Method $method Shipping method data. + * @param WP_REST_Request $request Request data. + * + * @return WC_Shipping_Method + */ + public function update_fields( $instance_id, $method, $request ) { + global $wpdb; + + // Update settings if present. + if ( isset( $request['settings'] ) ) { + $method->init_instance_settings(); + $instance_settings = $method->instance_settings; + $errors_found = false; + foreach ( $method->get_instance_form_fields() as $key => $field ) { + if ( isset( $request['settings'][ $key ] ) ) { + if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) { + $value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field ); + } else { + $value = $this->validate_setting_text_field( $request['settings'][ $key ], $field ); + } + if ( is_wp_error( $value ) ) { + $errors_found = true; + break; + } + $instance_settings[ $key ] = $value; + } + } + + if ( $errors_found ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) ); + } + + // Update order. + if ( isset( $request['order'] ) ) { + $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'method_order' => absint( $request['order'] ) ), array( 'instance_id' => absint( $instance_id ) ) ); + $method->method_order = absint( $request['order'] ); + } + + // Update if this method is enabled or not. + if ( isset( $request['enabled'] ) ) { + if ( $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'is_enabled' => $request['enabled'] ), array( 'instance_id' => absint( $instance_id ) ) ) ) { + do_action( 'woocommerce_shipping_zone_method_status_toggled', $instance_id, $method->id, $request['zone_id'], $request['enabled'] ); + $method->enabled = ( true === $request['enabled'] ? 'yes' : 'no' ); + } + } + + return $method; + } + + /** + * Prepare the Shipping Zone Method for the REST response. + * + * @param array $item Shipping Zone Method. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $method = array( + 'id' => $item->instance_id, + 'instance_id' => $item->instance_id, + 'title' => $item->instance_settings['title'], + 'order' => $item->method_order, + 'enabled' => ( 'yes' === $item->enabled ), + 'method_id' => $item->id, + 'method_title' => $item->method_title, + 'method_description' => $item->method_description, + 'settings' => $this->get_settings( $item ), + ); + + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $method, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $request['zone_id'], $item->instance_id ) ); + + $response = $this->prepare_response_for_collection( $response ); + + return $response; + } + + /** + * Return settings associated with this shipping zone method instance. + * + * @param WC_Shipping_Method $item Shipping method data. + * + * @return array + */ + public function get_settings( $item ) { + $item->init_instance_settings(); + $settings = array(); + foreach ( $item->get_instance_form_fields() as $id => $field ) { + $data = array( + 'id' => $id, + 'label' => $field['title'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => $item->instance_settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @param int $instance_id Given Shipping Zone Method Instance ID. + * @return array Links for the given Shipping Zone Method. + */ + protected function prepare_links( $zone_id, $instance_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + $links = array( + 'self' => array( + 'href' => rest_url( $base . '/methods/' . $instance_id ), + ), + 'collection' => array( + 'href' => rest_url( $base . '/methods' ), + ), + 'describes' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + + /** + * Get the Shipping Zone Methods schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_method', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'instance_id' => array( + 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Shipping method customer facing title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order' => array( + 'description' => __( 'Shipping method sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'enabled' => array( + 'description' => __( 'Shipping method enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'method_id' => array( + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_title' => array( + 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_description' => array( + 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'settings' => array( + 'description' => __( 'Shipping method settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php new file mode 100644 index 0000000..8320fad --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php @@ -0,0 +1,304 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'name' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Shipping zone name.', 'woocommerce' ), + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique ID for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_items_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get a single Shipping Zone. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $data = $zone->get_data(); + $data = $this->prepare_item_for_response( $data, $request ); + $data = $this->prepare_response_for_collection( $data ); + + return rest_ensure_response( $data ); + } + + /** + * Get all Shipping Zones. + * + * @param WP_REST_Request $request Request data. + * @return WP_REST_Response + */ + public function get_items( $request ) { + $rest_of_the_world = WC_Shipping_Zones::get_zone_by( 'zone_id', 0 ); + + $zones = WC_Shipping_Zones::get_zones(); + array_unshift( $zones, $rest_of_the_world->get_data() ); + $data = array(); + + foreach ( $zones as $zone_obj ) { + $zone = $this->prepare_item_for_response( $zone_obj, $request ); + $zone = $this->prepare_response_for_collection( $zone ); + $data[] = $zone; + } + + return rest_ensure_response( $data ); + } + + /** + * Create a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $zone = new WC_Shipping_Zone( null ); + + if ( ! is_null( $request->get_param( 'name' ) ) ) { + $zone->set_zone_name( $request->get_param( 'name' ) ); + } + + if ( ! is_null( $request->get_param( 'order' ) ) ) { + $zone->set_zone_order( $request->get_param( 'order' ) ); + } + + $zone->save(); + + if ( $zone->get_id() !== 0 ) { + $request->set_param( 'id', $zone->get_id() ); + $response = $this->get_item( $request ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); + return $response; + } else { + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); + } + } + + /** + * Update a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + if ( 0 === $zone->get_id() ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) ); + } + + $zone_changed = false; + + if ( ! is_null( $request->get_param( 'name' ) ) ) { + $zone->set_zone_name( $request->get_param( 'name' ) ); + $zone_changed = true; + } + + if ( ! is_null( $request->get_param( 'order' ) ) ) { + $zone->set_zone_order( $request->get_param( 'order' ) ); + $zone_changed = true; + } + + if ( $zone_changed ) { + $zone->save(); + } + + return $this->get_item( $request ); + } + + /** + * Delete a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function delete_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $force = $request['force']; + + $response = $this->get_item( $request ); + + if ( $force ) { + $zone->delete(); + } else { + return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + return $response; + } + + /** + * Prepare the Shipping Zone for the REST response. + * + * @param array $item Shipping Zone. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $data = array( + 'id' => (int) $item['id'], + 'name' => $item['zone_name'], + 'order' => (int) $item['zone_order'], + ); + + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $data['id'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @return array Links for the given Shipping Zone. + */ + protected function prepare_links( $zone_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $zone_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + 'describedby' => array( + 'href' => rest_url( trailingslashit( $base ) . $zone_id . '/locations' ), + ), + ); + + return $links; + } + + /** + * Get the Shipping Zones schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Shipping zone name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'order' => array( + 'description' => __( 'Shipping zone order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php new file mode 100644 index 0000000..06838eb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php @@ -0,0 +1,618 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view system status tools. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check whether a given request has permission to view a specific system status tool. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check whether a given request has permission to execute a specific system status tool. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * A list of available tools for use in the system status section. + * 'button' becomes 'action' in the API. + * + * @return array + */ + public function get_tools() { + $tools = array( + 'clear_transients' => array( + 'name' => __( 'WooCommerce transients', 'woocommerce' ), + 'button' => __( 'Clear transients', 'woocommerce' ), + 'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce' ), + ), + 'clear_expired_transients' => array( + 'name' => __( 'Expired transients', 'woocommerce' ), + 'button' => __( 'Clear transients', 'woocommerce' ), + 'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce' ), + ), + 'delete_orphaned_variations' => array( + 'name' => __( 'Orphaned variations', 'woocommerce' ), + 'button' => __( 'Delete orphaned variations', 'woocommerce' ), + 'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce' ), + ), + 'clear_expired_download_permissions' => array( + 'name' => __( 'Used-up download permissions', 'woocommerce' ), + 'button' => __( 'Clean up download permissions', 'woocommerce' ), + 'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce' ), + ), + 'regenerate_product_lookup_tables' => array( + 'name' => __( 'Product lookup tables', 'woocommerce' ), + 'button' => __( 'Regenerate', 'woocommerce' ), + 'desc' => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce' ), + ), + 'recount_terms' => array( + 'name' => __( 'Term counts', 'woocommerce' ), + 'button' => __( 'Recount terms', 'woocommerce' ), + 'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce' ), + ), + 'reset_roles' => array( + 'name' => __( 'Capabilities', 'woocommerce' ), + 'button' => __( 'Reset capabilities', 'woocommerce' ), + 'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce' ), + ), + 'clear_sessions' => array( + 'name' => __( 'Clear customer sessions', 'woocommerce' ), + 'button' => __( 'Clear', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce' ) + ), + ), + 'clear_template_cache' => array( + 'name' => __( 'Clear template cache', 'woocommerce' ), + 'button' => __( 'Clear', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will empty the template cache.', 'woocommerce' ) + ), + ), + 'install_pages' => array( + 'name' => __( 'Create default WooCommerce pages', 'woocommerce' ), + 'button' => __( 'Create pages', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce' ) + ), + ), + 'delete_taxes' => array( + 'name' => __( 'Delete WooCommerce tax rates', 'woocommerce' ), + 'button' => __( 'Delete tax rates', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce' ) + ), + ), + 'regenerate_thumbnails' => array( + 'name' => __( 'Regenerate shop thumbnails', 'woocommerce' ), + 'button' => __( 'Regenerate', 'woocommerce' ), + 'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce' ), + ), + 'db_update_routine' => array( + 'name' => __( 'Update database', 'woocommerce' ), + 'button' => __( 'Update database', 'woocommerce' ), + 'desc' => sprintf( + '%1$s %2$s', + __( 'Note:', 'woocommerce' ), + __( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce' ) + ), + ), + ); + if ( method_exists( 'WC_Install', 'verify_base_tables' ) ) { + $tools['verify_db_tables'] = array( + 'name' => __( 'Verify base database tables', 'woocommerce' ), + 'button' => __( 'Verify database', 'woocommerce' ), + 'desc' => sprintf( + __( 'Verify if all base database tables are present.', 'woocommerce' ) + ), + ); + } + + // Jetpack does the image resizing heavy lifting so you don't have to. + if ( ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) || ! apply_filters( 'woocommerce_background_image_regeneration', true ) ) { + unset( $tools['regenerate_thumbnails'] ); + } + + if ( ! function_exists( 'wc_clear_template_cache' ) ) { + unset( $tools['clear_template_cache'] ); + } + + return apply_filters( 'woocommerce_debug_tools', $tools ); + } + + /** + * Get a list of system status tools. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $tools = array(); + foreach ( $this->get_tools() as $id => $tool ) { + $tools[] = $this->prepare_response_for_collection( + $this->prepare_item_for_response( + array( + 'id' => $id, + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ), + $request + ) + ); + } + + $response = rest_ensure_response( $tools ); + return $response; + } + + /** + * Return a single tool. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $tools = $this->get_tools(); + if ( empty( $tools[ $request['id'] ] ) ) { + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + $tool = $tools[ $request['id'] ]; + return rest_ensure_response( + $this->prepare_item_for_response( + array( + 'id' => $request['id'], + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ), + $request + ) + ); + } + + /** + * Update (execute) a tool. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $tools = $this->get_tools(); + if ( empty( $tools[ $request['id'] ] ) ) { + return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $tool = $tools[ $request['id'] ]; + $tool = array( + 'id' => $request['id'], + 'name' => $tool['name'], + 'action' => $tool['button'], + 'description' => $tool['desc'], + ); + + $execute_return = $this->execute_tool( $request['id'] ); + $tool = array_merge( $tool, $execute_return ); + + /** + * Fires after a WooCommerce REST system status tool has been executed. + * + * @param array $tool Details about the tool that has been executed. + * @param WP_REST_Request $request The current WP_REST_Request object. + */ + do_action( 'woocommerce_rest_insert_system_status_tool', $tool, $request ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $tool, $request ); + return rest_ensure_response( $response ); + } + + /** + * Prepare a tool item for serialization. + * + * @param array $item Object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item['id'] ) ); + + return $response; + } + + /** + * Get the system status tools schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'system_status_tool', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the tool.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'name' => array( + 'description' => __( 'Tool name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'action' => array( + 'description' => __( 'What running the tool will do.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'description' => array( + 'description' => __( 'Tool description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'success' => array( + 'description' => __( 'Did the tool run successfully?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'edit' ), + ), + 'message' => array( + 'description' => __( 'Tool return message.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Prepare links for the request. + * + * @param string $id ID. + * @return array + */ + protected function prepare_links( $id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'item' => array( + 'href' => rest_url( trailingslashit( $base ) . $id ), + 'embeddable' => true, + ), + ); + + return $links; + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + + /** + * Actually executes a tool. + * + * @param string $tool Tool. + * @return array + */ + public function execute_tool( $tool ) { + global $wpdb; + $ran = true; + switch ( $tool ) { + case 'clear_transients': + wc_delete_product_transients(); + wc_delete_shop_order_transients(); + delete_transient( 'wc_count_comments' ); + delete_transient( 'as_comment_count' ); + + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + if ( $attribute_taxonomies ) { + foreach ( $attribute_taxonomies as $attribute ) { + delete_transient( 'wc_layered_nav_counts_pa_' . $attribute->attribute_name ); + } + } + + WC_Cache_Helper::get_transient_version( 'shipping', true ); + $message = __( 'Product transients cleared', 'woocommerce' ); + break; + + case 'clear_expired_transients': + /* translators: %d: amount of expired transients */ + $message = sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() ); + break; + + case 'delete_orphaned_variations': + // Delete orphans. + $result = absint( + $wpdb->query( + "DELETE products + FROM {$wpdb->posts} products + LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent + WHERE wp.ID IS NULL AND products.post_type = 'product_variation';" + ) + ); + /* translators: %d: amount of orphaned variations */ + $message = sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result ); + break; + + case 'clear_expired_download_permissions': + // Delete expired download permissions and ones with 0 downloads remaining. + $result = absint( + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )", + gmdate( 'Y-m-d', current_time( 'timestamp' ) ) + ) + ) + ); + /* translators: %d: amount of permissions */ + $message = sprintf( __( '%d permissions deleted', 'woocommerce' ), $result ); + break; + + case 'regenerate_product_lookup_tables': + if ( ! wc_update_product_lookup_tables_is_running() ) { + wc_update_product_lookup_tables(); + } + $message = __( 'Lookup tables are regenerating', 'woocommerce' ); + break; + case 'reset_roles': + // Remove then re-add caps and roles. + WC_Install::remove_roles(); + WC_Install::create_roles(); + $message = __( 'Roles successfully reset', 'woocommerce' ); + break; + + case 'recount_terms': + $product_cats = get_terms( + 'product_cat', + array( + 'hide_empty' => false, + 'fields' => 'id=>parent', + ) + ); + _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false ); + $product_tags = get_terms( + 'product_tag', + array( + 'hide_empty' => false, + 'fields' => 'id=>parent', + ) + ); + _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); + $message = __( 'Terms successfully recounted', 'woocommerce' ); + break; + + case 'clear_sessions': + $wpdb->query( "TRUNCATE {$wpdb->prefix}woocommerce_sessions" ); + $result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok. + wp_cache_flush(); + /* translators: %d: amount of sessions */ + $message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) ); + break; + + case 'install_pages': + WC_Install::create_pages(); + $message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce' ); + break; + + case 'delete_taxes': + $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" ); + $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); + + if ( method_exists( 'WC_Cache_Helper', 'invalidate_cache_group' ) ) { + WC_Cache_Helper::invalidate_cache_group( 'taxes' ); + } else { + WC_Cache_Helper::incr_cache_prefix( 'taxes' ); + } + $message = __( 'Tax rates successfully deleted', 'woocommerce' ); + break; + + case 'regenerate_thumbnails': + WC_Regenerate_Images::queue_image_regeneration(); + $message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' ); + break; + + case 'db_update_routine': + $blog_id = get_current_blog_id(); + // Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck(). + // This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running. + do_action( 'wp_' . $blog_id . '_wc_updater_cron' ); + $message = __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce' ); + break; + + case 'clear_template_cache': + if ( function_exists( 'wc_clear_template_cache' ) ) { + wc_clear_template_cache(); + $message = __( 'Template cache cleared.', 'woocommerce' ); + } else { + $message = __( 'The active version of WooCommerce does not support template cache clearing.', 'woocommerce' ); + $ran = false; + } + break; + + case 'verify_db_tables': + if ( ! method_exists( 'WC_Install', 'verify_base_tables' ) ) { + $message = __( 'You need WooCommerce 4.2 or newer to run this tool.', 'woocommerce' ); + $ran = false; + break; + } + // Try to manually create table again. + $missing_tables = WC_Install::verify_base_tables( true, true ); + if ( 0 === count( $missing_tables ) ) { + $message = __( 'Database verified successfully.', 'woocommerce' ); + } else { + $message = __( 'Verifying database... One or more tables are still missing: ', 'woocommerce' ); + $message .= implode( ', ', $missing_tables ); + $ran = false; + } + break; + + default: + $tools = $this->get_tools(); + if ( isset( $tools[ $tool ]['callback'] ) ) { + $callback = $tools[ $tool ]['callback']; + $return = call_user_func( $callback ); + if ( is_string( $return ) ) { + $message = $return; + } elseif ( false === $return ) { + $callback_string = is_array( $callback ) ? get_class( $callback[0] ) . '::' . $callback[1] : $callback; + $ran = false; + /* translators: %s: callback string */ + $message = sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback_string ); + } else { + $message = __( 'Tool ran.', 'woocommerce' ); + } + } else { + $ran = false; + $message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' ); + } + break; + } + + return array( + 'success' => $ran, + 'message' => $message, + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php new file mode 100644 index 0000000..e2d6569 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php @@ -0,0 +1,1272 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to view system status. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get a system status info, by section. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $fields = $this->get_fields_for_response( $request ); + $mappings = $this->get_item_mappings_per_fields( $fields ); + $response = $this->prepare_item_for_response( $mappings, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Get the system status schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'system_status', + 'type' => 'object', + 'properties' => array( + 'environment' => array( + 'description' => __( 'Environment.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'home_url' => array( + 'description' => __( 'Home URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'site_url' => array( + 'description' => __( 'Site URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'version' => array( + 'description' => __( 'WooCommerce version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'log_directory' => array( + 'description' => __( 'Log directory.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'log_directory_writable' => array( + 'description' => __( 'Is log directory writable?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_version' => array( + 'description' => __( 'WordPress version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_multisite' => array( + 'description' => __( 'Is WordPress multisite?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_memory_limit' => array( + 'description' => __( 'WordPress memory limit.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_debug_mode' => array( + 'description' => __( 'Is WordPress debug mode active?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'wp_cron' => array( + 'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'language' => array( + 'description' => __( 'WordPress language.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'server_info' => array( + 'description' => __( 'Server info.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_version' => array( + 'description' => __( 'PHP version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_post_max_size' => array( + 'description' => __( 'PHP post max size.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_max_execution_time' => array( + 'description' => __( 'PHP max execution time.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'php_max_input_vars' => array( + 'description' => __( 'PHP max input vars.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'curl_version' => array( + 'description' => __( 'cURL version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'suhosin_installed' => array( + 'description' => __( 'Is SUHOSIN installed?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'max_upload_size' => array( + 'description' => __( 'Max upload size.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'mysql_version' => array( + 'description' => __( 'MySQL version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'mysql_version_string' => array( + 'description' => __( 'MySQL version string.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'default_timezone' => array( + 'description' => __( 'Default timezone.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'fsockopen_or_curl_enabled' => array( + 'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'soapclient_enabled' => array( + 'description' => __( 'Is SoapClient class enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'domdocument_enabled' => array( + 'description' => __( 'Is DomDocument class enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'gzip_enabled' => array( + 'description' => __( 'Is GZip enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'mbstring_enabled' => array( + 'description' => __( 'Is mbstring enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_post_successful' => array( + 'description' => __( 'Remote POST successful?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_post_response' => array( + 'description' => __( 'Remote POST response.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_get_successful' => array( + 'description' => __( 'Remote GET successful?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'remote_get_response' => array( + 'description' => __( 'Remote GET response.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + 'database' => array( + 'description' => __( 'Database.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'wc_database_version' => array( + 'description' => __( 'WC database version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'database_prefix' => array( + 'description' => __( 'Database prefix.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'maxmind_geoip_database' => array( + 'description' => __( 'MaxMind GeoIP database.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'database_tables' => array( + 'description' => __( 'Database tables.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + ), + ), + 'active_plugins' => array( + 'description' => __( 'Active plugins.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'inactive_plugins' => array( + 'description' => __( 'Inactive plugins.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'dropins_mu_plugins' => array( + 'description' => __( 'Dropins & MU plugins.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'theme' => array( + 'description' => __( 'Theme.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'name' => array( + 'description' => __( 'Theme name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'version' => array( + 'description' => __( 'Theme version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'version_latest' => array( + 'description' => __( 'Latest version of theme.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'author_url' => array( + 'description' => __( 'Theme author URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'is_child_theme' => array( + 'description' => __( 'Is this theme a child theme?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'has_woocommerce_support' => array( + 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'has_woocommerce_file' => array( + 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'has_outdated_templates' => array( + 'description' => __( 'Does this theme have outdated templates?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'overrides' => array( + 'description' => __( 'Template overrides.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'parent_name' => array( + 'description' => __( 'Parent theme name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'parent_version' => array( + 'description' => __( 'Parent theme version.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'parent_author_url' => array( + 'description' => __( 'Parent theme author URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + 'settings' => array( + 'description' => __( 'Settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'api_enabled' => array( + 'description' => __( 'REST API enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'force_ssl' => array( + 'description' => __( 'SSL forced?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency' => array( + 'description' => __( 'Currency.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_symbol' => array( + 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_position' => array( + 'description' => __( 'Currency position.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'thousand_separator' => array( + 'description' => __( 'Thousand separator.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'decimal_separator' => array( + 'description' => __( 'Decimal separator.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'number_of_decimals' => array( + 'description' => __( 'Number of decimals.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'geolocation_enabled' => array( + 'description' => __( 'Geolocation enabled?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'taxonomies' => array( + 'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'product_visibility_terms' => array( + 'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + ), + ), + 'security' => array( + 'description' => __( 'Security.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'secure_connection' => array( + 'description' => __( 'Is the connection to your store secure?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'hide_errors' => array( + 'description' => __( 'Hide errors from visitors?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + 'pages' => array( + 'description' => __( 'WooCommerce pages.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'post_type_counts' => array( + 'description' => __( 'Total post count.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Return an array of sections and the data associated with each. + * + * @deprecated 3.9.0 + * @return array + */ + public function get_item_mappings() { + return array( + 'environment' => $this->get_environment_info(), + 'database' => $this->get_database_info(), + 'active_plugins' => $this->get_active_plugins(), + 'inactive_plugins' => $this->get_inactive_plugins(), + 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(), + 'theme' => $this->get_theme_info(), + 'settings' => $this->get_settings(), + 'security' => $this->get_security_info(), + 'pages' => $this->get_pages(), + 'post_type_counts' => $this->get_post_type_counts(), + ); + } + + /** + * Return an array of sections and the data associated with each. + * + * @since 3.9.0 + * @param array $fields List of fields to be included on the response. + * @return array + */ + public function get_item_mappings_per_fields( $fields ) { + return array( + 'environment' => $this->get_environment_info_per_fields( $fields ), + 'database' => $this->get_database_info(), + 'active_plugins' => $this->get_active_plugins(), + 'inactive_plugins' => $this->get_inactive_plugins(), + 'dropins_mu_plugins' => $this->get_dropins_mu_plugins(), + 'theme' => $this->get_theme_info(), + 'settings' => $this->get_settings(), + 'security' => $this->get_security_info(), + 'pages' => $this->get_pages(), + 'post_type_counts' => $this->get_post_type_counts(), + ); + } + + /** + * Get array of environment information. Includes thing like software + * versions, and various server settings. + * + * @deprecated 3.9.0 + * @return array + */ + public function get_environment_info() { + return $this->get_environment_info_per_fields( array( 'environment' ) ); + } + + /** + * Check if field item exists. + * + * @since 3.9.0 + * @param string $section Fields section. + * @param array $items List of items to check for. + * @param array $fields List of fields to be included on the response. + * @return bool + */ + private function check_if_field_item_exists( $section, $items, $fields ) { + if ( ! in_array( $section, $fields, true ) ) { + return false; + } + + $exclude = array(); + foreach ( $fields as $field ) { + $values = explode( '.', $field ); + + if ( $section !== $values[0] || empty( $values[1] ) ) { + continue; + } + + $exclude[] = $values[1]; + } + + return 0 <= count( array_intersect( $items, $exclude ) ); + } + + /** + * Get array of environment information. Includes thing like software + * versions, and various server settings. + * + * @param array $fields List of fields to be included on the response. + * @return array + */ + public function get_environment_info_per_fields( $fields ) { + global $wpdb; + + $enable_remote_post = $this->check_if_field_item_exists( 'environment', array( 'remote_post_successful', 'remote_post_response' ), $fields ); + $enable_remote_get = $this->check_if_field_item_exists( 'environment', array( 'remote_get_successful', 'remote_get_response' ), $fields ); + + // Figure out cURL version, if installed. + $curl_version = ''; + if ( function_exists( 'curl_version' ) ) { + $curl_version = curl_version(); + $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; + } elseif ( extension_loaded( 'curl' ) ) { + $curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' ); + } + + // WP memory limit. + $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); + if ( function_exists( 'memory_get_usage' ) ) { + $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged + } + + // Test POST requests. + $post_response_successful = null; + $post_response_code = null; + if ( $enable_remote_post ) { + $post_response_code = get_transient( 'woocommerce_test_remote_post' ); + + if ( false === $post_response_code || is_wp_error( $post_response_code ) ) { + $response = wp_safe_remote_post( + 'https://www.paypal.com/cgi-bin/webscr', + array( + 'timeout' => 10, + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', + 'body' => array( + 'cmd' => '_notify-validate', + ), + ) + ); + if ( ! is_wp_error( $response ) ) { + $post_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS ); + } + + $post_response_successful = ! is_wp_error( $post_response_code ) && $post_response_code >= 200 && $post_response_code < 300; + } + + // Test GET requests. + $get_response_successful = null; + $get_response_code = null; + if ( $enable_remote_get ) { + $get_response_code = get_transient( 'woocommerce_test_remote_get' ); + + if ( false === $get_response_code || is_wp_error( $get_response_code ) ) { + $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); + if ( ! is_wp_error( $response ) ) { + $get_response_code = $response['response']['code']; + } + set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS ); + } + + $get_response_successful = ! is_wp_error( $get_response_code ) && $get_response_code >= 200 && $get_response_code < 300; + } + + $database_version = wc_get_server_database_version(); + + // Return all environment info. Described by JSON Schema. + return array( + 'home_url' => get_option( 'home' ), + 'site_url' => get_option( 'siteurl' ), + 'version' => WC()->version, + 'log_directory' => WC_LOG_DIR, + 'log_directory_writable' => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_read_fopen + 'wp_version' => get_bloginfo( 'version' ), + 'wp_multisite' => is_multisite(), + 'wp_memory_limit' => $wp_memory_limit, + 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ), + 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ), + 'language' => get_locale(), + 'external_object_cache' => wp_using_ext_object_cache(), + 'server_info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '', + 'php_version' => phpversion(), + 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), + 'php_max_execution_time' => (int) ini_get( 'max_execution_time' ), + 'php_max_input_vars' => (int) ini_get( 'max_input_vars' ), + 'curl_version' => $curl_version, + 'suhosin_installed' => extension_loaded( 'suhosin' ), + 'max_upload_size' => wp_max_upload_size(), + 'mysql_version' => $database_version['number'], + 'mysql_version_string' => $database_version['string'], + 'default_timezone' => date_default_timezone_get(), + 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ), + 'soapclient_enabled' => class_exists( 'SoapClient' ), + 'domdocument_enabled' => class_exists( 'DOMDocument' ), + 'gzip_enabled' => is_callable( 'gzopen' ), + 'mbstring_enabled' => extension_loaded( 'mbstring' ), + 'remote_post_successful' => $post_response_successful, + 'remote_post_response' => is_wp_error( $post_response_code ) ? $post_response_code->get_error_message() : $post_response_code, + 'remote_get_successful' => $get_response_successful, + 'remote_get_response' => is_wp_error( $get_response_code ) ? $get_response_code->get_error_message() : $get_response_code, + ); + } + + /** + * Add prefix to table. + * + * @param string $table Table name. + * @return stromg + */ + protected function add_db_table_prefix( $table ) { + global $wpdb; + return $wpdb->prefix . $table; + } + + /** + * Get array of database information. Version, prefix, and table existence. + * + * @return array + */ + public function get_database_info() { + global $wpdb; + + $tables = array(); + $database_size = array(); + + // It is not possible to get the database name from some classes that replace wpdb (e.g., HyperDB) + // and that is why this if condition is needed. + if ( defined( 'DB_NAME' ) ) { + $database_table_information = $wpdb->get_results( + $wpdb->prepare( + "SELECT + table_name AS 'name', + engine AS 'engine', + round( ( data_length / 1024 / 1024 ), 2 ) 'data', + round( ( index_length / 1024 / 1024 ), 2 ) 'index' + FROM information_schema.TABLES + WHERE table_schema = %s + ORDER BY name ASC;", + DB_NAME + ) + ); + + // WC Core tables to check existence of. + $core_tables = apply_filters( + 'woocommerce_database_tables', + array( + 'woocommerce_sessions', + 'woocommerce_api_keys', + 'woocommerce_attribute_taxonomies', + 'woocommerce_downloadable_product_permissions', + 'woocommerce_order_items', + 'woocommerce_order_itemmeta', + 'woocommerce_tax_rates', + 'woocommerce_tax_rate_locations', + 'woocommerce_shipping_zones', + 'woocommerce_shipping_zone_locations', + 'woocommerce_shipping_zone_methods', + 'woocommerce_payment_tokens', + 'woocommerce_payment_tokenmeta', + 'woocommerce_log', + ) + ); + + /** + * Adding the prefix to the tables array, for backwards compatibility. + * + * If we changed the tables above to include the prefix, then any filters against that table could break. + */ + $core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables ); + + /** + * Organize WooCommerce and non-WooCommerce tables separately for display purposes later. + * + * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables. + */ + $tables = array( + 'woocommerce' => array_fill_keys( $core_tables, false ), + 'other' => array(), + ); + + $database_size = array( + 'data' => 0, + 'index' => 0, + ); + + $site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() ); + $global_tables = $wpdb->tables( 'global', true ); + foreach ( $database_table_information as $table ) { + // Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current. + if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) { + continue; + } + $table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other'; + + $tables[ $table_type ][ $table->name ] = array( + 'data' => $table->data, + 'index' => $table->index, + 'engine' => $table->engine, + ); + + $database_size['data'] += $table->data; + $database_size['index'] += $table->index; + } + } + + // Return all database info. Described by JSON Schema. + return array( + 'wc_database_version' => get_option( 'woocommerce_db_version' ), + 'database_prefix' => $wpdb->prefix, + 'maxmind_geoip_database' => '', + 'database_tables' => $tables, + 'database_size' => $database_size, + ); + } + + /** + * Get array of counts of objects. Orders, products, etc. + * + * @return array + */ + public function get_post_type_counts() { + global $wpdb; + + $post_type_counts = $wpdb->get_results( "SELECT post_type AS 'type', count(1) AS 'count' FROM {$wpdb->posts} GROUP BY post_type;" ); + + return is_array( $post_type_counts ) ? $post_type_counts : array(); + } + + /** + * Get a list of plugins active on the site. + * + * @return array + */ + public function get_active_plugins() { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + if ( ! function_exists( 'get_plugin_data' ) ) { + return array(); + } + + $active_plugins = (array) get_option( 'active_plugins', array() ); + if ( is_multisite() ) { + $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); + } + + $active_plugins_data = array(); + + foreach ( $active_plugins as $plugin ) { + $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + $active_plugins_data[] = $this->format_plugin_data( $plugin, $data ); + } + + return $active_plugins_data; + } + + /** + * Get a list of inplugins active on the site. + * + * @return array + */ + public function get_inactive_plugins() { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + if ( ! function_exists( 'get_plugins' ) ) { + return array(); + } + + $plugins = get_plugins(); + $active_plugins = (array) get_option( 'active_plugins', array() ); + + if ( is_multisite() ) { + $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); + } + + $plugins_data = array(); + + foreach ( $plugins as $plugin => $data ) { + if ( in_array( $plugin, $active_plugins, true ) ) { + continue; + } + $plugins_data[] = $this->format_plugin_data( $plugin, $data ); + } + + return $plugins_data; + } + + /** + * Format plugin data, including data on updates, into a standard format. + * + * @since 3.6.0 + * @param string $plugin Plugin directory/file. + * @param array $data Plugin data from WP. + * @return array Formatted data. + */ + protected function format_plugin_data( $plugin, $data ) { + require_once ABSPATH . 'wp-admin/includes/update.php'; + + if ( ! function_exists( 'get_plugin_updates' ) ) { + return array(); + } + + // Use WP API to lookup latest updates for plugins. WC_Helper injects updates for premium plugins. + if ( empty( $this->available_updates ) ) { + $this->available_updates = get_plugin_updates(); + } + + $version_latest = $data['Version']; + + // Find latest version. + if ( isset( $this->available_updates[ $plugin ]->update->new_version ) ) { + $version_latest = $this->available_updates[ $plugin ]->update->new_version; + } + + return array( + 'plugin' => $plugin, + 'name' => $data['Name'], + 'version' => $data['Version'], + 'version_latest' => $version_latest, + 'url' => $data['PluginURI'], + 'author_name' => $data['AuthorName'], + 'author_url' => esc_url_raw( $data['AuthorURI'] ), + 'network_activated' => $data['Network'], + ); + } + + /** + * Get a list of Dropins and MU plugins. + * + * @since 3.6.0 + * @return array + */ + public function get_dropins_mu_plugins() { + $dropins = get_dropins(); + $plugins = array( + 'dropins' => array(), + 'mu_plugins' => array(), + ); + foreach ( $dropins as $key => $dropin ) { + $plugins['dropins'][] = array( + 'plugin' => $key, + 'name' => $dropin['Name'], + ); + } + + $mu_plugins = get_mu_plugins(); + foreach ( $mu_plugins as $plugin => $mu_plugin ) { + $plugins['mu_plugins'][] = array( + 'plugin' => $plugin, + 'name' => $mu_plugin['Name'], + 'version' => $mu_plugin['Version'], + 'url' => $mu_plugin['PluginURI'], + 'author_name' => $mu_plugin['AuthorName'], + 'author_url' => esc_url_raw( $mu_plugin['AuthorURI'] ), + ); + } + return $plugins; + } + + /** + * Get info on the current active theme, info on parent theme (if presnet) + * and a list of template overrides. + * + * @return array + */ + public function get_theme_info() { + $active_theme = wp_get_theme(); + + // Get parent theme info if this theme is a child theme, otherwise + // pass empty info in the response. + if ( is_child_theme() ) { + $parent_theme = wp_get_theme( $active_theme->template ); + $parent_theme_info = array( + 'parent_name' => $parent_theme->name, + 'parent_version' => $parent_theme->version, + 'parent_version_latest' => WC_Admin_Status::get_latest_theme_version( $parent_theme ), + 'parent_author_url' => $parent_theme->{'Author URI'}, + ); + } else { + $parent_theme_info = array( + 'parent_name' => '', + 'parent_version' => '', + 'parent_version_latest' => '', + 'parent_author_url' => '', + ); + } + + /** + * Scan the theme directory for all WC templates to see if our theme + * overrides any of them. + */ + $override_files = array(); + $outdated_templates = false; + $scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); + + // Include *-product_ templates for backwards compatibility. + $scan_files[] = 'content-product_cat.php'; + $scan_files[] = 'taxonomy-product_cat.php'; + $scan_files[] = 'taxonomy-product_tag.php'; + + foreach ( $scan_files as $file ) { + $located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' ); + + if ( file_exists( $located ) ) { + $theme_file = $located; + } elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . $file; + } elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file; + } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { + $theme_file = get_template_directory() . '/' . $file; + } elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) { + $theme_file = get_template_directory() . '/' . WC()->template_path() . $file; + } else { + $theme_file = false; + } + + if ( ! empty( $theme_file ) ) { + $core_file = $file; + + // Update *-product_ template name before searching in core. + if ( false !== strpos( $core_file, '-product_cat' ) || false !== strpos( $core_file, '-product_tag' ) ) { + $core_file = str_replace( '_', '-', $core_file ); + } + + $core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $core_file ); + $theme_version = WC_Admin_Status::get_file_version( $theme_file ); + if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { + if ( ! $outdated_templates ) { + $outdated_templates = true; + } + } + $override_files[] = array( + 'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ), + 'version' => $theme_version, + 'core_version' => $core_version, + ); + } + } + + $active_theme_info = array( + 'name' => $active_theme->name, + 'version' => $active_theme->version, + 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ), + 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), + 'is_child_theme' => is_child_theme(), + 'has_woocommerce_support' => current_theme_supports( 'woocommerce' ), + 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), + 'has_outdated_templates' => $outdated_templates, + 'overrides' => $override_files, + ); + + return array_merge( $active_theme_info, $parent_theme_info ); + } + + /** + * Get some setting values for the site that are useful for debugging + * purposes. For full settings access, use the settings api. + * + * @return array + */ + public function get_settings() { + // Get a list of terms used for product/order taxonomies. + $term_response = array(); + $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $term_response[ $term->slug ] = strtolower( $term->name ); + } + + // Get a list of terms used for product visibility. + $product_visibility_terms = array(); + $terms = get_terms( 'product_visibility', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $product_visibility_terms[ $term->slug ] = strtolower( $term->name ); + } + + // Check if WooCommerce.com account is connected. + $woo_com_connected = 'no'; + $helper_options = get_option( 'woocommerce_helper_data', array() ); + if ( array_key_exists( 'auth', $helper_options ) && ! empty( $helper_options['auth'] ) ) { + $woo_com_connected = 'yes'; + } + + // Return array of useful settings for debugging. + return array( + 'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ), + 'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ), + 'currency' => get_woocommerce_currency(), + 'currency_symbol' => get_woocommerce_currency_symbol(), + 'currency_position' => get_option( 'woocommerce_currency_pos' ), + 'thousand_separator' => wc_get_price_thousand_separator(), + 'decimal_separator' => wc_get_price_decimal_separator(), + 'number_of_decimals' => wc_get_price_decimals(), + 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ), true ), + 'taxonomies' => $term_response, + 'product_visibility_terms' => $product_visibility_terms, + 'woocommerce_com_connected' => $woo_com_connected, + ); + } + + /** + * Returns security tips. + * + * @return array + */ + public function get_security_info() { + $check_page = wc_get_page_permalink( 'shop' ); + return array( + 'secure_connection' => 'https' === substr( $check_page, 0, 5 ), + 'hide_errors' => ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ), + ); + } + + /** + * Returns a mini-report on WC pages and if they are configured correctly: + * Present, visible, and including the correct shortcode. + * + * @return array + */ + public function get_pages() { + // WC pages to check against. + $check_pages = array( + _x( 'Shop base', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_shop_page_id', + 'shortcode' => '', + ), + _x( 'Cart', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_cart_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', + ), + _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_checkout_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', + ), + _x( 'My account', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_myaccount_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', + ), + _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_terms_page_id', + 'shortcode' => '', + ), + ); + + $pages_output = array(); + foreach ( $check_pages as $page_name => $values ) { + $page_id = get_option( $values['option'] ); + $page_set = false; + $page_exists = false; + $page_visible = false; + $shortcode_present = false; + $shortcode_required = false; + + // Page checks. + if ( $page_id ) { + $page_set = true; + } + if ( get_post( $page_id ) ) { + $page_exists = true; + } + if ( 'publish' === get_post_status( $page_id ) ) { + $page_visible = true; + } + + // Shortcode checks. + if ( $values['shortcode'] && get_post( $page_id ) ) { + $shortcode_required = true; + $page = get_post( $page_id ); + if ( strstr( $page->post_content, $values['shortcode'] ) ) { + $shortcode_present = true; + } + } + + // Wrap up our findings into an output array. + $pages_output[] = array( + 'page_name' => $page_name, + 'page_id' => $page_id, + 'page_set' => $page_set, + 'page_exists' => $page_exists, + 'page_visible' => $page_visible, + 'shortcode' => $values['shortcode'], + 'shortcode_required' => $shortcode_required, + 'shortcode_present' => $shortcode_present, + ); + } + + return $pages_output; + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + + /** + * Prepare the system status response + * + * @param array $system_status System status data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $system_status, $request ) { + $data = $this->add_additional_fields_to_object( $system_status, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); + + $response = rest_ensure_response( $data ); + + /** + * Filter the system status returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param mixed $system_status System status + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_system_status', $response, $system_status, $request ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php new file mode 100644 index 0000000..04f7909 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php @@ -0,0 +1,109 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P\w[\w\s\-]*)', + array( + 'args' => array( + 'slug' => array( + 'description' => __( 'Unique slug for the resource.', 'woocommerce' ), + 'type' => 'string', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get one tax class. + * + * @param WP_REST_Request $request Request object. + * @return array + */ + public function get_item( $request ) { + if ( 'standard' === $request['slug'] ) { + $tax_class = array( + 'slug' => 'standard', + 'name' => __( 'Standard rate', 'woocommerce' ), + ); + } else { + $tax_class = WC_Tax::get_tax_class_by( 'slug', sanitize_title( $request['slug'] ) ); + } + + $data = array(); + if ( $tax_class ) { + $class = $this->prepare_item_for_response( $tax_class, $request ); + $class = $this->prepare_response_for_collection( $class ); + $data[] = $class; + } + + return rest_ensure_response( $data ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-taxes-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-taxes-v2-controller.php new file mode 100644 index 0000000..54b53a2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-taxes-v2-controller.php @@ -0,0 +1,27 @@ +/deliveries endpoint. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Webhook Deliveries controller class. + * + * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system. + * @package WooCommerce\RestApi + * @extends WC_REST_Webhook_Deliveries_V1_Controller + */ +class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliveries_V1_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v2'; + + /** + * Prepare a single webhook delivery output for response. + * + * @param stdClass $log Delivery log object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $log, $request ) { + $data = (array) $log; + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $log ) ); + + /** + * Filter webhook delivery object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param stdClass $log Delivery log object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_webhook_delivery', $response, $log, $request ); + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook_delivery', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'duration' => array( + 'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'summary' => array( + 'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_url' => array( + 'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'request_headers' => array( + 'description' => __( 'Request headers.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'request_body' => array( + 'description' => __( 'Request body.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_code' => array( + 'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_message' => array( + 'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'response_headers' => array( + 'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'response_body' => array( + 'description' => __( 'The response body from the receiving server.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the webhook delivery was logged, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php new file mode 100644 index 0000000..c64eae1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php @@ -0,0 +1,182 @@ +post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $data = array( + 'id' => $webhook->get_id(), + 'name' => $webhook->get_name(), + 'status' => $webhook->get_status(), + 'topic' => $webhook->get_topic(), + 'resource' => $webhook->get_resource(), + 'event' => $webhook->get_event(), + 'hooks' => $webhook->get_hooks(), + 'delivery_url' => $webhook->get_delivery_url(), + 'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $webhook->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $webhook->get_date_modified() ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $webhook->get_id(), $request ) ); + + /** + * Filter webhook object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Webhook $webhook Webhook object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request ); + } + + /** + * Get the default REST API version. + * + * @since 3.0.0 + * @return string + */ + protected function get_default_api_version() { + return 'wp_api_v2'; + } + + /** + * Get the Webhook's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'webhook', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'A friendly name for the webhook.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Webhook status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'active', + 'enum' => array_keys( wc_get_webhook_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'topic' => array( + 'description' => __( 'Webhook topic.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'resource' => array( + 'description' => __( 'Webhook resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'event' => array( + 'description' => __( 'Webhook event.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'hooks' => array( + 'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'delivery_url' => array( + 'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'secret' => array( + 'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php new file mode 100644 index 0000000..4b0a086 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php @@ -0,0 +1,573 @@ + + * + * NOTE THAT ONLY CODE RELEVANT FOR MOST ENDPOINTS SHOULD BE INCLUDED INTO THIS CLASS. + * If necessary extend this class and create new abstract classes like `WC_REST_CRUD_Controller` or `WC_REST_Terms_Controller`. + * + * @class WC_REST_Controller + * @package WooCommerce\RestApi + * @see https://developer.wordpress.org/rest-api/extending-the-rest-api/controller-classes/ + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * Abstract Rest Controller Class + * + * @package WooCommerce\RestApi + * @extends WP_REST_Controller + * @version 2.6.0 + */ +abstract class WC_REST_Controller extends WP_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = ''; + + /** + * Add the schema from additional fields to an schema array. + * + * The type of object is inferred from the passed schema. + * + * @param array $schema Schema array. + * + * @return array + */ + protected function add_additional_fields_schema( $schema ) { + if ( empty( $schema['title'] ) ) { + return $schema; + } + + /** + * Can't use $this->get_object_type otherwise we cause an inf loop. + */ + $object_type = $schema['title']; + + $additional_fields = $this->get_additional_fields( $object_type ); + + foreach ( $additional_fields as $field_name => $field_options ) { + if ( ! $field_options['schema'] ) { + continue; + } + + $schema['properties'][ $field_name ] = $field_options['schema']; + } + + $schema['properties'] = apply_filters( 'woocommerce_rest_' . $object_type . '_schema', $schema['properties'] ); + + return $schema; + } + + /** + * Compatibility functions for WP 5.5, since custom types are not supported anymore. + * See @link https://core.trac.wordpress.org/changeset/48306 + * + * @param string $method Optional. HTTP method of the request. + * + * @return array Endpoint arguments. + */ + public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) { + + $endpoint_args = parent::get_endpoint_args_for_item_schema( $method ); + + if ( false === strpos( WP_REST_Server::EDITABLE, $method ) ) { + return $endpoint_args; + } + + $endpoint_args = $this->adjust_wp_5_5_datatype_compatibility( $endpoint_args ); + + return $endpoint_args; + } + + /** + * Change datatypes `date-time` to string, and `mixed` to composite of all built in types. This is required for maintaining forward compatibility with WP 5.5 since custom post types are not supported anymore. + * + * See @link https://core.trac.wordpress.org/changeset/48306 + * + * We still use the 'mixed' type, since if we convert to composite type everywhere, it won't work in 5.4 anymore because they require to define the full schema. + * + * @param array $endpoint_args Schema with datatypes to convert. + + * @return mixed Schema with converted datatype. + */ + protected function adjust_wp_5_5_datatype_compatibility( $endpoint_args ) { + if ( version_compare( get_bloginfo( 'version' ), '5.5', '<' ) ) { + return $endpoint_args; + } + + foreach ( $endpoint_args as $field_id => $params ) { + + if ( ! isset( $params['type'] ) ) { + continue; + } + + /** + * Custom types are not supported as of WP 5.5, this translates type => 'date-time' to type => 'string'. + */ + if ( 'date-time' === $params['type'] ) { + $params['type'] = array( 'null', 'string' ); + } + + /** + * WARNING: Order of fields here is important, types of fields are ordered from most specific to least specific as perceived by core's built-in type validation methods. + */ + if ( 'mixed' === $params['type'] ) { + $params['type'] = array( 'null', 'object', 'string', 'number', 'boolean', 'integer', 'array' ); + } + + if ( isset( $params['properties'] ) ) { + $params['properties'] = $this->adjust_wp_5_5_datatype_compatibility( $params['properties'] ); + } + + if ( isset( $params['items'] ) && isset( $params['items']['properties'] ) ) { + $params['items']['properties'] = $this->adjust_wp_5_5_datatype_compatibility( $params['items']['properties'] ); + } + + $endpoint_args[ $field_id ] = $params; + } + return $endpoint_args; + } + + /** + * Get normalized rest base. + * + * @return string + */ + protected function get_normalized_rest_base() { + return preg_replace( '/\(.*\)\//i', '', $this->rest_base ); + } + + /** + * Check batch limit. + * + * @param array $items Request items. + * @return bool|WP_Error + */ + protected function check_batch_limit( $items ) { + $limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() ); + $total = 0; + + if ( ! empty( $items['create'] ) ) { + $total += count( $items['create'] ); + } + + if ( ! empty( $items['update'] ) ) { + $total += count( $items['update'] ); + } + + if ( ! empty( $items['delete'] ) ) { + $total += count( $items['delete'] ); + } + + if ( $total > $limit ) { + /* translators: %s: items limit */ + return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) ); + } + + return true; + } + + /** + * Bulk create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + /** + * REST Server + * + * @var WP_REST_Server $wp_rest_server + */ + global $wp_rest_server; + + // Get the request params. + $items = array_filter( $request->get_params() ); + $query = $request->get_query_params(); + $response = array(); + + // Check batch limit. + $limit = $this->check_batch_limit( $items ); + if ( is_wp_error( $limit ) ) { + return $limit; + } + + if ( ! empty( $items['create'] ) ) { + foreach ( $items['create'] as $item ) { + $_item = new WP_REST_Request( 'POST' ); + + // Default parameters. + $defaults = array(); + $schema = $this->get_public_item_schema(); + foreach ( $schema['properties'] as $arg => $options ) { + if ( isset( $options['default'] ) ) { + $defaults[ $arg ] = $options['default']; + } + } + $_item->set_default_params( $defaults ); + + // Set request parameters. + $_item->set_body_params( $item ); + + // Set query (GET) parameters. + $_item->set_query_params( $query ); + + $_response = $this->create_item( $_item ); + + if ( is_wp_error( $_response ) ) { + $response['create'][] = array( + 'id' => 0, + 'error' => array( + 'code' => $_response->get_error_code(), + 'message' => $_response->get_error_message(), + 'data' => $_response->get_error_data(), + ), + ); + } else { + $response['create'][] = $wp_rest_server->response_to_data( $_response, '' ); + } + } + } + + if ( ! empty( $items['update'] ) ) { + foreach ( $items['update'] as $item ) { + $_item = new WP_REST_Request( 'PUT' ); + $_item->set_body_params( $item ); + $_response = $this->update_item( $_item ); + + if ( is_wp_error( $_response ) ) { + $response['update'][] = array( + 'id' => $item['id'], + 'error' => array( + 'code' => $_response->get_error_code(), + 'message' => $_response->get_error_message(), + 'data' => $_response->get_error_data(), + ), + ); + } else { + $response['update'][] = $wp_rest_server->response_to_data( $_response, '' ); + } + } + } + + if ( ! empty( $items['delete'] ) ) { + foreach ( $items['delete'] as $id ) { + $id = (int) $id; + + if ( 0 === $id ) { + continue; + } + + $_item = new WP_REST_Request( 'DELETE' ); + $_item->set_query_params( + array( + 'id' => $id, + 'force' => true, + ) + ); + $_response = $this->delete_item( $_item ); + + if ( is_wp_error( $_response ) ) { + $response['delete'][] = array( + 'id' => $id, + 'error' => array( + 'code' => $_response->get_error_code(), + 'message' => $_response->get_error_message(), + 'data' => $_response->get_error_data(), + ), + ); + } else { + $response['delete'][] = $wp_rest_server->response_to_data( $_response, '' ); + } + } + } + + return $response; + } + + /** + * Validate a text value for a text based setting. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string + */ + public function validate_setting_text_field( $value, $setting ) { + $value = is_null( $value ) ? '' : $value; + return wp_kses_post( trim( stripslashes( $value ) ) ); + } + + /** + * Validate select based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_select_field( $value, $setting ) { + if ( array_key_exists( $value, $setting['options'] ) ) { + return $value; + } else { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + /** + * Validate multiselect based settings. + * + * @since 3.0.0 + * @param array $values Values. + * @param array $setting Setting. + * @return array|WP_Error + */ + public function validate_setting_multiselect_field( $values, $setting ) { + if ( empty( $values ) ) { + return array(); + } + + if ( ! is_array( $values ) ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $final_values = array(); + foreach ( $values as $value ) { + if ( array_key_exists( $value, $setting['options'] ) ) { + $final_values[] = $value; + } + } + + return $final_values; + } + + /** + * Validate image_width based settings. + * + * @since 3.0.0 + * @param array $values Values. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_image_width_field( $values, $setting ) { + if ( ! is_array( $values ) ) { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $current = $setting['value']; + if ( isset( $values['width'] ) ) { + $current['width'] = intval( $values['width'] ); + } + if ( isset( $values['height'] ) ) { + $current['height'] = intval( $values['height'] ); + } + if ( isset( $values['crop'] ) ) { + $current['crop'] = (bool) $values['crop']; + } + return $current; + } + + /** + * Validate radio based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_radio_field( $value, $setting ) { + return $this->validate_setting_select_field( $value, $setting ); + } + + /** + * Validate checkbox based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string|WP_Error + */ + public function validate_setting_checkbox_field( $value, $setting ) { + if ( in_array( $value, array( 'yes', 'no' ) ) ) { + return $value; + } elseif ( empty( $value ) ) { + $value = isset( $setting['default'] ) ? $setting['default'] : 'no'; + return $value; + } else { + return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + } + + /** + * Validate textarea based settings. + * + * @since 3.0.0 + * @param string $value Value. + * @param array $setting Setting. + * @return string + */ + public function validate_setting_textarea_field( $value, $setting ) { + $value = is_null( $value ) ? '' : $value; + return wp_kses( + trim( stripslashes( $value ) ), + array_merge( + array( + 'iframe' => array( + 'src' => true, + 'style' => true, + 'id' => true, + 'class' => true, + ), + ), + wp_kses_allowed_html( 'post' ) + ) + ); + } + + /** + * Add meta query. + * + * @since 3.0.0 + * @param array $args Query args. + * @param array $meta_query Meta query. + * @return array + */ + protected function add_meta_query( $args, $meta_query ) { + if ( empty( $args['meta_query'] ) ) { + $args['meta_query'] = array(); + } + + $args['meta_query'][] = $meta_query; + + return $args['meta_query']; + } + + /** + * Get the batch schema, conforming to JSON Schema. + * + * @return array + */ + public function get_public_batch_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'batch', + 'type' => 'object', + 'properties' => array( + 'create' => array( + 'description' => __( 'List of created resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + ), + ), + 'update' => array( + 'description' => __( 'List of updated resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + ), + ), + 'delete' => array( + 'description' => __( 'List of delete resources.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + ), + ), + ); + + return $schema; + } + + /** + * Gets an array of fields to be included on the response. + * + * Included fields are based on item schema and `_fields=` request argument. + * Updated from WordPress 5.3, included into this class to support old versions. + * + * @since 3.5.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Fields to be included in the response. + */ + public function get_fields_for_response( $request ) { + $schema = $this->get_item_schema(); + $properties = isset( $schema['properties'] ) ? $schema['properties'] : array(); + + $additional_fields = $this->get_additional_fields(); + foreach ( $additional_fields as $field_name => $field_options ) { + // For back-compat, include any field with an empty schema + // because it won't be present in $this->get_item_schema(). + if ( is_null( $field_options['schema'] ) ) { + $properties[ $field_name ] = $field_options; + } + } + + // Exclude fields that specify a different context than the request context. + $context = $request['context']; + if ( $context ) { + foreach ( $properties as $name => $options ) { + if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) { + unset( $properties[ $name ] ); + } + } + } + + $fields = array_keys( $properties ); + + if ( ! isset( $request['_fields'] ) ) { + return $fields; + } + $requested_fields = wp_parse_list( $request['_fields'] ); + if ( 0 === count( $requested_fields ) ) { + return $fields; + } + // Trim off outside whitespace from the comma delimited list. + $requested_fields = array_map( 'trim', $requested_fields ); + // Always persist 'id', because it can be needed for add_additional_fields_to_object(). + if ( in_array( 'id', $fields, true ) ) { + $requested_fields[] = 'id'; + } + // Return the list of all requested fields which appear in the schema. + return array_reduce( + $requested_fields, + function( $response_fields, $field ) use ( $fields ) { + if ( in_array( $field, $fields, true ) ) { + $response_fields[] = $field; + return $response_fields; + } + // Check for nested fields if $field is not a direct match. + $nested_fields = explode( '.', $field ); + // A nested field is included so long as its top-level property is + // present in the schema. + if ( in_array( $nested_fields[0], $fields, true ) ) { + $response_fields[] = $field; + } + return $response_fields; + }, + array() + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-coupons-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-coupons-controller.php new file mode 100644 index 0000000..b975964 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-coupons-controller.php @@ -0,0 +1,27 @@ + 405 ) ); + } + + /** + * Check if a given request has access to read an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( $object && 0 !== $object->get_id() && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get object permalink. + * + * @param object $object Object. + * @return string + */ + protected function get_permalink( $object ) { + return ''; + } + + /** + * Prepares the object for the REST response. + * + * @since 3.0.0 + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. + */ + protected function prepare_object_for_response( $object, $request ) { + // translators: %s: Class method name. + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + } + + /** + * Prepares one object for create or update operation. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + */ + protected function prepare_object_for_database( $request, $creating = false ) { + // translators: %s: Class method name. + return new WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'woocommerce' ), __METHOD__ ), array( 'status' => 405 ) ); + } + + /** + * Get a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_object_for_response( $object, $request ); + $response = rest_ensure_response( $data ); + + if ( $this->public ) { + $response->link_header( 'alternate', $this->get_permalink( $object ), array( 'type' => 'text/html' ) ); + } + + return $response; + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + $object->save(); + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $object = $this->save_object( $request, true ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + try { + $this->update_additional_fields_for_object( $object, $request ); + + /** + * Fires after a single object is created or updated via the REST API. + * + * @param WC_Data $object Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating object, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true ); + } catch ( WC_Data_Exception $e ) { + $object->delete(); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + $object->delete(); + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ) ); + + return $response; + } + + /** + * Update a single post. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $object = $this->get_object( (int) $request['id'] ); + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $object = $this->save_object( $request, false ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + try { + $this->update_additional_fields_for_object( $object, $request ); + + /** + * Fires after a single object is created or updated via the REST API. + * + * @param WC_Data $object Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating object, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + return rest_ensure_response( $response ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = array(); + $args['offset'] = $request['offset']; + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['paged'] = $request['page']; + $args['post__in'] = $request['include']; + $args['post__not_in'] = $request['exclude']; + $args['posts_per_page'] = $request['per_page']; + $args['name'] = $request['slug']; + $args['post_parent__in'] = $request['parent']; + $args['post_parent__not_in'] = $request['parent_exclude']; + $args['s'] = $request['search']; + + if ( 'date' === $args['orderby'] ) { + $args['orderby'] = 'date ID'; + } + + $args['date_query'] = array(); + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $request['before'] ) ) { + $args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $request['after'] ) ) { + $args['date_query'][0]['after'] = $request['after']; + } + + // Force the post_type argument, since it's not a user input variable. + $args['post_type'] = $this->post_type; + + /** + * Filter the query arguments for a request. + * + * Enables adding extra arguments or setting defaults for a post + * collection request. + * + * @param array $args Key value array of query var to query value. + * @param WP_REST_Request $request The request used. + */ + $args = apply_filters( "woocommerce_rest_{$this->post_type}_object_query", $args, $request ); + + return $this->prepare_items_query( $args, $request ); + } + + /** + * Get objects. + * + * @since 3.0.0 + * @param array $query_args Query args. + * @return array + */ + protected function get_objects( $query_args ) { + $query = new WP_Query(); + $result = $query->query( $query_args ); + + $total_posts = $query->found_posts; + if ( $total_posts < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $query_args['paged'] ); + $count_query = new WP_Query(); + $count_query->query( $query_args ); + $total_posts = $count_query->found_posts; + } + + return array( + 'objects' => array_filter( array_map( array( $this, 'get_object' ), $result ) ), + 'total' => (int) $total_posts, + 'pages' => (int) ceil( $total_posts / (int) $query->query_vars['posts_per_page'] ), + ); + } + + /** + * Get a collection of posts. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $query_args = $this->prepare_objects_query( $request ); + $query_results = $this->get_objects( $query_args ); + + $objects = array(); + foreach ( $query_results['objects'] as $object ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) { + continue; + } + + $data = $this->prepare_object_for_response( $object, $request ); + $objects[] = $this->prepare_response_for_collection( $data ); + } + + $page = (int) $query_args['paged']; + $max_pages = $query_results['pages']; + + $response = rest_ensure_response( $objects ); + $response->header( 'X-WP-Total', $query_results['total'] ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $base = $this->rest_base; + $attrib_prefix = '(?P<'; + if ( strpos( $base, $attrib_prefix ) !== false ) { + $attrib_names = array(); + preg_match( '/\(\?P<[^>]+>.*\)/', $base, $attrib_names, PREG_OFFSET_CAPTURE ); + foreach ( $attrib_names as $attrib_name_match ) { + $beginning_offset = strlen( $attrib_prefix ); + $attrib_name_end = strpos( $attrib_name_match[0], '>', $attrib_name_match[1] ); + $attrib_name = substr( $attrib_name_match[0], $beginning_offset, $attrib_name_end - $beginning_offset ); + if ( isset( $request[ $attrib_name ] ) ) { + $base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base ); + } + } + } + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ) ); + + if ( $page > 1 ) { + $prev_page = $page - 1; + if ( $prev_page > $max_pages ) { + $prev_page = $max_pages; + } + $prev_link = add_query_arg( 'page', $prev_page, $base ); + $response->link_header( 'prev', $prev_link ); + } + if ( $max_pages > $page ) { + $next_page = $page + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $force = (bool) $request['force']; + $object = $this->get_object( (int) $request['id'] ); + $result = false; + + if ( ! $object || 0 === $object->get_id() ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0 && is_callable( array( $object, 'get_status' ) ); + + /** + * Filter whether an object is trashable. + * + * Return false to disable trash support for the object. + * + * @param boolean $supports_trash Whether the object type support trashing. + * @param WC_Data $object The object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_object_trashable", $supports_trash, $object ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $object->get_id() ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_object_for_response( $object, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + $object->delete( true ); + $result = 0 === $object->get_id(); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + } + + // Otherwise, only trash if we haven't already. + if ( is_callable( array( $object, 'get_status' ) ) ) { + if ( 'trash' === $object->get_status() ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } + + $object->delete(); + $result = 'trash' === $object->get_status(); + } + } + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single object is deleted or trashed via the REST API. + * + * @param WC_Data $object The deleted or trashed object. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}_object", $object, $response, $request ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $object, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $object->get_id() ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = array(); + $params['context'] = $this->get_context_param(); + $params['context']['default'] = 'view'; + + $params['page'] = array( + 'description' => __( 'Current page of the collection.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['search'] = array( + 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['before'] = array( + 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + $params['include'] = array( + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( + 'date', + 'id', + 'include', + 'title', + 'slug', + 'modified', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + if ( $this->hierarchical ) { + $params['parent'] = array( + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'sanitize_callback' => 'wp_parse_id_list', + 'default' => array(), + ); + $params['parent_exclude'] = array( + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'sanitize_callback' => 'wp_parse_id_list', + 'default' => array(), + ); + } + + /** + * Filter collection parameters for the posts controller. + * + * The dynamic part of the filter `$this->post_type` refers to the post + * type slug for the controller. + * + * This filter registers the collection parameter, but does not map the + * collection parameter to an internal WP_Query parameter. Use the + * `rest_{$this->post_type}_query` filter to set WP_Query parameters. + * + * @param array $query_params JSON Schema-formatted collection parameters. + * @param WP_Post_Type $post_type Post type object. + */ + return apply_filters( "rest_{$this->post_type}_collection_params", $params, $this->post_type ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-customer-downloads-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-customer-downloads-controller.php new file mode 100644 index 0000000..f6b8c98 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-customer-downloads-controller.php @@ -0,0 +1,27 @@ +/downloads endpoint. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Customers controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Customer_Downloads_V2_Controller + */ +class WC_REST_Customer_Downloads_Controller extends WC_REST_Customer_Downloads_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php new file mode 100644 index 0000000..473094b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php @@ -0,0 +1,307 @@ +get_data(); + $format_date = array( 'date_created', 'date_modified' ); + + // Format date values. + foreach ( $format_date as $key ) { + // Date created is stored UTC, date modified is stored WP local time. + $datetime = 'date_created' === $key ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $data[ $key ]->getTimestamp() ) ) : $data[ $key ]; + $data[ $key ] = wc_rest_prepare_date_response( $datetime, false ); + $data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime ); + } + + return array( + 'id' => $object->get_id(), + 'date_created' => $data['date_created'], + 'date_created_gmt' => $data['date_created_gmt'], + 'date_modified' => $data['date_modified'], + 'date_modified_gmt' => $data['date_modified_gmt'], + 'email' => $data['email'], + 'first_name' => $data['first_name'], + 'last_name' => $data['last_name'], + 'role' => $data['role'], + 'username' => $data['username'], + 'billing' => $data['billing'], + 'shipping' => $data['shipping'], + 'is_paying_customer' => $data['is_paying_customer'], + 'avatar_url' => $object->get_avatar_url(), + 'meta_data' => $data['meta_data'], + ); + } + + /** + * Get the Customer's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'customer', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the customer was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'email' => array( + 'description' => __( 'The email address for the customer.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'first_name' => array( + 'description' => __( 'Customer first name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'last_name' => array( + 'description' => __( 'Customer last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'role' => array( + 'description' => __( 'Customer role.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'username' => array( + 'description' => __( 'Customer login name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_user', + ), + ), + 'password' => array( + 'description' => __( 'Customer password.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'edit' ), + ), + 'billing' => array( + 'description' => __( 'List of billing address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'email' => array( + 'description' => __( 'Email address.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'phone' => array( + 'description' => __( 'Phone number.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping' => array( + 'description' => __( 'List of shipping address data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'first_name' => array( + 'description' => __( 'First name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'last_name' => array( + 'description' => __( 'Last name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'company' => array( + 'description' => __( 'Company name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_1' => array( + 'description' => __( 'Address line 1', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'address_2' => array( + 'description' => __( 'Address line 2', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'city' => array( + 'description' => __( 'City name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'state' => array( + 'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'postcode' => array( + 'description' => __( 'Postal code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'country' => array( + 'description' => __( 'ISO code of the country.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'is_paying_customer' => array( + 'description' => __( 'Is the customer a paying customer?', 'woocommerce' ), + 'type' => 'bool', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avatar_url' => array( + 'description' => __( 'Avatar URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php new file mode 100644 index 0000000..f998271 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php @@ -0,0 +1,362 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]+)', + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => array( + 'continent' => array( + 'description' => __( '2 character continent code.', 'woocommerce' ), + 'type' => 'string', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Return the list of countries and states for a given continent. + * + * @since 3.5.0 + * @param string $continent_code Continent code. + * @param WP_REST_Request $request Request data. + * @return array|mixed Response data, ready for insertion into collection data. + */ + public function get_continent( $continent_code, $request ) { + $continents = WC()->countries->get_continents(); + $countries = WC()->countries->get_countries(); + $states = WC()->countries->get_states(); + $locale_info = include WC()->plugin_path() . '/i18n/locale-info.php'; + $data = array(); + + if ( ! array_key_exists( $continent_code, $continents ) ) { + return false; + } + + $continent_list = $continents[ $continent_code ]; + + $continent = array( + 'code' => $continent_code, + 'name' => $continent_list['name'], + ); + + $local_countries = array(); + foreach ( $continent_list['countries'] as $country_code ) { + if ( isset( $countries[ $country_code ] ) ) { + $country = array( + 'code' => $country_code, + 'name' => $countries[ $country_code ], + ); + + // If we have detailed locale information include that in the response. + if ( array_key_exists( $country_code, $locale_info ) ) { + // Defensive programming against unexpected changes in locale-info.php. + $country_data = wp_parse_args( + $locale_info[ $country_code ], + array( + 'currency_code' => 'USD', + 'currency_pos' => 'left', + 'decimal_sep' => '.', + 'dimension_unit' => 'in', + 'num_decimals' => 2, + 'thousand_sep' => ',', + 'weight_unit' => 'lbs', + ) + ); + + $country = array_merge( $country, $country_data ); + } + + $local_states = array(); + if ( isset( $states[ $country_code ] ) ) { + foreach ( $states[ $country_code ] as $state_code => $state_name ) { + $local_states[] = array( + 'code' => $state_code, + 'name' => $state_name, + ); + } + } + $country['states'] = $local_states; + + // Allow only desired keys (e.g. filter out tax rates). + $allowed = array( + 'code', + 'currency_code', + 'currency_pos', + 'decimal_sep', + 'dimension_unit', + 'name', + 'num_decimals', + 'states', + 'thousand_sep', + 'weight_unit', + ); + $country = array_intersect_key( $country, array_flip( $allowed ) ); + + $local_countries[] = $country; + } + } + + $continent['countries'] = $local_countries; + return $continent; + } + + /** + * Return the list of states for all continents. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $continents = WC()->countries->get_continents(); + $data = array(); + + foreach ( array_keys( $continents ) as $continent_code ) { + $continent = $this->get_continent( $continent_code, $request ); + $response = $this->prepare_item_for_response( $continent, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + + return rest_ensure_response( $data ); + } + + /** + * Return the list of locations for a given continent. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $data = $this->get_continent( strtoupper( $request['location'] ), $request ); + if ( empty( $data ) ) { + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return $this->prepare_item_for_response( $data, $request ); + } + + /** + * Prepare the data object for response. + * + * @since 3.5.0 + * @param object $item Data object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter the location list returned from the API. + * + * Allows modification of the loction data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param array $item The original list of continent(s), countries, and states. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_data_continent', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given continent. + */ + protected function prepare_links( $item ) { + $continent_code = strtolower( $item['code'] ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $continent_code ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + return $links; + } + + /** + * Get the location schema, conforming to JSON Schema. + * + * @since 3.5.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_continents', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( '2 character continent code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of continent.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'countries' => array( + 'type' => 'array', + 'description' => __( 'List of countries on this continent.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_code' => array( + 'type' => 'string', + 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'currency_pos' => array( + 'type' => 'string', + 'description' => __( 'Currency symbol position for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'decimal_sep' => array( + 'type' => 'string', + 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'dimension_unit' => array( + 'type' => 'string', + 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'num_decimals' => array( + 'type' => 'integer', + 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'states' => array( + 'type' => 'array', + 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'State code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of state.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + 'thousand_sep' => array( + 'type' => 'string', + 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'weight_unit' => array( + 'type' => 'string', + 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php new file mode 100644 index 0000000..9315030 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php @@ -0,0 +1,184 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to read site data. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check whether a given request has permission to read site settings. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Return the list of data resources. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $data = array(); + $resources = array( + array( + 'slug' => 'continents', + 'description' => __( 'List of supported continents, countries, and states.', 'woocommerce' ), + ), + array( + 'slug' => 'countries', + 'description' => __( 'List of supported states in a given country.', 'woocommerce' ), + ), + array( + 'slug' => 'currencies', + 'description' => __( 'List of supported currencies.', 'woocommerce' ), + ), + ); + + foreach ( $resources as $resource ) { + $item = $this->prepare_item_for_response( (object) $resource, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare a data resource object for serialization. + * + * @param stdClass $resource Resource data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $resource, $request ) { + $data = array( + 'slug' => $resource->slug, + 'description' => $resource->description, + ); + + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $resource ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given country. + */ + protected function prepare_links( $item ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $item->slug ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Get the data index schema, conforming to JSON Schema. + * + * @since 3.5.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_index', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'Data resource ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Data resource description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php new file mode 100644 index 0000000..7144e5f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php @@ -0,0 +1,244 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]+)', + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => array( + 'location' => array( + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'type' => 'string', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get a list of countries and states. + * + * @param string $country_code Country code. + * @param WP_REST_Request $request Request data. + * @return array|mixed Response data, ready for insertion into collection data. + */ + public function get_country( $country_code, $request ) { + $countries = WC()->countries->get_countries(); + $states = WC()->countries->get_states(); + $data = array(); + + if ( ! array_key_exists( $country_code, $countries ) ) { + return false; + } + + $country = array( + 'code' => $country_code, + 'name' => $countries[ $country_code ], + ); + + $local_states = array(); + if ( isset( $states[ $country_code ] ) ) { + foreach ( $states[ $country_code ] as $state_code => $state_name ) { + $local_states[] = array( + 'code' => $state_code, + 'name' => $state_name, + ); + } + } + $country['states'] = $local_states; + return $country; + } + + /** + * Return the list of states for all countries. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $countries = WC()->countries->get_countries(); + $data = array(); + + foreach ( array_keys( $countries ) as $country_code ) { + $country = $this->get_country( $country_code, $request ); + $response = $this->prepare_item_for_response( $country, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + + return rest_ensure_response( $data ); + } + + /** + * Return the list of states for a given country. + * + * @since 3.5.0 + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $data = $this->get_country( strtoupper( $request['location'] ), $request ); + if ( empty( $data ) ) { + return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return $this->prepare_item_for_response( $data, $request ); + } + + /** + * Prepare the data object for response. + * + * @since 3.5.0 + * @param object $item Data object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter the states list for a country returned from the API. + * + * Allows modification of the loction data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param array $data The original country's states list. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_data_country', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given country. + */ + protected function prepare_links( $item ) { + $country_code = strtolower( $item['code'] ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $country_code ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + + /** + * Get the location schema, conforming to JSON Schema. + * + * @since 3.5.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_countries', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'states' => array( + 'type' => 'array', + 'description' => __( 'List of states in this country.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'context' => array( 'view' ), + 'readonly' => true, + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'State code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of state.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php new file mode 100644 index 0000000..09fca0f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php @@ -0,0 +1,227 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/current', + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_current_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\w-]{3})', + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'location' => array( + 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'type' => 'string', + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Get currency information. + * + * @param string $code Currency code. + * @param WP_REST_Request $request Request data. + * @return array|mixed Response data, ready for insertion into collection data. + */ + public function get_currency( $code, $request ) { + $currencies = get_woocommerce_currencies(); + $data = array(); + + if ( ! array_key_exists( $code, $currencies ) ) { + return false; + } + + $currency = array( + 'code' => $code, + 'name' => $currencies[ $code ], + 'symbol' => get_woocommerce_currency_symbol( $code ), + ); + + return $currency; + } + + /** + * Return the list of currencies. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $currencies = get_woocommerce_currencies(); + foreach ( array_keys( $currencies ) as $code ) { + $currency = $this->get_currency( $code, $request ); + $response = $this->prepare_item_for_response( $currency, $request ); + $data[] = $this->prepare_response_for_collection( $response ); + } + + return rest_ensure_response( $data ); + } + + /** + * Return information for a specific currency. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $data = $this->get_currency( strtoupper( $request['currency'] ), $request ); + if ( empty( $data ) ) { + return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) ); + } + return $this->prepare_item_for_response( $data, $request ); + } + + /** + * Return information for the current site currency. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function get_current_item( $request ) { + $currency = get_option( 'woocommerce_currency' ); + return $this->prepare_item_for_response( $this->get_currency( $currency, $request ), $request ); + } + + /** + * Prepare the data object for response. + * + * @param object $item Data object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, 'view' ); + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item ) ); + + /** + * Filter currency returned from the API. + * + * @param WP_REST_Response $response The response object. + * @param array $item Currency data. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_data_currency', $response, $item, $request ); + } + + /** + * Prepare links for the request. + * + * @param object $item Data object. + * @return array Links for the given currency. + */ + protected function prepare_links( $item ) { + $code = strtoupper( $item['code'] ); + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $code ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + + /** + * Get the currency schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'data_currencies', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'type' => 'string', + 'description' => __( 'ISO4217 currency code.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'type' => 'string', + 'description' => __( 'Full name of currency.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'symbol' => array( + 'type' => 'string', + 'description' => __( 'Currency symbol.', 'woocommerce' ), + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-network-orders-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-network-orders-controller.php new file mode 100644 index 0000000..e37e2da --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-network-orders-controller.php @@ -0,0 +1,27 @@ +/notes endpoint. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Order Notes controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Order_Notes_V2_Controller + */ +class WC_REST_Order_Notes_Controller extends WC_REST_Order_Notes_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; + + /** + * Prepare a single order note output for response. + * + * @param WP_Comment $note Order note object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $note, $request ) { + $data = array( + 'id' => (int) $note->comment_ID, + 'author' => __( 'woocommerce', 'woocommerce' ) === $note->comment_author ? 'system' : $note->comment_author, + 'date_created' => wc_rest_prepare_date_response( $note->comment_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ), + 'note' => $note->comment_content, + 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $note ) ); + + /** + * Filter order note object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $note Order note object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); + } + + /** + * Create a single order note. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order || $this->post_type !== $order->get_type() ) { + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Create the note. + $note_id = $order->add_order_note( $request['note'], $request['customer_note'], $request['added_by_user'] ); + + if ( ! $note_id ) { + return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $note = get_comment( $note_id ); + $this->update_additional_fields_for_object( $note, $request ); + + /** + * Fires after a order note is created or updated via the REST API. + * + * @param WP_Comment $note New order note object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $note, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, str_replace( '(?P[\d]+)', $order->get_id(), $this->rest_base ), $note_id ) ) ); + + return $response; + } + + /** + * Get the Order Notes schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'order_note', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'author' => array( + 'description' => __( 'Order note author.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'note' => array( + 'description' => __( 'Order note content.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'customer_note' => array( + 'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'added_by_user' => array( + 'description' => __( 'If true, this note will be attributed to the current user. If false, the note will be attributed to the system.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php new file mode 100644 index 0000000..7c6ef99 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php @@ -0,0 +1,86 @@ +/refunds endpoint. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Order Refunds controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Order_Refunds_V2_Controller + */ +class WC_REST_Order_Refunds_Controller extends WC_REST_Order_Refunds_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; + + /** + * Prepares one object for create or update operation. + * + * @since 3.0.0 + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data The prepared item, or WP_Error object on failure. + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $order = wc_get_order( (int) $request['order_id'] ); + + if ( ! $order ) { + return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); + } + + if ( 0 > $request['amount'] ) { + return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 ); + } + + // Create the refund. + $refund = wc_create_refund( + array( + 'order_id' => $order->get_id(), + 'amount' => $request['amount'], + 'reason' => empty( $request['reason'] ) ? null : $request['reason'], + 'line_items' => empty( $request['line_items'] ) ? array() : $request['line_items'], + 'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true, + 'restock_items' => true, + ) + ); + + if ( is_wp_error( $refund ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 ); + } + + if ( ! $refund ) { + return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 ); + } + + if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $refund->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + $refund->save_meta_data(); + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $coupon Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php new file mode 100644 index 0000000..174a866 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php @@ -0,0 +1,271 @@ +get_items( 'coupon' ) as $coupon ) { + $order->remove_coupon( $coupon->get_code() ); + } + + foreach ( $request['coupon_lines'] as $item ) { + if ( is_array( $item ) ) { + if ( empty( $item['id'] ) ) { + if ( empty( $item['code'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_coupon', __( 'Coupon code is required.', 'woocommerce' ), 400 ); + } + + $results = $order->apply_coupon( wc_clean( $item['code'] ) ); + + if ( is_wp_error( $results ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_' . $results->get_error_code(), $results->get_error_message(), 400 ); + } + } + } + } + + return true; + } + + /** + * Prepare a single order for create or update. + * + * @throws WC_REST_Exception When fails to set any item. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + $order = new WC_Order( $id ); + $schema = $this->get_item_schema(); + $data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) ); + + // Handle all writable props. + foreach ( $data_keys as $key ) { + $value = $request[ $key ]; + + if ( ! is_null( $value ) ) { + switch ( $key ) { + case 'coupon_lines': + case 'status': + // Change should be done later so transitions have new data. + break; + case 'billing': + case 'shipping': + $this->update_address( $order, $value, $key ); + break; + case 'line_items': + case 'shipping_lines': + case 'fee_lines': + if ( is_array( $value ) ) { + foreach ( $value as $item ) { + if ( is_array( $item ) ) { + if ( $this->item_is_null( $item ) || ( isset( $item['quantity'] ) && 0 === $item['quantity'] ) ) { + $order->remove_item( $item['id'] ); + } else { + $this->set_item( $order, $key, $item ); + } + } + } + } + break; + case 'meta_data': + if ( is_array( $value ) ) { + foreach ( $value as $meta ) { + $order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + break; + default: + if ( is_callable( array( $order, "set_{$key}" ) ) ) { + $order->{"set_{$key}"}( $value ); + } + break; + } + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $order Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); + } + + /** + * Save an object data. + * + * @since 3.0.0 + * @throws WC_REST_Exception But all errors are validated before returning any data. + * @param WP_REST_Request $request Full details about the request. + * @param bool $creating If is creating a new object. + * @return WC_Data|WP_Error + */ + protected function save_object( $request, $creating = false ) { + try { + $object = $this->prepare_object_for_database( $request, $creating ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + // Make sure gateways are loaded so hooks from gateways fire on save/create. + WC()->payment_gateways(); + + if ( ! is_null( $request['customer_id'] ) && 0 !== $request['customer_id'] ) { + // Make sure customer exists. + if ( false === get_user_by( 'id', $request['customer_id'] ) ) { + throw new WC_REST_Exception( 'woocommerce_rest_invalid_customer_id', __( 'Customer ID is invalid.', 'woocommerce' ), 400 ); + } + + // Make sure customer is part of blog. + if ( is_multisite() && ! is_user_member_of_blog( $request['customer_id'] ) ) { + add_user_to_blog( get_current_blog_id(), $request['customer_id'], 'customer' ); + } + } + + if ( $creating ) { + $object->set_created_via( 'rest-api' ); + $object->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $object->calculate_totals(); + } else { + // If items have changed, recalculate order totals. + if ( isset( $request['billing'] ) || isset( $request['shipping'] ) || isset( $request['line_items'] ) || isset( $request['shipping_lines'] ) || isset( $request['fee_lines'] ) || isset( $request['coupon_lines'] ) ) { + $object->calculate_totals( true ); + } + } + + // Set coupons. + $this->calculate_coupons( $request, $object ); + + // Set status. + if ( ! empty( $request['status'] ) ) { + $object->set_status( $request['status'] ); + } + + $object->save(); + + // Actions for after the order is saved. + if ( true === $request['set_paid'] ) { + if ( $creating || $object->needs_payment() ) { + $object->payment_complete( $request['transaction_id'] ); + } + } + + return $this->get_object( $object->get_id() ); + } catch ( WC_Data_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() ); + } catch ( WC_REST_Exception $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + // This is needed to get around an array to string notice in WC_REST_Orders_V2_Controller::prepare_objects_query. + $statuses = $request['status']; + unset( $request['status'] ); + $args = parent::prepare_objects_query( $request ); + + $args['post_status'] = array(); + foreach ( $statuses as $status ) { + if ( in_array( $status, $this->get_order_statuses(), true ) ) { + $args['post_status'][] = 'wc-' . $status; + } elseif ( 'any' === $status ) { + // Set status to "any" and short-circuit out. + $args['post_status'] = 'any'; + break; + } else { + $args['post_status'][] = $status; + } + } + + // Put the statuses back for further processing (next/prev links, etc). + $request['status'] = $statuses; + + return $args; + } + + /** + * Get the Order's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = parent::get_item_schema(); + + $schema['properties']['coupon_lines']['items']['properties']['discount']['readonly'] = true; + + return $schema; + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['status'] = array( + 'default' => 'any', + 'description' => __( 'Limit result set to orders which have specific statuses.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + 'enum' => array_merge( array( 'any', 'trash' ), $this->get_order_statuses() ), + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php new file mode 100644 index 0000000..8ffc68b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php @@ -0,0 +1,226 @@ + $gateway->id, + 'title' => $gateway->title, + 'description' => $gateway->description, + 'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '', + 'enabled' => ( 'yes' === $gateway->enabled ), + 'method_title' => $gateway->get_method_title(), + 'method_description' => $gateway->get_method_description(), + 'method_supports' => $gateway->supports, + 'settings' => $this->get_settings( $gateway ), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $gateway, $request ) ); + + /** + * Filter payment gateway objects returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WC_Payment_Gateway $gateway Payment gateway object. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request ); + } + + /** + * Return settings associated with this payment gateway. + * + * @param WC_Payment_Gateway $gateway Gateway instance. + * + * @return array + */ + public function get_settings( $gateway ) { + $settings = array(); + $gateway->init_form_fields(); + foreach ( $gateway->form_fields as $id => $field ) { + // Make sure we at least have a title and type. + if ( empty( $field['title'] ) || empty( $field['type'] ) ) { + continue; + } + + // Ignore 'enabled' and 'description' which get included elsewhere. + if ( in_array( $id, array( 'enabled', 'description' ), true ) ) { + continue; + } + + $data = array( + 'id' => $id, + 'label' => empty( $field['label'] ) ? $field['title'] : $field['label'], + 'description' => empty( $field['description'] ) ? '' : $field['description'], + 'type' => $field['type'], + 'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ], + 'default' => empty( $field['default'] ) ? '' : $field['default'], + 'tip' => empty( $field['description'] ) ? '' : $field['description'], + 'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'], + ); + if ( ! empty( $field['options'] ) ) { + $data['options'] = $field['options']; + } + $settings[ $id ] = $data; + } + return $settings; + } + + /** + * Get the payment gateway schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'payment_gateway', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Payment gateway ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'title' => array( + 'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'order' => array( + 'description' => __( 'Payment gateway sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'absint', + ), + ), + 'enabled' => array( + 'description' => __( 'Payment gateway enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'method_title' => array( + 'description' => __( 'Payment gateway method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_description' => array( + 'description' => __( 'Payment gateway method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'method_supports' => array( + 'description' => __( 'Supported features for this payment gateway.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'string', + ), + ), + 'settings' => array( + 'description' => __( 'Payment gateway settings.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php new file mode 100644 index 0000000..59757f3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php @@ -0,0 +1,724 @@ +post_type, 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $post = get_post( (int) $request['id'] ); + + if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $post = get_post( (int) $request['id'] ); + + if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete an item. + * + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function delete_item_permissions_check( $request ) { + $post = get_post( (int) $request['id'] ); + + if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return boolean|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $id = (int) $request['id']; + $post = get_post( $id ); + + if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $data ); + + if ( $this->public ) { + $response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) ); + } + + return $response; + } + + /** + * Create a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + + $post->post_type = $this->post_type; + $post_id = wp_insert_post( $post, true ); + + if ( is_wp_error( $post_id ) ) { + + if ( in_array( $post_id->get_error_code(), array( 'db_insert_error' ) ) ) { + $post_id->add_data( array( 'status' => 500 ) ); + } else { + $post_id->add_data( array( 'status' => 400 ) ); + } + return $post_id; + } + $post->ID = $post_id; + $post = get_post( $post_id ); + + $this->update_additional_fields_for_object( $post, $request ); + + // Add meta fields. + $meta_fields = $this->add_post_meta_fields( $post, $request ); + if ( is_wp_error( $meta_fields ) ) { + // Remove post. + $this->delete_post( $post ); + + return $meta_fields; + } + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post_id ) ) ); + + return $response; + } + + /** + * Add post meta fields. + * + * @param WP_Post $post Post Object. + * @param WP_REST_Request $request WP_REST_Request Object. + * @return bool|WP_Error + */ + protected function add_post_meta_fields( $post, $request ) { + return true; + } + + /** + * Delete post. + * + * @param WP_Post $post Post object. + */ + protected function delete_post( $post ) { + wp_delete_post( $post->ID, true ); + } + + /** + * Update a single post. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $post = get_post( $id ); + + if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) { + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( 'status' => 404 ) ); + } elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $post = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $post ) ) { + return $post; + } + // Convert the post object to an array, otherwise wp_update_post will expect non-escaped input. + $post_id = wp_update_post( (array) $post, true ); + if ( is_wp_error( $post_id ) ) { + if ( in_array( $post_id->get_error_code(), array( 'db_update_error' ) ) ) { + $post_id->add_data( array( 'status' => 500 ) ); + } else { + $post_id->add_data( array( 'status' => 400 ) ); + } + return $post_id; + } + + $post = get_post( $post_id ); + $this->update_additional_fields_for_object( $post, $request ); + + // Update meta fields. + $meta_fields = $this->update_post_meta_fields( $post, $request ); + if ( is_wp_error( $meta_fields ) ) { + return $meta_fields; + } + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + } + + /** + * Get a collection of posts. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $args = array(); + $args['offset'] = $request['offset']; + $args['order'] = $request['order']; + $args['orderby'] = $request['orderby']; + $args['paged'] = $request['page']; + $args['post__in'] = $request['include']; + $args['post__not_in'] = $request['exclude']; + $args['posts_per_page'] = $request['per_page']; + $args['name'] = $request['slug']; + $args['post_parent__in'] = $request['parent']; + $args['post_parent__not_in'] = $request['parent_exclude']; + $args['s'] = $request['search']; + + $args['date_query'] = array(); + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $request['before'] ) ) { + $args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $request['after'] ) ) { + $args['date_query'][0]['after'] = $request['after']; + } + + if ( 'wc/v1' === $this->namespace ) { + if ( is_array( $request['filter'] ) ) { + $args = array_merge( $args, $request['filter'] ); + unset( $args['filter'] ); + } + } + + // Force the post_type argument, since it's not a user input variable. + $args['post_type'] = $this->post_type; + + /** + * Filter the query arguments for a request. + * + * Enables adding extra arguments or setting defaults for a post + * collection request. + * + * @param array $args Key value array of query var to query value. + * @param WP_REST_Request $request The request used. + */ + $args = apply_filters( "woocommerce_rest_{$this->post_type}_query", $args, $request ); + $query_args = $this->prepare_items_query( $args, $request ); + + $posts_query = new WP_Query(); + $query_result = $posts_query->query( $query_args ); + + $posts = array(); + foreach ( $query_result as $post ) { + if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) { + continue; + } + + $data = $this->prepare_item_for_response( $post, $request ); + $posts[] = $this->prepare_response_for_collection( $data ); + } + + $page = (int) $query_args['paged']; + $total_posts = $posts_query->found_posts; + + if ( $total_posts < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $query_args['paged'] ); + $count_query = new WP_Query(); + $count_query->query( $query_args ); + $total_posts = $count_query->found_posts; + } + + $max_pages = ceil( $total_posts / (int) $query_args['posts_per_page'] ); + + $response = rest_ensure_response( $posts ); + $response->header( 'X-WP-Total', (int) $total_posts ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $request_params = $request->get_query_params(); + if ( ! empty( $request_params['filter'] ) ) { + // Normalize the pagination params. + unset( $request_params['filter']['posts_per_page'] ); + unset( $request_params['filter']['paged'] ); + } + $base = add_query_arg( $request_params, rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) ); + + if ( $page > 1 ) { + $prev_page = $page - 1; + if ( $prev_page > $max_pages ) { + $prev_page = $max_pages; + } + $prev_link = add_query_arg( 'page', $prev_page, $base ); + $response->link_header( 'prev', $prev_link ); + } + if ( $max_pages > $page ) { + $next_page = $page + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Delete a single item. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $id = (int) $request['id']; + $force = (bool) $request['force']; + $post = get_post( $id ); + + if ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) { + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $supports_trash = EMPTY_TRASH_DAYS > 0; + + /** + * Filter whether an item is trashable. + * + * Return false to disable trash support for the item. + * + * @param boolean $supports_trash Whether the item type support trashing. + * @param WP_Post $post The Post object being considered for trashing support. + */ + $supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post ); + + if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) { + /* translators: %s: post type */ + return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $post, $request ); + + // If we're forcing, then delete permanently. + if ( $force ) { + $result = wp_delete_post( $id, true ); + } else { + // If we don't support trashing for this type, error out. + if ( ! $supports_trash ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) ); + } + + // Otherwise, only trash if we haven't already. + if ( 'trash' === $post->post_status ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) ); + } + + // (Note that internally this falls through to `wp_delete_post` if + // the trash is disabled.) + $result = wp_trash_post( $id ); + } + + if ( ! $result ) { + /* translators: %s: post type */ + return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single item is deleted or trashed via the REST API. + * + * @param object $post The deleted or trashed item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return array Links for the given post. + */ + protected function prepare_links( $post, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + return $links; + } + + /** + * Determine the allowed query_vars for a get_items() response and + * prepare for WP_Query. + * + * @param array $prepared_args Prepared arguments. + * @param WP_REST_Request $request Request object. + * @return array $query_args + */ + protected function prepare_items_query( $prepared_args = array(), $request = null ) { + + $valid_vars = array_flip( $this->get_allowed_query_vars() ); + $query_args = array(); + foreach ( $valid_vars as $var => $index ) { + if ( isset( $prepared_args[ $var ] ) ) { + /** + * Filter the query_vars used in `get_items` for the constructed query. + * + * The dynamic portion of the hook name, $var, refers to the query_var key. + * + * @param mixed $prepared_args[ $var ] The query_var value. + */ + $query_args[ $var ] = apply_filters( "woocommerce_rest_query_var-{$var}", $prepared_args[ $var ] ); + } + } + + $query_args['ignore_sticky_posts'] = true; + + if ( 'include' === $query_args['orderby'] ) { + $query_args['orderby'] = 'post__in'; + } elseif ( 'id' === $query_args['orderby'] ) { + $query_args['orderby'] = 'ID'; // ID must be capitalized. + } elseif ( 'slug' === $query_args['orderby'] ) { + $query_args['orderby'] = 'name'; + } + + return $query_args; + } + + /** + * Get all the WP Query vars that are allowed for the API request. + * + * @return array + */ + protected function get_allowed_query_vars() { + global $wp; + + /** + * Filter the publicly allowed query vars. + * + * Allows adjusting of the default query vars that are made public. + * + * @param array Array of allowed WP_Query query vars. + */ + $valid_vars = apply_filters( 'query_vars', $wp->public_query_vars ); + + $post_type_obj = get_post_type_object( $this->post_type ); + if ( current_user_can( $post_type_obj->cap->edit_posts ) ) { + /** + * Filter the allowed 'private' query vars for authorized users. + * + * If the user has the `edit_posts` capability, we also allow use of + * private query parameters, which are only undesirable on the + * frontend, but are safe for use in query strings. + * + * To disable anyway, use + * `add_filter( 'woocommerce_rest_private_query_vars', '__return_empty_array' );` + * + * @param array $private_query_vars Array of allowed query vars for authorized users. + * } + */ + $private = apply_filters( 'woocommerce_rest_private_query_vars', $wp->private_query_vars ); + $valid_vars = array_merge( $valid_vars, $private ); + } + // Define our own in addition to WP's normal vars. + $rest_valid = array( + 'date_query', + 'ignore_sticky_posts', + 'offset', + 'post__in', + 'post__not_in', + 'post_parent', + 'post_parent__in', + 'post_parent__not_in', + 'posts_per_page', + 'meta_query', + 'tax_query', + 'meta_key', + 'meta_value', + 'meta_compare', + 'meta_value_num', + ); + $valid_vars = array_merge( $valid_vars, $rest_valid ); + + /** + * Filter allowed query vars for the REST API. + * + * This filter allows you to add or remove query vars from the final allowed + * list for all requests, including unauthenticated ones. To alter the + * vars for editors only. + * + * @param array { + * Array of allowed WP_Query query vars. + * + * @param string $allowed_query_var The query var to allow. + * } + */ + $valid_vars = apply_filters( 'woocommerce_rest_query_vars', $valid_vars ); + + return $valid_vars; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['before'] = array( + 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + $params['include'] = array( + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( + 'date', + 'id', + 'include', + 'title', + 'slug', + 'modified', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $post_type_obj = get_post_type_object( $this->post_type ); + + if ( isset( $post_type_obj->hierarchical ) && $post_type_obj->hierarchical ) { + $params['parent'] = array( + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'sanitize_callback' => 'wp_parse_id_list', + 'default' => array(), + ); + $params['parent_exclude'] = array( + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'sanitize_callback' => 'wp_parse_id_list', + 'default' => array(), + ); + } + + if ( 'wc/v1' === $this->namespace ) { + $params['filter'] = array( + 'type' => 'object', + 'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce' ), + ); + } + + return $params; + } + + /** + * Update post meta fields. + * + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return bool|WP_Error + */ + protected function update_post_meta_fields( $post, $request ) { + return true; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php new file mode 100644 index 0000000..3d08490 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php @@ -0,0 +1,27 @@ +/terms endpoint. + * + * @package WooCommerce\RestApi + * @since 2.6.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Product Attribute Terms controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Product_Attribute_Terms_V2_Controller + */ +class WC_REST_Product_Attribute_Terms_Controller extends WC_REST_Product_Attribute_Terms_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-attributes-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-attributes-controller.php new file mode 100644 index 0000000..06c55f5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-attributes-controller.php @@ -0,0 +1,27 @@ +term_id, 'display_type', true ); + + // Get category order. + $menu_order = get_term_meta( $item->term_id, 'order', true ); + + $data = array( + 'id' => (int) $item->term_id, + 'name' => $item->name, + 'slug' => $item->slug, + 'parent' => (int) $item->parent, + 'description' => $item->description, + 'display' => $display_type ? $display_type : 'default', + 'image' => null, + 'menu_order' => (int) $menu_order, + 'count' => (int) $item->count, + ); + + // Get category image. + $image_id = get_term_meta( $item->term_id, 'thumbnail_id', true ); + if ( $image_id ) { + $attachment = get_post( $image_id ); + + $data['image'] = array( + 'id' => (int) $image_id, + 'date_created' => wc_rest_prepare_date_response( $attachment->post_date ), + 'date_created_gmt' => wc_rest_prepare_date_response( $attachment->post_date_gmt ), + 'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ), + 'src' => wp_get_attachment_url( $image_id ), + 'name' => get_the_title( $attachment ), + 'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ), + ); + } + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $item, $request ) ); + + /** + * Filter a term item returned from the API. + * + * Allows modification of the term data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $item The original term object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request ); + } + + /** + * Get the Category schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->taxonomy, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'parent' => array( + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'HTML description of the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'display' => array( + 'description' => __( 'Category archive display type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'default', + 'enum' => array( 'default', 'products', 'subcategories', 'both' ), + 'context' => array( 'view', 'edit' ), + ), + 'image' => array( + 'description' => __( 'Image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'count' => array( + 'description' => __( 'Number of published products for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Update term meta fields. + * + * @param WP_Term $term Term object. + * @param WP_REST_Request $request Request instance. + * @return bool|WP_Error + * + * @since 3.5.5 + */ + protected function update_term_meta_fields( $term, $request ) { + $id = (int) $term->term_id; + + if ( isset( $request['display'] ) ) { + update_term_meta( $id, 'display_type', 'default' === $request['display'] ? '' : $request['display'] ); + } + + if ( isset( $request['menu_order'] ) ) { + update_term_meta( $id, 'order', $request['menu_order'] ); + } + + if ( isset( $request['image'] ) ) { + if ( empty( $request['image']['id'] ) && ! empty( $request['image']['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $request['image']['src'] ) ); + + if ( is_wp_error( $upload ) ) { + return $upload; + } + + $image_id = wc_rest_set_uploaded_image_as_attachment( $upload ); + } else { + $image_id = isset( $request['image']['id'] ) ? absint( $request['image']['id'] ) : 0; + } + + // Check if image_id is a valid image attachment before updating the term meta. + if ( $image_id && wp_attachment_is_image( $image_id ) ) { + update_term_meta( $id, 'thumbnail_id', $image_id ); + + // Set the image alt. + if ( ! empty( $request['image']['alt'] ) ) { + update_post_meta( $image_id, '_wp_attachment_image_alt', wc_clean( $request['image']['alt'] ) ); + } + + // Set the image title. + if ( ! empty( $request['image']['name'] ) ) { + wp_update_post( + array( + 'ID' => $image_id, + 'post_title' => wc_clean( $request['image']['name'] ), + ) + ); + } + } else { + delete_term_meta( $id, 'thumbnail_id' ); + } + } + + return true; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php new file mode 100644 index 0000000..40aea51 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php @@ -0,0 +1,1164 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'product_id' => array( + 'required' => true, + 'description' => __( 'Unique identifier for the product.', 'woocommerce' ), + 'type' => 'integer', + ), + 'review' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Review content.', 'woocommerce' ), + ), + 'reviewer' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Name of the reviewer.', 'woocommerce' ), + ), + 'reviewer_email' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'Email of the reviewer.', 'woocommerce' ), + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Check whether a given request has permission to read webhook deliveries. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_product_reviews_permissions( 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $id = (int) $request['id']; + $review = get_comment( $id ); + + if ( $review && ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a new product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $id = (int) $request['id']; + $review = get_comment( $id ); + + if ( $review && ! wc_rest_check_product_reviews_permissions( 'edit', $review->comment_ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $id = (int) $request['id']; + $review = get_comment( $id ); + + if ( $review && ! wc_rest_check_product_reviews_permissions( 'delete', $review->comment_ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return boolean|WP_Error + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_product_reviews_permissions( 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get all reviews. + * + * @param WP_REST_Request $request Full details about the request. + * @return array|WP_Error + */ + public function get_items( $request ) { + // Retrieve the list of registered collection query parameters. + $registered = $this->get_collection_params(); + + /* + * This array defines mappings between public API query parameters whose + * values are accepted as-passed, and their internal WP_Query parameter + * name equivalents (some are the same). Only values which are also + * present in $registered will be set. + */ + $parameter_mappings = array( + 'reviewer' => 'author__in', + 'reviewer_email' => 'author_email', + 'reviewer_exclude' => 'author__not_in', + 'exclude' => 'comment__not_in', + 'include' => 'comment__in', + 'offset' => 'offset', + 'order' => 'order', + 'per_page' => 'number', + 'product' => 'post__in', + 'search' => 'search', + 'status' => 'status', + ); + + $prepared_args = array(); + + /* + * For each known parameter which is both registered and present in the request, + * set the parameter's value on the query $prepared_args. + */ + foreach ( $parameter_mappings as $api_param => $wp_param ) { + if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { + $prepared_args[ $wp_param ] = $request[ $api_param ]; + } + } + + // Ensure certain parameter values default to empty strings. + foreach ( array( 'author_email', 'search' ) as $param ) { + if ( ! isset( $prepared_args[ $param ] ) ) { + $prepared_args[ $param ] = ''; + } + } + + if ( isset( $registered['orderby'] ) ) { + $prepared_args['orderby'] = $this->normalize_query_param( $request['orderby'] ); + } + + if ( isset( $prepared_args['status'] ) ) { + $prepared_args['status'] = 'approved' === $prepared_args['status'] ? 'approve' : $prepared_args['status']; + } + + $prepared_args['no_found_rows'] = false; + $prepared_args['date_query'] = array(); + + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $registered['before'], $request['before'] ) ) { + $prepared_args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $registered['after'], $request['after'] ) ) { + $prepared_args['date_query'][0]['after'] = $request['after']; + } + + if ( isset( $registered['page'] ) && empty( $request['offset'] ) ) { + $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); + } + + /** + * Filters arguments, before passing to WP_Comment_Query, when querying reviews via the REST API. + * + * @since 3.5.0 + * @link https://developer.wordpress.org/reference/classes/wp_comment_query/ + * @param array $prepared_args Array of arguments for WP_Comment_Query. + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( 'woocommerce_rest_product_review_query', $prepared_args, $request ); + + // Make sure that returns only reviews. + $prepared_args['type'] = 'review'; + + // Query reviews. + $query = new WP_Comment_Query(); + $query_result = $query->query( $prepared_args ); + $reviews = array(); + + foreach ( $query_result as $review ) { + if ( ! wc_rest_check_product_reviews_permissions( 'read', $review->comment_ID ) ) { + continue; + } + + $data = $this->prepare_item_for_response( $review, $request ); + $reviews[] = $this->prepare_response_for_collection( $data ); + } + + $total_reviews = (int) $query->found_comments; + $max_pages = (int) $query->max_num_pages; + + if ( $total_reviews < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $prepared_args['number'], $prepared_args['offset'] ); + + $query = new WP_Comment_Query(); + $prepared_args['count'] = true; + + $total_reviews = $query->query( $prepared_args ); + $max_pages = ceil( $total_reviews / $request['per_page'] ); + } + + $response = rest_ensure_response( $reviews ); + $response->header( 'X-WP-Total', $total_reviews ); + $response->header( 'X-WP-TotalPages', $max_pages ); + + $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); + + if ( $request['page'] > 1 ) { + $prev_page = $request['page'] - 1; + + if ( $prev_page > $max_pages ) { + $prev_page = $max_pages; + } + + $prev_link = add_query_arg( 'page', $prev_page, $base ); + $response->link_header( 'prev', $prev_link ); + } + + if ( $max_pages > $request['page'] ) { + $next_page = $request['page'] + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Create a single review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + if ( ! empty( $request['id'] ) ) { + return new WP_Error( 'woocommerce_rest_review_exists', __( 'Cannot create existing product review.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $product_id = (int) $request['product_id']; + + if ( 'product' !== get_post_type( $product_id ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_review = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $prepared_review ) ) { + return $prepared_review; + } + + $prepared_review['comment_type'] = 'review'; + + /* + * Do not allow a comment to be created with missing or empty comment_content. See wp_handle_comment_submission(). + */ + if ( empty( $prepared_review['comment_content'] ) ) { + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). + if ( ! isset( $prepared_review['comment_date_gmt'] ) ) { + $prepared_review['comment_date_gmt'] = current_time( 'mysql', true ); + } + + if ( ! empty( $_SERVER['REMOTE_ADDR'] ) && rest_is_ip_address( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) ) { // WPCS: input var ok, sanitization ok. + $prepared_review['comment_author_IP'] = wc_clean( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // WPCS: input var ok. + } else { + $prepared_review['comment_author_IP'] = '127.0.0.1'; + } + + if ( ! empty( $request['author_user_agent'] ) ) { + $prepared_review['comment_agent'] = $request['author_user_agent']; + } elseif ( $request->get_header( 'user_agent' ) ) { + $prepared_review['comment_agent'] = $request->get_header( 'user_agent' ); + } else { + $prepared_review['comment_agent'] = ''; + } + + $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_review ); + if ( is_wp_error( $check_comment_lengths ) ) { + $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $prepared_review['comment_parent'] = 0; + $prepared_review['comment_author_url'] = ''; + $prepared_review['comment_approved'] = wp_allow_comment( $prepared_review, true ); + + if ( is_wp_error( $prepared_review['comment_approved'] ) ) { + $error_code = $prepared_review['comment_approved']->get_error_code(); + $error_message = $prepared_review['comment_approved']->get_error_message(); + + if ( 'comment_duplicate' === $error_code ) { + return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 409 ) ); + } + + if ( 'comment_flood' === $error_code ) { + return new WP_Error( 'woocommerce_rest_' . $error_code, $error_message, array( 'status' => 400 ) ); + } + + return $prepared_review['comment_approved']; + } + + /** + * Filters a review before it is inserted via the REST API. + * + * Allows modification of the review right before it is inserted via wp_insert_comment(). + * Returning a WP_Error value from the filter will shortcircuit insertion and allow + * skipping further processing. + * + * @since 3.5.0 + * @param array|WP_Error $prepared_review The prepared review data for wp_insert_comment(). + * @param WP_REST_Request $request Request used to insert the review. + */ + $prepared_review = apply_filters( 'woocommerce_rest_pre_insert_product_review', $prepared_review, $request ); + if ( is_wp_error( $prepared_review ) ) { + return $prepared_review; + } + + $review_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_review ) ) ); + + if ( ! $review_id ) { + return new WP_Error( 'woocommerce_rest_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + if ( isset( $request['status'] ) ) { + $this->handle_status_param( $request['status'], $review_id ); + } + + update_comment_meta( $review_id, 'rating', ! empty( $request['rating'] ) ? $request['rating'] : '0' ); + + $review = get_comment( $review_id ); + + /** + * Fires after a comment is created or updated via the REST API. + * + * @param WP_Comment $review Inserted or updated comment object. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating a comment, false when updating. + */ + do_action( 'woocommerce_rest_insert_product_review', $review, $request, true ); + + $fields_update = $this->update_additional_fields_for_object( $review, $request ); + if ( is_wp_error( $fields_update ) ) { + return $fields_update; + } + + $context = current_user_can( 'moderate_comments' ) ? 'edit' : 'view'; + $request->set_param( 'context', $context ); + + $response = $this->prepare_item_for_response( $review, $request ); + $response = rest_ensure_response( $response ); + + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $review_id ) ) ); + + return $response; + } + + /** + * Get a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $review = $this->get_review( $request['id'] ); + if ( is_wp_error( $review ) ) { + return $review; + } + + $data = $this->prepare_item_for_response( $review, $request ); + $response = rest_ensure_response( $data ); + + return $response; + } + + /** + * Updates a review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. + */ + public function update_item( $request ) { + $review = $this->get_review( $request['id'] ); + if ( is_wp_error( $review ) ) { + return $review; + } + + $id = (int) $review->comment_ID; + + if ( isset( $request['type'] ) && 'review' !== get_comment_type( $id ) ) { + return new WP_Error( 'woocommerce_rest_review_invalid_type', __( 'Sorry, you are not allowed to change the comment type.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $prepared_args = $this->prepare_item_for_database( $request ); + if ( is_wp_error( $prepared_args ) ) { + return $prepared_args; + } + + if ( ! empty( $prepared_args['comment_post_ID'] ) ) { + if ( 'product' !== get_post_type( (int) $prepared_args['comment_post_ID'] ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + } + + if ( empty( $prepared_args ) && isset( $request['status'] ) ) { + // Only the comment status is being changed. + $change = $this->handle_status_param( $request['status'], $id ); + + if ( ! $change ) { + return new WP_Error( 'woocommerce_rest_review_failed_edit', __( 'Updating review status failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + } elseif ( ! empty( $prepared_args ) ) { + if ( is_wp_error( $prepared_args ) ) { + return $prepared_args; + } + + if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { + return new WP_Error( 'woocommerce_rest_review_content_invalid', __( 'Invalid review content.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $prepared_args['comment_ID'] = $id; + + $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); + if ( is_wp_error( $check_comment_lengths ) ) { + $error_code = str_replace( array( 'comment_author', 'comment_content' ), array( 'reviewer', 'review_content' ), $check_comment_lengths->get_error_code() ); + return new WP_Error( 'woocommerce_rest_' . $error_code, __( 'Product review field exceeds maximum length allowed.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $updated = wp_update_comment( wp_slash( (array) $prepared_args ) ); + + if ( false === $updated ) { + return new WP_Error( 'woocommerce_rest_comment_failed_edit', __( 'Updating review failed.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + if ( isset( $request['status'] ) ) { + $this->handle_status_param( $request['status'], $id ); + } + } + + if ( ! empty( $request['rating'] ) ) { + update_comment_meta( $id, 'rating', $request['rating'] ); + } + + $review = get_comment( $id ); + + /** This action is documented in includes/api/class-wc-rest-product-reviews-controller.php */ + do_action( 'woocommerce_rest_insert_product_review', $review, $request, false ); + + $fields_update = $this->update_additional_fields_for_object( $review, $request ); + + if ( is_wp_error( $fields_update ) ) { + return $fields_update; + } + + $request->set_param( 'context', 'edit' ); + + $response = $this->prepare_item_for_response( $review, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Deletes a review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response Response object on success, or error object on failure. + */ + public function delete_item( $request ) { + $review = $this->get_review( $request['id'] ); + if ( is_wp_error( $review ) ) { + return $review; + } + + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + /** + * Filters whether a review can be trashed. + * + * Return false to disable trash support for the post. + * + * @since 3.5.0 + * @param bool $supports_trash Whether the post type support trashing. + * @param WP_Comment $review The review object being considered for trashing support. + */ + $supports_trash = apply_filters( 'woocommerce_rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $review ); + + $request->set_param( 'context', 'edit' ); + + if ( $force ) { + $previous = $this->prepare_item_for_response( $review, $request ); + $result = wp_delete_comment( $review->comment_ID, true ); + $response = new WP_REST_Response(); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); + } else { + // If this type doesn't support trashing, error out. + if ( ! $supports_trash ) { + /* translators: %s: force=true */ + return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( "The object does not support trashing. Set '%s' to delete.", 'woocommerce' ), 'force=true' ), array( 'status' => 501 ) ); + } + + if ( 'trash' === $review->comment_approved ) { + return new WP_Error( 'woocommerce_rest_already_trashed', __( 'The object has already been trashed.', 'woocommerce' ), array( 'status' => 410 ) ); + } + + $result = wp_trash_comment( $review->comment_ID ); + $review = get_comment( $review->comment_ID ); + $response = $this->prepare_item_for_response( $review, $request ); + } + + if ( ! $result ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The object cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a review is deleted via the REST API. + * + * @param WP_Comment $review The deleted review data. + * @param WP_REST_Response $response The response returned from the API. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'woocommerce_rest_delete_review', $review, $response, $request ); + + return $response; + } + + /** + * Prepare a single product review output for response. + * + * @param WP_Comment $review Product review object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $review, $request ) { + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $fields = $this->get_fields_for_response( $request ); + $data = array(); + + if ( in_array( 'id', $fields, true ) ) { + $data['id'] = (int) $review->comment_ID; + } + if ( in_array( 'date_created', $fields, true ) ) { + $data['date_created'] = wc_rest_prepare_date_response( $review->comment_date ); + } + if ( in_array( 'date_created_gmt', $fields, true ) ) { + $data['date_created_gmt'] = wc_rest_prepare_date_response( $review->comment_date_gmt ); + } + if ( in_array( 'product_id', $fields, true ) ) { + $data['product_id'] = (int) $review->comment_post_ID; + } + if ( in_array( 'status', $fields, true ) ) { + $data['status'] = $this->prepare_status_response( (string) $review->comment_approved ); + } + if ( in_array( 'reviewer', $fields, true ) ) { + $data['reviewer'] = $review->comment_author; + } + if ( in_array( 'reviewer_email', $fields, true ) ) { + $data['reviewer_email'] = $review->comment_author_email; + } + if ( in_array( 'review', $fields, true ) ) { + $data['review'] = 'view' === $context ? wpautop( $review->comment_content ) : $review->comment_content; + } + if ( in_array( 'rating', $fields, true ) ) { + $data['rating'] = (int) get_comment_meta( $review->comment_ID, 'rating', true ); + } + if ( in_array( 'verified', $fields, true ) ) { + $data['verified'] = wc_review_is_from_verified_owner( $review->comment_ID ); + } + if ( in_array( 'reviewer_avatar_urls', $fields, true ) ) { + $data['reviewer_avatar_urls'] = rest_get_avatar_urls( $review->comment_author_email ); + } + + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $review ) ); + + /** + * Filter product reviews object returned from the REST API. + * + * @param WP_REST_Response $response The response object. + * @param WP_Comment $review Product review object used to create response. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); + } + + /** + * Prepare a single product review to be inserted into the database. + * + * @param WP_REST_Request $request Request object. + * @return array|WP_Error $prepared_review + */ + protected function prepare_item_for_database( $request ) { + if ( isset( $request['id'] ) ) { + $prepared_review['comment_ID'] = (int) $request['id']; + } + + if ( isset( $request['review'] ) ) { + $prepared_review['comment_content'] = $request['review']; + } + + if ( isset( $request['product_id'] ) ) { + $prepared_review['comment_post_ID'] = (int) $request['product_id']; + } + + if ( isset( $request['reviewer'] ) ) { + $prepared_review['comment_author'] = $request['reviewer']; + } + + if ( isset( $request['reviewer_email'] ) ) { + $prepared_review['comment_author_email'] = $request['reviewer_email']; + } + + if ( ! empty( $request['date_created'] ) ) { + $date_data = rest_get_date_with_gmt( $request['date_created'] ); + + if ( ! empty( $date_data ) ) { + list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; + } + } elseif ( ! empty( $request['date_created_gmt'] ) ) { + $date_data = rest_get_date_with_gmt( $request['date_created_gmt'], true ); + + if ( ! empty( $date_data ) ) { + list( $prepared_review['comment_date'], $prepared_review['comment_date_gmt'] ) = $date_data; + } + } + + /** + * Filters a review after it is prepared for the database. + * + * Allows modification of the review right after it is prepared for the database. + * + * @since 3.5.0 + * @param array $prepared_review The prepared review data for `wp_insert_comment`. + * @param WP_REST_Request $request The current request. + */ + return apply_filters( 'woocommerce_rest_preprocess_product_review', $prepared_review, $request ); + } + + /** + * Prepare links for the request. + * + * @param WP_Comment $review Product review object. + * @return array Links for the given product review. + */ + protected function prepare_links( $review ) { + $links = array( + 'self' => array( + 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $review->comment_ID ) ), + ), + 'collection' => array( + 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ), + ), + ); + + if ( 0 !== (int) $review->comment_post_ID ) { + $links['up'] = array( + 'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $review->comment_post_ID ) ), + ); + } + + if ( 0 !== (int) $review->user_id ) { + $links['reviewer'] = array( + 'href' => rest_url( 'wp/v2/users/' . $review->user_id ), + 'embeddable' => true, + ); + } + + return $links; + } + + /** + * Get the Product Review's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'product_review', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'product_id' => array( + 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Status of the review.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'approved', + 'enum' => array( 'approved', 'hold', 'spam', 'unspam', 'trash', 'untrash' ), + 'context' => array( 'view', 'edit' ), + ), + 'reviewer' => array( + 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'reviewer_email' => array( + 'description' => __( 'Reviewer email.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => array( 'view', 'edit' ), + ), + 'review' => array( + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'arg_options' => array( + 'sanitize_callback' => 'wp_filter_post_kses', + ), + ), + 'rating' => array( + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'verified' => array( + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + if ( get_option( 'show_avatars' ) ) { + $avatar_properties = array(); + $avatar_sizes = rest_get_avatar_sizes(); + + foreach ( $avatar_sizes as $size ) { + $avatar_properties[ $size ] = array( + /* translators: %d: avatar image size in pixels */ + 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce' ), $size ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'embed', 'view', 'edit' ), + ); + } + $schema['properties']['reviewer_avatar_urls'] = array( + 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $avatar_properties, + ); + } + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['context']['default'] = 'view'; + + $params['after'] = array( + 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + ); + $params['before'] = array( + 'description' => __( 'Limit response to reviews published before a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + ); + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + ); + $params['include'] = array( + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + ); + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + ); + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( + 'asc', + 'desc', + ), + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date_gmt', + 'enum' => array( + 'date', + 'date_gmt', + 'id', + 'include', + 'product', + ), + ); + $params['reviewer'] = array( + 'description' => __( 'Limit result set to reviews assigned to specific user IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['reviewer_exclude'] = array( + 'description' => __( 'Ensure result set excludes reviews assigned to specific user IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['reviewer_email'] = array( + 'default' => null, + 'description' => __( 'Limit result set to that from a specific author email.', 'woocommerce' ), + 'format' => 'email', + 'type' => 'string', + ); + $params['product'] = array( + 'default' => array(), + 'description' => __( 'Limit result set to reviews assigned to specific product IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['status'] = array( + 'default' => 'approved', + 'description' => __( 'Limit result set to reviews assigned a specific status.', 'woocommerce' ), + 'sanitize_callback' => 'sanitize_key', + 'type' => 'string', + 'enum' => array( + 'all', + 'hold', + 'approved', + 'spam', + 'trash', + ), + ); + + /** + * Filter collection parameters for the reviews controller. + * + * This filter registers the collection parameter, but does not map the + * collection parameter to an internal WP_Comment_Query parameter. Use the + * `wc_rest_review_query` filter to set WP_Comment_Query parameters. + * + * @since 3.5.0 + * @param array $params JSON Schema-formatted collection parameters. + */ + return apply_filters( 'woocommerce_rest_product_review_collection_params', $params ); + } + + /** + * Get the reivew, if the ID is valid. + * + * @since 3.5.0 + * @param int $id Supplied ID. + * @return WP_Comment|WP_Error Comment object if ID is valid, WP_Error otherwise. + */ + protected function get_review( $id ) { + $id = (int) $id; + $error = new WP_Error( 'woocommerce_rest_review_invalid_id', __( 'Invalid review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + + if ( 0 >= $id ) { + return $error; + } + + $review = get_comment( $id ); + if ( empty( $review ) ) { + return $error; + } + + if ( ! empty( $review->comment_post_ID ) ) { + $post = get_post( (int) $review->comment_post_ID ); + + if ( 'product' !== get_post_type( (int) $review->comment_post_ID ) ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + } + + return $review; + } + + /** + * Prepends internal property prefix to query parameters to match our response fields. + * + * @since 3.5.0 + * @param string $query_param Query parameter. + * @return string + */ + protected function normalize_query_param( $query_param ) { + $prefix = 'comment_'; + + switch ( $query_param ) { + case 'id': + $normalized = $prefix . 'ID'; + break; + case 'product': + $normalized = $prefix . 'post_ID'; + break; + case 'include': + $normalized = 'comment__in'; + break; + default: + $normalized = $prefix . $query_param; + break; + } + + return $normalized; + } + + /** + * Checks comment_approved to set comment status for single comment output. + * + * @since 3.5.0 + * @param string|int $comment_approved comment status. + * @return string Comment status. + */ + protected function prepare_status_response( $comment_approved ) { + switch ( $comment_approved ) { + case 'hold': + case '0': + $status = 'hold'; + break; + case 'approve': + case '1': + $status = 'approved'; + break; + case 'spam': + case 'trash': + default: + $status = $comment_approved; + break; + } + + return $status; + } + + /** + * Sets the comment_status of a given review object when creating or updating a review. + * + * @since 3.5.0 + * @param string|int $new_status New review status. + * @param int $id Review ID. + * @return bool Whether the status was changed. + */ + protected function handle_status_param( $new_status, $id ) { + $old_status = wp_get_comment_status( $id ); + + if ( $new_status === $old_status ) { + return false; + } + + switch ( $new_status ) { + case 'approved': + case 'approve': + case '1': + $changed = wp_set_comment_status( $id, 'approve' ); + break; + case 'hold': + case '0': + $changed = wp_set_comment_status( $id, 'hold' ); + break; + case 'spam': + $changed = wp_spam_comment( $id ); + break; + case 'unspam': + $changed = wp_unspam_comment( $id ); + break; + case 'trash': + $changed = wp_trash_comment( $id ); + break; + case 'untrash': + $changed = wp_untrash_comment( $id ); + break; + default: + $changed = false; + break; + } + + return $changed; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php new file mode 100644 index 0000000..5d3a31b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php @@ -0,0 +1,27 @@ +/variations endpoints. + * + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API variations controller class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Product_Variations_V2_Controller + */ +class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; + + /** + * Prepare a single variation output for response. + * + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_object_for_response( $object, $request ) { + $data = array( + 'id' => $object->get_id(), + 'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ), + 'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ), + 'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ), + 'description' => wc_format_content( $object->get_description() ), + 'permalink' => $object->get_permalink(), + 'sku' => $object->get_sku(), + 'price' => $object->get_price(), + 'regular_price' => $object->get_regular_price(), + 'sale_price' => $object->get_sale_price(), + 'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ), + 'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ), + 'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ), + 'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ), + 'on_sale' => $object->is_on_sale(), + 'status' => $object->get_status(), + 'purchasable' => $object->is_purchasable(), + 'virtual' => $object->is_virtual(), + 'downloadable' => $object->is_downloadable(), + 'downloads' => $this->get_downloads( $object ), + 'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1, + 'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1, + 'tax_status' => $object->get_tax_status(), + 'tax_class' => $object->get_tax_class(), + 'manage_stock' => $object->managing_stock(), + 'stock_quantity' => $object->get_stock_quantity(), + 'stock_status' => $object->get_stock_status(), + 'backorders' => $object->get_backorders(), + 'backorders_allowed' => $object->backorders_allowed(), + 'backordered' => $object->is_on_backorder(), + 'weight' => $object->get_weight(), + 'dimensions' => array( + 'length' => $object->get_length(), + 'width' => $object->get_width(), + 'height' => $object->get_height(), + ), + 'shipping_class' => $object->get_shipping_class(), + 'shipping_class_id' => $object->get_shipping_class_id(), + 'image' => $this->get_image( $object ), + 'attributes' => $this->get_attributes( $object ), + 'menu_order' => $object->get_menu_order(), + 'meta_data' => $object->get_meta_data(), + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $object, $request ) ); + + /** + * Filter the data for a response. + * + * The dynamic portion of the hook name, $this->post_type, + * refers to object type being prepared for the response. + * + * @param WP_REST_Response $response The response object. + * @param WC_Data $object Object data. + * @param WP_REST_Request $request Request object. + */ + return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); + } + + /** + * Prepare a single variation for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + if ( isset( $request['id'] ) ) { + $variation = wc_get_product( absint( $request['id'] ) ); + } else { + $variation = new WC_Product_Variation(); + } + + $variation->set_parent_id( absint( $request['product_id'] ) ); + + // Status. + if ( isset( $request['status'] ) ) { + $variation->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // SKU. + if ( isset( $request['sku'] ) ) { + $variation->set_sku( wc_clean( $request['sku'] ) ); + } + + // Thumbnail. + if ( isset( $request['image'] ) ) { + if ( is_array( $request['image'] ) ) { + $variation = $this->set_variation_image( $variation, $request['image'] ); + } else { + $variation->set_image_id( '' ); + } + } + + // Virtual variation. + if ( isset( $request['virtual'] ) ) { + $variation->set_virtual( $request['virtual'] ); + } + + // Downloadable variation. + if ( isset( $request['downloadable'] ) ) { + $variation->set_downloadable( $request['downloadable'] ); + } + + // Downloads. + if ( $variation->get_downloadable() ) { + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $variation = $this->save_downloadable_files( $variation, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $variation->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $variation->set_download_expiry( $request['download_expiry'] ); + } + } + + // Shipping data. + $variation = $this->save_product_shipping_data( $variation, $request ); + + // Stock handling. + if ( isset( $request['manage_stock'] ) ) { + $variation->set_manage_stock( $request['manage_stock'] ); + } + + if ( isset( $request['stock_status'] ) ) { + $variation->set_stock_status( $request['stock_status'] ); + } + + if ( isset( $request['backorders'] ) ) { + $variation->set_backorders( $request['backorders'] ); + } + + if ( $variation->get_manage_stock() ) { + if ( isset( $request['stock_quantity'] ) ) { + $variation->set_stock_quantity( $request['stock_quantity'] ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $variation->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $variation->set_stock_quantity( $stock_quantity ); + } + } else { + $variation->set_backorders( 'no' ); + $variation->set_stock_quantity( '' ); + } + + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $variation->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $variation->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + + // Tax class. + if ( isset( $request['tax_class'] ) ) { + $variation->set_tax_class( $request['tax_class'] ); + } + + // Description. + if ( isset( $request['description'] ) ) { + $variation->set_description( wp_kses_post( $request['description'] ) ); + } + + // Update taxonomies. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + $parent = wc_get_product( $variation->get_parent_id() ); + + if ( ! $parent ) { + return new WP_Error( + // Translators: %d parent ID. + "woocommerce_rest_{$this->post_type}_invalid_parent", + __( 'Cannot set attributes due to invalid parent product.', 'woocommerce' ), + array( 'status' => 404 ) + ); + } + + $parent_attributes = $parent->get_attributes(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = sanitize_title( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) { + continue; + } + + $attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() ); + $attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : ''; + + if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) { + // If dealing with a taxonomy, we need to get the slug from the name posted to the API. + $term = get_term_by( 'name', $attribute_value, $attribute_name ); + + if ( $term && ! is_wp_error( $term ) ) { + $attribute_value = $term->slug; + } else { + $attribute_value = sanitize_title( $attribute_value ); + } + } + + $attributes[ $attribute_key ] = $attribute_value; + } + + $variation->set_attributes( $attributes ); + } + + // Menu order. + if ( $request['menu_order'] ) { + $variation->set_menu_order( $request['menu_order'] ); + } + + // Meta data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $variation Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating ); + } + + /** + * Get the image for a product variation. + * + * @param WC_Product_Variation $variation Variation data. + * @return array + */ + protected function get_image( $variation ) { + if ( ! $variation->get_image_id() ) { + return; + } + + $attachment_id = $variation->get_image_id(); + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + return; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + return; + } + + if ( ! isset( $image ) ) { + return array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + } + + /** + * Set variation image. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product_Variation $variation Variation instance. + * @param array $image Image data. + * @return WC_Product_Variation + */ + protected function set_variation_image( $variation, $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id ) { + if ( isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $variation->get_id(), array( $image ) ) ) { + throw new WC_REST_Exception( 'woocommerce_variation_image_upload_error', $upload->get_error_message(), 400 ); + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $variation->get_id() ); + } else { + $variation->set_image_id( '' ); + return $variation; + } + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: attachment ID */ + throw new WC_REST_Exception( 'woocommerce_variation_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $variation->set_image_id( $attachment_id ); + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + + return $variation; + } + + /** + * Get the Variation's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the variation was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the variation was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Variation description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Variation URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current variation price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Variation regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Variation sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'on_sale' => array( + 'description' => __( 'Shows if the variation is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'status' => array( + 'description' => __( 'Variation status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_keys( get_post_statuses() ), + 'context' => array( 'view', 'edit' ), + ), + 'purchasable' => array( + 'description' => __( 'Shows if the variation can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the variation is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the variation is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at variation level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the variation is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Variation weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Variation dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Variation height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'image' => array( + 'description' => __( 'Variation image data.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Prepare objects query. + * + * @since 3.0.0 + * @param WP_REST_Request $request Full details about the request. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); + + // Set post_status. + $args['post_status'] = $request['status']; + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) + ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) + ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. + } + + // Filter product based on stock_status. + if ( ! empty( $request['stock_status'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, + array( + 'key' => '_stock_status', + 'value' => $request['stock_status'], + ) + ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + $args['post_parent'] = $request['product_id']; + + return $args; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + unset( + $params['in_stock'], + $params['type'], + $params['featured'], + $params['category'], + $params['tag'], + $params['shipping_class'], + $params['attribute'], + $params['attribute_term'] + ); + + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php new file mode 100644 index 0000000..d0db725 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php @@ -0,0 +1,1341 @@ +get_image_id() ) { + $attachment_ids[] = $product->get_image_id(); + } + + // Add gallery images. + $attachment_ids = array_merge( $attachment_ids, $product->get_gallery_image_ids() ); + + // Build image data. + foreach ( $attachment_ids as $attachment_id ) { + $attachment_post = get_post( $attachment_id ); + if ( is_null( $attachment_post ) ) { + continue; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + if ( ! is_array( $attachment ) ) { + continue; + } + + $images[] = array( + 'id' => (int) $attachment_id, + 'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ), + 'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ), + 'date_modified' => wc_rest_prepare_date_response( $attachment_post->post_modified, false ), + 'date_modified_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_modified_gmt ) ), + 'src' => current( $attachment ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ); + } + + return $images; + } + + /** + * Make extra product orderby features supported by WooCommerce available to the WC API. + * This includes 'price', 'popularity', and 'rating'. + * + * @param WP_REST_Request $request Request data. + * @return array + */ + protected function prepare_objects_query( $request ) { + $args = WC_REST_CRUD_Controller::prepare_objects_query( $request ); + + // Set post_status. + $args['post_status'] = $request['status']; + + // Taxonomy query to filter products by type, category, + // tag, shipping class, and attribute. + $tax_query = array(); + + // Map between taxonomy name and arg's key. + $taxonomies = array( + 'product_cat' => 'category', + 'product_tag' => 'tag', + 'product_shipping_class' => 'shipping_class', + ); + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) ) { + $tax_query[] = array( + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + ); + } + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + $tax_query[] = array( + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ); + } + + // Filter by attribute and term. + if ( ! empty( $request['attribute'] ) && ! empty( $request['attribute_term'] ) ) { + if ( in_array( $request['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $tax_query[] = array( + 'taxonomy' => $request['attribute'], + 'field' => 'term_id', + 'terms' => $request['attribute_term'], + ); + } + } + + // Build tax_query if taxonomies are set. + if ( ! empty( $tax_query ) ) { + if ( ! empty( $args['tax_query'] ) ) { + $args['tax_query'] = array_merge( $tax_query, $args['tax_query'] ); // WPCS: slow query ok. + } else { + $args['tax_query'] = $tax_query; // WPCS: slow query ok. + } + } + + // Filter featured. + if ( is_bool( $request['featured'] ) ) { + $args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => 'featured', + 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', + ); + } + + // Filter by sku. + if ( ! empty( $request['sku'] ) ) { + $skus = explode( ',', $request['sku'] ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $request['sku']; + } + + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, array( + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ) + ); + } + + // Filter by tax class. + if ( ! empty( $request['tax_class'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, array( + 'key' => '_tax_class', + 'value' => 'standard' !== $request['tax_class'] ? $request['tax_class'] : '', + ) + ); + } + + // Price filter. + if ( ! empty( $request['min_price'] ) || ! empty( $request['max_price'] ) ) { + $args['meta_query'] = $this->add_meta_query( $args, wc_get_min_max_price_meta_query( $request ) ); // WPCS: slow query ok. + } + + // Filter product by stock_status. + if ( ! empty( $request['stock_status'] ) ) { + $args['meta_query'] = $this->add_meta_query( // WPCS: slow query ok. + $args, array( + 'key' => '_stock_status', + 'value' => $request['stock_status'], + ) + ); + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + // Force the post_type argument, since it's not a user input variable. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = array( 'product', 'product_variation' ); + } else { + $args['post_type'] = $this->post_type; + } + + $orderby = $request->get_param( 'orderby' ); + $order = $request->get_param( 'order' ); + + $ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order ); + $args['orderby'] = $ordering_args['orderby']; + $args['order'] = $ordering_args['order']; + if ( $ordering_args['meta_key'] ) { + $args['meta_key'] = $ordering_args['meta_key']; // WPCS: slow query ok. + } + + return $args; + } + + /** + * Set product images. + * + * @throws WC_REST_Exception REST API exceptions. + * @param WC_Product $product Product instance. + * @param array $images Images data. + * @return WC_Product + */ + protected function set_product_images( $product, $images ) { + $images = is_array( $images ) ? array_filter( $images ) : array(); + + if ( ! empty( $images ) ) { + $gallery = array(); + + foreach ( $images as $index => $image ) { + $attachment_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; + + if ( 0 === $attachment_id && isset( $image['src'] ) ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $image['src'] ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images ) ) { + throw new WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + continue; + } + } + + $attachment_id = wc_rest_set_uploaded_image_as_attachment( $upload, $product->get_id() ); + } + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + /* translators: %s: image ID */ + throw new WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $attachment_id ), 400 ); + } + + $featured_image = $product->get_image_id(); + + if ( 0 === $index ) { + $product->set_image_id( $attachment_id ); + } else { + $gallery[] = $attachment_id; + } + + // Set the image alt if present. + if ( ! empty( $image['alt'] ) ) { + update_post_meta( $attachment_id, '_wp_attachment_image_alt', wc_clean( $image['alt'] ) ); + } + + // Set the image name if present. + if ( ! empty( $image['name'] ) ) { + wp_update_post( + array( + 'ID' => $attachment_id, + 'post_title' => $image['name'], + ) + ); + } + } + + $product->set_gallery_image_ids( $gallery ); + } else { + $product->set_image_id( '' ); + $product->set_gallery_image_ids( array() ); + } + + return $product; + } + + /** + * Prepare a single product for create or update. + * + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + * @return WP_Error|WC_Data + */ + protected function prepare_object_for_database( $request, $creating = false ) { + $id = isset( $request['id'] ) ? absint( $request['id'] ) : 0; + + // Type is the most important part here because we need to be using the correct class and methods. + if ( isset( $request['type'] ) ) { + $classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] ); + + if ( ! class_exists( $classname ) ) { + $classname = 'WC_Product_Simple'; + } + + $product = new $classname( $id ); + } elseif ( isset( $request['id'] ) ) { + $product = wc_get_product( $id ); + } else { + $product = new WC_Product_Simple(); + } + + if ( 'variation' === $product->get_type() ) { + return new WP_Error( + "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ), array( + 'status' => 404, + ) + ); + } + + // Post title. + if ( isset( $request['name'] ) ) { + $product->set_name( wp_filter_post_kses( $request['name'] ) ); + } + + // Post content. + if ( isset( $request['description'] ) ) { + $product->set_description( wp_filter_post_kses( $request['description'] ) ); + } + + // Post excerpt. + if ( isset( $request['short_description'] ) ) { + $product->set_short_description( wp_filter_post_kses( $request['short_description'] ) ); + } + + // Post status. + if ( isset( $request['status'] ) ) { + $product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' ); + } + + // Post slug. + if ( isset( $request['slug'] ) ) { + $product->set_slug( $request['slug'] ); + } + + // Menu order. + if ( isset( $request['menu_order'] ) ) { + $product->set_menu_order( $request['menu_order'] ); + } + + // Comment status. + if ( isset( $request['reviews_allowed'] ) ) { + $product->set_reviews_allowed( $request['reviews_allowed'] ); + } + + // Virtual. + if ( isset( $request['virtual'] ) ) { + $product->set_virtual( $request['virtual'] ); + } + + // Tax status. + if ( isset( $request['tax_status'] ) ) { + $product->set_tax_status( $request['tax_status'] ); + } + + // Tax Class. + if ( isset( $request['tax_class'] ) ) { + $product->set_tax_class( $request['tax_class'] ); + } + + // Catalog Visibility. + if ( isset( $request['catalog_visibility'] ) ) { + $product->set_catalog_visibility( $request['catalog_visibility'] ); + } + + // Purchase Note. + if ( isset( $request['purchase_note'] ) ) { + $product->set_purchase_note( wp_kses_post( wp_unslash( $request['purchase_note'] ) ) ); + } + + // Featured Product. + if ( isset( $request['featured'] ) ) { + $product->set_featured( $request['featured'] ); + } + + // Shipping data. + $product = $this->save_product_shipping_data( $product, $request ); + + // SKU. + if ( isset( $request['sku'] ) ) { + $product->set_sku( wc_clean( $request['sku'] ) ); + } + + // Attributes. + if ( isset( $request['attributes'] ) ) { + $attributes = array(); + + foreach ( $request['attributes'] as $attribute ) { + $attribute_id = 0; + $attribute_name = ''; + + // Check ID for global attributes or name for product attributes. + if ( ! empty( $attribute['id'] ) ) { + $attribute_id = absint( $attribute['id'] ); + $attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id ); + } elseif ( ! empty( $attribute['name'] ) ) { + $attribute_name = wc_clean( $attribute['name'] ); + } + + if ( ! $attribute_id && ! $attribute_name ) { + continue; + } + + if ( $attribute_id ) { + + if ( isset( $attribute['options'] ) ) { + $options = $attribute['options']; + + if ( ! is_array( $attribute['options'] ) ) { + // Text based attributes - Posted values are term names. + $options = explode( WC_DELIMITER, $options ); + } + + $values = array_map( 'wc_sanitize_term_text_based', $options ); + $values = array_filter( $values, 'strlen' ); + } else { + $values = array(); + } + + if ( ! empty( $values ) ) { + // Add attribute to array, but don't set values. + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_id( $attribute_id ); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } elseif ( isset( $attribute['options'] ) ) { + // Custom attribute - Add attribute to array and set the values. + if ( is_array( $attribute['options'] ) ) { + $values = $attribute['options']; + } else { + $values = explode( WC_DELIMITER, $attribute['options'] ); + } + $attribute_object = new WC_Product_Attribute(); + $attribute_object->set_name( $attribute_name ); + $attribute_object->set_options( $values ); + $attribute_object->set_position( isset( $attribute['position'] ) ? (string) absint( $attribute['position'] ) : '0' ); + $attribute_object->set_visible( ( isset( $attribute['visible'] ) && $attribute['visible'] ) ? 1 : 0 ); + $attribute_object->set_variation( ( isset( $attribute['variation'] ) && $attribute['variation'] ) ? 1 : 0 ); + $attributes[] = $attribute_object; + } + } + $product->set_attributes( $attributes ); + } + + // Sales and prices. + if ( in_array( $product->get_type(), array( 'variable', 'grouped' ), true ) ) { + $product->set_regular_price( '' ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->set_price( '' ); + } else { + // Regular Price. + if ( isset( $request['regular_price'] ) ) { + $product->set_regular_price( $request['regular_price'] ); + } + + // Sale Price. + if ( isset( $request['sale_price'] ) ) { + $product->set_sale_price( $request['sale_price'] ); + } + + if ( isset( $request['date_on_sale_from'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from'] ); + } + + if ( isset( $request['date_on_sale_from_gmt'] ) ) { + $product->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null ); + } + + if ( isset( $request['date_on_sale_to'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to'] ); + } + + if ( isset( $request['date_on_sale_to_gmt'] ) ) { + $product->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null ); + } + } + + // Product parent ID. + if ( isset( $request['parent_id'] ) ) { + $product->set_parent_id( $request['parent_id'] ); + } + + // Sold individually. + if ( isset( $request['sold_individually'] ) ) { + $product->set_sold_individually( $request['sold_individually'] ); + } + + // Stock status; stock_status has priority over in_stock. + if ( isset( $request['stock_status'] ) ) { + $stock_status = $request['stock_status']; + } else { + $stock_status = $product->get_stock_status(); + } + + // Stock data. + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { + // Manage stock. + if ( isset( $request['manage_stock'] ) ) { + $product->set_manage_stock( $request['manage_stock'] ); + } + + // Backorders. + if ( isset( $request['backorders'] ) ) { + $product->set_backorders( $request['backorders'] ); + } + + if ( $product->is_type( 'grouped' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } elseif ( $product->is_type( 'external' ) ) { + $product->set_manage_stock( 'no' ); + $product->set_backorders( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( 'instock' ); + } elseif ( $product->get_manage_stock() ) { + // Stock status is always determined by children so sync later. + if ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Stock quantity. + if ( isset( $request['stock_quantity'] ) ) { + $product->set_stock_quantity( wc_stock_amount( $request['stock_quantity'] ) ); + } elseif ( isset( $request['inventory_delta'] ) ) { + $stock_quantity = wc_stock_amount( $product->get_stock_quantity() ); + $stock_quantity += wc_stock_amount( $request['inventory_delta'] ); + $product->set_stock_quantity( wc_stock_amount( $stock_quantity ) ); + } + } else { + // Don't manage stock. + $product->set_manage_stock( 'no' ); + $product->set_stock_quantity( '' ); + $product->set_stock_status( $stock_status ); + } + } elseif ( ! $product->is_type( 'variable' ) ) { + $product->set_stock_status( $stock_status ); + } + + // Upsells. + if ( isset( $request['upsell_ids'] ) ) { + $upsells = array(); + $ids = $request['upsell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $upsells[] = $id; + } + } + } + + $product->set_upsell_ids( $upsells ); + } + + // Cross sells. + if ( isset( $request['cross_sell_ids'] ) ) { + $crosssells = array(); + $ids = $request['cross_sell_ids']; + + if ( ! empty( $ids ) ) { + foreach ( $ids as $id ) { + if ( $id && $id > 0 ) { + $crosssells[] = $id; + } + } + } + + $product->set_cross_sell_ids( $crosssells ); + } + + // Product categories. + if ( isset( $request['categories'] ) && is_array( $request['categories'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['categories'] ); + } + + // Product tags. + if ( isset( $request['tags'] ) && is_array( $request['tags'] ) ) { + $product = $this->save_taxonomy_terms( $product, $request['tags'], 'tag' ); + } + + // Downloadable. + if ( isset( $request['downloadable'] ) ) { + $product->set_downloadable( $request['downloadable'] ); + } + + // Downloadable options. + if ( $product->get_downloadable() ) { + + // Downloadable files. + if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) { + $product = $this->save_downloadable_files( $product, $request['downloads'] ); + } + + // Download limit. + if ( isset( $request['download_limit'] ) ) { + $product->set_download_limit( $request['download_limit'] ); + } + + // Download expiry. + if ( isset( $request['download_expiry'] ) ) { + $product->set_download_expiry( $request['download_expiry'] ); + } + } + + // Product url and button text for external products. + if ( $product->is_type( 'external' ) ) { + if ( isset( $request['external_url'] ) ) { + $product->set_product_url( $request['external_url'] ); + } + + if ( isset( $request['button_text'] ) ) { + $product->set_button_text( $request['button_text'] ); + } + } + + // Save default attributes for variable products. + if ( $product->is_type( 'variable' ) ) { + $product = $this->save_default_attributes( $product, $request ); + } + + // Set children for a grouped product. + if ( $product->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) { + $product->set_children( $request['grouped_products'] ); + } + + // Check for featured/gallery images, upload it and set it. + if ( isset( $request['images'] ) ) { + $product = $this->set_product_images( $product, $request['images'] ); + } + + // Allow set meta_data. + if ( is_array( $request['meta_data'] ) ) { + foreach ( $request['meta_data'] as $meta ) { + $product->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); + } + } + + if ( ! empty( $request['date_created'] ) ) { + $date = rest_parse_date( $request['date_created'] ); + + if ( $date ) { + $product->set_date_created( $date ); + } + } + + if ( ! empty( $request['date_created_gmt'] ) ) { + $date = rest_parse_date( $request['date_created_gmt'], true ); + + if ( $date ) { + $product->set_date_created( $date ); + } + } + + /** + * Filters an object before it is inserted via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, + * refers to the object type slug. + * + * @param WC_Data $product Object object. + * @param WP_REST_Request $request Request object. + * @param bool $creating If is creating a new object. + */ + return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating ); + } + + /** + * Get the Product's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $weight_unit = get_option( 'woocommerce_weight_unit' ); + $dimension_unit = get_option( 'woocommerce_dimension_unit' ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => $this->post_type, + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'slug' => array( + 'description' => __( 'Product slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'permalink' => array( + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "The date the product was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the product was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_modified' => array( + 'description' => __( "The date the product was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the product was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'simple', + 'enum' => array_keys( wc_get_product_types() ), + 'context' => array( 'view', 'edit' ), + ), + 'status' => array( + 'description' => __( 'Product status (post status).', 'woocommerce' ), + 'type' => 'string', + 'default' => 'publish', + 'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ), + 'context' => array( 'view', 'edit' ), + ), + 'featured' => array( + 'description' => __( 'Featured product.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'catalog_visibility' => array( + 'description' => __( 'Catalog visibility.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'visible', + 'enum' => array( 'visible', 'catalog', 'search', 'hidden' ), + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'Product description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'short_description' => array( + 'description' => __( 'Product short description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sku' => array( + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'price' => array( + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'regular_price' => array( + 'description' => __( 'Product regular price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sale_price' => array( + 'description' => __( 'Product sale price.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from' => array( + 'description' => __( "Start date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_from_gmt' => array( + 'description' => __( 'Start date of sale price, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'date_on_sale_to_gmt' => array( + 'description' => __( "End date of sale price, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + ), + 'price_html' => array( + 'description' => __( 'Price formatted in HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'on_sale' => array( + 'description' => __( 'Shows if the product is on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'purchasable' => array( + 'description' => __( 'Shows if the product can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Amount of sales.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'virtual' => array( + 'description' => __( 'If the product is virtual.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloadable' => array( + 'description' => __( 'If the product is downloadable.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'downloads' => array( + 'description' => __( 'List of downloadable files.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'File ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'File name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'file' => array( + 'description' => __( 'File URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'download_limit' => array( + 'description' => __( 'Number of times downloadable files can be downloaded after purchase.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'download_expiry' => array( + 'description' => __( 'Number of days until access to downloadable files expires.', 'woocommerce' ), + 'type' => 'integer', + 'default' => -1, + 'context' => array( 'view', 'edit' ), + ), + 'external_url' => array( + 'description' => __( 'Product external URL. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'button_text' => array( + 'description' => __( 'Product external button text. Only for external products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'tax_status' => array( + 'description' => __( 'Tax status.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'taxable', + 'enum' => array( 'taxable', 'shipping', 'none' ), + 'context' => array( 'view', 'edit' ), + ), + 'tax_class' => array( + 'description' => __( 'Tax class.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'manage_stock' => array( + 'description' => __( 'Stock management at product level.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'stock_quantity' => array( + 'description' => __( 'Stock quantity.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'stock_status' => array( + 'description' => __( 'Controls the stock status of the product.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'instock', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders' => array( + 'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'no', + 'enum' => array( 'no', 'notify', 'yes' ), + 'context' => array( 'view', 'edit' ), + ), + 'backorders_allowed' => array( + 'description' => __( 'Shows if backorders are allowed.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'backordered' => array( + 'description' => __( 'Shows if the product is on backordered.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'sold_individually' => array( + 'description' => __( 'Allow one item to be bought in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'weight' => array( + /* translators: %s: weight unit */ + 'description' => sprintf( __( 'Product weight (%s).', 'woocommerce' ), $weight_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'dimensions' => array( + 'description' => __( 'Product dimensions.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'length' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product length (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'width' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product width (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'height' => array( + /* translators: %s: dimension unit */ + 'description' => sprintf( __( 'Product height (%s).', 'woocommerce' ), $dimension_unit ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'shipping_required' => array( + 'description' => __( 'Shows if the product need to be shipped.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_taxable' => array( + 'description' => __( 'Shows whether or not the product shipping is taxable.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'shipping_class' => array( + 'description' => __( 'Shipping class slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'shipping_class_id' => array( + 'description' => __( 'Shipping class ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'reviews_allowed' => array( + 'description' => __( 'Allow reviews.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + 'context' => array( 'view', 'edit' ), + ), + 'average_rating' => array( + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'rating_count' => array( + 'description' => __( 'Amount of reviews that the product have.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'related_ids' => array( + 'description' => __( 'List of related products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'upsell_ids' => array( + 'description' => __( 'List of up-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'cross_sell_ids' => array( + 'description' => __( 'List of cross-sell products IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'Product parent ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'purchase_note' => array( + 'description' => __( 'Optional note to send the customer after purchase.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'categories' => array( + 'description' => __( 'List of categories.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Category ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Category name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Category slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'tags' => array( + 'description' => __( 'List of tags.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Tag ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Tag name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'Tag slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ), + ), + 'images' => array( + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'date_created' => array( + 'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified' => array( + 'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_modified_gmt' => array( + 'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'src' => array( + 'description' => __( 'Image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'alt' => array( + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'attributes' => array( + 'description' => __( 'List of attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'position' => array( + 'description' => __( 'Attribute position.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'visible' => array( + 'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'variation' => array( + 'description' => __( 'Define if the attribute can be used as variation.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'context' => array( 'view', 'edit' ), + ), + 'options' => array( + 'description' => __( 'List of available term names of the attribute.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'default_attributes' => array( + 'description' => __( 'Defaults variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Attribute ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'option' => array( + 'description' => __( 'Selected attribute term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + 'variations' => array( + 'description' => __( 'List of variations IDs.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'integer', + ), + 'readonly' => true, + ), + 'grouped_products' => array( + 'description' => __( 'List of grouped products ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'menu_order' => array( + 'description' => __( 'Menu order, used to custom sort products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'meta_data' => array( + 'description' => __( 'Meta data.', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Meta ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'key' => array( + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'value' => array( + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + ), + ), + ); + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Add new options for 'orderby' to the collection params. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + $params['orderby']['enum'] = array_merge( $params['orderby']['enum'], array( 'price', 'popularity', 'rating' ) ); + + unset( $params['in_stock'] ); + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + + /** + * Get product data. + * + * @param WC_Product $product Product instance. + * @param string $context Request context. + * Options: 'view' and 'edit'. + * @return array + */ + protected function get_product_data( $product, $context = 'view' ) { + $data = parent::get_product_data( $product, $context ); + + // Replace in_stock with stock_status. + $pos = array_search( 'in_stock', array_keys( $data ), true ); + $array_section_1 = array_slice( $data, 0, $pos, true ); + $array_section_2 = array_slice( $data, $pos + 1, null, true ); + + return $array_section_1 + array( 'stock_status' => $product->get_stock_status( $context ) ) + $array_section_2; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php new file mode 100644 index 0000000..10525ef --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php @@ -0,0 +1,143 @@ + $name ) { + $results = $wpdb->get_results( + $wpdb->prepare( " + SELECT count(meta_id) AS total + FROM $wpdb->postmeta + WHERE meta_key = 'discount_type' + AND meta_value = %s + ", $slug ) + ); + + $total = isset( $results[0] ) ? (int) $results[0]->total : 0; + + $data[] = array( + 'slug' => $slug, + 'name' => $name, + 'total' => $total, + ); + } + + set_transient( 'rest_api_coupons_type_count', $data, YEAR_IN_SECONDS ); + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + /** + * Filter a report returned from the API. + * + * Allows modification of the report data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $report The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_coupons_count', $response, $report, $request ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'report_coupon_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Coupon type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of coupons.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php new file mode 100644 index 0000000..5e5e679 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php @@ -0,0 +1,154 @@ + $total ) { + if ( in_array( $role, array( 'administrator', 'shop_manager' ), true ) ) { + continue; + } + + $total_customers += (int) $total; + } + + $customers_query = new WP_User_Query( + array( + 'role__not_in' => array( 'administrator', 'shop_manager' ), + 'number' => 0, + 'fields' => 'ID', + 'count_total' => true, + 'meta_query' => array( // WPCS: slow query ok. + array( + 'key' => 'paying_customer', + 'value' => 1, + 'compare' => '=', + ), + ), + ) + ); + + $total_paying = (int) $customers_query->get_total(); + + $data = array( + array( + 'slug' => 'paying', + 'name' => __( 'Paying customer', 'woocommerce' ), + 'total' => $total_paying, + ), + array( + 'slug' => 'non_paying', + 'name' => __( 'Non-paying customer', 'woocommerce' ), + 'total' => $total_customers - $total_paying, + ), + ); + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + /** + * Filter a report returned from the API. + * + * Allows modification of the report data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $report The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_customers_count', $response, $report, $request ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'report_customer_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Customer type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of customers.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php new file mode 100644 index 0000000..77c74f6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php @@ -0,0 +1,127 @@ + $name ) { + if ( ! isset( $totals->$slug ) ) { + continue; + } + + $data[] = array( + 'slug' => str_replace( 'wc-', '', $slug ), + 'name' => $name, + 'total' => (int) $totals->$slug, + ); + } + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + /** + * Filter a report returned from the API. + * + * Allows modification of the report data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $report The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_orders_count', $response, $report, $request ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'report_order_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Order status name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of orders.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php new file mode 100644 index 0000000..95fb0e8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php @@ -0,0 +1,133 @@ + 'product_type', + 'hide_empty' => false, + ) + ); + $data = array(); + + foreach ( $terms as $product_type ) { + if ( ! isset( $types[ $product_type->name ] ) ) { + continue; + } + + $data[] = array( + 'slug' => $product_type->name, + 'name' => $types[ $product_type->name ], + 'total' => (int) $product_type->count, + ); + } + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + /** + * Filter a report returned from the API. + * + * Allows modification of the report data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $report The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_products_count', $response, $report, $request ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'report_product_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Product type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of products.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php new file mode 100644 index 0000000..324a4aa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php @@ -0,0 +1,132 @@ + true, + 'post_type' => 'product', + 'meta_key' => 'rating', // WPCS: slow query ok. + 'meta_value' => '', // WPCS: slow query ok. + ); + + for ( $i = 1; $i <= 5; $i++ ) { + $query_data['meta_value'] = $i; + + $data[] = array( + 'slug' => 'rated_' . $i . '_out_of_5', + /* translators: %s: average rating */ + 'name' => sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $i ), + 'total' => (int) get_comments( $query_data ), + ); + } + + return $data; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $report, $request ) { + $data = array( + 'slug' => $report->slug, + 'name' => $report->name, + 'total' => $report->total, + ); + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + /** + * Filter a report returned from the API. + * + * Allows modification of the report data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $report The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_reviews_count', $response, $report, $request ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'report_review_total', + 'type' => 'object', + 'properties' => array( + 'slug' => array( + 'description' => __( 'An alphanumeric identifier for the resource.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Review type name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + 'total' => array( + 'description' => __( 'Amount of reviews.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-sales-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-sales-controller.php new file mode 100644 index 0000000..28fd0e9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-report-sales-controller.php @@ -0,0 +1,27 @@ + 'orders/totals', + 'description' => __( 'Orders totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'products/totals', + 'description' => __( 'Products totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'customers/totals', + 'description' => __( 'Customers totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'coupons/totals', + 'description' => __( 'Coupons totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'reviews/totals', + 'description' => __( 'Reviews totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'categories/totals', + 'description' => __( 'Categories totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'tags/totals', + 'description' => __( 'Tags totals.', 'woocommerce' ), + ); + $reports[] = array( + 'slug' => 'attributes/totals', + 'description' => __( 'Attributes totals.', 'woocommerce' ), + ); + + return $reports; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php new file mode 100644 index 0000000..0a2bb55 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php @@ -0,0 +1,250 @@ + 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + + if ( empty( $settings ) ) { + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_settings = array(); + foreach ( $settings as $setting ) { + $option_key = $setting['option_key']; + $setting = $this->filter_setting( $setting ); + $default = isset( $setting['default'] ) ? $setting['default'] : ''; + // Get the option value. + if ( is_array( $option_key ) ) { + $option = get_option( $option_key[0] ); + $setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default; + } else { + $admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default ); + $setting['value'] = $admin_setting_value; + } + + if ( 'multi_select_countries' === $setting['type'] ) { + $setting['options'] = WC()->countries->get_countries(); + $setting['type'] = 'multiselect'; + } elseif ( 'single_select_country' === $setting['type'] ) { + $setting['type'] = 'select'; + $setting['options'] = $this->get_countries_and_states(); + } elseif ( 'single_select_page' === $setting['type'] ) { + $pages = get_pages( + array( + 'sort_column' => 'menu_order', + 'sort_order' => 'ASC', + 'hierarchical' => 0, + ) + ); + $options = array(); + foreach ( $pages as $page ) { + $options[ $page->ID ] = ! empty( $page->post_title ) ? $page->post_title : '#' . $page->ID; + } + $setting['type'] = 'select'; + $setting['options'] = $options; + } + + $filtered_settings[] = $setting; + } + + return $filtered_settings; + } + + /** + * Returns a list of countries and states for use in the base location setting. + * + * @since 3.0.7 + * @return array Array of states and countries. + */ + private function get_countries_and_states() { + $countries = WC()->countries->get_countries(); + if ( ! $countries ) { + return array(); + } + $output = array(); + foreach ( $countries as $key => $value ) { + $states = WC()->countries->get_states( $key ); + + if ( $states ) { + foreach ( $states as $state_key => $state_value ) { + $output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value; + } + } else { + $output[ $key ] = $value; + } + } + return $output; + } + + /** + * Get the settings schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'group_id' => array( + 'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'value' => array( + 'description' => __( 'Setting value.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'mixed', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'tip' => array( + 'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Type of setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + 'context' => array( 'view', 'edit' ), + 'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ), + 'readonly' => true, + ), + 'options' => array( + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php new file mode 100644 index 0000000..ebc195b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php @@ -0,0 +1,112 @@ +namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + } + + /** + * Makes sure the current user has access to WRITE the settings APIs. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|bool + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Update a setting. + * + * @param WP_REST_Request $request Request data. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $options_controller = new WC_REST_Setting_Options_Controller(); + $response = $options_controller->update_item( $request ); + + return $response; + } + + /** + * Get the groups schema, conforming to JSON Schema. + * + * @since 3.0.0 + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'setting_group', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'label' => array( + 'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'description' => array( + 'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-methods-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-methods-controller.php new file mode 100644 index 0000000..6baff7d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-methods-controller.php @@ -0,0 +1,27 @@ +/locations endpoint. + * + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Locations class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Shipping_Zone_Locations_V2_Controller + */ +class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zone_Locations_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php new file mode 100644 index 0000000..32b59d0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php @@ -0,0 +1,27 @@ +/methods endpoint. + * + * @package WooCommerce\RestApi + * @since 3.0.0 + */ + +defined( 'ABSPATH' ) || exit; + +/** + * REST API Shipping Zone Methods class. + * + * @package WooCommerce\RestApi + * @extends WC_REST_Shipping_Zone_Methods_V2_Controller + */ +class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zone_Methods_V2_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v3'; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php new file mode 100644 index 0000000..ffd5dc4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php @@ -0,0 +1,125 @@ + 404 ) ); + } + + return $zone; + } + + /** + * Check whether a given request has permission to read Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check whether a given request has permission to edit Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check whether a given request has permission to delete Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller.php new file mode 100644 index 0000000..dafef18 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller.php @@ -0,0 +1,27 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( + $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + array( + 'name' => array( + 'type' => 'string', + 'description' => __( 'Name for the resource.', 'woocommerce' ), + 'required' => true, + ), + ) + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', + array( + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'type' => 'boolean', + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/batch', + array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) + ); + } + + /** + * Check if a given request has access to read the terms. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'read' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to create a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'create' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to read a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'read' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to update a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'edit' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access to delete a term. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'delete' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check if a given request has access batch create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return boolean|WP_Error + */ + public function batch_items_permissions_check( $request ) { + $permissions = $this->check_permissions( $request, 'batch' ); + if ( is_wp_error( $permissions ) ) { + return $permissions; + } + + if ( ! $permissions ) { + return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Check permissions. + * + * @param WP_REST_Request $request Full details about the request. + * @param string $context Request context. + * @return bool|WP_Error + */ + protected function check_permissions( $request, $context = 'read' ) { + // Get taxonomy. + $taxonomy = $this->get_taxonomy( $request ); + if ( ! $taxonomy || ! taxonomy_exists( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_invalid', __( 'Taxonomy does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Check permissions for a single term. + $id = intval( $request['id'] ); + if ( $id ) { + $term = get_term( $id, $taxonomy ); + + if ( is_wp_error( $term ) || ! $term || $term->taxonomy !== $taxonomy ) { + return new WP_Error( 'woocommerce_rest_term_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + return wc_rest_check_product_term_permissions( $taxonomy, $context, $term->term_id ); + } + + return wc_rest_check_product_term_permissions( $taxonomy, $context ); + } + + /** + * Get terms associated with a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $prepared_args = array( + 'exclude' => $request['exclude'], + 'include' => $request['include'], + 'order' => $request['order'], + 'orderby' => $request['orderby'], + 'product' => $request['product'], + 'hide_empty' => $request['hide_empty'], + 'number' => $request['per_page'], + 'search' => $request['search'], + 'slug' => $request['slug'], + ); + + if ( ! empty( $request['offset'] ) ) { + $prepared_args['offset'] = $request['offset']; + } else { + $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; + } + + $taxonomy_obj = get_taxonomy( $taxonomy ); + + if ( $taxonomy_obj->hierarchical && isset( $request['parent'] ) ) { + if ( 0 === $request['parent'] ) { + // Only query top-level terms. + $prepared_args['parent'] = 0; + } else { + if ( $request['parent'] ) { + $prepared_args['parent'] = $request['parent']; + } + } + } + + /** + * Filter the query arguments, before passing them to `get_terms()`. + * + * Enables adding extra arguments or setting defaults for a terms + * collection request. + * + * @see https://developer.wordpress.org/reference/functions/get_terms/ + * + * @param array $prepared_args Array of arguments to be + * passed to get_terms. + * @param WP_REST_Request $request The current request. + */ + $prepared_args = apply_filters( "woocommerce_rest_{$taxonomy}_query", $prepared_args, $request ); + + if ( ! empty( $prepared_args['product'] ) ) { + $query_result = $this->get_terms_for_product( $prepared_args, $request ); + $total_terms = $this->total_terms; + } else { + $query_result = get_terms( $taxonomy, $prepared_args ); + + $count_args = $prepared_args; + unset( $count_args['number'] ); + unset( $count_args['offset'] ); + $total_terms = wp_count_terms( $taxonomy, $count_args ); + + // Ensure we don't return results when offset is out of bounds. + // See https://core.trac.wordpress.org/ticket/35935. + if ( $prepared_args['offset'] && $prepared_args['offset'] >= $total_terms ) { + $query_result = array(); + } + + // wp_count_terms can return a falsy value when the term has no children. + if ( ! $total_terms ) { + $total_terms = 0; + } + } + $response = array(); + foreach ( $query_result as $term ) { + $data = $this->prepare_item_for_response( $term, $request ); + $response[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $response ); + + // Store pagination values for headers then unset for count query. + $per_page = (int) $prepared_args['number']; + $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); + + $response->header( 'X-WP-Total', (int) $total_terms ); + $max_pages = ceil( $total_terms / $per_page ); + $response->header( 'X-WP-TotalPages', (int) $max_pages ); + + $base = str_replace( '(?P[\d]+)', $request['attribute_id'], $this->rest_base ); + $base = add_query_arg( $request->get_query_params(), rest_url( '/' . $this->namespace . '/' . $base ) ); + if ( $page > 1 ) { + $prev_page = $page - 1; + if ( $prev_page > $max_pages ) { + $prev_page = $max_pages; + } + $prev_link = add_query_arg( 'page', $prev_page, $base ); + $response->link_header( 'prev', $prev_link ); + } + if ( $max_pages > $page ) { + $next_page = $page + 1; + $next_link = add_query_arg( 'page', $next_page, $base ); + $response->link_header( 'next', $next_link ); + } + + return $response; + } + + /** + * Create a single term for a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $name = $request['name']; + $args = array(); + $schema = $this->get_item_schema(); + + if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { + $args['description'] = $request['description']; + } + if ( isset( $request['slug'] ) ) { + $args['slug'] = $request['slug']; + } + if ( isset( $request['parent'] ) ) { + if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + } + $args['parent'] = $request['parent']; + } + + $term = wp_insert_term( $name, $taxonomy, $args ); + if ( is_wp_error( $term ) ) { + $error_data = array( 'status' => 400 ); + + // If we're going to inform the client that the term exists, + // give them the identifier they can actually use. + $term_id = $term->get_error_data( 'term_exists' ); + if ( $term_id ) { + $error_data['resource_id'] = $term_id; + } + + return new WP_Error( $term->get_error_code(), $term->get_error_message(), $error_data ); + } + + $term = get_term( $term['term_id'], $taxonomy ); + + $this->update_additional_fields_for_object( $term, $request ); + + // Add term data. + $meta_fields = $this->update_term_meta_fields( $term, $request ); + if ( is_wp_error( $meta_fields ) ) { + wp_delete_term( $term->term_id, $taxonomy ); + + return $meta_fields; + } + + /** + * Fires after a single term is created or updated via the REST API. + * + * @param WP_Term $term Inserted Term object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating term, false when updating. + */ + do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $term, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + + $base = '/' . $this->namespace . '/' . $this->rest_base; + if ( ! empty( $request['attribute_id'] ) ) { + $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); + } + + $response->header( 'Location', rest_url( $base . '/' . $term->term_id ) ); + + return $response; + } + + /** + * Get a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function get_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $term = get_term( (int) $request['id'], $taxonomy ); + + if ( is_wp_error( $term ) ) { + return $term; + } + + $response = $this->prepare_item_for_response( $term, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Update a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $term = get_term( (int) $request['id'], $taxonomy ); + $schema = $this->get_item_schema(); + $prepared_args = array(); + + if ( isset( $request['name'] ) ) { + $prepared_args['name'] = $request['name']; + } + if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { + $prepared_args['description'] = $request['description']; + } + if ( isset( $request['slug'] ) ) { + $prepared_args['slug'] = $request['slug']; + } + if ( isset( $request['parent'] ) ) { + if ( ! is_taxonomy_hierarchical( $taxonomy ) ) { + return new WP_Error( 'woocommerce_rest_taxonomy_not_hierarchical', __( 'Can not set resource parent, taxonomy is not hierarchical.', 'woocommerce' ), array( 'status' => 400 ) ); + } + $prepared_args['parent'] = $request['parent']; + } + + // Only update the term if we haz something to update. + if ( ! empty( $prepared_args ) ) { + $update = wp_update_term( $term->term_id, $term->taxonomy, $prepared_args ); + if ( is_wp_error( $update ) ) { + return $update; + } + } + + $term = get_term( (int) $request['id'], $taxonomy ); + + $this->update_additional_fields_for_object( $term, $request ); + + // Update term data. + $meta_fields = $this->update_term_meta_fields( $term, $request ); + if ( is_wp_error( $meta_fields ) ) { + return $meta_fields; + } + + /** + * Fires after a single term is created or updated via the REST API. + * + * @param WP_Term $term Inserted Term object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating term, false when updating. + */ + do_action( "woocommerce_rest_insert_{$taxonomy}", $term, $request, false ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $term, $request ); + return rest_ensure_response( $response ); + } + + /** + * Delete a single term from a taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error + */ + public function delete_item( $request ) { + $taxonomy = $this->get_taxonomy( $request ); + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Resource does not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $term = get_term( (int) $request['id'], $taxonomy ); + // Get default category id. + $default_category_id = absint( get_option( 'default_product_cat', 0 ) ); + + // Prevent deleting the default product category. + if ( $default_category_id === (int) $request['id'] ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Default product category cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $term, $request ); + + $retval = wp_delete_term( $term->term_id, $term->taxonomy ); + if ( ! $retval ) { + return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + /** + * Fires after a single term is deleted via the REST API. + * + * @param WP_Term $term The deleted term. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( "woocommerce_rest_delete_{$taxonomy}", $term, $response, $request ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param object $term Term object. + * @param WP_REST_Request $request Full details about the request. + * @return array Links for the given term. + */ + protected function prepare_links( $term, $request ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + + if ( ! empty( $request['attribute_id'] ) ) { + $base = str_replace( '(?P[\d]+)', (int) $request['attribute_id'], $base ); + } + + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $term->term_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + + if ( $term->parent ) { + $parent_term = get_term( (int) $term->parent, $term->taxonomy ); + if ( $parent_term ) { + $links['up'] = array( + 'href' => rest_url( trailingslashit( $base ) . $parent_term->term_id ), + ); + } + } + + return $links; + } + + /** + * Update term meta fields. + * + * @param WP_Term $term Term object. + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + protected function update_term_meta_fields( $term, $request ) { + return true; + } + + /** + * Get the terms attached to a product. + * + * This is an alternative to `get_terms()` that uses `get_the_terms()` + * instead, which hits the object cache. There are a few things not + * supported, notably `include`, `exclude`. In `self::get_items()` these + * are instead treated as a full query. + * + * @param array $prepared_args Arguments for `get_terms()`. + * @param WP_REST_Request $request Full details about the request. + * @return array List of term objects. (Total count in `$this->total_terms`). + */ + protected function get_terms_for_product( $prepared_args, $request ) { + $taxonomy = $this->get_taxonomy( $request ); + + $query_result = get_the_terms( $prepared_args['product'], $taxonomy ); + if ( empty( $query_result ) ) { + $this->total_terms = 0; + return array(); + } + + // get_items() verifies that we don't have `include` set, and default. + // ordering is by `name`. + if ( ! in_array( $prepared_args['orderby'], array( 'name', 'none', 'include' ), true ) ) { + switch ( $prepared_args['orderby'] ) { + case 'id': + $this->sort_column = 'term_id'; + break; + case 'slug': + case 'term_group': + case 'description': + case 'count': + $this->sort_column = $prepared_args['orderby']; + break; + } + usort( $query_result, array( $this, 'compare_terms' ) ); + } + if ( strtolower( $prepared_args['order'] ) !== 'asc' ) { + $query_result = array_reverse( $query_result ); + } + + // Pagination. + $this->total_terms = count( $query_result ); + $query_result = array_slice( $query_result, $prepared_args['offset'], $prepared_args['number'] ); + + return $query_result; + } + + /** + * Comparison function for sorting terms by a column. + * + * Uses `$this->sort_column` to determine field to sort by. + * + * @param stdClass $left Term object. + * @param stdClass $right Term object. + * @return int <0 if left is higher "priority" than right, 0 if equal, >0 if right is higher "priority" than left. + */ + protected function compare_terms( $left, $right ) { + $col = $this->sort_column; + $left_val = $left->$col; + $right_val = $right->$col; + + if ( is_int( $left_val ) && is_int( $right_val ) ) { + return $left_val - $right_val; + } + + return strcmp( $left_val, $right_val ); + } + + /** + * Get the query params for collections + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + if ( '' !== $this->taxonomy && taxonomy_exists( $this->taxonomy ) ) { + $taxonomy = get_taxonomy( $this->taxonomy ); + } else { + $taxonomy = new stdClass(); + $taxonomy->hierarchical = true; + } + + $params['context']['default'] = 'view'; + + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + $params['include'] = array( + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + if ( ! $taxonomy->hierarchical ) { + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + } + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'default' => 'asc', + 'enum' => array( + 'asc', + 'desc', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orderby'] = array( + 'description' => __( 'Sort collection by resource attribute.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'default' => 'name', + 'enum' => array( + 'id', + 'include', + 'name', + 'slug', + 'term_group', + 'description', + 'count', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['hide_empty'] = array( + 'description' => __( 'Whether to hide resources not assigned to any products.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + 'validate_callback' => 'rest_validate_request_arg', + ); + if ( $taxonomy->hierarchical ) { + $params['parent'] = array( + 'description' => __( 'Limit result set to resources assigned to a specific parent.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + } + $params['product'] = array( + 'description' => __( 'Limit result set to resources assigned to a specific product.', 'woocommerce' ), + 'type' => 'integer', + 'default' => null, + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['slug'] = array( + 'description' => __( 'Limit result set to resources with a specific slug.', 'woocommerce' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + + /** + * Get taxonomy. + * + * @param WP_REST_Request $request Full details about the request. + * @return int|WP_Error + */ + protected function get_taxonomy( $request ) { + // Check if taxonomy is defined. + // Prevents check for attribute taxonomy more than one time for each query. + if ( '' !== $this->taxonomy ) { + return $this->taxonomy; + } + + if ( ! empty( $request['attribute_id'] ) ) { + $taxonomy = wc_attribute_taxonomy_name_by_id( (int) $request['attribute_id'] ); + + $this->taxonomy = $taxonomy; + } + + return $this->taxonomy; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-webhooks-controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-webhooks-controller.php new file mode 100644 index 0000000..16c3060 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-webhooks-controller.php @@ -0,0 +1,37 @@ +init() + */ + public static function init() { + wc_deprecated_function( 'Automattic\WooCommerce\RestApi\Server::instance()->init()', '4.5.0' ); + \Automattic\WooCommerce\RestApi\Server::instance()->init(); + } + + /** + * Return the version of the package. + * + * @deprecated since 4.5.0. This tracks WooCommerce version now. + * @return string + */ + public static function get_version() { + wc_deprecated_function( 'WC()->version', '4.5.0' ); + return WC()->version; + } + + /** + * Return the path to the package. + * + * @deprecated since 4.5.0. Directly call Automattic\WooCommerce\RestApi\Server::get_path() + * @return string + */ + public static function get_path() { + wc_deprecated_function( 'Automattic\WooCommerce\RestApi\Server::get_path()', '4.5.0' ); + return \Automattic\WooCommerce\RestApi\Server::get_path(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Server.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Server.php new file mode 100644 index 0000000..ab69619 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Server.php @@ -0,0 +1,190 @@ +get_rest_namespaces() as $namespace => $controllers ) { + foreach ( $controllers as $controller_name => $controller_class ) { + $this->controllers[ $namespace ][ $controller_name ] = new $controller_class(); + $this->controllers[ $namespace ][ $controller_name ]->register_routes(); + } + } + } + + /** + * Get API namespaces - new namespaces should be registered here. + * + * @return array List of Namespaces and Main controller classes. + */ + protected function get_rest_namespaces() { + return apply_filters( + 'woocommerce_rest_api_get_rest_namespaces', + array( + 'wc/v1' => $this->get_v1_controllers(), + 'wc/v2' => $this->get_v2_controllers(), + 'wc/v3' => $this->get_v3_controllers(), + ) + ); + } + + /** + * List of controllers in the wc/v1 namespace. + * + * @return array + */ + protected function get_v1_controllers() { + return array( + 'coupons' => 'WC_REST_Coupons_V1_Controller', + 'customer-downloads' => 'WC_REST_Customer_Downloads_V1_Controller', + 'customers' => 'WC_REST_Customers_V1_Controller', + 'order-notes' => 'WC_REST_Order_Notes_V1_Controller', + 'order-refunds' => 'WC_REST_Order_Refunds_V1_Controller', + 'orders' => 'WC_REST_Orders_V1_Controller', + 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V1_Controller', + 'product-attributes' => 'WC_REST_Product_Attributes_V1_Controller', + 'product-categories' => 'WC_REST_Product_Categories_V1_Controller', + 'product-reviews' => 'WC_REST_Product_Reviews_V1_Controller', + 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V1_Controller', + 'product-tags' => 'WC_REST_Product_Tags_V1_Controller', + 'products' => 'WC_REST_Products_V1_Controller', + 'reports-sales' => 'WC_REST_Report_Sales_V1_Controller', + 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V1_Controller', + 'reports' => 'WC_REST_Reports_V1_Controller', + 'tax-classes' => 'WC_REST_Tax_Classes_V1_Controller', + 'taxes' => 'WC_REST_Taxes_V1_Controller', + 'webhooks' => 'WC_REST_Webhooks_V1_Controller', + 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V1_Controller', + ); + } + + /** + * List of controllers in the wc/v2 namespace. + * + * @return array + */ + protected function get_v2_controllers() { + return array( + 'coupons' => 'WC_REST_Coupons_V2_Controller', + 'customer-downloads' => 'WC_REST_Customer_Downloads_V2_Controller', + 'customers' => 'WC_REST_Customers_V2_Controller', + 'network-orders' => 'WC_REST_Network_Orders_V2_Controller', + 'order-notes' => 'WC_REST_Order_Notes_V2_Controller', + 'order-refunds' => 'WC_REST_Order_Refunds_V2_Controller', + 'orders' => 'WC_REST_Orders_V2_Controller', + 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_V2_Controller', + 'product-attributes' => 'WC_REST_Product_Attributes_V2_Controller', + 'product-categories' => 'WC_REST_Product_Categories_V2_Controller', + 'product-reviews' => 'WC_REST_Product_Reviews_V2_Controller', + 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_V2_Controller', + 'product-tags' => 'WC_REST_Product_Tags_V2_Controller', + 'products' => 'WC_REST_Products_V2_Controller', + 'product-variations' => 'WC_REST_Product_Variations_V2_Controller', + 'reports-sales' => 'WC_REST_Report_Sales_V2_Controller', + 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_V2_Controller', + 'reports' => 'WC_REST_Reports_V2_Controller', + 'settings' => 'WC_REST_Settings_V2_Controller', + 'settings-options' => 'WC_REST_Setting_Options_V2_Controller', + 'shipping-zones' => 'WC_REST_Shipping_Zones_V2_Controller', + 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_V2_Controller', + 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_V2_Controller', + 'tax-classes' => 'WC_REST_Tax_Classes_V2_Controller', + 'taxes' => 'WC_REST_Taxes_V2_Controller', + 'webhooks' => 'WC_REST_Webhooks_V2_Controller', + 'webhook-deliveries' => 'WC_REST_Webhook_Deliveries_V2_Controller', + 'system-status' => 'WC_REST_System_Status_V2_Controller', + 'system-status-tools' => 'WC_REST_System_Status_Tools_V2_Controller', + 'shipping-methods' => 'WC_REST_Shipping_Methods_V2_Controller', + 'payment-gateways' => 'WC_REST_Payment_Gateways_V2_Controller', + ); + } + + /** + * List of controllers in the wc/v3 namespace. + * + * @return array + */ + protected function get_v3_controllers() { + return array( + 'coupons' => 'WC_REST_Coupons_Controller', + 'customer-downloads' => 'WC_REST_Customer_Downloads_Controller', + 'customers' => 'WC_REST_Customers_Controller', + 'network-orders' => 'WC_REST_Network_Orders_Controller', + 'order-notes' => 'WC_REST_Order_Notes_Controller', + 'order-refunds' => 'WC_REST_Order_Refunds_Controller', + 'orders' => 'WC_REST_Orders_Controller', + 'product-attribute-terms' => 'WC_REST_Product_Attribute_Terms_Controller', + 'product-attributes' => 'WC_REST_Product_Attributes_Controller', + 'product-categories' => 'WC_REST_Product_Categories_Controller', + 'product-reviews' => 'WC_REST_Product_Reviews_Controller', + 'product-shipping-classes' => 'WC_REST_Product_Shipping_Classes_Controller', + 'product-tags' => 'WC_REST_Product_Tags_Controller', + 'products' => 'WC_REST_Products_Controller', + 'product-variations' => 'WC_REST_Product_Variations_Controller', + 'reports-sales' => 'WC_REST_Report_Sales_Controller', + 'reports-top-sellers' => 'WC_REST_Report_Top_Sellers_Controller', + 'reports-orders-totals' => 'WC_REST_Report_Orders_Totals_Controller', + 'reports-products-totals' => 'WC_REST_Report_Products_Totals_Controller', + 'reports-customers-totals' => 'WC_REST_Report_Customers_Totals_Controller', + 'reports-coupons-totals' => 'WC_REST_Report_Coupons_Totals_Controller', + 'reports-reviews-totals' => 'WC_REST_Report_Reviews_Totals_Controller', + 'reports' => 'WC_REST_Reports_Controller', + 'settings' => 'WC_REST_Settings_Controller', + 'settings-options' => 'WC_REST_Setting_Options_Controller', + 'shipping-zones' => 'WC_REST_Shipping_Zones_Controller', + 'shipping-zone-locations' => 'WC_REST_Shipping_Zone_Locations_Controller', + 'shipping-zone-methods' => 'WC_REST_Shipping_Zone_Methods_Controller', + 'tax-classes' => 'WC_REST_Tax_Classes_Controller', + 'taxes' => 'WC_REST_Taxes_Controller', + 'webhooks' => 'WC_REST_Webhooks_Controller', + 'system-status' => 'WC_REST_System_Status_Controller', + 'system-status-tools' => 'WC_REST_System_Status_Tools_Controller', + 'shipping-methods' => 'WC_REST_Shipping_Methods_Controller', + 'payment-gateways' => 'WC_REST_Payment_Gateways_Controller', + 'data' => 'WC_REST_Data_Controller', + 'data-continents' => 'WC_REST_Data_Continents_Controller', + 'data-countries' => 'WC_REST_Data_Countries_Controller', + 'data-currencies' => 'WC_REST_Data_Currencies_Controller', + ); + } + + /** + * Return the path to the package. + * + * @return string + */ + public static function get_path() { + return dirname( __DIR__ ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Utilities/ImageAttachment.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Utilities/ImageAttachment.php new file mode 100644 index 0000000..debecff --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Utilities/ImageAttachment.php @@ -0,0 +1,93 @@ +id = (int) $id; + $this->object_id = (int) $object_id; + } + + /** + * Upload an attachment file. + * + * @throws \WC_REST_Exception REST API exceptions. + * @param string $src URL to file. + */ + public function upload_image_from_src( $src ) { + $upload = wc_rest_upload_image_from_url( esc_url_raw( $src ) ); + + if ( is_wp_error( $upload ) ) { + if ( ! apply_filters( 'woocommerce_rest_suppress_image_upload_error', false, $upload, $this->object_id, $images ) ) { + throw new \WC_REST_Exception( 'woocommerce_product_image_upload_error', $upload->get_error_message(), 400 ); + } else { + return; + } + } + + $this->id = wc_rest_set_uploaded_image_as_attachment( $upload, $this->object_id ); + + if ( ! wp_attachment_is_image( $this->id ) ) { + /* translators: %s: image ID */ + throw new \WC_REST_Exception( 'woocommerce_product_invalid_image_id', sprintf( __( '#%s is an invalid image ID.', 'woocommerce' ), $this->id ), 400 ); + } + } + + /** + * Update attachment alt text. + * + * @param string $text Text to set. + */ + public function update_alt_text( $text ) { + if ( ! $this->id ) { + return; + } + update_post_meta( $this->id, '_wp_attachment_image_alt', wc_clean( $text ) ); + } + + /** + * Update attachment name. + * + * @param string $text Text to set. + */ + public function update_name( $text ) { + if ( ! $this->id ) { + return; + } + wp_update_post( + array( + 'ID' => $this->id, + 'post_title' => $text, + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Utilities/SingletonTrait.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Utilities/SingletonTrait.php new file mode 100644 index 0000000..b713a6c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/rest-api/Utilities/SingletonTrait.php @@ -0,0 +1,52 @@ +id = 'flat_rate'; + $this->instance_id = absint( $instance_id ); + $this->method_title = __( 'Flat rate', 'woocommerce' ); + $this->method_description = __( 'Lets you charge a fixed rate for shipping.', 'woocommerce' ); + $this->supports = array( + 'shipping-zones', + 'instance-settings', + 'instance-settings-modal', + ); + $this->init(); + + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + } + + /** + * Init user set variables. + */ + public function init() { + $this->instance_form_fields = include __DIR__ . '/includes/settings-flat-rate.php'; + $this->title = $this->get_option( 'title' ); + $this->tax_status = $this->get_option( 'tax_status' ); + $this->cost = $this->get_option( 'cost' ); + $this->type = $this->get_option( 'type', 'class' ); + } + + /** + * Evaluate a cost from a sum/string. + * + * @param string $sum Sum of shipping. + * @param array $args Args, must contain `cost` and `qty` keys. Having `array()` as default is for back compat reasons. + * @return string + */ + protected function evaluate_cost( $sum, $args = array() ) { + // Add warning for subclasses. + if ( ! is_array( $args ) || ! array_key_exists( 'qty', $args ) || ! array_key_exists( 'cost', $args ) ) { + wc_doing_it_wrong( __FUNCTION__, '$args must contain `cost` and `qty` keys.', '4.0.1' ); + } + + include_once WC()->plugin_path() . '/includes/libraries/class-wc-eval-math.php'; + + // Allow 3rd parties to process shipping cost arguments. + $args = apply_filters( 'woocommerce_evaluate_shipping_cost_args', $args, $sum, $this ); + $locale = localeconv(); + $decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'], ',' ); + $this->fee_cost = $args['cost']; + + // Expand shortcodes. + add_shortcode( 'fee', array( $this, 'fee' ) ); + + $sum = do_shortcode( + str_replace( + array( + '[qty]', + '[cost]', + ), + array( + $args['qty'], + $args['cost'], + ), + $sum + ) + ); + + remove_shortcode( 'fee', array( $this, 'fee' ) ); + + // Remove whitespace from string. + $sum = preg_replace( '/\s+/', '', $sum ); + + // Remove locale from string. + $sum = str_replace( $decimals, '.', $sum ); + + // Trim invalid start/end characters. + $sum = rtrim( ltrim( $sum, "\t\n\r\0\x0B+*/" ), "\t\n\r\0\x0B+-*/" ); + + // Do the math. + return $sum ? WC_Eval_Math::evaluate( $sum ) : 0; + } + + /** + * Work out fee (shortcode). + * + * @param array $atts Attributes. + * @return string + */ + public function fee( $atts ) { + $atts = shortcode_atts( + array( + 'percent' => '', + 'min_fee' => '', + 'max_fee' => '', + ), + $atts, + 'fee' + ); + + $calculated_fee = 0; + + if ( $atts['percent'] ) { + $calculated_fee = $this->fee_cost * ( floatval( $atts['percent'] ) / 100 ); + } + + if ( $atts['min_fee'] && $calculated_fee < $atts['min_fee'] ) { + $calculated_fee = $atts['min_fee']; + } + + if ( $atts['max_fee'] && $calculated_fee > $atts['max_fee'] ) { + $calculated_fee = $atts['max_fee']; + } + + return $calculated_fee; + } + + /** + * Calculate the shipping costs. + * + * @param array $package Package of items from cart. + */ + public function calculate_shipping( $package = array() ) { + $rate = array( + 'id' => $this->get_rate_id(), + 'label' => $this->title, + 'cost' => 0, + 'package' => $package, + ); + + // Calculate the costs. + $has_costs = false; // True when a cost is set. False if all costs are blank strings. + $cost = $this->get_option( 'cost' ); + + if ( '' !== $cost ) { + $has_costs = true; + $rate['cost'] = $this->evaluate_cost( + $cost, + array( + 'qty' => $this->get_package_item_qty( $package ), + 'cost' => $package['contents_cost'], + ) + ); + } + + // Add shipping class costs. + $shipping_classes = WC()->shipping()->get_shipping_classes(); + + if ( ! empty( $shipping_classes ) ) { + $found_shipping_classes = $this->find_shipping_classes( $package ); + $highest_class_cost = 0; + + foreach ( $found_shipping_classes as $shipping_class => $products ) { + // Also handles BW compatibility when slugs were used instead of ids. + $shipping_class_term = get_term_by( 'slug', $shipping_class, 'product_shipping_class' ); + $class_cost_string = $shipping_class_term && $shipping_class_term->term_id ? $this->get_option( 'class_cost_' . $shipping_class_term->term_id, $this->get_option( 'class_cost_' . $shipping_class, '' ) ) : $this->get_option( 'no_class_cost', '' ); + + if ( '' === $class_cost_string ) { + continue; + } + + $has_costs = true; + $class_cost = $this->evaluate_cost( + $class_cost_string, + array( + 'qty' => array_sum( wp_list_pluck( $products, 'quantity' ) ), + 'cost' => array_sum( wp_list_pluck( $products, 'line_total' ) ), + ) + ); + + if ( 'class' === $this->type ) { + $rate['cost'] += $class_cost; + } else { + $highest_class_cost = $class_cost > $highest_class_cost ? $class_cost : $highest_class_cost; + } + } + + if ( 'order' === $this->type && $highest_class_cost ) { + $rate['cost'] += $highest_class_cost; + } + } + + if ( $has_costs ) { + $this->add_rate( $rate ); + } + + /** + * Developers can add additional flat rates based on this one via this action since @version 2.4. + * + * Previously there were (overly complex) options to add additional rates however this was not user. + * friendly and goes against what Flat Rate Shipping was originally intended for. + */ + do_action( 'woocommerce_' . $this->id . '_shipping_add_rate', $this, $rate ); + } + + /** + * Get items in package. + * + * @param array $package Package of items from cart. + * @return int + */ + public function get_package_item_qty( $package ) { + $total_quantity = 0; + foreach ( $package['contents'] as $item_id => $values ) { + if ( $values['quantity'] > 0 && $values['data']->needs_shipping() ) { + $total_quantity += $values['quantity']; + } + } + return $total_quantity; + } + + /** + * Finds and returns shipping classes and the products with said class. + * + * @param mixed $package Package of items from cart. + * @return array + */ + public function find_shipping_classes( $package ) { + $found_shipping_classes = array(); + + foreach ( $package['contents'] as $item_id => $values ) { + if ( $values['data']->needs_shipping() ) { + $found_class = $values['data']->get_shipping_class(); + + if ( ! isset( $found_shipping_classes[ $found_class ] ) ) { + $found_shipping_classes[ $found_class ] = array(); + } + + $found_shipping_classes[ $found_class ][ $item_id ] = $values; + } + } + + return $found_shipping_classes; + } + + /** + * Sanitize the cost field. + * + * @since 3.4.0 + * @param string $value Unsanitized value. + * @throws Exception Last error triggered. + * @return string + */ + public function sanitize_cost( $value ) { + $value = is_null( $value ) ? '' : $value; + $value = wp_kses_post( trim( wp_unslash( $value ) ) ); + $value = str_replace( array( get_woocommerce_currency_symbol(), html_entity_decode( get_woocommerce_currency_symbol() ) ), '', $value ); + // Thrown an error on the front end if the evaluate_cost will fail. + $dummy_cost = $this->evaluate_cost( + $value, + array( + 'cost' => 1, + 'qty' => 1, + ) + ); + if ( false === $dummy_cost ) { + throw new Exception( WC_Eval_Math::$last_error ); + } + return $value; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/flat-rate/includes/settings-flat-rate.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/flat-rate/includes/settings-flat-rate.php new file mode 100644 index 0000000..b4609d6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/flat-rate/includes/settings-flat-rate.php @@ -0,0 +1,89 @@ +10.00 * [qty].', 'woocommerce' ) . '

    ' . __( 'Use [qty] for the number of items,
    [cost] for the total cost of items, and [fee percent="10" min_fee="20" max_fee=""] for percentage based fees.', 'woocommerce' ); + +$settings = array( + 'title' => array( + 'title' => __( 'Method title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => __( 'Flat rate', 'woocommerce' ), + 'desc_tip' => true, + ), + 'tax_status' => array( + 'title' => __( 'Tax status', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'default' => 'taxable', + 'options' => array( + 'taxable' => __( 'Taxable', 'woocommerce' ), + 'none' => _x( 'None', 'Tax status', 'woocommerce' ), + ), + ), + 'cost' => array( + 'title' => __( 'Cost', 'woocommerce' ), + 'type' => 'text', + 'placeholder' => '', + 'description' => $cost_desc, + 'default' => '0', + 'desc_tip' => true, + 'sanitize_callback' => array( $this, 'sanitize_cost' ), + ), +); + +$shipping_classes = WC()->shipping()->get_shipping_classes(); + +if ( ! empty( $shipping_classes ) ) { + $settings['class_costs'] = array( + 'title' => __( 'Shipping class costs', 'woocommerce' ), + 'type' => 'title', + 'default' => '', + /* translators: %s: URL for link. */ + 'description' => sprintf( __( 'These costs can optionally be added based on the product shipping class.', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=classes' ) ), + ); + foreach ( $shipping_classes as $shipping_class ) { + if ( ! isset( $shipping_class->term_id ) ) { + continue; + } + $settings[ 'class_cost_' . $shipping_class->term_id ] = array( + /* translators: %s: shipping class name */ + 'title' => sprintf( __( '"%s" shipping class cost', 'woocommerce' ), esc_html( $shipping_class->name ) ), + 'type' => 'text', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'description' => $cost_desc, + 'default' => $this->get_option( 'class_cost_' . $shipping_class->slug ), // Before 2.5.0, we used slug here which caused issues with long setting names. + 'desc_tip' => true, + 'sanitize_callback' => array( $this, 'sanitize_cost' ), + ); + } + + $settings['no_class_cost'] = array( + 'title' => __( 'No shipping class cost', 'woocommerce' ), + 'type' => 'text', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'description' => $cost_desc, + 'default' => '', + 'desc_tip' => true, + 'sanitize_callback' => array( $this, 'sanitize_cost' ), + ); + + $settings['type'] = array( + 'title' => __( 'Calculation type', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'default' => 'class', + 'options' => array( + 'class' => __( 'Per class: Charge shipping for each shipping class individually', 'woocommerce' ), + 'order' => __( 'Per order: Charge shipping for the most expensive shipping class', 'woocommerce' ), + ), + ); +} + +return $settings; diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/free-shipping/class-wc-shipping-free-shipping.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/free-shipping/class-wc-shipping-free-shipping.php new file mode 100644 index 0000000..fc630e6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/free-shipping/class-wc-shipping-free-shipping.php @@ -0,0 +1,245 @@ +id = 'free_shipping'; + $this->instance_id = absint( $instance_id ); + $this->method_title = __( 'Free shipping', 'woocommerce' ); + $this->method_description = __( 'Free shipping is a special method which can be triggered with coupons and minimum spends.', 'woocommerce' ); + $this->supports = array( + 'shipping-zones', + 'instance-settings', + 'instance-settings-modal', + ); + + $this->init(); + } + + /** + * Initialize free shipping. + */ + public function init() { + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Define user set variables. + $this->title = $this->get_option( 'title' ); + $this->min_amount = $this->get_option( 'min_amount', 0 ); + $this->requires = $this->get_option( 'requires' ); + $this->ignore_discounts = $this->get_option( 'ignore_discounts' ); + + // Actions. + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'admin_footer', array( 'WC_Shipping_Free_Shipping', 'enqueue_admin_js' ), 10 ); // Priority needs to be higher than wc_print_js (25). + } + + /** + * Init form fields. + */ + public function init_form_fields() { + $this->instance_form_fields = array( + 'title' => array( + 'title' => __( 'Title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => $this->method_title, + 'desc_tip' => true, + ), + 'requires' => array( + 'title' => __( 'Free shipping requires...', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'default' => '', + 'options' => array( + '' => __( 'N/A', 'woocommerce' ), + 'coupon' => __( 'A valid free shipping coupon', 'woocommerce' ), + 'min_amount' => __( 'A minimum order amount', 'woocommerce' ), + 'either' => __( 'A minimum order amount OR a coupon', 'woocommerce' ), + 'both' => __( 'A minimum order amount AND a coupon', 'woocommerce' ), + ), + ), + 'min_amount' => array( + 'title' => __( 'Minimum order amount', 'woocommerce' ), + 'type' => 'price', + 'placeholder' => wc_format_localized_price( 0 ), + 'description' => __( 'Users will need to spend this amount to get free shipping (if enabled above).', 'woocommerce' ), + 'default' => '0', + 'desc_tip' => true, + ), + 'ignore_discounts' => array( + 'title' => __( 'Coupons discounts', 'woocommerce' ), + 'label' => __( 'Apply minimum order rule before coupon discount', 'woocommerce' ), + 'type' => 'checkbox', + 'description' => __( 'If checked, free shipping would be available based on pre-discount order amount.', 'woocommerce' ), + 'default' => 'no', + 'desc_tip' => true, + ), + ); + } + + /** + * Get setting form fields for instances of this shipping method within zones. + * + * @return array + */ + public function get_instance_form_fields() { + return parent::get_instance_form_fields(); + } + + /** + * See if free shipping is available based on the package and cart. + * + * @param array $package Shipping package. + * @return bool + */ + public function is_available( $package ) { + $has_coupon = false; + $has_met_min_amount = false; + + if ( in_array( $this->requires, array( 'coupon', 'either', 'both' ), true ) ) { + $coupons = WC()->cart->get_coupons(); + + if ( $coupons ) { + foreach ( $coupons as $code => $coupon ) { + if ( $coupon->is_valid() && $coupon->get_free_shipping() ) { + $has_coupon = true; + break; + } + } + } + } + + if ( in_array( $this->requires, array( 'min_amount', 'either', 'both' ), true ) ) { + $total = WC()->cart->get_displayed_subtotal(); + + if ( WC()->cart->display_prices_including_tax() ) { + $total = $total - WC()->cart->get_discount_tax(); + } + + if ( 'no' === $this->ignore_discounts ) { + $total = $total - WC()->cart->get_discount_total(); + } + + $total = NumberUtil::round( $total, wc_get_price_decimals() ); + + if ( $total >= $this->min_amount ) { + $has_met_min_amount = true; + } + } + + switch ( $this->requires ) { + case 'min_amount': + $is_available = $has_met_min_amount; + break; + case 'coupon': + $is_available = $has_coupon; + break; + case 'both': + $is_available = $has_met_min_amount && $has_coupon; + break; + case 'either': + $is_available = $has_met_min_amount || $has_coupon; + break; + default: + $is_available = true; + break; + } + + return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available, $package, $this ); + } + + /** + * Called to calculate shipping rates for this method. Rates can be added using the add_rate() method. + * + * @uses WC_Shipping_Method::add_rate() + * + * @param array $package Shipping package. + */ + public function calculate_shipping( $package = array() ) { + $this->add_rate( + array( + 'label' => $this->title, + 'cost' => 0, + 'taxes' => false, + 'package' => $package, + ) + ); + } + + /** + * Enqueue JS to handle free shipping options. + * + * Static so that's enqueued only once. + */ + public static function enqueue_admin_js() { + wc_enqueue_js( + "jQuery( function( $ ) { + function wcFreeShippingShowHideMinAmountField( el ) { + var form = $( el ).closest( 'form' ); + var minAmountField = $( '#woocommerce_free_shipping_min_amount', form ).closest( 'tr' ); + var ignoreDiscountField = $( '#woocommerce_free_shipping_ignore_discounts', form ).closest( 'tr' ); + if ( 'coupon' === $( el ).val() || '' === $( el ).val() ) { + minAmountField.hide(); + ignoreDiscountField.hide(); + } else { + minAmountField.show(); + ignoreDiscountField.show(); + } + } + + $( document.body ).on( 'change', '#woocommerce_free_shipping_requires', function() { + wcFreeShippingShowHideMinAmountField( this ); + }); + + // Change while load. + $( '#woocommerce_free_shipping_requires' ).change(); + $( document.body ).on( 'wc_backbone_modal_loaded', function( evt, target ) { + if ( 'wc-modal-shipping-method-settings' === target ) { + wcFreeShippingShowHideMinAmountField( $( '#wc-backbone-modal-dialog #woocommerce_free_shipping_requires', evt.currentTarget ) ); + } + } ); + });" + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php new file mode 100644 index 0000000..1f579c4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-flat-rate/class-wc-shipping-legacy-flat-rate.php @@ -0,0 +1,411 @@ +id = 'legacy_flat_rate'; + $this->method_title = __( 'Flat rate (legacy)', 'woocommerce' ); + /* translators: %s: Admin shipping settings URL */ + $this->method_description = '' . sprintf( __( 'This method is deprecated in 2.6.0 and will be removed in future versions - we recommend disabling it and instead setting up a new rate within your Shipping zones.', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=shipping' ) ) . ''; + $this->init(); + + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_flat_rate_shipping_add_rate', array( $this, 'calculate_extra_shipping' ), 10, 2 ); + } + + /** + * Process and redirect if disabled. + */ + public function process_admin_options() { + parent::process_admin_options(); + + if ( 'no' === $this->settings['enabled'] ) { + wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=options' ) ); + exit; + } + } + + /** + * Return the name of the option in the WP DB. + * + * @since 2.6.0 + * @return string + */ + public function get_option_key() { + return $this->plugin_id . 'flat_rate_settings'; + } + + /** + * Init function. + */ + public function init() { + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Define user set variables. + $this->title = $this->get_option( 'title' ); + $this->availability = $this->get_option( 'availability' ); + $this->countries = $this->get_option( 'countries' ); + $this->tax_status = $this->get_option( 'tax_status' ); + $this->cost = $this->get_option( 'cost' ); + $this->type = $this->get_option( 'type', 'class' ); + $this->options = $this->get_option( 'options', false ); // @deprecated 2.4.0 + } + + /** + * Initialise Settings Form Fields. + */ + public function init_form_fields() { + $this->form_fields = include __DIR__ . '/includes/settings-flat-rate.php'; + } + + /** + * Evaluate a cost from a sum/string. + * + * @param string $sum Sum to evaluate. + * @param array $args Arguments. + * @return string + */ + protected function evaluate_cost( $sum, $args = array() ) { + include_once WC()->plugin_path() . '/includes/libraries/class-wc-eval-math.php'; + + $locale = localeconv(); + $decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'] ); + + $this->fee_cost = $args['cost']; + + // Expand shortcodes. + add_shortcode( 'fee', array( $this, 'fee' ) ); + + $sum = do_shortcode( + str_replace( + array( + '[qty]', + '[cost]', + ), + array( + $args['qty'], + $args['cost'], + ), + $sum + ) + ); + + remove_shortcode( 'fee', array( $this, 'fee' ) ); + + // Remove whitespace from string. + $sum = preg_replace( '/\s+/', '', $sum ); + + // Remove locale from string. + $sum = str_replace( $decimals, '.', $sum ); + + // Trim invalid start/end characters. + $sum = rtrim( ltrim( $sum, "\t\n\r\0\x0B+*/" ), "\t\n\r\0\x0B+-*/" ); + + // Do the math. + return $sum ? WC_Eval_Math::evaluate( $sum ) : 0; + } + + /** + * Work out fee (shortcode). + * + * @param array $atts Shortcode attributes. + * @return string + */ + public function fee( $atts ) { + $atts = shortcode_atts( + array( + 'percent' => '', + 'min_fee' => '', + ), + $atts, + 'fee' + ); + + $calculated_fee = 0; + + if ( $atts['percent'] ) { + $calculated_fee = $this->fee_cost * ( floatval( $atts['percent'] ) / 100 ); + } + + if ( $atts['min_fee'] && $calculated_fee < $atts['min_fee'] ) { + $calculated_fee = $atts['min_fee']; + } + + return $calculated_fee; + } + + /** + * Calculate shipping. + * + * @param array $package (default: array()). + */ + public function calculate_shipping( $package = array() ) { + $rate = array( + 'id' => $this->id, + 'label' => $this->title, + 'cost' => 0, + 'package' => $package, + ); + + // Calculate the costs. + $has_costs = false; // True when a cost is set. False if all costs are blank strings. + $cost = $this->get_option( 'cost' ); + + if ( '' !== $cost ) { + $has_costs = true; + $rate['cost'] = $this->evaluate_cost( + $cost, + array( + 'qty' => $this->get_package_item_qty( $package ), + 'cost' => $package['contents_cost'], + ) + ); + } + + // Add shipping class costs. + $found_shipping_classes = $this->find_shipping_classes( $package ); + $highest_class_cost = 0; + + foreach ( $found_shipping_classes as $shipping_class => $products ) { + // Also handles BW compatibility when slugs were used instead of ids. + $shipping_class_term = get_term_by( 'slug', $shipping_class, 'product_shipping_class' ); + $class_cost_string = $shipping_class_term && $shipping_class_term->term_id ? $this->get_option( 'class_cost_' . $shipping_class_term->term_id, $this->get_option( 'class_cost_' . $shipping_class, '' ) ) : $this->get_option( 'no_class_cost', '' ); + + if ( '' === $class_cost_string ) { + continue; + } + + $has_costs = true; + $class_cost = $this->evaluate_cost( + $class_cost_string, + array( + 'qty' => array_sum( wp_list_pluck( $products, 'quantity' ) ), + 'cost' => array_sum( wp_list_pluck( $products, 'line_total' ) ), + ) + ); + + if ( 'class' === $this->type ) { + $rate['cost'] += $class_cost; + } else { + $highest_class_cost = $class_cost > $highest_class_cost ? $class_cost : $highest_class_cost; + } + } + + if ( 'order' === $this->type && $highest_class_cost ) { + $rate['cost'] += $highest_class_cost; + } + + $rate['package'] = $package; + + // Add the rate. + if ( $has_costs ) { + $this->add_rate( $rate ); + } + + /** + * Developers can add additional flat rates based on this one via this action since @version 2.4. + * + * Previously there were (overly complex) options to add additional rates however this was not user. + * friendly and goes against what Flat Rate Shipping was originally intended for. + * + * This example shows how you can add an extra rate based on this flat rate via custom function: + * + * add_action( 'woocommerce_flat_rate_shipping_add_rate', 'add_another_custom_flat_rate', 10, 2 ); + * + * function add_another_custom_flat_rate( $method, $rate ) { + * $new_rate = $rate; + * $new_rate['id'] .= ':' . 'custom_rate_name'; // Append a custom ID. + * $new_rate['label'] = 'Rushed Shipping'; // Rename to 'Rushed Shipping'. + * $new_rate['cost'] += 2; // Add $2 to the cost. + * + * // Add it to WC. + * $method->add_rate( $new_rate ); + * }. + */ + do_action( 'woocommerce_flat_rate_shipping_add_rate', $this, $rate ); + } + + /** + * Get items in package. + * + * @param array $package Package information. + * @return int + */ + public function get_package_item_qty( $package ) { + $total_quantity = 0; + foreach ( $package['contents'] as $item_id => $values ) { + if ( $values['quantity'] > 0 && $values['data']->needs_shipping() ) { + $total_quantity += $values['quantity']; + } + } + return $total_quantity; + } + + /** + * Finds and returns shipping classes and the products with said class. + * + * @param mixed $package Package information. + * @return array + */ + public function find_shipping_classes( $package ) { + $found_shipping_classes = array(); + + foreach ( $package['contents'] as $item_id => $values ) { + if ( $values['data']->needs_shipping() ) { + $found_class = $values['data']->get_shipping_class(); + + if ( ! isset( $found_shipping_classes[ $found_class ] ) ) { + $found_shipping_classes[ $found_class ] = array(); + } + + $found_shipping_classes[ $found_class ][ $item_id ] = $values; + } + } + + return $found_shipping_classes; + } + + /** + * Adds extra calculated flat rates. + * + * @deprecated 2.4.0 + * + * Additional rates defined like this: + * Option Name | Additional Cost [+- Percents%] | Per Cost Type (order, class, or item). + * + * @param null $method Deprecated. + * @param array $rate Rate information. + */ + public function calculate_extra_shipping( $method, $rate ) { + if ( $this->options ) { + $options = array_filter( (array) explode( "\n", $this->options ) ); + + foreach ( $options as $option ) { + $this_option = array_map( 'trim', explode( WC_DELIMITER, $option ) ); + if ( count( $this_option ) !== 3 ) { + continue; + } + $extra_rate = $rate; + $extra_rate['id'] = $this->id . ':' . urldecode( sanitize_title( $this_option[0] ) ); + $extra_rate['label'] = $this_option[0]; + $extra_cost = $this->get_extra_cost( $this_option[1], $this_option[2], $rate['package'] ); + if ( is_array( $extra_rate['cost'] ) ) { + $extra_rate['cost']['order'] = $extra_rate['cost']['order'] + $extra_cost; + } else { + $extra_rate['cost'] += $extra_cost; + } + + $this->add_rate( $extra_rate ); + } + } + } + + /** + * Calculate the percentage adjustment for each shipping rate. + * + * @deprecated 2.4.0 + * @param float $cost Cost. + * @param float $percent_adjustment Percent adjusment. + * @param string $percent_operator Percent operator. + * @param float $base_price Base price. + * @return float + */ + public function calc_percentage_adjustment( $cost, $percent_adjustment, $percent_operator, $base_price ) { + if ( '+' === $percent_operator ) { + $cost += $percent_adjustment * $base_price; + } else { + $cost -= $percent_adjustment * $base_price; + } + return $cost; + } + + /** + * Get extra cost. + * + * @deprecated 2.4.0 + * @param string $cost_string Cost string. + * @param string $type Type. + * @param array $package Package information. + * @return float + */ + public function get_extra_cost( $cost_string, $type, $package ) { + $cost = $cost_string; + $cost_percent = false; + // @codingStandardsIgnoreStart + $pattern = + '/' . // Start regex. + '(\d+\.?\d*)' . // Capture digits, optionally capture a `.` and more digits. + '\s*' . // Match whitespace. + '(\+|-)' . // Capture the operand. + '\s*' . // Match whitespace. + '(\d+\.?\d*)' . // Capture digits, optionally capture a `.` and more digits. + '\%/'; // Match the percent sign & end regex. + // @codingStandardsIgnoreEnd + if ( preg_match( $pattern, $cost_string, $this_cost_matches ) ) { + $cost_operator = $this_cost_matches[2]; + $cost_percent = $this_cost_matches[3] / 100; + $cost = $this_cost_matches[1]; + } + switch ( $type ) { + case 'class': + $cost = $cost * count( $this->find_shipping_classes( $package ) ); + break; + case 'item': + $cost = $cost * $this->get_package_item_qty( $package ); + break; + } + if ( $cost_percent ) { + switch ( $type ) { + case 'class': + $shipping_classes = $this->find_shipping_classes( $package ); + foreach ( $shipping_classes as $shipping_class => $items ) { + foreach ( $items as $item_id => $values ) { + $cost = $this->calc_percentage_adjustment( $cost, $cost_percent, $cost_operator, $values['line_total'] ); + } + } + break; + case 'item': + foreach ( $package['contents'] as $item_id => $values ) { + if ( $values['data']->needs_shipping() ) { + $cost = $this->calc_percentage_adjustment( $cost, $cost_percent, $cost_operator, $values['line_total'] ); + } + } + break; + case 'order': + $cost = $this->calc_percentage_adjustment( $cost, $cost_percent, $cost_operator, $package['contents_cost'] ); + break; + } + } + return $cost; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-flat-rate/includes/settings-flat-rate.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-flat-rate/includes/settings-flat-rate.php new file mode 100644 index 0000000..de0fd0b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-flat-rate/includes/settings-flat-rate.php @@ -0,0 +1,133 @@ +10.00 * [qty]
    .', 'woocommerce' ) . '
    ' . __( 'Supports the following placeholders: [qty] = number of items, [cost] = cost of items, [fee percent="10" min_fee="20"] = Percentage based fee.', 'woocommerce' ); + +/** + * Settings for flat rate shipping. + */ +$settings = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Once disabled, this legacy method will no longer be available.', 'woocommerce' ), + 'default' => 'no', + ), + 'title' => array( + 'title' => __( 'Method title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => __( 'Flat rate', 'woocommerce' ), + 'desc_tip' => true, + ), + 'availability' => array( + 'title' => __( 'Availability', 'woocommerce' ), + 'type' => 'select', + 'default' => 'all', + 'class' => 'availability wc-enhanced-select', + 'options' => array( + 'all' => __( 'All allowed countries', 'woocommerce' ), + 'specific' => __( 'Specific Countries', 'woocommerce' ), + ), + ), + 'countries' => array( + 'title' => __( 'Specific countries', 'woocommerce' ), + 'type' => 'multiselect', + 'class' => 'wc-enhanced-select', + 'css' => 'width: 400px;', + 'default' => '', + 'options' => WC()->countries->get_shipping_countries(), + 'custom_attributes' => array( + 'data-placeholder' => __( 'Select some countries', 'woocommerce' ), + ), + ), + 'tax_status' => array( + 'title' => __( 'Tax status', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'default' => 'taxable', + 'options' => array( + 'taxable' => __( 'Taxable', 'woocommerce' ), + 'none' => _x( 'None', 'Tax status', 'woocommerce' ), + ), + ), + 'cost' => array( + 'title' => __( 'Cost', 'woocommerce' ), + 'type' => 'text', + 'placeholder' => '', + 'description' => $cost_desc, + 'default' => '', + 'desc_tip' => true, + ), +); + +$shipping_classes = WC()->shipping()->get_shipping_classes(); + +if ( ! empty( $shipping_classes ) ) { + $settings['class_costs'] = array( + 'title' => __( 'Shipping class costs', 'woocommerce' ), + 'type' => 'title', + 'default' => '', + /* translators: %s: Admin shipping settings URL */ + 'description' => sprintf( __( 'These costs can optionally be added based on the product shipping class.', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=classes' ) ), + ); + foreach ( $shipping_classes as $shipping_class ) { + if ( ! isset( $shipping_class->term_id ) ) { + continue; + } + $settings[ 'class_cost_' . $shipping_class->term_id ] = array( + /* translators: %s: shipping class name */ + 'title' => sprintf( __( '"%s" shipping class cost', 'woocommerce' ), esc_html( $shipping_class->name ) ), + 'type' => 'text', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'description' => $cost_desc, + 'default' => $this->get_option( 'class_cost_' . $shipping_class->slug ), // Before 2.5.0, we used slug here which caused issues with long setting names. + 'desc_tip' => true, + ); + } + $settings['no_class_cost'] = array( + 'title' => __( 'No shipping class cost', 'woocommerce' ), + 'type' => 'text', + 'placeholder' => __( 'N/A', 'woocommerce' ), + 'description' => $cost_desc, + 'default' => '', + 'desc_tip' => true, + ); + $settings['type'] = array( + 'title' => __( 'Calculation type', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'default' => 'class', + 'options' => array( + 'class' => __( 'Per class: Charge shipping for each shipping class individually', 'woocommerce' ), + 'order' => __( 'Per order: Charge shipping for the most expensive shipping class', 'woocommerce' ), + ), + ); +} + +if ( apply_filters( 'woocommerce_enable_deprecated_additional_flat_rates', $this->get_option( 'options', false ) ) ) { + $settings['additional_rates'] = array( + 'title' => __( 'Additional rates', 'woocommerce' ), + 'type' => 'title', + 'default' => '', + 'description' => __( 'These rates are extra shipping options with additional costs (based on the flat rate).', 'woocommerce' ), + ); + $settings['options'] = array( + 'title' => __( 'Additional rates', 'woocommerce' ), + 'type' => 'textarea', + 'description' => __( 'One per line: Option name | Additional cost [+- Percents] | Per cost type (order, class, or item) Example: Priority mail | 6.95 [+ 0.2%] | order.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => __( 'Option name | Additional cost [+- Percents%] | Per cost type (order, class, or item)', 'woocommerce' ), + ); +} + +return $settings; diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php new file mode 100644 index 0000000..1993426 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-free-shipping/class-wc-shipping-legacy-free-shipping.php @@ -0,0 +1,252 @@ +id = 'legacy_free_shipping'; + $this->method_title = __( 'Free shipping (legacy)', 'woocommerce' ); + /* translators: %s: Admin shipping settings URL */ + $this->method_description = '' . sprintf( __( 'This method is deprecated in 2.6.0 and will be removed in future versions - we recommend disabling it and instead setting up a new rate within your Shipping zones.', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=shipping' ) ) . ''; + $this->init(); + } + + /** + * Process and redirect if disabled. + */ + public function process_admin_options() { + parent::process_admin_options(); + + if ( 'no' === $this->settings['enabled'] ) { + wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=options' ) ); + exit; + } + } + + /** + * Return the name of the option in the WP DB. + * + * @since 2.6.0 + * @return string + */ + public function get_option_key() { + return $this->plugin_id . 'free_shipping_settings'; + } + + /** + * Init function. + */ + public function init() { + + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Define user set variables. + $this->enabled = $this->get_option( 'enabled' ); + $this->title = $this->get_option( 'title' ); + $this->min_amount = $this->get_option( 'min_amount', 0 ); + $this->availability = $this->get_option( 'availability' ); + $this->countries = $this->get_option( 'countries' ); + $this->requires = $this->get_option( 'requires' ); + + // Actions. + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + } + + /** + * Initialise Gateway Settings Form Fields. + */ + public function init_form_fields() { + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Once disabled, this legacy method will no longer be available.', 'woocommerce' ), + 'default' => 'no', + ), + 'title' => array( + 'title' => __( 'Method title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => __( 'Free Shipping', 'woocommerce' ), + 'desc_tip' => true, + ), + 'availability' => array( + 'title' => __( 'Method availability', 'woocommerce' ), + 'type' => 'select', + 'default' => 'all', + 'class' => 'availability wc-enhanced-select', + 'options' => array( + 'all' => __( 'All allowed countries', 'woocommerce' ), + 'specific' => __( 'Specific Countries', 'woocommerce' ), + ), + ), + 'countries' => array( + 'title' => __( 'Specific countries', 'woocommerce' ), + 'type' => 'multiselect', + 'class' => 'wc-enhanced-select', + 'css' => 'width: 400px;', + 'default' => '', + 'options' => WC()->countries->get_shipping_countries(), + 'custom_attributes' => array( + 'data-placeholder' => __( 'Select some countries', 'woocommerce' ), + ), + ), + 'requires' => array( + 'title' => __( 'Free shipping requires...', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'default' => '', + 'options' => array( + '' => __( 'N/A', 'woocommerce' ), + 'coupon' => __( 'A valid free shipping coupon', 'woocommerce' ), + 'min_amount' => __( 'A minimum order amount', 'woocommerce' ), + 'either' => __( 'A minimum order amount OR a coupon', 'woocommerce' ), + 'both' => __( 'A minimum order amount AND a coupon', 'woocommerce' ), + ), + ), + 'min_amount' => array( + 'title' => __( 'Minimum order amount', 'woocommerce' ), + 'type' => 'price', + 'placeholder' => wc_format_localized_price( 0 ), + 'description' => __( 'Users will need to spend this amount to get free shipping (if enabled above).', 'woocommerce' ), + 'default' => '0', + 'desc_tip' => true, + ), + ); + } + + /** + * Check if package is available. + * + * @param array $package Package information. + * @return bool + */ + public function is_available( $package ) { + if ( 'no' === $this->enabled ) { + return false; + } + + if ( 'specific' === $this->availability ) { + $ship_to_countries = $this->countries; + } else { + $ship_to_countries = array_keys( WC()->countries->get_shipping_countries() ); + } + + if ( is_array( $ship_to_countries ) && ! in_array( $package['destination']['country'], $ship_to_countries, true ) ) { + return false; + } + + // Enabled logic. + $is_available = false; + $has_coupon = false; + $has_met_min_amount = false; + + if ( in_array( $this->requires, array( 'coupon', 'either', 'both' ), true ) ) { + $coupons = WC()->cart->get_coupons(); + + if ( $coupons ) { + foreach ( $coupons as $code => $coupon ) { + if ( $coupon->is_valid() && $coupon->get_free_shipping() ) { + $has_coupon = true; + } + } + } + } + + if ( in_array( $this->requires, array( 'min_amount', 'either', 'both' ), true ) ) { + $total = WC()->cart->get_displayed_subtotal(); + + if ( WC()->cart->display_prices_including_tax() ) { + $total = NumberUtil::round( $total - ( WC()->cart->get_discount_total() + WC()->cart->get_discount_tax() ), wc_get_price_decimals() ); + } else { + $total = NumberUtil::round( $total - WC()->cart->get_discount_total(), wc_get_price_decimals() ); + } + + if ( $total >= $this->min_amount ) { + $has_met_min_amount = true; + } + } + + switch ( $this->requires ) { + case 'min_amount': + if ( $has_met_min_amount ) { + $is_available = true; + } + break; + case 'coupon': + if ( $has_coupon ) { + $is_available = true; + } + break; + case 'both': + if ( $has_met_min_amount && $has_coupon ) { + $is_available = true; + } + break; + case 'either': + if ( $has_met_min_amount || $has_coupon ) { + $is_available = true; + } + break; + default: + $is_available = true; + break; + } + + return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available, $package, $this ); + } + + /** + * Calculate shipping. + * + * @param array $package Package information. + */ + public function calculate_shipping( $package = array() ) { + $args = array( + 'id' => $this->id, + 'label' => $this->title, + 'cost' => 0, + 'taxes' => false, + 'package' => $package, + ); + $this->add_rate( $args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-international-delivery/class-wc-shipping-legacy-international-delivery.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-international-delivery/class-wc-shipping-legacy-international-delivery.php new file mode 100644 index 0000000..6ddc038 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-international-delivery/class-wc-shipping-legacy-international-delivery.php @@ -0,0 +1,85 @@ +id = 'legacy_international_delivery'; + $this->method_title = __( 'International flat rate (legacy)', 'woocommerce' ); + /* translators: %s: Admin shipping settings URL */ + $this->method_description = '' . sprintf( __( 'This method is deprecated in 2.6.0 and will be removed in future versions - we recommend disabling it and instead setting up a new rate within your Shipping zones.', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=shipping' ) ) . ''; + $this->init(); + + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + } + + /** + * Return the name of the option in the WP DB. + * + * @since 2.6.0 + * @return string + */ + public function get_option_key() { + return $this->plugin_id . 'international_delivery_settings'; + } + + /** + * Initialise settings form fields. + */ + public function init_form_fields() { + parent::init_form_fields(); + $this->form_fields['availability'] = array( + 'title' => __( 'Availability', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'description' => '', + 'default' => 'including', + 'options' => array( + 'including' => __( 'Selected countries', 'woocommerce' ), + 'excluding' => __( 'Excluding selected countries', 'woocommerce' ), + ), + ); + } + + /** + * Check if package is available. + * + * @param array $package Package information. + * @return bool + */ + public function is_available( $package ) { + if ( 'no' === $this->enabled ) { + return false; + } + if ( 'including' === $this->availability ) { + if ( is_array( $this->countries ) && ! in_array( $package['destination']['country'], $this->countries, true ) ) { + return false; + } + } else { + if ( is_array( $this->countries ) && ( in_array( $package['destination']['country'], $this->countries, true ) || ! $package['destination']['country'] ) ) { + return false; + } + } + return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', true, $package, $this ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-local-delivery/class-wc-shipping-legacy-local-delivery.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-local-delivery/class-wc-shipping-legacy-local-delivery.php new file mode 100644 index 0000000..4484b79 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-local-delivery/class-wc-shipping-legacy-local-delivery.php @@ -0,0 +1,181 @@ +id = 'legacy_local_delivery'; + $this->method_title = __( 'Local delivery (legacy)', 'woocommerce' ); + /* translators: %s: Admin shipping settings URL */ + $this->method_description = '' . sprintf( __( 'This method is deprecated in 2.6.0 and will be removed in future versions - we recommend disabling it and instead setting up a new rate within your Shipping zones.', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=shipping' ) ) . ''; + $this->init(); + } + + /** + * Process and redirect if disabled. + */ + public function process_admin_options() { + parent::process_admin_options(); + + if ( 'no' === $this->settings['enabled'] ) { + wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=options' ) ); + exit; + } + } + + /** + * Return the name of the option in the WP DB. + * + * @since 2.6.0 + * @return string + */ + public function get_option_key() { + return $this->plugin_id . 'local_delivery_settings'; + } + + /** + * Init function. + */ + public function init() { + + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Define user set variables. + $this->title = $this->get_option( 'title' ); + $this->type = $this->get_option( 'type' ); + $this->fee = $this->get_option( 'fee' ); + $this->type = $this->get_option( 'type' ); + $this->codes = $this->get_option( 'codes' ); + $this->availability = $this->get_option( 'availability' ); + $this->countries = $this->get_option( 'countries' ); + + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + } + + /** + * Calculate_shipping function. + * + * @param array $package (default: array()). + */ + public function calculate_shipping( $package = array() ) { + $shipping_total = 0; + + switch ( $this->type ) { + case 'fixed': + $shipping_total = $this->fee; + break; + case 'percent': + $shipping_total = $package['contents_cost'] * ( $this->fee / 100 ); + break; + case 'product': + foreach ( $package['contents'] as $item_id => $values ) { + if ( $values['quantity'] > 0 && $values['data']->needs_shipping() ) { + $shipping_total += $this->fee * $values['quantity']; + } + } + break; + } + + $rate = array( + 'id' => $this->id, + 'label' => $this->title, + 'cost' => $shipping_total, + 'package' => $package, + ); + + $this->add_rate( $rate ); + } + + /** + * Init form fields. + */ + public function init_form_fields() { + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Once disabled, this legacy method will no longer be available.', 'woocommerce' ), + 'default' => 'no', + ), + 'title' => array( + 'title' => __( 'Title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => __( 'Local delivery', 'woocommerce' ), + 'desc_tip' => true, + ), + 'type' => array( + 'title' => __( 'Fee type', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'description' => __( 'How to calculate delivery charges', 'woocommerce' ), + 'default' => 'fixed', + 'options' => array( + 'fixed' => __( 'Fixed amount', 'woocommerce' ), + 'percent' => __( 'Percentage of cart total', 'woocommerce' ), + 'product' => __( 'Fixed amount per product', 'woocommerce' ), + ), + 'desc_tip' => true, + ), + 'fee' => array( + 'title' => __( 'Delivery fee', 'woocommerce' ), + 'type' => 'price', + 'description' => __( 'What fee do you want to charge for local delivery, disregarded if you choose free. Leave blank to disable.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + 'placeholder' => wc_format_localized_price( 0 ), + ), + 'codes' => array( + 'title' => __( 'Allowed ZIP/post codes', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => __( 'What ZIP/post codes are available for local delivery?', 'woocommerce' ), + 'default' => '', + 'description' => __( 'Separate codes with a comma. Accepts wildcards, e.g. P* will match a postcode of PE30. Also accepts a pattern, e.g. NG1___ would match NG1 1AA but not NG10 1AA', 'woocommerce' ), + 'placeholder' => 'e.g. 12345, 56789', + ), + 'availability' => array( + 'title' => __( 'Method availability', 'woocommerce' ), + 'type' => 'select', + 'default' => 'all', + 'class' => 'availability wc-enhanced-select', + 'options' => array( + 'all' => __( 'All allowed countries', 'woocommerce' ), + 'specific' => __( 'Specific Countries', 'woocommerce' ), + ), + ), + 'countries' => array( + 'title' => __( 'Specific countries', 'woocommerce' ), + 'type' => 'multiselect', + 'class' => 'wc-enhanced-select', + 'css' => 'width: 400px;', + 'default' => '', + 'options' => WC()->countries->get_shipping_countries(), + 'custom_attributes' => array( + 'data-placeholder' => __( 'Select some countries', 'woocommerce' ), + ), + ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-local-pickup/class-wc-shipping-legacy-local-pickup.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-local-pickup/class-wc-shipping-legacy-local-pickup.php new file mode 100644 index 0000000..dc0608e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/legacy-local-pickup/class-wc-shipping-legacy-local-pickup.php @@ -0,0 +1,232 @@ +id = 'legacy_local_pickup'; + $this->method_title = __( 'Local pickup (legacy)', 'woocommerce' ); + /* translators: %s: Admin shipping settings URL */ + $this->method_description = '' . sprintf( __( 'This method is deprecated in 2.6.0 and will be removed in future versions - we recommend disabling it and instead setting up a new rate within your Shipping zones.', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=shipping' ) ) . ''; + $this->init(); + } + + /** + * Process and redirect if disabled. + */ + public function process_admin_options() { + parent::process_admin_options(); + + if ( 'no' === $this->settings['enabled'] ) { + wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=options' ) ); + exit; + } + } + + /** + * Return the name of the option in the WP DB. + * + * @since 2.6.0 + * @return string + */ + public function get_option_key() { + return $this->plugin_id . 'local_pickup_settings'; + } + + /** + * Init function. + */ + public function init() { + + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Define user set variables. + $this->enabled = $this->get_option( 'enabled' ); + $this->title = $this->get_option( 'title' ); + $this->codes = $this->get_option( 'codes' ); + $this->availability = $this->get_option( 'availability' ); + $this->countries = $this->get_option( 'countries' ); + + // Actions. + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + } + + /** + * Calculate shipping. + * + * @param array $package Package information. + */ + public function calculate_shipping( $package = array() ) { + $rate = array( + 'id' => $this->id, + 'label' => $this->title, + 'package' => $package, + ); + $this->add_rate( $rate ); + } + + /** + * Initialize form fields. + */ + public function init_form_fields() { + $this->form_fields = array( + 'enabled' => array( + 'title' => __( 'Enable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Once disabled, this legacy method will no longer be available.', 'woocommerce' ), + 'default' => 'no', + ), + 'title' => array( + 'title' => __( 'Title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => __( 'Local pickup', 'woocommerce' ), + 'desc_tip' => true, + ), + 'codes' => array( + 'title' => __( 'Allowed ZIP/post codes', 'woocommerce' ), + 'type' => 'text', + 'desc_tip' => __( 'What ZIP/post codes are available for local pickup?', 'woocommerce' ), + 'default' => '', + 'description' => __( 'Separate codes with a comma. Accepts wildcards, e.g. P* will match a postcode of PE30. Also accepts a pattern, e.g. NG1___ would match NG1 1AA but not NG10 1AA', 'woocommerce' ), + 'placeholder' => 'e.g. 12345, 56789', + ), + 'availability' => array( + 'title' => __( 'Method availability', 'woocommerce' ), + 'type' => 'select', + 'default' => 'all', + 'class' => 'availability wc-enhanced-select', + 'options' => array( + 'all' => __( 'All allowed countries', 'woocommerce' ), + 'specific' => __( 'Specific countries', 'woocommerce' ), + ), + ), + 'countries' => array( + 'title' => __( 'Specific countries', 'woocommerce' ), + 'type' => 'multiselect', + 'class' => 'wc-enhanced-select', + 'css' => 'width: 400px;', + 'default' => '', + 'options' => WC()->countries->get_shipping_countries(), + 'custom_attributes' => array( + 'data-placeholder' => __( 'Select some countries', 'woocommerce' ), + ), + ), + ); + } + + /** + * Get postcodes for this method. + * + * @return array + */ + public function get_valid_postcodes() { + $codes = array(); + + if ( '' !== $this->codes ) { + foreach ( explode( ',', $this->codes ) as $code ) { + $codes[] = strtoupper( trim( $code ) ); + } + } + + return $codes; + } + + /** + * See if a given postcode matches valid postcodes. + * + * @param string $postcode Postcode to check. + * @param string $country code Code of the country to check postcode against. + * @return boolean + */ + public function is_valid_postcode( $postcode, $country ) { + $codes = $this->get_valid_postcodes(); + $postcode = $this->clean( $postcode ); + $formatted_postcode = wc_format_postcode( $postcode, $country ); + + if ( in_array( $postcode, $codes, true ) || in_array( $formatted_postcode, $codes, true ) ) { + return true; + } + + // Pattern matching. + foreach ( $codes as $c ) { + $pattern = '/^' . str_replace( '_', '[0-9a-zA-Z]', preg_quote( $c ) ) . '$/i'; + if ( preg_match( $pattern, $postcode ) ) { + return true; + } + } + + // Wildcard search. + $wildcard_postcode = $formatted_postcode . '*'; + $postcode_length = strlen( $formatted_postcode ); + + for ( $i = 0; $i < $postcode_length; $i++ ) { + if ( in_array( $wildcard_postcode, $codes, true ) ) { + return true; + } + $wildcard_postcode = substr( $wildcard_postcode, 0, -2 ) . '*'; + } + + return false; + } + + /** + * See if the method is available. + * + * @param array $package Package information. + * @return bool + */ + public function is_available( $package ) { + $is_available = 'yes' === $this->enabled; + + if ( $is_available && $this->get_valid_postcodes() ) { + $is_available = $this->is_valid_postcode( $package['destination']['postcode'], $package['destination']['country'] ); + } + + if ( $is_available ) { + if ( 'specific' === $this->availability ) { + $ship_to_countries = $this->countries; + } else { + $ship_to_countries = array_keys( WC()->countries->get_shipping_countries() ); + } + if ( is_array( $ship_to_countries ) && ! in_array( $package['destination']['country'], $ship_to_countries, true ) ) { + $is_available = false; + } + } + + return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available, $package, $this ); + } + + /** + * Clean function. + * + * @access public + * @param mixed $code Code. + * @return string + */ + public function clean( $code ) { + return str_replace( '-', '', sanitize_title( $code ) ) . ( strstr( $code, '*' ) ? '*' : '' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/local-pickup/class-wc-shipping-local-pickup.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/local-pickup/class-wc-shipping-local-pickup.php new file mode 100644 index 0000000..a64c699 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shipping/local-pickup/class-wc-shipping-local-pickup.php @@ -0,0 +1,106 @@ +id = 'local_pickup'; + $this->instance_id = absint( $instance_id ); + $this->method_title = __( 'Local pickup', 'woocommerce' ); + $this->method_description = __( 'Allow customers to pick up orders themselves. By default, when using local pickup store base taxes will apply regardless of customer address.', 'woocommerce' ); + $this->supports = array( + 'shipping-zones', + 'instance-settings', + 'instance-settings-modal', + ); + $this->init(); + } + + /** + * Initialize local pickup. + */ + public function init() { + + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + // Define user set variables. + $this->title = $this->get_option( 'title' ); + $this->tax_status = $this->get_option( 'tax_status' ); + $this->cost = $this->get_option( 'cost' ); + + // Actions. + add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) ); + } + + /** + * Calculate local pickup shipping. + * + * @param array $package Package information. + */ + public function calculate_shipping( $package = array() ) { + $this->add_rate( + array( + 'label' => $this->title, + 'package' => $package, + 'cost' => $this->cost, + ) + ); + } + + /** + * Init form fields. + */ + public function init_form_fields() { + $this->instance_form_fields = array( + 'title' => array( + 'title' => __( 'Title', 'woocommerce' ), + 'type' => 'text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => __( 'Local pickup', 'woocommerce' ), + 'desc_tip' => true, + ), + 'tax_status' => array( + 'title' => __( 'Tax status', 'woocommerce' ), + 'type' => 'select', + 'class' => 'wc-enhanced-select', + 'default' => 'taxable', + 'options' => array( + 'taxable' => __( 'Taxable', 'woocommerce' ), + 'none' => _x( 'None', 'Tax status', 'woocommerce' ), + ), + ), + 'cost' => array( + 'title' => __( 'Cost', 'woocommerce' ), + 'type' => 'text', + 'placeholder' => '0', + 'description' => __( 'Optional cost for local pickup.', 'woocommerce' ), + 'default' => '', + 'desc_tip' => true, + ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-cart.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-cart.php new file mode 100644 index 0000000..3784fb7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-cart.php @@ -0,0 +1,102 @@ +shipping()->reset_shipping(); + + $address = array(); + + $address['country'] = isset( $_POST['calc_shipping_country'] ) ? wc_clean( wp_unslash( $_POST['calc_shipping_country'] ) ) : ''; // WPCS: input var ok, CSRF ok, sanitization ok. + $address['state'] = isset( $_POST['calc_shipping_state'] ) ? wc_clean( wp_unslash( $_POST['calc_shipping_state'] ) ) : ''; // WPCS: input var ok, CSRF ok, sanitization ok. + $address['postcode'] = isset( $_POST['calc_shipping_postcode'] ) ? wc_clean( wp_unslash( $_POST['calc_shipping_postcode'] ) ) : ''; // WPCS: input var ok, CSRF ok, sanitization ok. + $address['city'] = isset( $_POST['calc_shipping_city'] ) ? wc_clean( wp_unslash( $_POST['calc_shipping_city'] ) ) : ''; // WPCS: input var ok, CSRF ok, sanitization ok. + + $address = apply_filters( 'woocommerce_cart_calculate_shipping_address', $address ); + + if ( $address['postcode'] && ! WC_Validation::is_postcode( $address['postcode'], $address['country'] ) ) { + throw new Exception( __( 'Please enter a valid postcode / ZIP.', 'woocommerce' ) ); + } elseif ( $address['postcode'] ) { + $address['postcode'] = wc_format_postcode( $address['postcode'], $address['country'] ); + } + + if ( $address['country'] ) { + if ( ! WC()->customer->get_billing_first_name() ) { + WC()->customer->set_billing_location( $address['country'], $address['state'], $address['postcode'], $address['city'] ); + } + WC()->customer->set_shipping_location( $address['country'], $address['state'], $address['postcode'], $address['city'] ); + } else { + WC()->customer->set_billing_address_to_base(); + WC()->customer->set_shipping_address_to_base(); + } + + WC()->customer->set_calculated_shipping( true ); + WC()->customer->save(); + + wc_add_notice( __( 'Shipping costs updated.', 'woocommerce' ), 'notice' ); + + do_action( 'woocommerce_calculated_shipping' ); + + } catch ( Exception $e ) { + if ( ! empty( $e ) ) { + wc_add_notice( $e->getMessage(), 'error' ); + } + } + } + + /** + * Output the cart shortcode. + * + * @param array $atts Shortcode attributes. + */ + public static function output( $atts ) { + if ( ! apply_filters( 'woocommerce_output_cart_shortcode_content', true ) ) { + return; + } + + // Constants. + wc_maybe_define_constant( 'WOOCOMMERCE_CART', true ); + + $atts = shortcode_atts( array(), $atts, 'woocommerce_cart' ); + $nonce_value = wc_get_var( $_REQUEST['woocommerce-shipping-calculator-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + // Update Shipping. Nonce check uses new value and old value (woocommerce-cart). @todo remove in 4.0. + if ( ! empty( $_POST['calc_shipping'] ) && ( wp_verify_nonce( $nonce_value, 'woocommerce-shipping-calculator' ) || wp_verify_nonce( $nonce_value, 'woocommerce-cart' ) ) ) { // WPCS: input var ok. + self::calculate_shipping(); + + // Also calc totals before we check items so subtotals etc are up to date. + WC()->cart->calculate_totals(); + } + + // Check cart items are valid. + do_action( 'woocommerce_check_cart_items' ); + + // Calc totals. + WC()->cart->calculate_totals(); + + if ( WC()->cart->is_empty() ) { + wc_get_template( 'cart/cart-empty.php' ); + } else { + wc_get_template( 'cart/cart.php' ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-checkout.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-checkout.php new file mode 100644 index 0000000..4f6450e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-checkout.php @@ -0,0 +1,297 @@ +cart ) ) { + return; + } + + // Backwards compatibility with old pay and thanks link arguments. + if ( isset( $_GET['order'] ) && isset( $_GET['key'] ) ) { // WPCS: input var ok, CSRF ok. + wc_deprecated_argument( __CLASS__ . '->' . __FUNCTION__, '2.1', '"order" is no longer used to pass an order ID. Use the order-pay or order-received endpoint instead.' ); + + // Get the order to work out what we are showing. + $order_id = absint( $_GET['order'] ); // WPCS: input var ok. + $order = wc_get_order( $order_id ); + + if ( $order && $order->has_status( 'pending' ) ) { + $wp->query_vars['order-pay'] = absint( $_GET['order'] ); // WPCS: input var ok. + } else { + $wp->query_vars['order-received'] = absint( $_GET['order'] ); // WPCS: input var ok. + } + } + + // Handle checkout actions. + if ( ! empty( $wp->query_vars['order-pay'] ) ) { + + self::order_pay( $wp->query_vars['order-pay'] ); + + } elseif ( isset( $wp->query_vars['order-received'] ) ) { + + self::order_received( $wp->query_vars['order-received'] ); + + } else { + + self::checkout(); + + } + } + + /** + * Show the pay page. + * + * @throws Exception When validate fails. + * @param int $order_id Order ID. + */ + private static function order_pay( $order_id ) { + + do_action( 'before_woocommerce_pay' ); + + $order_id = absint( $order_id ); + + // Pay for existing order. + if ( isset( $_GET['pay_for_order'], $_GET['key'] ) && $order_id ) { // WPCS: input var ok, CSRF ok. + try { + $order_key = isset( $_GET['key'] ) ? wc_clean( wp_unslash( $_GET['key'] ) ) : ''; // WPCS: input var ok, CSRF ok. + $order = wc_get_order( $order_id ); + + // Order or payment link is invalid. + if ( ! $order || $order->get_id() !== $order_id || ! hash_equals( $order->get_order_key(), $order_key ) ) { + throw new Exception( __( 'Sorry, this order is invalid and cannot be paid for.', 'woocommerce' ) ); + } + + // Logged out customer does not have permission to pay for this order. + if ( ! current_user_can( 'pay_for_order', $order_id ) && ! is_user_logged_in() ) { + echo '
    ' . esc_html__( 'Please log in to your account below to continue to the payment form.', 'woocommerce' ) . '
    '; + woocommerce_login_form( + array( + 'redirect' => $order->get_checkout_payment_url(), + ) + ); + return; + } + + // Add notice if logged in customer is trying to pay for guest order. + if ( ! $order->get_user_id() && is_user_logged_in() ) { + // If order has does not have same billing email then current logged in user then show warning. + if ( $order->get_billing_email() !== wp_get_current_user()->user_email ) { + wc_print_notice( __( 'You are paying for a guest order. Please continue with payment only if you recognize this order.', 'woocommerce' ), 'error' ); + } + } + + // Logged in customer trying to pay for someone else's order. + if ( ! current_user_can( 'pay_for_order', $order_id ) ) { + throw new Exception( __( 'This order cannot be paid for. Please contact us if you need assistance.', 'woocommerce' ) ); + } + + // Does not need payment. + if ( ! $order->needs_payment() ) { + /* translators: %s: order status */ + throw new Exception( sprintf( __( 'This order’s status is “%s”—it cannot be paid for. Please contact us if you need assistance.', 'woocommerce' ), wc_get_order_status_name( $order->get_status() ) ) ); + } + + // Ensure order items are still stocked if paying for a failed order. Pending orders do not need this check because stock is held. + if ( ! $order->has_status( wc_get_is_pending_statuses() ) ) { + $quantities = array(); + + foreach ( $order->get_items() as $item_key => $item ) { + if ( $item && is_callable( array( $item, 'get_product' ) ) ) { + $product = $item->get_product(); + + if ( ! $product ) { + continue; + } + + $quantities[ $product->get_stock_managed_by_id() ] = isset( $quantities[ $product->get_stock_managed_by_id() ] ) ? $quantities[ $product->get_stock_managed_by_id() ] + $item->get_quantity() : $item->get_quantity(); + } + } + + foreach ( $order->get_items() as $item_key => $item ) { + if ( $item && is_callable( array( $item, 'get_product' ) ) ) { + $product = $item->get_product(); + + if ( ! $product ) { + continue; + } + + if ( ! apply_filters( 'woocommerce_pay_order_product_in_stock', $product->is_in_stock(), $product, $order ) ) { + /* translators: %s: product name */ + throw new Exception( sprintf( __( 'Sorry, "%s" is no longer in stock so this order cannot be paid for. We apologize for any inconvenience caused.', 'woocommerce' ), $product->get_name() ) ); + } + + // We only need to check products managing stock, with a limited stock qty. + if ( ! $product->managing_stock() || $product->backorders_allowed() ) { + continue; + } + + // Check stock based on all items in the cart and consider any held stock within pending orders. + $held_stock = wc_get_held_stock_quantity( $product, $order->get_id() ); + $required_stock = $quantities[ $product->get_stock_managed_by_id() ]; + + if ( ! apply_filters( 'woocommerce_pay_order_product_has_enough_stock', ( $product->get_stock_quantity() >= ( $held_stock + $required_stock ) ), $product, $order ) ) { + /* translators: 1: product name 2: quantity in stock */ + throw new Exception( sprintf( __( 'Sorry, we do not have enough "%1$s" in stock to fulfill your order (%2$s available). We apologize for any inconvenience caused.', 'woocommerce' ), $product->get_name(), wc_format_stock_quantity_for_display( $product->get_stock_quantity() - $held_stock, $product ) ) ); + } + } + } + } + + WC()->customer->set_props( + array( + 'billing_country' => $order->get_billing_country() ? $order->get_billing_country() : null, + 'billing_state' => $order->get_billing_state() ? $order->get_billing_state() : null, + 'billing_postcode' => $order->get_billing_postcode() ? $order->get_billing_postcode() : null, + ) + ); + WC()->customer->save(); + + $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); + + if ( count( $available_gateways ) ) { + current( $available_gateways )->set_current(); + } + + wc_get_template( + 'checkout/form-pay.php', + array( + 'order' => $order, + 'available_gateways' => $available_gateways, + 'order_button_text' => apply_filters( 'woocommerce_pay_order_button_text', __( 'Pay for order', 'woocommerce' ) ), + ) + ); + + } catch ( Exception $e ) { + wc_print_notice( $e->getMessage(), 'error' ); + } + } elseif ( $order_id ) { + + // Pay for order after checkout step. + $order_key = isset( $_GET['key'] ) ? wc_clean( wp_unslash( $_GET['key'] ) ) : ''; // WPCS: input var ok, CSRF ok. + $order = wc_get_order( $order_id ); + + if ( $order && $order->get_id() === $order_id && hash_equals( $order->get_order_key(), $order_key ) ) { + + if ( $order->needs_payment() ) { + + wc_get_template( 'checkout/order-receipt.php', array( 'order' => $order ) ); + + } else { + /* translators: %s: order status */ + wc_print_notice( sprintf( __( 'This order’s status is “%s”—it cannot be paid for. Please contact us if you need assistance.', 'woocommerce' ), wc_get_order_status_name( $order->get_status() ) ), 'error' ); + } + } else { + wc_print_notice( __( 'Sorry, this order is invalid and cannot be paid for.', 'woocommerce' ), 'error' ); + } + } else { + wc_print_notice( __( 'Invalid order.', 'woocommerce' ), 'error' ); + } + + do_action( 'after_woocommerce_pay' ); + } + + /** + * Show the thanks page. + * + * @param int $order_id Order ID. + */ + private static function order_received( $order_id = 0 ) { + $order = false; + + // Get the order. + $order_id = apply_filters( 'woocommerce_thankyou_order_id', absint( $order_id ) ); + $order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET['key'] ) ? '' : wc_clean( wp_unslash( $_GET['key'] ) ) ); // WPCS: input var ok, CSRF ok. + + if ( $order_id > 0 ) { + $order = wc_get_order( $order_id ); + if ( ! $order || ! hash_equals( $order->get_order_key(), $order_key ) ) { + $order = false; + } + } + + // Empty awaiting payment session. + unset( WC()->session->order_awaiting_payment ); + + // In case order is created from admin, but paid by the actual customer, store the ip address of the payer + // when they visit the payment confirmation page. + if ( $order && $order->is_created_via( 'admin' ) ) { + $order->set_customer_ip_address( WC_Geolocation::get_ip_address() ); + $order->save(); + } + + // Empty current cart. + wc_empty_cart(); + + wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) ); + } + + /** + * Show the checkout. + */ + private static function checkout() { + // Show non-cart errors. + do_action( 'woocommerce_before_checkout_form_cart_notices' ); + + // Check cart has contents. + if ( WC()->cart->is_empty() && ! is_customize_preview() && apply_filters( 'woocommerce_checkout_redirect_empty_cart', true ) ) { + return; + } + + // Check cart contents for errors. + do_action( 'woocommerce_check_cart_items' ); + + // Calc totals. + WC()->cart->calculate_totals(); + + // Get checkout object. + $checkout = WC()->checkout(); + + if ( empty( $_POST ) && wc_notice_count( 'error' ) > 0 ) { // WPCS: input var ok, CSRF ok. + + wc_get_template( 'checkout/cart-errors.php', array( 'checkout' => $checkout ) ); + wc_clear_notices(); + + } else { + + $non_js_checkout = ! empty( $_POST['woocommerce_checkout_update_totals'] ); // WPCS: input var ok, CSRF ok. + + if ( wc_notice_count( 'error' ) === 0 && $non_js_checkout ) { + wc_add_notice( __( 'The order totals have been updated. Please confirm your order by pressing the "Place order" button at the bottom of the page.', 'woocommerce' ) ); + } + + wc_get_template( 'checkout/form-checkout.php', array( 'checkout' => $checkout ) ); + + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-my-account.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-my-account.php new file mode 100644 index 0000000..270d70a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-my-account.php @@ -0,0 +1,415 @@ +cart ) ) { + return; + } + + if ( ! is_user_logged_in() || isset( $wp->query_vars['lost-password'] ) ) { + $message = apply_filters( 'woocommerce_my_account_message', '' ); + + if ( ! empty( $message ) ) { + wc_add_notice( $message ); + } + + // After password reset, add confirmation message. + if ( ! empty( $_GET['password-reset'] ) ) { // WPCS: input var ok, CSRF ok. + wc_add_notice( __( 'Your password has been reset successfully.', 'woocommerce' ) ); + } + + if ( isset( $wp->query_vars['lost-password'] ) ) { + self::lost_password(); + } else { + wc_get_template( 'myaccount/form-login.php' ); + } + } else { + // Start output buffer since the html may need discarding for BW compatibility. + ob_start(); + + if ( isset( $wp->query_vars['customer-logout'] ) ) { + /* translators: %s: logout url */ + wc_add_notice( sprintf( __( 'Are you sure you want to log out? Confirm and log out', 'woocommerce' ), wc_logout_url() ) ); + } + + // Collect notices before output. + $notices = wc_get_notices(); + + // Output the new account page. + self::my_account( $atts ); + + /** + * Deprecated my-account.php template handling. This code should be + * removed in a future release. + * + * If woocommerce_account_content did not run, this is an old template + * so we need to render the endpoint content again. + */ + if ( ! did_action( 'woocommerce_account_content' ) ) { + if ( ! empty( $wp->query_vars ) ) { + foreach ( $wp->query_vars as $key => $value ) { + if ( 'pagename' === $key ) { + continue; + } + if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) { + ob_clean(); // Clear previous buffer. + wc_set_notices( $notices ); + wc_print_notices(); + do_action( 'woocommerce_account_' . $key . '_endpoint', $value ); + break; + } + } + + wc_deprecated_function( 'Your theme version of my-account.php template', '2.6', 'the latest version, which supports multiple account pages and navigation, from WC 2.6.0' ); + } + } + + // Send output buffer. + ob_end_flush(); + } + } + + /** + * My account page. + * + * @param array $atts Shortcode attributes. + */ + private static function my_account( $atts ) { + $args = shortcode_atts( + array( + 'order_count' => 15, // @deprecated 2.6.0. Keep for backward compatibility. + ), + $atts, + 'woocommerce_my_account' + ); + + wc_get_template( + 'myaccount/my-account.php', + array( + 'current_user' => get_user_by( 'id', get_current_user_id() ), + 'order_count' => 'all' === $args['order_count'] ? -1 : $args['order_count'], + ) + ); + } + + /** + * View order page. + * + * @param int $order_id Order ID. + */ + public static function view_order( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( ! $order || ! current_user_can( 'view_order', $order_id ) ) { + echo '
    ' . esc_html__( 'Invalid order.', 'woocommerce' ) . ' ' . esc_html__( 'My account', 'woocommerce' ) . '
    '; + + return; + } + + // Backwards compatibility. + $status = new stdClass(); + $status->name = wc_get_order_status_name( $order->get_status() ); + + wc_get_template( + 'myaccount/view-order.php', + array( + 'status' => $status, // @deprecated 2.2. + 'order' => $order, + 'order_id' => $order->get_id(), + ) + ); + } + + /** + * Edit account details page. + */ + public static function edit_account() { + wc_get_template( 'myaccount/form-edit-account.php', array( 'user' => get_user_by( 'id', get_current_user_id() ) ) ); + } + + /** + * Edit address page. + * + * @param string $load_address Type of address to load. + */ + public static function edit_address( $load_address = 'billing' ) { + $current_user = wp_get_current_user(); + $load_address = sanitize_key( $load_address ); + $country = get_user_meta( get_current_user_id(), $load_address . '_country', true ); + + if ( ! $country ) { + $country = WC()->countries->get_base_country(); + } + + if ( 'billing' === $load_address ) { + $allowed_countries = WC()->countries->get_allowed_countries(); + + if ( ! array_key_exists( $country, $allowed_countries ) ) { + $country = current( array_keys( $allowed_countries ) ); + } + } + + if ( 'shipping' === $load_address ) { + $allowed_countries = WC()->countries->get_shipping_countries(); + + if ( ! array_key_exists( $country, $allowed_countries ) ) { + $country = current( array_keys( $allowed_countries ) ); + } + } + + $address = WC()->countries->get_address_fields( $country, $load_address . '_' ); + + // Enqueue scripts. + wp_enqueue_script( 'wc-country-select' ); + wp_enqueue_script( 'wc-address-i18n' ); + + // Prepare values. + foreach ( $address as $key => $field ) { + + $value = get_user_meta( get_current_user_id(), $key, true ); + + if ( ! $value ) { + switch ( $key ) { + case 'billing_email': + case 'shipping_email': + $value = $current_user->user_email; + break; + } + } + + $address[ $key ]['value'] = apply_filters( 'woocommerce_my_account_edit_address_field_value', $value, $key, $load_address ); + } + + wc_get_template( + 'myaccount/form-edit-address.php', + array( + 'load_address' => $load_address, + 'address' => apply_filters( 'woocommerce_address_to_edit', $address, $load_address ), + ) + ); + } + + /** + * Lost password page handling. + */ + public static function lost_password() { + /** + * After sending the reset link, don't show the form again. + */ + if ( ! empty( $_GET['reset-link-sent'] ) ) { // WPCS: input var ok, CSRF ok. + return wc_get_template( 'myaccount/lost-password-confirmation.php' ); + + /** + * Process reset key / login from email confirmation link + */ + } elseif ( ! empty( $_GET['show-reset-form'] ) ) { // WPCS: input var ok, CSRF ok. + if ( isset( $_COOKIE[ 'wp-resetpass-' . COOKIEHASH ] ) && 0 < strpos( $_COOKIE[ 'wp-resetpass-' . COOKIEHASH ], ':' ) ) { // @codingStandardsIgnoreLine + list( $rp_id, $rp_key ) = array_map( 'wc_clean', explode( ':', wp_unslash( $_COOKIE[ 'wp-resetpass-' . COOKIEHASH ] ), 2 ) ); // @codingStandardsIgnoreLine + $userdata = get_userdata( absint( $rp_id ) ); + $rp_login = $userdata ? $userdata->user_login : ''; + $user = self::check_password_reset_key( $rp_key, $rp_login ); + + // Reset key / login is correct, display reset password form with hidden key / login values. + if ( is_object( $user ) ) { + return wc_get_template( + 'myaccount/form-reset-password.php', + array( + 'key' => $rp_key, + 'login' => $rp_login, + ) + ); + } + } + } + + // Show lost password form by default. + wc_get_template( + 'myaccount/form-lost-password.php', + array( + 'form' => 'lost_password', + ) + ); + } + + /** + * Handles sending password retrieval email to customer. + * + * Based on retrieve_password() in core wp-login.php. + * + * @uses $wpdb WordPress Database object + * @return bool True: when finish. False: on error + */ + public static function retrieve_password() { + $login = isset( $_POST['user_login'] ) ? sanitize_user( wp_unslash( $_POST['user_login'] ) ) : ''; // WPCS: input var ok, CSRF ok. + + if ( empty( $login ) ) { + + wc_add_notice( __( 'Enter a username or email address.', 'woocommerce' ), 'error' ); + + return false; + + } else { + // Check on username first, as customers can use emails as usernames. + $user_data = get_user_by( 'login', $login ); + } + + // If no user found, check if it login is email and lookup user based on email. + if ( ! $user_data && is_email( $login ) && apply_filters( 'woocommerce_get_username_from_email', true ) ) { + $user_data = get_user_by( 'email', $login ); + } + + $errors = new WP_Error(); + + do_action( 'lostpassword_post', $errors ); + + if ( $errors->get_error_code() ) { + wc_add_notice( $errors->get_error_message(), 'error' ); + + return false; + } + + if ( ! $user_data ) { + wc_add_notice( __( 'Invalid username or email.', 'woocommerce' ), 'error' ); + + return false; + } + + if ( is_multisite() && ! is_user_member_of_blog( $user_data->ID, get_current_blog_id() ) ) { + wc_add_notice( __( 'Invalid username or email.', 'woocommerce' ), 'error' ); + + return false; + } + + // Redefining user_login ensures we return the right case in the email. + $user_login = $user_data->user_login; + + do_action( 'retrieve_password', $user_login ); + + $allow = apply_filters( 'allow_password_reset', true, $user_data->ID ); + + if ( ! $allow ) { + + wc_add_notice( __( 'Password reset is not allowed for this user', 'woocommerce' ), 'error' ); + + return false; + + } elseif ( is_wp_error( $allow ) ) { + + wc_add_notice( $allow->get_error_message(), 'error' ); + + return false; + } + + // Get password reset key (function introduced in WordPress 4.4). + $key = get_password_reset_key( $user_data ); + + // Send email notification. + WC()->mailer(); // Load email classes. + do_action( 'woocommerce_reset_password_notification', $user_login, $key ); + + return true; + } + + /** + * Retrieves a user row based on password reset key and login. + * + * @uses $wpdb WordPress Database object. + * @param string $key Hash to validate sending user's password. + * @param string $login The user login. + * @return WP_User|bool User's database row on success, false for invalid keys + */ + public static function check_password_reset_key( $key, $login ) { + // Check for the password reset key. + // Get user data or an error message in case of invalid or expired key. + $user = check_password_reset_key( $key, $login ); + + if ( is_wp_error( $user ) ) { + wc_add_notice( __( 'This key is invalid or has already been used. Please reset your password again if needed.', 'woocommerce' ), 'error' ); + return false; + } + + return $user; + } + + /** + * Handles resetting the user's password. + * + * @param object $user The user. + * @param string $new_pass New password for the user in plaintext. + */ + public static function reset_password( $user, $new_pass ) { + do_action( 'password_reset', $user, $new_pass ); + + wp_set_password( $new_pass, $user->ID ); + self::set_reset_password_cookie(); + + if ( ! apply_filters( 'woocommerce_disable_password_change_notification', false ) ) { + wp_password_change_notification( $user ); + } + } + + /** + * Set or unset the cookie. + * + * @param string $value Cookie value. + */ + public static function set_reset_password_cookie( $value = '' ) { + $rp_cookie = 'wp-resetpass-' . COOKIEHASH; + $rp_path = isset( $_SERVER['REQUEST_URI'] ) ? current( explode( '?', wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) : ''; // WPCS: input var ok, sanitization ok. + + if ( $value ) { + setcookie( $rp_cookie, $value, 0, $rp_path, COOKIE_DOMAIN, is_ssl(), true ); + } else { + setcookie( $rp_cookie, ' ', time() - YEAR_IN_SECONDS, $rp_path, COOKIE_DOMAIN, is_ssl(), true ); + } + } + + /** + * Show the add payment method page. + */ + public static function add_payment_method() { + if ( ! is_user_logged_in() ) { + wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) ); + exit(); + } else { + do_action( 'before_woocommerce_add_payment_method' ); + + wc_get_template( 'myaccount/form-add-payment-method.php' ); + + do_action( 'after_woocommerce_add_payment_method' ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-order-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-order-tracking.php new file mode 100644 index 0000000..6798539 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-order-tracking.php @@ -0,0 +1,71 @@ +cart ) ) { + return; + } + + $atts = shortcode_atts( array(), $atts, 'woocommerce_order_tracking' ); + $nonce_value = wc_get_var( $_REQUEST['woocommerce-order-tracking-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // @codingStandardsIgnoreLine. + + if ( isset( $_REQUEST['orderid'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-order_tracking' ) ) { // WPCS: input var ok. + + $order_id = empty( $_REQUEST['orderid'] ) ? 0 : ltrim( wc_clean( wp_unslash( $_REQUEST['orderid'] ) ), '#' ); // WPCS: input var ok. + $order_email = empty( $_REQUEST['order_email'] ) ? '' : sanitize_email( wp_unslash( $_REQUEST['order_email'] ) ); // WPCS: input var ok. + + if ( ! $order_id ) { + wc_print_notice( __( 'Please enter a valid order ID', 'woocommerce' ), 'error' ); + } elseif ( ! $order_email ) { + wc_print_notice( __( 'Please enter a valid email address', 'woocommerce' ), 'error' ); + } else { + $order = wc_get_order( apply_filters( 'woocommerce_shortcode_order_tracking_order_id', $order_id ) ); + + if ( $order && $order->get_id() && strtolower( $order->get_billing_email() ) === strtolower( $order_email ) ) { + do_action( 'woocommerce_track_order', $order->get_id() ); + wc_get_template( + 'order/tracking.php', + array( + 'order' => $order, + ) + ); + return; + } else { + wc_print_notice( __( 'Sorry, the order could not be found. Please contact us if you are having difficulty finding your order details.', 'woocommerce' ), 'error' ); + } + } + } + + wc_get_template( 'order/form-tracking.php' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-products.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-products.php new file mode 100644 index 0000000..d0d089f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/shortcodes/class-wc-shortcode-products.php @@ -0,0 +1,703 @@ +type = $type; + $this->attributes = $this->parse_attributes( $attributes ); + $this->query_args = $this->parse_query_args(); + } + + /** + * Get shortcode attributes. + * + * @since 3.2.0 + * @return array + */ + public function get_attributes() { + return $this->attributes; + } + + /** + * Get query args. + * + * @since 3.2.0 + * @return array + */ + public function get_query_args() { + return $this->query_args; + } + + /** + * Get shortcode type. + * + * @since 3.2.0 + * @return array + */ + public function get_type() { + return $this->type; + } + + /** + * Get shortcode content. + * + * @since 3.2.0 + * @return string + */ + public function get_content() { + return $this->product_loop(); + } + + /** + * Parse attributes. + * + * @since 3.2.0 + * @param array $attributes Shortcode attributes. + * @return array + */ + protected function parse_attributes( $attributes ) { + $attributes = $this->parse_legacy_attributes( $attributes ); + + $attributes = shortcode_atts( + array( + 'limit' => '-1', // Results limit. + 'columns' => '', // Number of columns. + 'rows' => '', // Number of rows. If defined, limit will be ignored. + 'orderby' => '', // menu_order, title, date, rand, price, popularity, rating, or id. + 'order' => '', // ASC or DESC. + 'ids' => '', // Comma separated IDs. + 'skus' => '', // Comma separated SKUs. + 'category' => '', // Comma separated category slugs or ids. + 'cat_operator' => 'IN', // Operator to compare categories. Possible values are 'IN', 'NOT IN', 'AND'. + 'attribute' => '', // Single attribute slug. + 'terms' => '', // Comma separated term slugs or ids. + 'terms_operator' => 'IN', // Operator to compare terms. Possible values are 'IN', 'NOT IN', 'AND'. + 'tag' => '', // Comma separated tag slugs. + 'tag_operator' => 'IN', // Operator to compare tags. Possible values are 'IN', 'NOT IN', 'AND'. + 'visibility' => 'visible', // Product visibility setting. Possible values are 'visible', 'catalog', 'search', 'hidden'. + 'class' => '', // HTML class. + 'page' => 1, // Page for pagination. + 'paginate' => false, // Should results be paginated. + 'cache' => true, // Should shortcode output be cached. + ), + $attributes, + $this->type + ); + + if ( ! absint( $attributes['columns'] ) ) { + $attributes['columns'] = wc_get_default_products_per_row(); + } + + return $attributes; + } + + /** + * Parse legacy attributes. + * + * @since 3.2.0 + * @param array $attributes Attributes. + * @return array + */ + protected function parse_legacy_attributes( $attributes ) { + $mapping = array( + 'per_page' => 'limit', + 'operator' => 'cat_operator', + 'filter' => 'terms', + ); + + foreach ( $mapping as $old => $new ) { + if ( isset( $attributes[ $old ] ) ) { + $attributes[ $new ] = $attributes[ $old ]; + unset( $attributes[ $old ] ); + } + } + + return $attributes; + } + + /** + * Parse query args. + * + * @since 3.2.0 + * @return array + */ + protected function parse_query_args() { + $query_args = array( + 'post_type' => 'product', + 'post_status' => 'publish', + 'ignore_sticky_posts' => true, + 'no_found_rows' => false === wc_string_to_bool( $this->attributes['paginate'] ), + 'orderby' => empty( $_GET['orderby'] ) ? $this->attributes['orderby'] : wc_clean( wp_unslash( $_GET['orderby'] ) ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended + ); + + $orderby_value = explode( '-', $query_args['orderby'] ); + $orderby = esc_attr( $orderby_value[0] ); + $order = ! empty( $orderby_value[1] ) ? $orderby_value[1] : strtoupper( $this->attributes['order'] ); + $query_args['orderby'] = $orderby; + $query_args['order'] = $order; + + if ( wc_string_to_bool( $this->attributes['paginate'] ) ) { + $this->attributes['page'] = absint( empty( $_GET['product-page'] ) ? 1 : $_GET['product-page'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + } + + if ( ! empty( $this->attributes['rows'] ) ) { + $this->attributes['limit'] = $this->attributes['columns'] * $this->attributes['rows']; + } + + $ordering_args = WC()->query->get_catalog_ordering_args( $query_args['orderby'], $query_args['order'] ); + $query_args['orderby'] = $ordering_args['orderby']; + $query_args['order'] = $ordering_args['order']; + if ( $ordering_args['meta_key'] ) { + $query_args['meta_key'] = $ordering_args['meta_key']; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + } + $query_args['posts_per_page'] = intval( $this->attributes['limit'] ); + if ( 1 < $this->attributes['page'] ) { + $query_args['paged'] = absint( $this->attributes['page'] ); + } + $query_args['meta_query'] = WC()->query->get_meta_query(); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + $query_args['tax_query'] = array(); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query + + // Visibility. + $this->set_visibility_query_args( $query_args ); + + // SKUs. + $this->set_skus_query_args( $query_args ); + + // IDs. + $this->set_ids_query_args( $query_args ); + + // Set specific types query args. + if ( method_exists( $this, "set_{$this->type}_query_args" ) ) { + $this->{"set_{$this->type}_query_args"}( $query_args ); + } + + // Attributes. + $this->set_attributes_query_args( $query_args ); + + // Categories. + $this->set_categories_query_args( $query_args ); + + // Tags. + $this->set_tags_query_args( $query_args ); + + $query_args = apply_filters( 'woocommerce_shortcode_products_query', $query_args, $this->attributes, $this->type ); + + // Always query only IDs. + $query_args['fields'] = 'ids'; + + return $query_args; + } + + /** + * Set skus query args. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_skus_query_args( &$query_args ) { + if ( ! empty( $this->attributes['skus'] ) ) { + $skus = array_map( 'trim', explode( ',', $this->attributes['skus'] ) ); + $query_args['meta_query'][] = array( + 'key' => '_sku', + 'value' => 1 === count( $skus ) ? $skus[0] : $skus, + 'compare' => 1 === count( $skus ) ? '=' : 'IN', + ); + } + } + + /** + * Set ids query args. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_ids_query_args( &$query_args ) { + if ( ! empty( $this->attributes['ids'] ) ) { + $ids = array_map( 'trim', explode( ',', $this->attributes['ids'] ) ); + + if ( 1 === count( $ids ) ) { + $query_args['p'] = $ids[0]; + } else { + $query_args['post__in'] = $ids; + } + } + } + + /** + * Set attributes query args. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_attributes_query_args( &$query_args ) { + if ( ! empty( $this->attributes['attribute'] ) || ! empty( $this->attributes['terms'] ) ) { + $taxonomy = strstr( $this->attributes['attribute'], 'pa_' ) ? sanitize_title( $this->attributes['attribute'] ) : 'pa_' . sanitize_title( $this->attributes['attribute'] ); + $terms = $this->attributes['terms'] ? array_map( 'sanitize_title', explode( ',', $this->attributes['terms'] ) ) : array(); + $field = 'slug'; + + if ( $terms && is_numeric( $terms[0] ) ) { + $field = 'term_id'; + $terms = array_map( 'absint', $terms ); + // Check numeric slugs. + foreach ( $terms as $term ) { + $the_term = get_term_by( 'slug', $term, $taxonomy ); + if ( false !== $the_term ) { + $terms[] = $the_term->term_id; + } + } + } + + // If no terms were specified get all products that are in the attribute taxonomy. + if ( ! $terms ) { + $terms = get_terms( + array( + 'taxonomy' => $taxonomy, + 'fields' => 'ids', + ) + ); + $field = 'term_id'; + } + + // We always need to search based on the slug as well, this is to accommodate numeric slugs. + $query_args['tax_query'][] = array( + 'taxonomy' => $taxonomy, + 'terms' => $terms, + 'field' => $field, + 'operator' => $this->attributes['terms_operator'], + ); + } + } + + /** + * Set categories query args. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_categories_query_args( &$query_args ) { + if ( ! empty( $this->attributes['category'] ) ) { + $categories = array_map( 'sanitize_title', explode( ',', $this->attributes['category'] ) ); + $field = 'slug'; + + if ( is_numeric( $categories[0] ) ) { + $field = 'term_id'; + $categories = array_map( 'absint', $categories ); + // Check numeric slugs. + foreach ( $categories as $cat ) { + $the_cat = get_term_by( 'slug', $cat, 'product_cat' ); + if ( false !== $the_cat ) { + $categories[] = $the_cat->term_id; + } + } + } + + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_cat', + 'terms' => $categories, + 'field' => $field, + 'operator' => $this->attributes['cat_operator'], + + /* + * When cat_operator is AND, the children categories should be excluded, + * as only products belonging to all the children categories would be selected. + */ + 'include_children' => 'AND' === $this->attributes['cat_operator'] ? false : true, + ); + } + } + + /** + * Set tags query args. + * + * @since 3.3.0 + * @param array $query_args Query args. + */ + protected function set_tags_query_args( &$query_args ) { + if ( ! empty( $this->attributes['tag'] ) ) { + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_tag', + 'terms' => array_map( 'sanitize_title', explode( ',', $this->attributes['tag'] ) ), + 'field' => 'slug', + 'operator' => $this->attributes['tag_operator'], + ); + } + } + + /** + * Set sale products query args. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_sale_products_query_args( &$query_args ) { + $query_args['post__in'] = array_merge( array( 0 ), wc_get_product_ids_on_sale() ); + } + + /** + * Set best selling products query args. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_best_selling_products_query_args( &$query_args ) { + $query_args['meta_key'] = 'total_sales'; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + $query_args['order'] = 'DESC'; + $query_args['orderby'] = 'meta_value_num'; + } + + /** + * Set top rated products query args. + * + * @since 3.6.5 + * @param array $query_args Query args. + */ + protected function set_top_rated_products_query_args( &$query_args ) { + $query_args['meta_key'] = '_wc_average_rating'; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + $query_args['order'] = 'DESC'; + $query_args['orderby'] = 'meta_value_num'; + } + + /** + * Set visibility as hidden. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_visibility_hidden_query_args( &$query_args ) { + $this->custom_visibility = true; + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'terms' => array( 'exclude-from-catalog', 'exclude-from-search' ), + 'field' => 'name', + 'operator' => 'AND', + 'include_children' => false, + ); + } + + /** + * Set visibility as catalog. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_visibility_catalog_query_args( &$query_args ) { + $this->custom_visibility = true; + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'terms' => 'exclude-from-search', + 'field' => 'name', + 'operator' => 'IN', + 'include_children' => false, + ); + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'terms' => 'exclude-from-catalog', + 'field' => 'name', + 'operator' => 'NOT IN', + 'include_children' => false, + ); + } + + /** + * Set visibility as search. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_visibility_search_query_args( &$query_args ) { + $this->custom_visibility = true; + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'terms' => 'exclude-from-catalog', + 'field' => 'name', + 'operator' => 'IN', + 'include_children' => false, + ); + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'terms' => 'exclude-from-search', + 'field' => 'name', + 'operator' => 'NOT IN', + 'include_children' => false, + ); + } + + /** + * Set visibility as featured. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_visibility_featured_query_args( &$query_args ) { + $query_args['tax_query'] = array_merge( $query_args['tax_query'], WC()->query->get_tax_query() ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query + + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'terms' => 'featured', + 'field' => 'name', + 'operator' => 'IN', + 'include_children' => false, + ); + } + + /** + * Set visibility query args. + * + * @since 3.2.0 + * @param array $query_args Query args. + */ + protected function set_visibility_query_args( &$query_args ) { + if ( method_exists( $this, 'set_visibility_' . $this->attributes['visibility'] . '_query_args' ) ) { + $this->{'set_visibility_' . $this->attributes['visibility'] . '_query_args'}( $query_args ); + } else { + $query_args['tax_query'] = array_merge( $query_args['tax_query'], WC()->query->get_tax_query() ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query + } + } + + /** + * Set product as visible when querying for hidden products. + * + * @since 3.2.0 + * @param bool $visibility Product visibility. + * @return bool + */ + public function set_product_as_visible( $visibility ) { + return $this->custom_visibility ? true : $visibility; + } + + /** + * Get wrapper classes. + * + * @since 3.2.0 + * @param int $columns Number of columns. + * @return array + */ + protected function get_wrapper_classes( $columns ) { + $classes = array( 'woocommerce' ); + + if ( 'product' !== $this->type ) { + $classes[] = 'columns-' . $columns; + } + + $classes[] = $this->attributes['class']; + + return $classes; + } + + /** + * Generate and return the transient name for this shortcode based on the query args. + * + * @since 3.3.0 + * @return string + */ + protected function get_transient_name() { + $transient_name = 'wc_product_loop_' . md5( wp_json_encode( $this->query_args ) . $this->type ); + + if ( 'rand' === $this->query_args['orderby'] ) { + // When using rand, we'll cache a number of random queries and pull those to avoid querying rand on each page load. + $rand_index = wp_rand( 0, max( 1, absint( apply_filters( 'woocommerce_product_query_max_rand_cache_count', 5 ) ) ) ); + $transient_name .= $rand_index; + } + + return $transient_name; + } + + /** + * Run the query and return an array of data, including queried ids and pagination information. + * + * @since 3.3.0 + * @return object Object with the following props; ids, per_page, found_posts, max_num_pages, current_page + */ + protected function get_query_results() { + $transient_name = $this->get_transient_name(); + $transient_version = WC_Cache_Helper::get_transient_version( 'product_query' ); + $cache = wc_string_to_bool( $this->attributes['cache'] ) === true; + $transient_value = $cache ? get_transient( $transient_name ) : false; + + if ( isset( $transient_value['value'], $transient_value['version'] ) && $transient_value['version'] === $transient_version ) { + $results = $transient_value['value']; + } else { + $query = new WP_Query( $this->query_args ); + + $paginated = ! $query->get( 'no_found_rows' ); + + $results = (object) array( + 'ids' => wp_parse_id_list( $query->posts ), + 'total' => $paginated ? (int) $query->found_posts : count( $query->posts ), + 'total_pages' => $paginated ? (int) $query->max_num_pages : 1, + 'per_page' => (int) $query->get( 'posts_per_page' ), + 'current_page' => $paginated ? (int) max( 1, $query->get( 'paged', 1 ) ) : 1, + ); + + if ( $cache ) { + $transient_value = array( + 'version' => $transient_version, + 'value' => $results, + ); + set_transient( $transient_name, $transient_value, DAY_IN_SECONDS * 30 ); + } + } + + // Remove ordering query arguments which may have been added by get_catalog_ordering_args. + WC()->query->remove_ordering_args(); + + /** + * Filter shortcode products query results. + * + * @since 4.0.0 + * @param stdClass $results Query results. + * @param WC_Shortcode_Products $this WC_Shortcode_Products instance. + */ + return apply_filters( 'woocommerce_shortcode_products_query_results', $results, $this ); + } + + /** + * Loop over found products. + * + * @since 3.2.0 + * @return string + */ + protected function product_loop() { + $columns = absint( $this->attributes['columns'] ); + $classes = $this->get_wrapper_classes( $columns ); + $products = $this->get_query_results(); + + ob_start(); + + if ( $products && $products->ids ) { + // Prime caches to reduce future queries. + if ( is_callable( '_prime_post_caches' ) ) { + _prime_post_caches( $products->ids ); + } + + // Setup the loop. + wc_setup_loop( + array( + 'columns' => $columns, + 'name' => $this->type, + 'is_shortcode' => true, + 'is_search' => false, + 'is_paginated' => wc_string_to_bool( $this->attributes['paginate'] ), + 'total' => $products->total, + 'total_pages' => $products->total_pages, + 'per_page' => $products->per_page, + 'current_page' => $products->current_page, + ) + ); + + $original_post = $GLOBALS['post']; + + do_action( "woocommerce_shortcode_before_{$this->type}_loop", $this->attributes ); + + // Fire standard shop loop hooks when paginating results so we can show result counts and so on. + if ( wc_string_to_bool( $this->attributes['paginate'] ) ) { + do_action( 'woocommerce_before_shop_loop' ); + } + + woocommerce_product_loop_start(); + + if ( wc_get_loop_prop( 'total' ) ) { + foreach ( $products->ids as $product_id ) { + $GLOBALS['post'] = get_post( $product_id ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + setup_postdata( $GLOBALS['post'] ); + + // Set custom product visibility when quering hidden products. + add_action( 'woocommerce_product_is_visible', array( $this, 'set_product_as_visible' ) ); + + // Render product template. + wc_get_template_part( 'content', 'product' ); + + // Restore product visibility. + remove_action( 'woocommerce_product_is_visible', array( $this, 'set_product_as_visible' ) ); + } + } + + $GLOBALS['post'] = $original_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + woocommerce_product_loop_end(); + + // Fire standard shop loop hooks when paginating results so we can show result counts and so on. + if ( wc_string_to_bool( $this->attributes['paginate'] ) ) { + do_action( 'woocommerce_after_shop_loop' ); + } + + do_action( "woocommerce_shortcode_after_{$this->type}_loop", $this->attributes ); + + wp_reset_postdata(); + wc_reset_loop(); + } else { + do_action( "woocommerce_shortcode_{$this->type}_loop_no_results", $this->attributes ); + } + + return '
    ' . ob_get_clean() . '
    '; + } + + /** + * Order by rating. + * + * @since 3.2.0 + * @param array $args Query args. + * @return array + */ + public static function order_by_rating_post_clauses( $args ) { + global $wpdb; + + $args['where'] .= " AND $wpdb->commentmeta.meta_key = 'rating' "; + $args['join'] .= "LEFT JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID) LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)"; + $args['orderby'] = "$wpdb->commentmeta.meta_value DESC"; + $args['groupby'] = "$wpdb->posts.ID"; + + return $args; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-eleven.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-eleven.php new file mode 100644 index 0000000..fb06a7a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-eleven.php @@ -0,0 +1,56 @@ + 150, + 'single_image_width' => 300, + ) + ); + } + + /** + * Open wrappers. + */ + public static function output_content_wrapper() { + echo '
    '; + } + + /** + * Close wrappers. + */ + public static function output_content_wrapper_end() { + echo '
    '; + } +} + +WC_Twenty_Eleven::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-fifteen.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-fifteen.php new file mode 100644 index 0000000..83e1930 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-fifteen.php @@ -0,0 +1,57 @@ + 200, + 'single_image_width' => 350, + ) + ); + } + + /** + * Open wrappers. + */ + public static function output_content_wrapper() { + echo '
    '; + } + + /** + * Close wrappers. + */ + public static function output_content_wrapper_end() { + echo '
    '; + } +} + +WC_Twenty_Fifteen::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-fourteen.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-fourteen.php new file mode 100644 index 0000000..ce04395 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-fourteen.php @@ -0,0 +1,58 @@ + 150, + 'single_image_width' => 300, + ) + ); + } + + /** + * Open wrappers. + */ + public static function output_content_wrapper() { + echo '
    '; + } + + /** + * Close wrappers. + */ + public static function output_content_wrapper_end() { + echo '
    '; + get_sidebar( 'content' ); + } +} + +WC_Twenty_Fourteen::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-nineteen.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-nineteen.php new file mode 100644 index 0000000..47c1aff --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-nineteen.php @@ -0,0 +1,132 @@ + 300, + 'single_image_width' => 450, + ) + ); + + // Tweak Twenty Nineteen features. + add_action( 'wp', array( __CLASS__, 'tweak_theme_features' ) ); + + // Color scheme CSS + add_filter( 'twentynineteen_custom_colors_css', array( __CLASS__, 'custom_colors_css' ), 10, 3 ); + } + + /** + * Open the Twenty Nineteen wrapper. + */ + public static function output_content_wrapper() { + echo '
    '; + echo '
    '; + } + + /** + * Close the Twenty Nineteen wrapper. + */ + public static function output_content_wrapper_end() { + echo '
    '; + echo '
    '; + } + + /** + * Enqueue CSS for this theme. + * + * @param array $styles Array of registered styles. + * @return array + */ + public static function enqueue_styles( $styles ) { + unset( $styles['woocommerce-general'] ); + + $styles['woocommerce-general'] = array( + 'src' => str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-nineteen.css', + 'deps' => '', + 'version' => Constants::get_constant( 'WC_VERSION' ), + 'media' => 'all', + 'has_rtl' => true, + ); + + return apply_filters( 'woocommerce_twenty_nineteen_styles', $styles ); + } + + /** + * Tweak Twenty Nineteen features. + */ + public static function tweak_theme_features() { + if ( is_woocommerce() ) { + add_filter( 'twentynineteen_can_show_post_thumbnail', '__return_false' ); + } + } + + /** + * Filters Twenty Nineteen custom colors CSS. + * + * @param string $css Base theme colors CSS. + * @param int $primary_color The user's selected color hue. + * @param string $saturation Filtered theme color saturation level. + */ + public static function custom_colors_css( $css, $primary_color, $saturation ) { + if ( function_exists( 'register_block_type' ) && is_admin() ) { + return $css; + } + + $lightness = absint( apply_filters( 'twentynineteen_custom_colors_lightness', 33 ) ); + $lightness = $lightness . '%'; + + $css .= ' + .onsale, + .woocommerce-info, + .woocommerce-store-notice { + background-color: hsl( ' . $primary_color . ', ' . $saturation . ', ' . $lightness . ' ); + } + + .woocommerce-tabs ul li.active a { + color: hsl( ' . $primary_color . ', ' . $saturation . ', ' . $lightness . ' ); + box-shadow: 0 2px 0 hsl( ' . $primary_color . ', ' . $saturation . ', ' . $lightness . ' ); + } + '; + + return $css; + } +} + +WC_Twenty_Nineteen::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-seventeen.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-seventeen.php new file mode 100644 index 0000000..2093d22 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-seventeen.php @@ -0,0 +1,114 @@ + 250, + 'single_image_width' => 350, + ) + ); + } + + /** + * Enqueue CSS for this theme. + * + * @param array $styles Array of registered styles. + * @return array + */ + public static function enqueue_styles( $styles ) { + unset( $styles['woocommerce-general'] ); + + $styles['woocommerce-general'] = array( + 'src' => str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-seventeen.css', + 'deps' => '', + 'version' => Constants::get_constant( 'WC_VERSION' ), + 'media' => 'all', + 'has_rtl' => true, + ); + + return apply_filters( 'woocommerce_twenty_seventeen_styles', $styles ); + } + + /** + * Open the Twenty Seventeen wrapper. + */ + public static function output_content_wrapper() { + echo '
    '; + echo '
    '; + echo '
    '; + } + + /** + * Close the Twenty Seventeen wrapper. + */ + public static function output_content_wrapper_end() { + echo '
    '; + echo '
    '; + get_sidebar(); + echo '
    '; + } + + /** + * Custom colors. + * + * @param string $css Styles. + * @param string $hue Color. + * @param string $saturation Saturation. + * @return string + */ + public static function custom_colors_css( $css, $hue, $saturation ) { + $css .= ' + .colors-custom .select2-container--default .select2-selection--single { + border-color: hsl( ' . $hue . ', ' . $saturation . ', 73% ); + } + .colors-custom .select2-container--default .select2-selection__rendered { + color: hsl( ' . $hue . ', ' . $saturation . ', 40% ); + } + .colors-custom .select2-container--default .select2-selection--single .select2-selection__arrow b { + border-color: hsl( ' . $hue . ', ' . $saturation . ', 40% ) transparent transparent transparent; + } + .colors-custom .select2-container--focus .select2-selection { + border-color: #000; + } + .colors-custom .select2-container--focus .select2-selection--single .select2-selection__arrow b { + border-color: #000 transparent transparent transparent; + } + .colors-custom .select2-container--focus .select2-selection .select2-selection__rendered { + color: #000; + } + '; + return $css; + } +} + +WC_Twenty_Seventeen::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-sixteen.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-sixteen.php new file mode 100644 index 0000000..c9681fa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-sixteen.php @@ -0,0 +1,56 @@ + 250, + 'single_image_width' => 400, + ) + ); + } + + /** + * Open wrappers. + */ + public static function output_content_wrapper() { + echo '
    '; + } + + /** + * Close wrappers. + */ + public static function output_content_wrapper_end() { + echo '
    '; + } +} + +WC_Twenty_Sixteen::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-ten.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-ten.php new file mode 100644 index 0000000..8a9262e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-ten.php @@ -0,0 +1,56 @@ + 200, + 'single_image_width' => 300, + ) + ); + } + + /** + * Open wrappers. + */ + public static function output_content_wrapper() { + echo '
    '; + } + + /** + * Close wrappers. + */ + public static function output_content_wrapper_end() { + echo '
    '; + } +} + +WC_Twenty_Ten::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-thirteen.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-thirteen.php new file mode 100644 index 0000000..4e80b3e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-thirteen.php @@ -0,0 +1,57 @@ + 200, + 'single_image_width' => 300, + ) + ); + } + + /** + * Open wrappers. + */ + public static function output_content_wrapper() { + echo '
    '; + } + + /** + * Close wrappers. + */ + public static function output_content_wrapper_end() { + echo '
    '; + } +} + +WC_Twenty_Thirteen::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-twelve.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-twelve.php new file mode 100644 index 0000000..116dabe --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-twelve.php @@ -0,0 +1,57 @@ + 200, + 'single_image_width' => 300, + ) + ); + } + + /** + * Open wrappers. + */ + public static function output_content_wrapper() { + echo '
    '; + } + + /** + * Close wrappers. + */ + public static function output_content_wrapper_end() { + echo '
    '; + } +} + +WC_Twenty_Twelve::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-twenty-one.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-twenty-one.php new file mode 100644 index 0000000..b7d36f6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-twenty-one.php @@ -0,0 +1,105 @@ + 450, + 'single_image_width' => 600, + ) + ); + + } + + /** + * Open the Twenty Twenty One wrapper. + */ + public static function output_content_wrapper() { + echo '
    '; + echo '
    '; + } + + /** + * Close the Twenty Twenty One wrapper. + */ + public static function output_content_wrapper_end() { + echo '
    '; + echo '
    '; + } + + /** + * Enqueue CSS for this theme. + * + * @param array $styles Array of registered styles. + * @return array + */ + public static function enqueue_styles( $styles ) { + unset( $styles['woocommerce-general'] ); + + $styles['woocommerce-general'] = array( + 'src' => str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-twenty-one.css', + 'deps' => '', + 'version' => Constants::get_constant( 'WC_VERSION' ), + 'media' => 'all', + 'has_rtl' => true, + ); + + return apply_filters( 'woocommerce_twenty_twenty_one_styles', $styles ); + } + + /** + * Enqueue the wp-admin CSS overrides for this theme. + */ + public static function enqueue_admin_styles() { + wp_enqueue_style( + 'woocommerce-twenty-twenty-one-admin', + str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-twenty-one-admin.css', + '', + Constants::get_constant( 'WC_VERSION' ), + 'all' + ); + } + + +} + +WC_Twenty_Twenty_One::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-twenty.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-twenty.php new file mode 100644 index 0000000..47296f6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/theme-support/class-wc-twenty-twenty.php @@ -0,0 +1,107 @@ + 450, + 'single_image_width' => 600, + ) + ); + + // Background color change. + add_action( 'after_setup_theme', array( __CLASS__, 'set_white_background' ), 10 ); + + } + + /** + * Open the Twenty Twenty wrapper. + */ + public static function output_content_wrapper() { + echo '
    '; + echo '
    '; + } + + /** + * Close the Twenty Twenty wrapper. + */ + public static function output_content_wrapper_end() { + echo '
    '; + echo '
    '; + } + + /** + * Set background color to white if it's default, otherwise don't touch it. + */ + public static function set_white_background() { + $background = sanitize_hex_color_no_hash( get_theme_mod( 'background_color' ) ); + $background_default = 'f5efe0'; + + // Don't change user's choice of background color. + if ( ! empty( $background ) && $background !== $background_default ) { + return; + } + + // In case default background is found, change it to white. + set_theme_mod( 'background_color', 'fff' ); + } + + /** + * Enqueue CSS for this theme. + * + * @param array $styles Array of registered styles. + * @return array + */ + public static function enqueue_styles( $styles ) { + unset( $styles['woocommerce-general'] ); + + $styles['woocommerce-general'] = array( + 'src' => str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-twenty.css', + 'deps' => '', + 'version' => Constants::get_constant( 'WC_VERSION' ), + 'media' => 'all', + 'has_rtl' => true, + ); + + return apply_filters( 'woocommerce_twenty_twenty_styles', $styles ); + } + +} + +WC_Twenty_Twenty::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-site-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-site-tracking.php new file mode 100644 index 0000000..74e0621 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-site-tracking.php @@ -0,0 +1,186 @@ + + + + registered['woo-tracks'] ) ) { + return; + } + + $woo_tracks_script = $wp_scripts->registered['woo-tracks']->src; + + ?> + + cap_key ) { + return false; + } + $user_id = $user->ID; + $anon_id = get_user_meta( $user_id, '_woocommerce_tracks_anon_id', true ); + + // If an id is still not found, create one and save it. + if ( ! $anon_id ) { + $anon_id = self::get_anon_id(); + update_user_meta( $user_id, '_woocommerce_tracks_anon_id', $anon_id ); + } + + // Don't set cookie on API requests. + if ( ! Constants::is_true( 'REST_REQUEST' ) && ! Constants::is_true( 'XMLRPC_REQUEST' ) ) { + wc_setcookie( 'tk_ai', $anon_id ); + } + } + + /** + * Record a Tracks event + * + * @param array $event Array of event properties. + * @return bool|WP_Error True on success, WP_Error on failure. + */ + public static function record_event( $event ) { + if ( ! $event instanceof WC_Tracks_Event ) { + $event = new WC_Tracks_Event( $event ); + } + + if ( is_wp_error( $event ) ) { + return $event; + } + + $pixel = $event->build_pixel_url( $event ); + + if ( ! $pixel ) { + return new WP_Error( 'invalid_pixel', 'cannot generate tracks pixel for given input', 400 ); + } + + return self::record_pixel( $pixel ); + } + + /** + * Synchronously request the pixel. + * + * @param string $pixel pixel url and query string. + * @return bool Always returns true. + */ + public static function record_pixel( $pixel ) { + // Add the Request Timestamp and URL terminator just before the HTTP request. + $pixel .= '&_rt=' . self::build_timestamp() . '&_=_'; + + wp_safe_remote_get( + $pixel, + array( + 'blocking' => false, + 'redirection' => 2, + 'httpversion' => '1.1', + 'timeout' => 1, + ) + ); + + return true; + } + + /** + * Create a timestap representing milliseconds since 1970-01-01 + * + * @return string A string representing a timestamp. + */ + public static function build_timestamp() { + $ts = NumberUtil::round( microtime( true ) * 1000 ); + + return number_format( $ts, 0, '', '' ); + } + + /** + * Get a user's identity to send to Tracks. If Jetpack exists, default to its implementation. + * + * @param int $user_id User id. + * @return array Identity properties. + */ + public static function get_identity( $user_id ) { + $jetpack_lib = '/tracks/client.php'; + + if ( class_exists( 'Jetpack' ) && Constants::is_defined( 'JETPACK__VERSION' ) ) { + if ( version_compare( Constants::get_constant( 'JETPACK__VERSION' ), '7.5', '<' ) ) { + if ( file_exists( jetpack_require_lib_dir() . $jetpack_lib ) ) { + include_once jetpack_require_lib_dir() . $jetpack_lib; + if ( function_exists( 'jetpack_tracks_get_identity' ) ) { + return jetpack_tracks_get_identity( $user_id ); + } + } + } else { + $tracking = new Automattic\Jetpack\Tracking(); + return $tracking->tracks_get_identity( $user_id ); + } + } + + // Start with a previously set cookie. + $anon_id = isset( $_COOKIE['tk_ai'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['tk_ai'] ) ) : false; + + // If there is no cookie, apply a saved id. + if ( ! $anon_id ) { + $anon_id = get_user_meta( $user_id, '_woocommerce_tracks_anon_id', true ); + } + + // If an id is still not found, create one and save it. + if ( ! $anon_id ) { + $anon_id = self::get_anon_id(); + + update_user_meta( $user_id, '_woocommerce_tracks_anon_id', $anon_id ); + } + + return array( + '_ut' => 'anon', + '_ui' => $anon_id, + ); + } + + /** + * Grabs the user's anon id from cookies, or generates and sets a new one + * + * @return string An anon id for the user + */ + public static function get_anon_id() { + static $anon_id = null; + + if ( ! isset( $anon_id ) ) { + + // Did the browser send us a cookie? + if ( isset( $_COOKIE['tk_ai'] ) ) { + $anon_id = sanitize_text_field( wp_unslash( $_COOKIE['tk_ai'] ) ); + } else { + + $binary = ''; + + // Generate a new anonId and try to save it in the browser's cookies. + // Note that base64-encoding an 18 character string generates a 24-character anon id. + for ( $i = 0; $i < 18; ++$i ) { + $binary .= chr( wp_rand( 0, 255 ) ); + } + + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode + $anon_id = 'woo:' . base64_encode( $binary ); + } + } + + return $anon_id; + } +} + +WC_Tracks_Client::init(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-tracks-event.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-tracks-event.php new file mode 100644 index 0000000..60b89b5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-tracks-event.php @@ -0,0 +1,167 @@ +error = $_event; + return; + } + + foreach ( $_event as $key => $value ) { + $this->{$key} = $value; + } + } + + /** + * Record Tracks event + * + * @return bool Always returns true. + */ + public function record() { + if ( wp_doing_ajax() || Constants::is_true( 'REST_REQUEST' ) ) { + return WC_Tracks_Client::record_event( $this ); + } + + return WC_Tracks_Footer_Pixel::record_event( $this ); + } + + /** + * Annotate the event with all relevant info. + * + * @param array $event Event arguments. + * @return bool|WP_Error True on success, WP_Error on failure. + */ + public static function validate_and_sanitize( $event ) { + $event = (object) $event; + + // Required. + if ( ! $event->_en ) { + return new WP_Error( 'invalid_event', 'A valid event must be specified via `_en`', 400 ); + } + + // Delete non-routable addresses otherwise geoip will discard the record entirely. + if ( property_exists( $event, '_via_ip' ) && preg_match( '/^192\.168|^10\./', $event->_via_ip ) ) { + unset( $event->_via_ip ); + } + + $validated = array( + 'browser_type' => WC_Tracks_Client::BROWSER_TYPE, + ); + + $_event = (object) array_merge( (array) $event, $validated ); + + // If you want to block property names, do it here. + // Make sure we have an event timestamp. + if ( ! isset( $_event->_ts ) ) { + $_event->_ts = WC_Tracks_Client::build_timestamp(); + } + + return $_event; + } + + /** + * Build a pixel URL that will send a Tracks event when fired. + * On error, returns an empty string (''). + * + * @return string A pixel URL or empty string ('') if there were invalid args. + */ + public function build_pixel_url() { + if ( $this->error ) { + return ''; + } + + $args = get_object_vars( $this ); + + // Request Timestamp and URL Terminator must be added just before the HTTP request or not at all. + unset( $args['_rt'], $args['_'] ); + + $validated = self::validate_and_sanitize( $args ); + + if ( is_wp_error( $validated ) ) { + return ''; + } + + return esc_url_raw( WC_Tracks_Client::PIXEL . '?' . http_build_query( $validated ) ); + } + + /** + * Check if event name is valid. + * + * @param string $name Event name. + * @return false|int + */ + public static function event_name_is_valid( $name ) { + return preg_match( self::EVENT_NAME_REGEX, $name ); + } + + /** + * Check if a property name is valid. + * + * @param string $name Event property. + * @return false|int + */ + public static function prop_name_is_valid( $name ) { + return preg_match( self::PROP_NAME_REGEX, $name ); + } + + /** + * Check event names + * + * @param object $event An event object. + */ + public static function scrutinize_event_names( $event ) { + if ( ! self::event_name_is_valid( $event->_en ) ) { + return; + } + + $allowed_key_names = array( + 'anonId', + 'Browser_Type', + ); + + foreach ( array_keys( (array) $event ) as $key ) { + if ( in_array( $key, $allowed_key_names, true ) ) { + continue; + } + if ( ! self::prop_name_is_valid( $key ) ) { + return; + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-tracks-footer-pixel.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-tracks-footer-pixel.php new file mode 100644 index 0000000..3ae6aa2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-tracks-footer-pixel.php @@ -0,0 +1,113 @@ +add_event( $event ); + + return true; + } + + /** + * Add a Tracks event to the queue. + * + * @param WC_Tracks_Event $event Event to track. + */ + public function add_event( $event ) { + $this->events[] = $event; + } + + /** + * Add events as tracking pixels to page footer. + */ + public function render_tracking_pixels() { + if ( empty( $this->events ) ) { + return; + } + + foreach ( $this->events as $event ) { + $pixel = $event->build_pixel_url(); + + if ( ! $pixel ) { + continue; + } + + echo ''; + } + + $this->events = array(); + } + + /** + * Fire off API calls for events that weren't converted to pixels. + * + * This handles wp_redirect(). + */ + public function send_tracks_requests() { + if ( empty( $this->events ) ) { + return; + } + + foreach ( $this->events as $event ) { + WC_Tracks_Client::record_event( $event ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-tracks.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-tracks.php new file mode 100644 index 0000000..565ef7c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/class-wc-tracks.php @@ -0,0 +1,115 @@ + home_url(), + 'blog_lang' => get_user_locale( $user_id ), + 'blog_id' => class_exists( 'Jetpack_Options' ) ? Jetpack_Options::get_option( 'id' ) : null, + 'products_count' => self::get_products_count(), + ); + set_transient( 'wc_tracks_blog_details', $blog_details, DAY_IN_SECONDS ); + } + return $blog_details; + } + + /** + * Gather details from the request to the server. + * + * @return array Server details. + */ + public static function get_server_details() { + $data = array(); + + $data['_via_ua'] = isset( $_SERVER['HTTP_USER_AGENT'] ) ? wc_clean( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : ''; + $data['_via_ip'] = isset( $_SERVER['REMOTE_ADDR'] ) ? wc_clean( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : ''; + $data['_lg'] = isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ? wc_clean( wp_unslash( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) : ''; + $data['_dr'] = isset( $_SERVER['HTTP_REFERER'] ) ? wc_clean( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : ''; + + $uri = isset( $_SERVER['REQUEST_URI'] ) ? wc_clean( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; + $host = isset( $_SERVER['HTTP_HOST'] ) ? wc_clean( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : ''; + $data['_dl'] = isset( $_SERVER['REQUEST_SCHEME'] ) ? wc_clean( wp_unslash( $_SERVER['REQUEST_SCHEME'] ) ) . '://' . $host . $uri : ''; + + return $data; + } + + /** + * Record an event in Tracks - this is the preferred way to record events from PHP. + * + * @param string $event_name The name of the event. + * @param array $properties Custom properties to send with the event. + * @return bool|WP_Error True for success or WP_Error if the event pixel could not be fired. + */ + public static function record_event( $event_name, $properties = array() ) { + /** + * Don't track users who don't have tracking enabled. + */ + if ( ! WC_Site_Tracking::is_tracking_enabled() ) { + return false; + } + + $user = wp_get_current_user(); + + // We don't want to track user events during unit tests/CI runs. + if ( $user instanceof WP_User && 'wptests_capabilities' === $user->cap_key ) { + return false; + } + $prefixed_event_name = self::PREFIX . $event_name; + + $data = array( + '_en' => $prefixed_event_name, + '_ts' => WC_Tracks_Client::build_timestamp(), + ); + + $server_details = self::get_server_details(); + $identity = WC_Tracks_Client::get_identity( $user->ID ); + $blog_details = self::get_blog_details( $user->ID ); + + // Allow event props to be filtered to enable adding site-wide props. + $filtered_properties = apply_filters( 'woocommerce_tracks_event_properties', $properties, $prefixed_event_name ); + + // Delete _ui and _ut protected properties. + unset( $filtered_properties['_ui'] ); + unset( $filtered_properties['_ut'] ); + + $event_obj = new WC_Tracks_Event( array_merge( $data, $server_details, $identity, $blog_details, $filtered_properties ) ); + + if ( is_wp_error( $event_obj->error ) ) { + return $event_obj->error; + } + + return $event_obj->record(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-admin-setup-wizard-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-admin-setup-wizard-tracking.php new file mode 100644 index 0000000..158904c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-admin-setup-wizard-tracking.php @@ -0,0 +1,176 @@ +queue as $script ) { + if ( in_array( $script, $allowed, true ) ) { + continue; + } + wp_dequeue_script( $script ); + } + } + + /** + * Track when tracking is opted into and OBW has started. + * + * @param string $option Option name. + * @param string $value Option value. + * + * @deprecated 4.6.0 + */ + public function track_start( $option, $value ) { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Track the marketing form on submit. + * + * @deprecated 4.6.0 + */ + public function track_ready_next_steps() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Track various events when a step is saved. + * + * @deprecated 4.6.0 + */ + public function add_step_save_events() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Track store setup and store properties on save. + * + * @deprecated 4.6.0 + */ + public function track_store_setup() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Track payment gateways selected. + * + * @deprecated 4.6.0 + */ + public function track_payments() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Track shipping units and whether or not labels are set. + * + * @deprecated 4.6.0 + */ + public function track_shipping() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Track recommended plugins selected for install. + * + * @deprecated 4.6.0 + */ + public function track_recommended() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Tracks when Jetpack is activated through the OBW. + * + * @deprecated 4.6.0 + */ + public function track_jetpack_activate() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Tracks when last next_steps screen is viewed in the OBW. + * + * @deprecated 4.6.0 + */ + public function track_next_steps() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Track skipped steps. + * + * @deprecated 4.6.0 + */ + public function track_skip_step() { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + } + + /** + * Set the OBW steps inside this class instance. + * + * @param array $steps Array of OBW steps. + * + * @deprecated 4.6.0 + */ + public function set_obw_steps( $steps ) { + _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.6.0', __( 'Onboarding is maintained in WooCommerce Admin.', 'woocommerce' ) ); + $this->steps = $steps; + + return $steps; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-coupon-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-coupon-tracking.php new file mode 100644 index 0000000..c5faffa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-coupon-tracking.php @@ -0,0 +1,39 @@ + $coupon->get_code(), + 'free_shipping' => $coupon->get_free_shipping(), + 'individual_use' => $coupon->get_individual_use(), + 'exclude_sale_items' => $coupon->get_exclude_sale_items(), + 'usage_limits_applied' => 0 < intval( $coupon->get_usage_limit() ) + || 0 < intval( $coupon->get_usage_limit_per_user() ) + || 0 < intval( $coupon->get_limit_usage_to_x_items() ), + ); + + WC_Tracks::record_event( 'coupon_updated', $properties ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-coupons-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-coupons-tracking.php new file mode 100644 index 0000000..cc32e40 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-coupons-tracking.php @@ -0,0 +1,73 @@ +tracks_coupons_bulk_actions(); + + WC_Tracks::record_event( + 'coupons_view', + array( + 'status' => isset( $_GET['post_status'] ) ? sanitize_text_field( wp_unslash( $_GET['post_status'] ) ) : 'all', + ) + ); + + if ( isset( $_GET['filter_action'] ) && 'Filter' === sanitize_text_field( wp_unslash( $_GET['filter_action'] ) ) && isset( $_GET['coupon_type'] ) ) { + WC_Tracks::record_event( + 'coupons_filter', + array( + 'filter' => 'coupon_type', + 'value' => sanitize_text_field( wp_unslash( $_GET['coupon_type'] ) ), + ) + ); + } + + if ( isset( $_GET['s'] ) && 0 < strlen( sanitize_text_field( wp_unslash( $_GET['s'] ) ) ) ) { + WC_Tracks::record_event( 'coupons_search' ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-extensions-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-extensions-tracking.php new file mode 100644 index 0000000..70f582b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-extensions-tracking.php @@ -0,0 +1,79 @@ + empty( $_REQUEST['section'] ) ? '_featured' : wc_clean( wp_unslash( $_REQUEST['section'] ) ), + ); + + if ( ! empty( $_REQUEST['search'] ) ) { + $event = 'extensions_view_search'; + $properties['search_term'] = wc_clean( wp_unslash( $_REQUEST['search'] ) ); + } + // phpcs:enable + + WC_Tracks::record_event( $event, $properties ); + } + + /** + * Send a Tracks even when a Helper connection process is initiated. + */ + public function track_helper_connection_start() { + WC_Tracks::record_event( 'extensions_subscriptions_connect' ); + } + + /** + * Send a Tracks even when a Helper connection process is cancelled. + */ + public function track_helper_connection_cancelled() { + WC_Tracks::record_event( 'extensions_subscriptions_cancelled' ); + } + + /** + * Send a Tracks even when a Helper connection process completed successfully. + */ + public function track_helper_connection_complete() { + WC_Tracks::record_event( 'extensions_subscriptions_connected' ); + } + + /** + * Send a Tracks even when a Helper has been disconnected. + */ + public function track_helper_disconnected() { + WC_Tracks::record_event( 'extensions_subscriptions_disconnect' ); + } + + /** + * Send a Tracks even when Helper subscriptions are refreshed. + */ + public function track_helper_subscriptions_refresh() { + WC_Tracks::record_event( 'extensions_subscriptions_update' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-importer-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-importer-tracking.php new file mode 100644 index 0000000..648424c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-importer-tracking.php @@ -0,0 +1,83 @@ +track_product_importer_start(); + } + + if ( 'done' === $_REQUEST['step'] ) { + return $this->track_product_importer_complete(); + } + // phpcs:enable + } + + /** + * Send a Tracks event when the product importer is started. + * + * @return void + */ + public function track_product_importer_start() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended + if ( ! isset( $_REQUEST['file'] ) || ! isset( $_REQUEST['_wpnonce'] ) ) { + return; + } + + $properties = array( + 'update_existing' => isset( $_REQUEST['update_existing'] ) ? (bool) $_REQUEST['update_existing'] : false, + 'delimiter' => empty( $_REQUEST['delimiter'] ) ? ',' : wc_clean( wp_unslash( $_REQUEST['delimiter'] ) ), + ); + // phpcs:enable + + WC_Tracks::record_event( 'product_import_start', $properties ); + } + + /** + * Send a Tracks event when the product importer has finished. + * + * @return void + */ + public function track_product_importer_complete() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended + if ( ! isset( $_REQUEST['nonce'] ) ) { + return; + } + + $properties = array( + '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, + ); + // phpcs:enable + + WC_Tracks::record_event( 'product_import_complete', $properties ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-order-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-order-tracking.php new file mode 100644 index 0000000..9035cb2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-order-tracking.php @@ -0,0 +1,40 @@ +get_id() ) { + return; + } + $properties = array( + 'current_status' => $order->get_status(), + 'date_created' => $order->get_date_created() ? $order->get_date_created()->format( DateTime::ATOM ) : '', + 'payment_method' => $order->get_payment_method(), + ); + + WC_Tracks::record_event( 'single_order_view', $properties ); + } +} + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-orders-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-orders-tracking.php new file mode 100644 index 0000000..a889074 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-orders-tracking.php @@ -0,0 +1,178 @@ +id ) { + // we are on the order listing page, and query results are being shown. + WC_Tracks::record_event( 'orders_view_search' ); + } + + return $order_ids; + } + + /** + * Send a Tracks event when the Orders page is viewed. + */ + public function track_orders_view() { + if ( isset( $_GET['post_type'] ) && 'shop_order' === wp_unslash( $_GET['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + // phpcs:disable WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput + $properties = array( + 'status' => isset( $_GET['post_status'] ) ? sanitize_text_field( $_GET['post_status'] ) : 'all', + ); + // phpcs:enable + + WC_Tracks::record_event( 'orders_view', $properties ); + } + } + + /** + * Send a Tracks event when an order status is changed. + * + * @param int $id Order id. + * @param string $previous_status the old WooCommerce order status. + * @param string $next_status the new WooCommerce order status. + */ + public function track_order_status_change( $id, $previous_status, $next_status ) { + $order = wc_get_order( $id ); + + $properties = array( + 'order_id' => $id, + 'next_status' => $next_status, + 'previous_status' => $previous_status, + 'date_created' => $order->get_date_created() ? $order->get_date_created()->date( 'Y-m-d' ) : '', + 'payment_method' => $order->get_payment_method(), + 'order_total' => $order->get_total(), + ); + + WC_Tracks::record_event( 'orders_edit_status_change', $properties ); + } + + /** + * Send a Tracks event when an order date is changed. + * + * @param int $id Order id. + */ + public function track_created_date_change( $id ) { + $post_type = get_post_type( $id ); + + if ( 'shop_order' !== $post_type ) { + return; + } + + if ( 'auto-draft' === get_post_status( $id ) ) { + return; + } + + $order = wc_get_order( $id ); + $date_created = $order->get_date_created() ? $order->get_date_created()->date( 'Y-m-d H:i:s' ) : ''; + // phpcs:disable WordPress.Security.NonceVerification + $new_date = sprintf( + '%s %2d:%2d:%2d', + isset( $_POST['order_date'] ) ? wc_clean( wp_unslash( $_POST['order_date'] ) ) : '', + isset( $_POST['order_date_hour'] ) ? wc_clean( wp_unslash( $_POST['order_date_hour'] ) ) : '', + isset( $_POST['order_date_minute'] ) ? wc_clean( wp_unslash( $_POST['order_date_minute'] ) ) : '', + isset( $_POST['order_date_second'] ) ? wc_clean( wp_unslash( $_POST['order_date_second'] ) ) : '' + ); + // phpcs:enable + + if ( $new_date !== $date_created ) { + $properties = array( + 'order_id' => $id, + 'status' => $order->get_status(), + ); + + WC_Tracks::record_event( 'order_edit_date_created', $properties ); + } + } + + /** + * Track order actions taken. + * + * @param int $order_id Order ID. + */ + public function track_order_action( $order_id ) { + // phpcs:disable WordPress.Security.NonceVerification + if ( ! empty( $_POST['wc_order_action'] ) ) { + $order = wc_get_order( $order_id ); + $action = wc_clean( wp_unslash( $_POST['wc_order_action'] ) ); + $properties = array( + 'order_id' => $order_id, + 'status' => $order->get_status(), + 'action' => $action, + ); + + WC_Tracks::record_event( 'order_edit_order_action', $properties ); + } + // phpcs:enable + } + + /** + * Track "add order" button on the Edit Order screen. + */ + public function track_add_order_from_edit() { + // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + if ( isset( $_GET['post_type'] ) && 'shop_order' === wp_unslash( $_GET['post_type'] ) ) { + $referer = wp_get_referer(); + + if ( $referer ) { + $referring_page = wp_parse_url( $referer ); + $referring_args = array(); + $post_edit_page = wp_parse_url( admin_url( 'post.php' ) ); + + if ( ! empty( $referring_page['query'] ) ) { + parse_str( $referring_page['query'], $referring_args ); + } + + // Determine if we arrived from an Order Edit screen. + if ( + $post_edit_page['path'] === $referring_page['path'] && + isset( $referring_args['action'] ) && + 'edit' === $referring_args['action'] && + isset( $referring_args['post'] ) && + 'shop_order' === get_post_type( $referring_args['post'] ) + ) { + WC_Tracks::record_event( 'order_edit_add_order' ); + } + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-products-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-products-tracking.php new file mode 100644 index 0000000..577e1d5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-products-tracking.php @@ -0,0 +1,211 @@ +post_type ) { + return; + } + + $properties = array( + 'product_id' => $product_id, + ); + + WC_Tracks::record_event( 'product_edit', $properties ); + } + + /** + * Track the Update button being clicked on the client side. + * This is needed because `track_product_updated` (using the `edit_post` + * hook) is called in response to a number of other triggers. + * + * @param WP_Post $post The post, not used. + */ + public function track_product_updated_client_side( $post ) { + wc_enqueue_js( + " + if ( $( 'h1.wp-heading-inline' ).text().trim() === '" . __( 'Edit product', 'woocommerce' ) . "') { + var initialStockValue = $( '#_stock' ).val(); + var hasRecordedEvent = false; + + $( '#publish' ).click( function() { + if ( hasRecordedEvent ) { + return; + } + + var currentStockValue = $( '#_stock' ).val(); + var properties = { + product_type: $( '#product-type' ).val(), + is_virtual: $( '#_virtual' ).is( ':checked' ) ? 'Y' : 'N', + is_downloadable: $( '#_downloadable' ).is( ':checked' ) ? 'Y' : 'N', + manage_stock: $( '#_manage_stock' ).is( ':checked' ) ? 'Y' : 'N', + stock_quantity_update: ( initialStockValue != currentStockValue ) ? 'Y' : 'N', + }; + + window.wcTracks.recordEvent( 'product_update', properties ); + hasRecordedEvent = true; + } ); + } + " + ); + } + + /** + * Send a Tracks event when a product is published. + * + * @param string $new_status New post_status. + * @param string $old_status Previous post_status. + * @param object $post WordPress post. + */ + public function track_product_published( $new_status, $old_status, $post ) { + if ( + 'product' !== $post->post_type || + 'publish' !== $new_status || + 'publish' === $old_status + ) { + return; + } + + $properties = array( + 'product_id' => $post->ID, + ); + + WC_Tracks::record_event( 'product_add_publish', $properties ); + } + + /** + * Send a Tracks event when a product category is created. + * + * @param int $category_id Category ID. + */ + public function track_product_category_created( $category_id ) { + // phpcs:disable WordPress.Security.NonceVerification.Missing + // Only track category creation from the edit product screen or the + // category management screen (which both occur via AJAX). + if ( + ! Constants::is_defined( 'DOING_AJAX' ) || + empty( $_POST['action'] ) || + ( + // Product Categories screen. + 'add-tag' !== $_POST['action'] && + // Edit Product screen. + 'add-product_cat' !== $_POST['action'] + ) + ) { + return; + } + + $category = get_term( $category_id, 'product_cat' ); + $properties = array( + 'category_id' => $category_id, + 'parent_id' => $category->parent, + 'page' => ( 'add-tag' === $_POST['action'] ) ? 'categories' : 'product', + ); + // phpcs:enable + + WC_Tracks::record_event( 'product_category_add', $properties ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-settings-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-settings-tracking.php new file mode 100644 index 0000000..c713db5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-settings-tracking.php @@ -0,0 +1,118 @@ +allowed_options[] = $option['id']; + + // Delay attaching this action since it could get fired a lot. + if ( false === has_action( 'update_option', array( $this, 'track_setting_change' ) ) ) { + add_action( 'update_option', array( $this, 'track_setting_change' ), 10, 3 ); + } + } + + /** + * Add WooCommerce option to a list of updated options. + * + * @param string $option_name Option being updated. + * @param mixed $old_value Old value of option. + * @param mixed $new_value New value of option. + */ + public function track_setting_change( $option_name, $old_value, $new_value ) { + // Make sure this is a WooCommerce option. + if ( ! in_array( $option_name, $this->allowed_options, true ) ) { + return; + } + + // Check to make sure the new value is truly different. + // `woocommerce_price_num_decimals` tends to trigger this + // because form values aren't coerced (e.g. '2' vs. 2). + if ( + is_scalar( $old_value ) && + is_scalar( $new_value ) && + (string) $old_value === (string) $new_value + ) { + return; + } + + $this->updated_options[] = $option_name; + } + + /** + * Send a Tracks event for WooCommerce options that changed values. + */ + public function send_settings_change_event() { + global $current_tab; + + if ( empty( $this->updated_options ) ) { + return; + } + + $properties = array( + 'settings' => implode( ',', $this->updated_options ), + ); + + if ( isset( $current_tab ) ) { + $properties['tab'] = $current_tab; + } + + WC_Tracks::record_event( 'settings_change', $properties ); + } + + /** + * Send a Tracks event for WooCommerce settings page views. + */ + public function track_settings_page_view() { + global $current_tab, $current_section; + + $properties = array( + 'tab' => $current_tab, + 'section' => empty( $current_section ) ? null : $current_section, + ); + + WC_Tracks::record_event( 'settings_view', $properties ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-status-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-status-tracking.php new file mode 100644 index 0000000..ce34a05 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/tracks/events/class-wc-status-tracking.php @@ -0,0 +1,48 @@ + $tab, + 'tool_used' => isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : null, + ) + ); + + if ( 'status' === $tab ) { + wc_enqueue_js( + " + $( 'a.debug-report' ).click( function() { + window.wcTracks.recordEvent( 'status_view_reports' ); + } ); + " + ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/traits/trait-wc-item-totals.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/traits/trait-wc-item-totals.php new file mode 100644 index 0000000..4bc8c9c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/traits/trait-wc-item-totals.php @@ -0,0 +1,91 @@ + 'parent', + 'id' => 'term_id', + 'slug' => 'slug', + ); + + /** + * Starts the list before the elements are added. + * + * @see Walker::start_el() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param object $cat Category. + * @param int $depth Depth of category in reference to parents. + * @param array $args Arguments. + * @param int $current_object_id Current object ID. + */ + public function start_el( &$output, $cat, $depth = 0, $args = array(), $current_object_id = 0 ) { + + if ( ! empty( $args['hierarchical'] ) ) { + $pad = str_repeat( ' ', $depth * 3 ); + } else { + $pad = ''; + } + + $cat_name = apply_filters( 'list_product_cats', $cat->name, $cat ); + $value = ( isset( $args['value'] ) && 'id' === $args['value'] ) ? $cat->term_id : $cat->slug; + $output .= "\t\n"; + } + + /** + * Traverse elements to create list from elements. + * + * Display one element if the element doesn't have any children otherwise, + * display the element and its children. Will only traverse up to the max. + * depth and no ignore elements under that depth. It is possible to set the. + * max depth to include all depths, see walk() method. + * + * This method shouldn't be called directly, use the walk() method instead. + * + * @since 2.5.0 + * + * @param object $element Data object. + * @param array $children_elements List of elements to continue traversing. + * @param int $max_depth Max depth to traverse. + * @param int $depth Depth of current element. + * @param array $args Arguments. + * @param string $output Passed by reference. Used to append additional content. + * @return null Null on failure with no changes to parameters. + */ + public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) { + if ( ! $element || ( 0 === $element->count && ! empty( $args[0]['hide_empty'] ) ) ) { + return; + } + parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/walkers/class-wc-product-cat-list-walker.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/walkers/class-wc-product-cat-list-walker.php new file mode 100644 index 0000000..3580184 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/walkers/class-wc-product-cat-list-walker.php @@ -0,0 +1,153 @@ + 'parent', + 'id' => 'term_id', + 'slug' => 'slug', + ); + + /** + * Starts the list before the elements are added. + * + * @see Walker::start_lvl() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param int $depth Depth of category. Used for tab indentation. + * @param array $args Will only append content if style argument value is 'list'. + */ + public function start_lvl( &$output, $depth = 0, $args = array() ) { + if ( 'list' !== $args['style'] ) { + return; + } + + $indent = str_repeat( "\t", $depth ); + $output .= "$indent
      \n"; + } + + /** + * Ends the list of after the elements are added. + * + * @see Walker::end_lvl() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param int $depth Depth of category. Used for tab indentation. + * @param array $args Will only append content if style argument value is 'list'. + */ + public function end_lvl( &$output, $depth = 0, $args = array() ) { + if ( 'list' !== $args['style'] ) { + return; + } + + $indent = str_repeat( "\t", $depth ); + $output .= "$indent
    \n"; + } + + /** + * Start the element output. + * + * @see Walker::start_el() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param object $cat Category. + * @param int $depth Depth of category in reference to parents. + * @param array $args Arguments. + * @param integer $current_object_id Current object ID. + */ + public function start_el( &$output, $cat, $depth = 0, $args = array(), $current_object_id = 0 ) { + $cat_id = intval( $cat->term_id ); + + $output .= '
  • ' . apply_filters( 'list_product_cats', $cat->name, $cat ) . ''; + + if ( $args['show_count'] ) { + $output .= ' (' . $cat->count . ')'; + } + } + + /** + * Ends the element output, if needed. + * + * @see Walker::end_el() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param object $cat Category. + * @param int $depth Depth of category. Not used. + * @param array $args Only uses 'list' for whether should append to output. + */ + public function end_el( &$output, $cat, $depth = 0, $args = array() ) { + $output .= "
  • \n"; + } + + /** + * Traverse elements to create list from elements. + * + * Display one element if the element doesn't have any children otherwise, + * display the element and its children. Will only traverse up to the max. + * depth and no ignore elements under that depth. It is possible to set the. + * max depth to include all depths, see walk() method. + * + * This method shouldn't be called directly, use the walk() method instead. + * + * @since 2.5.0 + * + * @param object $element Data object. + * @param array $children_elements List of elements to continue traversing. + * @param int $max_depth Max depth to traverse. + * @param int $depth Depth of current element. + * @param array $args Arguments. + * @param string $output Passed by reference. Used to append additional content. + * @return null Null on failure with no changes to parameters. + */ + public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) { + if ( ! $element || ( 0 === $element->count && ! empty( $args[0]['hide_empty'] ) ) ) { + return; + } + parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-account-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-account-functions.php new file mode 100644 index 0000000..2d67cad --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-account-functions.php @@ -0,0 +1,422 @@ + 0; + $lost_password_endpoint = get_option( 'woocommerce_myaccount_lost_password_endpoint' ); + + if ( $wc_account_page_exists && ! empty( $lost_password_endpoint ) ) { + return wc_get_endpoint_url( $lost_password_endpoint, '', $wc_account_page_url ); + } else { + return $default_url; + } +} + +add_filter( 'lostpassword_url', 'wc_lostpassword_url', 10, 1 ); + +/** + * Get the link to the edit account details page. + * + * @return string + */ +function wc_customer_edit_account_url() { + $edit_account_url = wc_get_endpoint_url( 'edit-account', '', wc_get_page_permalink( 'myaccount' ) ); + + return apply_filters( 'woocommerce_customer_edit_account_url', $edit_account_url ); +} + +/** + * Get the edit address slug translation. + * + * @param string $id Address ID. + * @param bool $flip Flip the array to make it possible to retrieve the values ​​from both sides. + * + * @return string Address slug i18n. + */ +function wc_edit_address_i18n( $id, $flip = false ) { + $slugs = apply_filters( + 'woocommerce_edit_address_slugs', + array( + 'billing' => sanitize_title( _x( 'billing', 'edit-address-slug', 'woocommerce' ) ), + 'shipping' => sanitize_title( _x( 'shipping', 'edit-address-slug', 'woocommerce' ) ), + ) + ); + + if ( $flip ) { + $slugs = array_flip( $slugs ); + } + + if ( ! isset( $slugs[ $id ] ) ) { + return $id; + } + + return $slugs[ $id ]; +} + +/** + * Get My Account menu items. + * + * @since 2.6.0 + * @return array + */ +function wc_get_account_menu_items() { + $endpoints = array( + 'orders' => get_option( 'woocommerce_myaccount_orders_endpoint', 'orders' ), + 'downloads' => get_option( 'woocommerce_myaccount_downloads_endpoint', 'downloads' ), + 'edit-address' => get_option( 'woocommerce_myaccount_edit_address_endpoint', 'edit-address' ), + 'payment-methods' => get_option( 'woocommerce_myaccount_payment_methods_endpoint', 'payment-methods' ), + 'edit-account' => get_option( 'woocommerce_myaccount_edit_account_endpoint', 'edit-account' ), + 'customer-logout' => get_option( 'woocommerce_logout_endpoint', 'customer-logout' ), + ); + + $items = array( + 'dashboard' => __( 'Dashboard', 'woocommerce' ), + 'orders' => __( 'Orders', 'woocommerce' ), + 'downloads' => __( 'Downloads', 'woocommerce' ), + 'edit-address' => _n( 'Addresses', 'Address', (int) wc_shipping_enabled(), 'woocommerce' ), + 'payment-methods' => __( 'Payment methods', 'woocommerce' ), + 'edit-account' => __( 'Account details', 'woocommerce' ), + 'customer-logout' => __( 'Logout', 'woocommerce' ), + ); + + // Remove missing endpoints. + foreach ( $endpoints as $endpoint_id => $endpoint ) { + if ( empty( $endpoint ) ) { + unset( $items[ $endpoint_id ] ); + } + } + + // Check if payment gateways support add new payment methods. + if ( isset( $items['payment-methods'] ) ) { + $support_payment_methods = false; + foreach ( WC()->payment_gateways->get_available_payment_gateways() as $gateway ) { + if ( $gateway->supports( 'add_payment_method' ) || $gateway->supports( 'tokenization' ) ) { + $support_payment_methods = true; + break; + } + } + + if ( ! $support_payment_methods ) { + unset( $items['payment-methods'] ); + } + } + + return apply_filters( 'woocommerce_account_menu_items', $items, $endpoints ); +} + +/** + * Get account menu item classes. + * + * @since 2.6.0 + * @param string $endpoint Endpoint. + * @return string + */ +function wc_get_account_menu_item_classes( $endpoint ) { + global $wp; + + $classes = array( + 'woocommerce-MyAccount-navigation-link', + 'woocommerce-MyAccount-navigation-link--' . $endpoint, + ); + + // Set current item class. + $current = isset( $wp->query_vars[ $endpoint ] ); + if ( 'dashboard' === $endpoint && ( isset( $wp->query_vars['page'] ) || empty( $wp->query_vars ) ) ) { + $current = true; // Dashboard is not an endpoint, so needs a custom check. + } elseif ( 'orders' === $endpoint && isset( $wp->query_vars['view-order'] ) ) { + $current = true; // When looking at individual order, highlight Orders list item (to signify where in the menu the user currently is). + } elseif ( 'payment-methods' === $endpoint && isset( $wp->query_vars['add-payment-method'] ) ) { + $current = true; + } + + if ( $current ) { + $classes[] = 'is-active'; + } + + $classes = apply_filters( 'woocommerce_account_menu_item_classes', $classes, $endpoint ); + + return implode( ' ', array_map( 'sanitize_html_class', $classes ) ); +} + +/** + * Get account endpoint URL. + * + * @since 2.6.0 + * @param string $endpoint Endpoint. + * @return string + */ +function wc_get_account_endpoint_url( $endpoint ) { + if ( 'dashboard' === $endpoint ) { + return wc_get_page_permalink( 'myaccount' ); + } + + if ( 'customer-logout' === $endpoint ) { + return wc_logout_url(); + } + + return wc_get_endpoint_url( $endpoint, '', wc_get_page_permalink( 'myaccount' ) ); +} + +/** + * Get My Account > Orders columns. + * + * @since 2.6.0 + * @return array + */ +function wc_get_account_orders_columns() { + $columns = apply_filters( + 'woocommerce_account_orders_columns', + array( + 'order-number' => __( 'Order', 'woocommerce' ), + 'order-date' => __( 'Date', 'woocommerce' ), + 'order-status' => __( 'Status', 'woocommerce' ), + 'order-total' => __( 'Total', 'woocommerce' ), + 'order-actions' => __( 'Actions', 'woocommerce' ), + ) + ); + + // Deprecated filter since 2.6.0. + return apply_filters( 'woocommerce_my_account_my_orders_columns', $columns ); +} + +/** + * Get My Account > Downloads columns. + * + * @since 2.6.0 + * @return array + */ +function wc_get_account_downloads_columns() { + $columns = apply_filters( + 'woocommerce_account_downloads_columns', + array( + 'download-product' => __( 'Product', 'woocommerce' ), + 'download-remaining' => __( 'Downloads remaining', 'woocommerce' ), + 'download-expires' => __( 'Expires', 'woocommerce' ), + 'download-file' => __( 'Download', 'woocommerce' ), + 'download-actions' => ' ', + ) + ); + + if ( ! has_filter( 'woocommerce_account_download_actions' ) ) { + unset( $columns['download-actions'] ); + } + + return $columns; +} + +/** + * Get My Account > Payment methods columns. + * + * @since 2.6.0 + * @return array + */ +function wc_get_account_payment_methods_columns() { + return apply_filters( + 'woocommerce_account_payment_methods_columns', + array( + 'method' => __( 'Method', 'woocommerce' ), + 'expires' => __( 'Expires', 'woocommerce' ), + 'actions' => ' ', + ) + ); +} + +/** + * Get My Account > Payment methods types + * + * @since 2.6.0 + * @return array + */ +function wc_get_account_payment_methods_types() { + return apply_filters( + 'woocommerce_payment_methods_types', + array( + 'cc' => __( 'Credit card', 'woocommerce' ), + 'echeck' => __( 'eCheck', 'woocommerce' ), + ) + ); +} + +/** + * Get account orders actions. + * + * @since 3.2.0 + * @param int|WC_Order $order Order instance or ID. + * @return array + */ +function wc_get_account_orders_actions( $order ) { + if ( ! is_object( $order ) ) { + $order_id = absint( $order ); + $order = wc_get_order( $order_id ); + } + + $actions = array( + 'pay' => array( + 'url' => $order->get_checkout_payment_url(), + 'name' => __( 'Pay', 'woocommerce' ), + ), + 'view' => array( + 'url' => $order->get_view_order_url(), + 'name' => __( 'View', 'woocommerce' ), + ), + 'cancel' => array( + 'url' => $order->get_cancel_order_url( wc_get_page_permalink( 'myaccount' ) ), + 'name' => __( 'Cancel', 'woocommerce' ), + ), + ); + + if ( ! $order->needs_payment() ) { + unset( $actions['pay'] ); + } + + if ( ! in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ), true ) ) { + unset( $actions['cancel'] ); + } + + return apply_filters( 'woocommerce_my_account_my_orders_actions', $actions, $order ); +} + +/** + * Get account formatted address. + * + * @since 3.2.0 + * @param string $address_type Address type. + * Accepts: 'billing' or 'shipping'. + * Default to 'billing'. + * @param int $customer_id Customer ID. + * Default to 0. + * @return string + */ +function wc_get_account_formatted_address( $address_type = 'billing', $customer_id = 0 ) { + $getter = "get_{$address_type}"; + $address = array(); + + if ( 0 === $customer_id ) { + $customer_id = get_current_user_id(); + } + + $customer = new WC_Customer( $customer_id ); + + if ( is_callable( array( $customer, $getter ) ) ) { + $address = $customer->$getter(); + unset( $address['email'], $address['tel'] ); + } + + return WC()->countries->get_formatted_address( apply_filters( 'woocommerce_my_account_my_address_formatted_address', $address, $customer->get_id(), $address_type ) ); +} + +/** + * Returns an array of a user's saved payments list for output on the account tab. + * + * @since 2.6 + * @param array $list List of payment methods passed from wc_get_customer_saved_methods_list(). + * @param int $customer_id The customer to fetch payment methods for. + * @return array Filtered list of customers payment methods. + */ +function wc_get_account_saved_payment_methods_list( $list, $customer_id ) { + $payment_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id ); + foreach ( $payment_tokens as $payment_token ) { + $delete_url = wc_get_endpoint_url( 'delete-payment-method', $payment_token->get_id() ); + $delete_url = wp_nonce_url( $delete_url, 'delete-payment-method-' . $payment_token->get_id() ); + $set_default_url = wc_get_endpoint_url( 'set-default-payment-method', $payment_token->get_id() ); + $set_default_url = wp_nonce_url( $set_default_url, 'set-default-payment-method-' . $payment_token->get_id() ); + + $type = strtolower( $payment_token->get_type() ); + $list[ $type ][] = array( + 'method' => array( + 'gateway' => $payment_token->get_gateway_id(), + ), + 'expires' => esc_html__( 'N/A', 'woocommerce' ), + 'is_default' => $payment_token->is_default(), + 'actions' => array( + 'delete' => array( + 'url' => $delete_url, + 'name' => esc_html__( 'Delete', 'woocommerce' ), + ), + ), + ); + $key = key( array_slice( $list[ $type ], -1, 1, true ) ); + + if ( ! $payment_token->is_default() ) { + $list[ $type ][ $key ]['actions']['default'] = array( + 'url' => $set_default_url, + 'name' => esc_html__( 'Make default', 'woocommerce' ), + ); + } + + $list[ $type ][ $key ] = apply_filters( 'woocommerce_payment_methods_list_item', $list[ $type ][ $key ], $payment_token ); + } + return $list; +} + +add_filter( 'woocommerce_saved_payment_methods_list', 'wc_get_account_saved_payment_methods_list', 10, 2 ); + +/** + * Controls the output for credit cards on the my account page. + * + * @since 2.6 + * @param array $item Individual list item from woocommerce_saved_payment_methods_list. + * @param WC_Payment_Token $payment_token The payment token associated with this method entry. + * @return array Filtered item. + */ +function wc_get_account_saved_payment_methods_list_item_cc( $item, $payment_token ) { + if ( 'cc' !== strtolower( $payment_token->get_type() ) ) { + return $item; + } + + $card_type = $payment_token->get_card_type(); + $item['method']['last4'] = $payment_token->get_last4(); + $item['method']['brand'] = ( ! empty( $card_type ) ? ucfirst( $card_type ) : esc_html__( 'Credit card', 'woocommerce' ) ); + $item['expires'] = $payment_token->get_expiry_month() . '/' . substr( $payment_token->get_expiry_year(), -2 ); + + return $item; +} + +add_filter( 'woocommerce_payment_methods_list_item', 'wc_get_account_saved_payment_methods_list_item_cc', 10, 2 ); + +/** + * Controls the output for eChecks on the my account page. + * + * @since 2.6 + * @param array $item Individual list item from woocommerce_saved_payment_methods_list. + * @param WC_Payment_Token $payment_token The payment token associated with this method entry. + * @return array Filtered item. + */ +function wc_get_account_saved_payment_methods_list_item_echeck( $item, $payment_token ) { + if ( 'echeck' !== strtolower( $payment_token->get_type() ) ) { + return $item; + } + + $item['method']['last4'] = $payment_token->get_last4(); + $item['method']['brand'] = esc_html__( 'eCheck', 'woocommerce' ); + + return $item; +} + +add_filter( 'woocommerce_payment_methods_list_item', 'wc_get_account_saved_payment_methods_list_item_echeck', 10, 2 ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-attribute-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-attribute-functions.php new file mode 100644 index 0000000..535a719 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-attribute-functions.php @@ -0,0 +1,734 @@ +get_results( "SELECT * FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_name != '' ORDER BY attribute_name ASC;" ); + + set_transient( 'wc_attribute_taxonomies', $raw_attribute_taxonomies ); + } + + /** + * Filter attribute taxonomies. + * + * @param array $attribute_taxonomies Results of the DB query. Each taxonomy is an object. + */ + $raw_attribute_taxonomies = (array) array_filter( apply_filters( 'woocommerce_attribute_taxonomies', $raw_attribute_taxonomies ) ); + + // Index by ID for easer lookups. + $attribute_taxonomies = array(); + + foreach ( $raw_attribute_taxonomies as $result ) { + $attribute_taxonomies[ 'id:' . $result->attribute_id ] = $result; + } + + wp_cache_set( $cache_key, $attribute_taxonomies, 'woocommerce-attributes' ); + + return $attribute_taxonomies; +} + +/** + * Get (cached) attribute taxonomy ID and name pairs. + * + * @since 3.6.0 + * @return array + */ +function wc_get_attribute_taxonomy_ids() { + $prefix = WC_Cache_Helper::get_cache_prefix( 'woocommerce-attributes' ); + $cache_key = $prefix . 'ids'; + $cache_value = wp_cache_get( $cache_key, 'woocommerce-attributes' ); + + if ( $cache_value ) { + return $cache_value; + } + + $taxonomy_ids = array_map( 'absint', wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_id', 'attribute_name' ) ); + + wp_cache_set( $cache_key, $taxonomy_ids, 'woocommerce-attributes' ); + + return $taxonomy_ids; +} + +/** + * Get (cached) attribute taxonomy label and name pairs. + * + * @since 3.6.0 + * @return array + */ +function wc_get_attribute_taxonomy_labels() { + $prefix = WC_Cache_Helper::get_cache_prefix( 'woocommerce-attributes' ); + $cache_key = $prefix . 'labels'; + $cache_value = wp_cache_get( $cache_key, 'woocommerce-attributes' ); + + if ( $cache_value ) { + return $cache_value; + } + + $taxonomy_labels = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_name' ); + + wp_cache_set( $cache_key, $taxonomy_labels, 'woocommerce-attributes' ); + + return $taxonomy_labels; +} + +/** + * Get a product attribute name. + * + * @param string $attribute_name Attribute name. + * @return string + */ +function wc_attribute_taxonomy_name( $attribute_name ) { + return $attribute_name ? 'pa_' . wc_sanitize_taxonomy_name( $attribute_name ) : ''; +} + +/** + * Get the attribute name used when storing values in post meta. + * + * @since 2.6.0 + * @param string $attribute_name Attribute name. + * @return string + */ +function wc_variation_attribute_name( $attribute_name ) { + return 'attribute_' . sanitize_title( $attribute_name ); +} + +/** + * Get a product attribute name by ID. + * + * @since 2.4.0 + * @param int $attribute_id Attribute ID. + * @return string Return an empty string if attribute doesn't exist. + */ +function wc_attribute_taxonomy_name_by_id( $attribute_id ) { + $taxonomy_ids = wc_get_attribute_taxonomy_ids(); + $attribute_name = (string) array_search( $attribute_id, $taxonomy_ids, true ); + return wc_attribute_taxonomy_name( $attribute_name ); +} + +/** + * Get a product attribute ID by name. + * + * @since 2.6.0 + * @param string $name Attribute name. + * @return int + */ +function wc_attribute_taxonomy_id_by_name( $name ) { + $name = wc_attribute_taxonomy_slug( $name ); + $taxonomy_ids = wc_get_attribute_taxonomy_ids(); + + return isset( $taxonomy_ids[ $name ] ) ? $taxonomy_ids[ $name ] : 0; +} + +/** + * Get a product attributes label. + * + * @param string $name Attribute name. + * @param WC_Product $product Product data. + * @return string + */ +function wc_attribute_label( $name, $product = '' ) { + if ( taxonomy_is_product_attribute( $name ) ) { + $slug = wc_attribute_taxonomy_slug( $name ); + $all_labels = wc_get_attribute_taxonomy_labels(); + $label = isset( $all_labels[ $slug ] ) ? $all_labels[ $slug ] : $slug; + } elseif ( $product ) { + if ( $product->is_type( 'variation' ) ) { + $product = wc_get_product( $product->get_parent_id() ); + } + $attributes = array(); + + if ( false !== $product ) { + $attributes = $product->get_attributes(); + } + + // Attempt to get label from product, as entered by the user. + if ( $attributes && isset( $attributes[ sanitize_title( $name ) ] ) ) { + $label = $attributes[ sanitize_title( $name ) ]->get_name(); + } else { + $label = $name; + } + } else { + $label = $name; + } + + return apply_filters( 'woocommerce_attribute_label', $label, $name, $product ); +} + +/** + * Get a product attributes orderby setting. + * + * @param string $name Attribute name. + * @return string + */ +function wc_attribute_orderby( $name ) { + $name = wc_attribute_taxonomy_slug( $name ); + $id = wc_attribute_taxonomy_id_by_name( $name ); + $taxonomies = wc_get_attribute_taxonomies(); + + return apply_filters( 'woocommerce_attribute_orderby', isset( $taxonomies[ 'id:' . $id ] ) ? $taxonomies[ 'id:' . $id ]->attribute_orderby : 'menu_order', $name ); +} + +/** + * Get an array of product attribute taxonomies. + * + * @return array + */ +function wc_get_attribute_taxonomy_names() { + $taxonomy_names = array(); + $attribute_taxonomies = wc_get_attribute_taxonomies(); + if ( ! empty( $attribute_taxonomies ) ) { + foreach ( $attribute_taxonomies as $tax ) { + $taxonomy_names[] = wc_attribute_taxonomy_name( $tax->attribute_name ); + } + } + return $taxonomy_names; +} + +/** + * Get attribute types. + * + * @since 2.4.0 + * @return array + */ +function wc_get_attribute_types() { + return (array) apply_filters( + 'product_attributes_type_selector', + array( + 'select' => __( 'Select', 'woocommerce' ), + ) + ); +} + +/** + * Check if there are custom attribute types. + * + * @since 3.3.2 + * @return bool True if there are custom types, otherwise false. + */ +function wc_has_custom_attribute_types() { + $types = wc_get_attribute_types(); + + return 1 < count( $types ) || ! array_key_exists( 'select', $types ); +} + +/** + * Get attribute type label. + * + * @since 3.0.0 + * @param string $type Attribute type slug. + * @return string + */ +function wc_get_attribute_type_label( $type ) { + $types = wc_get_attribute_types(); + + return isset( $types[ $type ] ) ? $types[ $type ] : __( 'Select', 'woocommerce' ); +} + +/** + * Check if attribute name is reserved. + * https://codex.wordpress.org/Function_Reference/register_taxonomy#Reserved_Terms. + * + * @since 2.4.0 + * @param string $attribute_name Attribute name. + * @return bool + */ +function wc_check_if_attribute_name_is_reserved( $attribute_name ) { + // Forbidden attribute names. + $reserved_terms = array( + 'attachment', + 'attachment_id', + 'author', + 'author_name', + 'calendar', + 'cat', + 'category', + 'category__and', + 'category__in', + 'category__not_in', + 'category_name', + 'comments_per_page', + 'comments_popup', + 'cpage', + 'day', + 'debug', + 'error', + 'exact', + 'feed', + 'hour', + 'link_category', + 'm', + 'minute', + 'monthnum', + 'more', + 'name', + 'nav_menu', + 'nopaging', + 'offset', + 'order', + 'orderby', + 'p', + 'page', + 'page_id', + 'paged', + 'pagename', + 'pb', + 'perm', + 'post', + 'post__in', + 'post__not_in', + 'post_format', + 'post_mime_type', + 'post_status', + 'post_tag', + 'post_type', + 'posts', + 'posts_per_archive_page', + 'posts_per_page', + 'preview', + 'robots', + 's', + 'search', + 'second', + 'sentence', + 'showposts', + 'static', + 'subpost', + 'subpost_id', + 'tag', + 'tag__and', + 'tag__in', + 'tag__not_in', + 'tag_id', + 'tag_slug__and', + 'tag_slug__in', + 'taxonomy', + 'tb', + 'term', + 'type', + 'w', + 'withcomments', + 'withoutcomments', + 'year', + ); + + return in_array( $attribute_name, $reserved_terms, true ); +} + +/** + * Callback for array filter to get visible only. + * + * @since 3.0.0 + * @param WC_Product_Attribute $attribute Attribute data. + * @return bool + */ +function wc_attributes_array_filter_visible( $attribute ) { + return $attribute && is_a( $attribute, 'WC_Product_Attribute' ) && $attribute->get_visible() && ( ! $attribute->is_taxonomy() || taxonomy_exists( $attribute->get_name() ) ); +} + +/** + * Callback for array filter to get variation attributes only. + * + * @since 3.0.0 + * @param WC_Product_Attribute $attribute Attribute data. + * @return bool + */ +function wc_attributes_array_filter_variation( $attribute ) { + return $attribute && is_a( $attribute, 'WC_Product_Attribute' ) && $attribute->get_variation(); +} + +/** + * Check if an attribute is included in the attributes area of a variation name. + * + * @since 3.0.2 + * @param string $attribute Attribute value to check for. + * @param string $name Product name to check in. + * @return bool + */ +function wc_is_attribute_in_product_name( $attribute, $name ) { + $is_in_name = stristr( $name, ' ' . $attribute . ',' ) || 0 === stripos( strrev( $name ), strrev( ' ' . $attribute ) ); + return apply_filters( 'woocommerce_is_attribute_in_product_name', $is_in_name, $attribute, $name ); +} + +/** + * Callback for array filter to get default attributes. Will allow for '0' string values, but regard all other + * class PHP FALSE equivalents normally. + * + * @since 3.1.0 + * @param mixed $attribute Attribute being considered for exclusion from parent array. + * @return bool + */ +function wc_array_filter_default_attributes( $attribute ) { + return is_scalar( $attribute ) && ( ! empty( $attribute ) || '0' === $attribute ); +} + +/** + * Get attribute data by ID. + * + * @since 3.2.0 + * @param int $id Attribute ID. + * @return stdClass|null + */ +function wc_get_attribute( $id ) { + $attributes = wc_get_attribute_taxonomies(); + + if ( ! isset( $attributes[ 'id:' . $id ] ) ) { + return null; + } + + $data = $attributes[ 'id:' . $id ]; + $attribute = new stdClass(); + $attribute->id = (int) $data->attribute_id; + $attribute->name = $data->attribute_label; + $attribute->slug = wc_attribute_taxonomy_name( $data->attribute_name ); + $attribute->type = $data->attribute_type; + $attribute->order_by = $data->attribute_orderby; + $attribute->has_archives = (bool) $data->attribute_public; + return $attribute; +} + +/** + * Create attribute. + * + * @since 3.2.0 + * @param array $args Attribute arguments { + * Array of attribute parameters. + * + * @type int $id Unique identifier, used to update an attribute. + * @type string $name Attribute name. Always required. + * @type string $slug Attribute alphanumeric identifier. + * @type string $type Type of attribute. + * Core by default accepts: 'select' and 'text'. + * Default to 'select'. + * @type string $order_by Sort order. + * Accepts: 'menu_order', 'name', 'name_num' and 'id'. + * Default to 'menu_order'. + * @type bool $has_archives Enable or disable attribute archives. False by default. + * } + * @return int|WP_Error + */ +function wc_create_attribute( $args ) { + global $wpdb; + + $args = wp_unslash( $args ); + $id = ! empty( $args['id'] ) ? intval( $args['id'] ) : 0; + $format = array( '%s', '%s', '%s', '%s', '%d' ); + + // Name is required. + if ( empty( $args['name'] ) ) { + return new WP_Error( 'missing_attribute_name', __( 'Please, provide an attribute name.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Set the attribute slug. + if ( empty( $args['slug'] ) ) { + $slug = wc_sanitize_taxonomy_name( $args['name'] ); + } else { + $slug = preg_replace( '/^pa\_/', '', wc_sanitize_taxonomy_name( $args['slug'] ) ); + } + + // Validate slug. + if ( strlen( $slug ) >= 28 ) { + /* translators: %s: attribute slug */ + return new WP_Error( 'invalid_product_attribute_slug_too_long', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } elseif ( wc_check_if_attribute_name_is_reserved( $slug ) ) { + /* translators: %s: attribute slug */ + return new WP_Error( 'invalid_product_attribute_slug_reserved_name', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } elseif ( ( 0 === $id && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) || ( isset( $args['old_slug'] ) && $args['old_slug'] !== $slug && taxonomy_exists( wc_attribute_taxonomy_name( $slug ) ) ) ) { + /* translators: %s: attribute slug */ + return new WP_Error( 'invalid_product_attribute_slug_already_exists', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), $slug ), array( 'status' => 400 ) ); + } + + // Validate type. + if ( empty( $args['type'] ) || ! array_key_exists( $args['type'], wc_get_attribute_types() ) ) { + $args['type'] = 'select'; + } + + // Validate order by. + if ( empty( $args['order_by'] ) || ! in_array( $args['order_by'], array( 'menu_order', 'name', 'name_num', 'id' ), true ) ) { + $args['order_by'] = 'menu_order'; + } + + $data = array( + 'attribute_label' => $args['name'], + 'attribute_name' => $slug, + 'attribute_type' => $args['type'], + 'attribute_orderby' => $args['order_by'], + 'attribute_public' => isset( $args['has_archives'] ) ? (int) $args['has_archives'] : 0, + ); + + // Create or update. + if ( 0 === $id ) { + $results = $wpdb->insert( + $wpdb->prefix . 'woocommerce_attribute_taxonomies', + $data, + $format + ); + + if ( is_wp_error( $results ) ) { + return new WP_Error( 'cannot_create_attribute', $results->get_error_message(), array( 'status' => 400 ) ); + } + + $id = $wpdb->insert_id; + + /** + * Attribute added. + * + * @param int $id Added attribute ID. + * @param array $data Attribute data. + */ + do_action( 'woocommerce_attribute_added', $id, $data ); + } else { + $results = $wpdb->update( + $wpdb->prefix . 'woocommerce_attribute_taxonomies', + $data, + array( 'attribute_id' => $id ), + $format, + array( '%d' ) + ); + + if ( false === $results ) { + return new WP_Error( 'cannot_update_attribute', __( 'Could not update the attribute.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + // Set old slug to check for database changes. + $old_slug = ! empty( $args['old_slug'] ) ? wc_sanitize_taxonomy_name( $args['old_slug'] ) : $slug; + + /** + * Attribute updated. + * + * @param int $id Added attribute ID. + * @param array $data Attribute data. + * @param string $old_slug Attribute old name. + */ + do_action( 'woocommerce_attribute_updated', $id, $data, $old_slug ); + + if ( $old_slug !== $slug ) { + // Update taxonomies in the wp term taxonomy table. + $wpdb->update( + $wpdb->term_taxonomy, + array( 'taxonomy' => wc_attribute_taxonomy_name( $data['attribute_name'] ) ), + array( 'taxonomy' => 'pa_' . $old_slug ) + ); + + // Update taxonomy ordering term meta. + $wpdb->update( + $wpdb->termmeta, + array( 'meta_key' => 'order_pa_' . sanitize_title( $data['attribute_name'] ) ), // WPCS: slow query ok. + array( 'meta_key' => 'order_pa_' . sanitize_title( $old_slug ) ) // WPCS: slow query ok. + ); + + // Update product attributes which use this taxonomy. + $old_taxonomy_name = 'pa_' . $old_slug; + $new_taxonomy_name = 'pa_' . $data['attribute_name']; + $old_attribute_key = sanitize_title( $old_taxonomy_name ); // @see WC_Product::set_attributes(). + $new_attribute_key = sanitize_title( $new_taxonomy_name ); // @see WC_Product::set_attributes(). + $metadatas = $wpdb->get_results( + $wpdb->prepare( + "SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_product_attributes' AND meta_value LIKE %s", + '%' . $wpdb->esc_like( $old_taxonomy_name ) . '%' + ), + ARRAY_A + ); + foreach ( $metadatas as $metadata ) { + $product_id = $metadata['post_id']; + $unserialized_data = maybe_unserialize( $metadata['meta_value'] ); + + if ( ! $unserialized_data || ! is_array( $unserialized_data ) || ! isset( $unserialized_data[ $old_attribute_key ] ) ) { + continue; + } + + $unserialized_data[ $new_attribute_key ] = $unserialized_data[ $old_attribute_key ]; + unset( $unserialized_data[ $old_attribute_key ] ); + $unserialized_data[ $new_attribute_key ]['name'] = $new_taxonomy_name; + update_post_meta( $product_id, '_product_attributes', wp_slash( $unserialized_data ) ); + } + + // Update variations which use this taxonomy. + $wpdb->update( + $wpdb->postmeta, + array( 'meta_key' => 'attribute_pa_' . sanitize_title( $data['attribute_name'] ) ), // WPCS: slow query ok. + array( 'meta_key' => 'attribute_pa_' . sanitize_title( $old_slug ) ) // WPCS: slow query ok. + ); + } + } + + // Clear cache and flush rewrite rules. + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); + delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); + + return $id; +} + +/** + * Update an attribute. + * + * For available args see wc_create_attribute(). + * + * @since 3.2.0 + * @param int $id Attribute ID. + * @param array $args Attribute arguments. + * @return int|WP_Error + */ +function wc_update_attribute( $id, $args ) { + global $wpdb; + + $attribute = wc_get_attribute( $id ); + + $args['id'] = $attribute ? $attribute->id : 0; + + if ( $args['id'] && empty( $args['name'] ) ) { + $args['name'] = $attribute->name; + } + + $args['old_slug'] = $wpdb->get_var( + $wpdb->prepare( + " + SELECT attribute_name + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", + $args['id'] + ) + ); + + return wc_create_attribute( $args ); +} + +/** + * Delete attribute by ID. + * + * @since 3.2.0 + * @param int $id Attribute ID. + * @return bool + */ +function wc_delete_attribute( $id ) { + global $wpdb; + + $name = $wpdb->get_var( + $wpdb->prepare( + " + SELECT attribute_name + FROM {$wpdb->prefix}woocommerce_attribute_taxonomies + WHERE attribute_id = %d + ", + $id + ) + ); + + $taxonomy = wc_attribute_taxonomy_name( $name ); + + /** + * Before deleting an attribute. + * + * @param int $id Attribute ID. + * @param string $name Attribute name. + * @param string $taxonomy Attribute taxonomy name. + */ + do_action( 'woocommerce_before_attribute_delete', $id, $name, $taxonomy ); + + if ( $name && $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = %d", $id ) ) ) { + if ( taxonomy_exists( $taxonomy ) ) { + $terms = get_terms( $taxonomy, 'orderby=name&hide_empty=0' ); + foreach ( $terms as $term ) { + wp_delete_term( $term->term_id, $taxonomy ); + } + } + + /** + * After deleting an attribute. + * + * @param int $id Attribute ID. + * @param string $name Attribute name. + * @param string $taxonomy Attribute taxonomy name. + */ + do_action( 'woocommerce_attribute_deleted', $id, $name, $taxonomy ); + wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' ); + delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); + + return true; + } + + return false; +} + +/** + * Get an unprefixed product attribute name. + * + * @since 3.6.0 + * + * @param string $attribute_name Attribute name. + * @return string + */ +function wc_attribute_taxonomy_slug( $attribute_name ) { + $prefix = WC_Cache_Helper::get_cache_prefix( 'woocommerce-attributes' ); + $cache_key = $prefix . 'slug-' . $attribute_name; + $cache_value = wp_cache_get( $cache_key, 'woocommerce-attributes' ); + + if ( $cache_value ) { + return $cache_value; + } + + $attribute_name = wc_sanitize_taxonomy_name( $attribute_name ); + $attribute_slug = 0 === strpos( $attribute_name, 'pa_' ) ? substr( $attribute_name, 3 ) : $attribute_name; + wp_cache_set( $cache_key, $attribute_slug, 'woocommerce-attributes' ); + + return $attribute_slug; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-cart-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-cart-functions.php new file mode 100644 index 0000000..1d159c7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-cart-functions.php @@ -0,0 +1,505 @@ +cart ) || '' === WC()->cart ) { + WC()->cart = new WC_Cart(); + } + WC()->cart->empty_cart( false ); +} + +/** + * Load the persistent cart. + * + * @param string $user_login User login. + * @param WP_User $user User data. + * @deprecated 2.3 + */ +function wc_load_persistent_cart( $user_login, $user ) { + if ( ! $user || ! apply_filters( 'woocommerce_persistent_cart_enabled', true ) ) { + return; + } + + $saved_cart = get_user_meta( $user->ID, '_woocommerce_persistent_cart_' . get_current_blog_id(), true ); + + if ( ! $saved_cart ) { + return; + } + + $cart = WC()->session->cart; + + if ( empty( $cart ) || ! is_array( $cart ) || 0 === count( $cart ) ) { + WC()->session->cart = $saved_cart['cart']; + } +} + +/** + * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer. + * + * Do not use for redirects, use {@see wp_get_referer()} instead. + * + * @since 2.6.1 + * @return string|false Referer URL on success, false on failure. + */ +function wc_get_raw_referer() { + if ( function_exists( 'wp_get_raw_referer' ) ) { + return wp_get_raw_referer(); + } + + if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) { // WPCS: input var ok, CSRF ok. + return wp_unslash( $_REQUEST['_wp_http_referer'] ); // WPCS: input var ok, CSRF ok, sanitization ok. + } elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) { // WPCS: input var ok, CSRF ok. + return wp_unslash( $_SERVER['HTTP_REFERER'] ); // WPCS: input var ok, CSRF ok, sanitization ok. + } + + return false; +} + +/** + * Add to cart messages. + * + * @param int|array $products Product ID list or single product ID. + * @param bool $show_qty Should qty's be shown? Added in 2.6.0. + * @param bool $return Return message rather than add it. + * + * @return mixed + */ +function wc_add_to_cart_message( $products, $show_qty = false, $return = false ) { + $titles = array(); + $count = 0; + + if ( ! is_array( $products ) ) { + $products = array( $products => 1 ); + $show_qty = false; + } + + if ( ! $show_qty ) { + $products = array_fill_keys( array_keys( $products ), 1 ); + } + + foreach ( $products as $product_id => $qty ) { + /* translators: %s: product name */ + $titles[] = apply_filters( 'woocommerce_add_to_cart_qty_html', ( $qty > 1 ? absint( $qty ) . ' × ' : '' ), $product_id ) . apply_filters( 'woocommerce_add_to_cart_item_name_in_quotes', sprintf( _x( '“%s”', 'Item name in quotes', 'woocommerce' ), strip_tags( get_the_title( $product_id ) ) ), $product_id ); + $count += $qty; + } + + $titles = array_filter( $titles ); + /* translators: %s: product name */ + $added_text = sprintf( _n( '%s has been added to your cart.', '%s have been added to your cart.', $count, 'woocommerce' ), wc_format_list_of_items( $titles ) ); + + // Output success messages. + if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) { + $return_to = apply_filters( 'woocommerce_continue_shopping_redirect', wc_get_raw_referer() ? wp_validate_redirect( wc_get_raw_referer(), false ) : wc_get_page_permalink( 'shop' ) ); + $message = sprintf( '%s %s', esc_url( $return_to ), esc_html__( 'Continue shopping', 'woocommerce' ), esc_html( $added_text ) ); + } else { + $message = sprintf( '%s %s', esc_url( wc_get_cart_url() ), esc_html__( 'View cart', 'woocommerce' ), esc_html( $added_text ) ); + } + + if ( has_filter( 'wc_add_to_cart_message' ) ) { + wc_deprecated_function( 'The wc_add_to_cart_message filter', '3.0', 'wc_add_to_cart_message_html' ); + $message = apply_filters( 'wc_add_to_cart_message', $message, $product_id ); + } + + $message = apply_filters( 'wc_add_to_cart_message_html', $message, $products, $show_qty ); + + if ( $return ) { + return $message; + } else { + wc_add_notice( $message, apply_filters( 'woocommerce_add_to_cart_notice_type', 'success' ) ); + } +} + +/** + * Comma separate a list of item names, and replace final comma with 'and'. + * + * @param array $items Cart items. + * @return string + */ +function wc_format_list_of_items( $items ) { + $item_string = ''; + + foreach ( $items as $key => $item ) { + $item_string .= $item; + + if ( count( $items ) === $key + 2 ) { + $item_string .= ' ' . __( 'and', 'woocommerce' ) . ' '; + } elseif ( count( $items ) !== $key + 1 ) { + $item_string .= ', '; + } + } + + return $item_string; +} + +/** + * Clear cart after payment. + */ +function wc_clear_cart_after_payment() { + global $wp; + + if ( ! empty( $wp->query_vars['order-received'] ) ) { + + $order_id = absint( $wp->query_vars['order-received'] ); + $order_key = isset( $_GET['key'] ) ? wc_clean( wp_unslash( $_GET['key'] ) ) : ''; // WPCS: input var ok, CSRF ok. + + if ( $order_id > 0 ) { + $order = wc_get_order( $order_id ); + + if ( $order && hash_equals( $order->get_order_key(), $order_key ) ) { + WC()->cart->empty_cart(); + } + } + } + + if ( WC()->session->order_awaiting_payment > 0 ) { + $order = wc_get_order( WC()->session->order_awaiting_payment ); + + if ( $order && $order->get_id() > 0 ) { + // If the order has not failed, or is not pending, the order must have gone through. + if ( ! $order->has_status( array( 'failed', 'pending', 'cancelled' ) ) ) { + WC()->cart->empty_cart(); + } + } + } +} +add_action( 'get_header', 'wc_clear_cart_after_payment' ); + +/** + * Get the subtotal. + */ +function wc_cart_totals_subtotal_html() { + echo WC()->cart->get_cart_subtotal(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +} + +/** + * Get shipping methods. + */ +function wc_cart_totals_shipping_html() { + $packages = WC()->shipping()->get_packages(); + $first = true; + + foreach ( $packages as $i => $package ) { + $chosen_method = isset( WC()->session->chosen_shipping_methods[ $i ] ) ? WC()->session->chosen_shipping_methods[ $i ] : ''; + $product_names = array(); + + if ( count( $packages ) > 1 ) { + foreach ( $package['contents'] as $item_id => $values ) { + $product_names[ $item_id ] = $values['data']->get_name() . ' ×' . $values['quantity']; + } + $product_names = apply_filters( 'woocommerce_shipping_package_details_array', $product_names, $package ); + } + + wc_get_template( + 'cart/cart-shipping.php', + array( + 'package' => $package, + 'available_methods' => $package['rates'], + 'show_package_details' => count( $packages ) > 1, + 'show_shipping_calculator' => is_cart() && apply_filters( 'woocommerce_shipping_show_shipping_calculator', $first, $i, $package ), + 'package_details' => implode( ', ', $product_names ), + /* translators: %d: shipping package number */ + 'package_name' => apply_filters( 'woocommerce_shipping_package_name', ( ( $i + 1 ) > 1 ) ? sprintf( _x( 'Shipping %d', 'shipping packages', 'woocommerce' ), ( $i + 1 ) ) : _x( 'Shipping', 'shipping packages', 'woocommerce' ), $i, $package ), + 'index' => $i, + 'chosen_method' => $chosen_method, + 'formatted_destination' => WC()->countries->get_formatted_address( $package['destination'], ', ' ), + 'has_calculated_shipping' => WC()->customer->has_calculated_shipping(), + ) + ); + + $first = false; + } +} + +/** + * Get taxes total. + */ +function wc_cart_totals_taxes_total_html() { + echo apply_filters( 'woocommerce_cart_totals_taxes_total_html', wc_price( WC()->cart->get_taxes_total() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +} + +/** + * Get a coupon label. + * + * @param string|WC_Coupon $coupon Coupon data or code. + * @param bool $echo Echo or return. + * + * @return string + */ +function wc_cart_totals_coupon_label( $coupon, $echo = true ) { + if ( is_string( $coupon ) ) { + $coupon = new WC_Coupon( $coupon ); + } + + /* translators: %s: coupon code */ + $label = apply_filters( 'woocommerce_cart_totals_coupon_label', sprintf( esc_html__( 'Coupon: %s', 'woocommerce' ), $coupon->get_code() ), $coupon ); + + if ( $echo ) { + echo $label; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } else { + return $label; + } +} + +/** + * Get coupon display HTML. + * + * @param string|WC_Coupon $coupon Coupon data or code. + */ +function wc_cart_totals_coupon_html( $coupon ) { + if ( is_string( $coupon ) ) { + $coupon = new WC_Coupon( $coupon ); + } + + $discount_amount_html = ''; + + $amount = WC()->cart->get_coupon_discount_amount( $coupon->get_code(), WC()->cart->display_cart_ex_tax ); + $discount_amount_html = '-' . wc_price( $amount ); + + if ( $coupon->get_free_shipping() && empty( $amount ) ) { + $discount_amount_html = __( 'Free shipping coupon', 'woocommerce' ); + } + + $discount_amount_html = apply_filters( 'woocommerce_coupon_discount_amount_html', $discount_amount_html, $coupon ); + $coupon_html = $discount_amount_html . ' ' . __( '[Remove]', 'woocommerce' ) . ''; + + echo wp_kses( apply_filters( 'woocommerce_cart_totals_coupon_html', $coupon_html, $coupon, $discount_amount_html ), array_replace_recursive( wp_kses_allowed_html( 'post' ), array( 'a' => array( 'data-coupon' => true ) ) ) ); // phpcs:ignore PHPCompatibility.PHP.NewFunctions.array_replace_recursiveFound +} + +/** + * Get order total html including inc tax if needed. + */ +function wc_cart_totals_order_total_html() { + $value = '' . WC()->cart->get_total() . ' '; + + // If prices are tax inclusive, show taxes here. + if ( wc_tax_enabled() && WC()->cart->display_prices_including_tax() ) { + $tax_string_array = array(); + $cart_tax_totals = WC()->cart->get_tax_totals(); + + if ( get_option( 'woocommerce_tax_total_display' ) === 'itemized' ) { + foreach ( $cart_tax_totals as $code => $tax ) { + $tax_string_array[] = sprintf( '%s %s', $tax->formatted_amount, $tax->label ); + } + } elseif ( ! empty( $cart_tax_totals ) ) { + $tax_string_array[] = sprintf( '%s %s', wc_price( WC()->cart->get_taxes_total( true, true ) ), WC()->countries->tax_or_vat() ); + } + + if ( ! empty( $tax_string_array ) ) { + $taxable_address = WC()->customer->get_taxable_address(); + if ( WC()->customer->is_customer_outside_base() && ! WC()->customer->has_calculated_shipping() ) { + $country = WC()->countries->estimated_for_prefix( $taxable_address[0] ) . WC()->countries->countries[ $taxable_address[0] ]; + /* translators: 1: tax amount 2: country name */ + $tax_text = wp_kses_post( sprintf( __( '(includes %1$s estimated for %2$s)', 'woocommerce' ), implode( ', ', $tax_string_array ), $country ) ); + } else { + /* translators: %s: tax amount */ + $tax_text = wp_kses_post( sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ) ); + } + + $value .= '' . $tax_text . ''; + } + } + + echo apply_filters( 'woocommerce_cart_totals_order_total_html', $value ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +} + +/** + * Get the fee value. + * + * @param object $fee Fee data. + */ +function wc_cart_totals_fee_html( $fee ) { + $cart_totals_fee_html = WC()->cart->display_prices_including_tax() ? wc_price( $fee->total + $fee->tax ) : wc_price( $fee->total ); + + echo apply_filters( 'woocommerce_cart_totals_fee_html', $cart_totals_fee_html, $fee ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +} + +/** + * Get a shipping methods full label including price. + * + * @param WC_Shipping_Rate $method Shipping method rate data. + * @return string + */ +function wc_cart_totals_shipping_method_label( $method ) { + $label = $method->get_label(); + $has_cost = 0 < $method->cost; + $hide_cost = ! $has_cost && in_array( $method->get_method_id(), array( 'free_shipping', 'local_pickup' ), true ); + + if ( $has_cost && ! $hide_cost ) { + if ( WC()->cart->display_prices_including_tax() ) { + $label .= ': ' . wc_price( $method->cost + $method->get_shipping_tax() ); + if ( $method->get_shipping_tax() > 0 && ! wc_prices_include_tax() ) { + $label .= ' ' . WC()->countries->inc_tax_or_vat() . ''; + } + } else { + $label .= ': ' . wc_price( $method->cost ); + if ( $method->get_shipping_tax() > 0 && wc_prices_include_tax() ) { + $label .= ' ' . WC()->countries->ex_tax_or_vat() . ''; + } + } + } + + return apply_filters( 'woocommerce_cart_shipping_method_full_label', $label, $method ); +} + +/** + * Round discount. + * + * @param double $value Amount to round. + * @param int $precision DP to round. + * @return float + */ +function wc_cart_round_discount( $value, $precision ) { + return wc_round_discount( $value, $precision ); +} + +/** + * Gets chosen shipping method IDs from chosen_shipping_methods session, without instance IDs. + * + * @since 2.6.2 + * @return string[] + */ +function wc_get_chosen_shipping_method_ids() { + $method_ids = array(); + $chosen_methods = WC()->session->get( 'chosen_shipping_methods', array() ); + foreach ( $chosen_methods as $chosen_method ) { + $chosen_method = explode( ':', $chosen_method ); + $method_ids[] = current( $chosen_method ); + } + return $method_ids; +} + +/** + * Get chosen method for package from session. + * + * @since 3.2.0 + * @param int $key Key of package. + * @param array $package Package data array. + * @return string|bool + */ +function wc_get_chosen_shipping_method_for_package( $key, $package ) { + $chosen_methods = WC()->session->get( 'chosen_shipping_methods' ); + $chosen_method = isset( $chosen_methods[ $key ] ) ? $chosen_methods[ $key ] : false; + $changed = wc_shipping_methods_have_changed( $key, $package ); + + // This is deprecated but here for BW compat. TODO: Remove in 4.0.0. + $method_counts = WC()->session->get( 'shipping_method_counts' ); + + if ( ! empty( $method_counts[ $key ] ) ) { + $method_count = absint( $method_counts[ $key ] ); + } else { + $method_count = 0; + } + + // If not set, not available, or available methods have changed, set to the DEFAULT option. + if ( ! $chosen_method || $changed || ! isset( $package['rates'][ $chosen_method ] ) || count( $package['rates'] ) !== $method_count ) { + $chosen_method = wc_get_default_shipping_method_for_package( $key, $package, $chosen_method ); + $chosen_methods[ $key ] = $chosen_method; + $method_counts[ $key ] = count( $package['rates'] ); + + WC()->session->set( 'chosen_shipping_methods', $chosen_methods ); + WC()->session->set( 'shipping_method_counts', $method_counts ); + + do_action( 'woocommerce_shipping_method_chosen', $chosen_method ); + } + return $chosen_method; +} + +/** + * Choose the default method for a package. + * + * @since 3.2.0 + * @param int $key Key of package. + * @param array $package Package data array. + * @param string $chosen_method Chosen method id. + * @return string + */ +function wc_get_default_shipping_method_for_package( $key, $package, $chosen_method ) { + $rate_keys = array_keys( $package['rates'] ); + $default = current( $rate_keys ); + $coupons = WC()->cart->get_coupons(); + foreach ( $coupons as $coupon ) { + if ( $coupon->get_free_shipping() ) { + foreach ( $rate_keys as $rate_key ) { + if ( 0 === stripos( $rate_key, 'free_shipping' ) ) { + $default = $rate_key; + break; + } + } + break; + } + } + return apply_filters( 'woocommerce_shipping_chosen_method', $default, $package['rates'], $chosen_method ); +} + +/** + * See if the methods have changed since the last request. + * + * @since 3.2.0 + * @param int $key Key of package. + * @param array $package Package data array. + * @return bool + */ +function wc_shipping_methods_have_changed( $key, $package ) { + // Lookup previous methods from session. + $previous_shipping_methods = WC()->session->get( 'previous_shipping_methods' ); + // Get new and old rates. + $new_rates = array_keys( $package['rates'] ); + $prev_rates = isset( $previous_shipping_methods[ $key ] ) ? $previous_shipping_methods[ $key ] : false; + // Update session. + $previous_shipping_methods[ $key ] = $new_rates; + WC()->session->set( 'previous_shipping_methods', $previous_shipping_methods ); + return $new_rates !== $prev_rates; +} + +/** + * Gets a hash of important product data that when changed should cause cart items to be invalidated. + * + * The woocommerce_cart_item_data_to_validate filter can be used to add custom properties. + * + * @param WC_Product $product Product object. + * @return string + */ +function wc_get_cart_item_data_hash( $product ) { + return md5( + wp_json_encode( + apply_filters( + 'woocommerce_cart_item_data_to_validate', + array( + 'type' => $product->get_type(), + 'attributes' => 'variation' === $product->get_type() ? $product->get_variation_attributes() : '', + ), + $product + ) + ) + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-conditional-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-conditional-functions.php new file mode 100644 index 0000000..641066c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-conditional-functions.php @@ -0,0 +1,496 @@ +query_vars['order-pay'] ); + } +} + +if ( ! function_exists( 'is_wc_endpoint_url' ) ) { + + /** + * Is_wc_endpoint_url - Check if an endpoint is showing. + * + * @param string|false $endpoint Whether endpoint. + * @return bool + */ + function is_wc_endpoint_url( $endpoint = false ) { + global $wp; + + $wc_endpoints = WC()->query->get_query_vars(); + + if ( false !== $endpoint ) { + if ( ! isset( $wc_endpoints[ $endpoint ] ) ) { + return false; + } else { + $endpoint_var = $wc_endpoints[ $endpoint ]; + } + + return isset( $wp->query_vars[ $endpoint_var ] ); + } else { + foreach ( $wc_endpoints as $key => $value ) { + if ( isset( $wp->query_vars[ $key ] ) ) { + return true; + } + } + + return false; + } + } +} + +if ( ! function_exists( 'is_account_page' ) ) { + + /** + * Is_account_page - Returns true when viewing an account page. + * + * @return bool + */ + function is_account_page() { + $page_id = wc_get_page_id( 'myaccount' ); + + return ( $page_id && is_page( $page_id ) ) || wc_post_content_has_shortcode( 'woocommerce_my_account' ) || apply_filters( 'woocommerce_is_account_page', false ); + } +} + +if ( ! function_exists( 'is_view_order_page' ) ) { + + /** + * Is_view_order_page - Returns true when on the view order page. + * + * @return bool + */ + function is_view_order_page() { + global $wp; + + $page_id = wc_get_page_id( 'myaccount' ); + + return ( $page_id && is_page( $page_id ) && isset( $wp->query_vars['view-order'] ) ); + } +} + +if ( ! function_exists( 'is_edit_account_page' ) ) { + + /** + * Check for edit account page. + * Returns true when viewing the edit account page. + * + * @since 2.5.1 + * @return bool + */ + function is_edit_account_page() { + global $wp; + + $page_id = wc_get_page_id( 'myaccount' ); + + return ( $page_id && is_page( $page_id ) && isset( $wp->query_vars['edit-account'] ) ); + } +} + +if ( ! function_exists( 'is_order_received_page' ) ) { + + /** + * Is_order_received_page - Returns true when viewing the order received page. + * + * @return bool + */ + function is_order_received_page() { + global $wp; + + $page_id = wc_get_page_id( 'checkout' ); + + return apply_filters( 'woocommerce_is_order_received_page', ( $page_id && is_page( $page_id ) && isset( $wp->query_vars['order-received'] ) ) ); + } +} + +if ( ! function_exists( 'is_add_payment_method_page' ) ) { + + /** + * Is_add_payment_method_page - Returns true when viewing the add payment method page. + * + * @return bool + */ + function is_add_payment_method_page() { + global $wp; + + $page_id = wc_get_page_id( 'myaccount' ); + + return ( $page_id && is_page( $page_id ) && ( isset( $wp->query_vars['payment-methods'] ) || isset( $wp->query_vars['add-payment-method'] ) ) ); + } +} + +if ( ! function_exists( 'is_lost_password_page' ) ) { + + /** + * Is_lost_password_page - Returns true when viewing the lost password page. + * + * @return bool + */ + function is_lost_password_page() { + global $wp; + + $page_id = wc_get_page_id( 'myaccount' ); + + return ( $page_id && is_page( $page_id ) && isset( $wp->query_vars['lost-password'] ) ); + } +} + +if ( ! function_exists( 'is_ajax' ) ) { + + /** + * Is_ajax - Returns true when the page is loaded via ajax. + * + * @return bool + */ + function is_ajax() { + return function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : Constants::is_defined( 'DOING_AJAX' ); + } +} + +if ( ! function_exists( 'is_store_notice_showing' ) ) { + + /** + * Is_store_notice_showing - Returns true when store notice is active. + * + * @return bool + */ + function is_store_notice_showing() { + return 'no' !== get_option( 'woocommerce_demo_store', 'no' ); + } +} + +if ( ! function_exists( 'is_filtered' ) ) { + + /** + * Is_filtered - Returns true when filtering products using layered nav or price sliders. + * + * @return bool + */ + function is_filtered() { + return apply_filters( 'woocommerce_is_filtered', ( count( WC_Query::get_layered_nav_chosen_attributes() ) > 0 || isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) || isset( $_GET['rating_filter'] ) ) ); // WPCS: CSRF ok. + } +} + +if ( ! function_exists( 'taxonomy_is_product_attribute' ) ) { + + /** + * Returns true when the passed taxonomy name is a product attribute. + * + * @uses $wc_product_attributes global which stores taxonomy names upon registration + * @param string $name of the attribute. + * @return bool + */ + function taxonomy_is_product_attribute( $name ) { + global $wc_product_attributes; + + return taxonomy_exists( $name ) && array_key_exists( $name, (array) $wc_product_attributes ); + } +} + +if ( ! function_exists( 'meta_is_product_attribute' ) ) { + + /** + * Returns true when the passed meta name is a product attribute. + * + * @param string $name of the attribute. + * @param string $value of the attribute. + * @param int $product_id to check for attribute. + * @return bool + */ + function meta_is_product_attribute( $name, $value, $product_id ) { + $product = wc_get_product( $product_id ); + + if ( $product && method_exists( $product, 'get_variation_attributes' ) ) { + $variation_attributes = $product->get_variation_attributes(); + $attributes = $product->get_attributes(); + return ( in_array( $name, array_keys( $attributes ), true ) && in_array( $value, $variation_attributes[ $attributes[ $name ]['name'] ], true ) ); + } else { + return false; + } + } +} + +if ( ! function_exists( 'wc_tax_enabled' ) ) { + + /** + * Are store-wide taxes enabled? + * + * @return bool + */ + function wc_tax_enabled() { + return apply_filters( 'wc_tax_enabled', get_option( 'woocommerce_calc_taxes' ) === 'yes' ); + } +} + +if ( ! function_exists( 'wc_shipping_enabled' ) ) { + + /** + * Is shipping enabled? + * + * @return bool + */ + function wc_shipping_enabled() { + return apply_filters( 'wc_shipping_enabled', get_option( 'woocommerce_ship_to_countries' ) !== 'disabled' ); + } +} + +if ( ! function_exists( 'wc_prices_include_tax' ) ) { + + /** + * Are prices inclusive of tax? + * + * @return bool + */ + function wc_prices_include_tax() { + return wc_tax_enabled() && apply_filters( 'woocommerce_prices_include_tax', get_option( 'woocommerce_prices_include_tax' ) === 'yes' ); + } +} + +/** + * Simple check for validating a URL, it must start with http:// or https://. + * and pass FILTER_VALIDATE_URL validation. + * + * @param string $url to check. + * @return bool + */ +function wc_is_valid_url( $url ) { + + // Must start with http:// or https://. + if ( 0 !== strpos( $url, 'http://' ) && 0 !== strpos( $url, 'https://' ) ) { + return false; + } + + // Must pass validation. + if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) { + return false; + } + + return true; +} + +/** + * Check if the home URL is https. If it is, we don't need to do things such as 'force ssl'. + * + * @since 2.4.13 + * @return bool + */ +function wc_site_is_https() { + return false !== strstr( get_option( 'home' ), 'https:' ); +} + +/** + * Check if the checkout is configured for https. Look at options, WP HTTPS plugin, or the permalink itself. + * + * @since 2.5.0 + * @return bool + */ +function wc_checkout_is_https() { + return wc_site_is_https() || 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) || class_exists( 'WordPressHTTPS' ) || strstr( wc_get_page_permalink( 'checkout' ), 'https:' ); +} + +/** + * Checks whether the content passed contains a specific short code. + * + * @param string $tag Shortcode tag to check. + * @return bool + */ +function wc_post_content_has_shortcode( $tag = '' ) { + global $post; + + return is_singular() && is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, $tag ); +} + +/** + * Check if reviews are enabled. + * + * @since 3.6.0 + * @return bool + */ +function wc_reviews_enabled() { + return 'yes' === get_option( 'woocommerce_enable_reviews' ); +} + +/** + * Check if reviews ratings are enabled. + * + * @since 3.6.0 + * @return bool + */ +function wc_review_ratings_enabled() { + return wc_reviews_enabled() && 'yes' === get_option( 'woocommerce_enable_review_rating' ); +} + +/** + * Check if review ratings are required. + * + * @since 3.6.0 + * @return bool + */ +function wc_review_ratings_required() { + return 'yes' === get_option( 'woocommerce_review_rating_required' ); +} + +/** + * Check if a CSV file is valid. + * + * @since 3.6.5 + * @param string $file File name. + * @param bool $check_path If should check for the path. + * @return bool + */ +function wc_is_file_valid_csv( $file, $check_path = true ) { + /** + * Filter check for CSV file path. + * + * @since 3.6.4 + * @param bool $check_import_file_path If requires file path check. Defaults to true. + */ + $check_import_file_path = apply_filters( 'woocommerce_csv_importer_check_import_file_path', true ); + + if ( $check_path && $check_import_file_path && false !== stripos( $file, '://' ) ) { + return false; + } + + /** + * Filter CSV valid file types. + * + * @since 3.6.5 + * @param array $valid_filetypes List of valid file types. + */ + $valid_filetypes = apply_filters( + 'woocommerce_csv_import_valid_filetypes', + array( + 'csv' => 'text/csv', + 'txt' => 'text/plain', + ) + ); + + $filetype = wp_check_filetype( $file, $valid_filetypes ); + + if ( in_array( $filetype['type'], $valid_filetypes, true ) ) { + return true; + } + + return false; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-core-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-core-functions.php new file mode 100644 index 0000000..5d84a9a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-core-functions.php @@ -0,0 +1,2504 @@ + null, + 'customer_id' => null, + 'customer_note' => null, + 'parent' => null, + 'created_via' => null, + 'cart_hash' => null, + 'order_id' => 0, + ); + + try { + $args = wp_parse_args( $args, $default_args ); + $order = new WC_Order( $args['order_id'] ); + + // Update props that were set (not null). + if ( ! is_null( $args['parent'] ) ) { + $order->set_parent_id( absint( $args['parent'] ) ); + } + + if ( ! is_null( $args['status'] ) ) { + $order->set_status( $args['status'] ); + } + + if ( ! is_null( $args['customer_note'] ) ) { + $order->set_customer_note( $args['customer_note'] ); + } + + if ( ! is_null( $args['customer_id'] ) ) { + $order->set_customer_id( is_numeric( $args['customer_id'] ) ? absint( $args['customer_id'] ) : 0 ); + } + + if ( ! is_null( $args['created_via'] ) ) { + $order->set_created_via( sanitize_text_field( $args['created_via'] ) ); + } + + if ( ! is_null( $args['cart_hash'] ) ) { + $order->set_cart_hash( sanitize_text_field( $args['cart_hash'] ) ); + } + + // Set these fields when creating a new order but not when updating an existing order. + if ( ! $args['order_id'] ) { + $order->set_currency( get_woocommerce_currency() ); + $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $order->set_customer_ip_address( WC_Geolocation::get_ip_address() ); + $order->set_customer_user_agent( wc_get_user_agent() ); + } + + // Update other order props set automatically. + $order->save(); + } catch ( Exception $e ) { + return new WP_Error( 'error', $e->getMessage() ); + } + + return $order; +} + +/** + * Update an order. Uses wc_create_order. + * + * @param array $args Order arguments. + * @return WC_Order|WP_Error + */ +function wc_update_order( $args ) { + if ( empty( $args['order_id'] ) ) { + return new WP_Error( __( 'Invalid order ID.', 'woocommerce' ) ); + } + return wc_create_order( $args ); +} + +/** + * Given a path, this will convert any of the subpaths into their corresponding tokens. + * + * @since 4.3.0 + * @param string $path The absolute path to tokenize. + * @param array $path_tokens An array keyed with the token, containing paths that should be replaced. + * @return string The tokenized path. + */ +function wc_tokenize_path( $path, $path_tokens ) { + // Order most to least specific so that the token can encompass as much of the path as possible. + uasort( + $path_tokens, + function ( $a, $b ) { + $a = strlen( $a ); + $b = strlen( $b ); + + if ( $a > $b ) { + return -1; + } + + if ( $b > $a ) { + return 1; + } + + return 0; + } + ); + + foreach ( $path_tokens as $token => $token_path ) { + if ( 0 !== strpos( $path, $token_path ) ) { + continue; + } + + $path = str_replace( $token_path, '{{' . $token . '}}', $path ); + } + + return $path; +} + +/** + * Given a tokenized path, this will expand the tokens to their full path. + * + * @since 4.3.0 + * @param string $path The absolute path to expand. + * @param array $path_tokens An array keyed with the token, containing paths that should be expanded. + * @return string The absolute path. + */ +function wc_untokenize_path( $path, $path_tokens ) { + foreach ( $path_tokens as $token => $token_path ) { + $path = str_replace( '{{' . $token . '}}', $token_path, $path ); + } + + return $path; +} + +/** + * Fetches an array containing all of the configurable path constants to be used in tokenization. + * + * @return array The key is the define and the path is the constant. + */ +function wc_get_path_define_tokens() { + $defines = array( + 'ABSPATH', + 'WP_CONTENT_DIR', + 'WP_PLUGIN_DIR', + 'WPMU_PLUGIN_DIR', + 'PLUGINDIR', + 'WP_THEME_DIR', + ); + + $path_tokens = array(); + foreach ( $defines as $define ) { + if ( defined( $define ) ) { + $path_tokens[ $define ] = constant( $define ); + } + } + + return apply_filters( 'woocommerce_get_path_define_tokens', $path_tokens ); +} + +/** + * Get template part (for templates like the shop-loop). + * + * WC_TEMPLATE_DEBUG_MODE will prevent overrides in themes from taking priority. + * + * @param mixed $slug Template slug. + * @param string $name Template name (default: ''). + */ +function wc_get_template_part( $slug, $name = '' ) { + $cache_key = sanitize_key( implode( '-', array( 'template-part', $slug, $name, Constants::get_constant( 'WC_VERSION' ) ) ) ); + $template = (string) wp_cache_get( $cache_key, 'woocommerce' ); + + if ( ! $template ) { + if ( $name ) { + $template = WC_TEMPLATE_DEBUG_MODE ? '' : locate_template( + array( + "{$slug}-{$name}.php", + WC()->template_path() . "{$slug}-{$name}.php", + ) + ); + + if ( ! $template ) { + $fallback = WC()->plugin_path() . "/templates/{$slug}-{$name}.php"; + $template = file_exists( $fallback ) ? $fallback : ''; + } + } + + if ( ! $template ) { + // If template file doesn't exist, look in yourtheme/slug.php and yourtheme/woocommerce/slug.php. + $template = WC_TEMPLATE_DEBUG_MODE ? '' : locate_template( + array( + "{$slug}.php", + WC()->template_path() . "{$slug}.php", + ) + ); + } + + // Don't cache the absolute path so that it can be shared between web servers with different paths. + $cache_path = wc_tokenize_path( $template, wc_get_path_define_tokens() ); + + wc_set_template_cache( $cache_key, $cache_path ); + } else { + // Make sure that the absolute path to the template is resolved. + $template = wc_untokenize_path( $template, wc_get_path_define_tokens() ); + } + + // Allow 3rd party plugins to filter template file from their plugin. + $template = apply_filters( 'wc_get_template_part', $template, $slug, $name ); + + if ( $template ) { + load_template( $template, false ); + } +} + +/** + * Get other templates (e.g. product attributes) passing attributes and including the file. + * + * @param string $template_name Template name. + * @param array $args Arguments. (default: array). + * @param string $template_path Template path. (default: ''). + * @param string $default_path Default path. (default: ''). + */ +function wc_get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) { + $cache_key = sanitize_key( implode( '-', array( 'template', $template_name, $template_path, $default_path, Constants::get_constant( 'WC_VERSION' ) ) ) ); + $template = (string) wp_cache_get( $cache_key, 'woocommerce' ); + + if ( ! $template ) { + $template = wc_locate_template( $template_name, $template_path, $default_path ); + + // Don't cache the absolute path so that it can be shared between web servers with different paths. + $cache_path = wc_tokenize_path( $template, wc_get_path_define_tokens() ); + + wc_set_template_cache( $cache_key, $cache_path ); + } else { + // Make sure that the absolute path to the template is resolved. + $template = wc_untokenize_path( $template, wc_get_path_define_tokens() ); + } + + // Allow 3rd party plugin filter template file from their plugin. + $filter_template = apply_filters( 'wc_get_template', $template, $template_name, $args, $template_path, $default_path ); + + if ( $filter_template !== $template ) { + if ( ! file_exists( $filter_template ) ) { + /* translators: %s template */ + wc_doing_it_wrong( __FUNCTION__, sprintf( __( '%s does not exist.', 'woocommerce' ), '' . $filter_template . '' ), '2.1' ); + return; + } + $template = $filter_template; + } + + $action_args = array( + 'template_name' => $template_name, + 'template_path' => $template_path, + 'located' => $template, + 'args' => $args, + ); + + if ( ! empty( $args ) && is_array( $args ) ) { + if ( isset( $args['action_args'] ) ) { + wc_doing_it_wrong( + __FUNCTION__, + __( 'action_args should not be overwritten when calling wc_get_template.', 'woocommerce' ), + '3.6.0' + ); + unset( $args['action_args'] ); + } + extract( $args ); // @codingStandardsIgnoreLine + } + + do_action( 'woocommerce_before_template_part', $action_args['template_name'], $action_args['template_path'], $action_args['located'], $action_args['args'] ); + + include $action_args['located']; + + do_action( 'woocommerce_after_template_part', $action_args['template_name'], $action_args['template_path'], $action_args['located'], $action_args['args'] ); +} + +/** + * Like wc_get_template, but returns the HTML instead of outputting. + * + * @see wc_get_template + * @since 2.5.0 + * @param string $template_name Template name. + * @param array $args Arguments. (default: array). + * @param string $template_path Template path. (default: ''). + * @param string $default_path Default path. (default: ''). + * + * @return string + */ +function wc_get_template_html( $template_name, $args = array(), $template_path = '', $default_path = '' ) { + ob_start(); + wc_get_template( $template_name, $args, $template_path, $default_path ); + return ob_get_clean(); +} +/** + * Locate a template and return the path for inclusion. + * + * This is the load order: + * + * yourtheme/$template_path/$template_name + * yourtheme/$template_name + * $default_path/$template_name + * + * @param string $template_name Template name. + * @param string $template_path Template path. (default: ''). + * @param string $default_path Default path. (default: ''). + * @return string + */ +function wc_locate_template( $template_name, $template_path = '', $default_path = '' ) { + if ( ! $template_path ) { + $template_path = WC()->template_path(); + } + + if ( ! $default_path ) { + $default_path = WC()->plugin_path() . '/templates/'; + } + + // Look within passed path within the theme - this is priority. + if ( false !== strpos( $template_name, 'product_cat' ) || false !== strpos( $template_name, 'product_tag' ) ) { + $cs_template = str_replace( '_', '-', $template_name ); + $template = locate_template( + array( + trailingslashit( $template_path ) . $cs_template, + $cs_template, + ) + ); + } + + if ( empty( $template ) ) { + $template = locate_template( + array( + trailingslashit( $template_path ) . $template_name, + $template_name, + ) + ); + } + + // Get default template/. + if ( ! $template || WC_TEMPLATE_DEBUG_MODE ) { + if ( empty( $cs_template ) ) { + $template = $default_path . $template_name; + } else { + $template = $default_path . $cs_template; + } + } + + // Return what we found. + return apply_filters( 'woocommerce_locate_template', $template, $template_name, $template_path ); +} + +/** + * Add a template to the template cache. + * + * @since 4.3.0 + * @param string $cache_key Object cache key. + * @param string $template Located template. + */ +function wc_set_template_cache( $cache_key, $template ) { + wp_cache_set( $cache_key, $template, 'woocommerce' ); + + $cached_templates = wp_cache_get( 'cached_templates', 'woocommerce' ); + if ( is_array( $cached_templates ) ) { + $cached_templates[] = $cache_key; + } else { + $cached_templates = array( $cache_key ); + } + + wp_cache_set( 'cached_templates', $cached_templates, 'woocommerce' ); +} + +/** + * Clear the template cache. + * + * @since 4.3.0 + */ +function wc_clear_template_cache() { + $cached_templates = wp_cache_get( 'cached_templates', 'woocommerce' ); + if ( is_array( $cached_templates ) ) { + foreach ( $cached_templates as $cache_key ) { + wp_cache_delete( $cache_key, 'woocommerce' ); + } + + wp_cache_delete( 'cached_templates', 'woocommerce' ); + } +} + +/** + * Get Base Currency Code. + * + * @return string + */ +function get_woocommerce_currency() { + return apply_filters( 'woocommerce_currency', get_option( 'woocommerce_currency' ) ); +} + +/** + * Get full list of currency codes. + * + * Currency symbols and names should follow the Unicode CLDR recommendation (http://cldr.unicode.org/translation/currency-names) + * + * @return array + */ +function get_woocommerce_currencies() { + static $currencies; + + if ( ! isset( $currencies ) ) { + $currencies = array_unique( + apply_filters( + 'woocommerce_currencies', + array( + 'AED' => __( 'United Arab Emirates dirham', 'woocommerce' ), + 'AFN' => __( 'Afghan afghani', 'woocommerce' ), + 'ALL' => __( 'Albanian lek', 'woocommerce' ), + 'AMD' => __( 'Armenian dram', 'woocommerce' ), + 'ANG' => __( 'Netherlands Antillean guilder', 'woocommerce' ), + 'AOA' => __( 'Angolan kwanza', 'woocommerce' ), + 'ARS' => __( 'Argentine peso', 'woocommerce' ), + 'AUD' => __( 'Australian dollar', 'woocommerce' ), + 'AWG' => __( 'Aruban florin', 'woocommerce' ), + 'AZN' => __( 'Azerbaijani manat', 'woocommerce' ), + 'BAM' => __( 'Bosnia and Herzegovina convertible mark', 'woocommerce' ), + 'BBD' => __( 'Barbadian dollar', 'woocommerce' ), + 'BDT' => __( 'Bangladeshi taka', 'woocommerce' ), + 'BGN' => __( 'Bulgarian lev', 'woocommerce' ), + 'BHD' => __( 'Bahraini dinar', 'woocommerce' ), + 'BIF' => __( 'Burundian franc', 'woocommerce' ), + 'BMD' => __( 'Bermudian dollar', 'woocommerce' ), + 'BND' => __( 'Brunei dollar', 'woocommerce' ), + 'BOB' => __( 'Bolivian boliviano', 'woocommerce' ), + 'BRL' => __( 'Brazilian real', 'woocommerce' ), + 'BSD' => __( 'Bahamian dollar', 'woocommerce' ), + 'BTC' => __( 'Bitcoin', 'woocommerce' ), + 'BTN' => __( 'Bhutanese ngultrum', 'woocommerce' ), + 'BWP' => __( 'Botswana pula', 'woocommerce' ), + 'BYR' => __( 'Belarusian ruble (old)', 'woocommerce' ), + 'BYN' => __( 'Belarusian ruble', 'woocommerce' ), + 'BZD' => __( 'Belize dollar', 'woocommerce' ), + 'CAD' => __( 'Canadian dollar', 'woocommerce' ), + 'CDF' => __( 'Congolese franc', 'woocommerce' ), + 'CHF' => __( 'Swiss franc', 'woocommerce' ), + 'CLP' => __( 'Chilean peso', 'woocommerce' ), + 'CNY' => __( 'Chinese yuan', 'woocommerce' ), + 'COP' => __( 'Colombian peso', 'woocommerce' ), + 'CRC' => __( 'Costa Rican colón', 'woocommerce' ), + 'CUC' => __( 'Cuban convertible peso', 'woocommerce' ), + 'CUP' => __( 'Cuban peso', 'woocommerce' ), + 'CVE' => __( 'Cape Verdean escudo', 'woocommerce' ), + 'CZK' => __( 'Czech koruna', 'woocommerce' ), + 'DJF' => __( 'Djiboutian franc', 'woocommerce' ), + 'DKK' => __( 'Danish krone', 'woocommerce' ), + 'DOP' => __( 'Dominican peso', 'woocommerce' ), + 'DZD' => __( 'Algerian dinar', 'woocommerce' ), + 'EGP' => __( 'Egyptian pound', 'woocommerce' ), + 'ERN' => __( 'Eritrean nakfa', 'woocommerce' ), + 'ETB' => __( 'Ethiopian birr', 'woocommerce' ), + 'EUR' => __( 'Euro', 'woocommerce' ), + 'FJD' => __( 'Fijian dollar', 'woocommerce' ), + 'FKP' => __( 'Falkland Islands pound', 'woocommerce' ), + 'GBP' => __( 'Pound sterling', 'woocommerce' ), + 'GEL' => __( 'Georgian lari', 'woocommerce' ), + 'GGP' => __( 'Guernsey pound', 'woocommerce' ), + 'GHS' => __( 'Ghana cedi', 'woocommerce' ), + 'GIP' => __( 'Gibraltar pound', 'woocommerce' ), + 'GMD' => __( 'Gambian dalasi', 'woocommerce' ), + 'GNF' => __( 'Guinean franc', 'woocommerce' ), + 'GTQ' => __( 'Guatemalan quetzal', 'woocommerce' ), + 'GYD' => __( 'Guyanese dollar', 'woocommerce' ), + 'HKD' => __( 'Hong Kong dollar', 'woocommerce' ), + 'HNL' => __( 'Honduran lempira', 'woocommerce' ), + 'HRK' => __( 'Croatian kuna', 'woocommerce' ), + 'HTG' => __( 'Haitian gourde', 'woocommerce' ), + 'HUF' => __( 'Hungarian forint', 'woocommerce' ), + 'IDR' => __( 'Indonesian rupiah', 'woocommerce' ), + 'ILS' => __( 'Israeli new shekel', 'woocommerce' ), + 'IMP' => __( 'Manx pound', 'woocommerce' ), + 'INR' => __( 'Indian rupee', 'woocommerce' ), + 'IQD' => __( 'Iraqi dinar', 'woocommerce' ), + 'IRR' => __( 'Iranian rial', 'woocommerce' ), + 'IRT' => __( 'Iranian toman', 'woocommerce' ), + 'ISK' => __( 'Icelandic króna', 'woocommerce' ), + 'JEP' => __( 'Jersey pound', 'woocommerce' ), + 'JMD' => __( 'Jamaican dollar', 'woocommerce' ), + 'JOD' => __( 'Jordanian dinar', 'woocommerce' ), + 'JPY' => __( 'Japanese yen', 'woocommerce' ), + 'KES' => __( 'Kenyan shilling', 'woocommerce' ), + 'KGS' => __( 'Kyrgyzstani som', 'woocommerce' ), + 'KHR' => __( 'Cambodian riel', 'woocommerce' ), + 'KMF' => __( 'Comorian franc', 'woocommerce' ), + 'KPW' => __( 'North Korean won', 'woocommerce' ), + 'KRW' => __( 'South Korean won', 'woocommerce' ), + 'KWD' => __( 'Kuwaiti dinar', 'woocommerce' ), + 'KYD' => __( 'Cayman Islands dollar', 'woocommerce' ), + 'KZT' => __( 'Kazakhstani tenge', 'woocommerce' ), + 'LAK' => __( 'Lao kip', 'woocommerce' ), + 'LBP' => __( 'Lebanese pound', 'woocommerce' ), + 'LKR' => __( 'Sri Lankan rupee', 'woocommerce' ), + 'LRD' => __( 'Liberian dollar', 'woocommerce' ), + 'LSL' => __( 'Lesotho loti', 'woocommerce' ), + 'LYD' => __( 'Libyan dinar', 'woocommerce' ), + 'MAD' => __( 'Moroccan dirham', 'woocommerce' ), + 'MDL' => __( 'Moldovan leu', 'woocommerce' ), + 'MGA' => __( 'Malagasy ariary', 'woocommerce' ), + 'MKD' => __( 'Macedonian denar', 'woocommerce' ), + 'MMK' => __( 'Burmese kyat', 'woocommerce' ), + 'MNT' => __( 'Mongolian tögrög', 'woocommerce' ), + 'MOP' => __( 'Macanese pataca', 'woocommerce' ), + 'MRU' => __( 'Mauritanian ouguiya', 'woocommerce' ), + 'MUR' => __( 'Mauritian rupee', 'woocommerce' ), + 'MVR' => __( 'Maldivian rufiyaa', 'woocommerce' ), + 'MWK' => __( 'Malawian kwacha', 'woocommerce' ), + 'MXN' => __( 'Mexican peso', 'woocommerce' ), + 'MYR' => __( 'Malaysian ringgit', 'woocommerce' ), + 'MZN' => __( 'Mozambican metical', 'woocommerce' ), + 'NAD' => __( 'Namibian dollar', 'woocommerce' ), + 'NGN' => __( 'Nigerian naira', 'woocommerce' ), + 'NIO' => __( 'Nicaraguan córdoba', 'woocommerce' ), + 'NOK' => __( 'Norwegian krone', 'woocommerce' ), + 'NPR' => __( 'Nepalese rupee', 'woocommerce' ), + 'NZD' => __( 'New Zealand dollar', 'woocommerce' ), + 'OMR' => __( 'Omani rial', 'woocommerce' ), + 'PAB' => __( 'Panamanian balboa', 'woocommerce' ), + 'PEN' => __( 'Sol', 'woocommerce' ), + 'PGK' => __( 'Papua New Guinean kina', 'woocommerce' ), + 'PHP' => __( 'Philippine peso', 'woocommerce' ), + 'PKR' => __( 'Pakistani rupee', 'woocommerce' ), + 'PLN' => __( 'Polish złoty', 'woocommerce' ), + 'PRB' => __( 'Transnistrian ruble', 'woocommerce' ), + 'PYG' => __( 'Paraguayan guaraní', 'woocommerce' ), + 'QAR' => __( 'Qatari riyal', 'woocommerce' ), + 'RON' => __( 'Romanian leu', 'woocommerce' ), + 'RSD' => __( 'Serbian dinar', 'woocommerce' ), + 'RUB' => __( 'Russian ruble', 'woocommerce' ), + 'RWF' => __( 'Rwandan franc', 'woocommerce' ), + 'SAR' => __( 'Saudi riyal', 'woocommerce' ), + 'SBD' => __( 'Solomon Islands dollar', 'woocommerce' ), + 'SCR' => __( 'Seychellois rupee', 'woocommerce' ), + 'SDG' => __( 'Sudanese pound', 'woocommerce' ), + 'SEK' => __( 'Swedish krona', 'woocommerce' ), + 'SGD' => __( 'Singapore dollar', 'woocommerce' ), + 'SHP' => __( 'Saint Helena pound', 'woocommerce' ), + 'SLL' => __( 'Sierra Leonean leone', 'woocommerce' ), + 'SOS' => __( 'Somali shilling', 'woocommerce' ), + 'SRD' => __( 'Surinamese dollar', 'woocommerce' ), + 'SSP' => __( 'South Sudanese pound', 'woocommerce' ), + 'STN' => __( 'São Tomé and Príncipe dobra', 'woocommerce' ), + 'SYP' => __( 'Syrian pound', 'woocommerce' ), + 'SZL' => __( 'Swazi lilangeni', 'woocommerce' ), + 'THB' => __( 'Thai baht', 'woocommerce' ), + 'TJS' => __( 'Tajikistani somoni', 'woocommerce' ), + 'TMT' => __( 'Turkmenistan manat', 'woocommerce' ), + 'TND' => __( 'Tunisian dinar', 'woocommerce' ), + 'TOP' => __( 'Tongan paʻanga', 'woocommerce' ), + 'TRY' => __( 'Turkish lira', 'woocommerce' ), + 'TTD' => __( 'Trinidad and Tobago dollar', 'woocommerce' ), + 'TWD' => __( 'New Taiwan dollar', 'woocommerce' ), + 'TZS' => __( 'Tanzanian shilling', 'woocommerce' ), + 'UAH' => __( 'Ukrainian hryvnia', 'woocommerce' ), + 'UGX' => __( 'Ugandan shilling', 'woocommerce' ), + 'USD' => __( 'United States (US) dollar', 'woocommerce' ), + 'UYU' => __( 'Uruguayan peso', 'woocommerce' ), + 'UZS' => __( 'Uzbekistani som', 'woocommerce' ), + 'VEF' => __( 'Venezuelan bolívar', 'woocommerce' ), + 'VES' => __( 'Bolívar soberano', 'woocommerce' ), + 'VND' => __( 'Vietnamese đồng', 'woocommerce' ), + 'VUV' => __( 'Vanuatu vatu', 'woocommerce' ), + 'WST' => __( 'Samoan tālā', 'woocommerce' ), + 'XAF' => __( 'Central African CFA franc', 'woocommerce' ), + 'XCD' => __( 'East Caribbean dollar', 'woocommerce' ), + 'XOF' => __( 'West African CFA franc', 'woocommerce' ), + 'XPF' => __( 'CFP franc', 'woocommerce' ), + 'YER' => __( 'Yemeni rial', 'woocommerce' ), + 'ZAR' => __( 'South African rand', 'woocommerce' ), + 'ZMW' => __( 'Zambian kwacha', 'woocommerce' ), + ) + ) + ); + } + + return $currencies; +} + +/** + * Get all available Currency symbols. + * + * Currency symbols and names should follow the Unicode CLDR recommendation (http://cldr.unicode.org/translation/currency-names) + * + * @since 4.1.0 + * @return array + */ +function get_woocommerce_currency_symbols() { + + $symbols = apply_filters( + 'woocommerce_currency_symbols', + array( + 'AED' => 'د.إ', + 'AFN' => '؋', + 'ALL' => 'L', + 'AMD' => 'AMD', + 'ANG' => 'ƒ', + 'AOA' => 'Kz', + 'ARS' => '$', + 'AUD' => '$', + 'AWG' => 'Afl.', + 'AZN' => 'AZN', + 'BAM' => 'KM', + 'BBD' => '$', + 'BDT' => '৳ ', + 'BGN' => 'лв.', + 'BHD' => '.د.ب', + 'BIF' => 'Fr', + 'BMD' => '$', + 'BND' => '$', + 'BOB' => 'Bs.', + 'BRL' => 'R$', + 'BSD' => '$', + 'BTC' => '฿', + 'BTN' => 'Nu.', + 'BWP' => 'P', + 'BYR' => 'Br', + 'BYN' => 'Br', + 'BZD' => '$', + 'CAD' => '$', + 'CDF' => 'Fr', + 'CHF' => 'CHF', + 'CLP' => '$', + 'CNY' => '¥', + 'COP' => '$', + 'CRC' => '₡', + 'CUC' => '$', + 'CUP' => '$', + 'CVE' => '$', + 'CZK' => 'Kč', + 'DJF' => 'Fr', + 'DKK' => 'DKK', + 'DOP' => 'RD$', + 'DZD' => 'د.ج', + 'EGP' => 'EGP', + 'ERN' => 'Nfk', + 'ETB' => 'Br', + 'EUR' => '€', + 'FJD' => '$', + 'FKP' => '£', + 'GBP' => '£', + 'GEL' => '₾', + 'GGP' => '£', + 'GHS' => '₵', + 'GIP' => '£', + 'GMD' => 'D', + 'GNF' => 'Fr', + 'GTQ' => 'Q', + 'GYD' => '$', + 'HKD' => '$', + 'HNL' => 'L', + 'HRK' => 'kn', + 'HTG' => 'G', + 'HUF' => 'Ft', + 'IDR' => 'Rp', + 'ILS' => '₪', + 'IMP' => '£', + 'INR' => '₹', + 'IQD' => 'ع.د', + 'IRR' => '﷼', + 'IRT' => 'تومان', + 'ISK' => 'kr.', + 'JEP' => '£', + 'JMD' => '$', + 'JOD' => 'د.ا', + 'JPY' => '¥', + 'KES' => 'KSh', + 'KGS' => 'сом', + 'KHR' => '៛', + 'KMF' => 'Fr', + 'KPW' => '₩', + 'KRW' => '₩', + 'KWD' => 'د.ك', + 'KYD' => '$', + 'KZT' => '₸', + 'LAK' => '₭', + 'LBP' => 'ل.ل', + 'LKR' => 'රු', + 'LRD' => '$', + 'LSL' => 'L', + 'LYD' => 'ل.د', + 'MAD' => 'د.م.', + 'MDL' => 'MDL', + 'MGA' => 'Ar', + 'MKD' => 'ден', + 'MMK' => 'Ks', + 'MNT' => '₮', + 'MOP' => 'P', + 'MRU' => 'UM', + 'MUR' => '₨', + 'MVR' => '.ރ', + 'MWK' => 'MK', + 'MXN' => '$', + 'MYR' => 'RM', + 'MZN' => 'MT', + 'NAD' => 'N$', + 'NGN' => '₦', + 'NIO' => 'C$', + 'NOK' => 'kr', + 'NPR' => '₨', + 'NZD' => '$', + 'OMR' => 'ر.ع.', + 'PAB' => 'B/.', + 'PEN' => 'S/', + 'PGK' => 'K', + 'PHP' => '₱', + 'PKR' => '₨', + 'PLN' => 'zł', + 'PRB' => 'р.', + 'PYG' => '₲', + 'QAR' => 'ر.ق', + 'RMB' => '¥', + 'RON' => 'lei', + 'RSD' => 'рсд', + 'RUB' => '₽', + 'RWF' => 'Fr', + 'SAR' => 'ر.س', + 'SBD' => '$', + 'SCR' => '₨', + 'SDG' => 'ج.س.', + 'SEK' => 'kr', + 'SGD' => '$', + 'SHP' => '£', + 'SLL' => 'Le', + 'SOS' => 'Sh', + 'SRD' => '$', + 'SSP' => '£', + 'STN' => 'Db', + 'SYP' => 'ل.س', + 'SZL' => 'L', + 'THB' => '฿', + 'TJS' => 'ЅМ', + 'TMT' => 'm', + 'TND' => 'د.ت', + 'TOP' => 'T$', + 'TRY' => '₺', + 'TTD' => '$', + 'TWD' => 'NT$', + 'TZS' => 'Sh', + 'UAH' => '₴', + 'UGX' => 'UGX', + 'USD' => '$', + 'UYU' => '$', + 'UZS' => 'UZS', + 'VEF' => 'Bs F', + 'VES' => 'Bs.S', + 'VND' => '₫', + 'VUV' => 'Vt', + 'WST' => 'T', + 'XAF' => 'CFA', + 'XCD' => '$', + 'XOF' => 'CFA', + 'XPF' => 'Fr', + 'YER' => '﷼', + 'ZAR' => 'R', + 'ZMW' => 'ZK', + ) + ); + + return $symbols; +} + +/** + * Get Currency symbol. + * + * Currency symbols and names should follow the Unicode CLDR recommendation (http://cldr.unicode.org/translation/currency-names) + * + * @param string $currency Currency. (default: ''). + * @return string + */ +function get_woocommerce_currency_symbol( $currency = '' ) { + if ( ! $currency ) { + $currency = get_woocommerce_currency(); + } + + $symbols = get_woocommerce_currency_symbols(); + + $currency_symbol = isset( $symbols[ $currency ] ) ? $symbols[ $currency ] : ''; + + return apply_filters( 'woocommerce_currency_symbol', $currency_symbol, $currency ); +} + +/** + * Send HTML emails from WooCommerce. + * + * @param mixed $to Receiver. + * @param mixed $subject Subject. + * @param mixed $message Message. + * @param string $headers Headers. (default: "Content-Type: text/html\r\n"). + * @param string $attachments Attachments. (default: ""). + * @return bool + */ +function wc_mail( $to, $subject, $message, $headers = "Content-Type: text/html\r\n", $attachments = '' ) { + $mailer = WC()->mailer(); + + return $mailer->send( $to, $subject, $message, $headers, $attachments ); +} + +/** + * Return "theme support" values from the current theme, if set. + * + * @since 3.3.0 + * @param string $prop Name of prop (or key::subkey for arrays of props) if you want a specific value. Leave blank to get all props as an array. + * @param mixed $default Optional value to return if the theme does not declare support for a prop. + * @return mixed Value of prop(s). + */ +function wc_get_theme_support( $prop = '', $default = null ) { + $theme_support = get_theme_support( 'woocommerce' ); + $theme_support = is_array( $theme_support ) ? $theme_support[0] : false; + + if ( ! $theme_support ) { + return $default; + } + + if ( $prop ) { + $prop_stack = explode( '::', $prop ); + $prop_key = array_shift( $prop_stack ); + + if ( isset( $theme_support[ $prop_key ] ) ) { + $value = $theme_support[ $prop_key ]; + + if ( count( $prop_stack ) ) { + foreach ( $prop_stack as $prop_key ) { + if ( is_array( $value ) && isset( $value[ $prop_key ] ) ) { + $value = $value[ $prop_key ]; + } else { + $value = $default; + break; + } + } + } + } else { + $value = $default; + } + + return $value; + } + + return $theme_support; +} + +/** + * Get an image size by name or defined dimensions. + * + * The returned variable is filtered by woocommerce_get_image_size_{image_size} filter to + * allow 3rd party customisation. + * + * Sizes defined by the theme take priority over settings. Settings are hidden when a theme + * defines sizes. + * + * @param array|string $image_size Name of the image size to get, or an array of dimensions. + * @return array Array of dimensions including width, height, and cropping mode. Cropping mode is 0 for no crop, and 1 for hard crop. + */ +function wc_get_image_size( $image_size ) { + $cache_key = 'size-' . ( is_array( $image_size ) ? implode( '-', $image_size ) : $image_size ); + $size = wp_cache_get( $cache_key, 'woocommerce' ); + + if ( $size ) { + return $size; + } + + $size = array( + 'width' => 600, + 'height' => 600, + 'crop' => 1, + ); + + if ( is_array( $image_size ) ) { + $size = array( + 'width' => isset( $image_size[0] ) ? absint( $image_size[0] ) : 600, + 'height' => isset( $image_size[1] ) ? absint( $image_size[1] ) : 600, + 'crop' => isset( $image_size[2] ) ? absint( $image_size[2] ) : 1, + ); + $image_size = $size['width'] . '_' . $size['height']; + } else { + $image_size = str_replace( 'woocommerce_', '', $image_size ); + + // Legacy size mapping. + if ( 'shop_single' === $image_size ) { + $image_size = 'single'; + } elseif ( 'shop_catalog' === $image_size ) { + $image_size = 'thumbnail'; + } elseif ( 'shop_thumbnail' === $image_size ) { + $image_size = 'gallery_thumbnail'; + } + + if ( 'single' === $image_size ) { + $size['width'] = absint( wc_get_theme_support( 'single_image_width', get_option( 'woocommerce_single_image_width', 600 ) ) ); + $size['height'] = ''; + $size['crop'] = 0; + + } elseif ( 'gallery_thumbnail' === $image_size ) { + $size['width'] = absint( wc_get_theme_support( 'gallery_thumbnail_image_width', 100 ) ); + $size['height'] = $size['width']; + $size['crop'] = 1; + + } elseif ( 'thumbnail' === $image_size ) { + $size['width'] = absint( wc_get_theme_support( 'thumbnail_image_width', get_option( 'woocommerce_thumbnail_image_width', 300 ) ) ); + $cropping = get_option( 'woocommerce_thumbnail_cropping', '1:1' ); + + if ( 'uncropped' === $cropping ) { + $size['height'] = ''; + $size['crop'] = 0; + } elseif ( 'custom' === $cropping ) { + $width = max( 1, get_option( 'woocommerce_thumbnail_cropping_custom_width', '4' ) ); + $height = max( 1, get_option( 'woocommerce_thumbnail_cropping_custom_height', '3' ) ); + $size['height'] = absint( NumberUtil::round( ( $size['width'] / $width ) * $height ) ); + $size['crop'] = 1; + } else { + $cropping_split = explode( ':', $cropping ); + $width = max( 1, current( $cropping_split ) ); + $height = max( 1, end( $cropping_split ) ); + $size['height'] = absint( NumberUtil::round( ( $size['width'] / $width ) * $height ) ); + $size['crop'] = 1; + } + } + } + + $size = apply_filters( 'woocommerce_get_image_size_' . $image_size, $size ); + + wp_cache_set( $cache_key, $size, 'woocommerce' ); + + return $size; +} + +/** + * Queue some JavaScript code to be output in the footer. + * + * @param string $code Code. + */ +function wc_enqueue_js( $code ) { + global $wc_queued_js; + + if ( empty( $wc_queued_js ) ) { + $wc_queued_js = ''; + } + + $wc_queued_js .= "\n" . $code . "\n"; +} + +/** + * Output any queued javascript code in the footer. + */ +function wc_print_js() { + global $wc_queued_js; + + if ( ! empty( $wc_queued_js ) ) { + // Sanitize. + $wc_queued_js = wp_check_invalid_utf8( $wc_queued_js ); + $wc_queued_js = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", $wc_queued_js ); + $wc_queued_js = str_replace( "\r", '', $wc_queued_js ); + + $js = "\n\n"; + + /** + * Queued jsfilter. + * + * @since 2.6.0 + * @param string $js JavaScript code. + */ + echo apply_filters( 'woocommerce_queued_js', $js ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + unset( $wc_queued_js ); + } +} + +/** + * Set a cookie - wrapper for setcookie using WP constants. + * + * @param string $name Name of the cookie being set. + * @param string $value Value of the cookie. + * @param integer $expire Expiry of the cookie. + * @param bool $secure Whether the cookie should be served only over https. + * @param bool $httponly Whether the cookie is only accessible over HTTP, not scripting languages like JavaScript. @since 3.6.0. + */ +function wc_setcookie( $name, $value, $expire = 0, $secure = false, $httponly = false ) { + if ( ! headers_sent() ) { + setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure, apply_filters( 'woocommerce_cookie_httponly', $httponly, $name, $value, $expire, $secure ) ); + } elseif ( Constants::is_true( 'WP_DEBUG' ) ) { + headers_sent( $file, $line ); + trigger_error( "{$name} cookie cannot be set - headers already sent by {$file} on line {$line}", E_USER_NOTICE ); // @codingStandardsIgnoreLine + } +} + +/** + * Get the URL to the WooCommerce REST API. + * + * @since 2.1 + * @param string $path an endpoint to include in the URL. + * @return string the URL. + */ +function get_woocommerce_api_url( $path ) { + if ( Constants::is_defined( 'WC_API_REQUEST_VERSION' ) ) { + $version = Constants::get_constant( 'WC_API_REQUEST_VERSION' ); + } else { + $version = substr( WC_API::VERSION, 0, 1 ); + } + + $url = get_home_url( null, "wc-api/v{$version}/", is_ssl() ? 'https' : 'http' ); + + if ( ! empty( $path ) && is_string( $path ) ) { + $url .= ltrim( $path, '/' ); + } + + return $url; +} + +/** + * Get a log file path. + * + * @since 2.2 + * + * @param string $handle name. + * @return string the log file path. + */ +function wc_get_log_file_path( $handle ) { + return WC_Log_Handler_File::get_log_file_path( $handle ); +} + +/** + * Get a log file name. + * + * @since 3.3 + * + * @param string $handle Name. + * @return string The log file name. + */ +function wc_get_log_file_name( $handle ) { + return WC_Log_Handler_File::get_log_file_name( $handle ); +} + +/** + * Recursively get page children. + * + * @param int $page_id Page ID. + * @return int[] + */ +function wc_get_page_children( $page_id ) { + $page_ids = get_posts( + array( + 'post_parent' => $page_id, + 'post_type' => 'page', + 'numberposts' => -1, // @codingStandardsIgnoreLine + 'post_status' => 'any', + 'fields' => 'ids', + ) + ); + + if ( ! empty( $page_ids ) ) { + foreach ( $page_ids as $page_id ) { + $page_ids = array_merge( $page_ids, wc_get_page_children( $page_id ) ); + } + } + + return $page_ids; +} + +/** + * Flushes rewrite rules when the shop page (or it's children) gets saved. + */ +function flush_rewrite_rules_on_shop_page_save() { + $screen = get_current_screen(); + $screen_id = $screen ? $screen->id : ''; + + // Check if this is the edit page. + if ( 'page' !== $screen_id ) { + return; + } + + // Check if page is edited. + if ( empty( $_GET['post'] ) || empty( $_GET['action'] ) || ( isset( $_GET['action'] ) && 'edit' !== $_GET['action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + return; + } + + $post_id = intval( $_GET['post'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $shop_page_id = wc_get_page_id( 'shop' ); + + if ( $shop_page_id === $post_id || in_array( $post_id, wc_get_page_children( $shop_page_id ), true ) ) { + do_action( 'woocommerce_flush_rewrite_rules' ); + } +} +add_action( 'admin_footer', 'flush_rewrite_rules_on_shop_page_save' ); + +/** + * Various rewrite rule fixes. + * + * @since 2.2 + * @param array $rules Rules. + * @return array + */ +function wc_fix_rewrite_rules( $rules ) { + global $wp_rewrite; + + $permalinks = wc_get_permalink_structure(); + + // Fix the rewrite rules when the product permalink have %product_cat% flag. + if ( preg_match( '`/(.+)(/%product_cat%)`', $permalinks['product_rewrite_slug'], $matches ) ) { + foreach ( $rules as $rule => $rewrite ) { + if ( preg_match( '`^' . preg_quote( $matches[1], '`' ) . '/\(`', $rule ) && preg_match( '/^(index\.php\?product_cat)(?!(.*product))/', $rewrite ) ) { + unset( $rules[ $rule ] ); + } + } + } + + // If the shop page is used as the base, we need to handle shop page subpages to avoid 404s. + if ( ! $permalinks['use_verbose_page_rules'] ) { + return $rules; + } + + $shop_page_id = wc_get_page_id( 'shop' ); + if ( $shop_page_id ) { + $page_rewrite_rules = array(); + $subpages = wc_get_page_children( $shop_page_id ); + + // Subpage rules. + foreach ( $subpages as $subpage ) { + $uri = get_page_uri( $subpage ); + $page_rewrite_rules[ $uri . '/?$' ] = 'index.php?pagename=' . $uri; + $wp_generated_rewrite_rules = $wp_rewrite->generate_rewrite_rules( $uri, EP_PAGES, true, true, false, false ); + foreach ( $wp_generated_rewrite_rules as $key => $value ) { + $wp_generated_rewrite_rules[ $key ] = $value . '&pagename=' . $uri; + } + $page_rewrite_rules = array_merge( $page_rewrite_rules, $wp_generated_rewrite_rules ); + } + + // Merge with rules. + $rules = array_merge( $page_rewrite_rules, $rules ); + } + + return $rules; +} +add_filter( 'rewrite_rules_array', 'wc_fix_rewrite_rules' ); + +/** + * Prevent product attachment links from breaking when using complex rewrite structures. + * + * @param string $link Link. + * @param int $post_id Post ID. + * @return string + */ +function wc_fix_product_attachment_link( $link, $post_id ) { + $parent_type = get_post_type( wp_get_post_parent_id( $post_id ) ); + if ( 'product' === $parent_type || 'product_variation' === $parent_type ) { + $link = home_url( '/?attachment_id=' . $post_id ); + } + return $link; +} +add_filter( 'attachment_link', 'wc_fix_product_attachment_link', 10, 2 ); + +/** + * Protect downloads from ms-files.php in multisite. + * + * @param string $rewrite rewrite rules. + * @return string + */ +function wc_ms_protect_download_rewite_rules( $rewrite ) { + if ( ! is_multisite() || 'redirect' === get_option( 'woocommerce_file_download_method' ) ) { + return $rewrite; + } + + $rule = "\n# WooCommerce Rules - Protect Files from ms-files.php\n\n"; + $rule .= "\n"; + $rule .= "RewriteEngine On\n"; + $rule .= "RewriteCond %{QUERY_STRING} file=woocommerce_uploads/ [NC]\n"; + $rule .= "RewriteRule /ms-files.php$ - [F]\n"; + $rule .= "\n\n"; + + return $rule . $rewrite; +} +add_filter( 'mod_rewrite_rules', 'wc_ms_protect_download_rewite_rules' ); + +/** + * Formats a string in the format COUNTRY:STATE into an array. + * + * @since 2.3.0 + * @param string $country_string Country string. + * @return array + */ +function wc_format_country_state_string( $country_string ) { + if ( strstr( $country_string, ':' ) ) { + list( $country, $state ) = explode( ':', $country_string ); + } else { + $country = $country_string; + $state = ''; + } + return array( + 'country' => $country, + 'state' => $state, + ); +} + +/** + * Get the store's base location. + * + * @since 2.3.0 + * @return array + */ +function wc_get_base_location() { + $default = apply_filters( 'woocommerce_get_base_location', get_option( 'woocommerce_default_country' ) ); + + return wc_format_country_state_string( $default ); +} + +/** + * Get the customer's default location. + * + * Filtered, and set to base location or left blank. If cache-busting, + * this should only be used when 'location' is set in the querystring. + * + * @since 2.3.0 + * @return array + */ +function wc_get_customer_default_location() { + $set_default_location_to = get_option( 'woocommerce_default_customer_address', 'base' ); + $default_location = '' === $set_default_location_to ? '' : get_option( 'woocommerce_default_country', '' ); + $location = wc_format_country_state_string( apply_filters( 'woocommerce_customer_default_location', $default_location ) ); + + // Geolocation takes priority if used and if geolocation is possible. + if ( 'geolocation' === $set_default_location_to || 'geolocation_ajax' === $set_default_location_to ) { + $ua = wc_get_user_agent(); + + // Exclude common bots from geolocation by user agent. + if ( ! stristr( $ua, 'bot' ) && ! stristr( $ua, 'spider' ) && ! stristr( $ua, 'crawl' ) ) { + $geolocation = WC_Geolocation::geolocate_ip( '', true, false ); + + if ( ! empty( $geolocation['country'] ) ) { + $location = $geolocation; + } + } + } + + // Once we have a location, ensure it's valid, otherwise fallback to a valid location. + $allowed_country_codes = WC()->countries->get_allowed_countries(); + + if ( ! empty( $location['country'] ) && ! array_key_exists( $location['country'], $allowed_country_codes ) ) { + $location['country'] = current( array_keys( $allowed_country_codes ) ); + $location['state'] = ''; + } + + return apply_filters( 'woocommerce_customer_default_location_array', $location ); +} + +/** + * Get user agent string. + * + * @since 3.0.0 + * @return string + */ +function wc_get_user_agent() { + return isset( $_SERVER['HTTP_USER_AGENT'] ) ? wc_clean( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : ''; // @codingStandardsIgnoreLine +} + +/** + * Generate a rand hash. + * + * @since 2.4.0 + * @return string + */ +function wc_rand_hash() { + if ( ! function_exists( 'openssl_random_pseudo_bytes' ) ) { + return sha1( wp_rand() ); + } + + return bin2hex( openssl_random_pseudo_bytes( 20 ) ); // @codingStandardsIgnoreLine +} + +/** + * WC API - Hash. + * + * @since 2.4.0 + * @param string $data Message to be hashed. + * @return string + */ +function wc_api_hash( $data ) { + return hash_hmac( 'sha256', $data, 'wc-api' ); +} + +/** + * Find all possible combinations of values from the input array and return in a logical order. + * + * @since 2.5.0 + * @param array $input Input. + * @return array + */ +function wc_array_cartesian( $input ) { + $input = array_filter( $input ); + $results = array(); + $indexes = array(); + $index = 0; + + // Generate indexes from keys and values so we have a logical sort order. + foreach ( $input as $key => $values ) { + foreach ( $values as $value ) { + $indexes[ $key ][ $value ] = $index++; + } + } + + // Loop over the 2D array of indexes and generate all combinations. + foreach ( $indexes as $key => $values ) { + // When result is empty, fill with the values of the first looped array. + if ( empty( $results ) ) { + foreach ( $values as $value ) { + $results[] = array( $key => $value ); + } + } else { + // Second and subsequent input sub-array merging. + foreach ( $results as $result_key => $result ) { + foreach ( $values as $value ) { + // If the key is not set, we can set it. + if ( ! isset( $results[ $result_key ][ $key ] ) ) { + $results[ $result_key ][ $key ] = $value; + } else { + // If the key is set, we can add a new combination to the results array. + $new_combination = $results[ $result_key ]; + $new_combination[ $key ] = $value; + $results[] = $new_combination; + } + } + } + } + } + + // Sort the indexes. + arsort( $results ); + + // Convert indexes back to values. + foreach ( $results as $result_key => $result ) { + $converted_values = array(); + + // Sort the values. + arsort( $results[ $result_key ] ); + + // Convert the values. + foreach ( $results[ $result_key ] as $key => $value ) { + $converted_values[ $key ] = array_search( $value, $indexes[ $key ], true ); + } + + $results[ $result_key ] = $converted_values; + } + + return $results; +} + +/** + * Run a MySQL transaction query, if supported. + * + * @since 2.5.0 + * @param string $type Types: start (default), commit, rollback. + * @param bool $force use of transactions. + */ +function wc_transaction_query( $type = 'start', $force = false ) { + global $wpdb; + + $wpdb->hide_errors(); + + wc_maybe_define_constant( 'WC_USE_TRANSACTIONS', true ); + + if ( Constants::is_true( 'WC_USE_TRANSACTIONS' ) || $force ) { + switch ( $type ) { + case 'commit': + $wpdb->query( 'COMMIT' ); + break; + case 'rollback': + $wpdb->query( 'ROLLBACK' ); + break; + default: + $wpdb->query( 'START TRANSACTION' ); + break; + } + } +} + +/** + * Gets the url to the cart page. + * + * @since 2.5.0 + * + * @return string Url to cart page + */ +function wc_get_cart_url() { + return apply_filters( 'woocommerce_get_cart_url', wc_get_page_permalink( 'cart' ) ); +} + +/** + * Gets the url to the checkout page. + * + * @since 2.5.0 + * + * @return string Url to checkout page + */ +function wc_get_checkout_url() { + $checkout_url = wc_get_page_permalink( 'checkout' ); + if ( $checkout_url ) { + // Force SSL if needed. + if ( is_ssl() || 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) ) { + $checkout_url = str_replace( 'http:', 'https:', $checkout_url ); + } + } + + return apply_filters( 'woocommerce_get_checkout_url', $checkout_url ); +} + +/** + * Register a shipping method. + * + * @since 1.5.7 + * @param string|object $shipping_method class name (string) or a class object. + */ +function woocommerce_register_shipping_method( $shipping_method ) { + WC()->shipping()->register_shipping_method( $shipping_method ); +} + +if ( ! function_exists( 'wc_get_shipping_zone' ) ) { + /** + * Get the shipping zone matching a given package from the cart. + * + * @since 2.6.0 + * @uses WC_Shipping_Zones::get_zone_matching_package + * @param array $package Shipping package. + * @return WC_Shipping_Zone + */ + function wc_get_shipping_zone( $package ) { + return WC_Shipping_Zones::get_zone_matching_package( $package ); + } +} + +/** + * Get a nice name for credit card providers. + * + * @since 2.6.0 + * @param string $type Provider Slug/Type. + * @return string + */ +function wc_get_credit_card_type_label( $type ) { + // Normalize. + $type = strtolower( $type ); + $type = str_replace( '-', ' ', $type ); + $type = str_replace( '_', ' ', $type ); + + $labels = apply_filters( + 'woocommerce_credit_card_type_labels', + array( + 'mastercard' => __( 'MasterCard', 'woocommerce' ), + 'visa' => __( 'Visa', 'woocommerce' ), + 'discover' => __( 'Discover', 'woocommerce' ), + 'american express' => __( 'American Express', 'woocommerce' ), + 'diners' => __( 'Diners', 'woocommerce' ), + 'jcb' => __( 'JCB', 'woocommerce' ), + ) + ); + + return apply_filters( 'woocommerce_get_credit_card_type_label', ( array_key_exists( $type, $labels ) ? $labels[ $type ] : ucfirst( $type ) ) ); +} + +/** + * Outputs a "back" link so admin screens can easily jump back a page. + * + * @param string $label Title of the page to return to. + * @param string $url URL of the page to return to. + */ +function wc_back_link( $label, $url ) { + echo ''; +} + +/** + * Display a WooCommerce help tip. + * + * @since 2.5.0 + * + * @param string $tip Help tip text. + * @param bool $allow_html Allow sanitized HTML if true or escape. + * @return string + */ +function wc_help_tip( $tip, $allow_html = false ) { + if ( $allow_html ) { + $tip = wc_sanitize_tooltip( $tip ); + } else { + $tip = esc_attr( $tip ); + } + + return ''; +} + +/** + * Return a list of potential postcodes for wildcard searching. + * + * @since 2.6.0 + * @param string $postcode Postcode. + * @param string $country Country to format postcode for matching. + * @return string[] + */ +function wc_get_wildcard_postcodes( $postcode, $country = '' ) { + $formatted_postcode = wc_format_postcode( $postcode, $country ); + $length = function_exists( 'mb_strlen' ) ? mb_strlen( $formatted_postcode ) : strlen( $formatted_postcode ); + $postcodes = array( + $postcode, + $formatted_postcode, + $formatted_postcode . '*', + ); + + for ( $i = 0; $i < $length; $i ++ ) { + $postcodes[] = ( function_exists( 'mb_substr' ) ? mb_substr( $formatted_postcode, 0, ( $i + 1 ) * -1 ) : substr( $formatted_postcode, 0, ( $i + 1 ) * -1 ) ) . '*'; + } + + return $postcodes; +} + +/** + * Used by shipping zones and taxes to compare a given $postcode to stored + * postcodes to find matches for numerical ranges, and wildcards. + * + * @since 2.6.0 + * @param string $postcode Postcode you want to match against stored postcodes. + * @param array $objects Array of postcode objects from Database. + * @param string $object_id_key DB column name for the ID. + * @param string $object_compare_key DB column name for the value. + * @param string $country Country from which this postcode belongs. Allows for formatting. + * @return array Array of matching object ID and matching values. + */ +function wc_postcode_location_matcher( $postcode, $objects, $object_id_key, $object_compare_key, $country = '' ) { + $postcode = wc_normalize_postcode( $postcode ); + $wildcard_postcodes = array_map( 'wc_clean', wc_get_wildcard_postcodes( $postcode, $country ) ); + $matches = array(); + + foreach ( $objects as $object ) { + $object_id = $object->$object_id_key; + $compare_against = $object->$object_compare_key; + + // Handle postcodes containing ranges. + if ( strstr( $compare_against, '...' ) ) { + $range = array_map( 'trim', explode( '...', $compare_against ) ); + + if ( 2 !== count( $range ) ) { + continue; + } + + list( $min, $max ) = $range; + + // If the postcode is non-numeric, make it numeric. + if ( ! is_numeric( $min ) || ! is_numeric( $max ) ) { + $compare = wc_make_numeric_postcode( $postcode ); + $min = str_pad( wc_make_numeric_postcode( $min ), strlen( $compare ), '0' ); + $max = str_pad( wc_make_numeric_postcode( $max ), strlen( $compare ), '0' ); + } else { + $compare = $postcode; + } + + if ( $compare >= $min && $compare <= $max ) { + $matches[ $object_id ] = isset( $matches[ $object_id ] ) ? $matches[ $object_id ] : array(); + $matches[ $object_id ][] = $compare_against; + } + } elseif ( in_array( $compare_against, $wildcard_postcodes, true ) ) { + // Wildcard and standard comparison. + $matches[ $object_id ] = isset( $matches[ $object_id ] ) ? $matches[ $object_id ] : array(); + $matches[ $object_id ][] = $compare_against; + } + } + + return $matches; +} + +/** + * Gets number of shipping methods currently enabled. Used to identify if + * shipping is configured. + * + * @since 2.6.0 + * @param bool $include_legacy Count legacy shipping methods too. + * @param bool $enabled_only Whether non-legacy shipping methods should be + * restricted to enabled ones. It doesn't affect + * legacy shipping methods. @since 4.3.0. + * @return int + */ +function wc_get_shipping_method_count( $include_legacy = false, $enabled_only = false ) { + global $wpdb; + + $transient_name = $include_legacy ? 'wc_shipping_method_count_legacy' : 'wc_shipping_method_count'; + $transient_version = WC_Cache_Helper::get_transient_version( 'shipping' ); + $transient_value = get_transient( $transient_name ); + + if ( isset( $transient_value['value'], $transient_value['version'] ) && $transient_value['version'] === $transient_version ) { + return absint( $transient_value['value'] ); + } + + $where_clause = $enabled_only ? 'WHERE is_enabled=1' : ''; + $method_count = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_shipping_zone_methods ${where_clause}" ) ); + + if ( $include_legacy ) { + // Count activated methods that don't support shipping zones. + $methods = WC()->shipping()->get_shipping_methods(); + + foreach ( $methods as $method ) { + if ( isset( $method->enabled ) && 'yes' === $method->enabled && ! $method->supports( 'shipping-zones' ) ) { + $method_count++; + } + } + } + + $transient_value = array( + 'version' => $transient_version, + 'value' => $method_count, + ); + + set_transient( $transient_name, $transient_value, DAY_IN_SECONDS * 30 ); + + return $method_count; +} + +/** + * Wrapper for set_time_limit to see if it is enabled. + * + * @since 2.6.0 + * @param int $limit Time limit. + */ +function wc_set_time_limit( $limit = 0 ) { + if ( function_exists( 'set_time_limit' ) && false === strpos( ini_get( 'disable_functions' ), 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved + @set_time_limit( $limit ); // @codingStandardsIgnoreLine + } +} + +/** + * Wrapper for nocache_headers which also disables page caching. + * + * @since 3.2.4 + */ +function wc_nocache_headers() { + WC_Cache_Helper::set_nocache_constants(); + nocache_headers(); +} + +/** + * Used to sort products attributes with uasort. + * + * @since 2.6.0 + * @param array $a First attribute to compare. + * @param array $b Second attribute to compare. + * @return int + */ +function wc_product_attribute_uasort_comparison( $a, $b ) { + $a_position = is_null( $a ) ? null : $a['position']; + $b_position = is_null( $b ) ? null : $b['position']; + return wc_uasort_comparison( $a_position, $b_position ); +} + +/** + * Used to sort shipping zone methods with uasort. + * + * @since 3.0.0 + * @param array $a First shipping zone method to compare. + * @param array $b Second shipping zone method to compare. + * @return int + */ +function wc_shipping_zone_method_order_uasort_comparison( $a, $b ) { + return wc_uasort_comparison( $a->method_order, $b->method_order ); +} + +/** + * User to sort checkout fields based on priority with uasort. + * + * @since 3.5.1 + * @param array $a First field to compare. + * @param array $b Second field to compare. + * @return int + */ +function wc_checkout_fields_uasort_comparison( $a, $b ) { + /* + * We are not guaranteed to get a priority + * setting. So don't compare if they don't + * exist. + */ + if ( ! isset( $a['priority'], $b['priority'] ) ) { + return 0; + } + + return wc_uasort_comparison( $a['priority'], $b['priority'] ); +} + +/** + * User to sort two values with ausort. + * + * @since 3.5.1 + * @param int $a First value to compare. + * @param int $b Second value to compare. + * @return int + */ +function wc_uasort_comparison( $a, $b ) { + if ( $a === $b ) { + return 0; + } + return ( $a < $b ) ? -1 : 1; +} + +/** + * Sort values based on ascii, usefull for special chars in strings. + * + * @param string $a First value. + * @param string $b Second value. + * @return int + */ +function wc_ascii_uasort_comparison( $a, $b ) { + // phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged + if ( function_exists( 'iconv' ) && defined( 'ICONV_IMPL' ) && @strcasecmp( ICONV_IMPL, 'unknown' ) !== 0 ) { + $a = @iconv( 'UTF-8', 'ASCII//TRANSLIT//IGNORE', $a ); + $b = @iconv( 'UTF-8', 'ASCII//TRANSLIT//IGNORE', $b ); + } + // phpcs:enable WordPress.PHP.NoSilencedErrors.Discouraged + + return strcmp( $a, $b ); +} + +/** + * Sort array according to current locale rules and maintaining index association. + * By default tries to use Collator from PHP Internationalization Functions if available. + * If PHP Collator class doesn't exists it fallback to removing accepts from a array + * and by sorting with `uasort( $data, 'strcmp' )` giving support for ASCII values. + * + * @since 4.6.0 + * @param array $data List of values to sort. + * @param string $locale Locale. + * @return array + */ +function wc_asort_by_locale( &$data, $locale = '' ) { + // Use Collator if PHP Internationalization Functions (php-intl) is available. + if ( class_exists( 'Collator' ) ) { + $locale = $locale ? $locale : get_locale(); + $collator = new Collator( $locale ); + $collator->asort( $data, Collator::SORT_STRING ); + return $data; + } + + $raw_data = $data; + + array_walk( + $data, + function ( &$value ) { + $value = remove_accents( html_entity_decode( $value ) ); + } + ); + + uasort( $data, 'strcmp' ); + + foreach ( $data as $key => $val ) { + $data[ $key ] = $raw_data[ $key ]; + } + + return $data; +} + +/** + * Get rounding mode for internal tax calculations. + * + * @since 3.2.4 + * @return int + */ +function wc_get_tax_rounding_mode() { + $constant = WC_TAX_ROUNDING_MODE; + + if ( 'auto' === $constant ) { + return 'yes' === get_option( 'woocommerce_prices_include_tax', 'no' ) ? 2 : 1; + } + + return intval( $constant ); +} + +/** + * Get rounding precision for internal WC calculations. + * Will increase the precision of wc_get_price_decimals by 2 decimals, unless WC_ROUNDING_PRECISION is set to a higher number. + * + * @since 2.6.3 + * @return int + */ +function wc_get_rounding_precision() { + $precision = wc_get_price_decimals() + 2; + if ( absint( WC_ROUNDING_PRECISION ) > $precision ) { + $precision = absint( WC_ROUNDING_PRECISION ); + } + return $precision; +} + +/** + * Add precision to a number and return a number. + * + * @since 3.2.0 + * @param float $value Number to add precision to. + * @param bool $round If should round after adding precision. + * @return int|float + */ +function wc_add_number_precision( $value, $round = true ) { + $cent_precision = pow( 10, wc_get_price_decimals() ); + $value = $value * $cent_precision; + return $round ? NumberUtil::round( $value, wc_get_rounding_precision() - wc_get_price_decimals() ) : $value; +} + +/** + * Remove precision from a number and return a float. + * + * @since 3.2.0 + * @param float $value Number to add precision to. + * @return float + */ +function wc_remove_number_precision( $value ) { + $cent_precision = pow( 10, wc_get_price_decimals() ); + return $value / $cent_precision; +} + +/** + * Add precision to an array of number and return an array of int. + * + * @since 3.2.0 + * @param array $value Number to add precision to. + * @param bool $round Should we round after adding precision?. + * @return int|array + */ +function wc_add_number_precision_deep( $value, $round = true ) { + if ( ! is_array( $value ) ) { + return wc_add_number_precision( $value, $round ); + } + + foreach ( $value as $key => $sub_value ) { + $value[ $key ] = wc_add_number_precision_deep( $sub_value, $round ); + } + + return $value; +} + +/** + * Remove precision from an array of number and return an array of int. + * + * @since 3.2.0 + * @param array $value Number to add precision to. + * @return int|array + */ +function wc_remove_number_precision_deep( $value ) { + if ( ! is_array( $value ) ) { + return wc_remove_number_precision( $value ); + } + + foreach ( $value as $key => $sub_value ) { + $value[ $key ] = wc_remove_number_precision_deep( $sub_value ); + } + + return $value; +} + +/** + * Get a shared logger instance. + * + * Use the woocommerce_logging_class filter to change the logging class. You may provide one of the following: + * - a class name which will be instantiated as `new $class` with no arguments + * - an instance which will be used directly as the logger + * In either case, the class or instance *must* implement WC_Logger_Interface. + * + * @see WC_Logger_Interface + * + * @return WC_Logger + */ +function wc_get_logger() { + static $logger = null; + + $class = apply_filters( 'woocommerce_logging_class', 'WC_Logger' ); + + if ( null !== $logger && is_string( $class ) && is_a( $logger, $class ) ) { + return $logger; + } + + $implements = class_implements( $class ); + + if ( is_array( $implements ) && in_array( 'WC_Logger_Interface', $implements, true ) ) { + $logger = is_object( $class ) ? $class : new $class(); + } else { + wc_doing_it_wrong( + __FUNCTION__, + sprintf( + /* translators: 1: class name 2: woocommerce_logging_class 3: WC_Logger_Interface */ + __( 'The class %1$s provided by %2$s filter must implement %3$s.', 'woocommerce' ), + '' . esc_html( is_object( $class ) ? get_class( $class ) : $class ) . '', + 'woocommerce_logging_class', + 'WC_Logger_Interface' + ), + '3.0' + ); + + $logger = is_a( $logger, 'WC_Logger' ) ? $logger : new WC_Logger(); + } + + return $logger; +} + +/** + * Trigger logging cleanup using the logging class. + * + * @since 3.4.0 + */ +function wc_cleanup_logs() { + $logger = wc_get_logger(); + + if ( is_callable( array( $logger, 'clear_expired_logs' ) ) ) { + $logger->clear_expired_logs(); + } +} +add_action( 'woocommerce_cleanup_logs', 'wc_cleanup_logs' ); + +/** + * Prints human-readable information about a variable. + * + * Some server environments block some debugging functions. This function provides a safe way to + * turn an expression into a printable, readable form without calling blocked functions. + * + * @since 3.0 + * + * @param mixed $expression The expression to be printed. + * @param bool $return Optional. Default false. Set to true to return the human-readable string. + * @return string|bool False if expression could not be printed. True if the expression was printed. + * If $return is true, a string representation will be returned. + */ +function wc_print_r( $expression, $return = false ) { + $alternatives = array( + array( + 'func' => 'print_r', + 'args' => array( $expression, true ), + ), + array( + 'func' => 'var_export', + 'args' => array( $expression, true ), + ), + array( + 'func' => 'json_encode', + 'args' => array( $expression ), + ), + array( + 'func' => 'serialize', + 'args' => array( $expression ), + ), + ); + + $alternatives = apply_filters( 'woocommerce_print_r_alternatives', $alternatives, $expression ); + + foreach ( $alternatives as $alternative ) { + if ( function_exists( $alternative['func'] ) ) { + $res = $alternative['func']( ...$alternative['args'] ); + if ( $return ) { + return $res; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + echo $res; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return true; + } + } + + return false; +} + +/** + * Registers the default log handler. + * + * @since 3.0 + * @param array $handlers Handlers. + * @return array + */ +function wc_register_default_log_handler( $handlers ) { + $handler_class = Constants::get_constant( 'WC_LOG_HANDLER' ); + if ( ! class_exists( $handler_class ) ) { + $handler_class = WC_Log_Handler_File::class; + } + + array_push( $handlers, new $handler_class() ); + + return $handlers; +} +add_filter( 'woocommerce_register_log_handlers', 'wc_register_default_log_handler' ); + +/** + * Based on wp_list_pluck, this calls a method instead of returning a property. + * + * @since 3.0.0 + * @param array $list List of objects or arrays. + * @param int|string $callback_or_field Callback method from the object to place instead of the entire object. + * @param int|string $index_key Optional. Field from the object to use as keys for the new array. + * Default null. + * @return array Array of values. + */ +function wc_list_pluck( $list, $callback_or_field, $index_key = null ) { + // Use wp_list_pluck if this isn't a callback. + $first_el = current( $list ); + if ( ! is_object( $first_el ) || ! is_callable( array( $first_el, $callback_or_field ) ) ) { + return wp_list_pluck( $list, $callback_or_field, $index_key ); + } + if ( ! $index_key ) { + /* + * This is simple. Could at some point wrap array_column() + * if we knew we had an array of arrays. + */ + foreach ( $list as $key => $value ) { + $list[ $key ] = $value->{$callback_or_field}(); + } + return $list; + } + + /* + * When index_key is not set for a particular item, push the value + * to the end of the stack. This is how array_column() behaves. + */ + $newlist = array(); + foreach ( $list as $value ) { + // Get index. @since 3.2.0 this supports a callback. + if ( is_callable( array( $value, $index_key ) ) ) { + $newlist[ $value->{$index_key}() ] = $value->{$callback_or_field}(); + } elseif ( isset( $value->$index_key ) ) { + $newlist[ $value->$index_key ] = $value->{$callback_or_field}(); + } else { + $newlist[] = $value->{$callback_or_field}(); + } + } + return $newlist; +} + +/** + * Get permalink settings for things like products and taxonomies. + * + * As of 3.3.0, the permalink settings are stored to the option instead of + * being blank and inheritting from the locale. This speeds up page loading + * times by negating the need to switch locales on each page load. + * + * This is more inline with WP core behavior which does not localize slugs. + * + * @since 3.0.0 + * @return array + */ +function wc_get_permalink_structure() { + $saved_permalinks = (array) get_option( 'woocommerce_permalinks', array() ); + $permalinks = wp_parse_args( + array_filter( $saved_permalinks ), + array( + 'product_base' => _x( 'product', 'slug', 'woocommerce' ), + 'category_base' => _x( 'product-category', 'slug', 'woocommerce' ), + 'tag_base' => _x( 'product-tag', 'slug', 'woocommerce' ), + 'attribute_base' => '', + 'use_verbose_page_rules' => false, + ) + ); + + if ( $saved_permalinks !== $permalinks ) { + update_option( 'woocommerce_permalinks', $permalinks ); + } + + $permalinks['product_rewrite_slug'] = untrailingslashit( $permalinks['product_base'] ); + $permalinks['category_rewrite_slug'] = untrailingslashit( $permalinks['category_base'] ); + $permalinks['tag_rewrite_slug'] = untrailingslashit( $permalinks['tag_base'] ); + $permalinks['attribute_rewrite_slug'] = untrailingslashit( $permalinks['attribute_base'] ); + + return $permalinks; +} + +/** + * Switch WooCommerce to site language. + * + * @since 3.1.0 + */ +function wc_switch_to_site_locale() { + if ( function_exists( 'switch_to_locale' ) ) { + switch_to_locale( get_locale() ); + + // Filter on plugin_locale so load_plugin_textdomain loads the correct locale. + add_filter( 'plugin_locale', 'get_locale' ); + + // Init WC locale. + WC()->load_plugin_textdomain(); + } +} + +/** + * Switch WooCommerce language to original. + * + * @since 3.1.0 + */ +function wc_restore_locale() { + if ( function_exists( 'restore_previous_locale' ) ) { + restore_previous_locale(); + + // Remove filter. + remove_filter( 'plugin_locale', 'get_locale' ); + + // Init WC locale. + WC()->load_plugin_textdomain(); + } +} + +/** + * Convert plaintext phone number to clickable phone number. + * + * Remove formatting and allow "+". + * Example and specs: https://developer.mozilla.org/en/docs/Web/HTML/Element/a#Creating_a_phone_link + * + * @since 3.1.0 + * + * @param string $phone Content to convert phone number. + * @return string Content with converted phone number. + */ +function wc_make_phone_clickable( $phone ) { + $number = trim( preg_replace( '/[^\d|\+]/', '', $phone ) ); + + return $number ? '' . esc_html( $phone ) . '' : ''; +} + +/** + * Get an item of post data if set, otherwise return a default value. + * + * @since 3.0.9 + * @param string $key Meta key. + * @param string $default Default value. + * @return mixed Value sanitized by wc_clean. + */ +function wc_get_post_data_by_key( $key, $default = '' ) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput, WordPress.Security.NonceVerification.Missing + return wc_clean( wp_unslash( wc_get_var( $_POST[ $key ], $default ) ) ); +} + +/** + * Get data if set, otherwise return a default value or null. Prevents notices when data is not set. + * + * @since 3.2.0 + * @param mixed $var Variable. + * @param string $default Default value. + * @return mixed + */ +function wc_get_var( &$var, $default = null ) { + return isset( $var ) ? $var : $default; +} + +/** + * Read in WooCommerce headers when reading plugin headers. + * + * @since 3.2.0 + * @param array $headers Headers. + * @return array + */ +function wc_enable_wc_plugin_headers( $headers ) { + if ( ! class_exists( 'WC_Plugin_Updates' ) ) { + include_once dirname( __FILE__ ) . '/admin/plugin-updates/class-wc-plugin-updates.php'; + } + + // WC requires at least - allows developers to define which version of WooCommerce the plugin requires to run. + $headers[] = WC_Plugin_Updates::VERSION_REQUIRED_HEADER; + + // WC tested up to - allows developers to define which version of WooCommerce they have tested up to. + $headers[] = WC_Plugin_Updates::VERSION_TESTED_HEADER; + + // Woo - This is used in WooCommerce extensions and is picked up by the helper. + $headers[] = 'Woo'; + + return $headers; +} +add_filter( 'extra_theme_headers', 'wc_enable_wc_plugin_headers' ); +add_filter( 'extra_plugin_headers', 'wc_enable_wc_plugin_headers' ); + +/** + * Prevent auto-updating the WooCommerce plugin on major releases if there are untested extensions active. + * + * @since 3.2.0 + * @param bool $should_update If should update. + * @param object $plugin Plugin data. + * @return bool + */ +function wc_prevent_dangerous_auto_updates( $should_update, $plugin ) { + if ( ! isset( $plugin->plugin, $plugin->new_version ) ) { + return $should_update; + } + + if ( 'woocommerce/woocommerce.php' !== $plugin->plugin ) { + return $should_update; + } + + if ( ! class_exists( 'WC_Plugin_Updates' ) ) { + include_once dirname( __FILE__ ) . '/admin/plugin-updates/class-wc-plugin-updates.php'; + } + + $new_version = wc_clean( $plugin->new_version ); + $plugin_updates = new WC_Plugin_Updates(); + $untested_plugins = $plugin_updates->get_untested_plugins( $new_version, 'major' ); + if ( ! empty( $untested_plugins ) ) { + return false; + } + + return $should_update; +} +add_filter( 'auto_update_plugin', 'wc_prevent_dangerous_auto_updates', 99, 2 ); + +/** + * Delete expired transients. + * + * Deletes all expired transients. The multi-table delete syntax is used. + * to delete the transient record from table a, and the corresponding. + * transient_timeout record from table b. + * + * Based on code inside core's upgrade_network() function. + * + * @since 3.2.0 + * @return int Number of transients that were cleared. + */ +function wc_delete_expired_transients() { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared + $sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b + WHERE a.option_name LIKE %s + AND a.option_name NOT LIKE %s + AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) ) + AND b.option_value < %d"; + $rows = $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_transient_' ) . '%', $wpdb->esc_like( '_transient_timeout_' ) . '%', time() ) ); + + $sql = "DELETE a, b FROM $wpdb->options a, $wpdb->options b + WHERE a.option_name LIKE %s + AND a.option_name NOT LIKE %s + AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) ) + AND b.option_value < %d"; + $rows2 = $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like( '_site_transient_timeout_' ) . '%', time() ) ); + // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared + + return absint( $rows + $rows2 ); +} +add_action( 'woocommerce_installed', 'wc_delete_expired_transients' ); + +/** + * Make a URL relative, if possible. + * + * @since 3.2.0 + * @param string $url URL to make relative. + * @return string + */ +function wc_get_relative_url( $url ) { + return wc_is_external_resource( $url ) ? $url : str_replace( array( 'http://', 'https://' ), '//', $url ); +} + +/** + * See if a resource is remote. + * + * @since 3.2.0 + * @param string $url URL to check. + * @return bool + */ +function wc_is_external_resource( $url ) { + $wp_base = str_replace( array( 'http://', 'https://' ), '//', get_home_url( null, '/', 'http' ) ); + + return strstr( $url, '://' ) && ! strstr( $url, $wp_base ); +} + +/** + * See if theme/s is activate or not. + * + * @since 3.3.0 + * @param string|array $theme Theme name or array of theme names to check. + * @return boolean + */ +function wc_is_active_theme( $theme ) { + return is_array( $theme ) ? in_array( get_template(), $theme, true ) : get_template() === $theme; +} + +/** + * Is the site using a default WP theme? + * + * @return boolean + */ +function wc_is_wp_default_theme_active() { + return wc_is_active_theme( + array( + 'twentytwentyone', + 'twentytwenty', + 'twentynineteen', + 'twentyseventeen', + 'twentysixteen', + 'twentyfifteen', + 'twentyfourteen', + 'twentythirteen', + 'twentyeleven', + 'twentytwelve', + 'twentyten', + ) + ); +} + +/** + * Cleans up session data - cron callback. + * + * @since 3.3.0 + */ +function wc_cleanup_session_data() { + $session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' ); + $session = new $session_class(); + + if ( is_callable( array( $session, 'cleanup_sessions' ) ) ) { + $session->cleanup_sessions(); + } +} +add_action( 'woocommerce_cleanup_sessions', 'wc_cleanup_session_data' ); + +/** + * Convert a decimal (e.g. 3.5) to a fraction (e.g. 7/2). + * From: https://www.designedbyaturtle.co.uk/2015/converting-a-decimal-to-a-fraction-in-php/ + * + * @param float $decimal the decimal number. + * @return array|bool a 1/2 would be [1, 2] array (this can be imploded with '/' to form a string). + */ +function wc_decimal_to_fraction( $decimal ) { + if ( 0 > $decimal || ! is_numeric( $decimal ) ) { + // Negative digits need to be passed in as positive numbers and prefixed as negative once the response is imploded. + return false; + } + + if ( 0 === $decimal ) { + return array( 0, 1 ); + } + + $tolerance = 1.e-4; + $numerator = 1; + $h2 = 0; + $denominator = 0; + $k2 = 1; + $b = 1 / $decimal; + + do { + $b = 1 / $b; + $a = floor( $b ); + $aux = $numerator; + $numerator = $a * $numerator + $h2; + $h2 = $aux; + $aux = $denominator; + $denominator = $a * $denominator + $k2; + $k2 = $aux; + $b = $b - $a; + } while ( abs( $decimal - $numerator / $denominator ) > $decimal * $tolerance ); + + return array( $numerator, $denominator ); +} + +/** + * Round discount. + * + * @param double $value Amount to round. + * @param int $precision DP to round. + * @return float + */ +function wc_round_discount( $value, $precision ) { + if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) ) { + return NumberUtil::round( $value, $precision, WC_DISCOUNT_ROUNDING_MODE ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctionParameters.round_modeFound + } + + if ( 2 === WC_DISCOUNT_ROUNDING_MODE ) { + return wc_legacy_round_half_down( $value, $precision ); + } + + return NumberUtil::round( $value, $precision ); +} + +/** + * Return the html selected attribute if stringified $value is found in array of stringified $options + * or if stringified $value is the same as scalar stringified $options. + * + * @param string|int $value Value to find within options. + * @param string|int|array $options Options to go through when looking for value. + * @return string + */ +function wc_selected( $value, $options ) { + if ( is_array( $options ) ) { + $options = array_map( 'strval', $options ); + return selected( in_array( (string) $value, $options, true ), true, false ); + } + + return selected( $value, $options, false ); +} + +/** + * Retrieves the MySQL server version. Based on $wpdb. + * + * @since 3.4.1 + * @return array Vesion information. + */ +function wc_get_server_database_version() { + global $wpdb; + + if ( empty( $wpdb->is_mysql ) ) { + return array( + 'string' => '', + 'number' => '', + ); + } + + // phpcs:disable WordPress.DB.RestrictedFunctions, PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved + if ( $wpdb->use_mysqli ) { + $server_info = mysqli_get_server_info( $wpdb->dbh ); + } else { + $server_info = mysql_get_server_info( $wpdb->dbh ); + } + // phpcs:enable WordPress.DB.RestrictedFunctions, PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved + + return array( + 'string' => $server_info, + 'number' => preg_replace( '/([^\d.]+).*/', '', $server_info ), + ); +} + +/** + * Initialize and load the cart functionality. + * + * @since 3.6.4 + * @return void + */ +function wc_load_cart() { + if ( ! did_action( 'before_woocommerce_init' ) || doing_action( 'before_woocommerce_init' ) ) { + /* translators: 1: wc_load_cart 2: woocommerce_init */ + wc_doing_it_wrong( __FUNCTION__, sprintf( __( '%1$s should not be called before the %2$s action.', 'woocommerce' ), 'wc_load_cart', 'woocommerce_init' ), '3.7' ); + return; + } + + // Ensure dependencies are loaded in all contexts. + include_once WC_ABSPATH . 'includes/wc-cart-functions.php'; + include_once WC_ABSPATH . 'includes/wc-notice-functions.php'; + + WC()->initialize_session(); + WC()->initialize_cart(); +} + +/** + * Test whether the context of execution comes from async action scheduler. + * + * @since 4.0.0 + * @return bool + */ +function wc_is_running_from_async_action_scheduler() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + return isset( $_REQUEST['action'] ) && 'as_async_request_queue_runner' === $_REQUEST['action']; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-coupon-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-coupon-functions.php new file mode 100644 index 0000000..28ef64a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-coupon-functions.php @@ -0,0 +1,111 @@ + __( 'Percentage discount', 'woocommerce' ), + 'fixed_cart' => __( 'Fixed cart discount', 'woocommerce' ), + 'fixed_product' => __( 'Fixed product discount', 'woocommerce' ), + ) + ); +} + +/** + * Get a coupon type's name. + * + * @param string $type Coupon type. + * @return string + */ +function wc_get_coupon_type( $type = '' ) { + $types = wc_get_coupon_types(); + return isset( $types[ $type ] ) ? $types[ $type ] : ''; +} + +/** + * Coupon types that apply to individual products. Controls which validation rules will apply. + * + * @since 2.5.0 + * @return array + */ +function wc_get_product_coupon_types() { + return (array) apply_filters( 'woocommerce_product_coupon_types', array( 'fixed_product', 'percent' ) ); +} + +/** + * Coupon types that apply to the cart as a whole. Controls which validation rules will apply. + * + * @since 2.5.0 + * @return array + */ +function wc_get_cart_coupon_types() { + return (array) apply_filters( 'woocommerce_cart_coupon_types', array( 'fixed_cart' ) ); +} + +/** + * Check if coupons are enabled. + * Filterable. + * + * @since 2.5.0 + * + * @return bool + */ +function wc_coupons_enabled() { + return apply_filters( 'woocommerce_coupons_enabled', 'yes' === get_option( 'woocommerce_enable_coupons' ) ); +} + +/** + * Get coupon code by ID. + * + * @since 3.0.0 + * @param int $id Coupon ID. + * @return string + */ +function wc_get_coupon_code_by_id( $id ) { + $data_store = WC_Data_Store::load( 'coupon' ); + return empty( $id ) ? '' : (string) $data_store->get_code_by_id( $id ); +} + +/** + * Get coupon ID by code. + * + * @since 3.0.0 + * @param string $code Coupon code. + * @param int $exclude Used to exclude an ID from the check if you're checking existence. + * @return int + */ +function wc_get_coupon_id_by_code( $code, $exclude = 0 ) { + + if ( empty( $code ) ) { + return 0; + } + + $data_store = WC_Data_Store::load( 'coupon' ); + $ids = wp_cache_get( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $code, 'coupons' ); + + if ( false === $ids ) { + $ids = $data_store->get_ids_by_code( $code ); + if ( $ids ) { + wp_cache_set( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $code, $ids, 'coupons' ); + } + } + + $ids = array_diff( array_filter( array_map( 'absint', (array) $ids ) ), array( $exclude ) ); + + return apply_filters( 'woocommerce_get_coupon_id_from_code', absint( current( $ids ) ), $code, $exclude ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-deprecated-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-deprecated-functions.php new file mode 100644 index 0000000..ea5f57f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-deprecated-functions.php @@ -0,0 +1,1125 @@ +is_rest_api_request() ) { + do_action( 'deprecated_function_run', $function, $replacement, $version ); + $log_string = "The {$function} function is deprecated since version {$version}."; + $log_string .= $replacement ? " Replace with {$replacement}." : ''; + error_log( $log_string ); + } else { + _deprecated_function( $function, $version, $replacement ); + } + // @codingStandardsIgnoreEnd +} + +/** + * Wrapper for deprecated hook so we can apply some extra logic. + * + * @since 3.3.0 + * @param string $hook The hook that was used. + * @param string $version The version of WordPress that deprecated the hook. + * @param string $replacement The hook that should have been used. + * @param string $message A message regarding the change. + */ +function wc_deprecated_hook( $hook, $version, $replacement = null, $message = null ) { + // @codingStandardsIgnoreStart + if ( is_ajax() || WC()->is_rest_api_request() ) { + do_action( 'deprecated_hook_run', $hook, $replacement, $version, $message ); + + $message = empty( $message ) ? '' : ' ' . $message; + $log_string = "{$hook} is deprecated since version {$version}"; + $log_string .= $replacement ? "! Use {$replacement} instead." : ' with no alternative available.'; + + error_log( $log_string . $message ); + } else { + _deprecated_hook( $hook, $version, $replacement, $message ); + } + // @codingStandardsIgnoreEnd +} + +/** + * When catching an exception, this allows us to log it if unexpected. + * + * @since 3.3.0 + * @param Exception $exception_object The exception object. + * @param string $function The function which threw exception. + * @param array $args The args passed to the function. + */ +function wc_caught_exception( $exception_object, $function = '', $args = array() ) { + // @codingStandardsIgnoreStart + $message = $exception_object->getMessage(); + $message .= '. Args: ' . print_r( $args, true ) . '.'; + + do_action( 'woocommerce_caught_exception', $exception_object, $function, $args ); + error_log( "Exception caught in {$function}. {$message}." ); + // @codingStandardsIgnoreEnd +} + +/** + * Wrapper for _doing_it_wrong(). + * + * @since 3.0.0 + * @param string $function Function used. + * @param string $message Message to log. + * @param string $version Version the message was added in. + */ +function wc_doing_it_wrong( $function, $message, $version ) { + // @codingStandardsIgnoreStart + $message .= ' Backtrace: ' . wp_debug_backtrace_summary(); + + if ( is_ajax() || WC()->is_rest_api_request() ) { + do_action( 'doing_it_wrong_run', $function, $message, $version ); + error_log( "{$function} was called incorrectly. {$message}. This message was added in version {$version}." ); + } else { + _doing_it_wrong( $function, $message, $version ); + } + // @codingStandardsIgnoreEnd +} + +/** + * Wrapper for deprecated arguments so we can apply some extra logic. + * + * @since 3.0.0 + * @param string $argument + * @param string $version + * @param string $replacement + */ +function wc_deprecated_argument( $argument, $version, $message = null ) { + if ( is_ajax() || WC()->is_rest_api_request() ) { + do_action( 'deprecated_argument_run', $argument, $message, $version ); + error_log( "The {$argument} argument is deprecated since version {$version}. {$message}" ); + } else { + _deprecated_argument( $argument, $version, $message ); + } +} + +/** + * @deprecated 2.1 + */ +function woocommerce_show_messages() { + wc_deprecated_function( 'woocommerce_show_messages', '2.1', 'wc_print_notices' ); + wc_print_notices(); +} + +/** + * @deprecated 2.1 + */ +function woocommerce_weekend_area_js() { + wc_deprecated_function( 'woocommerce_weekend_area_js', '2.1' ); +} + +/** + * @deprecated 2.1 + */ +function woocommerce_tooltip_js() { + wc_deprecated_function( 'woocommerce_tooltip_js', '2.1' ); +} + +/** + * @deprecated 2.1 + */ +function woocommerce_datepicker_js() { + wc_deprecated_function( 'woocommerce_datepicker_js', '2.1' ); +} + +/** + * @deprecated 2.1 + */ +function woocommerce_admin_scripts() { + wc_deprecated_function( 'woocommerce_admin_scripts', '2.1' ); +} + +/** + * @deprecated 2.1 + */ +function woocommerce_create_page( $slug, $option = '', $page_title = '', $page_content = '', $post_parent = 0 ) { + wc_deprecated_function( 'woocommerce_create_page', '2.1', 'wc_create_page' ); + return wc_create_page( $slug, $option, $page_title, $page_content, $post_parent ); +} + +/** + * @deprecated 2.1 + */ +function woocommerce_readfile_chunked( $file, $retbytes = true ) { + wc_deprecated_function( 'woocommerce_readfile_chunked', '2.1', 'WC_Download_Handler::readfile_chunked()' ); + return WC_Download_Handler::readfile_chunked( $file ); +} + +/** + * Formal total costs - format to the number of decimal places for the base currency. + * + * @access public + * @param mixed $number + * @deprecated 2.1 + * @return string + */ +function woocommerce_format_total( $number ) { + wc_deprecated_function( __FUNCTION__, '2.1', 'wc_format_decimal()' ); + return wc_format_decimal( $number, wc_get_price_decimals(), false ); +} + +/** + * Get product name with extra details such as SKU price and attributes. Used within admin. + * + * @access public + * @param WC_Product $product + * @deprecated 2.1 + * @return string + */ +function woocommerce_get_formatted_product_name( $product ) { + wc_deprecated_function( __FUNCTION__, '2.1', 'WC_Product::get_formatted_name()' ); + return $product->get_formatted_name(); +} + +/** + * Handle IPN requests for the legacy paypal gateway by calling gateways manually if needed. + * + * @access public + */ +function woocommerce_legacy_paypal_ipn() { + if ( ! empty( $_GET['paypalListener'] ) && 'paypal_standard_IPN' === $_GET['paypalListener'] ) { + WC()->payment_gateways(); + do_action( 'woocommerce_api_wc_gateway_paypal' ); + } +} +add_action( 'init', 'woocommerce_legacy_paypal_ipn' ); + +/** + * @deprecated 3.0 + */ +function get_product( $the_product = false, $args = array() ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_product' ); + return wc_get_product( $the_product, $args ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_protected_product_add_to_cart( $passed, $product_id ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_protected_product_add_to_cart' ); + return wc_protected_product_add_to_cart( $passed, $product_id ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_empty_cart() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_empty_cart' ); + wc_empty_cart(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_load_persistent_cart( $user_login, $user = 0 ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_load_persistent_cart' ); + return wc_load_persistent_cart( $user_login, $user ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_add_to_cart_message( $product_id ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_add_to_cart_message' ); + wc_add_to_cart_message( $product_id ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_clear_cart_after_payment() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_clear_cart_after_payment' ); + wc_clear_cart_after_payment(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_cart_totals_subtotal_html() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_subtotal_html' ); + wc_cart_totals_subtotal_html(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_cart_totals_shipping_html() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_shipping_html' ); + wc_cart_totals_shipping_html(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_cart_totals_coupon_html( $coupon ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_coupon_html' ); + wc_cart_totals_coupon_html( $coupon ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_cart_totals_order_total_html() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_order_total_html' ); + wc_cart_totals_order_total_html(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_cart_totals_fee_html( $fee ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_fee_html' ); + wc_cart_totals_fee_html( $fee ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_cart_totals_shipping_method_label( $method ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_shipping_method_label' ); + return wc_cart_totals_shipping_method_label( $method ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_template_part( $slug, $name = '' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_template_part' ); + wc_get_template_part( $slug, $name ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_template' ); + wc_get_template( $template_name, $args, $template_path, $default_path ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_locate_template( $template_name, $template_path = '', $default_path = '' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_locate_template' ); + return wc_locate_template( $template_name, $template_path, $default_path ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_mail( $to, $subject, $message, $headers = "Content-Type: text/html\r\n", $attachments = "" ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_mail' ); + wc_mail( $to, $subject, $message, $headers, $attachments ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_disable_admin_bar( $show_admin_bar ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_disable_admin_bar' ); + return wc_disable_admin_bar( $show_admin_bar ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_create_new_customer( $email, $username = '', $password = '' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_create_new_customer' ); + return wc_create_new_customer( $email, $username, $password ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_set_customer_auth_cookie( $customer_id ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_set_customer_auth_cookie' ); + wc_set_customer_auth_cookie( $customer_id ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_update_new_customer_past_orders( $customer_id ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_update_new_customer_past_orders' ); + return wc_update_new_customer_past_orders( $customer_id ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_paying_customer( $order_id ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_paying_customer' ); + wc_paying_customer( $order_id ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_customer_bought_product( $customer_email, $user_id, $product_id ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_customer_bought_product' ); + return wc_customer_bought_product( $customer_email, $user_id, $product_id ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_customer_has_capability( $allcaps, $caps, $args ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_customer_has_capability' ); + return wc_customer_has_capability( $allcaps, $caps, $args ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_sanitize_taxonomy_name( $taxonomy ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_sanitize_taxonomy_name' ); + return wc_sanitize_taxonomy_name( $taxonomy ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_filename_from_url( $file_url ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_filename_from_url' ); + return wc_get_filename_from_url( $file_url ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_dimension( $dim, $to_unit ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_dimension' ); + return wc_get_dimension( $dim, $to_unit ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_weight( $weight, $to_unit ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_weight' ); + return wc_get_weight( $weight, $to_unit ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_trim_zeros( $price ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_trim_zeros' ); + return wc_trim_zeros( $price ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_round_tax_total( $tax ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_round_tax_total' ); + return wc_round_tax_total( $tax ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_format_decimal( $number, $dp = false, $trim_zeros = false ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_format_decimal' ); + return wc_format_decimal( $number, $dp, $trim_zeros ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_clean( $var ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_clean' ); + return wc_clean( $var ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_array_overlay( $a1, $a2 ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_array_overlay' ); + return wc_array_overlay( $a1, $a2 ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_price( $price, $args = array() ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_price' ); + return wc_price( $price, $args ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_let_to_num( $size ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_let_to_num' ); + return wc_let_to_num( $size ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_date_format() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_date_format' ); + return wc_date_format(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_time_format() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_time_format' ); + return wc_time_format(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_timezone_string() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_timezone_string' ); + return wc_timezone_string(); +} + +if ( ! function_exists( 'woocommerce_rgb_from_hex' ) ) { + /** + * @deprecated 3.0 + */ + function woocommerce_rgb_from_hex( $color ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_rgb_from_hex' ); + return wc_rgb_from_hex( $color ); + } +} + +if ( ! function_exists( 'woocommerce_hex_darker' ) ) { + /** + * @deprecated 3.0 + */ + function woocommerce_hex_darker( $color, $factor = 30 ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_hex_darker' ); + return wc_hex_darker( $color, $factor ); + } +} + +if ( ! function_exists( 'woocommerce_hex_lighter' ) ) { + /** + * @deprecated 3.0 + */ + function woocommerce_hex_lighter( $color, $factor = 30 ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_hex_lighter' ); + return wc_hex_lighter( $color, $factor ); + } +} + +if ( ! function_exists( 'woocommerce_light_or_dark' ) ) { + /** + * @deprecated 3.0 + */ + function woocommerce_light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_light_or_dark' ); + return wc_light_or_dark( $color, $dark, $light ); + } +} + +if ( ! function_exists( 'woocommerce_format_hex' ) ) { + /** + * @deprecated 3.0 + */ + function woocommerce_format_hex( $hex ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_format_hex' ); + return wc_format_hex( $hex ); + } +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_order_id_by_order_key( $order_key ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_order_id_by_order_key' ); + return wc_get_order_id_by_order_key( $order_key ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_downloadable_file_permission( $download_id, $product_id, $order ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_downloadable_file_permission' ); + return wc_downloadable_file_permission( $download_id, $product_id, $order ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_downloadable_product_permissions( $order_id ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_downloadable_product_permissions' ); + wc_downloadable_product_permissions( $order_id ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_add_order_item( $order_id, $item ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_add_order_item' ); + return wc_add_order_item( $order_id, $item ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_delete_order_item( $item_id ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_delete_order_item' ); + return wc_delete_order_item( $item_id ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_update_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value = '' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_update_order_item_meta' ); + return wc_update_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique = false ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_add_order_item_meta' ); + return wc_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_delete_order_item_meta( $item_id, $meta_key, $meta_value = '', $delete_all = false ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_delete_order_item_meta' ); + return wc_delete_order_item_meta( $item_id, $meta_key, $meta_value, $delete_all ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_order_item_meta( $item_id, $key, $single = true ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_order_item_meta' ); + return wc_get_order_item_meta( $item_id, $key, $single ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_cancel_unpaid_orders() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cancel_unpaid_orders' ); + wc_cancel_unpaid_orders(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_processing_order_count() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_processing_order_count' ); + return wc_processing_order_count(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_page_id( $page ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_page_id' ); + return wc_get_page_id( $page ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_endpoint_url( $endpoint, $value = '', $permalink = '' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_endpoint_url' ); + return wc_get_endpoint_url( $endpoint, $value, $permalink ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_lostpassword_url( $url ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_lostpassword_url' ); + return wc_lostpassword_url( $url ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_customer_edit_account_url() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_customer_edit_account_url' ); + return wc_customer_edit_account_url(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_nav_menu_items( $items, $args ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_nav_menu_items' ); + return wc_nav_menu_items( $items ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_nav_menu_item_classes( $menu_items, $args ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_nav_menu_item_classes' ); + return wc_nav_menu_item_classes( $menu_items ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_list_pages( $pages ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_list_pages' ); + return wc_list_pages( $pages ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_product_dropdown_categories( $args = array(), $deprecated_hierarchical = 1, $deprecated_show_uncategorized = 1, $deprecated_orderby = '' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_product_dropdown_categories' ); + return wc_product_dropdown_categories( $args, $deprecated_hierarchical, $deprecated_show_uncategorized, $deprecated_orderby ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_walk_category_dropdown_tree( $a1 = '', $a2 = '', $a3 = '' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_walk_category_dropdown_tree' ); + return wc_walk_category_dropdown_tree( $a1, $a2, $a3 ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_taxonomy_metadata_wpdbfix() { + wc_deprecated_function( __FUNCTION__, '3.0' ); +} + +/** + * @deprecated 3.0 + */ +function wc_taxonomy_metadata_wpdbfix() { + wc_deprecated_function( __FUNCTION__, '3.0' ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_order_terms( $the_term, $next_id, $taxonomy, $index = 0, $terms = null ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_reorder_terms' ); + return wc_reorder_terms( $the_term, $next_id, $taxonomy, $index, $terms ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_set_term_order( $term_id, $index, $taxonomy, $recursive = false ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_set_term_order' ); + return wc_set_term_order( $term_id, $index, $taxonomy, $recursive ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_terms_clauses( $clauses, $taxonomies, $args ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_terms_clauses' ); + return wc_terms_clauses( $clauses, $taxonomies, $args ); +} + +/** + * @deprecated 3.0 + */ +function _woocommerce_term_recount( $terms, $taxonomy, $callback, $terms_are_term_taxonomy_ids ) { + wc_deprecated_function( __FUNCTION__, '3.0', '_wc_term_recount' ); + return _wc_term_recount( $terms, $taxonomy, $callback, $terms_are_term_taxonomy_ids ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_recount_after_stock_change( $product_id ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_recount_after_stock_change' ); + return wc_recount_after_stock_change( $product_id ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_change_term_counts( $terms, $taxonomies, $args ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_change_term_counts' ); + return wc_change_term_counts( $terms, $taxonomies ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_product_ids_on_sale() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_product_ids_on_sale' ); + return wc_get_product_ids_on_sale(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_featured_product_ids() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_featured_product_ids' ); + return wc_get_featured_product_ids(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_product_terms( $object_id, $taxonomy, $fields = 'all' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_product_terms' ); + return wc_get_product_terms( $object_id, $taxonomy, array( 'fields' => $fields ) ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_product_post_type_link( $permalink, $post ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_product_post_type_link' ); + return wc_product_post_type_link( $permalink, $post ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_placeholder_img_src() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_placeholder_img_src' ); + return wc_placeholder_img_src(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_placeholder_img( $size = 'woocommerce_thumbnail' ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_placeholder_img' ); + return wc_placeholder_img( $size ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_formatted_variation( $variation = '', $flat = false ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_formatted_variation' ); + return wc_get_formatted_variation( $variation, $flat ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_scheduled_sales() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_scheduled_sales' ); + return wc_scheduled_sales(); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_get_attachment_image_attributes( $attr ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_attachment_image_attributes' ); + return wc_get_attachment_image_attributes( $attr ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_prepare_attachment_for_js( $response ) { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_prepare_attachment_for_js' ); + return wc_prepare_attachment_for_js( $response ); +} + +/** + * @deprecated 3.0 + */ +function woocommerce_track_product_view() { + wc_deprecated_function( __FUNCTION__, '3.0', 'wc_track_product_view' ); + return wc_track_product_view(); +} + +/** + * @deprecated 2.3 has no replacement + */ +function woocommerce_compile_less_styles() { + wc_deprecated_function( 'woocommerce_compile_less_styles', '2.3' ); +} + +/** + * woocommerce_calc_shipping was an option used to determine if shipping was enabled prior to version 2.6.0. This has since been replaced with wc_shipping_enabled() function and + * the woocommerce_ship_to_countries setting. + * @deprecated 2.6.0 + * @return string + */ +function woocommerce_calc_shipping_backwards_compatibility( $value ) { + if ( Constants::is_defined( 'WC_UPDATING' ) ) { + return $value; + } + return 'disabled' === get_option( 'woocommerce_ship_to_countries' ) ? 'no' : 'yes'; +} +add_filter( 'pre_option_woocommerce_calc_shipping', 'woocommerce_calc_shipping_backwards_compatibility' ); + +/** + * @deprecated 3.0.0 + * @see WC_Structured_Data class + * + * @return string + */ +function woocommerce_get_product_schema() { + wc_deprecated_function( 'woocommerce_get_product_schema', '3.0' ); + + global $product; + + $schema = "Product"; + + // Downloadable product schema handling + if ( $product->is_downloadable() ) { + switch ( $product->download_type ) { + case 'application' : + $schema = "SoftwareApplication"; + break; + case 'music' : + $schema = "MusicAlbum"; + break; + default : + $schema = "Product"; + break; + } + } + + return 'http://schema.org/' . $schema; +} + +/** + * Save product price. + * + * This is a private function (internal use ONLY) used until a data manipulation api is built. + * + * @deprecated 3.0.0 + * @param int $product_id + * @param float $regular_price + * @param float $sale_price + * @param string $date_from + * @param string $date_to + */ +function _wc_save_product_price( $product_id, $regular_price, $sale_price = '', $date_from = '', $date_to = '' ) { + wc_doing_it_wrong( '_wc_save_product_price()', 'This function is not for developer use and is deprecated.', '3.0' ); + + $product_id = absint( $product_id ); + $regular_price = wc_format_decimal( $regular_price ); + $sale_price = '' === $sale_price ? '' : wc_format_decimal( $sale_price ); + $date_from = wc_clean( $date_from ); + $date_to = wc_clean( $date_to ); + + update_post_meta( $product_id, '_regular_price', $regular_price ); + update_post_meta( $product_id, '_sale_price', $sale_price ); + + // Save Dates + update_post_meta( $product_id, '_sale_price_dates_from', $date_from ? strtotime( $date_from ) : '' ); + update_post_meta( $product_id, '_sale_price_dates_to', $date_to ? strtotime( $date_to ) : '' ); + + if ( $date_to && ! $date_from ) { + $date_from = strtotime( 'NOW', current_time( 'timestamp' ) ); + update_post_meta( $product_id, '_sale_price_dates_from', $date_from ); + } + + // Update price if on sale + if ( '' !== $sale_price && '' === $date_to && '' === $date_from ) { + update_post_meta( $product_id, '_price', $sale_price ); + } else { + update_post_meta( $product_id, '_price', $regular_price ); + } + + if ( '' !== $sale_price && $date_from && strtotime( $date_from ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) { + update_post_meta( $product_id, '_price', $sale_price ); + } + + if ( $date_to && strtotime( $date_to ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) { + update_post_meta( $product_id, '_price', $regular_price ); + update_post_meta( $product_id, '_sale_price_dates_from', '' ); + update_post_meta( $product_id, '_sale_price_dates_to', '' ); + } +} + +/** + * Return customer avatar URL. + * + * @deprecated 3.1.0 + * @since 2.6.0 + * @param string $email the customer's email. + * @return string the URL to the customer's avatar. + */ +function wc_get_customer_avatar_url( $email ) { + // Deprecated in favor of WordPress get_avatar_url() function. + wc_deprecated_function( 'wc_get_customer_avatar_url()', '3.1', 'get_avatar_url()' ); + + return get_avatar_url( $email ); +} + +/** + * WooCommerce Core Supported Themes. + * + * @deprecated 3.3.0 + * @since 2.2 + * @return string[] + */ +function wc_get_core_supported_themes() { + wc_deprecated_function( 'wc_get_core_supported_themes()', '3.3' ); + return array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' ); +} + +/** + * Get min/max price meta query args. + * + * @deprecated 3.6.0 + * @since 3.0.0 + * @param array $args Min price and max price arguments. + * @return array + */ +function wc_get_min_max_price_meta_query( $args ) { + wc_deprecated_function( 'wc_get_min_max_price_meta_query()', '3.6' ); + + $current_min_price = isset( $args['min_price'] ) ? floatval( $args['min_price'] ) : 0; + $current_max_price = isset( $args['max_price'] ) ? floatval( $args['max_price'] ) : PHP_INT_MAX; + + return apply_filters( + 'woocommerce_get_min_max_price_meta_query', + array( + 'key' => '_price', + 'value' => array( $current_min_price, $current_max_price ), + 'compare' => 'BETWEEN', + 'type' => 'DECIMAL(10,' . wc_get_price_decimals() . ')', + ), + $args + ); +} + +/** + * When a term is split, ensure meta data maintained. + * + * @deprecated 3.6.0 + * @param int $old_term_id Old term ID. + * @param int $new_term_id New term ID. + * @param string $term_taxonomy_id Term taxonomy ID. + * @param string $taxonomy Taxonomy. + */ +function wc_taxonomy_metadata_update_content_for_split_terms( $old_term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { + wc_deprecated_function( 'wc_taxonomy_metadata_update_content_for_split_terms', '3.6' ); +} + +/** + * WooCommerce Term Meta API. + * + * WC tables for storing term meta are deprecated from WordPress 4.4 since 4.4 has its own table. + * This function serves as a wrapper, using the new table if present, or falling back to the WC table. + * + * @deprecated 3.6.0 + * @param int $term_id Term ID. + * @param string $meta_key Meta key. + * @param mixed $meta_value Meta value. + * @param string $prev_value Previous value. (default: ''). + * @return bool + */ +function update_woocommerce_term_meta( $term_id, $meta_key, $meta_value, $prev_value = '' ) { + wc_deprecated_function( 'update_woocommerce_term_meta', '3.6', 'update_term_meta' ); + return function_exists( 'update_term_meta' ) ? update_term_meta( $term_id, $meta_key, $meta_value, $prev_value ) : update_metadata( 'woocommerce_term', $term_id, $meta_key, $meta_value, $prev_value ); +} + +/** + * WooCommerce Term Meta API. + * + * WC tables for storing term meta are deprecated from WordPress 4.4 since 4.4 has its own table. + * This function serves as a wrapper, using the new table if present, or falling back to the WC table. + * + * @deprecated 3.6.0 + * @param int $term_id Term ID. + * @param string $meta_key Meta key. + * @param mixed $meta_value Meta value. + * @param bool $unique Make meta key unique. (default: false). + * @return bool + */ +function add_woocommerce_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) { + wc_deprecated_function( 'add_woocommerce_term_meta', '3.6', 'add_term_meta' ); + return function_exists( 'add_term_meta' ) ? add_term_meta( $term_id, $meta_key, $meta_value, $unique ) : add_metadata( 'woocommerce_term', $term_id, $meta_key, $meta_value, $unique ); +} + +/** + * WooCommerce Term Meta API + * + * WC tables for storing term meta are deprecated from WordPress 4.4 since 4.4 has its own table. + * This function serves as a wrapper, using the new table if present, or falling back to the WC table. + * + * @deprecated 3.6.0 + * @param int $term_id Term ID. + * @param string $meta_key Meta key. + * @param string $meta_value Meta value (default: ''). + * @param bool $deprecated Deprecated param (default: false). + * @return bool + */ +function delete_woocommerce_term_meta( $term_id, $meta_key, $meta_value = '', $deprecated = false ) { + wc_deprecated_function( 'delete_woocommerce_term_meta', '3.6', 'delete_term_meta' ); + return function_exists( 'delete_term_meta' ) ? delete_term_meta( $term_id, $meta_key, $meta_value ) : delete_metadata( 'woocommerce_term', $term_id, $meta_key, $meta_value ); +} + +/** + * WooCommerce Term Meta API + * + * WC tables for storing term meta are deprecated from WordPress 4.4 since 4.4 has its own table. + * This function serves as a wrapper, using the new table if present, or falling back to the WC table. + * + * @deprecated 3.6.0 + * @param int $term_id Term ID. + * @param string $key Meta key. + * @param bool $single Whether to return a single value. (default: true). + * @return mixed + */ +function get_woocommerce_term_meta( $term_id, $key, $single = true ) { + wc_deprecated_function( 'get_woocommerce_term_meta', '3.6', 'get_term_meta' ); + return function_exists( 'get_term_meta' ) ? get_term_meta( $term_id, $key, $single ) : get_metadata( 'woocommerce_term', $term_id, $key, $single ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-formatting-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-formatting-functions.php new file mode 100644 index 0000000..51a60e7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-formatting-functions.php @@ -0,0 +1,1481 @@ +strip_invalid_text_for_column( $wpdb->options, 'option_value', $value ); + + if ( is_wp_error( $value ) ) { + $value = ''; + } + + $value = esc_url_raw( trim( $value ) ); + $value = str_replace( 'http://', '', $value ); + return untrailingslashit( $value ); +} + +/** + * Gets the filename part of a download URL. + * + * @param string $file_url File URL. + * @return string + */ +function wc_get_filename_from_url( $file_url ) { + $parts = wp_parse_url( $file_url ); + if ( isset( $parts['path'] ) ) { + return basename( $parts['path'] ); + } +} + +/** + * Normalise dimensions, unify to cm then convert to wanted unit value. + * + * Usage: + * wc_get_dimension( 55, 'in' ); + * wc_get_dimension( 55, 'in', 'm' ); + * + * @param int|float $dimension Dimension. + * @param string $to_unit Unit to convert to. + * Options: 'in', 'm', 'cm', 'm'. + * @param string $from_unit Unit to convert from. + * Defaults to ''. + * Options: 'in', 'm', 'cm', 'm'. + * @return float + */ +function wc_get_dimension( $dimension, $to_unit, $from_unit = '' ) { + $to_unit = strtolower( $to_unit ); + + if ( empty( $from_unit ) ) { + $from_unit = strtolower( get_option( 'woocommerce_dimension_unit' ) ); + } + + // Unify all units to cm first. + if ( $from_unit !== $to_unit ) { + switch ( $from_unit ) { + case 'in': + $dimension *= 2.54; + break; + case 'm': + $dimension *= 100; + break; + case 'mm': + $dimension *= 0.1; + break; + case 'yd': + $dimension *= 91.44; + break; + } + + // Output desired unit. + switch ( $to_unit ) { + case 'in': + $dimension *= 0.3937; + break; + case 'm': + $dimension *= 0.01; + break; + case 'mm': + $dimension *= 10; + break; + case 'yd': + $dimension *= 0.010936133; + break; + } + } + + return ( $dimension < 0 ) ? 0 : $dimension; +} + +/** + * Normalise weights, unify to kg then convert to wanted unit value. + * + * Usage: + * wc_get_weight(55, 'kg'); + * wc_get_weight(55, 'kg', 'lbs'); + * + * @param int|float $weight Weight. + * @param string $to_unit Unit to convert to. + * Options: 'g', 'kg', 'lbs', 'oz'. + * @param string $from_unit Unit to convert from. + * Defaults to ''. + * Options: 'g', 'kg', 'lbs', 'oz'. + * @return float + */ +function wc_get_weight( $weight, $to_unit, $from_unit = '' ) { + $weight = (float) $weight; + $to_unit = strtolower( $to_unit ); + + if ( empty( $from_unit ) ) { + $from_unit = strtolower( get_option( 'woocommerce_weight_unit' ) ); + } + + // Unify all units to kg first. + if ( $from_unit !== $to_unit ) { + switch ( $from_unit ) { + case 'g': + $weight *= 0.001; + break; + case 'lbs': + $weight *= 0.453592; + break; + case 'oz': + $weight *= 0.0283495; + break; + } + + // Output desired unit. + switch ( $to_unit ) { + case 'g': + $weight *= 1000; + break; + case 'lbs': + $weight *= 2.20462; + break; + case 'oz': + $weight *= 35.274; + break; + } + } + + return ( $weight < 0 ) ? 0 : $weight; +} + +/** + * Trim trailing zeros off prices. + * + * @param string|float|int $price Price. + * @return string + */ +function wc_trim_zeros( $price ) { + return preg_replace( '/' . preg_quote( wc_get_price_decimal_separator(), '/' ) . '0++$/', '', $price ); +} + +/** + * Round a tax amount. + * + * @param double $value Amount to round. + * @param int $precision DP to round. Defaults to wc_get_price_decimals. + * @return float + */ +function wc_round_tax_total( $value, $precision = null ) { + $precision = is_null( $precision ) ? wc_get_price_decimals() : intval( $precision ); + + if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) ) { + $rounded_tax = NumberUtil::round( $value, $precision, wc_get_tax_rounding_mode() ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctionParameters.round_modeFound + } elseif ( 2 === wc_get_tax_rounding_mode() ) { + $rounded_tax = wc_legacy_round_half_down( $value, $precision ); + } else { + $rounded_tax = NumberUtil::round( $value, $precision ); + } + + return apply_filters( 'wc_round_tax_total', $rounded_tax, $value, $precision, WC_TAX_ROUNDING_MODE ); +} + +/** + * Round half down in PHP 5.2. + * + * @since 3.2.6 + * @param float $value Value to round. + * @param int $precision Precision to round down to. + * @return float + */ +function wc_legacy_round_half_down( $value, $precision ) { + $value = wc_float_to_string( $value ); + + if ( false !== strstr( $value, '.' ) ) { + $value = explode( '.', $value ); + + if ( strlen( $value[1] ) > $precision && substr( $value[1], -1 ) === '5' ) { + $value[1] = substr( $value[1], 0, -1 ) . '4'; + } + + $value = implode( '.', $value ); + } + + return NumberUtil::round( floatval( $value ), $precision ); +} + +/** + * Make a refund total negative. + * + * @param float $amount Refunded amount. + * + * @return float + */ +function wc_format_refund_total( $amount ) { + return $amount * -1; +} + +/** + * Format decimal numbers ready for DB storage. + * + * Sanitize, remove decimals, and optionally round + trim off zeros. + * + * This function does not remove thousands - this should be done before passing a value to the function. + * + * @param float|string $number Expects either a float or a string with a decimal separator only (no thousands). + * @param mixed $dp number Number of decimal points to use, blank to use woocommerce_price_num_decimals, or false to avoid all rounding. + * @param bool $trim_zeros From end of string. + * @return string + */ +function wc_format_decimal( $number, $dp = false, $trim_zeros = false ) { + $locale = localeconv(); + $decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'] ); + + // Remove locale from string. + if ( ! is_float( $number ) ) { + $number = str_replace( $decimals, '.', $number ); + + // Convert multiple dots to just one. + $number = preg_replace( '/\.(?![^.]+$)|[^0-9.-]/', '', wc_clean( $number ) ); + } + + if ( false !== $dp ) { + $dp = intval( '' === $dp ? wc_get_price_decimals() : $dp ); + $number = number_format( floatval( $number ), $dp, '.', '' ); + } elseif ( is_float( $number ) ) { + // DP is false - don't use number format, just return a string using whatever is given. Remove scientific notation using sprintf. + $number = str_replace( $decimals, '.', sprintf( '%.' . wc_get_rounding_precision() . 'f', $number ) ); + // We already had a float, so trailing zeros are not needed. + $trim_zeros = true; + } + + if ( $trim_zeros && strstr( $number, '.' ) ) { + $number = rtrim( rtrim( $number, '0' ), '.' ); + } + + return $number; +} + +/** + * Convert a float to a string without locale formatting which PHP adds when changing floats to strings. + * + * @param float $float Float value to format. + * @return string + */ +function wc_float_to_string( $float ) { + if ( ! is_float( $float ) ) { + return $float; + } + + $locale = localeconv(); + $string = strval( $float ); + $string = str_replace( $locale['decimal_point'], '.', $string ); + + return $string; +} + +/** + * Format a price with WC Currency Locale settings. + * + * @param string $value Price to localize. + * @return string + */ +function wc_format_localized_price( $value ) { + return apply_filters( 'woocommerce_format_localized_price', str_replace( '.', wc_get_price_decimal_separator(), strval( $value ) ), $value ); +} + +/** + * Format a decimal with PHP Locale settings. + * + * @param string $value Decimal to localize. + * @return string + */ +function wc_format_localized_decimal( $value ) { + $locale = localeconv(); + return apply_filters( 'woocommerce_format_localized_decimal', str_replace( '.', $locale['decimal_point'], strval( $value ) ), $value ); +} + +/** + * Format a coupon code. + * + * @since 3.0.0 + * @param string $value Coupon code to format. + * @return string + */ +function wc_format_coupon_code( $value ) { + return apply_filters( 'woocommerce_coupon_code', $value ); +} + +/** + * Sanitize a coupon code. + * + * Uses sanitize_post_field since coupon codes are stored as + * post_titles - the sanitization and escaping must match. + * + * @since 3.6.0 + * @param string $value Coupon code to format. + * @return string + */ +function wc_sanitize_coupon_code( $value ) { + return wp_filter_kses( sanitize_post_field( 'post_title', $value, 0, 'db' ) ); +} + +/** + * Clean variables using sanitize_text_field. Arrays are cleaned recursively. + * Non-scalar values are ignored. + * + * @param string|array $var Data to sanitize. + * @return string|array + */ +function wc_clean( $var ) { + if ( is_array( $var ) ) { + return array_map( 'wc_clean', $var ); + } else { + return is_scalar( $var ) ? sanitize_text_field( $var ) : $var; + } +} + +/** + * Function wp_check_invalid_utf8 with recursive array support. + * + * @param string|array $var Data to sanitize. + * @return string|array + */ +function wc_check_invalid_utf8( $var ) { + if ( is_array( $var ) ) { + return array_map( 'wc_check_invalid_utf8', $var ); + } else { + return wp_check_invalid_utf8( $var ); + } +} + +/** + * Run wc_clean over posted textarea but maintain line breaks. + * + * @since 3.0.0 + * @param string $var Data to sanitize. + * @return string + */ +function wc_sanitize_textarea( $var ) { + return implode( "\n", array_map( 'wc_clean', explode( "\n", $var ) ) ); +} + +/** + * Sanitize a string destined to be a tooltip. + * + * @since 2.3.10 Tooltips are encoded with htmlspecialchars to prevent XSS. Should not be used in conjunction with esc_attr() + * @param string $var Data to sanitize. + * @return string + */ +function wc_sanitize_tooltip( $var ) { + return htmlspecialchars( + wp_kses( + html_entity_decode( $var ), + array( + 'br' => array(), + 'em' => array(), + 'strong' => array(), + 'small' => array(), + 'span' => array(), + 'ul' => array(), + 'li' => array(), + 'ol' => array(), + 'p' => array(), + ) + ) + ); +} + +/** + * Merge two arrays. + * + * @param array $a1 First array to merge. + * @param array $a2 Second array to merge. + * @return array + */ +function wc_array_overlay( $a1, $a2 ) { + foreach ( $a1 as $k => $v ) { + if ( ! array_key_exists( $k, $a2 ) ) { + continue; + } + if ( is_array( $v ) && is_array( $a2[ $k ] ) ) { + $a1[ $k ] = wc_array_overlay( $v, $a2[ $k ] ); + } else { + $a1[ $k ] = $a2[ $k ]; + } + } + return $a1; +} + +/** + * Formats a stock amount by running it through a filter. + * + * @param int|float $amount Stock amount. + * @return int|float + */ +function wc_stock_amount( $amount ) { + return apply_filters( 'woocommerce_stock_amount', $amount ); +} + +/** + * Get the price format depending on the currency position. + * + * @return string + */ +function get_woocommerce_price_format() { + $currency_pos = get_option( 'woocommerce_currency_pos' ); + $format = '%1$s%2$s'; + + switch ( $currency_pos ) { + case 'left': + $format = '%1$s%2$s'; + break; + case 'right': + $format = '%2$s%1$s'; + break; + case 'left_space': + $format = '%1$s %2$s'; + break; + case 'right_space': + $format = '%2$s %1$s'; + break; + } + + return apply_filters( 'woocommerce_price_format', $format, $currency_pos ); +} + +/** + * Return the thousand separator for prices. + * + * @since 2.3 + * @return string + */ +function wc_get_price_thousand_separator() { + return stripslashes( apply_filters( 'wc_get_price_thousand_separator', get_option( 'woocommerce_price_thousand_sep' ) ) ); +} + +/** + * Return the decimal separator for prices. + * + * @since 2.3 + * @return string + */ +function wc_get_price_decimal_separator() { + $separator = apply_filters( 'wc_get_price_decimal_separator', get_option( 'woocommerce_price_decimal_sep' ) ); + return $separator ? stripslashes( $separator ) : '.'; +} + +/** + * Return the number of decimals after the decimal point. + * + * @since 2.3 + * @return int + */ +function wc_get_price_decimals() { + return absint( apply_filters( 'wc_get_price_decimals', get_option( 'woocommerce_price_num_decimals', 2 ) ) ); +} + +/** + * Format the price with a currency symbol. + * + * @param float $price Raw price. + * @param array $args Arguments to format a price { + * Array of arguments. + * Defaults to empty array. + * + * @type bool $ex_tax_label Adds exclude tax label. + * Defaults to false. + * @type string $currency Currency code. + * Defaults to empty string (Use the result from get_woocommerce_currency()). + * @type string $decimal_separator Decimal separator. + * Defaults the result of wc_get_price_decimal_separator(). + * @type string $thousand_separator Thousand separator. + * Defaults the result of wc_get_price_thousand_separator(). + * @type string $decimals Number of decimals. + * Defaults the result of wc_get_price_decimals(). + * @type string $price_format Price format depending on the currency position. + * Defaults the result of get_woocommerce_price_format(). + * } + * @return string + */ +function wc_price( $price, $args = array() ) { + $args = apply_filters( + 'wc_price_args', + wp_parse_args( + $args, + array( + 'ex_tax_label' => false, + 'currency' => '', + 'decimal_separator' => wc_get_price_decimal_separator(), + 'thousand_separator' => wc_get_price_thousand_separator(), + 'decimals' => wc_get_price_decimals(), + 'price_format' => get_woocommerce_price_format(), + ) + ) + ); + + $unformatted_price = $price; + $negative = $price < 0; + $price = apply_filters( 'raw_woocommerce_price', floatval( $negative ? $price * -1 : $price ) ); + $price = apply_filters( 'formatted_woocommerce_price', number_format( $price, $args['decimals'], $args['decimal_separator'], $args['thousand_separator'] ), $price, $args['decimals'], $args['decimal_separator'], $args['thousand_separator'] ); + + if ( apply_filters( 'woocommerce_price_trim_zeros', false ) && $args['decimals'] > 0 ) { + $price = wc_trim_zeros( $price ); + } + + $formatted_price = ( $negative ? '-' : '' ) . sprintf( $args['price_format'], '' . get_woocommerce_currency_symbol( $args['currency'] ) . '', $price ); + $return = '' . $formatted_price . ''; + + if ( $args['ex_tax_label'] && wc_tax_enabled() ) { + $return .= ' ' . WC()->countries->ex_tax_or_vat() . ''; + } + + /** + * Filters the string of price markup. + * + * @param string $return Price HTML markup. + * @param string $price Formatted price. + * @param array $args Pass on the args. + * @param float $unformatted_price Price as float to allow plugins custom formatting. Since 3.2.0. + */ + return apply_filters( 'wc_price', $return, $price, $args, $unformatted_price ); +} + +/** + * Notation to numbers. + * + * This function transforms the php.ini notation for numbers (like '2M') to an integer. + * + * @param string $size Size value. + * @return int + */ +function wc_let_to_num( $size ) { + $l = substr( $size, -1 ); + $ret = (int) substr( $size, 0, -1 ); + switch ( strtoupper( $l ) ) { + case 'P': + $ret *= 1024; + // No break. + case 'T': + $ret *= 1024; + // No break. + case 'G': + $ret *= 1024; + // No break. + case 'M': + $ret *= 1024; + // No break. + case 'K': + $ret *= 1024; + // No break. + } + return $ret; +} + +/** + * WooCommerce Date Format - Allows to change date format for everything WooCommerce. + * + * @return string + */ +function wc_date_format() { + return apply_filters( 'woocommerce_date_format', get_option( 'date_format' ) ); +} + +/** + * WooCommerce Time Format - Allows to change time format for everything WooCommerce. + * + * @return string + */ +function wc_time_format() { + return apply_filters( 'woocommerce_time_format', get_option( 'time_format' ) ); +} + +/** + * Convert mysql datetime to PHP timestamp, forcing UTC. Wrapper for strtotime. + * + * Based on wcs_strtotime_dark_knight() from WC Subscriptions by Prospress. + * + * @since 3.0.0 + * @param string $time_string Time string. + * @param int|null $from_timestamp Timestamp to convert from. + * @return int + */ +function wc_string_to_timestamp( $time_string, $from_timestamp = null ) { + $original_timezone = date_default_timezone_get(); + + // @codingStandardsIgnoreStart + date_default_timezone_set( 'UTC' ); + + if ( null === $from_timestamp ) { + $next_timestamp = strtotime( $time_string ); + } else { + $next_timestamp = strtotime( $time_string, $from_timestamp ); + } + + date_default_timezone_set( $original_timezone ); + // @codingStandardsIgnoreEnd + + return $next_timestamp; +} + +/** + * Convert a date string to a WC_DateTime. + * + * @since 3.1.0 + * @param string $time_string Time string. + * @return WC_DateTime + */ +function wc_string_to_datetime( $time_string ) { + // Strings are defined in local WP timezone. Convert to UTC. + if ( 1 === preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|((-|\+)\d{2}:\d{2}))$/', $time_string, $date_bits ) ) { + $offset = ! empty( $date_bits[7] ) ? iso8601_timezone_to_offset( $date_bits[7] ) : wc_timezone_offset(); + $timestamp = gmmktime( $date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1] ) - $offset; + } else { + $timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $time_string ) ) ) ); + } + $datetime = new WC_DateTime( "@{$timestamp}", new DateTimeZone( 'UTC' ) ); + + // Set local timezone or offset. + if ( get_option( 'timezone_string' ) ) { + $datetime->setTimezone( new DateTimeZone( wc_timezone_string() ) ); + } else { + $datetime->set_utc_offset( wc_timezone_offset() ); + } + + return $datetime; +} + +/** + * WooCommerce Timezone - helper to retrieve the timezone string for a site until. + * a WP core method exists (see https://core.trac.wordpress.org/ticket/24730). + * + * Adapted from https://secure.php.net/manual/en/function.timezone-name-from-abbr.php#89155. + * + * @since 2.1 + * @return string PHP timezone string for the site + */ +function wc_timezone_string() { + // Added in WordPress 5.3 Ref https://developer.wordpress.org/reference/functions/wp_timezone_string/. + if ( function_exists( 'wp_timezone_string' ) ) { + return wp_timezone_string(); + } + + // If site timezone string exists, return it. + $timezone = get_option( 'timezone_string' ); + if ( $timezone ) { + return $timezone; + } + + // Get UTC offset, if it isn't set then return UTC. + $utc_offset = floatval( get_option( 'gmt_offset', 0 ) ); + if ( ! is_numeric( $utc_offset ) || 0.0 === $utc_offset ) { + return 'UTC'; + } + + // Adjust UTC offset from hours to seconds. + $utc_offset = (int) ( $utc_offset * 3600 ); + + // Attempt to guess the timezone string from the UTC offset. + $timezone = timezone_name_from_abbr( '', $utc_offset ); + if ( $timezone ) { + return $timezone; + } + + // Last try, guess timezone string manually. + foreach ( timezone_abbreviations_list() as $abbr ) { + foreach ( $abbr as $city ) { + // WordPress restrict the use of date(), since it's affected by timezone settings, but in this case is just what we need to guess the correct timezone. + if ( (bool) date( 'I' ) === (bool) $city['dst'] && $city['timezone_id'] && intval( $city['offset'] ) === $utc_offset ) { // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date + return $city['timezone_id']; + } + } + } + + // Fallback to UTC. + return 'UTC'; +} + +/** + * Get timezone offset in seconds. + * + * @since 3.0.0 + * @return float + */ +function wc_timezone_offset() { + $timezone = get_option( 'timezone_string' ); + + if ( $timezone ) { + $timezone_object = new DateTimeZone( $timezone ); + return $timezone_object->getOffset( new DateTime( 'now' ) ); + } else { + return floatval( get_option( 'gmt_offset', 0 ) ) * HOUR_IN_SECONDS; + } +} + +/** + * Callback which can flatten post meta (gets the first value if it's an array). + * + * @since 3.0.0 + * @param array $value Value to flatten. + * @return mixed + */ +function wc_flatten_meta_callback( $value ) { + return is_array( $value ) ? current( $value ) : $value; +} + +if ( ! function_exists( 'wc_rgb_from_hex' ) ) { + + /** + * Convert RGB to HEX. + * + * @param mixed $color Color. + * + * @return array + */ + function wc_rgb_from_hex( $color ) { + $color = str_replace( '#', '', $color ); + // Convert shorthand colors to full format, e.g. "FFF" -> "FFFFFF". + $color = preg_replace( '~^(.)(.)(.)$~', '$1$1$2$2$3$3', $color ); + + $rgb = array(); + $rgb['R'] = hexdec( $color[0] . $color[1] ); + $rgb['G'] = hexdec( $color[2] . $color[3] ); + $rgb['B'] = hexdec( $color[4] . $color[5] ); + + return $rgb; + } +} + +if ( ! function_exists( 'wc_hex_darker' ) ) { + + /** + * Make HEX color darker. + * + * @param mixed $color Color. + * @param int $factor Darker factor. + * Defaults to 30. + * @return string + */ + function wc_hex_darker( $color, $factor = 30 ) { + $base = wc_rgb_from_hex( $color ); + $color = '#'; + + foreach ( $base as $k => $v ) { + $amount = $v / 100; + $amount = NumberUtil::round( $amount * $factor ); + $new_decimal = $v - $amount; + + $new_hex_component = dechex( $new_decimal ); + if ( strlen( $new_hex_component ) < 2 ) { + $new_hex_component = '0' . $new_hex_component; + } + $color .= $new_hex_component; + } + + return $color; + } +} + +if ( ! function_exists( 'wc_hex_lighter' ) ) { + + /** + * Make HEX color lighter. + * + * @param mixed $color Color. + * @param int $factor Lighter factor. + * Defaults to 30. + * @return string + */ + function wc_hex_lighter( $color, $factor = 30 ) { + $base = wc_rgb_from_hex( $color ); + $color = '#'; + + foreach ( $base as $k => $v ) { + $amount = 255 - $v; + $amount = $amount / 100; + $amount = NumberUtil::round( $amount * $factor ); + $new_decimal = $v + $amount; + + $new_hex_component = dechex( $new_decimal ); + if ( strlen( $new_hex_component ) < 2 ) { + $new_hex_component = '0' . $new_hex_component; + } + $color .= $new_hex_component; + } + + return $color; + } +} + +if ( ! function_exists( 'wc_hex_is_light' ) ) { + + /** + * Determine whether a hex color is light. + * + * @param mixed $color Color. + * @return bool True if a light color. + */ + function wc_hex_is_light( $color ) { + $hex = str_replace( '#', '', $color ); + + $c_r = hexdec( substr( $hex, 0, 2 ) ); + $c_g = hexdec( substr( $hex, 2, 2 ) ); + $c_b = hexdec( substr( $hex, 4, 2 ) ); + + $brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000; + + return $brightness > 155; + } +} + +if ( ! function_exists( 'wc_light_or_dark' ) ) { + + /** + * Detect if we should use a light or dark color on a background color. + * + * @param mixed $color Color. + * @param string $dark Darkest reference. + * Defaults to '#000000'. + * @param string $light Lightest reference. + * Defaults to '#FFFFFF'. + * @return string + */ + function wc_light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) { + return wc_hex_is_light( $color ) ? $dark : $light; + } +} + +if ( ! function_exists( 'wc_format_hex' ) ) { + + /** + * Format string as hex. + * + * @param string $hex HEX color. + * @return string|null + */ + function wc_format_hex( $hex ) { + $hex = trim( str_replace( '#', '', $hex ) ); + + if ( strlen( $hex ) === 3 ) { + $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; + } + + return $hex ? '#' . $hex : null; + } +} + +/** + * Format the postcode according to the country and length of the postcode. + * + * @param string $postcode Unformatted postcode. + * @param string $country Base country. + * @return string + */ +function wc_format_postcode( $postcode, $country ) { + $postcode = wc_normalize_postcode( $postcode ); + + switch ( $country ) { + case 'CA': + case 'GB': + $postcode = substr_replace( $postcode, ' ', -3, 0 ); + break; + case 'IE': + $postcode = substr_replace( $postcode, ' ', 3, 0 ); + break; + case 'BR': + case 'PL': + $postcode = substr_replace( $postcode, '-', -3, 0 ); + break; + case 'JP': + $postcode = substr_replace( $postcode, '-', 3, 0 ); + break; + case 'PT': + $postcode = substr_replace( $postcode, '-', 4, 0 ); + break; + case 'PR': + case 'US': + $postcode = rtrim( substr_replace( $postcode, '-', 5, 0 ), '-' ); + break; + case 'NL': + $postcode = substr_replace( $postcode, ' ', 4, 0 ); + break; + } + + return apply_filters( 'woocommerce_format_postcode', trim( $postcode ), $country ); +} + +/** + * Normalize postcodes. + * + * Remove spaces and convert characters to uppercase. + * + * @since 2.6.0 + * @param string $postcode Postcode. + * @return string + */ +function wc_normalize_postcode( $postcode ) { + return preg_replace( '/[\s\-]/', '', trim( wc_strtoupper( $postcode ) ) ); +} + +/** + * Format phone numbers. + * + * @param string $phone Phone number. + * @return string + */ +function wc_format_phone_number( $phone ) { + if ( ! WC_Validation::is_phone( $phone ) ) { + return ''; + } + return preg_replace( '/[^0-9\+\-\(\)\s]/', '-', preg_replace( '/[\x00-\x1F\x7F-\xFF]/', '', $phone ) ); +} + +/** + * Sanitize phone number. + * Allows only numbers and "+" (plus sign). + * + * @since 3.6.0 + * @param string $phone Phone number. + * @return string + */ +function wc_sanitize_phone_number( $phone ) { + return preg_replace( '/[^\d+]/', '', $phone ); +} + +/** + * Wrapper for mb_strtoupper which see's if supported first. + * + * @since 3.1.0 + * @param string $string String to format. + * @return string + */ +function wc_strtoupper( $string ) { + return function_exists( 'mb_strtoupper' ) ? mb_strtoupper( $string ) : strtoupper( $string ); +} + +/** + * Make a string lowercase. + * Try to use mb_strtolower() when available. + * + * @since 2.3 + * @param string $string String to format. + * @return string + */ +function wc_strtolower( $string ) { + return function_exists( 'mb_strtolower' ) ? mb_strtolower( $string ) : strtolower( $string ); +} + +/** + * Trim a string and append a suffix. + * + * @param string $string String to trim. + * @param integer $chars Amount of characters. + * Defaults to 200. + * @param string $suffix Suffix. + * Defaults to '...'. + * @return string + */ +function wc_trim_string( $string, $chars = 200, $suffix = '...' ) { + if ( strlen( $string ) > $chars ) { + if ( function_exists( 'mb_substr' ) ) { + $string = mb_substr( $string, 0, ( $chars - mb_strlen( $suffix ) ) ) . $suffix; + } else { + $string = substr( $string, 0, ( $chars - strlen( $suffix ) ) ) . $suffix; + } + } + return $string; +} + +/** + * Format content to display shortcodes. + * + * @since 2.3.0 + * @param string $raw_string Raw string. + * @return string + */ +function wc_format_content( $raw_string ) { + return apply_filters( 'woocommerce_format_content', apply_filters( 'woocommerce_short_description', $raw_string ), $raw_string ); +} + +/** + * Format product short description. + * Adds support for Jetpack Markdown. + * + * @codeCoverageIgnore + * @since 2.4.0 + * @param string $content Product short description. + * @return string + */ +function wc_format_product_short_description( $content ) { + // Add support for Jetpack Markdown. + if ( class_exists( 'WPCom_Markdown' ) ) { + $markdown = WPCom_Markdown::get_instance(); + + return wpautop( + $markdown->transform( + $content, + array( + 'unslash' => false, + ) + ) + ); + } + + return $content; +} + +/** + * Formats curency symbols when saved in settings. + * + * @codeCoverageIgnore + * @param string $value Option value. + * @param array $option Option name. + * @param string $raw_value Raw value. + * @return string + */ +function wc_format_option_price_separators( $value, $option, $raw_value ) { + return wp_kses_post( $raw_value ); +} +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_decimal_sep', 'wc_format_option_price_separators', 10, 3 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_thousand_sep', 'wc_format_option_price_separators', 10, 3 ); + +/** + * Formats decimals when saved in settings. + * + * @codeCoverageIgnore + * @param string $value Option value. + * @param array $option Option name. + * @param string $raw_value Raw value. + * @return string + */ +function wc_format_option_price_num_decimals( $value, $option, $raw_value ) { + return is_null( $raw_value ) ? 2 : absint( $raw_value ); +} +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_num_decimals', 'wc_format_option_price_num_decimals', 10, 3 ); + +/** + * Formats hold stock option and sets cron event up. + * + * @codeCoverageIgnore + * @param string $value Option value. + * @param array $option Option name. + * @param string $raw_value Raw value. + * @return string + */ +function wc_format_option_hold_stock_minutes( $value, $option, $raw_value ) { + $value = ! empty( $raw_value ) ? absint( $raw_value ) : ''; // Allow > 0 or set to ''. + + wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' ); + + if ( '' !== $value ) { + wp_schedule_single_event( time() + ( absint( $value ) * 60 ), 'woocommerce_cancel_unpaid_orders' ); + } + + return $value; +} +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_hold_stock_minutes', 'wc_format_option_hold_stock_minutes', 10, 3 ); + +/** + * Sanitize terms from an attribute text based. + * + * @since 2.4.5 + * @param string $term Term value. + * @return string + */ +function wc_sanitize_term_text_based( $term ) { + return trim( wp_strip_all_tags( wp_unslash( $term ) ) ); +} + +if ( ! function_exists( 'wc_make_numeric_postcode' ) ) { + /** + * Make numeric postcode. + * + * Converts letters to numbers so we can do a simple range check on postcodes. + * E.g. PE30 becomes 16050300 (P = 16, E = 05, 3 = 03, 0 = 00) + * + * @since 2.6.0 + * @param string $postcode Regular postcode. + * @return string + */ + function wc_make_numeric_postcode( $postcode ) { + $postcode = str_replace( array( ' ', '-' ), '', $postcode ); + $postcode_length = strlen( $postcode ); + $letters_to_numbers = array_merge( array( 0 ), range( 'A', 'Z' ) ); + $letters_to_numbers = array_flip( $letters_to_numbers ); + $numeric_postcode = ''; + + for ( $i = 0; $i < $postcode_length; $i ++ ) { + if ( is_numeric( $postcode[ $i ] ) ) { + $numeric_postcode .= str_pad( $postcode[ $i ], 2, '0', STR_PAD_LEFT ); + } elseif ( isset( $letters_to_numbers[ $postcode[ $i ] ] ) ) { + $numeric_postcode .= str_pad( $letters_to_numbers[ $postcode[ $i ] ], 2, '0', STR_PAD_LEFT ); + } else { + $numeric_postcode .= '00'; + } + } + + return $numeric_postcode; + } +} + +/** + * Format the stock amount ready for display based on settings. + * + * @since 3.0.0 + * @param WC_Product $product Product object for which the stock you need to format. + * @return string + */ +function wc_format_stock_for_display( $product ) { + $display = __( 'In stock', 'woocommerce' ); + $stock_amount = $product->get_stock_quantity(); + + switch ( get_option( 'woocommerce_stock_format' ) ) { + case 'low_amount': + if ( $stock_amount <= get_option( 'woocommerce_notify_low_stock_amount' ) ) { + /* translators: %s: stock amount */ + $display = sprintf( __( 'Only %s left in stock', 'woocommerce' ), wc_format_stock_quantity_for_display( $stock_amount, $product ) ); + } + break; + case '': + /* translators: %s: stock amount */ + $display = sprintf( __( '%s in stock', 'woocommerce' ), wc_format_stock_quantity_for_display( $stock_amount, $product ) ); + break; + } + + if ( $product->backorders_allowed() && $product->backorders_require_notification() ) { + $display .= ' ' . __( '(can be backordered)', 'woocommerce' ); + } + + return $display; +} + +/** + * Format the stock quantity ready for display. + * + * @since 3.0.0 + * @param int $stock_quantity Stock quantity. + * @param WC_Product $product Product instance so that we can pass through the filters. + * @return string + */ +function wc_format_stock_quantity_for_display( $stock_quantity, $product ) { + return apply_filters( 'woocommerce_format_stock_quantity', $stock_quantity, $product ); +} + +/** + * Format a sale price for display. + * + * @since 3.0.0 + * @param string $regular_price Regular price. + * @param string $sale_price Sale price. + * @return string + */ +function wc_format_sale_price( $regular_price, $sale_price ) { + $price = '' . ( is_numeric( $regular_price ) ? wc_price( $regular_price ) : $regular_price ) . ' ' . ( is_numeric( $sale_price ) ? wc_price( $sale_price ) : $sale_price ) . ''; + return apply_filters( 'woocommerce_format_sale_price', $price, $regular_price, $sale_price ); +} + +/** + * Format a price range for display. + * + * @param string $from Price from. + * @param string $to Price to. + * @return string + */ +function wc_format_price_range( $from, $to ) { + /* translators: 1: price from 2: price to */ + $price = sprintf( _x( '%1$s – %2$s', 'Price range: from-to', 'woocommerce' ), is_numeric( $from ) ? wc_price( $from ) : $from, is_numeric( $to ) ? wc_price( $to ) : $to ); + return apply_filters( 'woocommerce_format_price_range', $price, $from, $to ); +} + +/** + * Format a weight for display. + * + * @since 3.0.0 + * @param float $weight Weight. + * @return string + */ +function wc_format_weight( $weight ) { + $weight_string = wc_format_localized_decimal( $weight ); + + if ( ! empty( $weight_string ) ) { + $weight_string .= ' ' . get_option( 'woocommerce_weight_unit' ); + } else { + $weight_string = __( 'N/A', 'woocommerce' ); + } + + return apply_filters( 'woocommerce_format_weight', $weight_string, $weight ); +} + +/** + * Format dimensions for display. + * + * @since 3.0.0 + * @param array $dimensions Array of dimensions. + * @return string + */ +function wc_format_dimensions( $dimensions ) { + $dimension_string = implode( ' × ', array_filter( array_map( 'wc_format_localized_decimal', $dimensions ) ) ); + + if ( ! empty( $dimension_string ) ) { + $dimension_string .= ' ' . get_option( 'woocommerce_dimension_unit' ); + } else { + $dimension_string = __( 'N/A', 'woocommerce' ); + } + + return apply_filters( 'woocommerce_format_dimensions', $dimension_string, $dimensions ); +} + +/** + * Format a date for output. + * + * @since 3.0.0 + * @param WC_DateTime $date Instance of WC_DateTime. + * @param string $format Data format. + * Defaults to the wc_date_format function if not set. + * @return string + */ +function wc_format_datetime( $date, $format = '' ) { + if ( ! $format ) { + $format = wc_date_format(); + } + if ( ! is_a( $date, 'WC_DateTime' ) ) { + return ''; + } + return $date->date_i18n( $format ); +} + +/** + * Process oEmbeds. + * + * @since 3.1.0 + * @param string $content Content. + * @return string + */ +function wc_do_oembeds( $content ) { + global $wp_embed; + + $content = $wp_embed->autoembed( $content ); + + return $content; +} + +/** + * Get part of a string before :. + * + * Used for example in shipping methods ids where they take the format + * method_id:instance_id + * + * @since 3.2.0 + * @param string $string String to extract. + * @return string + */ +function wc_get_string_before_colon( $string ) { + return trim( current( explode( ':', (string) $string ) ) ); +} + +/** + * Array merge and sum function. + * + * Source: https://gist.github.com/Nickology/f700e319cbafab5eaedc + * + * @since 3.2.0 + * @return array + */ +function wc_array_merge_recursive_numeric() { + $arrays = func_get_args(); + + // If there's only one array, it's already merged. + if ( 1 === count( $arrays ) ) { + return $arrays[0]; + } + + // Remove any items in $arrays that are NOT arrays. + foreach ( $arrays as $key => $array ) { + if ( ! is_array( $array ) ) { + unset( $arrays[ $key ] ); + } + } + + // We start by setting the first array as our final array. + // We will merge all other arrays with this one. + $final = array_shift( $arrays ); + + foreach ( $arrays as $b ) { + foreach ( $final as $key => $value ) { + // If $key does not exist in $b, then it is unique and can be safely merged. + if ( ! isset( $b[ $key ] ) ) { + $final[ $key ] = $value; + } else { + // If $key is present in $b, then we need to merge and sum numeric values in both. + if ( is_numeric( $value ) && is_numeric( $b[ $key ] ) ) { + // If both values for these keys are numeric, we sum them. + $final[ $key ] = $value + $b[ $key ]; + } elseif ( is_array( $value ) && is_array( $b[ $key ] ) ) { + // If both values are arrays, we recursively call ourself. + $final[ $key ] = wc_array_merge_recursive_numeric( $value, $b[ $key ] ); + } else { + // If both keys exist but differ in type, then we cannot merge them. + // In this scenario, we will $b's value for $key is used. + $final[ $key ] = $b[ $key ]; + } + } + } + + // Finally, we need to merge any keys that exist only in $b. + foreach ( $b as $key => $value ) { + if ( ! isset( $final[ $key ] ) ) { + $final[ $key ] = $value; + } + } + } + + return $final; +} + +/** + * Implode and escape HTML attributes for output. + * + * @since 3.3.0 + * @param array $raw_attributes Attribute name value pairs. + * @return string + */ +function wc_implode_html_attributes( $raw_attributes ) { + $attributes = array(); + foreach ( $raw_attributes as $name => $value ) { + $attributes[] = esc_attr( $name ) . '="' . esc_attr( $value ) . '"'; + } + return implode( ' ', $attributes ); +} + +/** + * Escape JSON for use on HTML or attribute text nodes. + * + * @since 3.5.5 + * @param string $json JSON to escape. + * @param bool $html True if escaping for HTML text node, false for attributes. Determines how quotes are handled. + * @return string Escaped JSON. + */ +function wc_esc_json( $json, $html = false ) { + return _wp_specialchars( + $json, + $html ? ENT_NOQUOTES : ENT_QUOTES, // Escape quotes in attribute nodes only. + 'UTF-8', // json_encode() outputs UTF-8 (really just ASCII), not the blog's charset. + true // Double escape entities: `&` -> `&amp;`. + ); +} + +/** + * Parse a relative date option from the settings API into a standard format. + * + * @since 3.4.0 + * @param mixed $raw_value Value stored in DB. + * @return array Nicely formatted array with number and unit values. + */ +function wc_parse_relative_date_option( $raw_value ) { + $periods = array( + 'days' => __( 'Day(s)', 'woocommerce' ), + 'weeks' => __( 'Week(s)', 'woocommerce' ), + 'months' => __( 'Month(s)', 'woocommerce' ), + 'years' => __( 'Year(s)', 'woocommerce' ), + ); + + $value = wp_parse_args( + (array) $raw_value, + array( + 'number' => '', + 'unit' => 'days', + ) + ); + + $value['number'] = ! empty( $value['number'] ) ? absint( $value['number'] ) : ''; + + if ( ! in_array( $value['unit'], array_keys( $periods ), true ) ) { + $value['unit'] = 'days'; + } + + return $value; +} + +/** + * Format the endpoint slug, strip out anything not allowed in a url. + * + * @since 3.5.0 + * @param string $raw_value The raw value. + * @return string + */ +function wc_sanitize_endpoint_slug( $raw_value ) { + return sanitize_title( $raw_value ); +} +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_checkout_pay_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_checkout_order_received_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_add_payment_method_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_delete_payment_method_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_set_default_payment_method_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_orders_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_view_order_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_downloads_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_edit_account_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_edit_address_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_payment_methods_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_lost_password_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); +add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_logout_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-notice-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-notice-functions.php new file mode 100644 index 0000000..e119e58 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-notice-functions.php @@ -0,0 +1,294 @@ +session->get( 'wc_notices', array() ); + + if ( isset( $all_notices[ $notice_type ] ) ) { + + $notice_count = count( $all_notices[ $notice_type ] ); + + } elseif ( empty( $notice_type ) ) { + + foreach ( $all_notices as $notices ) { + $notice_count += count( $notices ); + } + } + + return $notice_count; +} + +/** + * Check if a notice has already been added. + * + * @since 2.1 + * @param string $message The text to display in the notice. + * @param string $notice_type Optional. The name of the notice type - either error, success or notice. + * @return bool + */ +function wc_has_notice( $message, $notice_type = 'success' ) { + if ( ! did_action( 'woocommerce_init' ) ) { + wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' ); + return false; + } + + $notices = WC()->session->get( 'wc_notices', array() ); + $notices = isset( $notices[ $notice_type ] ) ? $notices[ $notice_type ] : array(); + return array_search( $message, wp_list_pluck( $notices, 'notice' ), true ) !== false; +} + +/** + * Add and store a notice. + * + * @since 2.1 + * @version 3.9.0 + * @param string $message The text to display in the notice. + * @param string $notice_type Optional. The name of the notice type - either error, success or notice. + * @param array $data Optional notice data. + */ +function wc_add_notice( $message, $notice_type = 'success', $data = array() ) { + if ( ! did_action( 'woocommerce_init' ) ) { + wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' ); + return; + } + + $notices = WC()->session->get( 'wc_notices', array() ); + + // Backward compatibility. + if ( 'success' === $notice_type ) { + $message = apply_filters( 'woocommerce_add_message', $message ); + } + + $message = apply_filters( 'woocommerce_add_' . $notice_type, $message ); + + if ( ! empty( $message ) ) { + $notices[ $notice_type ][] = array( + 'notice' => $message, + 'data' => $data, + ); + } + + WC()->session->set( 'wc_notices', $notices ); +} + +/** + * Set all notices at once. + * + * @since 2.6.0 + * @param array[] $notices Array of notices. + */ +function wc_set_notices( $notices ) { + if ( ! did_action( 'woocommerce_init' ) ) { + wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.6' ); + return; + } + + WC()->session->set( 'wc_notices', $notices ); +} + +/** + * Unset all notices. + * + * @since 2.1 + */ +function wc_clear_notices() { + if ( ! did_action( 'woocommerce_init' ) ) { + wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' ); + return; + } + WC()->session->set( 'wc_notices', null ); +} + +/** + * Prints messages and errors which are stored in the session, then clears them. + * + * @since 2.1 + * @param bool $return true to return rather than echo. @since 3.5.0. + * @return string|null + */ +function wc_print_notices( $return = false ) { + if ( ! did_action( 'woocommerce_init' ) ) { + wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' ); + return; + } + + $all_notices = WC()->session->get( 'wc_notices', array() ); + $notice_types = apply_filters( 'woocommerce_notice_types', array( 'error', 'success', 'notice' ) ); + + // Buffer output. + ob_start(); + + foreach ( $notice_types as $notice_type ) { + if ( wc_notice_count( $notice_type ) > 0 ) { + $messages = array(); + + foreach ( $all_notices[ $notice_type ] as $notice ) { + $messages[] = isset( $notice['notice'] ) ? $notice['notice'] : $notice; + } + + wc_get_template( + "notices/{$notice_type}.php", + array( + 'messages' => array_filter( $messages ), // @deprecated 3.9.0 + 'notices' => array_filter( $all_notices[ $notice_type ] ), + ) + ); + } + } + + wc_clear_notices(); + + $notices = wc_kses_notice( ob_get_clean() ); + + if ( $return ) { + return $notices; + } + + echo $notices; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +} + +/** + * Print a single notice immediately. + * + * @since 2.1 + * @version 3.9.0 + * @param string $message The text to display in the notice. + * @param string $notice_type Optional. The singular name of the notice type - either error, success or notice. + * @param array $data Optional notice data. @since 3.9.0. + */ +function wc_print_notice( $message, $notice_type = 'success', $data = array() ) { + if ( 'success' === $notice_type ) { + $message = apply_filters( 'woocommerce_add_message', $message ); + } + + $message = apply_filters( 'woocommerce_add_' . $notice_type, $message ); + + wc_get_template( + "notices/{$notice_type}.php", + array( + 'messages' => array( $message ), // @deprecated 3.9.0 + 'notices' => array( + array( + 'notice' => $message, + 'data' => $data, + ), + ), + ) + ); +} + +/** + * Returns all queued notices, optionally filtered by a notice type. + * + * @since 2.1 + * @version 3.9.0 + * @param string $notice_type Optional. The singular name of the notice type - either error, success or notice. + * @return array[] + */ +function wc_get_notices( $notice_type = '' ) { + if ( ! did_action( 'woocommerce_init' ) ) { + wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' ); + return; + } + + $all_notices = WC()->session->get( 'wc_notices', array() ); + + if ( empty( $notice_type ) ) { + $notices = $all_notices; + } elseif ( isset( $all_notices[ $notice_type ] ) ) { + $notices = $all_notices[ $notice_type ]; + } else { + $notices = array(); + } + + return $notices; +} + +/** + * Add notices for WP Errors. + * + * @param WP_Error $errors Errors. + */ +function wc_add_wp_error_notices( $errors ) { + if ( is_wp_error( $errors ) && $errors->get_error_messages() ) { + foreach ( $errors->get_error_messages() as $error ) { + wc_add_notice( $error, 'error' ); + } + } +} + +/** + * Filters out the same tags as wp_kses_post, but allows tabindex for element. + * + * @since 3.5.0 + * @param string $message Content to filter through kses. + * @return string + */ +function wc_kses_notice( $message ) { + $allowed_tags = array_replace_recursive( + wp_kses_allowed_html( 'post' ), + array( + 'a' => array( + 'tabindex' => true, + ), + ) + ); + + /** + * Kses notice allowed tags. + * + * @since 3.9.0 + * @param array[]|string $allowed_tags An array of allowed HTML elements and attributes, or a context name such as 'post'. + */ + return wp_kses( $message, apply_filters( 'woocommerce_kses_notice_allowed_tags', $allowed_tags ) ); +} + +/** + * Get notice data attribute. + * + * @since 3.9.0 + * @param array $notice Notice data. + * @return string + */ +function wc_get_notice_data_attr( $notice ) { + if ( empty( $notice['data'] ) ) { + return; + } + + $attr = ''; + + foreach ( $notice['data'] as $key => $value ) { + $attr .= sprintf( + ' data-%1$s="%2$s"', + sanitize_title( $key ), + esc_attr( $value ) + ); + } + + return $attr; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-order-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-order-functions.php new file mode 100644 index 0000000..99f55dd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-order-functions.php @@ -0,0 +1,1090 @@ + 'limit', + 'post_type' => 'type', + 'post_status' => 'status', + 'post_parent' => 'parent', + 'author' => 'customer', + 'email' => 'billing_email', + 'posts_per_page' => 'limit', + 'paged' => 'page', + ); + + foreach ( $map_legacy as $from => $to ) { + if ( isset( $args[ $from ] ) ) { + $args[ $to ] = $args[ $from ]; + } + } + + // Map legacy date args to modern date args. + $date_before = false; + $date_after = false; + + if ( ! empty( $args['date_before'] ) ) { + $datetime = wc_string_to_datetime( $args['date_before'] ); + $date_before = strpos( $args['date_before'], ':' ) ? $datetime->getOffsetTimestamp() : $datetime->date( 'Y-m-d' ); + } + if ( ! empty( $args['date_after'] ) ) { + $datetime = wc_string_to_datetime( $args['date_after'] ); + $date_after = strpos( $args['date_after'], ':' ) ? $datetime->getOffsetTimestamp() : $datetime->date( 'Y-m-d' ); + } + + if ( $date_before && $date_after ) { + $args['date_created'] = $date_after . '...' . $date_before; + } elseif ( $date_before ) { + $args['date_created'] = '<' . $date_before; + } elseif ( $date_after ) { + $args['date_created'] = '>' . $date_after; + } + + $query = new WC_Order_Query( $args ); + return $query->get_orders(); +} + +/** + * Main function for returning orders, uses the WC_Order_Factory class. + * + * @since 2.2 + * + * @param mixed $the_order Post object or post ID of the order. + * + * @return bool|WC_Order|WC_Order_Refund + */ +function wc_get_order( $the_order = false ) { + if ( ! did_action( 'woocommerce_after_register_post_type' ) ) { + wc_doing_it_wrong( __FUNCTION__, 'wc_get_order should not be called before post types are registered (woocommerce_after_register_post_type action)', '2.5' ); + return false; + } + return WC()->order_factory->get_order( $the_order ); +} + +/** + * Get all order statuses. + * + * @since 2.2 + * @used-by WC_Order::set_status + * @return array + */ +function wc_get_order_statuses() { + $order_statuses = array( + 'wc-pending' => _x( 'Pending payment', 'Order status', 'woocommerce' ), + 'wc-processing' => _x( 'Processing', 'Order status', 'woocommerce' ), + 'wc-on-hold' => _x( 'On hold', 'Order status', 'woocommerce' ), + 'wc-completed' => _x( 'Completed', 'Order status', 'woocommerce' ), + 'wc-cancelled' => _x( 'Cancelled', 'Order status', 'woocommerce' ), + 'wc-refunded' => _x( 'Refunded', 'Order status', 'woocommerce' ), + 'wc-failed' => _x( 'Failed', 'Order status', 'woocommerce' ), + ); + return apply_filters( 'wc_order_statuses', $order_statuses ); +} + +/** + * See if a string is an order status. + * + * @param string $maybe_status Status, including any wc- prefix. + * @return bool + */ +function wc_is_order_status( $maybe_status ) { + $order_statuses = wc_get_order_statuses(); + return isset( $order_statuses[ $maybe_status ] ); +} + +/** + * Get list of statuses which are consider 'paid'. + * + * @since 3.0.0 + * @return array + */ +function wc_get_is_paid_statuses() { + return apply_filters( 'woocommerce_order_is_paid_statuses', array( 'processing', 'completed' ) ); +} + +/** + * Get list of statuses which are consider 'pending payment'. + * + * @since 3.6.0 + * @return array + */ +function wc_get_is_pending_statuses() { + return apply_filters( 'woocommerce_order_is_pending_statuses', array( 'pending' ) ); +} + +/** + * Get the nice name for an order status. + * + * @since 2.2 + * @param string $status Status. + * @return string + */ +function wc_get_order_status_name( $status ) { + $statuses = wc_get_order_statuses(); + $status = 'wc-' === substr( $status, 0, 3 ) ? substr( $status, 3 ) : $status; + $status = isset( $statuses[ 'wc-' . $status ] ) ? $statuses[ 'wc-' . $status ] : $status; + return $status; +} + +/** + * Generate an order key with prefix. + * + * @since 3.5.4 + * @param string $key Order key without a prefix. By default generates a 13 digit secret. + * @return string The order key. + */ +function wc_generate_order_key( $key = '' ) { + if ( '' === $key ) { + $key = wp_generate_password( 13, false ); + } + + return 'wc_' . apply_filters( 'woocommerce_generate_order_key', 'order_' . $key ); +} + +/** + * Finds an Order ID based on an order key. + * + * @param string $order_key An order key has generated by. + * @return int The ID of an order, or 0 if the order could not be found. + */ +function wc_get_order_id_by_order_key( $order_key ) { + $data_store = WC_Data_Store::load( 'order' ); + return $data_store->get_order_id_by_order_key( $order_key ); +} + +/** + * Get all registered order types. + * + * @since 2.2 + * @param string $for Optionally define what you are getting order types for so + * only relevant types are returned. + * e.g. for 'order-meta-boxes', 'order-count'. + * @return array + */ +function wc_get_order_types( $for = '' ) { + global $wc_order_types; + + if ( ! is_array( $wc_order_types ) ) { + $wc_order_types = array(); + } + + $order_types = array(); + + switch ( $for ) { + case 'order-count': + foreach ( $wc_order_types as $type => $args ) { + if ( ! $args['exclude_from_order_count'] ) { + $order_types[] = $type; + } + } + break; + case 'order-meta-boxes': + foreach ( $wc_order_types as $type => $args ) { + if ( $args['add_order_meta_boxes'] ) { + $order_types[] = $type; + } + } + break; + case 'view-orders': + foreach ( $wc_order_types as $type => $args ) { + if ( ! $args['exclude_from_order_views'] ) { + $order_types[] = $type; + } + } + break; + case 'reports': + foreach ( $wc_order_types as $type => $args ) { + if ( ! $args['exclude_from_order_reports'] ) { + $order_types[] = $type; + } + } + break; + case 'sales-reports': + foreach ( $wc_order_types as $type => $args ) { + if ( ! $args['exclude_from_order_sales_reports'] ) { + $order_types[] = $type; + } + } + break; + case 'order-webhooks': + foreach ( $wc_order_types as $type => $args ) { + if ( ! $args['exclude_from_order_webhooks'] ) { + $order_types[] = $type; + } + } + break; + default: + $order_types = array_keys( $wc_order_types ); + break; + } + + return apply_filters( 'wc_order_types', $order_types, $for ); +} + +/** + * Get an order type by post type name. + * + * @param string $type Post type name. + * @return bool|array Details about the order type. + */ +function wc_get_order_type( $type ) { + global $wc_order_types; + + if ( isset( $wc_order_types[ $type ] ) ) { + return $wc_order_types[ $type ]; + } + + return false; +} + +/** + * Register order type. Do not use before init. + * + * Wrapper for register post type, as well as a method of telling WC which. + * post types are types of orders, and having them treated as such. + * + * $args are passed to register_post_type, but there are a few specific to this function: + * - exclude_from_orders_screen (bool) Whether or not this order type also get shown in the main. + * orders screen. + * - add_order_meta_boxes (bool) Whether or not the order type gets shop_order meta boxes. + * - exclude_from_order_count (bool) Whether or not this order type is excluded from counts. + * - exclude_from_order_views (bool) Whether or not this order type is visible by customers when. + * viewing orders e.g. on the my account page. + * - exclude_from_order_reports (bool) Whether or not to exclude this type from core reports. + * - exclude_from_order_sales_reports (bool) Whether or not to exclude this type from core sales reports. + * + * @since 2.2 + * @see register_post_type for $args used in that function + * @param string $type Post type. (max. 20 characters, can not contain capital letters or spaces). + * @param array $args An array of arguments. + * @return bool Success or failure + */ +function wc_register_order_type( $type, $args = array() ) { + if ( post_type_exists( $type ) ) { + return false; + } + + global $wc_order_types; + + if ( ! is_array( $wc_order_types ) ) { + $wc_order_types = array(); + } + + // Register as a post type. + if ( is_wp_error( register_post_type( $type, $args ) ) ) { + return false; + } + + // Register for WC usage. + $order_type_args = array( + 'exclude_from_orders_screen' => false, + 'add_order_meta_boxes' => true, + 'exclude_from_order_count' => false, + 'exclude_from_order_views' => false, + 'exclude_from_order_webhooks' => false, + 'exclude_from_order_reports' => false, + 'exclude_from_order_sales_reports' => false, + 'class_name' => 'WC_Order', + ); + + $args = array_intersect_key( $args, $order_type_args ); + $args = wp_parse_args( $args, $order_type_args ); + $wc_order_types[ $type ] = $args; + + return true; +} + +/** + * Return the count of processing orders. + * + * @return int + */ +function wc_processing_order_count() { + return wc_orders_count( 'processing' ); +} + +/** + * Return the orders count of a specific order status. + * + * @param string $status Status. + * @return int + */ +function wc_orders_count( $status ) { + $count = 0; + $status = 'wc-' . $status; + $order_statuses = array_keys( wc_get_order_statuses() ); + + if ( ! in_array( $status, $order_statuses, true ) ) { + return 0; + } + + $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . $status; + $cached_count = wp_cache_get( $cache_key, 'counts' ); + + if ( false !== $cached_count ) { + return $cached_count; + } + + foreach ( wc_get_order_types( 'order-count' ) as $type ) { + $data_store = WC_Data_Store::load( 'shop_order' === $type ? 'order' : $type ); + if ( $data_store ) { + $count += $data_store->get_order_count( $status ); + } + } + + wp_cache_set( $cache_key, $count, 'counts' ); + + return $count; +} + +/** + * Grant downloadable product access to the file identified by $download_id. + * + * @param string $download_id File identifier. + * @param int|WC_Product $product Product instance or ID. + * @param WC_Order $order Order data. + * @param int $qty Quantity purchased. + * @return int|bool insert id or false on failure. + */ +function wc_downloadable_file_permission( $download_id, $product, $order, $qty = 1 ) { + if ( is_numeric( $product ) ) { + $product = wc_get_product( $product ); + } + $download = new WC_Customer_Download(); + $download->set_download_id( $download_id ); + $download->set_product_id( $product->get_id() ); + $download->set_user_id( $order->get_customer_id() ); + $download->set_order_id( $order->get_id() ); + $download->set_user_email( $order->get_billing_email() ); + $download->set_order_key( $order->get_order_key() ); + $download->set_downloads_remaining( 0 > $product->get_download_limit() ? '' : $product->get_download_limit() * $qty ); + $download->set_access_granted( time() ); + $download->set_download_count( 0 ); + + $expiry = $product->get_download_expiry(); + + if ( $expiry > 0 ) { + $from_date = $order->get_date_completed() ? $order->get_date_completed()->format( 'Y-m-d' ) : current_time( 'mysql', true ); + $download->set_access_expires( strtotime( $from_date . ' + ' . $expiry . ' DAY' ) ); + } + + $download = apply_filters( 'woocommerce_downloadable_file_permission', $download, $product, $order, $qty ); + + return $download->save(); +} + +/** + * Order Status completed - give downloadable product access to customer. + * + * @param int $order_id Order ID. + * @param bool $force Force downloadable permissions. + */ +function wc_downloadable_product_permissions( $order_id, $force = false ) { + $order = wc_get_order( $order_id ); + + if ( ! $order || ( $order->get_data_store()->get_download_permissions_granted( $order ) && ! $force ) ) { + return; + } + + if ( $order->has_status( 'processing' ) && 'no' === get_option( 'woocommerce_downloads_grant_access_after_payment' ) ) { + return; + } + + if ( count( $order->get_items() ) > 0 ) { + foreach ( $order->get_items() as $item ) { + $product = $item->get_product(); + + if ( $product && $product->exists() && $product->is_downloadable() ) { + $downloads = $product->get_downloads(); + + foreach ( array_keys( $downloads ) as $download_id ) { + wc_downloadable_file_permission( $download_id, $product, $order, $item->get_quantity() ); + } + } + } + } + + $order->get_data_store()->set_download_permissions_granted( $order, true ); + do_action( 'woocommerce_grant_product_download_permissions', $order_id ); +} +add_action( 'woocommerce_order_status_completed', 'wc_downloadable_product_permissions' ); +add_action( 'woocommerce_order_status_processing', 'wc_downloadable_product_permissions' ); + +/** + * Clear all transients cache for order data. + * + * @param int|WC_Order $order Order instance or ID. + */ +function wc_delete_shop_order_transients( $order = 0 ) { + if ( is_numeric( $order ) ) { + $order = wc_get_order( $order ); + } + $reports = WC_Admin_Reports::get_reports(); + $transients_to_clear = array( + 'wc_admin_report', + ); + + foreach ( $reports as $report_group ) { + foreach ( $report_group['reports'] as $report_key => $report ) { + $transients_to_clear[] = 'wc_report_' . $report_key; + } + } + + foreach ( $transients_to_clear as $transient ) { + delete_transient( $transient ); + } + + // Clear money spent for user associated with order. + if ( is_a( $order, 'WC_Order' ) ) { + $order_id = $order->get_id(); + delete_user_meta( $order->get_customer_id(), '_money_spent' ); + delete_user_meta( $order->get_customer_id(), '_order_count' ); + } else { + $order_id = 0; + } + + // Increments the transient version to invalidate cache. + WC_Cache_Helper::get_transient_version( 'orders', true ); + + // Do the same for regular cache. + WC_Cache_Helper::invalidate_cache_group( 'orders' ); + + do_action( 'woocommerce_delete_shop_order_transients', $order_id ); +} + +/** + * See if we only ship to billing addresses. + * + * @return bool + */ +function wc_ship_to_billing_address_only() { + return 'billing_only' === get_option( 'woocommerce_ship_to_destination' ); +} + +/** + * Create a new order refund programmatically. + * + * Returns a new refund object on success which can then be used to add additional data. + * + * @since 2.2 + * @throws Exception Throws exceptions when fail to create, but returns WP_Error instead. + * @param array $args New refund arguments. + * @return WC_Order_Refund|WP_Error + */ +function wc_create_refund( $args = array() ) { + $default_args = array( + 'amount' => 0, + 'reason' => null, + 'order_id' => 0, + 'refund_id' => 0, + 'line_items' => array(), + 'refund_payment' => false, + 'restock_items' => false, + ); + + try { + $args = wp_parse_args( $args, $default_args ); + $order = wc_get_order( $args['order_id'] ); + + if ( ! $order ) { + throw new Exception( __( 'Invalid order ID.', 'woocommerce' ) ); + } + + $remaining_refund_amount = $order->get_remaining_refund_amount(); + $remaining_refund_items = $order->get_remaining_refund_items(); + $refund_item_count = 0; + $refund = new WC_Order_Refund( $args['refund_id'] ); + + if ( 0 > $args['amount'] || $args['amount'] > $remaining_refund_amount ) { + throw new Exception( __( 'Invalid refund amount.', 'woocommerce' ) ); + } + + $refund->set_currency( $order->get_currency() ); + $refund->set_amount( $args['amount'] ); + $refund->set_parent_id( absint( $args['order_id'] ) ); + $refund->set_refunded_by( get_current_user_id() ? get_current_user_id() : 1 ); + $refund->set_prices_include_tax( $order->get_prices_include_tax() ); + + if ( ! is_null( $args['reason'] ) ) { + $refund->set_reason( $args['reason'] ); + } + + // Negative line items. + if ( count( $args['line_items'] ) > 0 ) { + $items = $order->get_items( array( 'line_item', 'fee', 'shipping' ) ); + + foreach ( $items as $item_id => $item ) { + if ( ! isset( $args['line_items'][ $item_id ] ) ) { + continue; + } + + $qty = isset( $args['line_items'][ $item_id ]['qty'] ) ? $args['line_items'][ $item_id ]['qty'] : 0; + $refund_total = $args['line_items'][ $item_id ]['refund_total']; + $refund_tax = isset( $args['line_items'][ $item_id ]['refund_tax'] ) ? array_filter( (array) $args['line_items'][ $item_id ]['refund_tax'] ) : array(); + + if ( empty( $qty ) && empty( $refund_total ) && empty( $args['line_items'][ $item_id ]['refund_tax'] ) ) { + continue; + } + + $class = get_class( $item ); + $refunded_item = new $class( $item ); + $refunded_item->set_id( 0 ); + $refunded_item->add_meta_data( '_refunded_item_id', $item_id, true ); + $refunded_item->set_total( wc_format_refund_total( $refund_total ) ); + $refunded_item->set_taxes( + array( + 'total' => array_map( 'wc_format_refund_total', $refund_tax ), + 'subtotal' => array_map( 'wc_format_refund_total', $refund_tax ), + ) + ); + + if ( is_callable( array( $refunded_item, 'set_subtotal' ) ) ) { + $refunded_item->set_subtotal( wc_format_refund_total( $refund_total ) ); + } + + if ( is_callable( array( $refunded_item, 'set_quantity' ) ) ) { + $refunded_item->set_quantity( $qty * -1 ); + } + + $refund->add_item( $refunded_item ); + $refund_item_count += $qty; + } + } + + $refund->update_taxes(); + $refund->calculate_totals( false ); + $refund->set_total( $args['amount'] * -1 ); + + // this should remain after update_taxes(), as this will save the order, and write the current date to the db + // so we must wait until the order is persisted to set the date. + if ( isset( $args['date_created'] ) ) { + $refund->set_date_created( $args['date_created'] ); + } + + /** + * Action hook to adjust refund before save. + * + * @since 3.0.0 + */ + do_action( 'woocommerce_create_refund', $refund, $args ); + + if ( $refund->save() ) { + if ( $args['refund_payment'] ) { + $result = wc_refund_payment( $order, $refund->get_amount(), $refund->get_reason() ); + + if ( is_wp_error( $result ) ) { + $refund->delete(); + return $result; + } + + $refund->set_refunded_payment( true ); + $refund->save(); + } + + if ( $args['restock_items'] ) { + wc_restock_refunded_items( $order, $args['line_items'] ); + } + + // Trigger notification emails. + if ( ( $remaining_refund_amount - $args['amount'] ) > 0 || ( $order->has_free_item() && ( $remaining_refund_items - $refund_item_count ) > 0 ) ) { + do_action( 'woocommerce_order_partially_refunded', $order->get_id(), $refund->get_id() ); + } else { + do_action( 'woocommerce_order_fully_refunded', $order->get_id(), $refund->get_id() ); + + $parent_status = apply_filters( 'woocommerce_order_fully_refunded_status', 'refunded', $order->get_id(), $refund->get_id() ); + + if ( $parent_status ) { + $order->update_status( $parent_status ); + } + } + } + + do_action( 'woocommerce_refund_created', $refund->get_id(), $args ); + do_action( 'woocommerce_order_refunded', $order->get_id(), $refund->get_id() ); + + } catch ( Exception $e ) { + if ( isset( $refund ) && is_a( $refund, 'WC_Order_Refund' ) ) { + wp_delete_post( $refund->get_id(), true ); + } + return new WP_Error( 'error', $e->getMessage() ); + } + + return $refund; +} + +/** + * Try to refund the payment for an order via the gateway. + * + * @since 3.0.0 + * @throws Exception Throws exceptions when fail to refund, but returns WP_Error instead. + * @param WC_Order $order Order instance. + * @param string $amount Amount to refund. + * @param string $reason Refund reason. + * @return bool|WP_Error + */ +function wc_refund_payment( $order, $amount, $reason = '' ) { + try { + if ( ! is_a( $order, 'WC_Order' ) ) { + throw new Exception( __( 'Invalid order.', 'woocommerce' ) ); + } + + $gateway_controller = WC_Payment_Gateways::instance(); + $all_gateways = $gateway_controller->payment_gateways(); + $payment_method = $order->get_payment_method(); + $gateway = isset( $all_gateways[ $payment_method ] ) ? $all_gateways[ $payment_method ] : false; + + if ( ! $gateway ) { + throw new Exception( __( 'The payment gateway for this order does not exist.', 'woocommerce' ) ); + } + + if ( ! $gateway->supports( 'refunds' ) ) { + throw new Exception( __( 'The payment gateway for this order does not support automatic refunds.', 'woocommerce' ) ); + } + + $result = $gateway->process_refund( $order->get_id(), $amount, $reason ); + + if ( ! $result ) { + throw new Exception( __( 'An error occurred while attempting to create the refund using the payment gateway API.', 'woocommerce' ) ); + } + + if ( is_wp_error( $result ) ) { + throw new Exception( $result->get_error_message() ); + } + + return true; + + } catch ( Exception $e ) { + return new WP_Error( 'error', $e->getMessage() ); + } +} + +/** + * Restock items during refund. + * + * @since 3.0.0 + * @param WC_Order $order Order instance. + * @param array $refunded_line_items Refunded items list. + */ +function wc_restock_refunded_items( $order, $refunded_line_items ) { + if ( ! apply_filters( 'woocommerce_can_restock_refunded_items', true, $order, $refunded_line_items ) ) { + return; + } + + $line_items = $order->get_items(); + + foreach ( $line_items as $item_id => $item ) { + if ( ! isset( $refunded_line_items[ $item_id ], $refunded_line_items[ $item_id ]['qty'] ) ) { + continue; + } + $product = $item->get_product(); + $item_stock_reduced = $item->get_meta( '_reduced_stock', true ); + $qty_to_refund = $refunded_line_items[ $item_id ]['qty']; + + if ( ! $item_stock_reduced || ! $qty_to_refund || ! $product || ! $product->managing_stock() ) { + continue; + } + + $old_stock = $product->get_stock_quantity(); + $new_stock = wc_update_product_stock( $product, $qty_to_refund, 'increase' ); + + // Update _reduced_stock meta to track changes. + $item_stock_reduced = $item_stock_reduced - $qty_to_refund; + + if ( 0 < $item_stock_reduced ) { + $item->update_meta_data( '_reduced_stock', $item_stock_reduced ); + } else { + $item->delete_meta_data( '_reduced_stock' ); + } + + /* translators: 1: product ID 2: old stock level 3: new stock level */ + $order->add_order_note( sprintf( __( 'Item #%1$s stock increased from %2$s to %3$s.', 'woocommerce' ), $product->get_id(), $old_stock, $new_stock ) ); + + $item->save(); + + do_action( 'woocommerce_restock_refunded_item', $product->get_id(), $old_stock, $new_stock, $order, $product ); + } +} + +/** + * Get tax class by tax id. + * + * @since 2.2 + * @param int $tax_id Tax ID. + * @return string + */ +function wc_get_tax_class_by_tax_id( $tax_id ) { + global $wpdb; + return $wpdb->get_var( $wpdb->prepare( "SELECT tax_rate_class FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %d", $tax_id ) ); +} + +/** + * Get payment gateway class by order data. + * + * @since 2.2 + * @param int|WC_Order $order Order instance. + * @return WC_Payment_Gateway|bool + */ +function wc_get_payment_gateway_by_order( $order ) { + if ( WC()->payment_gateways() ) { + $payment_gateways = WC()->payment_gateways()->payment_gateways(); + } else { + $payment_gateways = array(); + } + + if ( ! is_object( $order ) ) { + $order_id = absint( $order ); + $order = wc_get_order( $order_id ); + } + + return is_a( $order, 'WC_Order' ) && isset( $payment_gateways[ $order->get_payment_method() ] ) ? $payment_gateways[ $order->get_payment_method() ] : false; +} + +/** + * When refunding an order, create a refund line item if the partial refunds do not match order total. + * + * This is manual; no gateway refund will be performed. + * + * @since 2.4 + * @param int $order_id Order ID. + */ +function wc_order_fully_refunded( $order_id ) { + $order = wc_get_order( $order_id ); + $max_refund = wc_format_decimal( $order->get_total() - $order->get_total_refunded() ); + + if ( ! $max_refund ) { + return; + } + + // Create the refund object. + wc_switch_to_site_locale(); + wc_create_refund( + array( + 'amount' => $max_refund, + 'reason' => __( 'Order fully refunded.', 'woocommerce' ), + 'order_id' => $order_id, + 'line_items' => array(), + ) + ); + wc_restore_locale(); + + $order->add_order_note( __( 'Order status set to refunded. To return funds to the customer you will need to issue a refund through your payment gateway.', 'woocommerce' ) ); +} +add_action( 'woocommerce_order_status_refunded', 'wc_order_fully_refunded' ); + +/** + * Search orders. + * + * @since 2.6.0 + * @param string $term Term to search. + * @return array List of orders ID. + */ +function wc_order_search( $term ) { + $data_store = WC_Data_Store::load( 'order' ); + return $data_store->search_orders( str_replace( 'Order #', '', wc_clean( $term ) ) ); +} + +/** + * Update total sales amount for each product within a paid order. + * + * @since 3.0.0 + * @param int $order_id Order ID. + */ +function wc_update_total_sales_counts( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( ! $order || $order->get_data_store()->get_recorded_sales( $order ) ) { + return; + } + + if ( count( $order->get_items() ) > 0 ) { + foreach ( $order->get_items() as $item ) { + $product_id = $item->get_product_id(); + + if ( $product_id ) { + $data_store = WC_Data_Store::load( 'product' ); + $data_store->update_product_sales( $product_id, absint( $item->get_quantity() ), 'increase' ); + } + } + } + + $order->get_data_store()->set_recorded_sales( $order, true ); + + /** + * Called when sales for an order are recorded + * + * @param int $order_id order id + */ + do_action( 'woocommerce_recorded_sales', $order_id ); +} +add_action( 'woocommerce_order_status_completed', 'wc_update_total_sales_counts' ); +add_action( 'woocommerce_order_status_processing', 'wc_update_total_sales_counts' ); +add_action( 'woocommerce_order_status_on-hold', 'wc_update_total_sales_counts' ); + +/** + * Update used coupon amount for each coupon within an order. + * + * @since 3.0.0 + * @param int $order_id Order ID. + */ +function wc_update_coupon_usage_counts( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( ! $order ) { + return; + } + + $has_recorded = $order->get_data_store()->get_recorded_coupon_usage_counts( $order ); + + if ( $order->has_status( 'cancelled' ) && $has_recorded ) { + $action = 'reduce'; + $order->get_data_store()->set_recorded_coupon_usage_counts( $order, false ); + } elseif ( ! $order->has_status( 'cancelled' ) && ! $has_recorded ) { + $action = 'increase'; + $order->get_data_store()->set_recorded_coupon_usage_counts( $order, true ); + } elseif ( $order->has_status( 'cancelled' ) ) { + $order->get_data_store()->release_held_coupons( $order, true ); + return; + } else { + return; + } + + if ( count( $order->get_coupon_codes() ) > 0 ) { + foreach ( $order->get_coupon_codes() as $code ) { + if ( ! $code ) { + continue; + } + + $coupon = new WC_Coupon( $code ); + $used_by = $order->get_user_id(); + + if ( ! $used_by ) { + $used_by = $order->get_billing_email(); + } + + switch ( $action ) { + case 'reduce': + $coupon->decrease_usage_count( $used_by ); + break; + case 'increase': + $coupon->increase_usage_count( $used_by, $order ); + break; + } + } + $order->get_data_store()->release_held_coupons( $order, true ); + } +} +add_action( 'woocommerce_order_status_pending', 'wc_update_coupon_usage_counts' ); +add_action( 'woocommerce_order_status_completed', 'wc_update_coupon_usage_counts' ); +add_action( 'woocommerce_order_status_processing', 'wc_update_coupon_usage_counts' ); +add_action( 'woocommerce_order_status_on-hold', 'wc_update_coupon_usage_counts' ); +add_action( 'woocommerce_order_status_cancelled', 'wc_update_coupon_usage_counts' ); + +/** + * Cancel all unpaid orders after held duration to prevent stock lock for those products. + */ +function wc_cancel_unpaid_orders() { + $held_duration = get_option( 'woocommerce_hold_stock_minutes' ); + + if ( $held_duration < 1 || 'yes' !== get_option( 'woocommerce_manage_stock' ) ) { + return; + } + + $data_store = WC_Data_Store::load( 'order' ); + $unpaid_orders = $data_store->get_unpaid_orders( strtotime( '-' . absint( $held_duration ) . ' MINUTES', current_time( 'timestamp' ) ) ); + + if ( $unpaid_orders ) { + foreach ( $unpaid_orders as $unpaid_order ) { + $order = wc_get_order( $unpaid_order ); + + if ( apply_filters( 'woocommerce_cancel_unpaid_order', 'checkout' === $order->get_created_via(), $order ) ) { + $order->update_status( 'cancelled', __( 'Unpaid order cancelled - time limit reached.', 'woocommerce' ) ); + } + } + } + wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' ); + wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' ); +} +add_action( 'woocommerce_cancel_unpaid_orders', 'wc_cancel_unpaid_orders' ); + +/** + * Sanitize order id removing unwanted characters. + * + * E.g Users can sometimes try to track an order id using # with no success. + * This function will fix this. + * + * @since 3.1.0 + * @param int $order_id Order ID. + */ +function wc_sanitize_order_id( $order_id ) { + return (int) filter_var( $order_id, FILTER_SANITIZE_NUMBER_INT ); +} +add_filter( 'woocommerce_shortcode_order_tracking_order_id', 'wc_sanitize_order_id' ); + +/** + * Get an order note. + * + * @since 3.2.0 + * @param int|WP_Comment $data Note ID (or WP_Comment instance for internal use only). + * @return stdClass|null Object with order note details or null when does not exists. + */ +function wc_get_order_note( $data ) { + if ( is_numeric( $data ) ) { + $data = get_comment( $data ); + } + + if ( ! is_a( $data, 'WP_Comment' ) ) { + return null; + } + + return (object) apply_filters( + 'woocommerce_get_order_note', + array( + 'id' => (int) $data->comment_ID, + 'date_created' => wc_string_to_datetime( $data->comment_date ), + 'content' => $data->comment_content, + 'customer_note' => (bool) get_comment_meta( $data->comment_ID, 'is_customer_note', true ), + 'added_by' => __( 'WooCommerce', 'woocommerce' ) === $data->comment_author ? 'system' : $data->comment_author, + ), + $data + ); +} + +/** + * Get order notes. + * + * @since 3.2.0 + * @param array $args Query arguments { + * Array of query parameters. + * + * @type string $limit Maximum number of notes to retrieve. + * Default empty (no limit). + * @type int $order_id Limit results to those affiliated with a given order ID. + * Default 0. + * @type array $order__in Array of order IDs to include affiliated notes for. + * Default empty. + * @type array $order__not_in Array of order IDs to exclude affiliated notes for. + * Default empty. + * @type string $orderby Define how should sort notes. + * Accepts 'date_created', 'date_created_gmt' or 'id'. + * Default: 'id'. + * @type string $order How to order retrieved notes. + * Accepts 'ASC' or 'DESC'. + * Default: 'DESC'. + * @type string $type Define what type of note should retrieve. + * Accepts 'customer', 'internal' or empty for both. + * Default empty. + * } + * @return stdClass[] Array of stdClass objects with order notes details. + */ +function wc_get_order_notes( $args ) { + $key_mapping = array( + 'limit' => 'number', + 'order_id' => 'post_id', + 'order__in' => 'post__in', + 'order__not_in' => 'post__not_in', + ); + + foreach ( $key_mapping as $query_key => $db_key ) { + if ( isset( $args[ $query_key ] ) ) { + $args[ $db_key ] = $args[ $query_key ]; + unset( $args[ $query_key ] ); + } + } + + // Define orderby. + $orderby_mapping = array( + 'date_created' => 'comment_date', + 'date_created_gmt' => 'comment_date_gmt', + 'id' => 'comment_ID', + ); + + $args['orderby'] = ! empty( $args['orderby'] ) && in_array( $args['orderby'], array( 'date_created', 'date_created_gmt', 'id' ), true ) ? $orderby_mapping[ $args['orderby'] ] : 'comment_ID'; + + // Set WooCommerce order type. + if ( isset( $args['type'] ) && 'customer' === $args['type'] ) { + $args['meta_query'] = array( // WPCS: slow query ok. + array( + 'key' => 'is_customer_note', + 'value' => 1, + 'compare' => '=', + ), + ); + } elseif ( isset( $args['type'] ) && 'internal' === $args['type'] ) { + $args['meta_query'] = array( // WPCS: slow query ok. + array( + 'key' => 'is_customer_note', + 'compare' => 'NOT EXISTS', + ), + ); + } + + // Set correct comment type. + $args['type'] = 'order_note'; + + // Always approved. + $args['status'] = 'approve'; + + // Does not support 'count' or 'fields'. + unset( $args['count'], $args['fields'] ); + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + $notes = get_comments( $args ); + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); + + return array_filter( array_map( 'wc_get_order_note', $notes ) ); +} + +/** + * Create an order note. + * + * @since 3.2.0 + * @param int $order_id Order ID. + * @param string $note Note to add. + * @param bool $is_customer_note If is a costumer note. + * @param bool $added_by_user If note is create by an user. + * @return int|WP_Error Integer when created or WP_Error when found an error. + */ +function wc_create_order_note( $order_id, $note, $is_customer_note = false, $added_by_user = false ) { + $order = wc_get_order( $order_id ); + + if ( ! $order ) { + return new WP_Error( 'invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + return $order->add_order_note( $note, (int) $is_customer_note, $added_by_user ); +} + +/** + * Delete an order note. + * + * @since 3.2.0 + * @param int $note_id Order note. + * @return bool True on success, false on failure. + */ +function wc_delete_order_note( $note_id ) { + return wp_delete_comment( $note_id, true ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-order-item-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-order-item-functions.php new file mode 100644 index 0000000..5f7c6a1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-order-item-functions.php @@ -0,0 +1,181 @@ + '', + 'order_item_type' => 'line_item', + ); + + $item_array = wp_parse_args( $item_array, $defaults ); + $data_store = WC_Data_Store::load( 'order-item' ); + $item_id = $data_store->add_order_item( $order_id, $item_array ); + $item = WC_Order_Factory::get_order_item( $item_id ); + + do_action( 'woocommerce_new_order_item', $item_id, $item, $order_id ); + + return $item_id; +} + +/** + * Update an item for an order. + * + * @since 2.2 + * @param int $item_id Item ID. + * @param array $args Either `order_item_type` or `order_item_name`. + * + * @throws Exception When `WC_Data_Store::load` validation fails. + * @return bool True if successfully updated, false otherwise. + */ +function wc_update_order_item( $item_id, $args ) { + $data_store = WC_Data_Store::load( 'order-item' ); + $update = $data_store->update_order_item( $item_id, $args ); + + if ( false === $update ) { + return false; + } + + do_action( 'woocommerce_update_order_item', $item_id, $args ); + + return true; +} + +/** + * Delete an item from the order it belongs to based on item id. + * + * @param int $item_id Item ID. + * + * @throws Exception When `WC_Data_Store::load` validation fails. + * @return bool + */ +function wc_delete_order_item( $item_id ) { + $item_id = absint( $item_id ); + + if ( ! $item_id ) { + return false; + } + + $data_store = WC_Data_Store::load( 'order-item' ); + + do_action( 'woocommerce_before_delete_order_item', $item_id ); + + $data_store->delete_order_item( $item_id ); + + do_action( 'woocommerce_delete_order_item', $item_id ); + + return true; +} + +/** + * WooCommerce Order Item Meta API - Update term meta. + * + * @param int $item_id Item ID. + * @param string $meta_key Meta key. + * @param string $meta_value Meta value. + * @param string $prev_value Previous value (default: ''). + * + * @throws Exception When `WC_Data_Store::load` validation fails. + * @return bool + */ +function wc_update_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value = '' ) { + $data_store = WC_Data_Store::load( 'order-item' ); + if ( $data_store->update_metadata( $item_id, $meta_key, $meta_value, $prev_value ) ) { + WC_Cache_Helper::invalidate_cache_group( 'object_' . $item_id ); // Invalidate cache. + return true; + } + return false; +} + +/** + * WooCommerce Order Item Meta API - Add term meta. + * + * @param int $item_id Item ID. + * @param string $meta_key Meta key. + * @param string $meta_value Meta value. + * @param bool $unique If meta data should be unique (default: false). + * + * @throws Exception When `WC_Data_Store::load` validation fails. + * @return int New row ID or 0. + */ +function wc_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique = false ) { + $data_store = WC_Data_Store::load( 'order-item' ); + $meta_id = $data_store->add_metadata( $item_id, $meta_key, $meta_value, $unique ); + + if ( $meta_id ) { + WC_Cache_Helper::invalidate_cache_group( 'object_' . $item_id ); // Invalidate cache. + return $meta_id; + } + return 0; +} + +/** + * WooCommerce Order Item Meta API - Delete term meta. + * + * @param int $item_id Item ID. + * @param string $meta_key Meta key. + * @param string $meta_value Meta value (default: ''). + * @param bool $delete_all Delete all meta data, defaults to `false`. + * + * @throws Exception When `WC_Data_Store::load` validation fails. + * @return bool + */ +function wc_delete_order_item_meta( $item_id, $meta_key, $meta_value = '', $delete_all = false ) { + $data_store = WC_Data_Store::load( 'order-item' ); + if ( $data_store->delete_metadata( $item_id, $meta_key, $meta_value, $delete_all ) ) { + WC_Cache_Helper::invalidate_cache_group( 'object_' . $item_id ); // Invalidate cache. + return true; + } + return false; +} + +/** + * WooCommerce Order Item Meta API - Get term meta. + * + * @param int $item_id Item ID. + * @param string $key Meta key. + * @param bool $single Whether to return a single value. (default: true). + * + * @throws Exception When `WC_Data_Store::load` validation fails. + * @return mixed + */ +function wc_get_order_item_meta( $item_id, $key, $single = true ) { + $data_store = WC_Data_Store::load( 'order-item' ); + return $data_store->get_metadata( $item_id, $key, $single ); +} + +/** + * Get order ID by order item ID. + * + * @param int $item_id Item ID. + * + * @throws Exception When `WC_Data_Store::load` validation fails. + * @return int + */ +function wc_get_order_id_by_order_item_id( $item_id ) { + $data_store = WC_Data_Store::load( 'order-item' ); + return $data_store->get_order_id_by_order_item_id( $item_id ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-page-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-page-functions.php new file mode 100644 index 0000000..7519db9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-page-functions.php @@ -0,0 +1,227 @@ +query->get_current_endpoint(); + $action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; + $endpoint_title = WC()->query->get_endpoint_title( $endpoint, $action ); + $title = $endpoint_title ? $endpoint_title : $title; + + remove_filter( 'the_title', 'wc_page_endpoint_title' ); + } + + return $title; +} + +add_filter( 'the_title', 'wc_page_endpoint_title' ); + +/** + * Retrieve page ids - used for myaccount, edit_address, shop, cart, checkout, pay, view_order, terms. returns -1 if no page is found. + * + * @param string $page Page slug. + * @return int + */ +function wc_get_page_id( $page ) { + if ( 'pay' === $page || 'thanks' === $page ) { + wc_deprecated_argument( __FUNCTION__, '2.1', 'The "pay" and "thanks" pages are no-longer used - an endpoint is added to the checkout instead. To get a valid link use the WC_Order::get_checkout_payment_url() or WC_Order::get_checkout_order_received_url() methods instead.' ); + + $page = 'checkout'; + } + if ( 'change_password' === $page || 'edit_address' === $page || 'lost_password' === $page ) { + wc_deprecated_argument( __FUNCTION__, '2.1', 'The "change_password", "edit_address" and "lost_password" pages are no-longer used - an endpoint is added to the my-account instead. To get a valid link use the wc_customer_edit_account_url() function instead.' ); + + $page = 'myaccount'; + } + + $page = apply_filters( 'woocommerce_get_' . $page . '_page_id', get_option( 'woocommerce_' . $page . '_page_id' ) ); + + return $page ? absint( $page ) : -1; +} + +/** + * Retrieve page permalink. + * + * @param string $page page slug. + * @param string|bool $fallback Fallback URL if page is not set. Defaults to home URL. @since 3.4.0. + * @return string + */ +function wc_get_page_permalink( $page, $fallback = null ) { + $page_id = wc_get_page_id( $page ); + $permalink = 0 < $page_id ? get_permalink( $page_id ) : ''; + + if ( ! $permalink ) { + $permalink = is_null( $fallback ) ? get_home_url() : $fallback; + } + + return apply_filters( 'woocommerce_get_' . $page . '_page_permalink', $permalink ); +} + +/** + * Get endpoint URL. + * + * Gets the URL for an endpoint, which varies depending on permalink settings. + * + * @param string $endpoint Endpoint slug. + * @param string $value Query param value. + * @param string $permalink Permalink. + * + * @return string + */ +function wc_get_endpoint_url( $endpoint, $value = '', $permalink = '' ) { + if ( ! $permalink ) { + $permalink = get_permalink(); + } + + // Map endpoint to options. + $query_vars = WC()->query->get_query_vars(); + $endpoint = ! empty( $query_vars[ $endpoint ] ) ? $query_vars[ $endpoint ] : $endpoint; + $value = ( get_option( 'woocommerce_myaccount_edit_address_endpoint', 'edit-address' ) === $endpoint ) ? wc_edit_address_i18n( $value ) : $value; + + if ( get_option( 'permalink_structure' ) ) { + if ( strstr( $permalink, '?' ) ) { + $query_string = '?' . wp_parse_url( $permalink, PHP_URL_QUERY ); + $permalink = current( explode( '?', $permalink ) ); + } else { + $query_string = ''; + } + $url = trailingslashit( $permalink ); + + if ( $value ) { + $url .= trailingslashit( $endpoint ) . user_trailingslashit( $value ); + } else { + $url .= user_trailingslashit( $endpoint ); + } + + $url .= $query_string; + } else { + $url = add_query_arg( $endpoint, $value, $permalink ); + } + + return apply_filters( 'woocommerce_get_endpoint_url', $url, $endpoint, $value, $permalink ); +} + +/** + * Hide menu items conditionally. + * + * @param array $items Navigation items. + * @return array + */ +function wc_nav_menu_items( $items ) { + if ( ! is_user_logged_in() ) { + $customer_logout = get_option( 'woocommerce_logout_endpoint', 'customer-logout' ); + + if ( ! empty( $customer_logout ) && ! empty( $items ) && is_array( $items ) ) { + foreach ( $items as $key => $item ) { + if ( empty( $item->url ) ) { + continue; + } + $path = wp_parse_url( $item->url, PHP_URL_PATH ); + $query = wp_parse_url( $item->url, PHP_URL_QUERY ); + + if ( strstr( $path, $customer_logout ) || strstr( $query, $customer_logout ) ) { + unset( $items[ $key ] ); + } + } + } + } + + return $items; +} +add_filter( 'wp_nav_menu_objects', 'wc_nav_menu_items', 10 ); + + +/** + * Fix active class in nav for shop page. + * + * @param array $menu_items Menu items. + * @return array + */ +function wc_nav_menu_item_classes( $menu_items ) { + if ( ! is_woocommerce() ) { + return $menu_items; + } + + $shop_page = wc_get_page_id( 'shop' ); + $page_for_posts = (int) get_option( 'page_for_posts' ); + + if ( ! empty( $menu_items ) && is_array( $menu_items ) ) { + foreach ( $menu_items as $key => $menu_item ) { + $classes = (array) $menu_item->classes; + $menu_id = (int) $menu_item->object_id; + + // Unset active class for blog page. + if ( $page_for_posts === $menu_id ) { + $menu_items[ $key ]->current = false; + + if ( in_array( 'current_page_parent', $classes, true ) ) { + unset( $classes[ array_search( 'current_page_parent', $classes, true ) ] ); + } + + if ( in_array( 'current-menu-item', $classes, true ) ) { + unset( $classes[ array_search( 'current-menu-item', $classes, true ) ] ); + } + } elseif ( is_shop() && $shop_page === $menu_id && 'page' === $menu_item->object ) { + // Set active state if this is the shop page link. + $menu_items[ $key ]->current = true; + $classes[] = 'current-menu-item'; + $classes[] = 'current_page_item'; + + } elseif ( is_singular( 'product' ) && $shop_page === $menu_id ) { + // Set parent state if this is a product page. + $classes[] = 'current_page_parent'; + } + + $menu_items[ $key ]->classes = array_unique( $classes ); + } + } + + return $menu_items; +} +add_filter( 'wp_nav_menu_objects', 'wc_nav_menu_item_classes', 2 ); + + +/** + * Fix active class in wp_list_pages for shop page. + * + * See details in https://github.com/woocommerce/woocommerce/issues/177. + * + * @param string $pages Pages list. + * @return string + */ +function wc_list_pages( $pages ) { + if ( ! is_woocommerce() ) { + return $pages; + } + + // Remove current_page_parent class from any item. + $pages = str_replace( 'current_page_parent', '', $pages ); + // Find shop_page_id through woocommerce options. + $shop_page = 'page-item-' . wc_get_page_id( 'shop' ); + + if ( is_shop() ) { + // Add current_page_item class to shop page. + return str_replace( $shop_page, $shop_page . ' current_page_item', $pages ); + } + + // Add current_page_parent class to shop page. + return str_replace( $shop_page, $shop_page . ' current_page_parent', $pages ); +} +add_filter( 'wp_list_pages', 'wc_list_pages' ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-product-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-product-functions.php new file mode 100644 index 0000000..d4ee945 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-product-functions.php @@ -0,0 +1,1612 @@ + 'limit', + 'post_status' => 'status', + 'post_parent' => 'parent', + 'posts_per_page' => 'limit', + 'paged' => 'page', + ); + + foreach ( $map_legacy as $from => $to ) { + if ( isset( $args[ $from ] ) ) { + $args[ $to ] = $args[ $from ]; + } + } + + $query = new WC_Product_Query( $args ); + return $query->get_products(); +} + +/** + * Main function for returning products, uses the WC_Product_Factory class. + * + * This function should only be called after 'init' action is finished, as there might be taxonomies that are getting + * registered during the init action. + * + * @since 2.2.0 + * + * @param mixed $the_product Post object or post ID of the product. + * @param array $deprecated Previously used to pass arguments to the factory, e.g. to force a type. + * @return WC_Product|null|false + */ +function wc_get_product( $the_product = false, $deprecated = array() ) { + if ( ! did_action( 'woocommerce_init' ) || ! did_action( 'woocommerce_after_register_taxonomy' ) || ! did_action( 'woocommerce_after_register_post_type' ) ) { + /* translators: 1: wc_get_product 2: woocommerce_init 3: woocommerce_after_register_taxonomy 4: woocommerce_after_register_post_type */ + wc_doing_it_wrong( __FUNCTION__, sprintf( __( '%1$s should not be called before the %2$s, %3$s and %4$s actions have finished.', 'woocommerce' ), 'wc_get_product', 'woocommerce_init', 'woocommerce_after_register_taxonomy', 'woocommerce_after_register_post_type' ), '3.9' ); + return false; + } + if ( ! empty( $deprecated ) ) { + wc_deprecated_argument( 'args', '3.0', 'Passing args to wc_get_product is deprecated. If you need to force a type, construct the product class directly.' ); + } + return WC()->product_factory->get_product( $the_product, $deprecated ); +} + +/** + * Get a product object. + * + * @see WC_Product_Factory::get_product_classname + * @since 3.9.0 + * @param string $product_type Product type. If used an invalid type a WC_Product_Simple instance will be returned. + * @param int $product_id Product ID. + * @return WC_Product + */ +function wc_get_product_object( $product_type, $product_id = 0 ) { + $classname = WC_Product_Factory::get_product_classname( $product_id, $product_type ); + + return new $classname( $product_id ); +} + +/** + * Returns whether or not SKUS are enabled. + * + * @return bool + */ +function wc_product_sku_enabled() { + return apply_filters( 'wc_product_sku_enabled', true ); +} + +/** + * Returns whether or not product weights are enabled. + * + * @return bool + */ +function wc_product_weight_enabled() { + return apply_filters( 'wc_product_weight_enabled', true ); +} + +/** + * Returns whether or not product dimensions (HxWxD) are enabled. + * + * @return bool + */ +function wc_product_dimensions_enabled() { + return apply_filters( 'wc_product_dimensions_enabled', true ); +} + +/** + * Clear transient cache for product data. + * + * @param int $post_id (default: 0) The product ID. + */ +function wc_delete_product_transients( $post_id = 0 ) { + // Transient data to clear with a fixed name which may be stale after product updates. + $transients_to_clear = array( + 'wc_products_onsale', + 'wc_featured_products', + 'wc_outofstock_count', + 'wc_low_stock_count', + ); + + foreach ( $transients_to_clear as $transient ) { + delete_transient( $transient ); + } + + if ( $post_id > 0 ) { + // Transient names that include an ID - since they are dynamic they cannot be cleaned in bulk without the ID. + $post_transient_names = array( + 'wc_product_children_', + 'wc_var_prices_', + 'wc_related_', + 'wc_child_has_weight_', + 'wc_child_has_dimensions_', + ); + + foreach ( $post_transient_names as $transient ) { + delete_transient( $transient . $post_id ); + } + } + + // Increments the transient version to invalidate cache. + WC_Cache_Helper::get_transient_version( 'product', true ); + + do_action( 'woocommerce_delete_product_transients', $post_id ); +} + +/** + * Function that returns an array containing the IDs of the products that are on sale. + * + * @since 2.0 + * @return array + */ +function wc_get_product_ids_on_sale() { + // Load from cache. + $product_ids_on_sale = get_transient( 'wc_products_onsale' ); + + // Valid cache found. + if ( false !== $product_ids_on_sale ) { + return $product_ids_on_sale; + } + + $data_store = WC_Data_Store::load( 'product' ); + $on_sale_products = $data_store->get_on_sale_products(); + $product_ids_on_sale = wp_parse_id_list( array_merge( wp_list_pluck( $on_sale_products, 'id' ), array_diff( wp_list_pluck( $on_sale_products, 'parent_id' ), array( 0 ) ) ) ); + + set_transient( 'wc_products_onsale', $product_ids_on_sale, DAY_IN_SECONDS * 30 ); + + return $product_ids_on_sale; +} + +/** + * Function that returns an array containing the IDs of the featured products. + * + * @since 2.1 + * @return array + */ +function wc_get_featured_product_ids() { + // Load from cache. + $featured_product_ids = get_transient( 'wc_featured_products' ); + + // Valid cache found. + if ( false !== $featured_product_ids ) { + return $featured_product_ids; + } + + $data_store = WC_Data_Store::load( 'product' ); + $featured = $data_store->get_featured_product_ids(); + $product_ids = array_keys( $featured ); + $parent_ids = array_values( array_filter( $featured ) ); + $featured_product_ids = array_unique( array_merge( $product_ids, $parent_ids ) ); + + set_transient( 'wc_featured_products', $featured_product_ids, DAY_IN_SECONDS * 30 ); + + return $featured_product_ids; +} + +/** + * Filter to allow product_cat in the permalinks for products. + * + * @param string $permalink The existing permalink URL. + * @param WP_Post $post WP_Post object. + * @return string + */ +function wc_product_post_type_link( $permalink, $post ) { + // Abort if post is not a product. + if ( 'product' !== $post->post_type ) { + return $permalink; + } + + // Abort early if the placeholder rewrite tag isn't in the generated URL. + if ( false === strpos( $permalink, '%' ) ) { + return $permalink; + } + + // Get the custom taxonomy terms in use by this post. + $terms = get_the_terms( $post->ID, 'product_cat' ); + + if ( ! empty( $terms ) ) { + $terms = wp_list_sort( + $terms, + array( + 'parent' => 'DESC', + 'term_id' => 'ASC', + ) + ); + $category_object = apply_filters( 'wc_product_post_type_link_product_cat', $terms[0], $terms, $post ); + $product_cat = $category_object->slug; + + if ( $category_object->parent ) { + $ancestors = get_ancestors( $category_object->term_id, 'product_cat' ); + foreach ( $ancestors as $ancestor ) { + $ancestor_object = get_term( $ancestor, 'product_cat' ); + if ( apply_filters( 'woocommerce_product_post_type_link_parent_category_only', false ) ) { + $product_cat = $ancestor_object->slug; + } else { + $product_cat = $ancestor_object->slug . '/' . $product_cat; + } + } + } + } else { + // If no terms are assigned to this post, use a string instead (can't leave the placeholder there). + $product_cat = _x( 'uncategorized', 'slug', 'woocommerce' ); + } + + $find = array( + '%year%', + '%monthnum%', + '%day%', + '%hour%', + '%minute%', + '%second%', + '%post_id%', + '%category%', + '%product_cat%', + ); + + $replace = array( + date_i18n( 'Y', strtotime( $post->post_date ) ), + date_i18n( 'm', strtotime( $post->post_date ) ), + date_i18n( 'd', strtotime( $post->post_date ) ), + date_i18n( 'H', strtotime( $post->post_date ) ), + date_i18n( 'i', strtotime( $post->post_date ) ), + date_i18n( 's', strtotime( $post->post_date ) ), + $post->ID, + $product_cat, + $product_cat, + ); + + $permalink = str_replace( $find, $replace, $permalink ); + + return $permalink; +} +add_filter( 'post_type_link', 'wc_product_post_type_link', 10, 2 ); + +/** + * Get the placeholder image URL either from media, or use the fallback image. + * + * @param string $size Thumbnail size to use. + * @return string + */ +function wc_placeholder_img_src( $size = 'woocommerce_thumbnail' ) { + $src = WC()->plugin_url() . '/assets/images/placeholder.png'; + $placeholder_image = get_option( 'woocommerce_placeholder_image', 0 ); + + if ( ! empty( $placeholder_image ) ) { + if ( is_numeric( $placeholder_image ) ) { + $image = wp_get_attachment_image_src( $placeholder_image, $size ); + + if ( ! empty( $image[0] ) ) { + $src = $image[0]; + } + } else { + $src = $placeholder_image; + } + } + + return apply_filters( 'woocommerce_placeholder_img_src', $src ); +} + +/** + * Get the placeholder image. + * + * Uses wp_get_attachment_image if using an attachment ID @since 3.6.0 to handle responsiveness. + * + * @param string $size Image size. + * @param string|array $attr Optional. Attributes for the image markup. Default empty. + * @return string + */ +function wc_placeholder_img( $size = 'woocommerce_thumbnail', $attr = '' ) { + $dimensions = wc_get_image_size( $size ); + $placeholder_image = get_option( 'woocommerce_placeholder_image', 0 ); + + $default_attr = array( + 'class' => 'woocommerce-placeholder wp-post-image', + 'alt' => __( 'Placeholder', 'woocommerce' ), + ); + + $attr = wp_parse_args( $attr, $default_attr ); + + if ( wp_attachment_is_image( $placeholder_image ) ) { + $image_html = wp_get_attachment_image( + $placeholder_image, + $size, + false, + $attr + ); + } else { + $image = wc_placeholder_img_src( $size ); + $hwstring = image_hwstring( $dimensions['width'], $dimensions['height'] ); + $attributes = array(); + + foreach ( $attr as $name => $value ) { + $attribute[] = esc_attr( $name ) . '="' . esc_attr( $value ) . '"'; + } + + $image_html = ''; + } + + return apply_filters( 'woocommerce_placeholder_img', $image_html, $size, $dimensions ); +} + +/** + * Variation Formatting. + * + * Gets a formatted version of variation data or item meta. + * + * @param array|WC_Product_Variation $variation Variation object. + * @param bool $flat Should this be a flat list or HTML list? (default: false). + * @param bool $include_names include attribute names/labels in the list. + * @param bool $skip_attributes_in_name Do not list attributes already part of the variation name. + * @return string + */ +function wc_get_formatted_variation( $variation, $flat = false, $include_names = true, $skip_attributes_in_name = false ) { + $return = ''; + + if ( is_a( $variation, 'WC_Product_Variation' ) ) { + $variation_attributes = $variation->get_attributes(); + $product = $variation; + $variation_name = $variation->get_name(); + } else { + $product = false; + $variation_name = ''; + // Remove attribute_ prefix from names. + $variation_attributes = array(); + if ( is_array( $variation ) ) { + foreach ( $variation as $key => $value ) { + $variation_attributes[ str_replace( 'attribute_', '', $key ) ] = $value; + } + } + } + + $list_type = $include_names ? 'dl' : 'ul'; + + if ( is_array( $variation_attributes ) ) { + + if ( ! $flat ) { + $return = '<' . $list_type . ' class="variation">'; + } + + $variation_list = array(); + + foreach ( $variation_attributes as $name => $value ) { + // If this is a term slug, get the term's nice name. + if ( taxonomy_exists( $name ) ) { + $term = get_term_by( 'slug', $value, $name ); + if ( ! is_wp_error( $term ) && ! empty( $term->name ) ) { + $value = $term->name; + } + } + + // Do not list attributes already part of the variation name. + if ( '' === $value || ( $skip_attributes_in_name && wc_is_attribute_in_product_name( $value, $variation_name ) ) ) { + continue; + } + + if ( $include_names ) { + if ( $flat ) { + $variation_list[] = wc_attribute_label( $name, $product ) . ': ' . rawurldecode( $value ); + } else { + $variation_list[] = '
    ' . wc_attribute_label( $name, $product ) . ':
    ' . rawurldecode( $value ) . '
    '; + } + } else { + if ( $flat ) { + $variation_list[] = rawurldecode( $value ); + } else { + $variation_list[] = '
  • ' . rawurldecode( $value ) . '
  • '; + } + } + } + + if ( $flat ) { + $return .= implode( ', ', $variation_list ); + } else { + $return .= implode( '', $variation_list ); + } + + if ( ! $flat ) { + $return .= ''; + } + } + return $return; +} + +/** + * Function which handles the start and end of scheduled sales via cron. + */ +function wc_scheduled_sales() { + $data_store = WC_Data_Store::load( 'product' ); + + // Sales which are due to start. + $product_ids = $data_store->get_starting_sales(); + if ( $product_ids ) { + do_action( 'wc_before_products_starting_sales', $product_ids ); + foreach ( $product_ids as $product_id ) { + $product = wc_get_product( $product_id ); + + if ( $product ) { + $sale_price = $product->get_sale_price(); + + if ( $sale_price ) { + $product->set_price( $sale_price ); + $product->set_date_on_sale_from( '' ); + } else { + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + } + + $product->save(); + } + } + do_action( 'wc_after_products_starting_sales', $product_ids ); + + WC_Cache_Helper::get_transient_version( 'product', true ); + delete_transient( 'wc_products_onsale' ); + } + + // Sales which are due to end. + $product_ids = $data_store->get_ending_sales(); + if ( $product_ids ) { + do_action( 'wc_before_products_ending_sales', $product_ids ); + foreach ( $product_ids as $product_id ) { + $product = wc_get_product( $product_id ); + + if ( $product ) { + $regular_price = $product->get_regular_price(); + $product->set_price( $regular_price ); + $product->set_sale_price( '' ); + $product->set_date_on_sale_to( '' ); + $product->set_date_on_sale_from( '' ); + $product->save(); + } + } + do_action( 'wc_after_products_ending_sales', $product_ids ); + + WC_Cache_Helper::get_transient_version( 'product', true ); + delete_transient( 'wc_products_onsale' ); + } +} +add_action( 'woocommerce_scheduled_sales', 'wc_scheduled_sales' ); + +/** + * Get attachment image attributes. + * + * @param array $attr Image attributes. + * @return array + */ +function wc_get_attachment_image_attributes( $attr ) { + if ( isset( $attr['src'] ) && strstr( $attr['src'], 'woocommerce_uploads/' ) ) { + $attr['src'] = wc_placeholder_img_src(); + + if ( isset( $attr['srcset'] ) ) { + $attr['srcset'] = ''; + } + } + return $attr; +} +add_filter( 'wp_get_attachment_image_attributes', 'wc_get_attachment_image_attributes' ); + + +/** + * Prepare attachment for JavaScript. + * + * @param array $response JS version of a attachment post object. + * @return array + */ +function wc_prepare_attachment_for_js( $response ) { + + if ( isset( $response['url'] ) && strstr( $response['url'], 'woocommerce_uploads/' ) ) { + $response['full']['url'] = wc_placeholder_img_src(); + if ( isset( $response['sizes'] ) ) { + foreach ( $response['sizes'] as $size => $value ) { + $response['sizes'][ $size ]['url'] = wc_placeholder_img_src(); + } + } + } + + return $response; +} +add_filter( 'wp_prepare_attachment_for_js', 'wc_prepare_attachment_for_js' ); + +/** + * Track product views. + */ +function wc_track_product_view() { + if ( ! is_singular( 'product' ) || ! is_active_widget( false, false, 'woocommerce_recently_viewed_products', true ) ) { + return; + } + + global $post; + + if ( empty( $_COOKIE['woocommerce_recently_viewed'] ) ) { // @codingStandardsIgnoreLine. + $viewed_products = array(); + } else { + $viewed_products = wp_parse_id_list( (array) explode( '|', wp_unslash( $_COOKIE['woocommerce_recently_viewed'] ) ) ); // @codingStandardsIgnoreLine. + } + + // Unset if already in viewed products list. + $keys = array_flip( $viewed_products ); + + if ( isset( $keys[ $post->ID ] ) ) { + unset( $viewed_products[ $keys[ $post->ID ] ] ); + } + + $viewed_products[] = $post->ID; + + if ( count( $viewed_products ) > 15 ) { + array_shift( $viewed_products ); + } + + // Store for session only. + wc_setcookie( 'woocommerce_recently_viewed', implode( '|', $viewed_products ) ); +} + +add_action( 'template_redirect', 'wc_track_product_view', 20 ); + +/** + * Get product types. + * + * @since 2.2 + * @return array + */ +function wc_get_product_types() { + return (array) apply_filters( + 'product_type_selector', + array( + 'simple' => __( 'Simple product', 'woocommerce' ), + 'grouped' => __( 'Grouped product', 'woocommerce' ), + 'external' => __( 'External/Affiliate product', 'woocommerce' ), + 'variable' => __( 'Variable product', 'woocommerce' ), + ) + ); +} + +/** + * Check if product sku is unique. + * + * @since 2.2 + * @param int $product_id Product ID. + * @param string $sku Product SKU. + * @return bool + */ +function wc_product_has_unique_sku( $product_id, $sku ) { + $data_store = WC_Data_Store::load( 'product' ); + $sku_found = $data_store->is_existing_sku( $product_id, $sku ); + + if ( apply_filters( 'wc_product_has_unique_sku', $sku_found, $product_id, $sku ) ) { + return false; + } + + return true; +} + +/** + * Force a unique SKU. + * + * @since 3.0.0 + * @param integer $product_id Product ID. + */ +function wc_product_force_unique_sku( $product_id ) { + $product = wc_get_product( $product_id ); + $current_sku = $product ? $product->get_sku( 'edit' ) : ''; + + if ( $current_sku ) { + try { + $new_sku = wc_product_generate_unique_sku( $product_id, $current_sku ); + + if ( $current_sku !== $new_sku ) { + $product->set_sku( $new_sku ); + $product->save(); + } + } catch ( Exception $e ) {} // @codingStandardsIgnoreLine. + } +} + +/** + * Recursively appends a suffix until a unique SKU is found. + * + * @since 3.0.0 + * @param integer $product_id Product ID. + * @param string $sku Product SKU. + * @param integer $index An optional index that can be added to the product SKU. + * @return string + */ +function wc_product_generate_unique_sku( $product_id, $sku, $index = 0 ) { + $generated_sku = 0 < $index ? $sku . '-' . $index : $sku; + + if ( ! wc_product_has_unique_sku( $product_id, $generated_sku ) ) { + $generated_sku = wc_product_generate_unique_sku( $product_id, $sku, ( $index + 1 ) ); + } + + return $generated_sku; +} + +/** + * Get product ID by SKU. + * + * @since 2.3.0 + * @param string $sku Product SKU. + * @return int + */ +function wc_get_product_id_by_sku( $sku ) { + $data_store = WC_Data_Store::load( 'product' ); + return $data_store->get_product_id_by_sku( $sku ); +} + +/** + * Get attibutes/data for an individual variation from the database and maintain it's integrity. + * + * @since 2.4.0 + * @param int $variation_id Variation ID. + * @return array + */ +function wc_get_product_variation_attributes( $variation_id ) { + // Build variation data from meta. + $all_meta = get_post_meta( $variation_id ); + $parent_id = wp_get_post_parent_id( $variation_id ); + $parent_attributes = array_filter( (array) get_post_meta( $parent_id, '_product_attributes', true ) ); + $found_parent_attributes = array(); + $variation_attributes = array(); + + // Compare to parent variable product attributes and ensure they match. + foreach ( $parent_attributes as $attribute_name => $options ) { + if ( ! empty( $options['is_variation'] ) ) { + $attribute = 'attribute_' . sanitize_title( $attribute_name ); + $found_parent_attributes[] = $attribute; + if ( ! array_key_exists( $attribute, $variation_attributes ) ) { + $variation_attributes[ $attribute ] = ''; // Add it - 'any' will be asumed. + } + } + } + + // Get the variation attributes from meta. + foreach ( $all_meta as $name => $value ) { + // Only look at valid attribute meta, and also compare variation level attributes and remove any which do not exist at parent level. + if ( 0 !== strpos( $name, 'attribute_' ) || ! in_array( $name, $found_parent_attributes, true ) ) { + unset( $variation_attributes[ $name ] ); + continue; + } + /** + * Pre 2.4 handling where 'slugs' were saved instead of the full text attribute. + * Attempt to get full version of the text attribute from the parent. + */ + if ( sanitize_title( $value[0] ) === $value[0] && version_compare( get_post_meta( $parent_id, '_product_version', true ), '2.4.0', '<' ) ) { + foreach ( $parent_attributes as $attribute ) { + if ( 'attribute_' . sanitize_title( $attribute['name'] ) !== $name ) { + continue; + } + $text_attributes = wc_get_text_attributes( $attribute['value'] ); + + foreach ( $text_attributes as $text_attribute ) { + if ( sanitize_title( $text_attribute ) === $value[0] ) { + $value[0] = $text_attribute; + break; + } + } + } + } + + $variation_attributes[ $name ] = $value[0]; + } + + return $variation_attributes; +} + +/** + * Get all product cats for a product by ID, including hierarchy + * + * @since 2.5.0 + * @param int $product_id Product ID. + * @return array + */ +function wc_get_product_cat_ids( $product_id ) { + $product_cats = wc_get_product_term_ids( $product_id, 'product_cat' ); + + foreach ( $product_cats as $product_cat ) { + $product_cats = array_merge( $product_cats, get_ancestors( $product_cat, 'product_cat' ) ); + } + + return $product_cats; +} + +/** + * Gets data about an attachment, such as alt text and captions. + * + * @since 2.6.0 + * + * @param int|null $attachment_id Attachment ID. + * @param WC_Product|bool $product WC_Product object. + * + * @return array + */ +function wc_get_product_attachment_props( $attachment_id = null, $product = false ) { + $props = array( + 'title' => '', + 'caption' => '', + 'url' => '', + 'alt' => '', + 'src' => '', + 'srcset' => false, + 'sizes' => false, + ); + $attachment = get_post( $attachment_id ); + + if ( $attachment && 'attachment' === $attachment->post_type ) { + $props['title'] = wp_strip_all_tags( $attachment->post_title ); + $props['caption'] = wp_strip_all_tags( $attachment->post_excerpt ); + $props['url'] = wp_get_attachment_url( $attachment_id ); + + // Alt text. + $alt_text = array( wp_strip_all_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ), $props['caption'], wp_strip_all_tags( $attachment->post_title ) ); + + if ( $product && $product instanceof WC_Product ) { + $alt_text[] = wp_strip_all_tags( get_the_title( $product->get_id() ) ); + } + + $alt_text = array_filter( $alt_text ); + $props['alt'] = isset( $alt_text[0] ) ? $alt_text[0] : ''; + + // Large version. + $full_size = apply_filters( 'woocommerce_gallery_full_size', apply_filters( 'woocommerce_product_thumbnails_large_size', 'full' ) ); + $src = wp_get_attachment_image_src( $attachment_id, $full_size ); + $props['full_src'] = $src[0]; + $props['full_src_w'] = $src[1]; + $props['full_src_h'] = $src[2]; + + // Gallery thumbnail. + $gallery_thumbnail = wc_get_image_size( 'gallery_thumbnail' ); + $gallery_thumbnail_size = apply_filters( 'woocommerce_gallery_thumbnail_size', array( $gallery_thumbnail['width'], $gallery_thumbnail['height'] ) ); + $src = wp_get_attachment_image_src( $attachment_id, $gallery_thumbnail_size ); + $props['gallery_thumbnail_src'] = $src[0]; + $props['gallery_thumbnail_src_w'] = $src[1]; + $props['gallery_thumbnail_src_h'] = $src[2]; + + // Thumbnail version. + $thumbnail_size = apply_filters( 'woocommerce_thumbnail_size', 'woocommerce_thumbnail' ); + $src = wp_get_attachment_image_src( $attachment_id, $thumbnail_size ); + $props['thumb_src'] = $src[0]; + $props['thumb_src_w'] = $src[1]; + $props['thumb_src_h'] = $src[2]; + + // Image source. + $image_size = apply_filters( 'woocommerce_gallery_image_size', 'woocommerce_single' ); + $src = wp_get_attachment_image_src( $attachment_id, $image_size ); + $props['src'] = $src[0]; + $props['src_w'] = $src[1]; + $props['src_h'] = $src[2]; + $props['srcset'] = function_exists( 'wp_get_attachment_image_srcset' ) ? wp_get_attachment_image_srcset( $attachment_id, $image_size ) : false; + $props['sizes'] = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $attachment_id, $image_size ) : false; + } + return $props; +} + +/** + * Get product visibility options. + * + * @since 3.0.0 + * @return array + */ +function wc_get_product_visibility_options() { + return apply_filters( + 'woocommerce_product_visibility_options', + array( + 'visible' => __( 'Shop and search results', 'woocommerce' ), + 'catalog' => __( 'Shop only', 'woocommerce' ), + 'search' => __( 'Search results only', 'woocommerce' ), + 'hidden' => __( 'Hidden', 'woocommerce' ), + ) + ); +} + +/** + * Get product tax class options. + * + * @since 3.0.0 + * @return array + */ +function wc_get_product_tax_class_options() { + $tax_classes = WC_Tax::get_tax_classes(); + $tax_class_options = array(); + $tax_class_options[''] = __( 'Standard', 'woocommerce' ); + + if ( ! empty( $tax_classes ) ) { + foreach ( $tax_classes as $class ) { + $tax_class_options[ sanitize_title( $class ) ] = $class; + } + } + return $tax_class_options; +} + +/** + * Get stock status options. + * + * @since 3.0.0 + * @return array + */ +function wc_get_product_stock_status_options() { + return apply_filters( + 'woocommerce_product_stock_status_options', + array( + 'instock' => __( 'In stock', 'woocommerce' ), + 'outofstock' => __( 'Out of stock', 'woocommerce' ), + 'onbackorder' => __( 'On backorder', 'woocommerce' ), + ) + ); +} + +/** + * Get backorder options. + * + * @since 3.0.0 + * @return array + */ +function wc_get_product_backorder_options() { + return array( + 'no' => __( 'Do not allow', 'woocommerce' ), + 'notify' => __( 'Allow, but notify customer', 'woocommerce' ), + 'yes' => __( 'Allow', 'woocommerce' ), + ); +} + +/** + * Get related products based on product category and tags. + * + * @since 3.0.0 + * @param int $product_id Product ID. + * @param int $limit Limit of results. + * @param array $exclude_ids Exclude IDs from the results. + * @return array + */ +function wc_get_related_products( $product_id, $limit = 5, $exclude_ids = array() ) { + + $product_id = absint( $product_id ); + $limit = $limit >= -1 ? $limit : 5; + $exclude_ids = array_merge( array( 0, $product_id ), $exclude_ids ); + $transient_name = 'wc_related_' . $product_id; + $query_args = http_build_query( + array( + 'limit' => $limit, + 'exclude_ids' => $exclude_ids, + ) + ); + + $transient = get_transient( $transient_name ); + $related_posts = $transient && isset( $transient[ $query_args ] ) ? $transient[ $query_args ] : false; + + // We want to query related posts if they are not cached, or we don't have enough. + if ( false === $related_posts || count( $related_posts ) < $limit ) { + + $cats_array = apply_filters( 'woocommerce_product_related_posts_relate_by_category', true, $product_id ) ? apply_filters( 'woocommerce_get_related_product_cat_terms', wc_get_product_term_ids( $product_id, 'product_cat' ), $product_id ) : array(); + $tags_array = apply_filters( 'woocommerce_product_related_posts_relate_by_tag', true, $product_id ) ? apply_filters( 'woocommerce_get_related_product_tag_terms', wc_get_product_term_ids( $product_id, 'product_tag' ), $product_id ) : array(); + + // Don't bother if none are set, unless woocommerce_product_related_posts_force_display is set to true in which case all products are related. + if ( empty( $cats_array ) && empty( $tags_array ) && ! apply_filters( 'woocommerce_product_related_posts_force_display', false, $product_id ) ) { + $related_posts = array(); + } else { + $data_store = WC_Data_Store::load( 'product' ); + $related_posts = $data_store->get_related_products( $cats_array, $tags_array, $exclude_ids, $limit + 10, $product_id ); + } + + if ( $transient ) { + $transient[ $query_args ] = $related_posts; + } else { + $transient = array( $query_args => $related_posts ); + } + + set_transient( $transient_name, $transient, DAY_IN_SECONDS ); + } + + $related_posts = apply_filters( + 'woocommerce_related_products', + $related_posts, + $product_id, + array( + 'limit' => $limit, + 'excluded_ids' => $exclude_ids, + ) + ); + + if ( apply_filters( 'woocommerce_product_related_posts_shuffle', true ) ) { + shuffle( $related_posts ); + } + + return array_slice( $related_posts, 0, $limit ); +} + +/** + * Retrieves product term ids for a taxonomy. + * + * @since 3.0.0 + * @param int $product_id Product ID. + * @param string $taxonomy Taxonomy slug. + * @return array + */ +function wc_get_product_term_ids( $product_id, $taxonomy ) { + $terms = get_the_terms( $product_id, $taxonomy ); + return ( empty( $terms ) || is_wp_error( $terms ) ) ? array() : wp_list_pluck( $terms, 'term_id' ); +} + +/** + * For a given product, and optionally price/qty, work out the price with tax included, based on store settings. + * + * @since 3.0.0 + * @param WC_Product $product WC_Product object. + * @param array $args Optional arguments to pass product quantity and price. + * @return float + */ +function wc_get_price_including_tax( $product, $args = array() ) { + $args = wp_parse_args( + $args, + array( + 'qty' => '', + 'price' => '', + ) + ); + + $price = '' !== $args['price'] ? max( 0.0, (float) $args['price'] ) : $product->get_price(); + $qty = '' !== $args['qty'] ? max( 0.0, (float) $args['qty'] ) : 1; + + if ( '' === $price ) { + return ''; + } elseif ( empty( $qty ) ) { + return 0.0; + } + + $line_price = $price * $qty; + $return_price = $line_price; + + if ( $product->is_taxable() ) { + if ( ! wc_prices_include_tax() ) { + $tax_rates = WC_Tax::get_rates( $product->get_tax_class() ); + $taxes = WC_Tax::calc_tax( $line_price, $tax_rates, false ); + + if ( 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' ) ) { + $taxes_total = array_sum( $taxes ); + } else { + $taxes_total = array_sum( array_map( 'wc_round_tax_total', $taxes ) ); + } + + $return_price = NumberUtil::round( $line_price + $taxes_total, wc_get_price_decimals() ); + } else { + $tax_rates = WC_Tax::get_rates( $product->get_tax_class() ); + $base_tax_rates = WC_Tax::get_base_tax_rates( $product->get_tax_class( 'unfiltered' ) ); + + /** + * If the customer is excempt from VAT, remove the taxes here. + * Either remove the base or the user taxes depending on woocommerce_adjust_non_base_location_prices setting. + */ + if ( ! empty( WC()->customer ) && WC()->customer->get_is_vat_exempt() ) { // @codingStandardsIgnoreLine. + $remove_taxes = apply_filters( 'woocommerce_adjust_non_base_location_prices', true ) ? WC_Tax::calc_tax( $line_price, $base_tax_rates, true ) : WC_Tax::calc_tax( $line_price, $tax_rates, true ); + + if ( 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' ) ) { + $remove_taxes_total = array_sum( $remove_taxes ); + } else { + $remove_taxes_total = array_sum( array_map( 'wc_round_tax_total', $remove_taxes ) ); + } + + $return_price = NumberUtil::round( $line_price - $remove_taxes_total, wc_get_price_decimals() ); + + /** + * The woocommerce_adjust_non_base_location_prices filter can stop base taxes being taken off when dealing with out of base locations. + * e.g. If a product costs 10 including tax, all users will pay 10 regardless of location and taxes. + * This feature is experimental @since 2.4.7 and may change in the future. Use at your risk. + */ + } elseif ( $tax_rates !== $base_tax_rates && apply_filters( 'woocommerce_adjust_non_base_location_prices', true ) ) { + $base_taxes = WC_Tax::calc_tax( $line_price, $base_tax_rates, true ); + $modded_taxes = WC_Tax::calc_tax( $line_price - array_sum( $base_taxes ), $tax_rates, false ); + + if ( 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' ) ) { + $base_taxes_total = array_sum( $base_taxes ); + $modded_taxes_total = array_sum( $modded_taxes ); + } else { + $base_taxes_total = array_sum( array_map( 'wc_round_tax_total', $base_taxes ) ); + $modded_taxes_total = array_sum( array_map( 'wc_round_tax_total', $modded_taxes ) ); + } + + $return_price = NumberUtil::round( $line_price - $base_taxes_total + $modded_taxes_total, wc_get_price_decimals() ); + } + } + } + return apply_filters( 'woocommerce_get_price_including_tax', $return_price, $qty, $product ); +} + +/** + * For a given product, and optionally price/qty, work out the price with tax excluded, based on store settings. + * + * @since 3.0.0 + * @param WC_Product $product WC_Product object. + * @param array $args Optional arguments to pass product quantity and price. + * @return float + */ +function wc_get_price_excluding_tax( $product, $args = array() ) { + $args = wp_parse_args( + $args, + array( + 'qty' => '', + 'price' => '', + ) + ); + + $price = '' !== $args['price'] ? max( 0.0, (float) $args['price'] ) : $product->get_price(); + $qty = '' !== $args['qty'] ? max( 0.0, (float) $args['qty'] ) : 1; + + if ( '' === $price ) { + return ''; + } elseif ( empty( $qty ) ) { + return 0.0; + } + + $line_price = $price * $qty; + + if ( $product->is_taxable() && wc_prices_include_tax() ) { + $tax_rates = WC_Tax::get_rates( $product->get_tax_class() ); + $base_tax_rates = WC_Tax::get_base_tax_rates( $product->get_tax_class( 'unfiltered' ) ); + $remove_taxes = apply_filters( 'woocommerce_adjust_non_base_location_prices', true ) ? WC_Tax::calc_tax( $line_price, $base_tax_rates, true ) : WC_Tax::calc_tax( $line_price, $tax_rates, true ); + $return_price = $line_price - array_sum( $remove_taxes ); // Unrounded since we're dealing with tax inclusive prices. Matches logic in cart-totals class. @see adjust_non_base_location_price. + } else { + $return_price = $line_price; + } + + return apply_filters( 'woocommerce_get_price_excluding_tax', $return_price, $qty, $product ); +} + +/** + * Returns the price including or excluding tax, based on the 'woocommerce_tax_display_shop' setting. + * + * @since 3.0.0 + * @param WC_Product $product WC_Product object. + * @param array $args Optional arguments to pass product quantity and price. + * @return float + */ +function wc_get_price_to_display( $product, $args = array() ) { + $args = wp_parse_args( + $args, + array( + 'qty' => 1, + 'price' => $product->get_price(), + ) + ); + + $price = $args['price']; + $qty = $args['qty']; + + return 'incl' === get_option( 'woocommerce_tax_display_shop' ) ? + wc_get_price_including_tax( + $product, + array( + 'qty' => $qty, + 'price' => $price, + ) + ) : + wc_get_price_excluding_tax( + $product, + array( + 'qty' => $qty, + 'price' => $price, + ) + ); +} + +/** + * Returns the product categories in a list. + * + * @param int $product_id Product ID. + * @param string $sep (default: ', '). + * @param string $before (default: ''). + * @param string $after (default: ''). + * @return string + */ +function wc_get_product_category_list( $product_id, $sep = ', ', $before = '', $after = '' ) { + return get_the_term_list( $product_id, 'product_cat', $before, $sep, $after ); +} + +/** + * Returns the product tags in a list. + * + * @param int $product_id Product ID. + * @param string $sep (default: ', '). + * @param string $before (default: ''). + * @param string $after (default: ''). + * @return string + */ +function wc_get_product_tag_list( $product_id, $sep = ', ', $before = '', $after = '' ) { + return get_the_term_list( $product_id, 'product_tag', $before, $sep, $after ); +} + +/** + * Callback for array filter to get visible only. + * + * @since 3.0.0 + * @param WC_Product $product WC_Product object. + * @return bool + */ +function wc_products_array_filter_visible( $product ) { + return $product && is_a( $product, 'WC_Product' ) && $product->is_visible(); +} + +/** + * Callback for array filter to get visible grouped products only. + * + * @since 3.1.0 + * @param WC_Product $product WC_Product object. + * @return bool + */ +function wc_products_array_filter_visible_grouped( $product ) { + return $product && is_a( $product, 'WC_Product' ) && ( 'publish' === $product->get_status() || current_user_can( 'edit_product', $product->get_id() ) ); +} + +/** + * Callback for array filter to get products the user can edit only. + * + * @since 3.0.0 + * @param WC_Product $product WC_Product object. + * @return bool + */ +function wc_products_array_filter_editable( $product ) { + return $product && is_a( $product, 'WC_Product' ) && current_user_can( 'edit_product', $product->get_id() ); +} + +/** + * Callback for array filter to get products the user can view only. + * + * @since 3.4.0 + * @param WC_Product $product WC_Product object. + * @return bool + */ +function wc_products_array_filter_readable( $product ) { + return $product && is_a( $product, 'WC_Product' ) && current_user_can( 'read_product', $product->get_id() ); +} + +/** + * Sort an array of products by a value. + * + * @since 3.0.0 + * + * @param array $products List of products to be ordered. + * @param string $orderby Optional order criteria. + * @param string $order Ascending or descending order. + * + * @return array + */ +function wc_products_array_orderby( $products, $orderby = 'date', $order = 'desc' ) { + $orderby = strtolower( $orderby ); + $order = strtolower( $order ); + switch ( $orderby ) { + case 'title': + case 'id': + case 'date': + case 'modified': + case 'menu_order': + case 'price': + usort( $products, 'wc_products_array_orderby_' . $orderby ); + break; + case 'none': + break; + default: + shuffle( $products ); + break; + } + if ( 'desc' === $order ) { + $products = array_reverse( $products ); + } + return $products; +} + +/** + * Sort by title. + * + * @since 3.0.0 + * @param WC_Product $a First WC_Product object. + * @param WC_Product $b Second WC_Product object. + * @return int + */ +function wc_products_array_orderby_title( $a, $b ) { + return strcasecmp( $a->get_name(), $b->get_name() ); +} + +/** + * Sort by id. + * + * @since 3.0.0 + * @param WC_Product $a First WC_Product object. + * @param WC_Product $b Second WC_Product object. + * @return int + */ +function wc_products_array_orderby_id( $a, $b ) { + if ( $a->get_id() === $b->get_id() ) { + return 0; + } + return ( $a->get_id() < $b->get_id() ) ? -1 : 1; +} + +/** + * Sort by date. + * + * @since 3.0.0 + * @param WC_Product $a First WC_Product object. + * @param WC_Product $b Second WC_Product object. + * @return int + */ +function wc_products_array_orderby_date( $a, $b ) { + if ( $a->get_date_created() === $b->get_date_created() ) { + return 0; + } + return ( $a->get_date_created() < $b->get_date_created() ) ? -1 : 1; +} + +/** + * Sort by modified. + * + * @since 3.0.0 + * @param WC_Product $a First WC_Product object. + * @param WC_Product $b Second WC_Product object. + * @return int + */ +function wc_products_array_orderby_modified( $a, $b ) { + if ( $a->get_date_modified() === $b->get_date_modified() ) { + return 0; + } + return ( $a->get_date_modified() < $b->get_date_modified() ) ? -1 : 1; +} + +/** + * Sort by menu order. + * + * @since 3.0.0 + * @param WC_Product $a First WC_Product object. + * @param WC_Product $b Second WC_Product object. + * @return int + */ +function wc_products_array_orderby_menu_order( $a, $b ) { + if ( $a->get_menu_order() === $b->get_menu_order() ) { + return 0; + } + return ( $a->get_menu_order() < $b->get_menu_order() ) ? -1 : 1; +} + +/** + * Sort by price low to high. + * + * @since 3.0.0 + * @param WC_Product $a First WC_Product object. + * @param WC_Product $b Second WC_Product object. + * @return int + */ +function wc_products_array_orderby_price( $a, $b ) { + if ( $a->get_price() === $b->get_price() ) { + return 0; + } + return ( $a->get_price() < $b->get_price() ) ? -1 : 1; +} + +/** + * Queue a product for syncing at the end of the request. + * + * @param int $product_id Product ID. + */ +function wc_deferred_product_sync( $product_id ) { + global $wc_deferred_product_sync; + + if ( empty( $wc_deferred_product_sync ) ) { + $wc_deferred_product_sync = array(); + } + + $wc_deferred_product_sync[] = $product_id; +} + +/** + * See if the lookup table is being generated already. + * + * @since 3.6.0 + * @return bool + */ +function wc_update_product_lookup_tables_is_running() { + $table_updates_pending = WC()->queue()->search( + array( + 'status' => 'pending', + 'group' => 'wc_update_product_lookup_tables', + 'per_page' => 1, + ) + ); + + return (bool) count( $table_updates_pending ); +} + +/** + * Populate lookup table data for products. + * + * @since 3.6.0 + */ +function wc_update_product_lookup_tables() { + global $wpdb; + + $is_cli = Constants::is_true( 'WP_CLI' ); + + if ( ! $is_cli ) { + WC_Admin_Notices::add_notice( 'regenerating_lookup_table' ); + } + + // Note that the table is not yet generated. + update_option( 'woocommerce_product_lookup_table_is_generating', true ); + + // Make a row per product in lookup table. + $wpdb->query( + " + INSERT IGNORE INTO {$wpdb->wc_product_meta_lookup} (`product_id`) + SELECT + posts.ID + FROM {$wpdb->posts} posts + WHERE + posts.post_type IN ('product', 'product_variation') + " + ); + + // List of column names in the lookup table we need to populate. + $columns = array( + 'min_max_price', + 'stock_quantity', + 'sku', + 'stock_status', + 'average_rating', + 'total_sales', + 'downloadable', + 'virtual', + 'onsale', + 'tax_class', + 'tax_status', // When last column is updated, woocommerce_product_lookup_table_is_generating is updated. + ); + + foreach ( $columns as $index => $column ) { + if ( $is_cli ) { + wc_update_product_lookup_tables_column( $column ); + } else { + WC()->queue()->schedule_single( + time() + $index, + 'wc_update_product_lookup_tables_column', + array( + 'column' => $column, + ), + 'wc_update_product_lookup_tables' + ); + } + } + + // Rating counts are serialised so they have to be unserialised before populating the lookup table. + if ( $is_cli ) { + $rating_count_rows = $wpdb->get_results( + " + SELECT post_id, meta_value FROM {$wpdb->postmeta} + WHERE meta_key = '_wc_rating_count' + AND meta_value != '' + AND meta_value != 'a:0:{}' + ", + ARRAY_A + ); + wc_update_product_lookup_tables_rating_count( $rating_count_rows ); + } else { + WC()->queue()->schedule_single( + time() + 10, + 'wc_update_product_lookup_tables_rating_count_batch', + array( + 'offset' => 0, + 'limit' => 50, + ), + 'wc_update_product_lookup_tables' + ); + } +} + +/** + * Populate lookup table column data. + * + * @since 3.6.0 + * @param string $column Column name to set. + */ +function wc_update_product_lookup_tables_column( $column ) { + if ( empty( $column ) ) { + return; + } + global $wpdb; + switch ( $column ) { + case 'min_max_price': + $wpdb->query( + " + UPDATE + {$wpdb->wc_product_meta_lookup} lookup_table + INNER JOIN ( + SELECT lookup_table.product_id, MIN( meta_value+0 ) as min_price, MAX( meta_value+0 ) as max_price + FROM {$wpdb->wc_product_meta_lookup} lookup_table + LEFT JOIN {$wpdb->postmeta} meta1 ON lookup_table.product_id = meta1.post_id AND meta1.meta_key = '_price' + WHERE + meta1.meta_value <> '' + GROUP BY lookup_table.product_id + ) as source on source.product_id = lookup_table.product_id + SET + lookup_table.min_price = source.min_price, + lookup_table.max_price = source.max_price + " + ); + break; + case 'stock_quantity': + $wpdb->query( + " + UPDATE + {$wpdb->wc_product_meta_lookup} lookup_table + LEFT JOIN {$wpdb->postmeta} meta1 ON lookup_table.product_id = meta1.post_id AND meta1.meta_key = '_manage_stock' + LEFT JOIN {$wpdb->postmeta} meta2 ON lookup_table.product_id = meta2.post_id AND meta2.meta_key = '_stock' + SET + lookup_table.stock_quantity = meta2.meta_value + WHERE + meta1.meta_value = 'yes' + " + ); + break; + case 'sku': + case 'stock_status': + case 'average_rating': + case 'total_sales': + case 'tax_class': + case 'tax_status': + if ( 'total_sales' === $column ) { + $meta_key = 'total_sales'; + } elseif ( 'average_rating' === $column ) { + $meta_key = '_wc_average_rating'; + } else { + $meta_key = '_' . $column; + } + $column = esc_sql( $column ); + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $wpdb->query( + $wpdb->prepare( + " + UPDATE + {$wpdb->wc_product_meta_lookup} lookup_table + LEFT JOIN {$wpdb->postmeta} meta ON lookup_table.product_id = meta.post_id AND meta.meta_key = %s + SET + lookup_table.`{$column}` = meta.meta_value + ", + $meta_key + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + break; + case 'downloadable': + case 'virtual': + $column = esc_sql( $column ); + $meta_key = '_' . $column; + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $wpdb->query( + $wpdb->prepare( + " + UPDATE + {$wpdb->wc_product_meta_lookup} lookup_table + LEFT JOIN {$wpdb->postmeta} meta1 ON lookup_table.product_id = meta1.post_id AND meta1.meta_key = %s + SET + lookup_table.`{$column}` = IF ( meta1.meta_value = 'yes', 1, 0 ) + ", + $meta_key + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + break; + case 'onsale': + $column = esc_sql( $column ); + $decimals = absint( wc_get_price_decimals() ); + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $wpdb->query( + $wpdb->prepare( + " + UPDATE + {$wpdb->wc_product_meta_lookup} lookup_table + LEFT JOIN {$wpdb->postmeta} meta1 ON lookup_table.product_id = meta1.post_id AND meta1.meta_key = '_price' + LEFT JOIN {$wpdb->postmeta} meta2 ON lookup_table.product_id = meta2.post_id AND meta2.meta_key = '_sale_price' + SET + lookup_table.`{$column}` = IF ( + CAST( meta1.meta_value AS DECIMAL ) >= 0 + AND CAST( meta2.meta_value AS CHAR ) != '' + AND CAST( meta1.meta_value AS DECIMAL( 10, %d ) ) = CAST( meta2.meta_value AS DECIMAL( 10, %d ) ) + , 1, 0 ) + ", + $decimals, + $decimals + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + break; + } + + // Final column - mark complete. + if ( 'tax_status' === $column ) { + delete_option( 'woocommerce_product_lookup_table_is_generating' ); + } +} +add_action( 'wc_update_product_lookup_tables_column', 'wc_update_product_lookup_tables_column' ); + +/** + * Populate rating count lookup table data for products. + * + * @since 3.6.0 + * @param array $rows Rows of rating counts to update in lookup table. + */ +function wc_update_product_lookup_tables_rating_count( $rows ) { + if ( ! $rows || ! is_array( $rows ) ) { + return; + } + global $wpdb; + + foreach ( $rows as $row ) { + $count = array_sum( (array) maybe_unserialize( $row['meta_value'] ) ); + $wpdb->update( + $wpdb->wc_product_meta_lookup, + array( + 'rating_count' => absint( $count ), + ), + array( + 'product_id' => absint( $row['post_id'] ), + ) + ); + } +} + +/** + * Populate a batch of rating count lookup table data for products. + * + * @since 3.6.2 + * @param array $offset Offset to query. + * @param array $limit Limit to query. + */ +function wc_update_product_lookup_tables_rating_count_batch( $offset = 0, $limit = 0 ) { + global $wpdb; + + if ( ! $limit ) { + return; + } + + $rating_count_rows = $wpdb->get_results( + $wpdb->prepare( + " + SELECT post_id, meta_value FROM {$wpdb->postmeta} + WHERE meta_key = '_wc_rating_count' + AND meta_value != '' + AND meta_value != 'a:0:{}' + ORDER BY post_id ASC + LIMIT %d, %d + ", + $offset, + $limit + ), + ARRAY_A + ); + + if ( $rating_count_rows ) { + wc_update_product_lookup_tables_rating_count( $rating_count_rows ); + WC()->queue()->schedule_single( + time() + 1, + 'wc_update_product_lookup_tables_rating_count_batch', + array( + 'offset' => $offset + $limit, + 'limit' => $limit, + ), + 'wc_update_product_lookup_tables' + ); + } +} +add_action( 'wc_update_product_lookup_tables_rating_count_batch', 'wc_update_product_lookup_tables_rating_count_batch', 10, 2 ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-rest-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-rest-functions.php new file mode 100644 index 0000000..54029b4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-rest-functions.php @@ -0,0 +1,356 @@ +setTimezone( new DateTimeZone( wc_timezone_string() ) ); + } elseif ( is_string( $date ) ) { + $date = new WC_DateTime( $date, new DateTimeZone( 'UTC' ) ); + $date->setTimezone( new DateTimeZone( wc_timezone_string() ) ); + } + + if ( ! is_a( $date, 'WC_DateTime' ) ) { + return null; + } + + // Get timestamp before changing timezone to UTC. + return gmdate( 'Y-m-d\TH:i:s', $utc ? $date->getTimestamp() : $date->getOffsetTimestamp() ); +} + +/** + * Returns image mime types users are allowed to upload via the API. + * + * @since 2.6.4 + * @return array + */ +function wc_rest_allowed_image_mime_types() { + return apply_filters( + 'woocommerce_rest_allowed_image_mime_types', + array( + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'ico' => 'image/x-icon', + ) + ); +} + +/** + * Upload image from URL. + * + * @since 2.6.0 + * @param string $image_url Image URL. + * @return array|WP_Error Attachment data or error message. + */ +function wc_rest_upload_image_from_url( $image_url ) { + $parsed_url = wp_parse_url( $image_url ); + + // Check parsed URL. + if ( ! $parsed_url || ! is_array( $parsed_url ) ) { + /* translators: %s: image URL */ + return new WP_Error( 'woocommerce_rest_invalid_image_url', sprintf( __( 'Invalid URL %s.', 'woocommerce' ), $image_url ), array( 'status' => 400 ) ); + } + + // Ensure url is valid. + $image_url = esc_url_raw( $image_url ); + + // download_url function is part of wp-admin. + if ( ! function_exists( 'download_url' ) ) { + include_once ABSPATH . 'wp-admin/includes/file.php'; + } + + $file_array = array(); + $file_array['name'] = basename( current( explode( '?', $image_url ) ) ); + + // Download file to temp location. + $file_array['tmp_name'] = download_url( $image_url ); + + // If error storing temporarily, return the error. + if ( is_wp_error( $file_array['tmp_name'] ) ) { + return new WP_Error( + 'woocommerce_rest_invalid_remote_image_url', + /* translators: %s: image URL */ + sprintf( __( 'Error getting remote image %s.', 'woocommerce' ), $image_url ) . ' ' + /* translators: %s: error message */ + . sprintf( __( 'Error: %s', 'woocommerce' ), $file_array['tmp_name']->get_error_message() ), + array( 'status' => 400 ) + ); + } + + // Do the validation and storage stuff. + $file = wp_handle_sideload( + $file_array, + array( + 'test_form' => false, + 'mimes' => wc_rest_allowed_image_mime_types(), + ), + current_time( 'Y/m' ) + ); + + if ( isset( $file['error'] ) ) { + @unlink( $file_array['tmp_name'] ); // @codingStandardsIgnoreLine. + + /* translators: %s: error message */ + return new WP_Error( 'woocommerce_rest_invalid_image', sprintf( __( 'Invalid image: %s', 'woocommerce' ), $file['error'] ), array( 'status' => 400 ) ); + } + + do_action( 'woocommerce_rest_api_uploaded_image_from_url', $file, $image_url ); + + return $file; +} + +/** + * Set uploaded image as attachment. + * + * @since 2.6.0 + * @param array $upload Upload information from wp_upload_bits. + * @param int $id Post ID. Default to 0. + * @return int Attachment ID + */ +function wc_rest_set_uploaded_image_as_attachment( $upload, $id = 0 ) { + $info = wp_check_filetype( $upload['file'] ); + $title = ''; + $content = ''; + + if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) { + include_once ABSPATH . 'wp-admin/includes/image.php'; + } + + $image_meta = wp_read_image_metadata( $upload['file'] ); + if ( $image_meta ) { + if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { + $title = wc_clean( $image_meta['title'] ); + } + if ( trim( $image_meta['caption'] ) ) { + $content = wc_clean( $image_meta['caption'] ); + } + } + + $attachment = array( + 'post_mime_type' => $info['type'], + 'guid' => $upload['url'], + 'post_parent' => $id, + 'post_title' => $title ? $title : basename( $upload['file'] ), + 'post_content' => $content, + ); + + $attachment_id = wp_insert_attachment( $attachment, $upload['file'], $id ); + if ( ! is_wp_error( $attachment_id ) ) { + wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $upload['file'] ) ); + } + + return $attachment_id; +} + +/** + * Validate reports request arguments. + * + * @since 2.6.0 + * @param mixed $value Value to valdate. + * @param WP_REST_Request $request Request instance. + * @param string $param Param to validate. + * @return WP_Error|boolean + */ +function wc_rest_validate_reports_request_arg( $value, $request, $param ) { + + $attributes = $request->get_attributes(); + if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { + return true; + } + $args = $attributes['args'][ $param ]; + + if ( 'string' === $args['type'] && ! is_string( $value ) ) { + /* translators: 1: param 2: type */ + return new WP_Error( 'woocommerce_rest_invalid_param', sprintf( __( '%1$s is not of type %2$s', 'woocommerce' ), $param, 'string' ) ); + } + + if ( 'date' === $args['format'] ) { + $regex = '#^\d{4}-\d{2}-\d{2}$#'; + + if ( ! preg_match( $regex, $value, $matches ) ) { + return new WP_Error( 'woocommerce_rest_invalid_date', __( 'The date you provided is invalid.', 'woocommerce' ) ); + } + } + + return true; +} + +/** + * Encodes a value according to RFC 3986. + * Supports multidimensional arrays. + * + * @since 2.6.0 + * @param string|array $value The value to encode. + * @return string|array Encoded values. + */ +function wc_rest_urlencode_rfc3986( $value ) { + if ( is_array( $value ) ) { + return array_map( 'wc_rest_urlencode_rfc3986', $value ); + } + + return str_replace( array( '+', '%7E' ), array( ' ', '~' ), rawurlencode( $value ) ); +} + +/** + * Check permissions of posts on REST API. + * + * @since 2.6.0 + * @param string $post_type Post type. + * @param string $context Request context. + * @param int $object_id Post ID. + * @return bool + */ +function wc_rest_check_post_permissions( $post_type, $context = 'read', $object_id = 0 ) { + $contexts = array( + 'read' => 'read_private_posts', + 'create' => 'publish_posts', + 'edit' => 'edit_post', + 'delete' => 'delete_post', + 'batch' => 'edit_others_posts', + ); + + if ( 'revision' === $post_type ) { + $permission = false; + } else { + $cap = $contexts[ $context ]; + $post_type_object = get_post_type_object( $post_type ); + $permission = current_user_can( $post_type_object->cap->$cap, $object_id ); + } + + return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, $post_type ); +} + +/** + * Check permissions of users on REST API. + * + * @since 2.6.0 + * @param string $context Request context. + * @param int $object_id Post ID. + * @return bool + */ +function wc_rest_check_user_permissions( $context = 'read', $object_id = 0 ) { + $contexts = array( + 'read' => 'list_users', + 'create' => 'promote_users', // Check if current user can create users, shop managers are not allowed to create users. + 'edit' => 'edit_users', + 'delete' => 'delete_users', + 'batch' => 'promote_users', + ); + + // Check to allow shop_managers to manage only customers. + if ( in_array( $context, array( 'edit', 'delete' ), true ) && wc_current_user_has_role( 'shop_manager' ) ) { + $permission = false; + $user_data = get_userdata( $object_id ); + $shop_manager_editable_roles = apply_filters( 'woocommerce_shop_manager_editable_roles', array( 'customer' ) ); + + if ( isset( $user_data->roles ) ) { + $can_manage_users = array_intersect( $user_data->roles, array_unique( $shop_manager_editable_roles ) ); + + // Check if Shop Manager can edit customer or with the is same shop manager. + if ( 0 < count( $can_manage_users ) || intval( $object_id ) === intval( get_current_user_id() ) ) { + $permission = current_user_can( $contexts[ $context ], $object_id ); + } + } + } else { + $permission = current_user_can( $contexts[ $context ], $object_id ); + } + + return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, 'user' ); +} + +/** + * Check permissions of product terms on REST API. + * + * @since 2.6.0 + * @param string $taxonomy Taxonomy. + * @param string $context Request context. + * @param int $object_id Post ID. + * @return bool + */ +function wc_rest_check_product_term_permissions( $taxonomy, $context = 'read', $object_id = 0 ) { + $contexts = array( + 'read' => 'manage_terms', + 'create' => 'edit_terms', + 'edit' => 'edit_terms', + 'delete' => 'delete_terms', + 'batch' => 'edit_terms', + ); + + $cap = $contexts[ $context ]; + $taxonomy_object = get_taxonomy( $taxonomy ); + $permission = current_user_can( $taxonomy_object->cap->$cap, $object_id ); + + return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, $taxonomy ); +} + +/** + * Check manager permissions on REST API. + * + * @since 2.6.0 + * @param string $object Object. + * @param string $context Request context. + * @return bool + */ +function wc_rest_check_manager_permissions( $object, $context = 'read' ) { + $objects = array( + 'reports' => 'view_woocommerce_reports', + 'settings' => 'manage_woocommerce', + 'system_status' => 'manage_woocommerce', + 'attributes' => 'manage_product_terms', + 'shipping_methods' => 'manage_woocommerce', + 'payment_gateways' => 'manage_woocommerce', + 'webhooks' => 'manage_woocommerce', + ); + + $permission = current_user_can( $objects[ $object ] ); + + return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, 0, $object ); +} + +/** + * Check product reviews permissions on REST API. + * + * @since 3.5.0 + * @param string $context Request context. + * @param string $object_id Object ID. + * @return bool + */ +function wc_rest_check_product_reviews_permissions( $context = 'read', $object_id = 0 ) { + $permission = false; + $contexts = array( + 'read' => 'moderate_comments', + 'create' => 'moderate_comments', + 'edit' => 'moderate_comments', + 'delete' => 'moderate_comments', + 'batch' => 'moderate_comments', + ); + + if ( isset( $contexts[ $context ] ) ) { + $permission = current_user_can( $contexts[ $context ] ); + } + + return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, 'product_review' ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-stock-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-stock-functions.php new file mode 100644 index 0000000..ccac0ea --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-stock-functions.php @@ -0,0 +1,400 @@ +managing_stock() ) { + // Some products (variations) can have their stock managed by their parent. Get the correct object to be updated here. + $product_id_with_stock = $product->get_stock_managed_by_id(); + $product_with_stock = $product_id_with_stock !== $product->get_id() ? wc_get_product( $product_id_with_stock ) : $product; + $data_store = WC_Data_Store::load( 'product' ); + + // Update the database. + $new_stock = $data_store->update_product_stock( $product_id_with_stock, $stock_quantity, $operation ); + + // Update the product object. + $data_store->read_stock_quantity( $product_with_stock, $new_stock ); + + // If this is not being called during an update routine, save the product so stock status etc is in sync, and caches are cleared. + if ( ! $updating ) { + $product_with_stock->save(); + } + + // Fire actions to let 3rd parties know the stock changed. + if ( $product_with_stock->is_type( 'variation' ) ) { + do_action( 'woocommerce_variation_set_stock', $product_with_stock ); + } else { + do_action( 'woocommerce_product_set_stock', $product_with_stock ); + } + + return $product_with_stock->get_stock_quantity(); + } + return $product->get_stock_quantity(); +} + +/** + * Update a product's stock status. + * + * @param int $product_id Product ID. + * @param string $status Status. + */ +function wc_update_product_stock_status( $product_id, $status ) { + $product = wc_get_product( $product_id ); + + if ( $product ) { + $product->set_stock_status( $status ); + $product->save(); + } +} + +/** + * When a payment is complete, we can reduce stock levels for items within an order. + * + * @since 3.0.0 + * @param int $order_id Order ID. + */ +function wc_maybe_reduce_stock_levels( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( ! $order ) { + return; + } + + $stock_reduced = $order->get_data_store()->get_stock_reduced( $order_id ); + $trigger_reduce = apply_filters( 'woocommerce_payment_complete_reduce_order_stock', ! $stock_reduced, $order_id ); + + // Only continue if we're reducing stock. + if ( ! $trigger_reduce ) { + return; + } + + wc_reduce_stock_levels( $order ); + + // Ensure stock is marked as "reduced" in case payment complete or other stock actions are called. + $order->get_data_store()->set_stock_reduced( $order_id, true ); +} +add_action( 'woocommerce_payment_complete', 'wc_maybe_reduce_stock_levels' ); +add_action( 'woocommerce_order_status_completed', 'wc_maybe_reduce_stock_levels' ); +add_action( 'woocommerce_order_status_processing', 'wc_maybe_reduce_stock_levels' ); +add_action( 'woocommerce_order_status_on-hold', 'wc_maybe_reduce_stock_levels' ); + +/** + * When a payment is cancelled, restore stock. + * + * @since 3.0.0 + * @param int $order_id Order ID. + */ +function wc_maybe_increase_stock_levels( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( ! $order ) { + return; + } + + $stock_reduced = $order->get_data_store()->get_stock_reduced( $order_id ); + $trigger_increase = (bool) $stock_reduced; + + // Only continue if we're increasing stock. + if ( ! $trigger_increase ) { + return; + } + + wc_increase_stock_levels( $order ); + + // Ensure stock is not marked as "reduced" anymore. + $order->get_data_store()->set_stock_reduced( $order_id, false ); +} +add_action( 'woocommerce_order_status_cancelled', 'wc_maybe_increase_stock_levels' ); +add_action( 'woocommerce_order_status_pending', 'wc_maybe_increase_stock_levels' ); + +/** + * Reduce stock levels for items within an order, if stock has not already been reduced for the items. + * + * @since 3.0.0 + * @param int|WC_Order $order_id Order ID or order instance. + */ +function wc_reduce_stock_levels( $order_id ) { + if ( is_a( $order_id, 'WC_Order' ) ) { + $order = $order_id; + $order_id = $order->get_id(); + } else { + $order = wc_get_order( $order_id ); + } + // We need an order, and a store with stock management to continue. + if ( ! $order || 'yes' !== get_option( 'woocommerce_manage_stock' ) || ! apply_filters( 'woocommerce_can_reduce_order_stock', true, $order ) ) { + return; + } + + $changes = array(); + + // Loop over all items. + foreach ( $order->get_items() as $item ) { + if ( ! $item->is_type( 'line_item' ) ) { + continue; + } + + // Only reduce stock once for each item. + $product = $item->get_product(); + $item_stock_reduced = $item->get_meta( '_reduced_stock', true ); + + if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) { + continue; + } + + /** + * Filter order item quantity. + * + * @param int|float $quantity Quantity. + * @param WC_Order $order Order data. + * @param WC_Order_Item_Product $item Order item data. + */ + $qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item ); + $item_name = $product->get_formatted_name(); + $new_stock = wc_update_product_stock( $product, $qty, 'decrease' ); + + if ( is_wp_error( $new_stock ) ) { + /* translators: %s item name. */ + $order->add_order_note( sprintf( __( 'Unable to reduce stock for item %s.', 'woocommerce' ), $item_name ) ); + continue; + } + + $item->add_meta_data( '_reduced_stock', $qty, true ); + $item->save(); + + $changes[] = array( + 'product' => $product, + 'from' => $new_stock + $qty, + 'to' => $new_stock, + ); + } + + wc_trigger_stock_change_notifications( $order, $changes ); + + do_action( 'woocommerce_reduce_order_stock', $order ); +} + +/** + * After stock change events, triggers emails and adds order notes. + * + * @since 3.5.0 + * @param WC_Order $order order object. + * @param array $changes Array of changes. + */ +function wc_trigger_stock_change_notifications( $order, $changes ) { + if ( empty( $changes ) ) { + return; + } + + $order_notes = array(); + $no_stock_amount = absint( get_option( 'woocommerce_notify_no_stock_amount', 0 ) ); + + foreach ( $changes as $change ) { + $order_notes[] = $change['product']->get_formatted_name() . ' ' . $change['from'] . '→' . $change['to']; + $low_stock_amount = absint( wc_get_low_stock_amount( wc_get_product( $change['product']->get_id() ) ) ); + if ( $change['to'] <= $no_stock_amount ) { + do_action( 'woocommerce_no_stock', wc_get_product( $change['product']->get_id() ) ); + } elseif ( $change['to'] <= $low_stock_amount ) { + do_action( 'woocommerce_low_stock', wc_get_product( $change['product']->get_id() ) ); + } + + if ( $change['to'] < 0 ) { + do_action( + 'woocommerce_product_on_backorder', + array( + 'product' => wc_get_product( $change['product']->get_id() ), + 'order_id' => $order->get_id(), + 'quantity' => abs( $change['from'] - $change['to'] ), + ) + ); + } + } + + $order->add_order_note( __( 'Stock levels reduced:', 'woocommerce' ) . ' ' . implode( ', ', $order_notes ) ); +} + +/** + * Increase stock levels for items within an order. + * + * @since 3.0.0 + * @param int|WC_Order $order_id Order ID or order instance. + */ +function wc_increase_stock_levels( $order_id ) { + if ( is_a( $order_id, 'WC_Order' ) ) { + $order = $order_id; + $order_id = $order->get_id(); + } else { + $order = wc_get_order( $order_id ); + } + + // We need an order, and a store with stock management to continue. + if ( ! $order || 'yes' !== get_option( 'woocommerce_manage_stock' ) || ! apply_filters( 'woocommerce_can_restore_order_stock', true, $order ) ) { + return; + } + + $changes = array(); + + // Loop over all items. + foreach ( $order->get_items() as $item ) { + if ( ! $item->is_type( 'line_item' ) ) { + continue; + } + + // Only increase stock once for each item. + $product = $item->get_product(); + $item_stock_reduced = $item->get_meta( '_reduced_stock', true ); + + if ( ! $item_stock_reduced || ! $product || ! $product->managing_stock() ) { + continue; + } + + $item_name = $product->get_formatted_name(); + $new_stock = wc_update_product_stock( $product, $item_stock_reduced, 'increase' ); + + if ( is_wp_error( $new_stock ) ) { + /* translators: %s item name. */ + $order->add_order_note( sprintf( __( 'Unable to restore stock for item %s.', 'woocommerce' ), $item_name ) ); + continue; + } + + $item->delete_meta_data( '_reduced_stock' ); + $item->save(); + + $changes[] = $item_name . ' ' . ( $new_stock - $item_stock_reduced ) . '→' . $new_stock; + } + + if ( $changes ) { + $order->add_order_note( __( 'Stock levels increased:', 'woocommerce' ) . ' ' . implode( ', ', $changes ) ); + } + + do_action( 'woocommerce_restore_order_stock', $order ); +} + +/** + * See how much stock is being held in pending orders. + * + * @since 3.5.0 + * @param WC_Product $product Product to check. + * @param integer $exclude_order_id Order ID to exclude. + * @return int + */ +function wc_get_held_stock_quantity( WC_Product $product, $exclude_order_id = 0 ) { + /** + * Filter: woocommerce_hold_stock_for_checkout + * Allows enable/disable hold stock functionality on checkout. + * + * @since 4.3.0 + * @param bool $enabled Default to true if managing stock globally. + */ + if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', wc_string_to_bool( get_option( 'woocommerce_manage_stock', 'yes' ) ) ) ) { + return 0; + } + + return ( new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock() )->get_reserved_stock( $product, $exclude_order_id ); +} + +/** + * Hold stock for an order. + * + * @throws ReserveStockException If reserve stock fails. + * + * @since 4.1.0 + * @param \WC_Order|int $order Order ID or instance. + */ +function wc_reserve_stock_for_order( $order ) { + /** + * Filter: woocommerce_hold_stock_for_checkout + * Allows enable/disable hold stock functionality on checkout. + * + * @since @since 4.1.0 + * @param bool $enabled Default to true if managing stock globally. + */ + if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', wc_string_to_bool( get_option( 'woocommerce_manage_stock', 'yes' ) ) ) ) { + return; + } + + $order = $order instanceof WC_Order ? $order : wc_get_order( $order ); + + if ( $order ) { + ( new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock() )->reserve_stock_for_order( $order ); + } +} +add_action( 'woocommerce_checkout_order_created', 'wc_reserve_stock_for_order' ); + +/** + * Release held stock for an order. + * + * @since 4.3.0 + * @param \WC_Order|int $order Order ID or instance. + */ +function wc_release_stock_for_order( $order ) { + /** + * Filter: woocommerce_hold_stock_for_checkout + * Allows enable/disable hold stock functionality on checkout. + * + * @since 4.3.0 + * @param bool $enabled Default to true if managing stock globally. + */ + if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', wc_string_to_bool( get_option( 'woocommerce_manage_stock', 'yes' ) ) ) ) { + return; + } + + $order = $order instanceof WC_Order ? $order : wc_get_order( $order ); + + if ( $order ) { + ( new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock() )->release_stock_for_order( $order ); + } +} +add_action( 'woocommerce_checkout_order_exception', 'wc_release_stock_for_order' ); +add_action( 'woocommerce_payment_complete', 'wc_release_stock_for_order', 11 ); +add_action( 'woocommerce_order_status_cancelled', 'wc_release_stock_for_order', 11 ); +add_action( 'woocommerce_order_status_completed', 'wc_release_stock_for_order', 11 ); +add_action( 'woocommerce_order_status_processing', 'wc_release_stock_for_order', 11 ); +add_action( 'woocommerce_order_status_on-hold', 'wc_release_stock_for_order', 11 ); + +/** + * Return low stock amount to determine if notification needs to be sent + * + * @param WC_Product $product Product to get data from. + * @since 3.5.0 + * @return int + */ +function wc_get_low_stock_amount( WC_Product $product ) { + if ( $product->is_type( 'variation' ) ) { + $product = wc_get_product( $product->get_parent_id() ); + } + $low_stock_amount = $product->get_low_stock_amount(); + if ( '' === $low_stock_amount ) { + $low_stock_amount = get_option( 'woocommerce_notify_low_stock_amount', 2 ); + } + + return $low_stock_amount; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-template-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-template-functions.php new file mode 100644 index 0000000..cca00d0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-template-functions.php @@ -0,0 +1,3758 @@ +cart->is_empty() && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) && ! is_customize_preview() && apply_filters( 'woocommerce_checkout_redirect_empty_cart', true ) ) { + wc_add_notice( __( 'Checkout is not available whilst your cart is empty.', 'woocommerce' ), 'notice' ); + wp_safe_redirect( wc_get_cart_url() ); + exit; + + } + + // Logout. + if ( isset( $wp->query_vars['customer-logout'] ) && ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'customer-logout' ) ) { + wp_safe_redirect( str_replace( '&', '&', wp_logout_url( wc_get_page_permalink( 'myaccount' ) ) ) ); + exit; + } + + // Redirect to the correct logout endpoint. + if ( isset( $wp->query_vars['customer-logout'] ) && 'true' === $wp->query_vars['customer-logout'] ) { + wp_safe_redirect( esc_url_raw( wc_get_account_endpoint_url( 'customer-logout' ) ) ); + exit; + } + + // Trigger 404 if trying to access an endpoint on wrong page. + if ( is_wc_endpoint_url() && ! is_account_page() && ! is_checkout() && apply_filters( 'woocommerce_account_endpoint_page_not_found', true ) ) { + $wp_query->set_404(); + status_header( 404 ); + include get_query_template( '404' ); + exit; + } + + // Redirect to the product page if we have a single product. + if ( is_search() && is_post_type_archive( 'product' ) && apply_filters( 'woocommerce_redirect_single_search_result', true ) && 1 === absint( $wp_query->found_posts ) ) { + $product = wc_get_product( $wp_query->post ); + + if ( $product && $product->is_visible() ) { + wp_safe_redirect( get_permalink( $product->get_id() ), 302 ); + exit; + } + } + + // Ensure gateways and shipping methods are loaded early. + if ( is_add_payment_method_page() || is_checkout() ) { + // Buffer the checkout page. + ob_start(); + + // Ensure gateways and shipping methods are loaded early. + WC()->payment_gateways(); + WC()->shipping(); + } +} +add_action( 'template_redirect', 'wc_template_redirect' ); + +/** + * When loading sensitive checkout or account pages, send a HTTP header to limit rendering of pages to same origin iframes for security reasons. + * + * Can be disabled with: remove_action( 'template_redirect', 'wc_send_frame_options_header' ); + * + * @since 2.3.10 + */ +function wc_send_frame_options_header() { + + if ( ( is_checkout() || is_account_page() ) && ! is_customize_preview() ) { + send_frame_options_header(); + } +} +add_action( 'template_redirect', 'wc_send_frame_options_header' ); + +/** + * No index our endpoints. + * Prevent indexing pages like order-received. + * + * @since 2.5.3 + */ +function wc_prevent_endpoint_indexing() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.PHP.NoSilencedErrors.Discouraged + if ( is_wc_endpoint_url() || isset( $_GET['download_file'] ) ) { + @header( 'X-Robots-Tag: noindex' ); + } + // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.PHP.NoSilencedErrors.Discouraged +} +add_action( 'template_redirect', 'wc_prevent_endpoint_indexing' ); + +/** + * Remove adjacent_posts_rel_link_wp_head - pointless for products. + * + * @since 3.0.0 + */ +function wc_prevent_adjacent_posts_rel_link_wp_head() { + if ( is_singular( 'product' ) ) { + remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 ); + } +} +add_action( 'template_redirect', 'wc_prevent_adjacent_posts_rel_link_wp_head' ); + +/** + * Show the gallery if JS is disabled. + * + * @since 3.0.6 + */ +function wc_gallery_noscript() { + ?> + + post_type ) || ! in_array( $post->post_type, array( 'product', 'product_variation' ), true ) ) { + return; + } + + $GLOBALS['product'] = wc_get_product( $post ); + + return $GLOBALS['product']; +} +add_action( 'the_post', 'wc_setup_product_data' ); + +/** + * Sets up the woocommerce_loop global from the passed args or from the main query. + * + * @since 3.3.0 + * @param array $args Args to pass into the global. + */ +function wc_setup_loop( $args = array() ) { + $default_args = array( + 'loop' => 0, + 'columns' => wc_get_default_products_per_row(), + 'name' => '', + 'is_shortcode' => false, + 'is_paginated' => true, + 'is_search' => false, + 'is_filtered' => false, + 'total' => 0, + 'total_pages' => 0, + 'per_page' => 0, + 'current_page' => 1, + ); + + // If this is a main WC query, use global args as defaults. + if ( $GLOBALS['wp_query']->get( 'wc_query' ) ) { + $default_args = array_merge( + $default_args, + array( + 'is_search' => $GLOBALS['wp_query']->is_search(), + 'is_filtered' => is_filtered(), + 'total' => $GLOBALS['wp_query']->found_posts, + 'total_pages' => $GLOBALS['wp_query']->max_num_pages, + 'per_page' => $GLOBALS['wp_query']->get( 'posts_per_page' ), + 'current_page' => max( 1, $GLOBALS['wp_query']->get( 'paged', 1 ) ), + ) + ); + } + + // Merge any existing values. + if ( isset( $GLOBALS['woocommerce_loop'] ) ) { + $default_args = array_merge( $default_args, $GLOBALS['woocommerce_loop'] ); + } + + $GLOBALS['woocommerce_loop'] = wp_parse_args( $args, $default_args ); +} +add_action( 'woocommerce_before_shop_loop', 'wc_setup_loop' ); + +/** + * Resets the woocommerce_loop global. + * + * @since 3.3.0 + */ +function wc_reset_loop() { + unset( $GLOBALS['woocommerce_loop'] ); +} +add_action( 'woocommerce_after_shop_loop', 'woocommerce_reset_loop', 999 ); + +/** + * Gets a property from the woocommerce_loop global. + * + * @since 3.3.0 + * @param string $prop Prop to get. + * @param string $default Default if the prop does not exist. + * @return mixed + */ +function wc_get_loop_prop( $prop, $default = '' ) { + wc_setup_loop(); // Ensure shop loop is setup. + + return isset( $GLOBALS['woocommerce_loop'], $GLOBALS['woocommerce_loop'][ $prop ] ) ? $GLOBALS['woocommerce_loop'][ $prop ] : $default; +} + +/** + * Sets a property in the woocommerce_loop global. + * + * @since 3.3.0 + * @param string $prop Prop to set. + * @param string $value Value to set. + */ +function wc_set_loop_prop( $prop, $value = '' ) { + if ( ! isset( $GLOBALS['woocommerce_loop'] ) ) { + wc_setup_loop(); + } + $GLOBALS['woocommerce_loop'][ $prop ] = $value; +} + +/** + * Set the current visbility for a product in the woocommerce_loop global. + * + * @since 4.4.0 + * @param int $product_id Product it to cache visbiility for. + * @param bool $value The poduct visibility value to cache. + */ +function wc_set_loop_product_visibility( $product_id, $value ) { + wc_set_loop_prop( "product_visibility_$product_id", $value ); +} + +/** + * Gets the cached current visibility for a product from the woocommerce_loop global. + * + * @since 4.4.0 + * @param int $product_id Product id to get the cached visibility for. + * + * @return bool|null The cached product visibility, or null if on visibility has been cached for that product. + */ +function wc_get_loop_product_visibility( $product_id ) { + return wc_get_loop_prop( "product_visibility_$product_id", null ); +} + +/** + * Should the WooCommerce loop be displayed? + * + * This will return true if we have posts (products) or if we have subcats to display. + * + * @since 3.4.0 + * @return bool + */ +function woocommerce_product_loop() { + return have_posts() || 'products' !== woocommerce_get_loop_display_mode(); +} + +/** + * Output generator tag to aid debugging. + * + * @param string $gen Generator. + * @param string $type Type. + * @return string + */ +function wc_generator_tag( $gen, $type ) { + $version = Constants::get_constant( 'WC_VERSION' ); + + switch ( $type ) { + case 'html': + $gen .= "\n" . ''; + break; + case 'xhtml': + $gen .= "\n" . ''; + break; + } + return $gen; +} + +/** + * Add body classes for WC pages. + * + * @param array $classes Body Classes. + * @return array + */ +function wc_body_class( $classes ) { + $classes = (array) $classes; + + if ( is_woocommerce() ) { + + $classes[] = 'woocommerce'; + $classes[] = 'woocommerce-page'; + + } elseif ( is_checkout() ) { + + $classes[] = 'woocommerce-checkout'; + $classes[] = 'woocommerce-page'; + + } elseif ( is_cart() ) { + + $classes[] = 'woocommerce-cart'; + $classes[] = 'woocommerce-page'; + + } elseif ( is_account_page() ) { + + $classes[] = 'woocommerce-account'; + $classes[] = 'woocommerce-page'; + + } + + if ( is_store_notice_showing() ) { + $classes[] = 'woocommerce-demo-store'; + } + + foreach ( WC()->query->get_query_vars() as $key => $value ) { + if ( is_wc_endpoint_url( $key ) ) { + $classes[] = 'woocommerce-' . sanitize_html_class( $key ); + } + } + + $classes[] = 'woocommerce-no-js'; + + add_action( 'wp_footer', 'wc_no_js' ); + + return array_unique( $classes ); +} + +/** + * NO JS handling. + * + * @since 3.4.0 + */ +function wc_no_js() { + ?> + + $max_columns ) { + $columns = $max_columns; + update_option( 'woocommerce_catalog_columns', $columns ); + } + + if ( has_filter( 'loop_shop_columns' ) ) { // Legacy filter handling. + $columns = apply_filters( 'loop_shop_columns', $columns ); + } + + $columns = absint( $columns ); + + return max( 1, $columns ); +} + +/** + * Get the default rows setting - this is how many product rows will be shown in loops. + * + * @since 3.3.0 + * @return int + */ +function wc_get_default_product_rows_per_page() { + $rows = absint( get_option( 'woocommerce_catalog_rows', 4 ) ); + $product_grid = wc_get_theme_support( 'product_grid' ); + $min_rows = isset( $product_grid['min_rows'] ) ? absint( $product_grid['min_rows'] ) : 0; + $max_rows = isset( $product_grid['max_rows'] ) ? absint( $product_grid['max_rows'] ) : 0; + + if ( $min_rows && $rows < $min_rows ) { + $rows = $min_rows; + update_option( 'woocommerce_catalog_rows', $rows ); + } elseif ( $max_rows && $rows > $max_rows ) { + $rows = $max_rows; + update_option( 'woocommerce_catalog_rows', $rows ); + } + + return $rows; +} + +/** + * Reset the product grid settings when a new theme is activated. + * + * @since 3.3.0 + */ +function wc_reset_product_grid_settings() { + $product_grid = wc_get_theme_support( 'product_grid' ); + + if ( ! empty( $product_grid['default_rows'] ) ) { + update_option( 'woocommerce_catalog_rows', absint( $product_grid['default_rows'] ) ); + } + + if ( ! empty( $product_grid['default_columns'] ) ) { + update_option( 'woocommerce_catalog_columns', absint( $product_grid['default_columns'] ) ); + } + + wp_cache_flush(); // Flush any caches which could impact settings or templates. +} +add_action( 'after_switch_theme', 'wc_reset_product_grid_settings' ); + +/** + * Get classname for woocommerce loops. + * + * @since 2.6.0 + * @return string + */ +function wc_get_loop_class() { + $loop_index = wc_get_loop_prop( 'loop', 0 ); + $columns = absint( max( 1, wc_get_loop_prop( 'columns', wc_get_default_products_per_row() ) ) ); + + $loop_index ++; + wc_set_loop_prop( 'loop', $loop_index ); + + if ( 0 === ( $loop_index - 1 ) % $columns || 1 === $columns ) { + return 'first'; + } + + if ( 0 === $loop_index % $columns ) { + return 'last'; + } + + return ''; +} + + +/** + * Get the classes for the product cat div. + * + * @since 2.4.0 + * + * @param string|array $class One or more classes to add to the class list. + * @param object $category object Optional. + * + * @return array + */ +function wc_get_product_cat_class( $class = '', $category = null ) { + $classes = is_array( $class ) ? $class : array_map( 'trim', explode( ' ', $class ) ); + $classes[] = 'product-category'; + $classes[] = 'product'; + $classes[] = wc_get_loop_class(); + $classes = apply_filters( 'product_cat_class', $classes, $class, $category ); + + return array_unique( array_filter( $classes ) ); +} + +/** + * Adds extra post classes for products via the WordPress post_class hook, if used. + * + * Note: For performance reasons we instead recommend using wc_product_class/wc_get_product_class instead. + * + * @since 2.1.0 + * @param array $classes Current classes. + * @param string|array $class Additional class. + * @param int $post_id Post ID. + * @return array + */ +function wc_product_post_class( $classes, $class = '', $post_id = 0 ) { + if ( ! $post_id || ! in_array( get_post_type( $post_id ), array( 'product', 'product_variation' ), true ) ) { + return $classes; + } + + $product = wc_get_product( $post_id ); + + if ( ! $product ) { + return $classes; + } + + $classes[] = 'product'; + $classes[] = wc_get_loop_class(); + $classes[] = $product->get_stock_status(); + + if ( $product->is_on_sale() ) { + $classes[] = 'sale'; + } + if ( $product->is_featured() ) { + $classes[] = 'featured'; + } + if ( $product->is_downloadable() ) { + $classes[] = 'downloadable'; + } + if ( $product->is_virtual() ) { + $classes[] = 'virtual'; + } + if ( $product->is_sold_individually() ) { + $classes[] = 'sold-individually'; + } + if ( $product->is_taxable() ) { + $classes[] = 'taxable'; + } + if ( $product->is_shipping_taxable() ) { + $classes[] = 'shipping-taxable'; + } + if ( $product->is_purchasable() ) { + $classes[] = 'purchasable'; + } + if ( $product->get_type() ) { + $classes[] = 'product-type-' . $product->get_type(); + } + if ( $product->is_type( 'variable' ) && $product->get_default_attributes() ) { + $classes[] = 'has-default-attributes'; + } + + $key = array_search( 'hentry', $classes, true ); + if ( false !== $key ) { + unset( $classes[ $key ] ); + } + + return $classes; +} + +/** + * Get product taxonomy HTML classes. + * + * @since 3.4.0 + * @param array $term_ids Array of terms IDs or objects. + * @param string $taxonomy Taxonomy. + * @return array + */ +function wc_get_product_taxonomy_class( $term_ids, $taxonomy ) { + $classes = array(); + + foreach ( $term_ids as $term_id ) { + $term = get_term( $term_id, $taxonomy ); + + if ( empty( $term->slug ) ) { + continue; + } + + $term_class = sanitize_html_class( $term->slug, $term->term_id ); + if ( is_numeric( $term_class ) || ! trim( $term_class, '-' ) ) { + $term_class = $term->term_id; + } + + // 'post_tag' uses the 'tag' prefix for backward compatibility. + if ( 'post_tag' === $taxonomy ) { + $classes[] = 'tag-' . $term_class; + } else { + $classes[] = sanitize_html_class( $taxonomy . '-' . $term_class, $taxonomy . '-' . $term->term_id ); + } + } + + return $classes; +} + +/** + * Retrieves the classes for the post div as an array. + * + * This method was modified from WordPress's get_post_class() to allow the removal of taxonomies + * (for performance reasons). Previously wc_product_post_class was hooked into post_class. @since 3.6.0 + * + * @since 3.4.0 + * @param string|array $class One or more classes to add to the class list. + * @param int|WP_Post|WC_Product $product Product ID or product object. + * @return array + */ +function wc_get_product_class( $class = '', $product = null ) { + if ( is_null( $product ) && ! empty( $GLOBALS['product'] ) ) { + // Product was null so pull from global. + $product = $GLOBALS['product']; + } + + if ( $product && ! is_a( $product, 'WC_Product' ) ) { + // Make sure we have a valid product, or set to false. + $product = wc_get_product( $product ); + } + + if ( $class ) { + if ( ! is_array( $class ) ) { + $class = preg_split( '#\s+#', $class ); + } + } else { + $class = array(); + } + + $post_classes = array_map( 'esc_attr', $class ); + + if ( ! $product ) { + return $post_classes; + } + + // Run through the post_class hook so 3rd parties using this previously can still append classes. + // Note, to change classes you will need to use the newer woocommerce_post_class filter. + // @internal This removes the wc_product_post_class filter so classes are not duplicated. + $filtered = has_filter( 'post_class', 'wc_product_post_class' ); + + if ( $filtered ) { + remove_filter( 'post_class', 'wc_product_post_class', 20 ); + } + + $post_classes = apply_filters( 'post_class', $post_classes, $class, $product->get_id() ); + + if ( $filtered ) { + add_filter( 'post_class', 'wc_product_post_class', 20, 3 ); + } + + $classes = array_merge( + $post_classes, + array( + 'product', + 'type-product', + 'post-' . $product->get_id(), + 'status-' . $product->get_status(), + wc_get_loop_class(), + $product->get_stock_status(), + ), + wc_get_product_taxonomy_class( $product->get_category_ids(), 'product_cat' ), + wc_get_product_taxonomy_class( $product->get_tag_ids(), 'product_tag' ) + ); + + if ( $product->get_image_id() ) { + $classes[] = 'has-post-thumbnail'; + } + if ( $product->get_post_password() ) { + $classes[] = post_password_required( $product->get_id() ) ? 'post-password-required' : 'post-password-protected'; + } + if ( $product->is_on_sale() ) { + $classes[] = 'sale'; + } + if ( $product->is_featured() ) { + $classes[] = 'featured'; + } + if ( $product->is_downloadable() ) { + $classes[] = 'downloadable'; + } + if ( $product->is_virtual() ) { + $classes[] = 'virtual'; + } + if ( $product->is_sold_individually() ) { + $classes[] = 'sold-individually'; + } + if ( $product->is_taxable() ) { + $classes[] = 'taxable'; + } + if ( $product->is_shipping_taxable() ) { + $classes[] = 'shipping-taxable'; + } + if ( $product->is_purchasable() ) { + $classes[] = 'purchasable'; + } + if ( $product->get_type() ) { + $classes[] = 'product-type-' . $product->get_type(); + } + if ( $product->is_type( 'variable' ) && $product->get_default_attributes() ) { + $classes[] = 'has-default-attributes'; + } + + // Include attributes and any extra taxonomies only if enabled via the hook - this is a performance issue. + if ( apply_filters( 'woocommerce_get_product_class_include_taxonomies', false ) ) { + $taxonomies = get_taxonomies( array( 'public' => true ) ); + $type = 'variation' === $product->get_type() ? 'product_variation' : 'product'; + foreach ( (array) $taxonomies as $taxonomy ) { + if ( is_object_in_taxonomy( $type, $taxonomy ) && ! in_array( $taxonomy, array( 'product_cat', 'product_tag' ), true ) ) { + $classes = array_merge( $classes, wc_get_product_taxonomy_class( (array) get_the_terms( $product->get_id(), $taxonomy ), $taxonomy ) ); + } + } + } + + /** + * WooCommerce Post Class filter. + * + * @since 3.6.2 + * @param array $classes Array of CSS classes. + * @param WC_Product $product Product object. + */ + $classes = apply_filters( 'woocommerce_post_class', $classes, $product ); + + return array_map( 'esc_attr', array_unique( array_filter( $classes ) ) ); +} + +/** + * Display the classes for the product div. + * + * @since 3.4.0 + * @param string|array $class One or more classes to add to the class list. + * @param int|WP_Post|WC_Product $product_id Product ID or product object. + */ +function wc_product_class( $class = '', $product_id = null ) { + echo 'class="' . esc_attr( implode( ' ', wc_get_product_class( $class, $product_id ) ) ) . '"'; +} + +/** + * Outputs hidden form inputs for each query string variable. + * + * @since 3.0.0 + * @param string|array $values Name value pairs, or a URL to parse. + * @param array $exclude Keys to exclude. + * @param string $current_key Current key we are outputting. + * @param bool $return Whether to return. + * @return string + */ +function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '', $return = false ) { + if ( is_null( $values ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $values = $_GET; + } elseif ( is_string( $values ) ) { + $url_parts = wp_parse_url( $values ); + $values = array(); + + if ( ! empty( $url_parts['query'] ) ) { + // This is to preserve full-stops, pluses and spaces in the query string when ran through parse_str. + $replace_chars = array( + '.' => '{dot}', + '+' => '{plus}', + ); + + $query_string = str_replace( array_keys( $replace_chars ), array_values( $replace_chars ), $url_parts['query'] ); + + // Parse the string. + parse_str( $query_string, $parsed_query_string ); + + // Convert the full-stops, pluses and spaces back and add to values array. + foreach ( $parsed_query_string as $key => $value ) { + $new_key = str_replace( array_values( $replace_chars ), array_keys( $replace_chars ), $key ); + $new_value = str_replace( array_values( $replace_chars ), array_keys( $replace_chars ), $value ); + $values[ $new_key ] = $new_value; + } + } + } + $html = ''; + + foreach ( $values as $key => $value ) { + if ( in_array( $key, $exclude, true ) ) { + continue; + } + if ( $current_key ) { + $key = $current_key . '[' . $key . ']'; + } + if ( is_array( $value ) ) { + $html .= wc_query_string_form_fields( $value, $exclude, $key, true ); + } else { + $html .= ''; + } + } + + if ( $return ) { + return $html; + } + + echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +} + +/** + * Get the terms and conditons page ID. + * + * @since 3.4.0 + * @return int + */ +function wc_terms_and_conditions_page_id() { + $page_id = wc_get_page_id( 'terms' ); + return apply_filters( 'woocommerce_terms_and_conditions_page_id', 0 < $page_id ? absint( $page_id ) : 0 ); +} + +/** + * Get the privacy policy page ID. + * + * @since 3.4.0 + * @return int + */ +function wc_privacy_policy_page_id() { + $page_id = get_option( 'wp_page_for_privacy_policy', 0 ); + return apply_filters( 'woocommerce_privacy_policy_page_id', 0 < $page_id ? absint( $page_id ) : 0 ); +} + +/** + * See if the checkbox is enabled or not based on the existance of the terms page and checkbox text. + * + * @since 3.4.0 + * @return bool + */ +function wc_terms_and_conditions_checkbox_enabled() { + $page_id = wc_terms_and_conditions_page_id(); + $page = $page_id ? get_post( $page_id ) : false; + return $page && wc_get_terms_and_conditions_checkbox_text(); +} + +/** + * Get the terms and conditons checkbox text, if set. + * + * @since 3.4.0 + * @return string + */ +function wc_get_terms_and_conditions_checkbox_text() { + /* translators: %s terms and conditions page name and link */ + return trim( apply_filters( 'woocommerce_get_terms_and_conditions_checkbox_text', get_option( 'woocommerce_checkout_terms_and_conditions_checkbox_text', sprintf( __( 'I have read and agree to the website %s', 'woocommerce' ), '[terms]' ) ) ) ); +} + +/** + * Get the privacy policy text, if set. + * + * @since 3.4.0 + * @param string $type Type of policy to load. Valid values include registration and checkout. + * @return string + */ +function wc_get_privacy_policy_text( $type = '' ) { + $text = ''; + + switch ( $type ) { + case 'checkout': + /* translators: %s privacy policy page name and link */ + $text = get_option( 'woocommerce_checkout_privacy_policy_text', sprintf( __( 'Your personal data will be used to process your order, support your experience throughout this website, and for other purposes described in our %s.', 'woocommerce' ), '[privacy_policy]' ) ); + break; + case 'registration': + /* translators: %s privacy policy page name and link */ + $text = get_option( 'woocommerce_registration_privacy_policy_text', sprintf( __( 'Your personal data will be used to support your experience throughout this website, to manage access to your account, and for other purposes described in our %s.', 'woocommerce' ), '[privacy_policy]' ) ); + break; + } + + return trim( apply_filters( 'woocommerce_get_privacy_policy_text', $text, $type ) ); +} + +/** + * Output t&c checkbox text. + * + * @since 3.4.0 + */ +function wc_terms_and_conditions_checkbox_text() { + $text = wc_get_terms_and_conditions_checkbox_text(); + + if ( ! $text ) { + return; + } + + echo wp_kses_post( wc_replace_policy_page_link_placeholders( $text ) ); +} + +/** + * Output t&c page's content (if set). The page can be set from checkout settings. + * + * @since 3.4.0 + */ +function wc_terms_and_conditions_page_content() { + $terms_page_id = wc_terms_and_conditions_page_id(); + + if ( ! $terms_page_id ) { + return; + } + + $page = get_post( $terms_page_id ); + + if ( $page && 'publish' === $page->post_status && $page->post_content && ! has_shortcode( $page->post_content, 'woocommerce_checkout' ) ) { + echo ''; + } +} + +/** + * Render privacy policy text on the checkout. + * + * @since 3.4.0 + */ +function wc_checkout_privacy_policy_text() { + echo '
    '; + wc_privacy_policy_text( 'checkout' ); + echo '
    '; +} + +/** + * Render privacy policy text on the register forms. + * + * @since 3.4.0 + */ +function wc_registration_privacy_policy_text() { + echo '
    '; + wc_privacy_policy_text( 'registration' ); + echo '
    '; +} + +/** + * Output privacy policy text. This is custom text which can be added via the customizer/privacy settings section. + * + * Loads the relevant policy for the current page unless a specific policy text is required. + * + * @since 3.4.0 + * @param string $type Type of policy to load. Valid values include registration and checkout. + */ +function wc_privacy_policy_text( $type = 'checkout' ) { + if ( ! wc_privacy_policy_page_id() ) { + return; + } + echo wp_kses_post( wpautop( wc_replace_policy_page_link_placeholders( wc_get_privacy_policy_text( $type ) ) ) ); +} + +/** + * Replaces placeholders with links to WooCommerce policy pages. + * + * @since 3.4.0 + * @param string $text Text to find/replace within. + * @return string + */ +function wc_replace_policy_page_link_placeholders( $text ) { + $privacy_page_id = wc_privacy_policy_page_id(); + $terms_page_id = wc_terms_and_conditions_page_id(); + $privacy_link = $privacy_page_id ? '
    ' . __( 'privacy policy', 'woocommerce' ) . '' : __( 'privacy policy', 'woocommerce' ); + $terms_link = $terms_page_id ? '' . __( 'terms and conditions', 'woocommerce' ) . '' : __( 'terms and conditions', 'woocommerce' ); + + $find_replace = array( + '[terms]' => $terms_link, + '[privacy_policy]' => $privacy_link, + ); + + return str_replace( array_keys( $find_replace ), array_values( $find_replace ), $text ); +} + +/** + * Template pages + */ + +if ( ! function_exists( 'woocommerce_content' ) ) { + + /** + * Output WooCommerce content. + * + * This function is only used in the optional 'woocommerce.php' template. + * which people can add to their themes to add basic woocommerce support. + * without hooks or modifying core templates. + */ + function woocommerce_content() { + + if ( is_singular( 'product' ) ) { + + while ( have_posts() ) : + the_post(); + wc_get_template_part( 'content', 'single-product' ); + endwhile; + + } else { + ?> + + + +

    + + + + + + + + + + + + + + + + + + + + + + + ' . wp_kses_post( $notice ) . ' ' . esc_html__( 'Dismiss', 'woocommerce' ) . '

    ', $notice ); + } +} + +/** + * Loop + */ + +if ( ! function_exists( 'woocommerce_page_title' ) ) { + + /** + * Page Title function. + * + * @param bool $echo Should echo title. + * @return string + */ + function woocommerce_page_title( $echo = true ) { + + if ( is_search() ) { + /* translators: %s: search query */ + $page_title = sprintf( __( 'Search results: “%s”', 'woocommerce' ), get_search_query() ); + + if ( get_query_var( 'paged' ) ) { + /* translators: %s: page number */ + $page_title .= sprintf( __( ' – Page %s', 'woocommerce' ), get_query_var( 'paged' ) ); + } + } elseif ( is_tax() ) { + + $page_title = single_term_title( '', false ); + + } else { + + $shop_page_id = wc_get_page_id( 'shop' ); + $page_title = get_the_title( $shop_page_id ); + + } + + $page_title = apply_filters( 'woocommerce_page_title', $page_title ); + + if ( $echo ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $page_title; + } else { + return $page_title; + } + } +} + +if ( ! function_exists( 'woocommerce_product_loop_start' ) ) { + + /** + * Output the start of a product loop. By default this is a UL. + * + * @param bool $echo Should echo?. + * @return string + */ + function woocommerce_product_loop_start( $echo = true ) { + ob_start(); + + wc_set_loop_prop( 'loop', 0 ); + + wc_get_template( 'loop/loop-start.php' ); + + $loop_start = apply_filters( 'woocommerce_product_loop_start', ob_get_clean() ); + + if ( $echo ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $loop_start; + } else { + return $loop_start; + } + } +} + +if ( ! function_exists( 'woocommerce_product_loop_end' ) ) { + + /** + * Output the end of a product loop. By default this is a UL. + * + * @param bool $echo Should echo?. + * @return string + */ + function woocommerce_product_loop_end( $echo = true ) { + ob_start(); + + wc_get_template( 'loop/loop-end.php' ); + + $loop_end = apply_filters( 'woocommerce_product_loop_end', ob_get_clean() ); + + if ( $echo ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $loop_end; + } else { + return $loop_end; + } + } +} +if ( ! function_exists( 'woocommerce_template_loop_product_title' ) ) { + + /** + * Show the product title in the product loop. By default this is an H2. + */ + function woocommerce_template_loop_product_title() { + echo '

    ' . get_the_title() . '

    '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} +if ( ! function_exists( 'woocommerce_template_loop_category_title' ) ) { + + /** + * Show the subcategory title in the product loop. + * + * @param object $category Category object. + */ + function woocommerce_template_loop_category_title( $category ) { + ?> +

    + name ); + + if ( $category->count > 0 ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo apply_filters( 'woocommerce_subcategory_count_html', ' (' . esc_html( $category->count ) . ')', $category ); + } + ?> +

    + '; + } +} + +if ( ! function_exists( 'woocommerce_template_loop_product_link_close' ) ) { + /** + * Insert the closing anchor tag for products in the loop. + */ + function woocommerce_template_loop_product_link_close() { + echo ''; + } +} + +if ( ! function_exists( 'woocommerce_template_loop_category_link_open' ) ) { + /** + * Insert the opening anchor tag for categories in the loop. + * + * @param int|object|string $category Category ID, Object or String. + */ + function woocommerce_template_loop_category_link_open( $category ) { + echo ''; + } +} + +if ( ! function_exists( 'woocommerce_template_loop_category_link_close' ) ) { + /** + * Insert the closing anchor tag for categories in the loop. + */ + function woocommerce_template_loop_category_link_close() { + echo ''; + } +} + +if ( ! function_exists( 'woocommerce_taxonomy_archive_description' ) ) { + + /** + * Show an archive description on taxonomy archives. + */ + function woocommerce_taxonomy_archive_description() { + if ( is_product_taxonomy() && 0 === absint( get_query_var( 'paged' ) ) ) { + $term = get_queried_object(); + + if ( $term && ! empty( $term->description ) ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
    ' . wc_format_content( $term->description ) . '
    '; + } + } + } +} +if ( ! function_exists( 'woocommerce_product_archive_description' ) ) { + + /** + * Show a shop page description on product archives. + */ + function woocommerce_product_archive_description() { + // Don't display the description on search results page. + if ( is_search() ) { + return; + } + + if ( is_post_type_archive( 'product' ) && in_array( absint( get_query_var( 'paged' ) ), array( 0, 1 ), true ) ) { + $shop_page = get_post( wc_get_page_id( 'shop' ) ); + if ( $shop_page ) { + $description = wc_format_content( $shop_page->post_content ); + if ( $description ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
    ' . $description . '
    '; + } + } + } + } +} + +if ( ! function_exists( 'woocommerce_template_loop_add_to_cart' ) ) { + + /** + * Get the add to cart template for the loop. + * + * @param array $args Arguments. + */ + function woocommerce_template_loop_add_to_cart( $args = array() ) { + global $product; + + if ( $product ) { + $defaults = array( + 'quantity' => 1, + 'class' => implode( + ' ', + array_filter( + array( + 'button', + 'product_type_' . $product->get_type(), + $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '', + $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock() ? 'ajax_add_to_cart' : '', + ) + ) + ), + 'attributes' => array( + 'data-product_id' => $product->get_id(), + 'data-product_sku' => $product->get_sku(), + 'aria-label' => $product->add_to_cart_description(), + 'rel' => 'nofollow', + ), + ); + + $args = apply_filters( 'woocommerce_loop_add_to_cart_args', wp_parse_args( $args, $defaults ), $product ); + + if ( isset( $args['attributes']['aria-label'] ) ) { + $args['attributes']['aria-label'] = wp_strip_all_tags( $args['attributes']['aria-label'] ); + } + + wc_get_template( 'loop/add-to-cart.php', $args ); + } + } +} + +if ( ! function_exists( 'woocommerce_template_loop_product_thumbnail' ) ) { + + /** + * Get the product thumbnail for the loop. + */ + function woocommerce_template_loop_product_thumbnail() { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo woocommerce_get_product_thumbnail(); + } +} +if ( ! function_exists( 'woocommerce_template_loop_price' ) ) { + + /** + * Get the product price for the loop. + */ + function woocommerce_template_loop_price() { + wc_get_template( 'loop/price.php' ); + } +} +if ( ! function_exists( 'woocommerce_template_loop_rating' ) ) { + + /** + * Display the average rating in the loop. + */ + function woocommerce_template_loop_rating() { + wc_get_template( 'loop/rating.php' ); + } +} +if ( ! function_exists( 'woocommerce_show_product_loop_sale_flash' ) ) { + + /** + * Get the sale flash for the loop. + */ + function woocommerce_show_product_loop_sale_flash() { + wc_get_template( 'loop/sale-flash.php' ); + } +} + +if ( ! function_exists( 'woocommerce_get_product_thumbnail' ) ) { + + /** + * Get the product thumbnail, or the placeholder if not set. + * + * @param string $size (default: 'woocommerce_thumbnail'). + * @param int $deprecated1 Deprecated since WooCommerce 2.0 (default: 0). + * @param int $deprecated2 Deprecated since WooCommerce 2.0 (default: 0). + * @return string + */ + function woocommerce_get_product_thumbnail( $size = 'woocommerce_thumbnail', $deprecated1 = 0, $deprecated2 = 0 ) { + global $product; + + $image_size = apply_filters( 'single_product_archive_thumbnail_size', $size ); + + return $product ? $product->get_image( $image_size ) : ''; + } +} + +if ( ! function_exists( 'woocommerce_result_count' ) ) { + + /** + * Output the result count text (Showing x - x of x results). + */ + function woocommerce_result_count() { + if ( ! wc_get_loop_prop( 'is_paginated' ) || ! woocommerce_products_will_display() ) { + return; + } + $args = array( + 'total' => wc_get_loop_prop( 'total' ), + 'per_page' => wc_get_loop_prop( 'per_page' ), + 'current' => wc_get_loop_prop( 'current_page' ), + ); + + wc_get_template( 'loop/result-count.php', $args ); + } +} + +if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) { + + /** + * Output the product sorting options. + */ + function woocommerce_catalog_ordering() { + if ( ! wc_get_loop_prop( 'is_paginated' ) || ! woocommerce_products_will_display() ) { + return; + } + $show_default_orderby = 'menu_order' === apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby', 'menu_order' ) ); + $catalog_orderby_options = apply_filters( + 'woocommerce_catalog_orderby', + array( + 'menu_order' => __( 'Default sorting', 'woocommerce' ), + 'popularity' => __( 'Sort by popularity', 'woocommerce' ), + 'rating' => __( 'Sort by average rating', 'woocommerce' ), + 'date' => __( 'Sort by latest', 'woocommerce' ), + 'price' => __( 'Sort by price: low to high', 'woocommerce' ), + 'price-desc' => __( 'Sort by price: high to low', 'woocommerce' ), + ) + ); + + $default_orderby = wc_get_loop_prop( 'is_search' ) ? 'relevance' : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby', '' ) ); + // phpcs:disable WordPress.Security.NonceVerification.Recommended + $orderby = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( $_GET['orderby'] ) ) : $default_orderby; + // phpcs:enable WordPress.Security.NonceVerification.Recommended + + if ( wc_get_loop_prop( 'is_search' ) ) { + $catalog_orderby_options = array_merge( array( 'relevance' => __( 'Relevance', 'woocommerce' ) ), $catalog_orderby_options ); + + unset( $catalog_orderby_options['menu_order'] ); + } + + if ( ! $show_default_orderby ) { + unset( $catalog_orderby_options['menu_order'] ); + } + + if ( ! wc_review_ratings_enabled() ) { + unset( $catalog_orderby_options['rating'] ); + } + + if ( ! array_key_exists( $orderby, $catalog_orderby_options ) ) { + $orderby = current( array_keys( $catalog_orderby_options ) ); + } + + wc_get_template( + 'loop/orderby.php', + array( + 'catalog_orderby_options' => $catalog_orderby_options, + 'orderby' => $orderby, + 'show_default_orderby' => $show_default_orderby, + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_pagination' ) ) { + + /** + * Output the pagination. + */ + function woocommerce_pagination() { + if ( ! wc_get_loop_prop( 'is_paginated' ) || ! woocommerce_products_will_display() ) { + return; + } + + $args = array( + 'total' => wc_get_loop_prop( 'total_pages' ), + 'current' => wc_get_loop_prop( 'current_page' ), + 'base' => esc_url_raw( add_query_arg( 'product-page', '%#%', false ) ), + 'format' => '?product-page=%#%', + ); + + if ( ! wc_get_loop_prop( 'is_shortcode' ) ) { + $args['format'] = ''; + $args['base'] = esc_url_raw( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ); + } + + wc_get_template( 'loop/pagination.php', $args ); + } +} + +/** + * Single Product + */ + +if ( ! function_exists( 'woocommerce_show_product_images' ) ) { + + /** + * Output the product image before the single product summary. + */ + function woocommerce_show_product_images() { + wc_get_template( 'single-product/product-image.php' ); + } +} +if ( ! function_exists( 'woocommerce_show_product_thumbnails' ) ) { + + /** + * Output the product thumbnails. + */ + function woocommerce_show_product_thumbnails() { + wc_get_template( 'single-product/product-thumbnails.php' ); + } +} + +/** + * Get HTML for a gallery image. + * + * Hooks: woocommerce_gallery_thumbnail_size, woocommerce_gallery_image_size and woocommerce_gallery_full_size accept name based image sizes, or an array of width/height values. + * + * @since 3.3.2 + * @param int $attachment_id Attachment ID. + * @param bool $main_image Is this the main image or a thumbnail?. + * @return string + */ +function wc_get_gallery_image_html( $attachment_id, $main_image = false ) { + $flexslider = (bool) apply_filters( 'woocommerce_single_product_flexslider_enabled', get_theme_support( 'wc-product-gallery-slider' ) ); + $gallery_thumbnail = wc_get_image_size( 'gallery_thumbnail' ); + $thumbnail_size = apply_filters( 'woocommerce_gallery_thumbnail_size', array( $gallery_thumbnail['width'], $gallery_thumbnail['height'] ) ); + $image_size = apply_filters( 'woocommerce_gallery_image_size', $flexslider || $main_image ? 'woocommerce_single' : $thumbnail_size ); + $full_size = apply_filters( 'woocommerce_gallery_full_size', apply_filters( 'woocommerce_product_thumbnails_large_size', 'full' ) ); + $thumbnail_src = wp_get_attachment_image_src( $attachment_id, $thumbnail_size ); + $full_src = wp_get_attachment_image_src( $attachment_id, $full_size ); + $alt_text = trim( wp_strip_all_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ); + $image = wp_get_attachment_image( + $attachment_id, + $image_size, + false, + apply_filters( + 'woocommerce_gallery_image_html_attachment_image_params', + array( + 'title' => _wp_specialchars( get_post_field( 'post_title', $attachment_id ), ENT_QUOTES, 'UTF-8', true ), + 'data-caption' => _wp_specialchars( get_post_field( 'post_excerpt', $attachment_id ), ENT_QUOTES, 'UTF-8', true ), + 'data-src' => esc_url( $full_src[0] ), + 'data-large_image' => esc_url( $full_src[0] ), + 'data-large_image_width' => esc_attr( $full_src[1] ), + 'data-large_image_height' => esc_attr( $full_src[2] ), + 'class' => esc_attr( $main_image ? 'wp-post-image' : '' ), + ), + $attachment_id, + $image_size, + $main_image + ) + ); + + return ''; +} + +if ( ! function_exists( 'woocommerce_output_product_data_tabs' ) ) { + + /** + * Output the product tabs. + */ + function woocommerce_output_product_data_tabs() { + wc_get_template( 'single-product/tabs/tabs.php' ); + } +} +if ( ! function_exists( 'woocommerce_template_single_title' ) ) { + + /** + * Output the product title. + */ + function woocommerce_template_single_title() { + wc_get_template( 'single-product/title.php' ); + } +} +if ( ! function_exists( 'woocommerce_template_single_rating' ) ) { + + /** + * Output the product rating. + */ + function woocommerce_template_single_rating() { + if ( post_type_supports( 'product', 'comments' ) ) { + wc_get_template( 'single-product/rating.php' ); + } + } +} +if ( ! function_exists( 'woocommerce_template_single_price' ) ) { + + /** + * Output the product price. + */ + function woocommerce_template_single_price() { + wc_get_template( 'single-product/price.php' ); + } +} +if ( ! function_exists( 'woocommerce_template_single_excerpt' ) ) { + + /** + * Output the product short description (excerpt). + */ + function woocommerce_template_single_excerpt() { + wc_get_template( 'single-product/short-description.php' ); + } +} +if ( ! function_exists( 'woocommerce_template_single_meta' ) ) { + + /** + * Output the product meta. + */ + function woocommerce_template_single_meta() { + wc_get_template( 'single-product/meta.php' ); + } +} +if ( ! function_exists( 'woocommerce_template_single_sharing' ) ) { + + /** + * Output the product sharing. + */ + function woocommerce_template_single_sharing() { + wc_get_template( 'single-product/share.php' ); + } +} +if ( ! function_exists( 'woocommerce_show_product_sale_flash' ) ) { + + /** + * Output the product sale flash. + */ + function woocommerce_show_product_sale_flash() { + wc_get_template( 'single-product/sale-flash.php' ); + } +} + +if ( ! function_exists( 'woocommerce_template_single_add_to_cart' ) ) { + + /** + * Trigger the single product add to cart action. + */ + function woocommerce_template_single_add_to_cart() { + global $product; + do_action( 'woocommerce_' . $product->get_type() . '_add_to_cart' ); + } +} +if ( ! function_exists( 'woocommerce_simple_add_to_cart' ) ) { + + /** + * Output the simple product add to cart area. + */ + function woocommerce_simple_add_to_cart() { + wc_get_template( 'single-product/add-to-cart/simple.php' ); + } +} +if ( ! function_exists( 'woocommerce_grouped_add_to_cart' ) ) { + + /** + * Output the grouped product add to cart area. + */ + function woocommerce_grouped_add_to_cart() { + global $product; + + $products = array_filter( array_map( 'wc_get_product', $product->get_children() ), 'wc_products_array_filter_visible_grouped' ); + + if ( $products ) { + wc_get_template( + 'single-product/add-to-cart/grouped.php', + array( + 'grouped_product' => $product, + 'grouped_products' => $products, + 'quantites_required' => false, + ) + ); + } + } +} +if ( ! function_exists( 'woocommerce_variable_add_to_cart' ) ) { + + /** + * Output the variable product add to cart area. + */ + function woocommerce_variable_add_to_cart() { + global $product; + + // Enqueue variation scripts. + wp_enqueue_script( 'wc-add-to-cart-variation' ); + + // Get Available variations? + $get_variations = count( $product->get_children() ) <= apply_filters( 'woocommerce_ajax_variation_threshold', 30, $product ); + + // Load the template. + wc_get_template( + 'single-product/add-to-cart/variable.php', + array( + 'available_variations' => $get_variations ? $product->get_available_variations() : false, + 'attributes' => $product->get_variation_attributes(), + 'selected_attributes' => $product->get_default_attributes(), + ) + ); + } +} +if ( ! function_exists( 'woocommerce_external_add_to_cart' ) ) { + + /** + * Output the external product add to cart area. + */ + function woocommerce_external_add_to_cart() { + global $product; + + if ( ! $product->add_to_cart_url() ) { + return; + } + + wc_get_template( + 'single-product/add-to-cart/external.php', + array( + 'product_url' => $product->add_to_cart_url(), + 'button_text' => $product->single_add_to_cart_text(), + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_quantity_input' ) ) { + + /** + * Output the quantity input for add to cart forms. + * + * @param array $args Args for the input. + * @param WC_Product|null $product Product. + * @param boolean $echo Whether to return or echo|string. + * + * @return string + */ + function woocommerce_quantity_input( $args = array(), $product = null, $echo = true ) { + if ( is_null( $product ) ) { + $product = $GLOBALS['product']; + } + + $defaults = array( + 'input_id' => uniqid( 'quantity_' ), + 'input_name' => 'quantity', + 'input_value' => '1', + 'classes' => apply_filters( 'woocommerce_quantity_input_classes', array( 'input-text', 'qty', 'text' ), $product ), + 'max_value' => apply_filters( 'woocommerce_quantity_input_max', -1, $product ), + 'min_value' => apply_filters( 'woocommerce_quantity_input_min', 0, $product ), + 'step' => apply_filters( 'woocommerce_quantity_input_step', 1, $product ), + 'pattern' => apply_filters( 'woocommerce_quantity_input_pattern', has_filter( 'woocommerce_stock_amount', 'intval' ) ? '[0-9]*' : '' ), + 'inputmode' => apply_filters( 'woocommerce_quantity_input_inputmode', has_filter( 'woocommerce_stock_amount', 'intval' ) ? 'numeric' : '' ), + 'product_name' => $product ? $product->get_title() : '', + 'placeholder' => apply_filters( 'woocommerce_quantity_input_placeholder', '', $product ), + ); + + $args = apply_filters( 'woocommerce_quantity_input_args', wp_parse_args( $args, $defaults ), $product ); + + // Apply sanity to min/max args - min cannot be lower than 0. + $args['min_value'] = max( $args['min_value'], 0 ); + $args['max_value'] = 0 < $args['max_value'] ? $args['max_value'] : ''; + + // Max cannot be lower than min if defined. + if ( '' !== $args['max_value'] && $args['max_value'] < $args['min_value'] ) { + $args['max_value'] = $args['min_value']; + } + + ob_start(); + + wc_get_template( 'global/quantity-input.php', $args ); + + if ( $echo ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo ob_get_clean(); + } else { + return ob_get_clean(); + } + } +} + +if ( ! function_exists( 'woocommerce_product_description_tab' ) ) { + + /** + * Output the description tab content. + */ + function woocommerce_product_description_tab() { + wc_get_template( 'single-product/tabs/description.php' ); + } +} +if ( ! function_exists( 'woocommerce_product_additional_information_tab' ) ) { + + /** + * Output the attributes tab content. + */ + function woocommerce_product_additional_information_tab() { + wc_get_template( 'single-product/tabs/additional-information.php' ); + } +} +if ( ! function_exists( 'woocommerce_default_product_tabs' ) ) { + + /** + * Add default product tabs to product pages. + * + * @param array $tabs Array of tabs. + * @return array + */ + function woocommerce_default_product_tabs( $tabs = array() ) { + global $product, $post; + + // Description tab - shows product content. + if ( $post->post_content ) { + $tabs['description'] = array( + 'title' => __( 'Description', 'woocommerce' ), + 'priority' => 10, + 'callback' => 'woocommerce_product_description_tab', + ); + } + + // Additional information tab - shows attributes. + if ( $product && ( $product->has_attributes() || apply_filters( 'wc_product_enable_dimensions_display', $product->has_weight() || $product->has_dimensions() ) ) ) { + $tabs['additional_information'] = array( + 'title' => __( 'Additional information', 'woocommerce' ), + 'priority' => 20, + 'callback' => 'woocommerce_product_additional_information_tab', + ); + } + + // Reviews tab - shows comments. + if ( comments_open() ) { + $tabs['reviews'] = array( + /* translators: %s: reviews count */ + 'title' => sprintf( __( 'Reviews (%d)', 'woocommerce' ), $product->get_review_count() ), + 'priority' => 30, + 'callback' => 'comments_template', + ); + } + + return $tabs; + } +} + +if ( ! function_exists( 'woocommerce_sort_product_tabs' ) ) { + + /** + * Sort tabs by priority. + * + * @param array $tabs Array of tabs. + * @return array + */ + function woocommerce_sort_product_tabs( $tabs = array() ) { + + // Make sure the $tabs parameter is an array. + if ( ! is_array( $tabs ) ) { + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error + trigger_error( 'Function woocommerce_sort_product_tabs() expects an array as the first parameter. Defaulting to empty array.' ); + $tabs = array(); + } + + // Re-order tabs by priority. + if ( ! function_exists( '_sort_priority_callback' ) ) { + /** + * Sort Priority Callback Function + * + * @param array $a Comparison A. + * @param array $b Comparison B. + * @return bool + */ + function _sort_priority_callback( $a, $b ) { + if ( ! isset( $a['priority'], $b['priority'] ) || $a['priority'] === $b['priority'] ) { + return 0; + } + return ( $a['priority'] < $b['priority'] ) ? -1 : 1; + } + } + + uasort( $tabs, '_sort_priority_callback' ); + + return $tabs; + } +} + +if ( ! function_exists( 'woocommerce_comments' ) ) { + + /** + * Output the Review comments template. + * + * @param WP_Comment $comment Comment object. + * @param array $args Arguments. + * @param int $depth Depth. + */ + function woocommerce_comments( $comment, $args, $depth ) { + // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + $GLOBALS['comment'] = $comment; + wc_get_template( + 'single-product/review.php', + array( + 'comment' => $comment, + 'args' => $args, + 'depth' => $depth, + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_review_display_gravatar' ) ) { + /** + * Display the review authors gravatar + * + * @param array $comment WP_Comment. + * @return void + */ + function woocommerce_review_display_gravatar( $comment ) { + echo get_avatar( $comment, apply_filters( 'woocommerce_review_gravatar_size', '60' ), '' ); + } +} + +if ( ! function_exists( 'woocommerce_review_display_rating' ) ) { + /** + * Display the reviewers star rating + * + * @return void + */ + function woocommerce_review_display_rating() { + if ( post_type_supports( 'product', 'comments' ) ) { + wc_get_template( 'single-product/review-rating.php' ); + } + } +} + +if ( ! function_exists( 'woocommerce_review_display_meta' ) ) { + /** + * Display the review authors meta (name, verified owner, review date) + * + * @return void + */ + function woocommerce_review_display_meta() { + wc_get_template( 'single-product/review-meta.php' ); + } +} + +if ( ! function_exists( 'woocommerce_review_display_comment_text' ) ) { + + /** + * Display the review content. + */ + function woocommerce_review_display_comment_text() { + echo '
    '; + comment_text(); + echo '
    '; + } +} + +if ( ! function_exists( 'woocommerce_output_related_products' ) ) { + + /** + * Output the related products. + */ + function woocommerce_output_related_products() { + + $args = array( + 'posts_per_page' => 4, + 'columns' => 4, + 'orderby' => 'rand', // @codingStandardsIgnoreLine. + ); + + woocommerce_related_products( apply_filters( 'woocommerce_output_related_products_args', $args ) ); + } +} + +if ( ! function_exists( 'woocommerce_related_products' ) ) { + + /** + * Output the related products. + * + * @param array $args Provided arguments. + */ + function woocommerce_related_products( $args = array() ) { + global $product; + + if ( ! $product ) { + return; + } + + $defaults = array( + 'posts_per_page' => 2, + 'columns' => 2, + 'orderby' => 'rand', // @codingStandardsIgnoreLine. + 'order' => 'desc', + ); + + $args = wp_parse_args( $args, $defaults ); + + // Get visible related products then sort them at random. + $args['related_products'] = array_filter( array_map( 'wc_get_product', wc_get_related_products( $product->get_id(), $args['posts_per_page'], $product->get_upsell_ids() ) ), 'wc_products_array_filter_visible' ); + + // Handle orderby. + $args['related_products'] = wc_products_array_orderby( $args['related_products'], $args['orderby'], $args['order'] ); + + // Set global loop values. + wc_set_loop_prop( 'name', 'related' ); + wc_set_loop_prop( 'columns', apply_filters( 'woocommerce_related_products_columns', $args['columns'] ) ); + + wc_get_template( 'single-product/related.php', $args ); + } +} + +if ( ! function_exists( 'woocommerce_upsell_display' ) ) { + + /** + * Output product up sells. + * + * @param int $limit (default: -1). + * @param int $columns (default: 4). + * @param string $orderby Supported values - rand, title, ID, date, modified, menu_order, price. + * @param string $order Sort direction. + */ + function woocommerce_upsell_display( $limit = '-1', $columns = 4, $orderby = 'rand', $order = 'desc' ) { + global $product; + + if ( ! $product ) { + return; + } + + // Handle the legacy filter which controlled posts per page etc. + $args = apply_filters( + 'woocommerce_upsell_display_args', + array( + 'posts_per_page' => $limit, + 'orderby' => $orderby, + 'order' => $order, + 'columns' => $columns, + ) + ); + wc_set_loop_prop( 'name', 'up-sells' ); + wc_set_loop_prop( 'columns', apply_filters( 'woocommerce_upsells_columns', isset( $args['columns'] ) ? $args['columns'] : $columns ) ); + + $orderby = apply_filters( 'woocommerce_upsells_orderby', isset( $args['orderby'] ) ? $args['orderby'] : $orderby ); + $order = apply_filters( 'woocommerce_upsells_order', isset( $args['order'] ) ? $args['order'] : $order ); + $limit = apply_filters( 'woocommerce_upsells_total', isset( $args['posts_per_page'] ) ? $args['posts_per_page'] : $limit ); + + // Get visible upsells then sort them at random, then limit result set. + $upsells = wc_products_array_orderby( array_filter( array_map( 'wc_get_product', $product->get_upsell_ids() ), 'wc_products_array_filter_visible' ), $orderby, $order ); + $upsells = $limit > 0 ? array_slice( $upsells, 0, $limit ) : $upsells; + + wc_get_template( + 'single-product/up-sells.php', + array( + 'upsells' => $upsells, + + // Not used now, but used in previous version of up-sells.php. + 'posts_per_page' => $limit, + 'orderby' => $orderby, + 'columns' => $columns, + ) + ); + } +} + +/** Cart */ + +if ( ! function_exists( 'woocommerce_shipping_calculator' ) ) { + + /** + * Output the cart shipping calculator. + * + * @param string $button_text Text for the shipping calculation toggle. + */ + function woocommerce_shipping_calculator( $button_text = '' ) { + if ( 'no' === get_option( 'woocommerce_enable_shipping_calc' ) || ! WC()->cart->needs_shipping() ) { + return; + } + wp_enqueue_script( 'wc-country-select' ); + wc_get_template( + 'cart/shipping-calculator.php', + array( + 'button_text' => $button_text, + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_cart_totals' ) ) { + + /** + * Output the cart totals. + */ + function woocommerce_cart_totals() { + if ( is_checkout() ) { + return; + } + wc_get_template( 'cart/cart-totals.php' ); + } +} + +if ( ! function_exists( 'woocommerce_cross_sell_display' ) ) { + + /** + * Output the cart cross-sells. + * + * @param int $limit (default: 2). + * @param int $columns (default: 2). + * @param string $orderby (default: 'rand'). + * @param string $order (default: 'desc'). + */ + function woocommerce_cross_sell_display( $limit = 2, $columns = 2, $orderby = 'rand', $order = 'desc' ) { + if ( is_checkout() ) { + return; + } + // Get visible cross sells then sort them at random. + $cross_sells = array_filter( array_map( 'wc_get_product', WC()->cart->get_cross_sells() ), 'wc_products_array_filter_visible' ); + + wc_set_loop_prop( 'name', 'cross-sells' ); + wc_set_loop_prop( 'columns', apply_filters( 'woocommerce_cross_sells_columns', $columns ) ); + + // Handle orderby and limit results. + $orderby = apply_filters( 'woocommerce_cross_sells_orderby', $orderby ); + $order = apply_filters( 'woocommerce_cross_sells_order', $order ); + $cross_sells = wc_products_array_orderby( $cross_sells, $orderby, $order ); + $limit = apply_filters( 'woocommerce_cross_sells_total', $limit ); + $cross_sells = $limit > 0 ? array_slice( $cross_sells, 0, $limit ) : $cross_sells; + + wc_get_template( + 'cart/cross-sells.php', + array( + 'cross_sells' => $cross_sells, + + // Not used now, but used in previous version of up-sells.php. + 'posts_per_page' => $limit, + 'orderby' => $orderby, + 'columns' => $columns, + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_button_proceed_to_checkout' ) ) { + + /** + * Output the proceed to checkout button. + */ + function woocommerce_button_proceed_to_checkout() { + wc_get_template( 'cart/proceed-to-checkout-button.php' ); + } +} + +if ( ! function_exists( 'woocommerce_widget_shopping_cart_button_view_cart' ) ) { + + /** + * Output the view cart button. + */ + function woocommerce_widget_shopping_cart_button_view_cart() { + echo '' . esc_html__( 'View cart', 'woocommerce' ) . ''; + } +} + +if ( ! function_exists( 'woocommerce_widget_shopping_cart_proceed_to_checkout' ) ) { + + /** + * Output the proceed to checkout button. + */ + function woocommerce_widget_shopping_cart_proceed_to_checkout() { + echo '' . esc_html__( 'Checkout', 'woocommerce' ) . ''; + } +} + +if ( ! function_exists( 'woocommerce_widget_shopping_cart_subtotal' ) ) { + /** + * Output to view cart subtotal. + * + * @since 3.7.0 + */ + function woocommerce_widget_shopping_cart_subtotal() { + echo '' . esc_html__( 'Subtotal:', 'woocommerce' ) . ' ' . WC()->cart->get_cart_subtotal(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} + +/** Mini-Cart */ + +if ( ! function_exists( 'woocommerce_mini_cart' ) ) { + + /** + * Output the Mini-cart - used by cart widget. + * + * @param array $args Arguments. + */ + function woocommerce_mini_cart( $args = array() ) { + + $defaults = array( + 'list_class' => '', + ); + + $args = wp_parse_args( $args, $defaults ); + + wc_get_template( 'cart/mini-cart.php', $args ); + } +} + +/** Login */ + +if ( ! function_exists( 'woocommerce_login_form' ) ) { + + /** + * Output the WooCommerce Login Form. + * + * @param array $args Arguments. + */ + function woocommerce_login_form( $args = array() ) { + + $defaults = array( + 'message' => '', + 'redirect' => '', + 'hidden' => false, + ); + + $args = wp_parse_args( $args, $defaults ); + + wc_get_template( 'global/form-login.php', $args ); + } +} + +if ( ! function_exists( 'woocommerce_checkout_login_form' ) ) { + + /** + * Output the WooCommerce Checkout Login Form. + */ + function woocommerce_checkout_login_form() { + wc_get_template( + 'checkout/form-login.php', + array( + 'checkout' => WC()->checkout(), + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_breadcrumb' ) ) { + + /** + * Output the WooCommerce Breadcrumb. + * + * @param array $args Arguments. + */ + function woocommerce_breadcrumb( $args = array() ) { + $args = wp_parse_args( + $args, + apply_filters( + 'woocommerce_breadcrumb_defaults', + array( + 'delimiter' => ' / ', + 'wrap_before' => '', + 'before' => '', + 'after' => '', + 'home' => _x( 'Home', 'breadcrumb', 'woocommerce' ), + ) + ) + ); + + $breadcrumbs = new WC_Breadcrumb(); + + if ( ! empty( $args['home'] ) ) { + $breadcrumbs->add_crumb( $args['home'], apply_filters( 'woocommerce_breadcrumb_home_url', home_url() ) ); + } + + $args['breadcrumb'] = $breadcrumbs->generate(); + + /** + * WooCommerce Breadcrumb hook + * + * @hooked WC_Structured_Data::generate_breadcrumblist_data() - 10 + */ + do_action( 'woocommerce_breadcrumb', $breadcrumbs, $args ); + + wc_get_template( 'global/breadcrumb.php', $args ); + } +} + +if ( ! function_exists( 'woocommerce_order_review' ) ) { + + /** + * Output the Order review table for the checkout. + * + * @param bool $deprecated Deprecated param. + */ + function woocommerce_order_review( $deprecated = false ) { + wc_get_template( + 'checkout/review-order.php', + array( + 'checkout' => WC()->checkout(), + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_checkout_payment' ) ) { + + /** + * Output the Payment Methods on the checkout. + */ + function woocommerce_checkout_payment() { + if ( WC()->cart->needs_payment() ) { + $available_gateways = WC()->payment_gateways()->get_available_payment_gateways(); + WC()->payment_gateways()->set_current_gateway( $available_gateways ); + } else { + $available_gateways = array(); + } + + wc_get_template( + 'checkout/payment.php', + array( + 'checkout' => WC()->checkout(), + 'available_gateways' => $available_gateways, + 'order_button_text' => apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ), + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_checkout_coupon_form' ) ) { + + /** + * Output the Coupon form for the checkout. + */ + function woocommerce_checkout_coupon_form() { + wc_get_template( + 'checkout/form-coupon.php', + array( + 'checkout' => WC()->checkout(), + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_products_will_display' ) ) { + + /** + * Check if we will be showing products or not (and not sub-categories only). + * + * @return bool + */ + function woocommerce_products_will_display() { + $display_type = woocommerce_get_loop_display_mode(); + + return 0 < wc_get_loop_prop( 'total', 0 ) && 'subcategories' !== $display_type; + } +} + +if ( ! function_exists( 'woocommerce_get_loop_display_mode' ) ) { + + /** + * See what is going to display in the loop. + * + * @since 3.3.0 + * @return string Either products, subcategories, or both, based on current page. + */ + function woocommerce_get_loop_display_mode() { + // Only return products when filtering things. + if ( wc_get_loop_prop( 'is_search' ) || wc_get_loop_prop( 'is_filtered' ) ) { + return 'products'; + } + + $parent_id = 0; + $display_type = ''; + + if ( is_shop() ) { + $display_type = get_option( 'woocommerce_shop_page_display', '' ); + } elseif ( is_product_category() ) { + $parent_id = get_queried_object_id(); + $display_type = get_term_meta( $parent_id, 'display_type', true ); + $display_type = '' === $display_type ? get_option( 'woocommerce_category_archive_display', '' ) : $display_type; + } + + if ( ( ! is_shop() || 'subcategories' !== $display_type ) && 1 < wc_get_loop_prop( 'current_page' ) ) { + return 'products'; + } + + // Ensure valid value. + if ( '' === $display_type || ! in_array( $display_type, array( 'products', 'subcategories', 'both' ), true ) ) { + $display_type = 'products'; + } + + // If we're showing categories, ensure we actually have something to show. + if ( in_array( $display_type, array( 'subcategories', 'both' ), true ) ) { + $subcategories = woocommerce_get_product_subcategories( $parent_id ); + + if ( empty( $subcategories ) ) { + $display_type = 'products'; + } + } + + return $display_type; + } +} + +if ( ! function_exists( 'woocommerce_maybe_show_product_subcategories' ) ) { + + /** + * Maybe display categories before, or instead of, a product loop. + * + * @since 3.3.0 + * @param string $loop_html HTML. + * @return string + */ + function woocommerce_maybe_show_product_subcategories( $loop_html = '' ) { + if ( wc_get_loop_prop( 'is_shortcode' ) && ! WC_Template_Loader::in_content_filter() ) { + return $loop_html; + } + + $display_type = woocommerce_get_loop_display_mode(); + + // If displaying categories, append to the loop. + if ( 'subcategories' === $display_type || 'both' === $display_type ) { + ob_start(); + woocommerce_output_product_categories( + array( + 'parent_id' => is_product_category() ? get_queried_object_id() : 0, + ) + ); + $loop_html .= ob_get_clean(); + + if ( 'subcategories' === $display_type ) { + wc_set_loop_prop( 'total', 0 ); + + // This removes pagination and products from display for themes not using wc_get_loop_prop in their product loops. @todo Remove in future major version. + global $wp_query; + + if ( $wp_query->is_main_query() ) { + $wp_query->post_count = 0; + $wp_query->max_num_pages = 0; + } + } + } + + return $loop_html; + } +} + +if ( ! function_exists( 'woocommerce_product_subcategories' ) ) { + /** + * This is a legacy function which used to check if we needed to display subcats and then output them. It was called by templates. + * + * From 3.3 onwards this is all handled via hooks and the woocommerce_maybe_show_product_subcategories function. + * + * Since some templates have not updated compatibility, to avoid showing incorrect categories this function has been deprecated and will + * return nothing. Replace usage with woocommerce_output_product_categories to render the category list manually. + * + * This is a legacy function which also checks if things should display. + * Themes no longer need to call these functions. It's all done via hooks. + * + * @deprecated 3.3.1 @todo Add a notice in a future version. + * @param array $args Arguments. + * @return null|boolean + */ + function woocommerce_product_subcategories( $args = array() ) { + $defaults = array( + 'before' => '', + 'after' => '', + 'force_display' => false, + ); + + $args = wp_parse_args( $args, $defaults ); + + if ( $args['force_display'] ) { + // We can still render if display is forced. + woocommerce_output_product_categories( + array( + 'before' => $args['before'], + 'after' => $args['after'], + 'parent_id' => is_product_category() ? get_queried_object_id() : 0, + ) + ); + return true; + } else { + // Output nothing. woocommerce_maybe_show_product_subcategories will handle the output of cats. + $display_type = woocommerce_get_loop_display_mode(); + + if ( 'subcategories' === $display_type ) { + // This removes pagination and products from display for themes not using wc_get_loop_prop in their product loops. @todo Remove in future major version. + global $wp_query; + + if ( $wp_query->is_main_query() ) { + $wp_query->post_count = 0; + $wp_query->max_num_pages = 0; + } + } + + return 'subcategories' === $display_type || 'both' === $display_type; + } + } +} + +if ( ! function_exists( 'woocommerce_output_product_categories' ) ) { + /** + * Display product sub categories as thumbnails. + * + * This is a replacement for woocommerce_product_subcategories which also does some logic + * based on the loop. This function however just outputs when called. + * + * @since 3.3.1 + * @param array $args Arguments. + * @return boolean + */ + function woocommerce_output_product_categories( $args = array() ) { + $args = wp_parse_args( + $args, + array( + 'before' => apply_filters( 'woocommerce_before_output_product_categories', '' ), + 'after' => apply_filters( 'woocommerce_after_output_product_categories', '' ), + 'parent_id' => 0, + ) + ); + + $product_categories = woocommerce_get_product_subcategories( $args['parent_id'] ); + + if ( ! $product_categories ) { + return false; + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $args['before']; + + foreach ( $product_categories as $category ) { + wc_get_template( + 'content-product_cat.php', + array( + 'category' => $category, + ) + ); + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $args['after']; + + return true; + } +} + +if ( ! function_exists( 'woocommerce_get_product_subcategories' ) ) { + /** + * Get (and cache) product subcategories. + * + * @param int $parent_id Get subcategories of this ID. + * @return array + */ + function woocommerce_get_product_subcategories( $parent_id = 0 ) { + $parent_id = absint( $parent_id ); + $cache_key = apply_filters( 'woocommerce_get_product_subcategories_cache_key', 'product-category-hierarchy-' . $parent_id, $parent_id ); + $product_categories = $cache_key ? wp_cache_get( $cache_key, 'product_cat' ) : false; + + if ( false === $product_categories ) { + // NOTE: using child_of instead of parent - this is not ideal but due to a WP bug ( https://core.trac.wordpress.org/ticket/15626 ) pad_counts won't work. + $product_categories = get_categories( + apply_filters( + 'woocommerce_product_subcategories_args', + array( + 'parent' => $parent_id, + 'hide_empty' => 0, + 'hierarchical' => 1, + 'taxonomy' => 'product_cat', + 'pad_counts' => 1, + ) + ) + ); + + if ( $cache_key ) { + wp_cache_set( $cache_key, $product_categories, 'product_cat' ); + } + } + + if ( apply_filters( 'woocommerce_product_subcategories_hide_empty', true ) ) { + $product_categories = wp_list_filter( $product_categories, array( 'count' => 0 ), 'NOT' ); + } + + return $product_categories; + } +} + +if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) { + + /** + * Show subcategory thumbnails. + * + * @param mixed $category Category. + */ + function woocommerce_subcategory_thumbnail( $category ) { + $small_thumbnail_size = apply_filters( 'subcategory_archive_thumbnail_size', 'woocommerce_thumbnail' ); + $dimensions = wc_get_image_size( $small_thumbnail_size ); + $thumbnail_id = get_term_meta( $category->term_id, 'thumbnail_id', true ); + + if ( $thumbnail_id ) { + $image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size ); + $image = $image[0]; + $image_srcset = function_exists( 'wp_get_attachment_image_srcset' ) ? wp_get_attachment_image_srcset( $thumbnail_id, $small_thumbnail_size ) : false; + $image_sizes = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $thumbnail_id, $small_thumbnail_size ) : false; + } else { + $image = wc_placeholder_img_src(); + $image_srcset = false; + $image_sizes = false; + } + + if ( $image ) { + // Prevent esc_url from breaking spaces in urls for image embeds. + // Ref: https://core.trac.wordpress.org/ticket/23605. + $image = str_replace( ' ', '%20', $image ); + + // Add responsive image markup if available. + if ( $image_srcset && $image_sizes ) { + echo '' . esc_attr( $category->name ) . ''; + } else { + echo '' . esc_attr( $category->name ) . ''; + } + } + } +} + +if ( ! function_exists( 'woocommerce_order_details_table' ) ) { + + /** + * Displays order details in a table. + * + * @param mixed $order_id Order ID. + */ + function woocommerce_order_details_table( $order_id ) { + if ( ! $order_id ) { + return; + } + + wc_get_template( + 'order/order-details.php', + array( + 'order_id' => $order_id, + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_order_downloads_table' ) ) { + + /** + * Displays order downloads in a table. + * + * @since 3.2.0 + * @param array $downloads Downloads. + */ + function woocommerce_order_downloads_table( $downloads ) { + if ( ! $downloads ) { + return; + } + wc_get_template( + 'order/order-downloads.php', + array( + 'downloads' => $downloads, + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_order_again_button' ) ) { + + /** + * Display an 'order again' button on the view order page. + * + * @param object $order Order. + */ + function woocommerce_order_again_button( $order ) { + if ( ! $order || ! $order->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_order_again', array( 'completed' ) ) ) || ! is_user_logged_in() ) { + return; + } + + wc_get_template( + 'order/order-again.php', + array( + 'order' => $order, + 'order_again_url' => wp_nonce_url( add_query_arg( 'order_again', $order->get_id(), wc_get_cart_url() ), 'woocommerce-order_again' ), + ) + ); + } +} + +/** Forms */ + +if ( ! function_exists( 'woocommerce_form_field' ) ) { + + /** + * Outputs a checkout/address form field. + * + * @param string $key Key. + * @param mixed $args Arguments. + * @param string $value (default: null). + * @return string + */ + function woocommerce_form_field( $key, $args, $value = null ) { + $defaults = array( + 'type' => 'text', + 'label' => '', + 'description' => '', + 'placeholder' => '', + 'maxlength' => false, + 'required' => false, + 'autocomplete' => false, + 'id' => $key, + 'class' => array(), + 'label_class' => array(), + 'input_class' => array(), + 'return' => false, + 'options' => array(), + 'custom_attributes' => array(), + 'validate' => array(), + 'default' => '', + 'autofocus' => '', + 'priority' => '', + ); + + $args = wp_parse_args( $args, $defaults ); + $args = apply_filters( 'woocommerce_form_field_args', $args, $key, $value ); + + if ( $args['required'] ) { + $args['class'][] = 'validate-required'; + $required = ' *'; + } else { + $required = ' (' . esc_html__( 'optional', 'woocommerce' ) . ')'; + } + + if ( is_string( $args['label_class'] ) ) { + $args['label_class'] = array( $args['label_class'] ); + } + + if ( is_null( $value ) ) { + $value = $args['default']; + } + + // Custom attribute handling. + $custom_attributes = array(); + $args['custom_attributes'] = array_filter( (array) $args['custom_attributes'], 'strlen' ); + + if ( $args['maxlength'] ) { + $args['custom_attributes']['maxlength'] = absint( $args['maxlength'] ); + } + + if ( ! empty( $args['autocomplete'] ) ) { + $args['custom_attributes']['autocomplete'] = $args['autocomplete']; + } + + if ( true === $args['autofocus'] ) { + $args['custom_attributes']['autofocus'] = 'autofocus'; + } + + if ( $args['description'] ) { + $args['custom_attributes']['aria-describedby'] = $args['id'] . '-description'; + } + + if ( ! empty( $args['custom_attributes'] ) && is_array( $args['custom_attributes'] ) ) { + foreach ( $args['custom_attributes'] as $attribute => $attribute_value ) { + $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"'; + } + } + + if ( ! empty( $args['validate'] ) ) { + foreach ( $args['validate'] as $validate ) { + $args['class'][] = 'validate-' . $validate; + } + } + + $field = ''; + $label_id = $args['id']; + $sort = $args['priority'] ? $args['priority'] : ''; + $field_container = '

    %3$s

    '; + + switch ( $args['type'] ) { + case 'country': + $countries = 'shipping_country' === $key ? WC()->countries->get_shipping_countries() : WC()->countries->get_allowed_countries(); + + if ( 1 === count( $countries ) ) { + + $field .= '' . current( array_values( $countries ) ) . ''; + + $field .= ''; + + } else { + + $field = ''; + + $field .= ''; + + } + + break; + case 'state': + /* Get country this state field is representing */ + $for_country = isset( $args['country'] ) ? $args['country'] : WC()->checkout->get_value( 'billing_state' === $key ? 'billing_country' : 'shipping_country' ); + $states = WC()->countries->get_states( $for_country ); + + if ( is_array( $states ) && empty( $states ) ) { + + $field_container = ''; + + $field .= ''; + + } elseif ( ! is_null( $for_country ) && is_array( $states ) ) { + + $field .= ''; + + } else { + + $field .= ''; + + } + + break; + case 'textarea': + $field .= ''; + + break; + case 'checkbox': + $field = ''; + + break; + case 'text': + case 'password': + case 'datetime': + case 'datetime-local': + case 'date': + case 'month': + case 'time': + case 'week': + case 'number': + case 'email': + case 'url': + case 'tel': + $field .= ''; + + break; + case 'hidden': + $field .= ''; + + break; + case 'select': + $field = ''; + $options = ''; + + if ( ! empty( $args['options'] ) ) { + foreach ( $args['options'] as $option_key => $option_text ) { + if ( '' === $option_key ) { + // If we have a blank option, select2 needs a placeholder. + if ( empty( $args['placeholder'] ) ) { + $args['placeholder'] = $option_text ? $option_text : __( 'Choose an option', 'woocommerce' ); + } + $custom_attributes[] = 'data-allow_clear="true"'; + } + $options .= ''; + } + + $field .= ''; + } + + break; + case 'radio': + $label_id .= '_' . current( array_keys( $args['options'] ) ); + + if ( ! empty( $args['options'] ) ) { + foreach ( $args['options'] as $option_key => $option_text ) { + $field .= ''; + $field .= ''; + } + } + + break; + } + + if ( ! empty( $field ) ) { + $field_html = ''; + + if ( $args['label'] && 'checkbox' !== $args['type'] ) { + $field_html .= ''; + } + + $field_html .= '' . $field; + + if ( $args['description'] ) { + $field_html .= ''; + } + + $field_html .= ''; + + $container_class = esc_attr( implode( ' ', $args['class'] ) ); + $container_id = esc_attr( $args['id'] ) . '_field'; + $field = sprintf( $field_container, $container_class, $container_id, $field_html ); + } + + /** + * Filter by type. + */ + $field = apply_filters( 'woocommerce_form_field_' . $args['type'], $field, $key, $args, $value ); + + /** + * General filter on form fields. + * + * @since 3.4.0 + */ + $field = apply_filters( 'woocommerce_form_field', $field, $key, $args, $value ); + + if ( $args['return'] ) { + return $field; + } else { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $field; + } + } +} + +if ( ! function_exists( 'get_product_search_form' ) ) { + + /** + * Display product search form. + * + * Will first attempt to locate the product-searchform.php file in either the child or. + * the parent, then load it. If it doesn't exist, then the default search form. + * will be displayed. + * + * The default searchform uses html5. + * + * @param bool $echo (default: true). + * @return string + */ + function get_product_search_form( $echo = true ) { + global $product_search_form_index; + + ob_start(); + + if ( empty( $product_search_form_index ) ) { + $product_search_form_index = 0; + } + + do_action( 'pre_get_product_search_form' ); + + wc_get_template( + 'product-searchform.php', + array( + 'index' => $product_search_form_index++, + ) + ); + + $form = apply_filters( 'get_product_search_form', ob_get_clean() ); + + if ( ! $echo ) { + return $form; + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $form; + } +} + +if ( ! function_exists( 'woocommerce_output_auth_header' ) ) { + + /** + * Output the Auth header. + */ + function woocommerce_output_auth_header() { + wc_get_template( 'auth/header.php' ); + } +} + +if ( ! function_exists( 'woocommerce_output_auth_footer' ) ) { + + /** + * Output the Auth footer. + */ + function woocommerce_output_auth_footer() { + wc_get_template( 'auth/footer.php' ); + } +} + +if ( ! function_exists( 'woocommerce_single_variation' ) ) { + + /** + * Output placeholders for the single variation. + */ + function woocommerce_single_variation() { + echo '
    '; + } +} + +if ( ! function_exists( 'woocommerce_single_variation_add_to_cart_button' ) ) { + + /** + * Output the add to cart button for variations. + */ + function woocommerce_single_variation_add_to_cart_button() { + wc_get_template( 'single-product/add-to-cart/variation-add-to-cart-button.php' ); + } +} + +if ( ! function_exists( 'wc_dropdown_variation_attribute_options' ) ) { + + /** + * Output a list of variation attributes for use in the cart forms. + * + * @param array $args Arguments. + * @since 2.4.0 + */ + function wc_dropdown_variation_attribute_options( $args = array() ) { + $args = wp_parse_args( + apply_filters( 'woocommerce_dropdown_variation_attribute_options_args', $args ), + array( + 'options' => false, + 'attribute' => false, + 'product' => false, + 'selected' => false, + 'name' => '', + 'id' => '', + 'class' => '', + 'show_option_none' => __( 'Choose an option', 'woocommerce' ), + ) + ); + + // Get selected value. + if ( false === $args['selected'] && $args['attribute'] && $args['product'] instanceof WC_Product ) { + $selected_key = 'attribute_' . sanitize_title( $args['attribute'] ); + // phpcs:disable WordPress.Security.NonceVerification.Recommended + $args['selected'] = isset( $_REQUEST[ $selected_key ] ) ? wc_clean( wp_unslash( $_REQUEST[ $selected_key ] ) ) : $args['product']->get_variation_default_attribute( $args['attribute'] ); + // phpcs:enable WordPress.Security.NonceVerification.Recommended + } + + $options = $args['options']; + $product = $args['product']; + $attribute = $args['attribute']; + $name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute ); + $id = $args['id'] ? $args['id'] : sanitize_title( $attribute ); + $class = $args['class']; + $show_option_none = (bool) $args['show_option_none']; + $show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __( 'Choose an option', 'woocommerce' ); // We'll do our best to hide the placeholder, but we'll need to show something when resetting options. + + if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) { + $attributes = $product->get_variation_attributes(); + $options = $attributes[ $attribute ]; + } + + $html = ''; + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo apply_filters( 'woocommerce_dropdown_variation_attribute_options_html', $html, $args ); + } +} + +if ( ! function_exists( 'woocommerce_account_content' ) ) { + + /** + * My Account content output. + */ + function woocommerce_account_content() { + global $wp; + + if ( ! empty( $wp->query_vars ) ) { + foreach ( $wp->query_vars as $key => $value ) { + // Ignore pagename param. + if ( 'pagename' === $key ) { + continue; + } + + if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) { + do_action( 'woocommerce_account_' . $key . '_endpoint', $value ); + return; + } + } + } + + // No endpoint found? Default to dashboard. + wc_get_template( + 'myaccount/dashboard.php', + array( + 'current_user' => get_user_by( 'id', get_current_user_id() ), + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_account_navigation' ) ) { + + /** + * My Account navigation template. + */ + function woocommerce_account_navigation() { + wc_get_template( 'myaccount/navigation.php' ); + } +} + +if ( ! function_exists( 'woocommerce_account_orders' ) ) { + + /** + * My Account > Orders template. + * + * @param int $current_page Current page number. + */ + function woocommerce_account_orders( $current_page ) { + $current_page = empty( $current_page ) ? 1 : absint( $current_page ); + $customer_orders = wc_get_orders( + apply_filters( + 'woocommerce_my_account_my_orders_query', + array( + 'customer' => get_current_user_id(), + 'page' => $current_page, + 'paginate' => true, + ) + ) + ); + + wc_get_template( + 'myaccount/orders.php', + array( + 'current_page' => absint( $current_page ), + 'customer_orders' => $customer_orders, + 'has_orders' => 0 < $customer_orders->total, + ) + ); + } +} + +if ( ! function_exists( 'woocommerce_account_view_order' ) ) { + + /** + * My Account > View order template. + * + * @param int $order_id Order ID. + */ + function woocommerce_account_view_order( $order_id ) { + WC_Shortcode_My_Account::view_order( absint( $order_id ) ); + } +} + +if ( ! function_exists( 'woocommerce_account_downloads' ) ) { + + /** + * My Account > Downloads template. + */ + function woocommerce_account_downloads() { + wc_get_template( 'myaccount/downloads.php' ); + } +} + +if ( ! function_exists( 'woocommerce_account_edit_address' ) ) { + + /** + * My Account > Edit address template. + * + * @param string $type Address type. + */ + function woocommerce_account_edit_address( $type ) { + $type = wc_edit_address_i18n( sanitize_title( $type ), true ); + + WC_Shortcode_My_Account::edit_address( $type ); + } +} + +if ( ! function_exists( 'woocommerce_account_payment_methods' ) ) { + + /** + * My Account > Downloads template. + */ + function woocommerce_account_payment_methods() { + wc_get_template( 'myaccount/payment-methods.php' ); + } +} + +if ( ! function_exists( 'woocommerce_account_add_payment_method' ) ) { + + /** + * My Account > Add payment method template. + */ + function woocommerce_account_add_payment_method() { + WC_Shortcode_My_Account::add_payment_method(); + } +} + +if ( ! function_exists( 'woocommerce_account_edit_account' ) ) { + + /** + * My Account > Edit account template. + */ + function woocommerce_account_edit_account() { + WC_Shortcode_My_Account::edit_account(); + } +} + +if ( ! function_exists( 'wc_no_products_found' ) ) { + + /** + * Handles the loop when no products were found/no product exist. + */ + function wc_no_products_found() { + wc_get_template( 'loop/no-products-found.php' ); + } +} + + +if ( ! function_exists( 'wc_get_email_order_items' ) ) { + /** + * Get HTML for the order items to be shown in emails. + * + * @param WC_Order $order Order object. + * @param array $args Arguments. + * + * @since 3.0.0 + * @return string + */ + function wc_get_email_order_items( $order, $args = array() ) { + ob_start(); + + $defaults = array( + 'show_sku' => false, + 'show_image' => false, + 'image_size' => array( 32, 32 ), + 'plain_text' => false, + 'sent_to_admin' => false, + ); + + $args = wp_parse_args( $args, $defaults ); + $template = $args['plain_text'] ? 'emails/plain/email-order-items.php' : 'emails/email-order-items.php'; + + wc_get_template( + $template, + apply_filters( + 'woocommerce_email_order_items_args', + array( + 'order' => $order, + 'items' => $order->get_items(), + 'show_download_links' => $order->is_download_permitted() && ! $args['sent_to_admin'], + 'show_sku' => $args['show_sku'], + 'show_purchase_note' => $order->is_paid() && ! $args['sent_to_admin'], + 'show_image' => $args['show_image'], + 'image_size' => $args['image_size'], + 'plain_text' => $args['plain_text'], + 'sent_to_admin' => $args['sent_to_admin'], + ) + ) + ); + + return apply_filters( 'woocommerce_email_order_items_table', ob_get_clean(), $order ); + } +} + +if ( ! function_exists( 'wc_display_item_meta' ) ) { + /** + * Display item meta data. + * + * @since 3.0.0 + * @param WC_Order_Item $item Order Item. + * @param array $args Arguments. + * @return string|void + */ + function wc_display_item_meta( $item, $args = array() ) { + $strings = array(); + $html = ''; + $args = wp_parse_args( + $args, + array( + 'before' => '
    • ', + 'after' => '
    ', + 'separator' => '
  • ', + 'echo' => true, + 'autop' => false, + 'label_before' => '', + 'label_after' => ': ', + ) + ); + + foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) { + $value = $args['autop'] ? wp_kses_post( $meta->display_value ) : wp_kses_post( make_clickable( trim( $meta->display_value ) ) ); + $strings[] = $args['label_before'] . wp_kses_post( $meta->display_key ) . $args['label_after'] . $value; + } + + if ( $strings ) { + $html = $args['before'] . implode( $args['separator'], $strings ) . $args['after']; + } + + $html = apply_filters( 'woocommerce_display_item_meta', $html, $item, $args ); + + if ( $args['echo'] ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $html; + } else { + return $html; + } + } +} + +if ( ! function_exists( 'wc_display_item_downloads' ) ) { + /** + * Display item download links. + * + * @since 3.0.0 + * @param WC_Order_Item $item Order Item. + * @param array $args Arguments. + * @return string|void + */ + function wc_display_item_downloads( $item, $args = array() ) { + $strings = array(); + $html = ''; + $args = wp_parse_args( + $args, + array( + 'before' => '
    • ', + 'after' => '
    ', + 'separator' => '
  • ', + 'echo' => true, + 'show_url' => false, + ) + ); + + $downloads = is_object( $item ) && $item->is_type( 'line_item' ) ? $item->get_item_downloads() : array(); + + if ( $downloads ) { + $i = 0; + foreach ( $downloads as $file ) { + $i ++; + + if ( $args['show_url'] ) { + $strings[] = '' . esc_html( $file['name'] ) . ': ' . esc_html( $file['download_url'] ); + } else { + /* translators: %d: downloads count */ + $prefix = count( $downloads ) > 1 ? sprintf( __( 'Download %d', 'woocommerce' ), $i ) : __( 'Download', 'woocommerce' ); + $strings[] = '' . $prefix . ': ' . esc_html( $file['name'] ) . ''; + } + } + } + + if ( $strings ) { + $html = $args['before'] . implode( $args['separator'], $strings ) . $args['after']; + } + + $html = apply_filters( 'woocommerce_display_item_downloads', $html, $item, $args ); + + if ( $args['echo'] ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $html; + } else { + return $html; + } + } +} + +if ( ! function_exists( 'woocommerce_photoswipe' ) ) { + + /** + * Get the shop sidebar template. + */ + function woocommerce_photoswipe() { + if ( current_theme_supports( 'wc-product-gallery-lightbox' ) ) { + wc_get_template( 'single-product/photoswipe.php' ); + } + } +} + +/** + * Outputs a list of product attributes for a product. + * + * @since 3.0.0 + * @param WC_Product $product Product Object. + */ +function wc_display_product_attributes( $product ) { + $product_attributes = array(); + + // Display weight and dimensions before attribute list. + $display_dimensions = apply_filters( 'wc_product_enable_dimensions_display', $product->has_weight() || $product->has_dimensions() ); + + if ( $display_dimensions && $product->has_weight() ) { + $product_attributes['weight'] = array( + 'label' => __( 'Weight', 'woocommerce' ), + 'value' => wc_format_weight( $product->get_weight() ), + ); + } + + if ( $display_dimensions && $product->has_dimensions() ) { + $product_attributes['dimensions'] = array( + 'label' => __( 'Dimensions', 'woocommerce' ), + 'value' => wc_format_dimensions( $product->get_dimensions( false ) ), + ); + } + + // Add product attributes to list. + $attributes = array_filter( $product->get_attributes(), 'wc_attributes_array_filter_visible' ); + + foreach ( $attributes as $attribute ) { + $values = array(); + + if ( $attribute->is_taxonomy() ) { + $attribute_taxonomy = $attribute->get_taxonomy_object(); + $attribute_values = wc_get_product_terms( $product->get_id(), $attribute->get_name(), array( 'fields' => 'all' ) ); + + foreach ( $attribute_values as $attribute_value ) { + $value_name = esc_html( $attribute_value->name ); + + if ( $attribute_taxonomy->attribute_public ) { + $values[] = ''; + } else { + $values[] = $value_name; + } + } + } else { + $values = $attribute->get_options(); + + foreach ( $values as &$value ) { + $value = make_clickable( esc_html( $value ) ); + } + } + + $product_attributes[ 'attribute_' . sanitize_title_with_dashes( $attribute->get_name() ) ] = array( + 'label' => wc_attribute_label( $attribute->get_name() ), + 'value' => apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values ), + ); + } + + /** + * Hook: woocommerce_display_product_attributes. + * + * @since 3.6.0. + * @param array $product_attributes Array of atributes to display; label, value. + * @param WC_Product $product Showing attributes for this product. + */ + $product_attributes = apply_filters( 'woocommerce_display_product_attributes', $product_attributes, $product ); + + wc_get_template( + 'single-product/product-attributes.php', + array( + 'product_attributes' => $product_attributes, + // Legacy params. + 'product' => $product, + 'attributes' => $attributes, + 'display_dimensions' => $display_dimensions, + ) + ); +} + +/** + * Get HTML to show product stock. + * + * @since 3.0.0 + * @param WC_Product $product Product Object. + * @return string + */ +function wc_get_stock_html( $product ) { + $html = ''; + $availability = $product->get_availability(); + + if ( ! empty( $availability['availability'] ) ) { + ob_start(); + + wc_get_template( + 'single-product/stock.php', + array( + 'product' => $product, + 'class' => $availability['class'], + 'availability' => $availability['availability'], + ) + ); + + $html = ob_get_clean(); + } + + if ( has_filter( 'woocommerce_stock_html' ) ) { + wc_deprecated_function( 'The woocommerce_stock_html filter', '', 'woocommerce_get_stock_html' ); + $html = apply_filters( 'woocommerce_stock_html', $html, $availability['availability'], $product ); + } + + return apply_filters( 'woocommerce_get_stock_html', $html, $product ); +} + +/** + * Get HTML for ratings. + * + * @since 3.0.0 + * @param float $rating Rating being shown. + * @param int $count Total number of ratings. + * @return string + */ +function wc_get_rating_html( $rating, $count = 0 ) { + $html = ''; + + if ( 0 < $rating ) { + /* translators: %s: rating */ + $label = sprintf( __( 'Rated %s out of 5', 'woocommerce' ), $rating ); + $html = ''; + } + + return apply_filters( 'woocommerce_product_get_rating_html', $html, $rating, $count ); +} + +/** + * Get HTML for star rating. + * + * @since 3.1.0 + * @param float $rating Rating being shown. + * @param int $count Total number of ratings. + * @return string + */ +function wc_get_star_rating_html( $rating, $count = 0 ) { + $html = ''; + + if ( 0 < $count ) { + /* translators: 1: rating 2: rating count */ + $html .= sprintf( _n( 'Rated %1$s out of 5 based on %2$s customer rating', 'Rated %1$s out of 5 based on %2$s customer ratings', $count, 'woocommerce' ), '' . esc_html( $rating ) . '', '' . esc_html( $count ) . '' ); + } else { + /* translators: %s: rating */ + $html .= sprintf( esc_html__( 'Rated %s out of 5', 'woocommerce' ), '' . esc_html( $rating ) . '' ); + } + + $html .= ''; + + return apply_filters( 'woocommerce_get_star_rating_html', $html, $rating, $count ); +} + +/** + * Returns a 'from' prefix if you want to show where prices start at. + * + * @since 3.0.0 + * @return string + */ +function wc_get_price_html_from_text() { + return apply_filters( 'woocommerce_get_price_html_from_text', '' . _x( 'From:', 'min_price', 'woocommerce' ) . ' ' ); +} + +/** + * Get logout endpoint. + * + * @since 2.6.9 + * + * @param string $redirect Redirect URL. + * + * @return string + */ +function wc_logout_url( $redirect = '' ) { + $redirect = $redirect ? $redirect : apply_filters( 'woocommerce_logout_default_redirect_url', wc_get_page_permalink( 'myaccount' ) ); + + if ( get_option( 'woocommerce_logout_endpoint' ) ) { + return wp_nonce_url( wc_get_endpoint_url( 'customer-logout', '', $redirect ), 'customer-logout' ); + } + + return wp_logout_url( $redirect ); +} + +/** + * Show notice if cart is empty. + * + * @since 3.1.0 + */ +function wc_empty_cart_message() { + echo '

    ' . wp_kses_post( apply_filters( 'wc_empty_cart_message', __( 'Your cart is currently empty.', 'woocommerce' ) ) ) . '

    '; +} + +/** + * Disable search engines indexing core, dynamic, cart/checkout pages. + * + * @since 3.2.0 + */ +function wc_page_noindex() { + if ( is_page( wc_get_page_id( 'cart' ) ) || is_page( wc_get_page_id( 'checkout' ) ) || is_page( wc_get_page_id( 'myaccount' ) ) ) { + wp_no_robots(); + } +} +add_action( 'wp_head', 'wc_page_noindex' ); + +/** + * Get a slug identifying the current theme. + * + * @since 3.3.0 + * @return string + */ +function wc_get_theme_slug_for_templates() { + return apply_filters( 'woocommerce_theme_slug_for_templates', get_option( 'template' ) ); +} + +/** + * Gets and formats a list of cart item data + variations for display on the frontend. + * + * @since 3.3.0 + * @param array $cart_item Cart item object. + * @param bool $flat Should the data be returned flat or in a list. + * @return string + */ +function wc_get_formatted_cart_item_data( $cart_item, $flat = false ) { + $item_data = array(); + + // Variation values are shown only if they are not found in the title as of 3.0. + // This is because variation titles display the attributes. + if ( $cart_item['data']->is_type( 'variation' ) && is_array( $cart_item['variation'] ) ) { + foreach ( $cart_item['variation'] as $name => $value ) { + $taxonomy = wc_attribute_taxonomy_name( str_replace( 'attribute_pa_', '', urldecode( $name ) ) ); + + if ( taxonomy_exists( $taxonomy ) ) { + // If this is a term slug, get the term's nice name. + $term = get_term_by( 'slug', $value, $taxonomy ); + if ( ! is_wp_error( $term ) && $term && $term->name ) { + $value = $term->name; + } + $label = wc_attribute_label( $taxonomy ); + } else { + // If this is a custom option slug, get the options name. + $value = apply_filters( 'woocommerce_variation_option_name', $value, null, $taxonomy, $cart_item['data'] ); + $label = wc_attribute_label( str_replace( 'attribute_', '', $name ), $cart_item['data'] ); + } + + // Check the nicename against the title. + if ( '' === $value || wc_is_attribute_in_product_name( $value, $cart_item['data']->get_name() ) ) { + continue; + } + + $item_data[] = array( + 'key' => $label, + 'value' => $value, + ); + } + } + + // Filter item data to allow 3rd parties to add more to the array. + $item_data = apply_filters( 'woocommerce_get_item_data', $item_data, $cart_item ); + + // Format item data ready to display. + foreach ( $item_data as $key => $data ) { + // Set hidden to true to not display meta on cart. + if ( ! empty( $data['hidden'] ) ) { + unset( $item_data[ $key ] ); + continue; + } + $item_data[ $key ]['key'] = ! empty( $data['key'] ) ? $data['key'] : $data['name']; + $item_data[ $key ]['display'] = ! empty( $data['display'] ) ? $data['display'] : $data['value']; + } + + // Output flat or in list format. + if ( count( $item_data ) > 0 ) { + ob_start(); + + if ( $flat ) { + foreach ( $item_data as $data ) { + echo esc_html( $data['key'] ) . ': ' . wp_kses_post( $data['display'] ) . "\n"; + } + } else { + wc_get_template( 'cart/cart-item-data.php', array( 'item_data' => $item_data ) ); + } + + return ob_get_clean(); + } + + return ''; +} + +/** + * Gets the url to remove an item from the cart. + * + * @since 3.3.0 + * @param string $cart_item_key contains the id of the cart item. + * @return string url to page + */ +function wc_get_cart_remove_url( $cart_item_key ) { + $cart_page_url = wc_get_cart_url(); + return apply_filters( 'woocommerce_get_remove_url', $cart_page_url ? wp_nonce_url( add_query_arg( 'remove_item', $cart_item_key, $cart_page_url ), 'woocommerce-cart' ) : '' ); +} + +/** + * Gets the url to re-add an item into the cart. + * + * @since 3.3.0 + * @param string $cart_item_key Cart item key to undo. + * @return string url to page + */ +function wc_get_cart_undo_url( $cart_item_key ) { + $cart_page_url = wc_get_cart_url(); + + $query_args = array( + 'undo_item' => $cart_item_key, + ); + + return apply_filters( 'woocommerce_get_undo_url', $cart_page_url ? wp_nonce_url( add_query_arg( $query_args, $cart_page_url ), 'woocommerce-cart' ) : '', $cart_item_key ); +} + +/** + * Outputs all queued notices on WC pages. + * + * @since 3.5.0 + */ +function woocommerce_output_all_notices() { + echo '
    '; + wc_print_notices(); + echo '
    '; +} + +/** + * Products RSS Feed. + * + * @deprecated 2.6 + */ +function wc_products_rss_feed() { + wc_deprecated_function( 'wc_products_rss_feed', '2.6' ); +} + +if ( ! function_exists( 'woocommerce_reset_loop' ) ) { + + /** + * Reset the loop's index and columns when we're done outputting a product loop. + * + * @deprecated 3.3 + */ + function woocommerce_reset_loop() { + wc_reset_loop(); + } +} + +if ( ! function_exists( 'woocommerce_product_reviews_tab' ) ) { + /** + * Output the reviews tab content. + * + * @deprecated 2.4.0 Unused. + */ + function woocommerce_product_reviews_tab() { + wc_deprecated_function( 'woocommerce_product_reviews_tab', '2.4' ); + } +} + +/** + * Display pay buttons HTML. + * + * @since 3.9.0 + */ +function wc_get_pay_buttons() { + $supported_gateways = array(); + $available_gateways = WC()->payment_gateways()->get_available_payment_gateways(); + + foreach ( $available_gateways as $gateway ) { + if ( $gateway->supports( 'pay_button' ) ) { + $supported_gateways[] = $gateway->get_pay_button_id(); + } + } + + if ( ! $supported_gateways ) { + return; + } + + echo '
    '; + foreach ( $supported_gateways as $pay_button_id ) { + echo sprintf( '
    ', esc_attr( $pay_button_id ) ); + } + echo '
    '; +} + +// phpcs:enable Generic.Commenting.Todo.TaskFound diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-template-hooks.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-template-hooks.php new file mode 100644 index 0000000..cc0b518 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-template-hooks.php @@ -0,0 +1,314 @@ +query_vars; + + // Put back valid orderby values. + if ( 'menu_order' === $args['orderby'] ) { + $args['orderby'] = 'name'; + $args['force_menu_order_sort'] = true; + } + + if ( 'name_num' === $args['orderby'] ) { + $args['orderby'] = 'name'; + $args['force_numeric_name'] = true; + } + + // When COUNTING, disable custom sorting. + if ( 'count' === $args['fields'] ) { + return; + } + + // Support menu_order arg used in previous versions. + if ( ! empty( $args['menu_order'] ) ) { + $args['order'] = 'DESC' === strtoupper( $args['menu_order'] ) ? 'DESC' : 'ASC'; + $args['force_menu_order_sort'] = true; + } + + if ( ! empty( $args['force_menu_order_sort'] ) ) { + $args['orderby'] = 'meta_value_num'; + $args['meta_key'] = 'order'; // phpcs:ignore + $terms_query->meta_query->parse_query_vars( $args ); + } +} +add_action( 'pre_get_terms', 'wc_change_pre_get_terms', 10, 1 ); + +/** + * Adjust term query to handle custom sorting parameters. + * + * @param array $clauses Clauses. + * @param array $taxonomies Taxonomies. + * @param array $args Arguments. + * @return array + */ +function wc_terms_clauses( $clauses, $taxonomies, $args ) { + global $wpdb; + + // No need to filter when counting. + if ( strpos( $clauses['fields'], 'COUNT(*)' ) !== false ) { + return $clauses; + } + + // Force numeric sort if using name_num custom sorting param. + if ( ! empty( $args['force_numeric_name'] ) ) { + $clauses['orderby'] = str_replace( 'ORDER BY t.name', 'ORDER BY t.name+0', $clauses['orderby'] ); + } + + // For sorting, force left join in case order meta is missing. + if ( ! empty( $args['force_menu_order_sort'] ) ) { + $clauses['join'] = str_replace( "INNER JOIN {$wpdb->termmeta} ON ( t.term_id = {$wpdb->termmeta}.term_id )", "LEFT JOIN {$wpdb->termmeta} ON ( t.term_id = {$wpdb->termmeta}.term_id AND {$wpdb->termmeta}.meta_key='order')", $clauses['join'] ); + $clauses['where'] = str_replace( "{$wpdb->termmeta}.meta_key = 'order'", "( {$wpdb->termmeta}.meta_key = 'order' OR {$wpdb->termmeta}.meta_key IS NULL )", $clauses['where'] ); + $clauses['orderby'] = 'DESC' === $args['order'] ? str_replace( 'meta_value+0', 'meta_value+0 DESC, t.name', $clauses['orderby'] ) : str_replace( 'meta_value+0', 'meta_value+0 ASC, t.name', $clauses['orderby'] ); + } + + return $clauses; +} +add_filter( 'terms_clauses', 'wc_terms_clauses', 99, 3 ); + +/** + * Helper to get cached object terms and filter by field using wp_list_pluck(). + * Works as a cached alternative for wp_get_post_terms() and wp_get_object_terms(). + * + * @since 3.0.0 + * @param int $object_id Object ID. + * @param string $taxonomy Taxonomy slug. + * @param string $field Field name. + * @param string $index_key Index key name. + * @return array + */ +function wc_get_object_terms( $object_id, $taxonomy, $field = null, $index_key = null ) { + // Test if terms exists. get_the_terms() return false when it finds no terms. + $terms = get_the_terms( $object_id, $taxonomy ); + + if ( ! $terms || is_wp_error( $terms ) ) { + return array(); + } + + return is_null( $field ) ? $terms : wp_list_pluck( $terms, $field, $index_key ); +} + +/** + * Cached version of wp_get_post_terms(). + * This is a private function (internal use ONLY). + * + * @since 3.0.0 + * @param int $product_id Product ID. + * @param string $taxonomy Taxonomy slug. + * @param array $args Query arguments. + * @return array + */ +function _wc_get_cached_product_terms( $product_id, $taxonomy, $args = array() ) { + $cache_key = 'wc_' . $taxonomy . md5( wp_json_encode( $args ) ); + $cache_group = WC_Cache_Helper::get_cache_prefix( 'product_' . $product_id ) . $product_id; + $terms = wp_cache_get( $cache_key, $cache_group ); + + if ( false !== $terms ) { + return $terms; + } + + $terms = wp_get_post_terms( $product_id, $taxonomy, $args ); + + wp_cache_add( $cache_key, $terms, $cache_group ); + + return $terms; +} + +/** + * Wrapper used to get terms for a product. + * + * @param int $product_id Product ID. + * @param string $taxonomy Taxonomy slug. + * @param array $args Query arguments. + * @return array + */ +function wc_get_product_terms( $product_id, $taxonomy, $args = array() ) { + if ( ! taxonomy_exists( $taxonomy ) ) { + return array(); + } + + return apply_filters( 'woocommerce_get_product_terms', _wc_get_cached_product_terms( $product_id, $taxonomy, $args ), $product_id, $taxonomy, $args ); +} + +/** + * Sort by name (numeric). + * + * @param WP_Post $a First item to compare. + * @param WP_Post $b Second item to compare. + * @return int + */ +function _wc_get_product_terms_name_num_usort_callback( $a, $b ) { + $a_name = (float) $a->name; + $b_name = (float) $b->name; + + if ( abs( $a_name - $b_name ) < 0.001 ) { + return 0; + } + + return ( $a_name < $b_name ) ? -1 : 1; +} + +/** + * Sort by parent. + * + * @param WP_Post $a First item to compare. + * @param WP_Post $b Second item to compare. + * @return int + */ +function _wc_get_product_terms_parent_usort_callback( $a, $b ) { + if ( $a->parent === $b->parent ) { + return 0; + } + return ( $a->parent < $b->parent ) ? 1 : -1; +} + +/** + * WooCommerce Dropdown categories. + * + * @param array $args Args to control display of dropdown. + */ +function wc_product_dropdown_categories( $args = array() ) { + global $wp_query; + + $args = wp_parse_args( + $args, + array( + 'pad_counts' => 1, + 'show_count' => 1, + 'hierarchical' => 1, + 'hide_empty' => 1, + 'show_uncategorized' => 1, + 'orderby' => 'name', + 'selected' => isset( $wp_query->query_vars['product_cat'] ) ? $wp_query->query_vars['product_cat'] : '', + 'show_option_none' => __( 'Select a category', 'woocommerce' ), + 'option_none_value' => '', + 'value_field' => 'slug', + 'taxonomy' => 'product_cat', + 'name' => 'product_cat', + 'class' => 'dropdown_product_cat', + ) + ); + + if ( 'order' === $args['orderby'] ) { + $args['orderby'] = 'meta_value_num'; + $args['meta_key'] = 'order'; // phpcs:ignore + } + + wp_dropdown_categories( $args ); +} + +/** + * Custom walker for Product Categories. + * + * Previously used by wc_product_dropdown_categories, but wp_dropdown_categories has been fixed in core. + * + * @param mixed ...$args Variable number of parameters to be passed to the walker. + * @return mixed + */ +function wc_walk_category_dropdown_tree( ...$args ) { + if ( ! class_exists( 'WC_Product_Cat_Dropdown_Walker', false ) ) { + include_once WC()->plugin_path() . '/includes/walkers/class-wc-product-cat-dropdown-walker.php'; + } + + // The user's options are the third parameter. + if ( empty( $args[2]['walker'] ) || ! is_a( $args[2]['walker'], 'Walker' ) ) { + $walker = new WC_Product_Cat_Dropdown_Walker(); + } else { + $walker = $args[2]['walker']; + } + + return $walker->walk( ...$args ); +} + +/** + * Migrate data from WC term meta to WP term meta. + * + * When the database is updated to support term meta, migrate WC term meta data across. + * We do this when the new version is >= 34370, and the old version is < 34370 (34370 is when term meta table was added). + * + * @param string $wp_db_version The new $wp_db_version. + * @param string $wp_current_db_version The old (current) $wp_db_version. + */ +function wc_taxonomy_metadata_migrate_data( $wp_db_version, $wp_current_db_version ) { + if ( $wp_db_version >= 34370 && $wp_current_db_version < 34370 ) { + global $wpdb; + if ( $wpdb->query( "INSERT INTO {$wpdb->termmeta} ( term_id, meta_key, meta_value ) SELECT woocommerce_term_id, meta_key, meta_value FROM {$wpdb->prefix}woocommerce_termmeta;" ) ) { + $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_termmeta" ); + } + } +} +add_action( 'wp_upgrade', 'wc_taxonomy_metadata_migrate_data', 10, 2 ); + +/** + * Move a term before the a given element of its hierarchy level. + * + * @param int $the_term Term ID. + * @param int $next_id The id of the next sibling element in save hierarchy level. + * @param string $taxonomy Taxnomy. + * @param int $index Term index (default: 0). + * @param mixed $terms List of terms. (default: null). + * @return int + */ +function wc_reorder_terms( $the_term, $next_id, $taxonomy, $index = 0, $terms = null ) { + if ( ! $terms ) { + $terms = get_terms( $taxonomy, 'hide_empty=0&parent=0&menu_order=ASC' ); + } + if ( empty( $terms ) ) { + return $index; + } + + $id = intval( $the_term->term_id ); + + $term_in_level = false; // Flag: is our term to order in this level of terms. + + foreach ( $terms as $term ) { + $term_id = intval( $term->term_id ); + + if ( $term_id === $id ) { // Our term to order, we skip. + $term_in_level = true; + continue; // Our term to order, we skip. + } + // the nextid of our term to order, lets move our term here. + if ( null !== $next_id && $term_id === $next_id ) { + $index++; + $index = wc_set_term_order( $id, $index, $taxonomy, true ); + } + + // Set order. + $index++; + $index = wc_set_term_order( $term_id, $index, $taxonomy ); + + /** + * After a term has had it's order set. + */ + do_action( 'woocommerce_after_set_term_order', $term, $index, $taxonomy ); + + // If that term has children we walk through them. + $children = get_terms( $taxonomy, "parent={$term_id}&hide_empty=0&menu_order=ASC" ); + if ( ! empty( $children ) ) { + $index = wc_reorder_terms( $the_term, $next_id, $taxonomy, $index, $children ); + } + } + + // No nextid meaning our term is in last position. + if ( $term_in_level && null === $next_id ) { + $index = wc_set_term_order( $id, $index + 1, $taxonomy, true ); + } + + return $index; +} + +/** + * Set the sort order of a term. + * + * @param int $term_id Term ID. + * @param int $index Index. + * @param string $taxonomy Taxonomy. + * @param bool $recursive Recursive (default: false). + * @return int + */ +function wc_set_term_order( $term_id, $index, $taxonomy, $recursive = false ) { + + $term_id = (int) $term_id; + $index = (int) $index; + + update_term_meta( $term_id, 'order', $index ); + + if ( ! $recursive ) { + return $index; + } + + $children = get_terms( $taxonomy, "parent=$term_id&hide_empty=0&menu_order=ASC" ); + + foreach ( $children as $term ) { + $index++; + $index = wc_set_term_order( $term->term_id, $index, $taxonomy, true ); + } + + clean_term_cache( $term_id, $taxonomy ); + + return $index; +} + +/** + * Function for recounting product terms, ignoring hidden products. + * + * @param array $terms List of terms. + * @param object $taxonomy Taxonomy. + * @param bool $callback Callback. + * @param bool $terms_are_term_taxonomy_ids If terms are from term_taxonomy_id column. + */ +function _wc_term_recount( $terms, $taxonomy, $callback = true, $terms_are_term_taxonomy_ids = true ) { + global $wpdb; + + // Standard callback. + if ( $callback ) { + _update_post_term_count( $terms, $taxonomy ); + } + + $exclude_term_ids = array(); + $product_visibility_term_ids = wc_get_product_visibility_term_ids(); + + if ( $product_visibility_term_ids['exclude-from-catalog'] ) { + $exclude_term_ids[] = $product_visibility_term_ids['exclude-from-catalog']; + } + + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && $product_visibility_term_ids['outofstock'] ) { + $exclude_term_ids[] = $product_visibility_term_ids['outofstock']; + } + + $query = array( + 'fields' => " + SELECT COUNT( DISTINCT ID ) FROM {$wpdb->posts} p + ", + 'join' => '', + 'where' => " + WHERE 1=1 + AND p.post_status = 'publish' + AND p.post_type = 'product' + + ", + ); + + if ( count( $exclude_term_ids ) ) { + $query['join'] .= " LEFT JOIN ( SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN ( " . implode( ',', array_map( 'absint', $exclude_term_ids ) ) . ' ) ) AS exclude_join ON exclude_join.object_id = p.ID'; + $query['where'] .= ' AND exclude_join.object_id IS NULL'; + } + + // Pre-process term taxonomy ids. + if ( ! $terms_are_term_taxonomy_ids ) { + // We passed in an array of TERMS in format id=>parent. + $terms = array_filter( (array) array_keys( $terms ) ); + } else { + // If we have term taxonomy IDs we need to get the term ID. + $term_taxonomy_ids = $terms; + $terms = array(); + foreach ( $term_taxonomy_ids as $term_taxonomy_id ) { + $term = get_term_by( 'term_taxonomy_id', $term_taxonomy_id, $taxonomy->name ); + $terms[] = $term->term_id; + } + } + + // Exit if we have no terms to count. + if ( empty( $terms ) ) { + return; + } + + // Ancestors need counting. + if ( is_taxonomy_hierarchical( $taxonomy->name ) ) { + foreach ( $terms as $term_id ) { + $terms = array_merge( $terms, get_ancestors( $term_id, $taxonomy->name ) ); + } + } + + // Unique terms only. + $terms = array_unique( $terms ); + + // Count the terms. + foreach ( $terms as $term_id ) { + $terms_to_count = array( absint( $term_id ) ); + + if ( is_taxonomy_hierarchical( $taxonomy->name ) ) { + // We need to get the $term's hierarchy so we can count its children too. + $children = get_term_children( $term_id, $taxonomy->name ); + + if ( $children && ! is_wp_error( $children ) ) { + $terms_to_count = array_unique( array_map( 'absint', array_merge( $terms_to_count, $children ) ) ); + } + } + + // Generate term query. + $term_query = $query; + $term_query['join'] .= " INNER JOIN ( SELECT object_id FROM {$wpdb->term_relationships} INNER JOIN {$wpdb->term_taxonomy} using( term_taxonomy_id ) WHERE term_id IN ( " . implode( ',', array_map( 'absint', $terms_to_count ) ) . ' ) ) AS include_join ON include_join.object_id = p.ID'; + + // Get the count. + $count = $wpdb->get_var( implode( ' ', $term_query ) ); // WPCS: unprepared SQL ok. + + // Update the count. + update_term_meta( $term_id, 'product_count_' . $taxonomy->name, absint( $count ) ); + } + + delete_transient( 'wc_term_counts' ); +} + +/** + * Recount terms after the stock amount changes. + * + * @param int $product_id Product ID. + */ +function wc_recount_after_stock_change( $product_id ) { + if ( 'yes' !== get_option( 'woocommerce_hide_out_of_stock_items' ) ) { + return; + } + + $product_terms = get_the_terms( $product_id, 'product_cat' ); + + if ( $product_terms ) { + $product_cats = array(); + + foreach ( $product_terms as $term ) { + $product_cats[ $term->term_id ] = $term->parent; + } + + _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), false, false ); + } + + $product_terms = get_the_terms( $product_id, 'product_tag' ); + + if ( $product_terms ) { + $product_tags = array(); + + foreach ( $product_terms as $term ) { + $product_tags[ $term->term_id ] = $term->parent; + } + + _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), false, false ); + } +} +add_action( 'woocommerce_product_set_stock_status', 'wc_recount_after_stock_change' ); + + +/** + * Overrides the original term count for product categories and tags with the product count. + * that takes catalog visibility into account. + * + * @param array $terms List of terms. + * @param string|array $taxonomies Single taxonomy or list of taxonomies. + * @return array + */ +function wc_change_term_counts( $terms, $taxonomies ) { + if ( is_admin() || is_ajax() ) { + return $terms; + } + + if ( ! isset( $taxonomies[0] ) || ! in_array( $taxonomies[0], apply_filters( 'woocommerce_change_term_counts', array( 'product_cat', 'product_tag' ) ), true ) ) { + return $terms; + } + + $o_term_counts = get_transient( 'wc_term_counts' ); + $term_counts = $o_term_counts; + + foreach ( $terms as &$term ) { + if ( is_object( $term ) ) { + $term_counts[ $term->term_id ] = isset( $term_counts[ $term->term_id ] ) ? $term_counts[ $term->term_id ] : get_term_meta( $term->term_id, 'product_count_' . $taxonomies[0], true ); + + if ( '' !== $term_counts[ $term->term_id ] ) { + $term->count = absint( $term_counts[ $term->term_id ] ); + } + } + } + + // Update transient. + if ( $term_counts !== $o_term_counts ) { + set_transient( 'wc_term_counts', $term_counts, DAY_IN_SECONDS * 30 ); + } + + return $terms; +} +add_filter( 'get_terms', 'wc_change_term_counts', 10, 2 ); + +/** + * Return products in a given term, and cache value. + * + * To keep in sync, product_count will be cleared on "set_object_terms". + * + * @param int $term_id Term ID. + * @param string $taxonomy Taxonomy. + * @return array + */ +function wc_get_term_product_ids( $term_id, $taxonomy ) { + $product_ids = get_term_meta( $term_id, 'product_ids', true ); + + if ( false === $product_ids || ! is_array( $product_ids ) ) { + $product_ids = get_objects_in_term( $term_id, $taxonomy ); + update_term_meta( $term_id, 'product_ids', $product_ids ); + } + + return $product_ids; +} + +/** + * When a post is updated and terms recounted (called by _update_post_term_count), clear the ids. + * + * @param int $object_id Object ID. + * @param array $terms An array of object terms. + * @param array $tt_ids An array of term taxonomy IDs. + * @param string $taxonomy Taxonomy slug. + * @param bool $append Whether to append new terms to the old terms. + * @param array $old_tt_ids Old array of term taxonomy IDs. + */ +function wc_clear_term_product_ids( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) { + foreach ( $old_tt_ids as $term_id ) { + delete_term_meta( $term_id, 'product_ids' ); + } + foreach ( $tt_ids as $term_id ) { + delete_term_meta( $term_id, 'product_ids' ); + } +} +add_action( 'set_object_terms', 'wc_clear_term_product_ids', 10, 6 ); + +/** + * Get full list of product visibilty term ids. + * + * @since 3.0.0 + * @return int[] + */ +function wc_get_product_visibility_term_ids() { + if ( ! taxonomy_exists( 'product_visibility' ) ) { + wc_doing_it_wrong( __FUNCTION__, 'wc_get_product_visibility_term_ids should not be called before taxonomies are registered (woocommerce_after_register_post_type action).', '3.1' ); + return array(); + } + return array_map( + 'absint', + wp_parse_args( + wp_list_pluck( + get_terms( + array( + 'taxonomy' => 'product_visibility', + 'hide_empty' => false, + ) + ), + 'term_taxonomy_id', + 'name' + ), + array( + 'exclude-from-catalog' => 0, + 'exclude-from-search' => 0, + 'featured' => 0, + 'outofstock' => 0, + 'rated-1' => 0, + 'rated-2' => 0, + 'rated-3' => 0, + 'rated-4' => 0, + 'rated-5' => 0, + ) + ) + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-update-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-update-functions.php new file mode 100644 index 0000000..132f5d6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-update-functions.php @@ -0,0 +1,2220 @@ +get_results( "SELECT meta_value, meta_id, post_id FROM {$wpdb->postmeta} WHERE meta_key = '_file_path' AND meta_value != '';" ); + + if ( $existing_file_paths ) { + + foreach ( $existing_file_paths as $existing_file_path ) { + + $old_file_path = trim( $existing_file_path->meta_value ); + + if ( ! empty( $old_file_path ) ) { + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize + $file_paths = serialize( array( md5( $old_file_path ) => $old_file_path ) ); + + $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = '_file_paths', meta_value = %s WHERE meta_id = %d", $file_paths, $existing_file_path->meta_id ) ); + + $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}woocommerce_downloadable_product_permissions SET download_id = %s WHERE product_id = %d", md5( $old_file_path ), $existing_file_path->post_id ) ); + + } + } + } +} + +/** + * Update permalinks for 2.0 + * + * @return void + */ +function wc_update_200_permalinks() { + // Setup default permalinks if shop page is defined. + $permalinks = get_option( 'woocommerce_permalinks' ); + $shop_page_id = wc_get_page_id( 'shop' ); + + if ( empty( $permalinks ) && $shop_page_id > 0 ) { + + $base_slug = $shop_page_id > 0 && get_post( $shop_page_id ) ? get_page_uri( $shop_page_id ) : 'shop'; + + $category_base = 'yes' === get_option( 'woocommerce_prepend_shop_page_to_urls' ) ? trailingslashit( $base_slug ) : ''; + $category_slug = get_option( 'woocommerce_product_category_slug' ) ? get_option( 'woocommerce_product_category_slug' ) : _x( 'product-category', 'slug', 'woocommerce' ); + $tag_slug = get_option( 'woocommerce_product_tag_slug' ) ? get_option( 'woocommerce_product_tag_slug' ) : _x( 'product-tag', 'slug', 'woocommerce' ); + + if ( 'yes' === get_option( 'woocommerce_prepend_shop_page_to_products' ) ) { + $product_base = trailingslashit( $base_slug ); + } else { + $product_slug = get_option( 'woocommerce_product_slug' ); + if ( false !== $product_slug && ! empty( $product_slug ) ) { + $product_base = trailingslashit( $product_slug ); + } else { + $product_base = trailingslashit( _x( 'product', 'slug', 'woocommerce' ) ); + } + } + + if ( 'yes' === get_option( 'woocommerce_prepend_category_to_products' ) ) { + $product_base .= trailingslashit( '%product_cat%' ); + } + + $permalinks = array( + 'product_base' => untrailingslashit( $product_base ), + 'category_base' => untrailingslashit( $category_base . $category_slug ), + 'attribute_base' => untrailingslashit( $category_base ), + 'tag_base' => untrailingslashit( $category_base . $tag_slug ), + ); + + update_option( 'woocommerce_permalinks', $permalinks ); + } +} + +/** + * Update sub-category display options for 2.0 + * + * @return void + */ +function wc_update_200_subcat_display() { + // Update subcat display settings. + if ( 'yes' === get_option( 'woocommerce_shop_show_subcategories' ) ) { + if ( 'yes' === get_option( 'woocommerce_hide_products_when_showing_subcategories' ) ) { + update_option( 'woocommerce_shop_page_display', 'subcategories' ); + } else { + update_option( 'woocommerce_shop_page_display', 'both' ); + } + } + + if ( 'yes' === get_option( 'woocommerce_show_subcategories' ) ) { + if ( 'yes' === get_option( 'woocommerce_hide_products_when_showing_subcategories' ) ) { + update_option( 'woocommerce_category_archive_display', 'subcategories' ); + } else { + update_option( 'woocommerce_category_archive_display', 'both' ); + } + } +} + +/** + * Update tax rates for 2.0 + * + * @return void + */ +function wc_update_200_taxrates() { + global $wpdb; + + // Update tax rates. + $loop = 0; + $tax_rates = get_option( 'woocommerce_tax_rates' ); + + if ( $tax_rates ) { + foreach ( $tax_rates as $tax_rate ) { + + foreach ( $tax_rate['countries'] as $country => $states ) { + + $states = array_reverse( $states ); + + foreach ( $states as $state ) { + + if ( '*' === $state ) { + $state = ''; + } + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rates', + array( + 'tax_rate_country' => $country, + 'tax_rate_state' => $state, + 'tax_rate' => $tax_rate['rate'], + 'tax_rate_name' => $tax_rate['label'], + 'tax_rate_priority' => 1, + 'tax_rate_compound' => ( 'yes' === $tax_rate['compound'] ) ? 1 : 0, + 'tax_rate_shipping' => ( 'yes' === $tax_rate['shipping'] ) ? 1 : 0, + 'tax_rate_order' => $loop, + 'tax_rate_class' => $tax_rate['class'], + ) + ); + + $loop++; + } + } + } + } + + $local_tax_rates = get_option( 'woocommerce_local_tax_rates' ); + + if ( $local_tax_rates ) { + foreach ( $local_tax_rates as $tax_rate ) { + + $location_type = ( 'postcode' === $tax_rate['location_type'] ) ? 'postcode' : 'city'; + + if ( '*' === $tax_rate['state'] ) { + $tax_rate['state'] = ''; + } + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rates', + array( + 'tax_rate_country' => $tax_rate['country'], + 'tax_rate_state' => $tax_rate['state'], + 'tax_rate' => $tax_rate['rate'], + 'tax_rate_name' => $tax_rate['label'], + 'tax_rate_priority' => 2, + 'tax_rate_compound' => ( 'yes' === $tax_rate['compound'] ) ? 1 : 0, + 'tax_rate_shipping' => ( 'yes' === $tax_rate['shipping'] ) ? 1 : 0, + 'tax_rate_order' => $loop, + 'tax_rate_class' => $tax_rate['class'], + ) + ); + + $tax_rate_id = $wpdb->insert_id; + + if ( $tax_rate['locations'] ) { + foreach ( $tax_rate['locations'] as $location ) { + + $wpdb->insert( + $wpdb->prefix . 'woocommerce_tax_rate_locations', + array( + 'location_code' => $location, + 'tax_rate_id' => $tax_rate_id, + 'location_type' => $location_type, + ) + ); + + } + } + + $loop++; + } + } + + update_option( 'woocommerce_tax_rates_backup', $tax_rates ); + update_option( 'woocommerce_local_tax_rates_backup', $local_tax_rates ); + delete_option( 'woocommerce_tax_rates' ); + delete_option( 'woocommerce_local_tax_rates' ); +} + +/** + * Update order item line items for 2.0 + * + * @return void + */ +function wc_update_200_line_items() { + global $wpdb; + + // Now its time for the massive update to line items - move them to the new DB tables. + // Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_items' WHERE meta_key = '_order_items_old'. + $order_item_rows = $wpdb->get_results( + "SELECT meta_value, post_id FROM {$wpdb->postmeta} WHERE meta_key = '_order_items'" + ); + + foreach ( $order_item_rows as $order_item_row ) { + + $order_items = (array) maybe_unserialize( $order_item_row->meta_value ); + + foreach ( $order_items as $order_item ) { + + if ( ! isset( $order_item['line_total'] ) && isset( $order_item['taxrate'] ) && isset( $order_item['cost'] ) ) { + $order_item['line_tax'] = number_format( ( $order_item['cost'] * $order_item['qty'] ) * ( $order_item['taxrate'] / 100 ), 2, '.', '' ); + $order_item['line_total'] = $order_item['cost'] * $order_item['qty']; + $order_item['line_subtotal_tax'] = $order_item['line_tax']; + $order_item['line_subtotal'] = $order_item['line_total']; + } + + $order_item['line_tax'] = isset( $order_item['line_tax'] ) ? $order_item['line_tax'] : 0; + $order_item['line_total'] = isset( $order_item['line_total'] ) ? $order_item['line_total'] : 0; + $order_item['line_subtotal_tax'] = isset( $order_item['line_subtotal_tax'] ) ? $order_item['line_subtotal_tax'] : 0; + $order_item['line_subtotal'] = isset( $order_item['line_subtotal'] ) ? $order_item['line_subtotal'] : 0; + + $item_id = wc_add_order_item( + $order_item_row->post_id, + array( + 'order_item_name' => $order_item['name'], + 'order_item_type' => 'line_item', + ) + ); + + // Add line item meta. + if ( $item_id ) { + wc_add_order_item_meta( $item_id, '_qty', absint( $order_item['qty'] ) ); + wc_add_order_item_meta( $item_id, '_tax_class', $order_item['tax_class'] ); + wc_add_order_item_meta( $item_id, '_product_id', $order_item['id'] ); + wc_add_order_item_meta( $item_id, '_variation_id', $order_item['variation_id'] ); + wc_add_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( $order_item['line_subtotal'] ) ); + wc_add_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( $order_item['line_subtotal_tax'] ) ); + wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( $order_item['line_total'] ) ); + wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $order_item['line_tax'] ) ); + + $meta_rows = array(); + + // Insert meta. + if ( ! empty( $order_item['item_meta'] ) ) { + foreach ( $order_item['item_meta'] as $key => $meta ) { + // Backwards compatibility. + if ( is_array( $meta ) && isset( $meta['meta_name'] ) ) { + $meta_rows[] = '(' . $item_id . ',"' . esc_sql( $meta['meta_name'] ) . '","' . esc_sql( $meta['meta_value'] ) . '")'; + } else { + $meta_rows[] = '(' . $item_id . ',"' . esc_sql( $key ) . '","' . esc_sql( $meta ) . '")'; + } + } + } + + // Insert meta rows at once. + if ( count( $meta_rows ) > 0 ) { + $wpdb->query( + $wpdb->prepare( + "INSERT INTO {$wpdb->prefix}woocommerce_order_itemmeta ( order_item_id, meta_key, meta_value ) + VALUES " . implode( ',', $meta_rows ) . ';', // @codingStandardsIgnoreLine + $order_item_row->post_id + ) + ); + } + + // Delete from DB (rename). + $wpdb->query( + $wpdb->prepare( + "UPDATE {$wpdb->postmeta} + SET meta_key = '_order_items_old' + WHERE meta_key = '_order_items' + AND post_id = %d", + $order_item_row->post_id + ) + ); + } + + unset( $meta_rows, $item_id, $order_item ); + } + } + + // Do the same kind of update for order_taxes - move to lines. + // Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_taxes' WHERE meta_key = '_order_taxes_old'. + $order_tax_rows = $wpdb->get_results( + "SELECT meta_value, post_id FROM {$wpdb->postmeta} + WHERE meta_key = '_order_taxes'" + ); + + foreach ( $order_tax_rows as $order_tax_row ) { + + $order_taxes = (array) maybe_unserialize( $order_tax_row->meta_value ); + + if ( ! empty( $order_taxes ) ) { + foreach ( $order_taxes as $order_tax ) { + + if ( ! isset( $order_tax['label'] ) || ! isset( $order_tax['cart_tax'] ) || ! isset( $order_tax['shipping_tax'] ) ) { + continue; + } + + $item_id = wc_add_order_item( + $order_tax_row->post_id, + array( + 'order_item_name' => $order_tax['label'], + 'order_item_type' => 'tax', + ) + ); + + // Add line item meta. + if ( $item_id ) { + wc_add_order_item_meta( $item_id, 'compound', absint( isset( $order_tax['compound'] ) ? $order_tax['compound'] : 0 ) ); + wc_add_order_item_meta( $item_id, 'tax_amount', wc_clean( $order_tax['cart_tax'] ) ); + wc_add_order_item_meta( $item_id, 'shipping_tax_amount', wc_clean( $order_tax['shipping_tax'] ) ); + } + + // Delete from DB (rename). + $wpdb->query( + $wpdb->prepare( + "UPDATE {$wpdb->postmeta} + SET meta_key = '_order_taxes_old' + WHERE meta_key = '_order_taxes' + AND post_id = %d", + $order_tax_row->post_id + ) + ); + + unset( $tax_amount ); + } + } + } +} + +/** + * Update image settings for 2.0 + * + * @return void + */ +function wc_update_200_images() { + // Grab the pre 2.0 Image options and use to populate the new image options settings, + // cleaning up afterwards like nice people do. + foreach ( array( 'catalog', 'single', 'thumbnail' ) as $value ) { + + $old_settings = array_filter( + array( + 'width' => get_option( 'woocommerce_' . $value . '_image_width' ), + 'height' => get_option( 'woocommerce_' . $value . '_image_height' ), + 'crop' => get_option( 'woocommerce_' . $value . '_image_crop' ), + ) + ); + + if ( ! empty( $old_settings ) && update_option( 'shop_' . $value . '_image_size', $old_settings ) ) { + + delete_option( 'woocommerce_' . $value . '_image_width' ); + delete_option( 'woocommerce_' . $value . '_image_height' ); + delete_option( 'woocommerce_' . $value . '_image_crop' ); + + } + } +} + +/** + * Update DB version for 2.0 + * + * @return void + */ +function wc_update_200_db_version() { + WC_Install::update_db_version( '2.0.0' ); +} + +/** + * Update Brazilian States for 2.0.9 + * + * @return void + */ +function wc_update_209_brazillian_state() { + global $wpdb; + + // phpcs:disable WordPress.DB.SlowDBQuery + + // Update brazillian state codes. + $wpdb->update( + $wpdb->postmeta, + array( + 'meta_value' => 'BA', + ), + array( + 'meta_key' => '_billing_state', + 'meta_value' => 'BH', + ) + ); + $wpdb->update( + $wpdb->postmeta, + array( + 'meta_value' => 'BA', + ), + array( + 'meta_key' => '_shipping_state', + 'meta_value' => 'BH', + ) + ); + $wpdb->update( + $wpdb->usermeta, + array( + 'meta_value' => 'BA', + ), + array( + 'meta_key' => 'billing_state', + 'meta_value' => 'BH', + ) + ); + $wpdb->update( + $wpdb->usermeta, + array( + 'meta_value' => 'BA', + ), + array( + 'meta_key' => 'shipping_state', + 'meta_value' => 'BH', + ) + ); + + // phpcs:enable WordPress.DB.SlowDBQuery +} + +/** + * Update DB version for 2.0.9 + * + * @return void + */ +function wc_update_209_db_version() { + WC_Install::update_db_version( '2.0.9' ); +} + +/** + * Remove pages for 2.1 + * + * @return void + */ +function wc_update_210_remove_pages() { + // Pages no longer used. + wp_trash_post( get_option( 'woocommerce_pay_page_id' ) ); + wp_trash_post( get_option( 'woocommerce_thanks_page_id' ) ); + wp_trash_post( get_option( 'woocommerce_view_order_page_id' ) ); + wp_trash_post( get_option( 'woocommerce_change_password_page_id' ) ); + wp_trash_post( get_option( 'woocommerce_edit_address_page_id' ) ); + wp_trash_post( get_option( 'woocommerce_lost_password_page_id' ) ); +} + +/** + * Update file paths to support multiple files for 2.1 + * + * @return void + */ +function wc_update_210_file_paths() { + global $wpdb; + + // Upgrade file paths to support multiple file paths + names etc. + $existing_file_paths = $wpdb->get_results( "SELECT meta_value, meta_id FROM {$wpdb->postmeta} WHERE meta_key = '_file_paths' AND meta_value != '';" ); + + if ( $existing_file_paths ) { + + foreach ( $existing_file_paths as $existing_file_path ) { + + $needs_update = false; + $new_value = array(); + $value = maybe_unserialize( trim( $existing_file_path->meta_value ) ); + + if ( $value ) { + foreach ( $value as $key => $file ) { + if ( ! is_array( $file ) ) { + $needs_update = true; + $new_value[ $key ] = array( + 'file' => $file, + 'name' => wc_get_filename_from_url( $file ), + ); + } else { + $new_value[ $key ] = $file; + } + } + if ( $needs_update ) { + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize + $new_value = serialize( $new_value ); + + $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = %s, meta_value = %s WHERE meta_id = %d", '_downloadable_files', $new_value, $existing_file_path->meta_id ) ); + } + } + } + } +} + +/** + * Update DB version for 2.1 + * + * @return void + */ +function wc_update_210_db_version() { + WC_Install::update_db_version( '2.1.0' ); +} + +/** + * Update shipping options for 2.2 + * + * @return void + */ +function wc_update_220_shipping() { + $woocommerce_ship_to_destination = 'shipping'; + + if ( get_option( 'woocommerce_ship_to_billing_address_only' ) === 'yes' ) { + $woocommerce_ship_to_destination = 'billing_only'; + } elseif ( get_option( 'woocommerce_ship_to_billing' ) === 'yes' ) { + $woocommerce_ship_to_destination = 'billing'; + } + + add_option( 'woocommerce_ship_to_destination', $woocommerce_ship_to_destination, '', 'no' ); +} + +/** + * Update order statuses for 2.2 + * + * @return void + */ +function wc_update_220_order_status() { + global $wpdb; + $wpdb->query( + "UPDATE {$wpdb->posts} as posts + LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id + LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id ) + LEFT JOIN {$wpdb->terms} AS term USING( term_id ) + SET posts.post_status = 'wc-pending' + WHERE posts.post_type = 'shop_order' + AND posts.post_status = 'publish' + AND tax.taxonomy = 'shop_order_status' + AND term.slug LIKE 'pending%';" + ); + $wpdb->query( + "UPDATE {$wpdb->posts} as posts + LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id + LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id ) + LEFT JOIN {$wpdb->terms} AS term USING( term_id ) + SET posts.post_status = 'wc-processing' + WHERE posts.post_type = 'shop_order' + AND posts.post_status = 'publish' + AND tax.taxonomy = 'shop_order_status' + AND term.slug LIKE 'processing%';" + ); + $wpdb->query( + "UPDATE {$wpdb->posts} as posts + LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id + LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id ) + LEFT JOIN {$wpdb->terms} AS term USING( term_id ) + SET posts.post_status = 'wc-on-hold' + WHERE posts.post_type = 'shop_order' + AND posts.post_status = 'publish' + AND tax.taxonomy = 'shop_order_status' + AND term.slug LIKE 'on-hold%';" + ); + $wpdb->query( + "UPDATE {$wpdb->posts} as posts + LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id + LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id ) + LEFT JOIN {$wpdb->terms} AS term USING( term_id ) + SET posts.post_status = 'wc-completed' + WHERE posts.post_type = 'shop_order' + AND posts.post_status = 'publish' + AND tax.taxonomy = 'shop_order_status' + AND term.slug LIKE 'completed%';" + ); + $wpdb->query( + "UPDATE {$wpdb->posts} as posts + LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id + LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id ) + LEFT JOIN {$wpdb->terms} AS term USING( term_id ) + SET posts.post_status = 'wc-cancelled' + WHERE posts.post_type = 'shop_order' + AND posts.post_status = 'publish' + AND tax.taxonomy = 'shop_order_status' + AND term.slug LIKE 'cancelled%';" + ); + $wpdb->query( + "UPDATE {$wpdb->posts} as posts + LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id + LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id ) + LEFT JOIN {$wpdb->terms} AS term USING( term_id ) + SET posts.post_status = 'wc-refunded' + WHERE posts.post_type = 'shop_order' + AND posts.post_status = 'publish' + AND tax.taxonomy = 'shop_order_status' + AND term.slug LIKE 'refunded%';" + ); + $wpdb->query( + "UPDATE {$wpdb->posts} as posts + LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id + LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id ) + LEFT JOIN {$wpdb->terms} AS term USING( term_id ) + SET posts.post_status = 'wc-failed' + WHERE posts.post_type = 'shop_order' + AND posts.post_status = 'publish' + AND tax.taxonomy = 'shop_order_status' + AND term.slug LIKE 'failed%';" + ); +} + +/** + * Update variations for 2.2 + * + * @return void + */ +function wc_update_220_variations() { + global $wpdb; + // Update variations which manage stock. + $update_variations = $wpdb->get_results( + "SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent FROM {$wpdb->posts} as posts + LEFT OUTER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id AND postmeta.meta_key = '_stock' + LEFT OUTER JOIN {$wpdb->postmeta} as postmeta2 ON posts.ID = postmeta2.post_id AND postmeta2.meta_key = '_manage_stock' + WHERE posts.post_type = 'product_variation' + AND postmeta.meta_value IS NOT NULL + AND postmeta.meta_value != '' + AND postmeta2.meta_value IS NULL" + ); + + foreach ( $update_variations as $variation ) { + $parent_backorders = get_post_meta( $variation->variation_parent, '_backorders', true ); + add_post_meta( $variation->variation_id, '_manage_stock', 'yes', true ); + add_post_meta( $variation->variation_id, '_backorders', $parent_backorders ? $parent_backorders : 'no', true ); + } +} + +/** + * Update attributes for 2.2 + * + * @return void + */ +function wc_update_220_attributes() { + global $wpdb; + // Update taxonomy names with correct sanitized names. + $attribute_taxonomies = $wpdb->get_results( 'SELECT attribute_name, attribute_id FROM ' . $wpdb->prefix . 'woocommerce_attribute_taxonomies' ); + + foreach ( $attribute_taxonomies as $attribute_taxonomy ) { + $sanitized_attribute_name = wc_sanitize_taxonomy_name( $attribute_taxonomy->attribute_name ); + if ( $sanitized_attribute_name !== $attribute_taxonomy->attribute_name ) { + if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT 1=1 FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_name = %s;", $sanitized_attribute_name ) ) ) { + // Update attribute. + $wpdb->update( + "{$wpdb->prefix}woocommerce_attribute_taxonomies", + array( + 'attribute_name' => $sanitized_attribute_name, + ), + array( + 'attribute_id' => $attribute_taxonomy->attribute_id, + ) + ); + + // Update terms. + $wpdb->update( + $wpdb->term_taxonomy, + array( 'taxonomy' => wc_attribute_taxonomy_name( $sanitized_attribute_name ) ), + array( 'taxonomy' => 'pa_' . $attribute_taxonomy->attribute_name ) + ); + } + } + } + + delete_transient( 'wc_attribute_taxonomies' ); + WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' ); +} + +/** + * Update DB version for 2.2 + * + * @return void + */ +function wc_update_220_db_version() { + WC_Install::update_db_version( '2.2.0' ); +} + +/** + * Update options for 2.3 + * + * @return void + */ +function wc_update_230_options() { + // _money_spent and _order_count may be out of sync - clear them + delete_metadata( 'user', 0, '_money_spent', '', true ); + delete_metadata( 'user', 0, '_order_count', '', true ); + + // To prevent taxes being hidden when using a default 'no address' in a store with tax inc prices, set the woocommerce_default_customer_address to use the store base address by default. + if ( '' === get_option( 'woocommerce_default_customer_address', false ) && wc_prices_include_tax() ) { + update_option( 'woocommerce_default_customer_address', 'base' ); + } +} + +/** + * Update DB version for 2.3 + * + * @return void + */ +function wc_update_230_db_version() { + WC_Install::update_db_version( '2.3.0' ); +} + +/** + * Update calc discount options for 2.4 + * + * @return void + */ +function wc_update_240_options() { + /** + * Coupon discount calculations. + * Maintain the old coupon logic for upgrades. + */ + update_option( 'woocommerce_calc_discounts_sequentially', 'yes' ); +} + +/** + * Update shipping methods for 2.4 + * + * @return void + */ +function wc_update_240_shipping_methods() { + /** + * Flat Rate Shipping. + * Update legacy options to new math based options. + */ + $shipping_methods = array( + 'woocommerce_flat_rates' => new WC_Shipping_Legacy_Flat_Rate(), + 'woocommerce_international_delivery_flat_rates' => new WC_Shipping_Legacy_International_Delivery(), + ); + foreach ( $shipping_methods as $flat_rate_option_key => $shipping_method ) { + // Stop this running more than once if routine is repeated. + if ( version_compare( $shipping_method->get_option( 'version', 0 ), '2.4.0', '<' ) ) { + $shipping_classes = WC()->shipping()->get_shipping_classes(); + $has_classes = count( $shipping_classes ) > 0; + $cost_key = $has_classes ? 'no_class_cost' : 'cost'; + $min_fee = $shipping_method->get_option( 'minimum_fee' ); + $math_cost_strings = array( + 'cost' => array(), + 'no_class_cost' => array(), + ); + + $math_cost_strings[ $cost_key ][] = $shipping_method->get_option( 'cost' ); + $fee = $shipping_method->get_option( 'fee' ); + + if ( $fee ) { + $math_cost_strings[ $cost_key ][] = strstr( $fee, '%' ) ? '[fee percent="' . str_replace( '%', '', $fee ) . '" min="' . esc_attr( $min_fee ) . '"]' : $fee; + } + + foreach ( $shipping_classes as $shipping_class ) { + $rate_key = 'class_cost_' . $shipping_class->slug; + $math_cost_strings[ $rate_key ] = $math_cost_strings['no_class_cost']; + } + + $flat_rates = array_filter( (array) get_option( $flat_rate_option_key, array() ) ); + + if ( $flat_rates ) { + foreach ( $flat_rates as $shipping_class => $rate ) { + $rate_key = 'class_cost_' . $shipping_class; + if ( $rate['cost'] || $rate['fee'] ) { + $math_cost_strings[ $rate_key ][] = $rate['cost']; + $math_cost_strings[ $rate_key ][] = strstr( $rate['fee'], '%' ) ? '[fee percent="' . str_replace( '%', '', $rate['fee'] ) . '" min="' . esc_attr( $min_fee ) . '"]' : $rate['fee']; + } + } + } + + if ( 'item' === $shipping_method->type ) { + foreach ( $math_cost_strings as $key => $math_cost_string ) { + $math_cost_strings[ $key ] = array_filter( array_map( 'trim', $math_cost_strings[ $key ] ) ); + if ( ! empty( $math_cost_strings[ $key ] ) ) { + $last_key = max( 0, count( $math_cost_strings[ $key ] ) - 1 ); + $math_cost_strings[ $key ][0] = '( ' . $math_cost_strings[ $key ][0]; + $math_cost_strings[ $key ][ $last_key ] .= ' ) * [qty]'; + } + } + } + + $math_cost_strings['cost'][] = $shipping_method->get_option( 'cost_per_order' ); + + // Save settings. + foreach ( $math_cost_strings as $option_id => $math_cost_string ) { + $shipping_method->settings[ $option_id ] = implode( ' + ', array_filter( $math_cost_string ) ); + } + + $shipping_method->settings['version'] = '2.4.0'; + $shipping_method->settings['type'] = 'item' === $shipping_method->settings['type'] ? 'class' : $shipping_method->settings['type']; + + update_option( $shipping_method->plugin_id . $shipping_method->id . '_settings', $shipping_method->settings ); + } + } +} + +/** + * Update API keys for 2.4 + * + * @return void + */ +function wc_update_240_api_keys() { + global $wpdb; + /** + * Update the old user API keys to the new Apps keys. + */ + $api_users = $wpdb->get_results( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = 'woocommerce_api_consumer_key'" ); + $apps_keys = array(); + + // Get user data. + foreach ( $api_users as $_user ) { + $user = get_userdata( $_user->user_id ); + $apps_keys[] = array( + 'user_id' => $user->ID, + 'permissions' => $user->woocommerce_api_key_permissions, + 'consumer_key' => wc_api_hash( $user->woocommerce_api_consumer_key ), + 'consumer_secret' => $user->woocommerce_api_consumer_secret, + 'truncated_key' => substr( $user->woocommerce_api_consumer_secret, -7 ), + ); + } + + if ( ! empty( $apps_keys ) ) { + // Create new apps. + foreach ( $apps_keys as $app ) { + $wpdb->insert( + $wpdb->prefix . 'woocommerce_api_keys', + $app, + array( + '%d', + '%s', + '%s', + '%s', + '%s', + ) + ); + } + + // Delete old user keys from usermeta. + foreach ( $api_users as $_user ) { + $user_id = intval( $_user->user_id ); + delete_user_meta( $user_id, 'woocommerce_api_consumer_key' ); + delete_user_meta( $user_id, 'woocommerce_api_consumer_secret' ); + delete_user_meta( $user_id, 'woocommerce_api_key_permissions' ); + } + } +} + +/** + * Update webhooks for 2.4 + * + * @return void + */ +function wc_update_240_webhooks() { + // phpcs:disable WordPress.DB.SlowDBQuery + + /** + * Webhooks. + * Make sure order.update webhooks get the woocommerce_order_edit_status hook. + */ + $order_update_webhooks = get_posts( + array( + 'posts_per_page' => -1, + 'post_type' => 'shop_webhook', + 'meta_key' => '_topic', + 'meta_value' => 'order.updated', + ) + ); + foreach ( $order_update_webhooks as $order_update_webhook ) { + $webhook = new WC_Webhook( $order_update_webhook->ID ); + $webhook->set_topic( 'order.updated' ); + } + + // phpcs:enable WordPress.DB.SlowDBQuery +} + +/** + * Update refunds for 2.4 + * + * @return void + */ +function wc_update_240_refunds() { + global $wpdb; + /** + * Refunds for full refunded orders. + * Update fully refunded orders to ensure they have a refund line item so reports add up. + */ + $refunded_orders = get_posts( + array( + 'posts_per_page' => -1, + 'post_type' => 'shop_order', + 'post_status' => array( 'wc-refunded' ), + ) + ); + + // Ensure emails are disabled during this update routine. + remove_all_actions( 'woocommerce_order_status_refunded_notification' ); + remove_all_actions( 'woocommerce_order_partially_refunded_notification' ); + remove_action( 'woocommerce_order_status_refunded', array( 'WC_Emails', 'send_transactional_email' ) ); + remove_action( 'woocommerce_order_partially_refunded', array( 'WC_Emails', 'send_transactional_email' ) ); + + foreach ( $refunded_orders as $refunded_order ) { + $order_total = get_post_meta( $refunded_order->ID, '_order_total', true ); + $refunded_total = $wpdb->get_var( + $wpdb->prepare( + "SELECT SUM( postmeta.meta_value ) + FROM $wpdb->postmeta AS postmeta + INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) + WHERE postmeta.meta_key = '_refund_amount' + AND postmeta.post_id = posts.ID", + $refunded_order->ID + ) + ); + + if ( $order_total > $refunded_total ) { + wc_create_refund( + array( + 'amount' => $order_total - $refunded_total, + 'reason' => __( 'Order fully refunded', 'woocommerce' ), + 'order_id' => $refunded_order->ID, + 'line_items' => array(), + 'date' => $refunded_order->post_modified, + ) + ); + } + } + + wc_delete_shop_order_transients(); +} + +/** + * Update DB version for 2.4 + * + * @return void + */ +function wc_update_240_db_version() { + WC_Install::update_db_version( '2.4.0' ); +} + +/** + * Update variations for 2.4.1 + * + * @return void + */ +function wc_update_241_variations() { + global $wpdb; + + // Select variations that don't have any _stock_status implemented on WooCommerce 2.2. + $update_variations = $wpdb->get_results( + "SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent + FROM {$wpdb->posts} as posts + LEFT OUTER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id AND postmeta.meta_key = '_stock_status' + WHERE posts.post_type = 'product_variation' + AND postmeta.meta_value IS NULL" + ); + + foreach ( $update_variations as $variation ) { + // Get the parent _stock_status. + $parent_stock_status = get_post_meta( $variation->variation_parent, '_stock_status', true ); + + // Set the _stock_status. + add_post_meta( $variation->variation_id, '_stock_status', $parent_stock_status ? $parent_stock_status : 'instock', true ); + + // Delete old product children array. + delete_transient( 'wc_product_children_' . $variation->variation_parent ); + } + + // Invalidate old transients such as wc_var_price. + WC_Cache_Helper::get_transient_version( 'product', true ); +} + +/** + * Update DB version for 2.4.1 + * + * @return void + */ +function wc_update_241_db_version() { + WC_Install::update_db_version( '2.4.1' ); +} + +/** + * Update currency settings for 2.5 + * + * @return void + */ +function wc_update_250_currency() { + global $wpdb; + // Fix currency settings for LAK currency. + $current_currency = get_option( 'woocommerce_currency' ); + + if ( 'KIP' === $current_currency ) { + update_option( 'woocommerce_currency', 'LAK' ); + } + + // phpcs:disable WordPress.DB.SlowDBQuery + + // Update LAK currency code. + $wpdb->update( + $wpdb->postmeta, + array( + 'meta_value' => 'LAK', + ), + array( + 'meta_key' => '_order_currency', + 'meta_value' => 'KIP', + ) + ); + + // phpcs:enable WordPress.DB.SlowDBQuery +} + +/** + * Update DB version for 2.5 + * + * @return void + */ +function wc_update_250_db_version() { + WC_Install::update_db_version( '2.5.0' ); +} + +/** + * Update ship to countries options for 2.6 + * + * @return void + */ +function wc_update_260_options() { + // woocommerce_calc_shipping option has been removed in 2.6. + if ( 'no' === get_option( 'woocommerce_calc_shipping' ) ) { + update_option( 'woocommerce_ship_to_countries', 'disabled' ); + } + + WC_Admin_Notices::add_notice( 'legacy_shipping' ); +} + +/** + * Update term meta for 2.6 + * + * @return void + */ +function wc_update_260_termmeta() { + global $wpdb; + /** + * Migrate term meta to WordPress tables. + */ + if ( get_option( 'db_version' ) >= 34370 && $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_termmeta';" ) ) { + if ( $wpdb->query( "INSERT INTO {$wpdb->termmeta} ( term_id, meta_key, meta_value ) SELECT woocommerce_term_id, meta_key, meta_value FROM {$wpdb->prefix}woocommerce_termmeta;" ) ) { + $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_termmeta" ); + wp_cache_flush(); + } + } +} + +/** + * Update zones for 2.6 + * + * @return void + */ +function wc_update_260_zones() { + global $wpdb; + /** + * Old (table rate) shipping zones to new core shipping zones migration. + * zone_enabled and zone_type are no longer used, but it's safe to leave them be. + */ + if ( $wpdb->get_var( "SHOW COLUMNS FROM `{$wpdb->prefix}woocommerce_shipping_zones` LIKE 'zone_enabled';" ) ) { + $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_shipping_zones CHANGE `zone_type` `zone_type` VARCHAR(40) NOT NULL DEFAULT '';" ); + $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_shipping_zones CHANGE `zone_enabled` `zone_enabled` INT(1) NOT NULL DEFAULT 1;" ); + } +} + +/** + * Update zone methods for 2.6 + * + * @return void + */ +function wc_update_260_zone_methods() { + global $wpdb; + + /** + * Shipping zones in WC 2.6.0 use a table named woocommerce_shipping_zone_methods. + * Migrate the old data out of woocommerce_shipping_zone_shipping_methods into the new table and port over any known options (used by table rates and flat rate boxes). + */ + if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_shipping_zone_shipping_methods';" ) ) { + $old_methods = $wpdb->get_results( "SELECT zone_id, shipping_method_type, shipping_method_order, shipping_method_id FROM {$wpdb->prefix}woocommerce_shipping_zone_shipping_methods;" ); + + if ( $old_methods ) { + $max_new_id = $wpdb->get_var( "SELECT MAX(instance_id) FROM {$wpdb->prefix}woocommerce_shipping_zone_methods" ); + $max_old_id = $wpdb->get_var( "SELECT MAX(shipping_method_id) FROM {$wpdb->prefix}woocommerce_shipping_zone_shipping_methods" ); + + // Avoid ID conflicts. + $wpdb->query( $wpdb->prepare( "ALTER TABLE {$wpdb->prefix}woocommerce_shipping_zone_methods AUTO_INCREMENT = %d;", max( $max_new_id, $max_old_id ) + 1 ) ); + + // Store changes. + $changes = array(); + + // Move data. + foreach ( $old_methods as $old_method ) { + $wpdb->insert( + $wpdb->prefix . 'woocommerce_shipping_zone_methods', + array( + 'zone_id' => $old_method->zone_id, + 'method_id' => $old_method->shipping_method_type, + 'method_order' => $old_method->shipping_method_order, + ) + ); + + $new_instance_id = $wpdb->insert_id; + + // Move main settings. + $older_settings_key = 'woocommerce_' . $old_method->shipping_method_type . '-' . $old_method->shipping_method_id . '_settings'; + $old_settings_key = 'woocommerce_' . $old_method->shipping_method_type . '_' . $old_method->shipping_method_id . '_settings'; + add_option( 'woocommerce_' . $old_method->shipping_method_type . '_' . $new_instance_id . '_settings', get_option( $old_settings_key, get_option( $older_settings_key ) ) ); + + // Handling for table rate and flat rate box shipping. + if ( 'table_rate' === $old_method->shipping_method_type ) { + // Move priority settings. + add_option( 'woocommerce_table_rate_default_priority_' . $new_instance_id, get_option( 'woocommerce_table_rate_default_priority_' . $old_method->shipping_method_id ) ); + add_option( 'woocommerce_table_rate_priorities_' . $new_instance_id, get_option( 'woocommerce_table_rate_priorities_' . $old_method->shipping_method_id ) ); + + // Move rates. + $wpdb->update( + $wpdb->prefix . 'woocommerce_shipping_table_rates', + array( + 'shipping_method_id' => $new_instance_id, + ), + array( + 'shipping_method_id' => $old_method->shipping_method_id, + ) + ); + } elseif ( 'flat_rate_boxes' === $old_method->shipping_method_type ) { + $wpdb->update( + $wpdb->prefix . 'woocommerce_shipping_flat_rate_boxes', + array( + 'shipping_method_id' => $new_instance_id, + ), + array( + 'shipping_method_id' => $old_method->shipping_method_id, + ) + ); + } + + $changes[ $old_method->shipping_method_id ] = $new_instance_id; + } + + // $changes contains keys (old method ids) and values (new instance ids) if extra processing is needed in plugins. + // Store this to an option so extensions can pick it up later, then fire an action. + update_option( 'woocommerce_updated_instance_ids', $changes ); + do_action( 'woocommerce_updated_instance_ids', $changes ); + } + } + + // Change ranges used to ... + $wpdb->query( "UPDATE {$wpdb->prefix}woocommerce_shipping_zone_locations SET location_code = REPLACE( location_code, '-', '...' );" ); +} + +/** + * Update refunds for 2.6 + * + * @return void + */ +function wc_update_260_refunds() { + global $wpdb; + /** + * Refund item qty should be negative. + */ + $wpdb->query( + "UPDATE {$wpdb->prefix}woocommerce_order_itemmeta as item_meta + LEFT JOIN {$wpdb->prefix}woocommerce_order_items as items ON item_meta.order_item_id = items.order_item_id + LEFT JOIN {$wpdb->posts} as posts ON items.order_id = posts.ID + SET item_meta.meta_value = item_meta.meta_value * -1 + WHERE item_meta.meta_value > 0 AND item_meta.meta_key = '_qty' AND posts.post_type = 'shop_order_refund'" + ); +} + +/** + * Update DB version for 2.6 + * + * @return void + */ +function wc_update_260_db_version() { + WC_Install::update_db_version( '2.6.0' ); +} + +/** + * Update webhooks for 3.0 + * + * @return void + */ +function wc_update_300_webhooks() { + // phpcs:disable WordPress.DB.SlowDBQuery + + /** + * Make sure product.update webhooks get the woocommerce_product_quick_edit_save + * and woocommerce_product_bulk_edit_save hooks. + */ + $product_update_webhooks = get_posts( + array( + 'posts_per_page' => -1, + 'post_type' => 'shop_webhook', + 'meta_key' => '_topic', + 'meta_value' => 'product.updated', + ) + ); + foreach ( $product_update_webhooks as $product_update_webhook ) { + $webhook = new WC_Webhook( $product_update_webhook->ID ); + $webhook->set_topic( 'product.updated' ); + } + + // phpcs:enable WordPress.DB.SlowDBQuery +} + +/** + * Add an index to the field comment_type to improve the response time of the query + * used by WC_Comments::wp_count_comments() to get the number of comments by type. + */ +function wc_update_300_comment_type_index() { + global $wpdb; + + $index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->comments} WHERE column_name = 'comment_type' and key_name = 'woo_idx_comment_type'" ); + + if ( is_null( $index_exists ) ) { + // Add an index to the field comment_type to improve the response time of the query + // used by WC_Comments::wp_count_comments() to get the number of comments by type. + $wpdb->query( "ALTER TABLE {$wpdb->comments} ADD INDEX woo_idx_comment_type (comment_type)" ); + } +} + +/** + * Update grouped products for 3.0 + * + * @return void + */ +function wc_update_300_grouped_products() { + global $wpdb; + $parents = $wpdb->get_col( "SELECT DISTINCT( post_parent ) FROM {$wpdb->posts} WHERE post_parent > 0 AND post_type = 'product';" ); + foreach ( $parents as $parent_id ) { + $parent = wc_get_product( $parent_id ); + if ( $parent && $parent->is_type( 'grouped' ) ) { + $children_ids = get_posts( + array( + 'post_parent' => $parent_id, + 'posts_per_page' => -1, + 'post_type' => 'product', + 'fields' => 'ids', + ) + ); + update_post_meta( $parent_id, '_children', $children_ids ); + + // Update children to remove the parent. + $wpdb->update( + $wpdb->posts, + array( + 'post_parent' => 0, + ), + array( + 'post_parent' => $parent_id, + ) + ); + } + } +} + +/** + * Update shipping tax classes for 3.0 + * + * @return void + */ +function wc_update_300_settings() { + $woocommerce_shipping_tax_class = get_option( 'woocommerce_shipping_tax_class' ); + if ( '' === $woocommerce_shipping_tax_class ) { + update_option( 'woocommerce_shipping_tax_class', 'inherit' ); + } elseif ( 'standard' === $woocommerce_shipping_tax_class ) { + update_option( 'woocommerce_shipping_tax_class', '' ); + } +} + +/** + * Convert meta values into term for product visibility. + */ +function wc_update_300_product_visibility() { + global $wpdb; + + WC_Install::create_terms(); + + $featured_term = get_term_by( 'name', 'featured', 'product_visibility' ); + + if ( $featured_term ) { + $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_featured' AND meta_value = 'yes';", $featured_term->term_taxonomy_id ) ); + } + + $exclude_search_term = get_term_by( 'name', 'exclude-from-search', 'product_visibility' ); + + if ( $exclude_search_term ) { + $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_visibility' AND meta_value IN ('hidden', 'catalog');", $exclude_search_term->term_taxonomy_id ) ); + } + + $exclude_catalog_term = get_term_by( 'name', 'exclude-from-catalog', 'product_visibility' ); + + if ( $exclude_catalog_term ) { + $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_visibility' AND meta_value IN ('hidden', 'search');", $exclude_catalog_term->term_taxonomy_id ) ); + } + + $outofstock_term = get_term_by( 'name', 'outofstock', 'product_visibility' ); + + if ( $outofstock_term ) { + $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_stock_status' AND meta_value = 'outofstock';", $outofstock_term->term_taxonomy_id ) ); + } + + $rating_term = get_term_by( 'name', 'rated-1', 'product_visibility' ); + + if ( $rating_term ) { + $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 1;", $rating_term->term_taxonomy_id ) ); + } + + $rating_term = get_term_by( 'name', 'rated-2', 'product_visibility' ); + + if ( $rating_term ) { + $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 2;", $rating_term->term_taxonomy_id ) ); + } + + $rating_term = get_term_by( 'name', 'rated-3', 'product_visibility' ); + + if ( $rating_term ) { + $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 3;", $rating_term->term_taxonomy_id ) ); + } + + $rating_term = get_term_by( 'name', 'rated-4', 'product_visibility' ); + + if ( $rating_term ) { + $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 4;", $rating_term->term_taxonomy_id ) ); + } + + $rating_term = get_term_by( 'name', 'rated-5', 'product_visibility' ); + + if ( $rating_term ) { + $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 5;", $rating_term->term_taxonomy_id ) ); + } +} + +/** + * Update DB Version. + */ +function wc_update_300_db_version() { + WC_Install::update_db_version( '3.0.0' ); +} + +/** + * Add an index to the downloadable product permissions table to improve performance of update_user_by_order_id. + */ +function wc_update_310_downloadable_products() { + global $wpdb; + + $index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE column_name = 'order_id' and key_name = 'order_id'" ); + + if ( is_null( $index_exists ) ) { + $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions ADD INDEX order_id (order_id)" ); + } +} + +/** + * Find old order notes and ensure they have the correct type for exclusion. + */ +function wc_update_310_old_comments() { + global $wpdb; + + $wpdb->query( "UPDATE $wpdb->comments comments LEFT JOIN $wpdb->posts as posts ON comments.comment_post_ID = posts.ID SET comment_type = 'order_note' WHERE posts.post_type = 'shop_order' AND comment_type = '';" ); +} + +/** + * Update DB Version. + */ +function wc_update_310_db_version() { + WC_Install::update_db_version( '3.1.0' ); +} + +/** + * Update shop_manager capabilities. + */ +function wc_update_312_shop_manager_capabilities() { + $role = get_role( 'shop_manager' ); + $role->remove_cap( 'unfiltered_html' ); +} + +/** + * Update DB Version. + */ +function wc_update_312_db_version() { + WC_Install::update_db_version( '3.1.2' ); +} + +/** + * Update state codes for Mexico. + */ +function wc_update_320_mexican_states() { + global $wpdb; + + $mx_states = array( + 'Distrito Federal' => 'CMX', + 'Jalisco' => 'JAL', + 'Nuevo Leon' => 'NLE', + 'Aguascalientes' => 'AGS', + 'Baja California' => 'BCN', + 'Baja California Sur' => 'BCS', + 'Campeche' => 'CAM', + 'Chiapas' => 'CHP', + 'Chihuahua' => 'CHH', + 'Coahuila' => 'COA', + 'Colima' => 'COL', + 'Durango' => 'DGO', + 'Guanajuato' => 'GTO', + 'Guerrero' => 'GRO', + 'Hidalgo' => 'HGO', + 'Estado de Mexico' => 'MEX', + 'Michoacan' => 'MIC', + 'Morelos' => 'MOR', + 'Nayarit' => 'NAY', + 'Oaxaca' => 'OAX', + 'Puebla' => 'PUE', + 'Queretaro' => 'QRO', + 'Quintana Roo' => 'ROO', + 'San Luis Potosi' => 'SLP', + 'Sinaloa' => 'SIN', + 'Sonora' => 'SON', + 'Tabasco' => 'TAB', + 'Tamaulipas' => 'TMP', + 'Tlaxcala' => 'TLA', + 'Veracruz' => 'VER', + 'Yucatan' => 'YUC', + 'Zacatecas' => 'ZAC', + ); + + foreach ( $mx_states as $old => $new ) { + $wpdb->query( + $wpdb->prepare( + "UPDATE $wpdb->postmeta + SET meta_value = %s + WHERE meta_key IN ( '_billing_state', '_shipping_state' ) + AND meta_value = %s", + $new, + $old + ) + ); + $wpdb->update( + "{$wpdb->prefix}woocommerce_shipping_zone_locations", + array( + 'location_code' => 'MX:' . $new, + ), + array( + 'location_code' => 'MX:' . $old, + ) + ); + $wpdb->update( + "{$wpdb->prefix}woocommerce_tax_rates", + array( + 'tax_rate_state' => strtoupper( $new ), + ), + array( + 'tax_rate_state' => strtoupper( $old ), + ) + ); + } +} + +/** + * Update DB Version. + */ +function wc_update_320_db_version() { + WC_Install::update_db_version( '3.2.0' ); +} + +/** + * Update image settings to use new aspect ratios and widths. + */ +function wc_update_330_image_options() { + $old_thumbnail_size = get_option( 'shop_catalog_image_size', array() ); + $old_single_size = get_option( 'shop_single_image_size', array() ); + + if ( ! empty( $old_thumbnail_size['width'] ) ) { + $width = absint( $old_thumbnail_size['width'] ); + $height = absint( $old_thumbnail_size['height'] ); + $hard_crop = ! empty( $old_thumbnail_size['crop'] ); + + if ( ! $width ) { + $width = 300; + } + + if ( ! $height ) { + $height = $width; + } + + update_option( 'woocommerce_thumbnail_image_width', $width ); + + // Calculate cropping mode from old image options. + if ( ! $hard_crop ) { + update_option( 'woocommerce_thumbnail_cropping', 'uncropped' ); + } elseif ( $width === $height ) { + update_option( 'woocommerce_thumbnail_cropping', '1:1' ); + } else { + $ratio = $width / $height; + $fraction = wc_decimal_to_fraction( $ratio ); + + if ( $fraction ) { + update_option( 'woocommerce_thumbnail_cropping', 'custom' ); + update_option( 'woocommerce_thumbnail_cropping_custom_width', $fraction[0] ); + update_option( 'woocommerce_thumbnail_cropping_custom_height', $fraction[1] ); + } + } + } + + // Single is uncropped. + if ( ! empty( $old_single_size['width'] ) ) { + update_option( 'woocommerce_single_image_width', absint( $old_single_size['width'] ) ); + } +} + +/** + * Migrate webhooks from post type to CRUD. + */ +function wc_update_330_webhooks() { + register_post_type( 'shop_webhook' ); + + // Map statuses from post_type to Webhooks CRUD. + $statuses = array( + 'publish' => 'active', + 'draft' => 'paused', + 'pending' => 'disabled', + ); + + $posts = get_posts( + array( + 'posts_per_page' => -1, + 'post_type' => 'shop_webhook', + 'post_status' => 'any', + ) + ); + + foreach ( $posts as $post ) { + $webhook = new WC_Webhook(); + $webhook->set_name( $post->post_title ); + $webhook->set_status( isset( $statuses[ $post->post_status ] ) ? $statuses[ $post->post_status ] : 'disabled' ); + $webhook->set_delivery_url( get_post_meta( $post->ID, '_delivery_url', true ) ); + $webhook->set_secret( get_post_meta( $post->ID, '_secret', true ) ); + $webhook->set_topic( get_post_meta( $post->ID, '_topic', true ) ); + $webhook->set_api_version( get_post_meta( $post->ID, '_api_version', true ) ); + $webhook->set_user_id( $post->post_author ); + $webhook->set_pending_delivery( false ); + $webhook->save(); + + wp_delete_post( $post->ID, true ); + } + + unregister_post_type( 'shop_webhook' ); +} + +/** + * Assign default cat to all products with no cats. + */ +function wc_update_330_set_default_product_cat() { + global $wpdb; + + $default_category = get_option( 'default_product_cat', 0 ); + + if ( $default_category ) { + $wpdb->query( + $wpdb->prepare( + "INSERT INTO {$wpdb->term_relationships} (object_id, term_taxonomy_id) + SELECT DISTINCT posts.ID, %s FROM {$wpdb->posts} posts + LEFT JOIN + ( + SELECT object_id FROM {$wpdb->term_relationships} term_relationships + LEFT JOIN {$wpdb->term_taxonomy} term_taxonomy ON term_relationships.term_taxonomy_id = term_taxonomy.term_taxonomy_id + WHERE term_taxonomy.taxonomy = 'product_cat' + ) AS tax_query + ON posts.ID = tax_query.object_id + WHERE posts.post_type = 'product' + AND tax_query.object_id IS NULL", + $default_category + ) + ); + wp_cache_flush(); + delete_transient( 'wc_term_counts' ); + wp_update_term_count_now( array( $default_category ), 'product_cat' ); + } +} + +/** + * Update product stock status to use the new onbackorder status. + */ +function wc_update_330_product_stock_status() { + global $wpdb; + + if ( 'yes' !== get_option( 'woocommerce_manage_stock' ) ) { + return; + } + + $min_stock_amount = (int) get_option( 'woocommerce_notify_no_stock_amount', 0 ); + + // Get all products that have stock management enabled, stock less than or equal to min stock amount, and backorders enabled. + $post_ids = $wpdb->get_col( + $wpdb->prepare( + "SELECT t1.post_id FROM $wpdb->postmeta t1 + INNER JOIN $wpdb->postmeta t2 + ON t1.post_id = t2.post_id + AND t1.meta_key = '_manage_stock' AND t1.meta_value = 'yes' + AND t2.meta_key = '_stock' AND t2.meta_value <= %d + INNER JOIN $wpdb->postmeta t3 + ON t2.post_id = t3.post_id + AND t3.meta_key = '_backorders' AND ( t3.meta_value = 'yes' OR t3.meta_value = 'notify' )", + $min_stock_amount + ) + ); + + if ( empty( $post_ids ) ) { + return; + } + + $post_ids = array_map( 'absint', $post_ids ); + + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared + // Set the status to onbackorder for those products. + $wpdb->query( + "UPDATE $wpdb->postmeta + SET meta_value = 'onbackorder' + WHERE meta_key = '_stock_status' AND post_id IN ( " . implode( ',', $post_ids ) . ' )' + ); + // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared +} + +/** + * Clear addons page transients + */ +function wc_update_330_clear_transients() { + delete_transient( 'wc_addons_sections' ); + delete_transient( 'wc_addons_featured' ); +} + +/** + * Set PayPal's sandbox credentials. + */ +function wc_update_330_set_paypal_sandbox_credentials() { + + $paypal_settings = get_option( 'woocommerce_paypal_settings' ); + + if ( isset( $paypal_settings['testmode'] ) && 'yes' === $paypal_settings['testmode'] ) { + foreach ( array( 'api_username', 'api_password', 'api_signature' ) as $credential ) { + if ( ! empty( $paypal_settings[ $credential ] ) ) { + $paypal_settings[ 'sandbox_' . $credential ] = $paypal_settings[ $credential ]; + } + } + + update_option( 'woocommerce_paypal_settings', $paypal_settings ); + } +} + +/** + * Update DB Version. + */ +function wc_update_330_db_version() { + WC_Install::update_db_version( '3.3.0' ); +} + +/** + * Update state codes for Ireland and BD. + */ +function wc_update_340_states() { + $country_states = array( + 'IE' => array( + 'CK' => 'CO', + 'DN' => 'D', + 'GY' => 'G', + 'TY' => 'TA', + ), + 'BD' => array( + 'BAG' => 'BD-05', + 'BAN' => 'BD-01', + 'BAR' => 'BD-02', + 'BARI' => 'BD-06', + 'BHO' => 'BD-07', + 'BOG' => 'BD-03', + 'BRA' => 'BD-04', + 'CHA' => 'BD-09', + 'CHI' => 'BD-10', + 'CHU' => 'BD-12', + 'COX' => 'BD-11', + 'COM' => 'BD-08', + 'DHA' => 'BD-13', + 'DIN' => 'BD-14', + 'FAR' => 'BD-15', + 'FEN' => 'BD-16', + 'GAI' => 'BD-19', + 'GAZI' => 'BD-18', + 'GOP' => 'BD-17', + 'HAB' => 'BD-20', + 'JAM' => 'BD-21', + 'JES' => 'BD-22', + 'JHA' => 'BD-25', + 'JHE' => 'BD-23', + 'JOY' => 'BD-24', + 'KHA' => 'BD-29', + 'KHU' => 'BD-27', + 'KIS' => 'BD-26', + 'KUR' => 'BD-28', + 'KUS' => 'BD-30', + 'LAK' => 'BD-31', + 'LAL' => 'BD-32', + 'MAD' => 'BD-36', + 'MAG' => 'BD-37', + 'MAN' => 'BD-33', + 'MEH' => 'BD-39', + 'MOU' => 'BD-38', + 'MUN' => 'BD-35', + 'MYM' => 'BD-34', + 'NAO' => 'BD-48', + 'NAR' => 'BD-43', + 'NARG' => 'BD-40', + 'NARD' => 'BD-42', + 'NAT' => 'BD-44', + 'NAW' => 'BD-45', + 'NET' => 'BD-41', + 'NIL' => 'BD-46', + 'NOA' => 'BD-47', + 'PAB' => 'BD-49', + 'PAN' => 'BD-52', + 'PAT' => 'BD-51', + 'PIR' => 'BD-50', + 'RAJB' => 'BD-53', + 'RAJ' => 'BD-54', + 'RAN' => 'BD-56', + 'RANP' => 'BD-55', + 'SAT' => 'BD-58', + 'SHA' => 'BD-57', + 'SIR' => 'BD-59', + 'SUN' => 'BD-61', + 'SYL' => 'BD-60', + 'TAN' => 'BD-63', + 'THA' => 'BD-64', + ), + ); + + update_option( 'woocommerce_update_340_states', $country_states ); +} + +/** + * Update next state in the queue. + * + * @return bool True to run again, false if completed. + */ +function wc_update_340_state() { + global $wpdb; + + $country_states = array_filter( (array) get_option( 'woocommerce_update_340_states', array() ) ); + + if ( empty( $country_states ) ) { + return false; + } + + foreach ( $country_states as $country => $states ) { + foreach ( $states as $old => $new ) { + $wpdb->query( + $wpdb->prepare( + "UPDATE $wpdb->postmeta + SET meta_value = %s + WHERE meta_key IN ( '_billing_state', '_shipping_state' ) + AND meta_value = %s", + $new, + $old + ) + ); + $wpdb->update( + "{$wpdb->prefix}woocommerce_shipping_zone_locations", + array( + 'location_code' => $country . ':' . $new, + ), + array( + 'location_code' => $country . ':' . $old, + ) + ); + $wpdb->update( + "{$wpdb->prefix}woocommerce_tax_rates", + array( + 'tax_rate_state' => strtoupper( $new ), + ), + array( + 'tax_rate_state' => strtoupper( $old ), + ) + ); + unset( $country_states[ $country ][ $old ] ); + + if ( empty( $country_states[ $country ] ) ) { + unset( $country_states[ $country ] ); + } + break 2; + } + } + + if ( ! empty( $country_states ) ) { + return update_option( 'woocommerce_update_340_states', $country_states ); + } + + delete_option( 'woocommerce_update_340_states' ); + + return false; +} + +/** + * Set last active prop for users. + */ +function wc_update_340_last_active() { + global $wpdb; + // @codingStandardsIgnoreStart. + $wpdb->query( + $wpdb->prepare( " + INSERT INTO {$wpdb->usermeta} (user_id, meta_key, meta_value) + SELECT DISTINCT users.ID, 'wc_last_active', %s + FROM {$wpdb->users} as users + LEFT OUTER JOIN {$wpdb->usermeta} AS usermeta ON users.ID = usermeta.user_id AND usermeta.meta_key = 'wc_last_active' + WHERE usermeta.meta_value IS NULL + ", + (string) strtotime( date( 'Y-m-d', current_time( 'timestamp', true ) ) ) + ) + ); + // @codingStandardsIgnoreEnd. +} + +/** + * Update DB Version. + */ +function wc_update_340_db_version() { + WC_Install::update_db_version( '3.4.0' ); +} + +/** + * Remove duplicate foreign keys + * + * @return void + */ +function wc_update_343_cleanup_foreign_keys() { + global $wpdb; + + $results = $wpdb->get_results( + "SELECT CONSTRAINT_NAME + FROM information_schema.TABLE_CONSTRAINTS + WHERE CONSTRAINT_SCHEMA = '{$wpdb->dbname}' + AND CONSTRAINT_NAME LIKE '%wc_download_log_ib%' + AND CONSTRAINT_TYPE = 'FOREIGN KEY' + AND TABLE_NAME = '{$wpdb->prefix}wc_download_log'" + ); + + if ( $results ) { + foreach ( $results as $fk ) { + $wpdb->query( "ALTER TABLE {$wpdb->prefix}wc_download_log DROP FOREIGN KEY {$fk->CONSTRAINT_NAME}" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + } +} + +/** + * Update DB version. + * + * @return void + */ +function wc_update_343_db_version() { + WC_Install::update_db_version( '3.4.3' ); +} + +/** + * Recreate user roles so existing users will get the new capabilities. + * + * @return void + */ +function wc_update_344_recreate_roles() { + WC_Install::remove_roles(); + WC_Install::create_roles(); +} + +/** + * Update DB version. + * + * @return void + */ +function wc_update_344_db_version() { + WC_Install::update_db_version( '3.4.4' ); +} + +/** + * Set the comment type to 'review' for product reviews that don't have a comment type. + */ +function wc_update_350_reviews_comment_type() { + global $wpdb; + + $wpdb->query( + "UPDATE {$wpdb->prefix}comments JOIN {$wpdb->prefix}posts ON {$wpdb->prefix}posts.ID = {$wpdb->prefix}comments.comment_post_ID AND ( {$wpdb->prefix}posts.post_type = 'product' OR {$wpdb->prefix}posts.post_type = 'product_variation' ) SET {$wpdb->prefix}comments.comment_type = 'review' WHERE {$wpdb->prefix}comments.comment_type = ''" + ); +} + +/** + * Update DB Version. + */ +function wc_update_350_db_version() { + WC_Install::update_db_version( '3.5.0' ); +} + +/** + * Drop the fk_wc_download_log_permission_id FK as we use a new one with the table and blog prefix for MS compatability. + * + * @return void + */ +function wc_update_352_drop_download_log_fk() { + global $wpdb; + $results = $wpdb->get_results( + "SELECT CONSTRAINT_NAME + FROM information_schema.TABLE_CONSTRAINTS + WHERE CONSTRAINT_SCHEMA = '{$wpdb->dbname}' + AND CONSTRAINT_NAME = 'fk_wc_download_log_permission_id' + AND CONSTRAINT_TYPE = 'FOREIGN KEY' + AND TABLE_NAME = '{$wpdb->prefix}wc_download_log'" + ); + + // We only need to drop the old key as WC_Install::create_tables() takes care of creating the new FK. + if ( $results ) { + $wpdb->query( "ALTER TABLE {$wpdb->prefix}wc_download_log DROP FOREIGN KEY fk_wc_download_log_permission_id" ); // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared + } +} + +/** + * Remove edit_user capabilities from shop managers and use "translated" capabilities instead. + * See wc_shop_manager_has_capability function. + */ +function wc_update_354_modify_shop_manager_caps() { + global $wp_roles; + + if ( ! class_exists( 'WP_Roles' ) ) { + return; + } + + if ( ! isset( $wp_roles ) ) { + $wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine + } + + $wp_roles->remove_cap( 'shop_manager', 'edit_users' ); +} + +/** + * Update DB Version. + */ +function wc_update_354_db_version() { + WC_Install::update_db_version( '3.5.4' ); +} + +/** + * Update product lookup tables in bulk. + */ +function wc_update_360_product_lookup_tables() { + wc_update_product_lookup_tables(); +} + +/** + * Renames ordering meta to be consistent across taxonomies. + */ +function wc_update_360_term_meta() { + global $wpdb; + + $wpdb->query( "UPDATE {$wpdb->termmeta} SET meta_key = 'order' WHERE meta_key LIKE 'order_pa_%';" ); +} + +/** + * Add new user_order_remaining_expires to speed up user download permission fetching. + * + * @return void + */ +function wc_update_360_downloadable_product_permissions_index() { + global $wpdb; + + $index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE key_name = 'user_order_remaining_expires'" ); + + if ( is_null( $index_exists ) ) { + $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions ADD INDEX user_order_remaining_expires (user_id,order_id,downloads_remaining,access_expires)" ); + } +} + +/** + * Update DB Version. + */ +function wc_update_360_db_version() { + WC_Install::update_db_version( '3.6.0' ); +} + +/** + * Put tax classes into a DB table. + * + * @return void + */ +function wc_update_370_tax_rate_classes() { + global $wpdb; + + $classes = array_map( 'trim', explode( "\n", get_option( 'woocommerce_tax_classes' ) ) ); + + if ( $classes ) { + foreach ( $classes as $class ) { + if ( empty( $class ) ) { + continue; + } + WC_Tax::create_tax_class( $class ); + } + } + delete_option( 'woocommerce_tax_classes' ); +} + +/** + * Update currency settings for 3.7.0 + * + * @return void + */ +function wc_update_370_mro_std_currency() { + global $wpdb; + + // Fix currency settings for MRU and STN currency. + $current_currency = get_option( 'woocommerce_currency' ); + + if ( 'MRO' === $current_currency ) { + update_option( 'woocommerce_currency', 'MRU' ); + } + + if ( 'STD' === $current_currency ) { + update_option( 'woocommerce_currency', 'STN' ); + } + + // Update MRU currency code. + $wpdb->update( + $wpdb->postmeta, + array( + 'meta_value' => 'MRU', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value + ), + array( + 'meta_key' => '_order_currency', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + 'meta_value' => 'MRO', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value + ) + ); + + // Update STN currency code. + $wpdb->update( + $wpdb->postmeta, + array( + 'meta_value' => 'STN', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value + ), + array( + 'meta_key' => '_order_currency', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + 'meta_value' => 'STD', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value + ) + ); +} + +/** + * Update DB Version. + */ +function wc_update_370_db_version() { + WC_Install::update_db_version( '3.7.0' ); +} + +/** + * We've moved the MaxMind database to a new location, as per the TOS' requirement that the database not + * be publicly accessible. + */ +function wc_update_390_move_maxmind_database() { + // Make sure to use all of the correct filters to pull the local database path. + $old_path = apply_filters( 'woocommerce_geolocation_local_database_path', WP_CONTENT_DIR . '/uploads/GeoLite2-Country.mmdb', 2 ); + + // Generate a prefix for the old file and store it in the integration as it would expect it. + $prefix = wp_generate_password( 32, false ); + update_option( 'woocommerce_maxmind_geolocation_settings', array( 'database_prefix' => $prefix ) ); + + // Generate the new path in the same way that the integration will. + $uploads_dir = wp_upload_dir(); + $new_path = trailingslashit( $uploads_dir['basedir'] ) . 'woocommerce_uploads/' . $prefix . '-GeoLite2-Country.mmdb'; + $new_path = apply_filters( 'woocommerce_geolocation_local_database_path', $new_path, 2 ); + $new_path = apply_filters( 'woocommerce_maxmind_geolocation_database_path', $new_path ); + + // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged + @rename( $old_path, $new_path ); +} + +/** + * So that we can best meet MaxMind's TOS, the geolocation database update cron should run once per 15 days. + */ +function wc_update_390_change_geolocation_database_update_cron() { + wp_clear_scheduled_hook( 'woocommerce_geoip_updater' ); + wp_schedule_event( time() + ( DAY_IN_SECONDS * 15 ), 'fifteendays', 'woocommerce_geoip_updater' ); +} + +/** + * Update DB version. + */ +function wc_update_390_db_version() { + WC_Install::update_db_version( '3.9.0' ); +} + +/** + * Increase column size + */ +function wc_update_400_increase_size_of_column() { + global $wpdb; + $wpdb->query( "ALTER TABLE {$wpdb->prefix}wc_product_meta_lookup MODIFY COLUMN `min_price` decimal(19,4) NULL default NULL" ); + $wpdb->query( "ALTER TABLE {$wpdb->prefix}wc_product_meta_lookup MODIFY COLUMN `max_price` decimal(19,4) NULL default NULL" ); +} + +/** + * Reset ActionScheduler migration status. Needs AS >= 3.0 shipped with WC >= 4.0. + */ +function wc_update_400_reset_action_scheduler_migration_status() { + if ( + class_exists( 'ActionScheduler_DataController' ) && + method_exists( 'ActionScheduler_DataController', 'mark_migration_incomplete' ) + ) { + \ActionScheduler_DataController::mark_migration_incomplete(); + } +} + +/** + * Update DB version. + */ +function wc_update_400_db_version() { + WC_Install::update_db_version( '4.0.0' ); +} + +/** + * Register attributes as terms for variable products, in increments of 100 products. + * + * This migration was added to support a new mechanism to improve the filtering of + * variable products by attribute (https://github.com/woocommerce/woocommerce/pull/26260), + * however that mechanism was later reverted (https://github.com/woocommerce/woocommerce/pull/27625) + * due to numerous issues found. Thus the migration is no longer needed. + * + * @return bool true if the migration needs to be run again. + */ +function wc_update_440_insert_attribute_terms_for_variable_products() { + return false; +} + +/** + * Update DB version. + */ +function wc_update_440_db_version() { + WC_Install::update_db_version( '4.4.0' ); +} + +/** + * Update DB version to 4.5.0. + */ +function wc_update_450_db_version() { + WC_Install::update_db_version( '4.5.0' ); +} + +/** + * Sanitize all coupons code. + * + * @return bool True to run again, false if completed. + */ +function wc_update_450_sanitize_coupons_code() { + global $wpdb; + + $coupon_id = 0; + $last_coupon_id = get_option( 'woocommerce_update_450_last_coupon_id', '0' ); + + $coupons = $wpdb->get_results( + $wpdb->prepare( + "SELECT ID, post_title FROM $wpdb->posts WHERE ID > %d AND post_type = 'shop_coupon' LIMIT 10", + $last_coupon_id + ), + ARRAY_A + ); + + if ( empty( $coupons ) ) { + delete_option( 'woocommerce_update_450_last_coupon_id' ); + return false; + } + + foreach ( $coupons as $key => $data ) { + $coupon_id = intval( $data['ID'] ); + $code = trim( wp_filter_kses( $data['post_title'] ) ); + + if ( ! empty( $code ) && $data['post_title'] !== $code ) { + $wpdb->update( + $wpdb->posts, + array( + 'post_title' => $code, + ), + array( + 'ID' => $coupon_id, + ), + array( + '%s', + ), + array( + '%d', + ) + ); + + // Clean cache. + clean_post_cache( $coupon_id ); + wp_cache_delete( WC_Cache_Helper::get_cache_prefix( 'coupons' ) . 'coupon_id_from_code_' . $data['post_title'], 'coupons' ); + } + } + + // Start the run again. + if ( $coupon_id ) { + return update_option( 'woocommerce_update_450_last_coupon_id', $coupon_id ); + } + + delete_option( 'woocommerce_update_450_last_coupon_id' ); + return false; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-user-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-user-functions.php new file mode 100644 index 0000000..ae59b7e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-user-functions.php @@ -0,0 +1,925 @@ +Please log in.', 'woocommerce' ), $email ) ); + } + + if ( 'yes' === get_option( 'woocommerce_registration_generate_username', 'yes' ) && empty( $username ) ) { + $username = wc_create_new_customer_username( $email, $args ); + } + + $username = sanitize_user( $username ); + + if ( empty( $username ) || ! validate_username( $username ) ) { + return new WP_Error( 'registration-error-invalid-username', __( 'Please enter a valid account username.', 'woocommerce' ) ); + } + + if ( username_exists( $username ) ) { + return new WP_Error( 'registration-error-username-exists', __( 'An account is already registered with that username. Please choose another.', 'woocommerce' ) ); + } + + // Handle password creation. + $password_generated = false; + if ( 'yes' === get_option( 'woocommerce_registration_generate_password' ) && empty( $password ) ) { + $password = wp_generate_password(); + $password_generated = true; + } + + if ( empty( $password ) ) { + return new WP_Error( 'registration-error-missing-password', __( 'Please enter an account password.', 'woocommerce' ) ); + } + + // Use WP_Error to handle registration errors. + $errors = new WP_Error(); + + do_action( 'woocommerce_register_post', $username, $email, $errors ); + + $errors = apply_filters( 'woocommerce_registration_errors', $errors, $username, $email ); + + if ( $errors->get_error_code() ) { + return $errors; + } + + $new_customer_data = apply_filters( + 'woocommerce_new_customer_data', + array_merge( + $args, + array( + 'user_login' => $username, + 'user_pass' => $password, + 'user_email' => $email, + 'role' => 'customer', + ) + ) + ); + + $customer_id = wp_insert_user( $new_customer_data ); + + if ( is_wp_error( $customer_id ) ) { + return $customer_id; + } + + do_action( 'woocommerce_created_customer', $customer_id, $new_customer_data, $password_generated ); + + return $customer_id; + } +} + +/** + * Create a unique username for a new customer. + * + * @since 3.6.0 + * @param string $email New customer email address. + * @param array $new_user_args Array of new user args, maybe including first and last names. + * @param string $suffix Append string to username to make it unique. + * @return string Generated username. + */ +function wc_create_new_customer_username( $email, $new_user_args = array(), $suffix = '' ) { + $username_parts = array(); + + if ( isset( $new_user_args['first_name'] ) ) { + $username_parts[] = sanitize_user( $new_user_args['first_name'], true ); + } + + if ( isset( $new_user_args['last_name'] ) ) { + $username_parts[] = sanitize_user( $new_user_args['last_name'], true ); + } + + // Remove empty parts. + $username_parts = array_filter( $username_parts ); + + // If there are no parts, e.g. name had unicode chars, or was not provided, fallback to email. + if ( empty( $username_parts ) ) { + $email_parts = explode( '@', $email ); + $email_username = $email_parts[0]; + + // Exclude common prefixes. + if ( in_array( + $email_username, + array( + 'sales', + 'hello', + 'mail', + 'contact', + 'info', + ), + true + ) ) { + // Get the domain part. + $email_username = $email_parts[1]; + } + + $username_parts[] = sanitize_user( $email_username, true ); + } + + $username = wc_strtolower( implode( '.', $username_parts ) ); + + if ( $suffix ) { + $username .= $suffix; + } + + /** + * WordPress 4.4 - filters the list of blocked usernames. + * + * @since 3.7.0 + * @param array $usernames Array of blocked usernames. + */ + $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); + + // Stop illegal logins and generate a new random username. + if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ), true ) ) { + $new_args = array(); + + /** + * Filter generated customer username. + * + * @since 3.7.0 + * @param string $username Generated username. + * @param string $email New customer email address. + * @param array $new_user_args Array of new user args, maybe including first and last names. + * @param string $suffix Append string to username to make it unique. + */ + $new_args['first_name'] = apply_filters( + 'woocommerce_generated_customer_username', + 'woo_user_' . zeroise( wp_rand( 0, 9999 ), 4 ), + $email, + $new_user_args, + $suffix + ); + + return wc_create_new_customer_username( $email, $new_args, $suffix ); + } + + if ( username_exists( $username ) ) { + // Generate something unique to append to the username in case of a conflict with another user. + $suffix = '-' . zeroise( wp_rand( 0, 9999 ), 4 ); + return wc_create_new_customer_username( $email, $new_user_args, $suffix ); + } + + /** + * Filter new customer username. + * + * @since 3.7.0 + * @param string $username Customer username. + * @param string $email New customer email address. + * @param array $new_user_args Array of new user args, maybe including first and last names. + * @param string $suffix Append string to username to make it unique. + */ + return apply_filters( 'woocommerce_new_customer_username', $username, $email, $new_user_args, $suffix ); +} + +/** + * Login a customer (set auth cookie and set global user object). + * + * @param int $customer_id Customer ID. + */ +function wc_set_customer_auth_cookie( $customer_id ) { + wp_set_current_user( $customer_id ); + wp_set_auth_cookie( $customer_id, true ); + + // Update session. + WC()->session->init_session_cookie(); +} + +/** + * Get past orders (by email) and update them. + * + * @param int $customer_id Customer ID. + * @return int + */ +function wc_update_new_customer_past_orders( $customer_id ) { + $linked = 0; + $complete = 0; + $customer = get_user_by( 'id', absint( $customer_id ) ); + $customer_orders = wc_get_orders( + array( + 'limit' => -1, + 'customer' => array( array( 0, $customer->user_email ) ), + 'return' => 'ids', + ) + ); + + if ( ! empty( $customer_orders ) ) { + foreach ( $customer_orders as $order_id ) { + $order = wc_get_order( $order_id ); + if ( ! $order ) { + continue; + } + + $order->set_customer_id( $customer->ID ); + $order->save(); + + if ( $order->has_downloadable_item() ) { + $data_store = WC_Data_Store::load( 'customer-download' ); + $data_store->delete_by_order_id( $order->get_id() ); + wc_downloadable_product_permissions( $order->get_id(), true ); + } + + do_action( 'woocommerce_update_new_customer_past_order', $order_id, $customer ); + + if ( get_post_status( $order_id ) === 'wc-completed' ) { + $complete++; + } + + $linked++; + } + } + + if ( $complete ) { + update_user_meta( $customer_id, 'paying_customer', 1 ); + update_user_meta( $customer_id, '_order_count', '' ); + update_user_meta( $customer_id, '_money_spent', '' ); + } + + return $linked; +} + +/** + * Order payment completed - This is a paying customer. + * + * @param int $order_id Order ID. + */ +function wc_paying_customer( $order_id ) { + $order = wc_get_order( $order_id ); + $customer_id = $order->get_customer_id(); + + if ( $customer_id > 0 && 'shop_order_refund' !== $order->get_type() ) { + $customer = new WC_Customer( $customer_id ); + + if ( ! $customer->get_is_paying_customer() ) { + $customer->set_is_paying_customer( true ); + $customer->save(); + } + } +} +add_action( 'woocommerce_payment_complete', 'wc_paying_customer' ); +add_action( 'woocommerce_order_status_completed', 'wc_paying_customer' ); + +/** + * Checks if a user (by email or ID or both) has bought an item. + * + * @param string $customer_email Customer email to check. + * @param int $user_id User ID to check. + * @param int $product_id Product ID to check. + * @return bool + */ +function wc_customer_bought_product( $customer_email, $user_id, $product_id ) { + global $wpdb; + + $result = apply_filters( 'woocommerce_pre_customer_bought_product', null, $customer_email, $user_id, $product_id ); + + if ( null !== $result ) { + return $result; + } + + $transient_name = 'wc_customer_bought_product_' . md5( $customer_email . $user_id ); + $transient_version = WC_Cache_Helper::get_transient_version( 'orders' ); + $transient_value = get_transient( $transient_name ); + + if ( isset( $transient_value['value'], $transient_value['version'] ) && $transient_value['version'] === $transient_version ) { + $result = $transient_value['value']; + } else { + $customer_data = array( $user_id ); + + if ( $user_id ) { + $user = get_user_by( 'id', $user_id ); + + if ( isset( $user->user_email ) ) { + $customer_data[] = $user->user_email; + } + } + + if ( is_email( $customer_email ) ) { + $customer_data[] = $customer_email; + } + + $customer_data = array_map( 'esc_sql', array_filter( array_unique( $customer_data ) ) ); + $statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() ); + + if ( count( $customer_data ) === 0 ) { + return false; + } + + $result = $wpdb->get_col( + " + SELECT im.meta_value FROM {$wpdb->posts} AS p + INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id + INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON p.ID = i.order_id + INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id + WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' ) + AND pm.meta_key IN ( '_billing_email', '_customer_user' ) + AND im.meta_key IN ( '_product_id', '_variation_id' ) + AND im.meta_value != 0 + AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' ) + " + ); // WPCS: unprepared SQL ok. + $result = array_map( 'absint', $result ); + + $transient_value = array( + 'version' => $transient_version, + 'value' => $result, + ); + + set_transient( $transient_name, $transient_value, DAY_IN_SECONDS * 30 ); + } + return in_array( absint( $product_id ), $result, true ); +} + +/** + * Checks if the current user has a role. + * + * @param string $role The role. + * @return bool + */ +function wc_current_user_has_role( $role ) { + return wc_user_has_role( wp_get_current_user(), $role ); +} + +/** + * Checks if a user has a role. + * + * @param int|\WP_User $user The user. + * @param string $role The role. + * @return bool + */ +function wc_user_has_role( $user, $role ) { + if ( ! is_object( $user ) ) { + $user = get_userdata( $user ); + } + + if ( ! $user || ! $user->exists() ) { + return false; + } + + return in_array( $role, $user->roles, true ); +} + +/** + * Checks if a user has a certain capability. + * + * @param array $allcaps All capabilities. + * @param array $caps Capabilities. + * @param array $args Arguments. + * + * @return array The filtered array of all capabilities. + */ +function wc_customer_has_capability( $allcaps, $caps, $args ) { + if ( isset( $caps[0] ) ) { + switch ( $caps[0] ) { + case 'view_order': + $user_id = intval( $args[1] ); + $order = wc_get_order( $args[2] ); + + if ( $order && $user_id === $order->get_user_id() ) { + $allcaps['view_order'] = true; + } + break; + case 'pay_for_order': + $user_id = intval( $args[1] ); + $order_id = isset( $args[2] ) ? $args[2] : null; + + // When no order ID, we assume it's a new order + // and thus, customer can pay for it. + if ( ! $order_id ) { + $allcaps['pay_for_order'] = true; + break; + } + + $order = wc_get_order( $order_id ); + + if ( $order && ( $user_id === $order->get_user_id() || ! $order->get_user_id() ) ) { + $allcaps['pay_for_order'] = true; + } + break; + case 'order_again': + $user_id = intval( $args[1] ); + $order = wc_get_order( $args[2] ); + + if ( $order && $user_id === $order->get_user_id() ) { + $allcaps['order_again'] = true; + } + break; + case 'cancel_order': + $user_id = intval( $args[1] ); + $order = wc_get_order( $args[2] ); + + if ( $order && $user_id === $order->get_user_id() ) { + $allcaps['cancel_order'] = true; + } + break; + case 'download_file': + $user_id = intval( $args[1] ); + $download = $args[2]; + + if ( $download && $user_id === $download->get_user_id() ) { + $allcaps['download_file'] = true; + } + break; + } + } + return $allcaps; +} +add_filter( 'user_has_cap', 'wc_customer_has_capability', 10, 3 ); + +/** + * Safe way of allowing shop managers restricted capabilities that will remove + * access to the capabilities if WooCommerce is deactivated. + * + * @since 3.5.4 + * @param bool[] $allcaps Array of key/value pairs where keys represent a capability name and boolean values + * represent whether the user has that capability. + * @param string[] $caps Required primitive capabilities for the requested capability. + * @param array $args Arguments that accompany the requested capability check. + * @param WP_User $user The user object. + * @return bool[] + */ +function wc_shop_manager_has_capability( $allcaps, $caps, $args, $user ) { + + if ( wc_user_has_role( $user, 'shop_manager' ) ) { + // @see wc_modify_map_meta_cap, which limits editing to customers. + $allcaps['edit_users'] = true; + } + + return $allcaps; +} +add_filter( 'user_has_cap', 'wc_shop_manager_has_capability', 10, 4 ); + +/** + * Modify the list of editable roles to prevent non-admin adding admin users. + * + * @param array $roles Roles. + * @return array + */ +function wc_modify_editable_roles( $roles ) { + if ( is_multisite() && is_super_admin() ) { + return $roles; + } + if ( ! wc_current_user_has_role( 'administrator' ) ) { + unset( $roles['administrator'] ); + + if ( wc_current_user_has_role( 'shop_manager' ) ) { + $shop_manager_editable_roles = apply_filters( 'woocommerce_shop_manager_editable_roles', array( 'customer' ) ); + return array_intersect_key( $roles, array_flip( $shop_manager_editable_roles ) ); + } + } + + return $roles; +} +add_filter( 'editable_roles', 'wc_modify_editable_roles' ); + +/** + * Modify capabilities to prevent non-admin users editing admin users. + * + * $args[0] will be the user being edited in this case. + * + * @param array $caps Array of caps. + * @param string $cap Name of the cap we are checking. + * @param int $user_id ID of the user being checked against. + * @param array $args Arguments. + * @return array + */ +function wc_modify_map_meta_cap( $caps, $cap, $user_id, $args ) { + if ( is_multisite() && is_super_admin() ) { + return $caps; + } + switch ( $cap ) { + case 'edit_user': + case 'remove_user': + case 'promote_user': + case 'delete_user': + if ( ! isset( $args[0] ) || $args[0] === $user_id ) { + break; + } else { + if ( ! wc_current_user_has_role( 'administrator' ) ) { + if ( wc_user_has_role( $args[0], 'administrator' ) ) { + $caps[] = 'do_not_allow'; + } elseif ( wc_current_user_has_role( 'shop_manager' ) ) { + // Shop managers can only edit customer info. + $userdata = get_userdata( $args[0] ); + $shop_manager_editable_roles = apply_filters( 'woocommerce_shop_manager_editable_roles', array( 'customer' ) ); + if ( property_exists( $userdata, 'roles' ) && ! empty( $userdata->roles ) && ! array_intersect( $userdata->roles, $shop_manager_editable_roles ) ) { + $caps[] = 'do_not_allow'; + } + } + } + } + break; + } + return $caps; +} +add_filter( 'map_meta_cap', 'wc_modify_map_meta_cap', 10, 4 ); + +/** + * Get customer download permissions from the database. + * + * @param int $customer_id Customer/User ID. + * @return array + */ +function wc_get_customer_download_permissions( $customer_id ) { + $data_store = WC_Data_Store::load( 'customer-download' ); + return apply_filters( 'woocommerce_permission_list', $data_store->get_downloads_for_customer( $customer_id ), $customer_id ); +} + +/** + * Get customer available downloads. + * + * @param int $customer_id Customer/User ID. + * @return array + */ +function wc_get_customer_available_downloads( $customer_id ) { + $downloads = array(); + $_product = null; + $order = null; + $file_number = 0; + + // Get results from valid orders only. + $results = wc_get_customer_download_permissions( $customer_id ); + + if ( $results ) { + foreach ( $results as $result ) { + $order_id = intval( $result->order_id ); + + if ( ! $order || $order->get_id() !== $order_id ) { + // New order. + $order = wc_get_order( $order_id ); + $_product = null; + } + + // Make sure the order exists for this download. + if ( ! $order ) { + continue; + } + + // Check if downloads are permitted. + if ( ! $order->is_download_permitted() ) { + continue; + } + + $product_id = intval( $result->product_id ); + + if ( ! $_product || $_product->get_id() !== $product_id ) { + // New product. + $file_number = 0; + $_product = wc_get_product( $product_id ); + } + + // Check product exists and has the file. + if ( ! $_product || ! $_product->exists() || ! $_product->has_file( $result->download_id ) ) { + continue; + } + + $download_file = $_product->get_file( $result->download_id ); + + // Download name will be 'Product Name' for products with a single downloadable file, and 'Product Name - File X' for products with multiple files. + $download_name = apply_filters( + 'woocommerce_downloadable_product_name', + $download_file['name'], + $_product, + $result->download_id, + $file_number + ); + + $downloads[] = array( + 'download_url' => add_query_arg( + array( + 'download_file' => $product_id, + 'order' => $result->order_key, + 'email' => rawurlencode( $result->user_email ), + 'key' => $result->download_id, + ), + home_url( '/' ) + ), + 'download_id' => $result->download_id, + 'product_id' => $_product->get_id(), + 'product_name' => $_product->get_name(), + 'product_url' => $_product->is_visible() ? $_product->get_permalink() : '', // Since 3.3.0. + 'download_name' => $download_name, + 'order_id' => $order->get_id(), + 'order_key' => $order->get_order_key(), + 'downloads_remaining' => $result->downloads_remaining, + 'access_expires' => $result->access_expires, + 'file' => array( + 'name' => $download_file->get_name(), + 'file' => $download_file->get_file(), + ), + ); + + $file_number++; + } + } + + return apply_filters( 'woocommerce_customer_available_downloads', $downloads, $customer_id ); +} + +/** + * Get total spent by customer. + * + * @param int $user_id User ID. + * @return string + */ +function wc_get_customer_total_spent( $user_id ) { + $customer = new WC_Customer( $user_id ); + return $customer->get_total_spent(); +} + +/** + * Get total orders by customer. + * + * @param int $user_id User ID. + * @return int + */ +function wc_get_customer_order_count( $user_id ) { + $customer = new WC_Customer( $user_id ); + return $customer->get_order_count(); +} + +/** + * Reset _customer_user on orders when a user is deleted. + * + * @param int $user_id User ID. + */ +function wc_reset_order_customer_id_on_deleted_user( $user_id ) { + global $wpdb; + + $wpdb->update( + $wpdb->postmeta, + array( + 'meta_value' => 0, + ), + array( + 'meta_key' => '_customer_user', + 'meta_value' => $user_id, + ) + ); // WPCS: slow query ok. +} + +add_action( 'deleted_user', 'wc_reset_order_customer_id_on_deleted_user' ); + +/** + * Get review verification status. + * + * @param int $comment_id Comment ID. + * @return bool + */ +function wc_review_is_from_verified_owner( $comment_id ) { + $verified = get_comment_meta( $comment_id, 'verified', true ); + return '' === $verified ? WC_Comments::add_comment_purchase_verification( $comment_id ) : (bool) $verified; +} + +/** + * Disable author archives for customers. + * + * @since 2.5.0 + */ +function wc_disable_author_archives_for_customers() { + global $author; + + if ( is_author() ) { + $user = get_user_by( 'id', $author ); + + if ( user_can( $user, 'customer' ) && ! user_can( $user, 'edit_posts' ) ) { + wp_safe_redirect( wc_get_page_permalink( 'shop' ) ); + exit; + } + } +} + +add_action( 'template_redirect', 'wc_disable_author_archives_for_customers' ); + +/** + * Hooks into the `profile_update` hook to set the user last updated timestamp. + * + * @since 2.6.0 + * @param int $user_id The user that was updated. + * @param array $old The profile fields pre-change. + */ +function wc_update_profile_last_update_time( $user_id, $old ) { + wc_set_user_last_update_time( $user_id ); +} + +add_action( 'profile_update', 'wc_update_profile_last_update_time', 10, 2 ); + +/** + * Hooks into the update user meta function to set the user last updated timestamp. + * + * @since 2.6.0 + * @param int $meta_id ID of the meta object that was changed. + * @param int $user_id The user that was updated. + * @param string $meta_key Name of the meta key that was changed. + * @param string $_meta_value Value of the meta that was changed. + */ +function wc_meta_update_last_update_time( $meta_id, $user_id, $meta_key, $_meta_value ) { + $keys_to_track = apply_filters( 'woocommerce_user_last_update_fields', array( 'first_name', 'last_name' ) ); + + $update_time = in_array( $meta_key, $keys_to_track, true ) ? true : false; + $update_time = 'billing_' === substr( $meta_key, 0, 8 ) ? true : $update_time; + $update_time = 'shipping_' === substr( $meta_key, 0, 9 ) ? true : $update_time; + + if ( $update_time ) { + wc_set_user_last_update_time( $user_id ); + } +} + +add_action( 'update_user_meta', 'wc_meta_update_last_update_time', 10, 4 ); + +/** + * Sets a user's "last update" time to the current timestamp. + * + * @since 2.6.0 + * @param int $user_id The user to set a timestamp for. + */ +function wc_set_user_last_update_time( $user_id ) { + update_user_meta( $user_id, 'last_update', gmdate( 'U' ) ); +} + +/** + * Get customer saved payment methods list. + * + * @since 2.6.0 + * @param int $customer_id Customer ID. + * @return array + */ +function wc_get_customer_saved_methods_list( $customer_id ) { + return apply_filters( 'woocommerce_saved_payment_methods_list', array(), $customer_id ); +} + +/** + * Get info about customer's last order. + * + * @since 2.6.0 + * @param int $customer_id Customer ID. + * @return WC_Order|bool Order object if successful or false. + */ +function wc_get_customer_last_order( $customer_id ) { + $customer = new WC_Customer( $customer_id ); + + return $customer->get_last_order(); +} + +/** + * Add support for searching by display_name. + * + * @since 3.2.0 + * @param array $search_columns Column names. + * @return array + */ +function wc_user_search_columns( $search_columns ) { + $search_columns[] = 'display_name'; + return $search_columns; +} +add_filter( 'user_search_columns', 'wc_user_search_columns' ); + +/** + * When a user is deleted in WordPress, delete corresponding WooCommerce data. + * + * @param int $user_id User ID being deleted. + */ +function wc_delete_user_data( $user_id ) { + global $wpdb; + + // Clean up sessions. + $wpdb->delete( + $wpdb->prefix . 'woocommerce_sessions', + array( + 'session_key' => $user_id, + ) + ); + + // Revoke API keys. + $wpdb->delete( + $wpdb->prefix . 'woocommerce_api_keys', + array( + 'user_id' => $user_id, + ) + ); + + // Clean up payment tokens. + $payment_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id ); + + foreach ( $payment_tokens as $payment_token ) { + $payment_token->delete(); + } +} +add_action( 'delete_user', 'wc_delete_user_data' ); + +/** + * Store user agents. Used for tracker. + * + * @since 3.0.0 + * @param string $user_login User login. + * @param int|object $user User. + */ +function wc_maybe_store_user_agent( $user_login, $user ) { + if ( 'yes' === get_option( 'woocommerce_allow_tracking', 'no' ) && user_can( $user, 'manage_woocommerce' ) ) { + $admin_user_agents = array_filter( (array) get_option( 'woocommerce_tracker_ua', array() ) ); + $admin_user_agents[] = wc_get_user_agent(); + update_option( 'woocommerce_tracker_ua', array_unique( $admin_user_agents ) ); + } +} +add_action( 'wp_login', 'wc_maybe_store_user_agent', 10, 2 ); + +/** + * Update logic triggered on login. + * + * @since 3.4.0 + * @param string $user_login User login. + * @param object $user User. + */ +function wc_user_logged_in( $user_login, $user ) { + wc_update_user_last_active( $user->ID ); + update_user_meta( $user->ID, '_woocommerce_load_saved_cart_after_login', 1 ); +} +add_action( 'wp_login', 'wc_user_logged_in', 10, 2 ); + +/** + * Update when the user was last active. + * + * @since 3.4.0 + */ +function wc_current_user_is_active() { + if ( ! is_user_logged_in() ) { + return; + } + wc_update_user_last_active( get_current_user_id() ); +} +add_action( 'wp', 'wc_current_user_is_active', 10 ); + +/** + * Set the user last active timestamp to now. + * + * @since 3.4.0 + * @param int $user_id User ID to mark active. + */ +function wc_update_user_last_active( $user_id ) { + if ( ! $user_id ) { + return; + } + update_user_meta( $user_id, 'wc_last_active', (string) strtotime( date( 'Y-m-d', time() ) ) ); +} + +/** + * Translate WC roles using the woocommerce textdomain. + * + * @since 3.7.0 + * @param string $translation Translated text. + * @param string $text Text to translate. + * @param string $context Context information for the translators. + * @param string $domain Text domain. Unique identifier for retrieving translated strings. + * @return string + */ +function wc_translate_user_roles( $translation, $text, $context, $domain ) { + // translate_user_role() only accepts a second parameter starting in WP 5.2. + if ( version_compare( get_bloginfo( 'version' ), '5.2', '<' ) ) { + return $translation; + } + + if ( 'User role' === $context && 'default' === $domain && in_array( $text, array( 'Shop manager', 'Customer' ), true ) ) { + return translate_user_role( $text, 'woocommerce' ); + } + + return $translation; +} +add_filter( 'gettext_with_context', 'wc_translate_user_roles', 10, 4 ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-webhook-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-webhook-functions.php new file mode 100644 index 0000000..bc1d159 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-webhook-functions.php @@ -0,0 +1,204 @@ + $data['webhook']->get_id(), + 'arg' => $data['arg'], + ); + + $next_scheduled_date = WC()->queue()->get_next( 'woocommerce_deliver_webhook_async', $queue_args, 'woocommerce-webhooks' ); + + // Make webhooks unique - only schedule one webhook every 10 minutes to maintain backward compatibility with WP Cron behaviour seen in WC < 3.5.0. + if ( is_null( $next_scheduled_date ) || $next_scheduled_date->getTimestamp() >= ( 600 + gmdate( 'U' ) ) ) { + WC()->queue()->add( 'woocommerce_deliver_webhook_async', $queue_args, 'woocommerce-webhooks' ); + } + } else { + // Deliver immediately. + $data['webhook']->deliver( $data['arg'] ); + } + } +} +add_action( 'shutdown', 'wc_webhook_execute_queue' ); + +/** + * Process webhook delivery. + * + * @since 3.3.0 + * @param WC_Webhook $webhook Webhook instance. + * @param array $arg Delivery arguments. + */ +function wc_webhook_process_delivery( $webhook, $arg ) { + // We need to queue the webhook so that it can be ran after the request has finished processing. + global $wc_queued_webhooks; + if ( ! isset( $wc_queued_webhooks ) ) { + $wc_queued_webhooks = array(); + } + $wc_queued_webhooks[] = array( + 'webhook' => $webhook, + 'arg' => $arg, + ); +} +add_action( 'woocommerce_webhook_process_delivery', 'wc_webhook_process_delivery', 10, 2 ); + +/** + * Wrapper function to execute the `woocommerce_deliver_webhook_async` cron. + * hook, see WC_Webhook::process(). + * + * @since 2.2.0 + * @param int $webhook_id Webhook ID to deliver. + * @throws Exception If webhook cannot be read/found and $data parameter of WC_Webhook class constructor is set. + * @param mixed $arg Hook argument. + */ +function wc_deliver_webhook_async( $webhook_id, $arg ) { + $webhook = new WC_Webhook( $webhook_id ); + $webhook->deliver( $arg ); +} +add_action( 'woocommerce_deliver_webhook_async', 'wc_deliver_webhook_async', 10, 2 ); + +/** + * Check if the given topic is a valid webhook topic, a topic is valid if: + * + * + starts with `action.woocommerce_` or `action.wc_`. + * + it has a valid resource & event. + * + * @since 2.2.0 + * @param string $topic Webhook topic. + * @return bool + */ +function wc_is_webhook_valid_topic( $topic ) { + $invalid_topics = array( + 'action.woocommerce_login_credentials', + 'action.woocommerce_product_csv_importer_check_import_file_path', + 'action.woocommerce_webhook_should_deliver', + ); + + if ( in_array( $topic, $invalid_topics, true ) ) { + return false; + } + + // Custom topics are prefixed with woocommerce_ or wc_ are valid. + if ( 0 === strpos( $topic, 'action.woocommerce_' ) || 0 === strpos( $topic, 'action.wc_' ) ) { + return true; + } + + $data = explode( '.', $topic ); + + if ( ! isset( $data[0] ) || ! isset( $data[1] ) ) { + return false; + } + + $valid_resources = apply_filters( 'woocommerce_valid_webhook_resources', array( 'coupon', 'customer', 'order', 'product' ) ); + $valid_events = apply_filters( 'woocommerce_valid_webhook_events', array( 'created', 'updated', 'deleted', 'restored' ) ); + + if ( in_array( $data[0], $valid_resources, true ) && in_array( $data[1], $valid_events, true ) ) { + return true; + } + + return false; +} + +/** + * Check if given status is a valid webhook status. + * + * @since 3.5.3 + * @param string $status Status to check. + * @return bool + */ +function wc_is_webhook_valid_status( $status ) { + return in_array( $status, array_keys( wc_get_webhook_statuses() ), true ); +} + +/** + * Get Webhook statuses. + * + * @since 2.3.0 + * @return array + */ +function wc_get_webhook_statuses() { + return apply_filters( + 'woocommerce_webhook_statuses', + array( + 'active' => __( 'Active', 'woocommerce' ), + 'paused' => __( 'Paused', 'woocommerce' ), + 'disabled' => __( 'Disabled', 'woocommerce' ), + ) + ); +} + +/** + * Load webhooks. + * + * @since 3.3.0 + * @throws Exception If webhook cannot be read/found and $data parameter of WC_Webhook class constructor is set. + * @param string $status Optional - status to filter results by. Must be a key in return value of @see wc_get_webhook_statuses(). @since 3.5.0. + * @param null|int $limit Limit number of webhooks loaded. @since 3.6.0. + * @return bool + */ +function wc_load_webhooks( $status = '', $limit = null ) { + $data_store = WC_Data_Store::load( 'webhook' ); + $webhooks = $data_store->get_webhooks_ids( $status ); + $loaded = 0; + + foreach ( $webhooks as $webhook_id ) { + $webhook = new WC_Webhook( $webhook_id ); + $webhook->enqueue(); + $loaded ++; + + if ( ! is_null( $limit ) && $loaded >= $limit ) { + break; + } + } + + return 0 < $loaded; +} + +/** + * Get webhook. + * + * @param int|WC_Webhook $id Webhook ID or object. + * @throws Exception If webhook cannot be read/found and $data parameter of WC_Webhook class constructor is set. + * @return WC_Webhook|null + */ +function wc_get_webhook( $id ) { + $webhook = new WC_Webhook( $id ); + + return 0 !== $webhook->get_id() ? $webhook : null; +} + +/** + * Get webhoook REST API versions. + * + * @since 3.5.1 + * @return array + */ +function wc_get_webhook_rest_api_versions() { + return array( + 'wp_api_v1', + 'wp_api_v2', + 'wp_api_v3', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-widget-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-widget-functions.php new file mode 100644 index 0000000..49da8f7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wc-widget-functions.php @@ -0,0 +1,52 @@ + 400 ) ); + } + + return true; + } + + /** + * Validates if WP CRON is enabled. + * + * @since 3.8.0 + * @return bool + */ + private static function met_wp_cron_requirement() { + return ! Constants::is_true( 'DISABLE_WP_CRON' ); + } + + /** + * Validates if `WP_CONTENT_DIR` is writable. + * + * @since 3.8.0 + * @return bool + */ + private static function met_filesystem_requirement() { + return is_writable( WP_CONTENT_DIR ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wccom-site/class-wc-wccom-site-installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wccom-site/class-wc-wccom-site-installer.php new file mode 100644 index 0000000..e066141 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wccom-site/class-wc-wccom-site-installer.php @@ -0,0 +1,577 @@ + 'idle', + 'steps' => array(), + 'current_step' => null, + ); + + /** + * Represents product step state. + * + * @var array + */ + private static $default_step_state = array( + 'download_url' => '', + 'product_type' => '', + 'last_step' => '', + 'last_error' => '', + 'download_path' => '', + 'unpacked_path' => '', + 'installed_path' => '', + 'activate' => false, + ); + + /** + * Product install steps. Each step is a method name in this class that + * will be passed with product ID arg \WP_Upgrader instance. + * + * @var array + */ + private static $install_steps = array( + 'get_product_info', + 'download_product', + 'unpack_product', + 'move_product', + 'activate_product', + ); + + /** + * Get the product install state. + * + * @since 3.7.0 + * @param string $key Key in state data. If empty key is passed array of + * state will be returned. + * @return array Product install state. + */ + public static function get_state( $key = '' ) { + $state = WC_Helper_Options::get( 'product_install', self::$default_state ); + if ( ! empty( $key ) ) { + return isset( $state[ $key ] ) ? $state[ $key ] : null; + } + + return $state; + } + + /** + * Update the product install state. + * + * @since 3.7.0 + * @param string $key Key in state data. + * @param mixed $value Value. + */ + public static function update_state( $key, $value ) { + $state = WC_Helper_Options::get( 'product_install', self::$default_state ); + + $state[ $key ] = $value; + WC_Helper_Options::update( 'product_install', $state ); + } + + /** + * Reset product install state. + * + * @since 3.7.0 + * @param array $products List of product IDs. + */ + public static function reset_state( $products = array() ) { + WC()->queue()->cancel_all( 'woocommerce_wccom_install_products' ); + WC_Helper_Options::update( 'product_install', self::$default_state ); + } + + /** + * Schedule installing given list of products. + * + * @since 3.7.0 + * @param array $products Array of products where key is product ID and + * element is install args. + * @return array State. + */ + public static function schedule_install( $products ) { + $state = self::get_state(); + $status = ! empty( $state['status'] ) ? $state['status'] : ''; + if ( 'in-progress' === $status ) { + return $state; + } + self::update_state( 'status', 'in-progress' ); + + $steps = array_fill_keys( array_keys( $products ), self::$default_step_state ); + self::update_state( 'steps', $steps ); + + self::update_state( 'current_step', null ); + + $args = array( + 'products' => $products, + ); + + // Clear the cache of customer's subscription before asking for them. + // Thus, they will be re-fetched from WooCommerce.com after a purchase. + WC_Helper::_flush_subscriptions_cache(); + + WC()->queue()->cancel_all( 'woocommerce_wccom_install_products', $args ); + WC()->queue()->add( 'woocommerce_wccom_install_products', $args ); + + return self::get_state(); + } + + /** + * Install a given product IDs. + * + * Run via `woocommerce_wccom_install_products` hook. + * + * @since 3.7.0 + * @param array $products Array of products where key is product ID and + * element is install args. + */ + public static function install( $products ) { + require_once ABSPATH . 'wp-admin/includes/file.php'; + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + WP_Filesystem(); + $upgrader = new WP_Upgrader( new Automatic_Upgrader_Skin() ); + $upgrader->init(); + wp_clean_plugins_cache(); + + foreach ( $products as $product_id => $install_args ) { + self::install_product( $product_id, $install_args, $upgrader ); + } + + self::finish_installation(); + } + + /** + * Finish installation by updating the state. + * + * @since 3.7.0 + */ + private static function finish_installation() { + $state = self::get_state(); + if ( empty( $state['steps'] ) ) { + return; + } + + foreach ( $state['steps'] as $step ) { + if ( ! empty( $step['last_error'] ) ) { + $state['status'] = 'has_error'; + break; + } + } + + if ( 'has_error' !== $state['status'] ) { + $state['status'] = 'finished'; + } + + WC_Helper_Options::update( 'product_install', $state ); + } + + /** + * Install a single product given its ID. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @param array $install_args Install args. + * @param \WP_Upgrader $upgrader Core class to handle installation. + */ + private static function install_product( $product_id, $install_args, $upgrader ) { + foreach ( self::$install_steps as $step ) { + self::do_install_step( $product_id, $install_args, $step, $upgrader ); + } + } + + /** + * Perform product installation step. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @param array $install_args Install args. + * @param string $step Installation step. + * @param \WP_Upgrader $upgrader Core class to handle installation. + */ + private static function do_install_step( $product_id, $install_args, $step, $upgrader ) { + $state_steps = self::get_state( 'steps' ); + if ( empty( $state_steps[ $product_id ] ) ) { + $state_steps[ $product_id ] = self::$default_step_state; + } + + if ( ! empty( $state_steps[ $product_id ]['last_error'] ) ) { + return; + } + + $state_steps[ $product_id ]['last_step'] = $step; + + if ( ! empty( $install_args['activate'] ) ) { + $state_steps[ $product_id ]['activate'] = true; + } + + self::update_state( + 'current_step', + array( + 'product_id' => $product_id, + 'step' => $step, + ) + ); + + $result = call_user_func( array( __CLASS__, $step ), $product_id, $upgrader ); + if ( is_wp_error( $result ) ) { + $state_steps[ $product_id ]['last_error'] = $result->get_error_message(); + } else { + switch ( $step ) { + case 'get_product_info': + $state_steps[ $product_id ]['download_url'] = $result['download_url']; + $state_steps[ $product_id ]['product_type'] = $result['product_type']; + $state_steps[ $product_id ]['product_name'] = $result['product_name']; + break; + case 'download_product': + $state_steps[ $product_id ]['download_path'] = $result; + break; + case 'unpack_product': + $state_steps[ $product_id ]['unpacked_path'] = $result; + break; + case 'move_product': + $state_steps[ $product_id ]['installed_path'] = $result['destination']; + if ( isset( $result[ self::$folder_exists ] ) ) { + $state_steps[ $product_id ]['warning'] = array( + 'message' => self::$folder_exists, + 'plugin_info' => self::get_plugin_info( $state_steps[ $product_id ]['installed_path'] ), + ); + } + break; + } + } + + self::update_state( 'steps', $state_steps ); + } + + /** + * Get product info from its ID. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @return array|\WP_Error + */ + private static function get_product_info( $product_id ) { + $product_info = array( + 'download_url' => '', + 'product_type' => '', + ); + + // Get product info from woocommerce.com. + $request = WC_Helper_API::get( + add_query_arg( + array( 'product_id' => absint( $product_id ) ), + 'info' + ), + array( + 'authenticated' => true, + ) + ); + + if ( 200 !== wp_remote_retrieve_response_code( $request ) ) { + return new WP_Error( 'product_info_failed', __( 'Failed to retrieve product info from woocommerce.com', 'woocommerce' ) ); + } + + $result = json_decode( wp_remote_retrieve_body( $request ), true ); + + $product_info['product_type'] = $result['_product_type']; + $product_info['product_name'] = $result['name']; + + if ( ! empty( $result['_wporg_product'] ) && ! empty( $result['download_link'] ) ) { + // For wporg product, download is set already from info response. + $product_info['download_url'] = $result['download_link']; + } elseif ( ! WC_Helper::has_product_subscription( $product_id ) ) { + // Non-wporg product needs subscription. + return new WP_Error( 'missing_subscription', __( 'Missing product subscription', 'woocommerce' ) ); + } else { + // Retrieve download URL for non-wporg product. + WC_Helper_Updater::flush_updates_cache(); + $updates = WC_Helper_Updater::get_update_data(); + if ( empty( $updates[ $product_id ]['package'] ) ) { + return new WP_Error( 'missing_product_package', __( 'Could not find product package.', 'woocommerce' ) ); + } + + $product_info['download_url'] = $updates[ $product_id ]['package']; + } + + return $product_info; + } + + /** + * Download product by its ID and returns the path of the zip package. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @param \WP_Upgrader $upgrader Core class to handle installation. + * @return \WP_Error|string + */ + private static function download_product( $product_id, $upgrader ) { + $steps = self::get_state( 'steps' ); + if ( empty( $steps[ $product_id ]['download_url'] ) ) { + return new WP_Error( 'missing_download_url', __( 'Could not find download url for the product.', 'woocommerce' ) ); + } + return $upgrader->download_package( $steps[ $product_id ]['download_url'] ); + } + + /** + * Unpack downloaded product. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @param \WP_Upgrader $upgrader Core class to handle installation. + * @return \WP_Error|string + */ + private static function unpack_product( $product_id, $upgrader ) { + $steps = self::get_state( 'steps' ); + if ( empty( $steps[ $product_id ]['download_path'] ) ) { + return new WP_Error( 'missing_download_path', __( 'Could not find download path.', 'woocommerce' ) ); + } + + return $upgrader->unpack_package( $steps[ $product_id ]['download_path'], true ); + } + + /** + * Move product to plugins directory. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @param \WP_Upgrader $upgrader Core class to handle installation. + * @return array|\WP_Error + */ + private static function move_product( $product_id, $upgrader ) { + $steps = self::get_state( 'steps' ); + if ( empty( $steps[ $product_id ]['unpacked_path'] ) ) { + return new WP_Error( 'missing_unpacked_path', __( 'Could not find unpacked path.', 'woocommerce' ) ); + } + + $destination = 'plugin' === $steps[ $product_id ]['product_type'] + ? WP_PLUGIN_DIR + : get_theme_root(); + + $package = array( + 'source' => $steps[ $product_id ]['unpacked_path'], + 'destination' => $destination, + 'clear_working' => true, + 'hook_extra' => array( + 'type' => $steps[ $product_id ]['product_type'], + 'action' => 'install', + ), + ); + + $result = $upgrader->install_package( $package ); + + /** + * If install package returns error 'folder_exists' threat as success. + */ + if ( is_wp_error( $result ) && array_key_exists( self::$folder_exists, $result->errors ) ) { + return array( + self::$folder_exists => true, + 'destination' => $result->error_data[ self::$folder_exists ], + ); + } + return $result; + } + + /** + * Activate product given its product ID. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @return \WP_Error|null + */ + private static function activate_product( $product_id ) { + $steps = self::get_state( 'steps' ); + if ( ! $steps[ $product_id ]['activate'] ) { + return null; + } + + if ( 'plugin' === $steps[ $product_id ]['product_type'] ) { + return self::activate_plugin( $product_id ); + } + return self::activate_theme( $product_id ); + } + + /** + * Activate plugin given its product ID. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @return \WP_Error|null + */ + private static function activate_plugin( $product_id ) { + // Clear plugins cache used in `WC_Helper::get_local_woo_plugins`. + wp_clean_plugins_cache(); + $filename = false; + + // If product is WP.org one, find out its filename. + $dir_name = self::get_wporg_product_dir_name( $product_id ); + if ( false !== $dir_name ) { + $filename = self::get_wporg_plugin_main_file( $dir_name ); + } + + if ( false === $filename ) { + $plugins = wp_list_filter( + WC_Helper::get_local_woo_plugins(), + array( + '_product_id' => $product_id, + ) + ); + + $filename = is_array( $plugins ) && ! empty( $plugins ) ? key( $plugins ) : ''; + } + + if ( empty( $filename ) ) { + return new WP_Error( 'unknown_filename', __( 'Unknown product filename.', 'woocommerce' ) ); + } + + return activate_plugin( $filename ); + } + + /** + * Activate theme given its product ID. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @return \WP_Error|null + */ + private static function activate_theme( $product_id ) { + // Clear plugins cache used in `WC_Helper::get_local_woo_themes`. + wp_clean_themes_cache(); + $theme_slug = false; + + // If product is WP.org theme, find out its slug. + $dir_name = self::get_wporg_product_dir_name( $product_id ); + if ( false !== $dir_name ) { + $theme_slug = basename( $dir_name ); + } + + if ( false === $theme_slug ) { + $themes = wp_list_filter( + WC_Helper::get_local_woo_themes(), + array( + '_product_id' => $product_id, + ) + ); + + $theme_slug = is_array( $themes ) && ! empty( $themes ) ? dirname( key( $themes ) ) : ''; + } + + if ( empty( $theme_slug ) ) { + return new WP_Error( 'unknown_filename', __( 'Unknown product filename.', 'woocommerce' ) ); + } + + return switch_theme( $theme_slug ); + } + + /** + * Get installed directory of WP.org product. + * + * @since 3.7.0 + * @param int $product_id Product ID. + * @return bool|string + */ + private static function get_wporg_product_dir_name( $product_id ) { + $steps = self::get_state( 'steps' ); + $product = $steps[ $product_id ]; + + if ( empty( $product['download_url'] ) || empty( $product['installed_path'] ) ) { + return false; + } + + // Check whether product was downloaded from WordPress.org. + $parsed_url = wp_parse_url( $product['download_url'] ); + if ( ! empty( $parsed_url['host'] ) && 'downloads.wordpress.org' !== $parsed_url['host'] ) { + return false; + } + + return basename( $product['installed_path'] ); + } + + /** + * Get WP.org plugin's main file. + * + * @since 3.7.0 + * @param string $dir Directory name of the plugin. + * @return bool|string + */ + private static function get_wporg_plugin_main_file( $dir ) { + // Ensure that exact dir name is used. + $dir = trailingslashit( $dir ); + + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $plugins = get_plugins(); + foreach ( $plugins as $path => $plugin ) { + if ( 0 === strpos( $path, $dir ) ) { + return $path; + } + } + + return false; + } + + + /** + * Get plugin info + * + * @since 3.9.0 + * @param string $dir Directory name of the plugin. + * @return bool|array + */ + private static function get_plugin_info( $dir ) { + $plugin_folder = basename( $dir ); + + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $plugins = get_plugins(); + + $related_plugins = array_filter( + $plugins, + function( $key ) use ( $plugin_folder ) { + return strpos( $key, $plugin_folder . '/' ) === 0; + }, + ARRAY_FILTER_USE_KEY + ); + + if ( 1 === count( $related_plugins ) ) { + $plugin_key = array_keys( $related_plugins )[0]; + $plugin_data = $plugins[ $plugin_key ]; + return array( + 'name' => $plugin_data['Name'], + 'version' => $plugin_data['Version'], + 'active' => is_plugin_active( $plugin_key ), + ); + } + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wccom-site/class-wc-wccom-site.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wccom-site/class-wc-wccom-site.php new file mode 100644 index 0000000..d09cb06 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wccom-site/class-wc-wccom-site.php @@ -0,0 +1,253 @@ + WC_REST_WCCOM_Site_Installer_Errors::NO_ACCESS_TOKEN_HTTP_CODE ) + ); + } + ); + return false; + } + + if ( ! empty( $_SERVER['HTTP_X_WOO_SIGNATURE'] ) ) { + $signature = trim( $_SERVER['HTTP_X_WOO_SIGNATURE'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + } elseif ( ! empty( $_GET['signature'] ) && is_string( $_GET['signature'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $signature = trim( $_GET['signature'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + } else { + add_filter( + self::AUTH_ERROR_FILTER_NAME, + function() { + return new WP_Error( + WC_REST_WCCOM_Site_Installer_Errors::NO_SIGNATURE_CODE, + WC_REST_WCCOM_Site_Installer_Errors::NO_SIGNATURE_MESSAGE, + array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::NO_SIGNATURE_HTTP_CODE ) + ); + } + ); + return false; + } + + require_once WC_ABSPATH . 'includes/admin/helper/class-wc-helper-options.php'; + $site_auth = WC_Helper_Options::get( 'auth' ); + + if ( empty( $site_auth['access_token'] ) ) { + add_filter( + self::AUTH_ERROR_FILTER_NAME, + function() { + return new WP_Error( + WC_REST_WCCOM_Site_Installer_Errors::SITE_NOT_CONNECTED_CODE, + WC_REST_WCCOM_Site_Installer_Errors::SITE_NOT_CONNECTED_MESSAGE, + array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::SITE_NOT_CONNECTED_HTTP_CODE ) + ); + } + ); + return false; + } + + if ( ! hash_equals( $access_token, $site_auth['access_token'] ) ) { + add_filter( + self::AUTH_ERROR_FILTER_NAME, + function() { + return new WP_Error( + WC_REST_WCCOM_Site_Installer_Errors::INVALID_TOKEN_CODE, + WC_REST_WCCOM_Site_Installer_Errors::INVALID_TOKEN_MESSAGE, + array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::INVALID_TOKEN_HTTP_CODE ) + ); + } + ); + return false; + } + + $body = WP_REST_Server::get_raw_data(); + + if ( ! self::verify_wccom_request( $body, $signature, $site_auth['access_token_secret'] ) ) { + add_filter( + self::AUTH_ERROR_FILTER_NAME, + function() { + return new WP_Error( + WC_REST_WCCOM_Site_Installer_Errors::REQUEST_VERIFICATION_FAILED_CODE, + WC_REST_WCCOM_Site_Installer_Errors::REQUEST_VERIFICATION_FAILED_MESSAGE, + array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::REQUEST_VERIFICATION_FAILED_HTTP_CODE ) + ); + } + ); + return false; + } + + $user = get_user_by( 'id', $site_auth['user_id'] ); + if ( ! $user ) { + add_filter( + self::AUTH_ERROR_FILTER_NAME, + function() { + return new WP_Error( + WC_REST_WCCOM_Site_Installer_Errors::USER_NOT_FOUND_CODE, + WC_REST_WCCOM_Site_Installer_Errors::USER_NOT_FOUND_MESSAGE, + array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::USER_NOT_FOUND_HTTP_CODE ) + ); + } + ); + return false; + } + + return $user; + } + + /** + * Get the authorization header. + * + * On certain systems and configurations, the Authorization header will be + * stripped out by the server or PHP. Typically this is then used to + * generate `PHP_AUTH_USER`/`PHP_AUTH_PASS` but not passed on. We use + * `getallheaders` here to try and grab it out instead. + * + * @since 3.7.0 + * @return string Authorization header if set. + */ + protected static function get_authorization_header() { + if ( ! empty( $_SERVER['HTTP_AUTHORIZATION'] ) ) { + return wp_unslash( $_SERVER['HTTP_AUTHORIZATION'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + } + + if ( function_exists( 'getallheaders' ) ) { + $headers = getallheaders(); + // Check for the authoization header case-insensitively. + foreach ( $headers as $key => $value ) { + if ( 'authorization' === strtolower( $key ) ) { + return $value; + } + } + } + + return ''; + } + + /** + * Check if this is a request to WCCOM Site REST API. + * + * @since 3.7.0 + * @return bool + */ + protected static function is_request_to_wccom_site_rest_api() { + + if ( isset( $_REQUEST['rest_route'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $route = wp_unslash( $_REQUEST['rest_route'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Recommended + $rest_prefix = ''; + } else { + $route = wp_unslash( add_query_arg( array() ) ); + $rest_prefix = trailingslashit( rest_get_url_prefix() ); + } + + return false !== strpos( $route, $rest_prefix . 'wccom-site/' ); + } + + /** + * Verify WooCommerce.com request from a given body and signature request. + * + * @since 3.7.0 + * @param string $body Request body. + * @param string $signature Request signature found in X-Woo-Signature header. + * @param string $access_token_secret Access token secret for this site. + * @return bool + */ + protected static function verify_wccom_request( $body, $signature, $access_token_secret ) { + // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $data = array( + 'host' => $_SERVER['HTTP_HOST'], + 'request_uri' => urldecode( remove_query_arg( array( 'token', 'signature' ), $_SERVER['REQUEST_URI'] ) ), + 'method' => strtoupper( $_SERVER['REQUEST_METHOD'] ), + ); + // phpcs:enable + + if ( ! empty( $body ) ) { + $data['body'] = $body; + } + + $expected_signature = hash_hmac( 'sha256', wp_json_encode( $data ), $access_token_secret ); + + return hash_equals( $expected_signature, $signature ); + } + + /** + * Register wccom-site REST namespace. + * + * @since 3.7.0 + * @param array $namespaces List of registered namespaces. + * @return array Registered namespaces. + */ + public static function register_rest_namespace( $namespaces ) { + require_once WC_ABSPATH . 'includes/wccom-site/rest-api/class-wc-rest-wccom-site-installer-errors.php'; + require_once WC_ABSPATH . 'includes/wccom-site/rest-api/endpoints/class-wc-rest-wccom-site-installer-controller.php'; + + $namespaces['wccom-site/v1'] = array( + 'installer' => 'WC_REST_WCCOM_Site_Installer_Controller', + ); + + return $namespaces; + } +} + +WC_WCCOM_Site::load(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wccom-site/rest-api/class-wc-rest-wccom-site-installer-errors.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wccom-site/rest-api/class-wc-rest-wccom-site-installer-errors.php new file mode 100644 index 0000000..366b9d0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/wccom-site/rest-api/class-wc-rest-wccom-site-installer-errors.php @@ -0,0 +1,73 @@ +namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_install_state' ), + 'permission_callback' => array( $this, 'check_permission' ), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'install' ), + 'permission_callback' => array( $this, 'check_permission' ), + 'args' => array( + 'products' => array( + 'required' => true, + 'type' => 'object', + ), + ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'reset_install' ), + 'permission_callback' => array( $this, 'check_permission' ), + ), + ) + ); + } + + /** + * Check permissions. + * + * @since 3.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function check_permission( $request ) { + $current_user = wp_get_current_user(); + + if ( empty( $current_user ) || ( $current_user instanceof WP_User && ! $current_user->exists() ) ) { + return apply_filters( + WC_WCCOM_Site::AUTH_ERROR_FILTER_NAME, + new WP_Error( + WC_REST_WCCOM_Site_Installer_Errors::NOT_AUTHENTICATED_CODE, + WC_REST_WCCOM_Site_Installer_Errors::NOT_AUTHENTICATED_MESSAGE, + array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::NOT_AUTHENTICATED_HTTP_CODE ) + ) + ); + } + + if ( ! user_can( $current_user, 'install_plugins' ) || ! user_can( $current_user, 'install_themes' ) ) { + return new WP_Error( + WC_REST_WCCOM_Site_Installer_Errors::NO_PERMISSION_CODE, + WC_REST_WCCOM_Site_Installer_Errors::NO_PERMISSION_MESSAGE, + array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::NO_PERMISSION_HTTP_CODE ) + ); + } + + return true; + } + + /** + * Get installation state. + * + * @since 3.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function get_install_state( $request ) { + $requirements_met = WC_WCCOM_Site_Installer_Requirements_Check::met_requirements(); + if ( is_wp_error( $requirements_met ) ) { + return $requirements_met; + } + + return rest_ensure_response( WC_WCCOM_Site_Installer::get_state() ); + } + + /** + * Install WooCommerce.com products. + * + * @since 3.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function install( $request ) { + $requirements_met = WC_WCCOM_Site_Installer_Requirements_Check::met_requirements(); + if ( is_wp_error( $requirements_met ) ) { + return $requirements_met; + } + + if ( empty( $request['products'] ) ) { + return new WP_Error( 'missing_products', __( 'Missing products in request body.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + $validation_result = $this->validate_products( $request['products'] ); + if ( is_wp_error( $validation_result ) ) { + return $validation_result; + } + + return rest_ensure_response( WC_WCCOM_Site_Installer::schedule_install( $request['products'] ) ); + } + + /** + * Reset installation state. + * + * @since 3.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return bool|WP_Error + */ + public function reset_install( $request ) { + $resp = rest_ensure_response( WC_WCCOM_Site_Installer::reset_state() ); + $resp->set_status( 204 ); + + return $resp; + } + + /** + * Validate products from request body. + * + * @since 3.7.0 + * @param array $products Array of products where key is product ID and + * element is install args. + * @return bool|WP_Error + */ + protected function validate_products( $products ) { + $err = new WP_Error( 'invalid_products', __( 'Invalid products in request body.', 'woocommerce' ), array( 'status' => 400 ) ); + + if ( ! is_array( $products ) ) { + return $err; + } + + foreach ( $products as $product_id => $install_args ) { + if ( ! absint( $product_id ) ) { + return $err; + } + + if ( empty( $install_args ) || ! is_array( $install_args ) ) { + return $err; + } + } + + return true; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-cart.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-cart.php new file mode 100644 index 0000000..cc76280 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-cart.php @@ -0,0 +1,80 @@ +widget_cssclass = 'woocommerce widget_shopping_cart'; + $this->widget_description = __( 'Display the customer shopping cart.', 'woocommerce' ); + $this->widget_id = 'woocommerce_widget_cart'; + $this->widget_name = __( 'Cart', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Cart', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + 'hide_if_empty' => array( + 'type' => 'checkbox', + 'std' => 0, + 'label' => __( 'Hide if cart is empty', 'woocommerce' ), + ), + ); + + if ( is_customize_preview() ) { + wp_enqueue_script( 'wc-cart-fragments' ); + } + + parent::__construct(); + } + + /** + * Output widget. + * + * @see WP_Widget + * + * @param array $args Arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + if ( apply_filters( 'woocommerce_widget_cart_is_hidden', is_cart() || is_checkout() ) ) { + return; + } + + $hide_if_empty = empty( $instance['hide_if_empty'] ) ? 0 : 1; + + if ( ! isset( $instance['title'] ) ) { + $instance['title'] = __( 'Cart', 'woocommerce' ); + } + + $this->widget_start( $args, $instance ); + + if ( $hide_if_empty ) { + echo '
    '; + } + + // Insert cart widget placeholder - code in woocommerce.js will update this on page load. + echo '
    '; + + if ( $hide_if_empty ) { + echo '
    '; + } + + $this->widget_end( $args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav-filters.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav-filters.php new file mode 100644 index 0000000..a333081 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav-filters.php @@ -0,0 +1,113 @@ +widget_cssclass = 'woocommerce widget_layered_nav_filters'; + $this->widget_description = __( 'Display a list of active product filters.', 'woocommerce' ); + $this->widget_id = 'woocommerce_layered_nav_filters'; + $this->widget_name = __( 'Active Product Filters', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Active filters', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + ); + + parent::__construct(); + } + + /** + * Output widget. + * + * @see WP_Widget + * @param array $args Arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + if ( ! is_shop() && ! is_product_taxonomy() ) { + return; + } + + $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes(); + $min_price = isset( $_GET['min_price'] ) ? wc_clean( wp_unslash( $_GET['min_price'] ) ) : 0; // WPCS: input var ok, CSRF ok. + $max_price = isset( $_GET['max_price'] ) ? wc_clean( wp_unslash( $_GET['max_price'] ) ) : 0; // WPCS: input var ok, CSRF ok. + $rating_filter = isset( $_GET['rating_filter'] ) ? array_filter( array_map( 'absint', explode( ',', wp_unslash( $_GET['rating_filter'] ) ) ) ) : array(); // WPCS: sanitization ok, input var ok, CSRF ok. + $base_link = $this->get_current_page_url(); + + if ( 0 < count( $_chosen_attributes ) || 0 < $min_price || 0 < $max_price || ! empty( $rating_filter ) ) { + + $this->widget_start( $args, $instance ); + + echo '
      '; + + // Attributes. + if ( ! empty( $_chosen_attributes ) ) { + foreach ( $_chosen_attributes as $taxonomy => $data ) { + foreach ( $data['terms'] as $term_slug ) { + $term = get_term_by( 'slug', $term_slug, $taxonomy ); + if ( ! $term ) { + continue; + } + + $filter_name = 'filter_' . wc_attribute_taxonomy_slug( $taxonomy ); + $current_filter = isset( $_GET[ $filter_name ] ) ? explode( ',', wc_clean( wp_unslash( $_GET[ $filter_name ] ) ) ) : array(); // WPCS: input var ok, CSRF ok. + $current_filter = array_map( 'sanitize_title', $current_filter ); + $new_filter = array_diff( $current_filter, array( $term_slug ) ); + + $link = remove_query_arg( array( 'add-to-cart', $filter_name ), $base_link ); + + if ( count( $new_filter ) > 0 ) { + $link = add_query_arg( $filter_name, implode( ',', $new_filter ), $link ); + } + + $filter_classes = array( 'chosen', 'chosen-' . sanitize_html_class( str_replace( 'pa_', '', $taxonomy ) ), 'chosen-' . sanitize_html_class( str_replace( 'pa_', '', $taxonomy ) . '-' . $term_slug ) ); + + echo '
    • ' . esc_html( $term->name ) . '
    • '; + } + } + } + + if ( $min_price ) { + $link = remove_query_arg( 'min_price', $base_link ); + /* translators: %s: minimum price */ + echo '
    • ' . sprintf( __( 'Min %s', 'woocommerce' ), wc_price( $min_price ) ) . '
    • '; // WPCS: XSS ok. + } + + if ( $max_price ) { + $link = remove_query_arg( 'max_price', $base_link ); + /* translators: %s: maximum price */ + echo '
    • ' . sprintf( __( 'Max %s', 'woocommerce' ), wc_price( $max_price ) ) . '
    • '; // WPCS: XSS ok. + } + + if ( ! empty( $rating_filter ) ) { + foreach ( $rating_filter as $rating ) { + $link_ratings = implode( ',', array_diff( $rating_filter, array( $rating ) ) ); + $link = $link_ratings ? add_query_arg( 'rating_filter', $link_ratings ) : remove_query_arg( 'rating_filter', $base_link ); + + /* translators: %s: rating */ + echo '
    • ' . sprintf( esc_html__( 'Rated %s out of 5', 'woocommerce' ), esc_html( $rating ) ) . '
    • '; + } + } + + echo '
    '; + + $this->widget_end( $args ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav.php new file mode 100644 index 0000000..1ad76f4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav.php @@ -0,0 +1,532 @@ +widget_cssclass = 'woocommerce widget_layered_nav woocommerce-widget-layered-nav'; + $this->widget_description = __( 'Display a list of attributes to filter products in your store.', 'woocommerce' ); + $this->widget_id = 'woocommerce_layered_nav'; + $this->widget_name = __( 'Filter Products by Attribute', 'woocommerce' ); + parent::__construct(); + } + + /** + * Updates a particular instance of a widget. + * + * @see WP_Widget->update + * + * @param array $new_instance New Instance. + * @param array $old_instance Old Instance. + * + * @return array + */ + public function update( $new_instance, $old_instance ) { + $this->init_settings(); + return parent::update( $new_instance, $old_instance ); + } + + /** + * Outputs the settings update form. + * + * @see WP_Widget->form + * + * @param array $instance Instance. + */ + public function form( $instance ) { + $this->init_settings(); + parent::form( $instance ); + } + + /** + * Init settings after post types are registered. + */ + public function init_settings() { + $attribute_array = array(); + $std_attribute = ''; + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + if ( ! empty( $attribute_taxonomies ) ) { + foreach ( $attribute_taxonomies as $tax ) { + if ( taxonomy_exists( wc_attribute_taxonomy_name( $tax->attribute_name ) ) ) { + $attribute_array[ $tax->attribute_name ] = $tax->attribute_name; + } + } + $std_attribute = current( $attribute_array ); + } + + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Filter by', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + 'attribute' => array( + 'type' => 'select', + 'std' => $std_attribute, + 'label' => __( 'Attribute', 'woocommerce' ), + 'options' => $attribute_array, + ), + 'display_type' => array( + 'type' => 'select', + 'std' => 'list', + 'label' => __( 'Display type', 'woocommerce' ), + 'options' => array( + 'list' => __( 'List', 'woocommerce' ), + 'dropdown' => __( 'Dropdown', 'woocommerce' ), + ), + ), + 'query_type' => array( + 'type' => 'select', + 'std' => 'and', + 'label' => __( 'Query type', 'woocommerce' ), + 'options' => array( + 'and' => __( 'AND', 'woocommerce' ), + 'or' => __( 'OR', 'woocommerce' ), + ), + ), + ); + } + + /** + * Get this widgets taxonomy. + * + * @param array $instance Array of instance options. + * @return string + */ + protected function get_instance_taxonomy( $instance ) { + if ( isset( $instance['attribute'] ) ) { + return wc_attribute_taxonomy_name( $instance['attribute'] ); + } + + $attribute_taxonomies = wc_get_attribute_taxonomies(); + + if ( ! empty( $attribute_taxonomies ) ) { + foreach ( $attribute_taxonomies as $tax ) { + if ( taxonomy_exists( wc_attribute_taxonomy_name( $tax->attribute_name ) ) ) { + return wc_attribute_taxonomy_name( $tax->attribute_name ); + } + } + } + + return ''; + } + + /** + * Get this widgets query type. + * + * @param array $instance Array of instance options. + * @return string + */ + protected function get_instance_query_type( $instance ) { + return isset( $instance['query_type'] ) ? $instance['query_type'] : 'and'; + } + + /** + * Get this widgets display type. + * + * @param array $instance Array of instance options. + * @return string + */ + protected function get_instance_display_type( $instance ) { + return isset( $instance['display_type'] ) ? $instance['display_type'] : 'list'; + } + + /** + * Output widget. + * + * @see WP_Widget + * + * @param array $args Arguments. + * @param array $instance Instance. + */ + public function widget( $args, $instance ) { + if ( ! is_shop() && ! is_product_taxonomy() ) { + return; + } + + $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes(); + $taxonomy = $this->get_instance_taxonomy( $instance ); + $query_type = $this->get_instance_query_type( $instance ); + $display_type = $this->get_instance_display_type( $instance ); + + if ( ! taxonomy_exists( $taxonomy ) ) { + return; + } + + $terms = get_terms( $taxonomy, array( 'hide_empty' => '1' ) ); + + if ( 0 === count( $terms ) ) { + return; + } + + ob_start(); + + $this->widget_start( $args, $instance ); + + if ( 'dropdown' === $display_type ) { + wp_enqueue_script( 'selectWoo' ); + wp_enqueue_style( 'select2' ); + $found = $this->layered_nav_dropdown( $terms, $taxonomy, $query_type ); + } else { + $found = $this->layered_nav_list( $terms, $taxonomy, $query_type ); + } + + $this->widget_end( $args ); + + // Force found when option is selected - do not force found on taxonomy attributes. + if ( ! is_tax() && is_array( $_chosen_attributes ) && array_key_exists( $taxonomy, $_chosen_attributes ) ) { + $found = true; + } + + if ( ! $found ) { + ob_end_clean(); + } else { + echo ob_get_clean(); // @codingStandardsIgnoreLine + } + } + + /** + * Return the currently viewed taxonomy name. + * + * @return string + */ + protected function get_current_taxonomy() { + return is_tax() ? get_queried_object()->taxonomy : ''; + } + + /** + * Return the currently viewed term ID. + * + * @return int + */ + protected function get_current_term_id() { + return absint( is_tax() ? get_queried_object()->term_id : 0 ); + } + + /** + * Return the currently viewed term slug. + * + * @return int + */ + protected function get_current_term_slug() { + return absint( is_tax() ? get_queried_object()->slug : 0 ); + } + + /** + * Show dropdown layered nav. + * + * @param array $terms Terms. + * @param string $taxonomy Taxonomy. + * @param string $query_type Query Type. + * @return bool Will nav display? + */ + protected function layered_nav_dropdown( $terms, $taxonomy, $query_type ) { + global $wp; + $found = false; + + if ( $taxonomy !== $this->get_current_taxonomy() ) { + $term_counts = $this->get_filtered_term_product_counts( wp_list_pluck( $terms, 'term_id' ), $taxonomy, $query_type ); + $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes(); + $taxonomy_filter_name = wc_attribute_taxonomy_slug( $taxonomy ); + $taxonomy_label = wc_attribute_label( $taxonomy ); + + /* translators: %s: taxonomy name */ + $any_label = apply_filters( 'woocommerce_layered_nav_any_label', sprintf( __( 'Any %s', 'woocommerce' ), $taxonomy_label ), $taxonomy_label, $taxonomy ); + $multiple = 'or' === $query_type; + $current_values = isset( $_chosen_attributes[ $taxonomy ]['terms'] ) ? $_chosen_attributes[ $taxonomy ]['terms'] : array(); + + if ( '' === get_option( 'permalink_structure' ) ) { + $form_action = remove_query_arg( array( 'page', 'paged' ), add_query_arg( $wp->query_string, '', home_url( $wp->request ) ) ); + } else { + $form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) ); + } + + echo '
    '; + echo ''; + + if ( $multiple ) { + echo ''; + } + + if ( 'or' === $query_type ) { + echo ''; + } + + echo ''; + echo wc_query_string_form_fields( null, array( 'filter_' . $taxonomy_filter_name, 'query_type_' . $taxonomy_filter_name ), '', true ); // @codingStandardsIgnoreLine + echo '
    '; + + wc_enqueue_js( + " + // Update value on change. + jQuery( '.dropdown_layered_nav_" . esc_js( $taxonomy_filter_name ) . "' ).change( function() { + var slug = jQuery( this ).val(); + jQuery( ':input[name=\"filter_" . esc_js( $taxonomy_filter_name ) . "\"]' ).val( slug ); + + // Submit form on change if standard dropdown. + if ( ! jQuery( this ).attr( 'multiple' ) ) { + jQuery( this ).closest( 'form' ).submit(); + } + }); + + // Use Select2 enhancement if possible + if ( jQuery().selectWoo ) { + var wc_layered_nav_select = function() { + jQuery( '.dropdown_layered_nav_" . esc_js( $taxonomy_filter_name ) . "' ).selectWoo( { + placeholder: decodeURIComponent('" . rawurlencode( (string) wp_specialchars_decode( $any_label ) ) . "'), + minimumResultsForSearch: 5, + width: '100%', + allowClear: " . ( $multiple ? 'false' : 'true' ) . ", + language: { + noResults: function() { + return '" . esc_js( _x( 'No matches found', 'enhanced select', 'woocommerce' ) ) . "'; + } + } + } ); + }; + wc_layered_nav_select(); + } + " + ); + } + + return $found; + } + + /** + * Count products within certain terms, taking the main WP query into consideration. + * + * This query allows counts to be generated based on the viewed products, not all products. + * + * @param array $term_ids Term IDs. + * @param string $taxonomy Taxonomy. + * @param string $query_type Query Type. + * @return array + */ + protected function get_filtered_term_product_counts( $term_ids, $taxonomy, $query_type ) { + global $wpdb; + + $tax_query = $this->get_main_tax_query(); + $meta_query = $this->get_main_meta_query(); + + if ( 'or' === $query_type ) { + foreach ( $tax_query as $key => $query ) { + if ( is_array( $query ) && $taxonomy === $query['taxonomy'] ) { + unset( $tax_query[ $key ] ); + } + } + } + + $meta_query = new WP_Meta_Query( $meta_query ); + $tax_query = new WP_Tax_Query( $tax_query ); + $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); + $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); + $term_ids_sql = '(' . implode( ',', array_map( 'absint', $term_ids ) ) . ')'; + + // Generate query. + $query = array(); + $query['select'] = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) AS term_count, terms.term_id AS term_count_id"; + $query['from'] = "FROM {$wpdb->posts}"; + $query['join'] = " + INNER JOIN {$wpdb->term_relationships} AS term_relationships ON {$wpdb->posts}.ID = term_relationships.object_id + INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id ) + INNER JOIN {$wpdb->terms} AS terms USING( term_id ) + " . $tax_query_sql['join'] . $meta_query_sql['join']; + + $query['where'] = " + WHERE {$wpdb->posts}.post_type IN ( 'product' ) + AND {$wpdb->posts}.post_status = 'publish' + {$tax_query_sql['where']} {$meta_query_sql['where']} + AND terms.term_id IN $term_ids_sql"; + + $search = $this->get_main_search_query_sql(); + if ( $search ) { + $query['where'] .= ' AND ' . $search; + } + + $query['group_by'] = 'GROUP BY terms.term_id'; + $query = apply_filters( 'woocommerce_get_filtered_term_product_counts_query', $query ); + $query_sql = implode( ' ', $query ); + + // We have a query - let's see if cached results of this query already exist. + $query_hash = md5( $query_sql ); + + // Maybe store a transient of the count values. + $cache = apply_filters( 'woocommerce_layered_nav_count_maybe_cache', true ); + if ( true === $cache ) { + $cached_counts = (array) get_transient( 'wc_layered_nav_counts_' . sanitize_title( $taxonomy ) ); + } else { + $cached_counts = array(); + } + + if ( ! isset( $cached_counts[ $query_hash ] ) ) { + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $results = $wpdb->get_results( $query_sql, ARRAY_A ); + $counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) ); + $cached_counts[ $query_hash ] = $counts; + if ( true === $cache ) { + set_transient( 'wc_layered_nav_counts_' . sanitize_title( $taxonomy ), $cached_counts, DAY_IN_SECONDS ); + } + } + + return array_map( 'absint', (array) $cached_counts[ $query_hash ] ); + } + + /** + * Wrapper for WC_Query::get_main_tax_query() to ease unit testing. + * + * @since 4.4.0 + * @return array + */ + protected function get_main_tax_query() { + return WC_Query::get_main_tax_query(); + } + + /** + * Wrapper for WC_Query::get_main_search_query_sql() to ease unit testing. + * + * @since 4.4.0 + * @return string + */ + protected function get_main_search_query_sql() { + return WC_Query::get_main_search_query_sql(); + } + + /** + * Wrapper for WC_Query::get_main_search_queryget_main_meta_query to ease unit testing. + * + * @since 4.4.0 + * @return array + */ + protected function get_main_meta_query() { + return WC_Query::get_main_meta_query(); + } + + /** + * Show list based layered nav. + * + * @param array $terms Terms. + * @param string $taxonomy Taxonomy. + * @param string $query_type Query Type. + * @return bool Will nav display? + */ + protected function layered_nav_list( $terms, $taxonomy, $query_type ) { + // List display. + echo '
      '; + + $term_counts = $this->get_filtered_term_product_counts( wp_list_pluck( $terms, 'term_id' ), $taxonomy, $query_type ); + $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes(); + $found = false; + $base_link = $this->get_current_page_url(); + + foreach ( $terms as $term ) { + $current_values = isset( $_chosen_attributes[ $taxonomy ]['terms'] ) ? $_chosen_attributes[ $taxonomy ]['terms'] : array(); + $option_is_set = in_array( $term->slug, $current_values, true ); + $count = isset( $term_counts[ $term->term_id ] ) ? $term_counts[ $term->term_id ] : 0; + + // Skip the term for the current archive. + if ( $this->get_current_term_id() === $term->term_id ) { + continue; + } + + // Only show options with count > 0. + if ( 0 < $count ) { + $found = true; + } elseif ( 0 === $count && ! $option_is_set ) { + continue; + } + + $filter_name = 'filter_' . wc_attribute_taxonomy_slug( $taxonomy ); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $current_filter = isset( $_GET[ $filter_name ] ) ? explode( ',', wc_clean( wp_unslash( $_GET[ $filter_name ] ) ) ) : array(); + $current_filter = array_map( 'sanitize_title', $current_filter ); + + if ( ! in_array( $term->slug, $current_filter, true ) ) { + $current_filter[] = $term->slug; + } + + $link = remove_query_arg( $filter_name, $base_link ); + + // Add current filters to URL. + foreach ( $current_filter as $key => $value ) { + // Exclude query arg for current term archive term. + if ( $value === $this->get_current_term_slug() ) { + unset( $current_filter[ $key ] ); + } + + // Exclude self so filter can be unset on click. + if ( $option_is_set && $value === $term->slug ) { + unset( $current_filter[ $key ] ); + } + } + + if ( ! empty( $current_filter ) ) { + asort( $current_filter ); + $link = add_query_arg( $filter_name, implode( ',', $current_filter ), $link ); + + // Add Query type Arg to URL. + if ( 'or' === $query_type && ! ( 1 === count( $current_filter ) && $option_is_set ) ) { + $link = add_query_arg( 'query_type_' . wc_attribute_taxonomy_slug( $taxonomy ), 'or', $link ); + } + $link = str_replace( '%2C', ',', $link ); + } + + if ( $count > 0 || $option_is_set ) { + $link = apply_filters( 'woocommerce_layered_nav_link', $link, $term, $taxonomy ); + $term_html = '' . esc_html( $term->name ) . ''; + } else { + $link = false; + $term_html = '' . esc_html( $term->name ) . ''; + } + + $term_html .= ' ' . apply_filters( 'woocommerce_layered_nav_count', '(' . absint( $count ) . ')', $count, $term ); + + echo '
    • '; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.EscapeOutput.OutputNotEscaped + echo apply_filters( 'woocommerce_layered_nav_term_html', $term_html, $term, $link, $count ); + echo '
    • '; + } + + echo '
    '; + + return $found; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-price-filter.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-price-filter.php new file mode 100644 index 0000000..cd8c590 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-price-filter.php @@ -0,0 +1,186 @@ +widget_cssclass = 'woocommerce widget_price_filter'; + $this->widget_description = __( 'Display a slider to filter products in your store by price.', 'woocommerce' ); + $this->widget_id = 'woocommerce_price_filter'; + $this->widget_name = __( 'Filter Products by Price', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Filter by price', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + ); + $suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min'; + $version = Constants::get_constant( 'WC_VERSION' ); + wp_register_script( 'accounting', WC()->plugin_url() . '/assets/js/accounting/accounting' . $suffix . '.js', array( 'jquery' ), '0.4.2', true ); + wp_register_script( 'wc-jquery-ui-touchpunch', WC()->plugin_url() . '/assets/js/jquery-ui-touch-punch/jquery-ui-touch-punch' . $suffix . '.js', array( 'jquery-ui-slider' ), $version, true ); + wp_register_script( 'wc-price-slider', WC()->plugin_url() . '/assets/js/frontend/price-slider' . $suffix . '.js', array( 'jquery-ui-slider', 'wc-jquery-ui-touchpunch', 'accounting' ), $version, true ); + wp_localize_script( + 'wc-price-slider', + 'woocommerce_price_slider_params', + array( + 'currency_format_num_decimals' => 0, + 'currency_format_symbol' => get_woocommerce_currency_symbol(), + 'currency_format_decimal_sep' => esc_attr( wc_get_price_decimal_separator() ), + 'currency_format_thousand_sep' => esc_attr( wc_get_price_thousand_separator() ), + 'currency_format' => esc_attr( str_replace( array( '%1$s', '%2$s' ), array( '%s', '%v' ), get_woocommerce_price_format() ) ), + ) + ); + + if ( is_customize_preview() ) { + wp_enqueue_script( 'wc-price-slider' ); + } + + parent::__construct(); + } + + /** + * Output widget. + * + * @see WP_Widget + * + * @param array $args Arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + global $wp; + + // Requires lookup table added in 3.6. + if ( version_compare( get_option( 'woocommerce_db_version', null ), '3.6', '<' ) ) { + return; + } + + if ( ! is_shop() && ! is_product_taxonomy() ) { + return; + } + + // If there are not posts and we're not filtering, hide the widget. + if ( ! WC()->query->get_main_query()->post_count && ! isset( $_GET['min_price'] ) && ! isset( $_GET['max_price'] ) ) { // WPCS: input var ok, CSRF ok. + return; + } + + wp_enqueue_script( 'wc-price-slider' ); + + // Round values to nearest 10 by default. + $step = max( apply_filters( 'woocommerce_price_filter_widget_step', 10 ), 1 ); + + // Find min and max price in current result set. + $prices = $this->get_filtered_price(); + $min_price = $prices->min_price; + $max_price = $prices->max_price; + + // Check to see if we should add taxes to the prices if store are excl tax but display incl. + $tax_display_mode = get_option( 'woocommerce_tax_display_shop' ); + + if ( wc_tax_enabled() && ! wc_prices_include_tax() && 'incl' === $tax_display_mode ) { + $tax_class = apply_filters( 'woocommerce_price_filter_widget_tax_class', '' ); // Uses standard tax class. + $tax_rates = WC_Tax::get_rates( $tax_class ); + + if ( $tax_rates ) { + $min_price += WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $min_price, $tax_rates ) ); + $max_price += WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $max_price, $tax_rates ) ); + } + } + + $min_price = apply_filters( 'woocommerce_price_filter_widget_min_amount', floor( $min_price / $step ) * $step ); + $max_price = apply_filters( 'woocommerce_price_filter_widget_max_amount', ceil( $max_price / $step ) * $step ); + + // If both min and max are equal, we don't need a slider. + if ( $min_price === $max_price ) { + return; + } + + $current_min_price = isset( $_GET['min_price'] ) ? floor( floatval( wp_unslash( $_GET['min_price'] ) ) / $step ) * $step : $min_price; // WPCS: input var ok, CSRF ok. + $current_max_price = isset( $_GET['max_price'] ) ? ceil( floatval( wp_unslash( $_GET['max_price'] ) ) / $step ) * $step : $max_price; // WPCS: input var ok, CSRF ok. + + $this->widget_start( $args, $instance ); + + if ( '' === get_option( 'permalink_structure' ) ) { + $form_action = remove_query_arg( array( 'page', 'paged', 'product-page' ), add_query_arg( $wp->query_string, '', home_url( $wp->request ) ) ); + } else { + $form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) ); + } + + wc_get_template( + 'content-widget-price-filter.php', + array( + 'form_action' => $form_action, + 'step' => $step, + 'min_price' => $min_price, + 'max_price' => $max_price, + 'current_min_price' => $current_min_price, + 'current_max_price' => $current_max_price, + ) + ); + + $this->widget_end( $args ); + } + + /** + * Get filtered min price for current products. + * + * @return int + */ + protected function get_filtered_price() { + global $wpdb; + + $args = WC()->query->get_main_query()->query_vars; + $tax_query = isset( $args['tax_query'] ) ? $args['tax_query'] : array(); + $meta_query = isset( $args['meta_query'] ) ? $args['meta_query'] : array(); + + if ( ! is_post_type_archive( 'product' ) && ! empty( $args['taxonomy'] ) && ! empty( $args['term'] ) ) { + $tax_query[] = WC()->query->get_main_tax_query(); + } + + foreach ( $meta_query + $tax_query as $key => $query ) { + if ( ! empty( $query['price_filter'] ) || ! empty( $query['rating_filter'] ) ) { + unset( $meta_query[ $key ] ); + } + } + + $meta_query = new WP_Meta_Query( $meta_query ); + $tax_query = new WP_Tax_Query( $tax_query ); + $search = WC_Query::get_main_search_query_sql(); + + $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); + $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); + $search_query_sql = $search ? ' AND ' . $search : ''; + + $sql = " + SELECT min( min_price ) as min_price, MAX( max_price ) as max_price + FROM {$wpdb->wc_product_meta_lookup} + WHERE product_id IN ( + SELECT ID FROM {$wpdb->posts} + " . $tax_query_sql['join'] . $meta_query_sql['join'] . " + WHERE {$wpdb->posts}.post_type IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_post_type', array( 'product' ) ) ) ) . "') + AND {$wpdb->posts}.post_status = 'publish' + " . $tax_query_sql['where'] . $meta_query_sql['where'] . $search_query_sql . ' + )'; + + $sql = apply_filters( 'woocommerce_price_filter_sql', $sql, $meta_query_sql, $tax_query_sql ); + + return $wpdb->get_row( $sql ); // WPCS: unprepared SQL ok. + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-product-categories.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-product-categories.php new file mode 100644 index 0000000..26b590b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-product-categories.php @@ -0,0 +1,301 @@ +widget_cssclass = 'woocommerce widget_product_categories'; + $this->widget_description = __( 'A list or dropdown of product categories.', 'woocommerce' ); + $this->widget_id = 'woocommerce_product_categories'; + $this->widget_name = __( 'Product Categories', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Product categories', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + 'orderby' => array( + 'type' => 'select', + 'std' => 'name', + 'label' => __( 'Order by', 'woocommerce' ), + 'options' => array( + 'order' => __( 'Category order', 'woocommerce' ), + 'name' => __( 'Name', 'woocommerce' ), + ), + ), + 'dropdown' => array( + 'type' => 'checkbox', + 'std' => 0, + 'label' => __( 'Show as dropdown', 'woocommerce' ), + ), + 'count' => array( + 'type' => 'checkbox', + 'std' => 0, + 'label' => __( 'Show product counts', 'woocommerce' ), + ), + 'hierarchical' => array( + 'type' => 'checkbox', + 'std' => 1, + 'label' => __( 'Show hierarchy', 'woocommerce' ), + ), + 'show_children_only' => array( + 'type' => 'checkbox', + 'std' => 0, + 'label' => __( 'Only show children of the current category', 'woocommerce' ), + ), + 'hide_empty' => array( + 'type' => 'checkbox', + 'std' => 0, + 'label' => __( 'Hide empty categories', 'woocommerce' ), + ), + 'max_depth' => array( + 'type' => 'text', + 'std' => '', + 'label' => __( 'Maximum depth', 'woocommerce' ), + ), + ); + + parent::__construct(); + } + + /** + * Output widget. + * + * @see WP_Widget + * @param array $args Widget arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + global $wp_query, $post; + + $count = isset( $instance['count'] ) ? $instance['count'] : $this->settings['count']['std']; + $hierarchical = isset( $instance['hierarchical'] ) ? $instance['hierarchical'] : $this->settings['hierarchical']['std']; + $show_children_only = isset( $instance['show_children_only'] ) ? $instance['show_children_only'] : $this->settings['show_children_only']['std']; + $dropdown = isset( $instance['dropdown'] ) ? $instance['dropdown'] : $this->settings['dropdown']['std']; + $orderby = isset( $instance['orderby'] ) ? $instance['orderby'] : $this->settings['orderby']['std']; + $hide_empty = isset( $instance['hide_empty'] ) ? $instance['hide_empty'] : $this->settings['hide_empty']['std']; + $dropdown_args = array( + 'hide_empty' => $hide_empty, + ); + $list_args = array( + 'show_count' => $count, + 'hierarchical' => $hierarchical, + 'taxonomy' => 'product_cat', + 'hide_empty' => $hide_empty, + ); + $max_depth = absint( isset( $instance['max_depth'] ) ? $instance['max_depth'] : $this->settings['max_depth']['std'] ); + + $list_args['menu_order'] = false; + $dropdown_args['depth'] = $max_depth; + $list_args['depth'] = $max_depth; + + if ( 'order' === $orderby ) { + $list_args['orderby'] = 'meta_value_num'; + $dropdown_args['orderby'] = 'meta_value_num'; + $list_args['meta_key'] = 'order'; + $dropdown_args['meta_key'] = 'order'; + } + + $this->current_cat = false; + $this->cat_ancestors = array(); + + if ( is_tax( 'product_cat' ) ) { + $this->current_cat = $wp_query->queried_object; + $this->cat_ancestors = get_ancestors( $this->current_cat->term_id, 'product_cat' ); + + } elseif ( is_singular( 'product' ) ) { + $terms = wc_get_product_terms( + $post->ID, + 'product_cat', + apply_filters( + 'woocommerce_product_categories_widget_product_terms_args', + array( + 'orderby' => 'parent', + 'order' => 'DESC', + ) + ) + ); + + if ( $terms ) { + $main_term = apply_filters( 'woocommerce_product_categories_widget_main_term', $terms[0], $terms ); + $this->current_cat = $main_term; + $this->cat_ancestors = get_ancestors( $main_term->term_id, 'product_cat' ); + } + } + + // Show Siblings and Children Only. + if ( $show_children_only && $this->current_cat ) { + if ( $hierarchical ) { + $include = array_merge( + $this->cat_ancestors, + array( $this->current_cat->term_id ), + get_terms( + 'product_cat', + array( + 'fields' => 'ids', + 'parent' => 0, + 'hierarchical' => true, + 'hide_empty' => false, + ) + ), + get_terms( + 'product_cat', + array( + 'fields' => 'ids', + 'parent' => $this->current_cat->term_id, + 'hierarchical' => true, + 'hide_empty' => false, + ) + ) + ); + // Gather siblings of ancestors. + if ( $this->cat_ancestors ) { + foreach ( $this->cat_ancestors as $ancestor ) { + $include = array_merge( + $include, + get_terms( + 'product_cat', + array( + 'fields' => 'ids', + 'parent' => $ancestor, + 'hierarchical' => false, + 'hide_empty' => false, + ) + ) + ); + } + } + } else { + // Direct children. + $include = get_terms( + 'product_cat', + array( + 'fields' => 'ids', + 'parent' => $this->current_cat->term_id, + 'hierarchical' => true, + 'hide_empty' => false, + ) + ); + } + + $list_args['include'] = implode( ',', $include ); + $dropdown_args['include'] = $list_args['include']; + + if ( empty( $include ) ) { + return; + } + } elseif ( $show_children_only ) { + $dropdown_args['depth'] = 1; + $dropdown_args['child_of'] = 0; + $dropdown_args['hierarchical'] = 1; + $list_args['depth'] = 1; + $list_args['child_of'] = 0; + $list_args['hierarchical'] = 1; + } + + $this->widget_start( $args, $instance ); + + if ( $dropdown ) { + wc_product_dropdown_categories( + apply_filters( + 'woocommerce_product_categories_widget_dropdown_args', + wp_parse_args( + $dropdown_args, + array( + 'show_count' => $count, + 'hierarchical' => $hierarchical, + 'show_uncategorized' => 0, + 'selected' => $this->current_cat ? $this->current_cat->slug : '', + ) + ) + ) + ); + + wp_enqueue_script( 'selectWoo' ); + wp_enqueue_style( 'select2' ); + + wc_enqueue_js( + " + jQuery( '.dropdown_product_cat' ).change( function() { + if ( jQuery(this).val() != '' ) { + var this_page = ''; + var home_url = '" . esc_js( home_url( '/' ) ) . "'; + if ( home_url.indexOf( '?' ) > 0 ) { + this_page = home_url + '&product_cat=' + jQuery(this).val(); + } else { + this_page = home_url + '?product_cat=' + jQuery(this).val(); + } + location.href = this_page; + } else { + location.href = '" . esc_js( wc_get_page_permalink( 'shop' ) ) . "'; + } + }); + + if ( jQuery().selectWoo ) { + var wc_product_cat_select = function() { + jQuery( '.dropdown_product_cat' ).selectWoo( { + placeholder: '" . esc_js( __( 'Select a category', 'woocommerce' ) ) . "', + minimumResultsForSearch: 5, + width: '100%', + allowClear: true, + language: { + noResults: function() { + return '" . esc_js( _x( 'No matches found', 'enhanced select', 'woocommerce' ) ) . "'; + } + } + } ); + }; + wc_product_cat_select(); + } + " + ); + } else { + include_once WC()->plugin_path() . '/includes/walkers/class-wc-product-cat-list-walker.php'; + + $list_args['walker'] = new WC_Product_Cat_List_Walker(); + $list_args['title_li'] = ''; + $list_args['pad_counts'] = 1; + $list_args['show_option_none'] = __( 'No product categories exist.', 'woocommerce' ); + $list_args['current_category'] = ( $this->current_cat ) ? $this->current_cat->term_id : ''; + $list_args['current_category_ancestors'] = $this->cat_ancestors; + $list_args['max_depth'] = $max_depth; + + echo '
      '; + + wp_list_categories( apply_filters( 'woocommerce_product_categories_widget_args', $list_args ) ); + + echo '
    '; + } + + $this->widget_end( $args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-product-search.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-product-search.php new file mode 100644 index 0000000..c27debb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-product-search.php @@ -0,0 +1,50 @@ +widget_cssclass = 'woocommerce widget_product_search'; + $this->widget_description = __( 'A search form for your store.', 'woocommerce' ); + $this->widget_id = 'woocommerce_product_search'; + $this->widget_name = __( 'Product Search', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => '', + 'label' => __( 'Title', 'woocommerce' ), + ), + ); + + parent::__construct(); + } + + /** + * Output widget. + * + * @see WP_Widget + * + * @param array $args Arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + $this->widget_start( $args, $instance ); + + get_product_search_form(); + + $this->widget_end( $args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-product-tag-cloud.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-product-tag-cloud.php new file mode 100644 index 0000000..4d85bc0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-product-tag-cloud.php @@ -0,0 +1,121 @@ +widget_cssclass = 'woocommerce widget_product_tag_cloud'; + $this->widget_description = __( 'A cloud of your most used product tags.', 'woocommerce' ); + $this->widget_id = 'woocommerce_product_tag_cloud'; + $this->widget_name = __( 'Product Tag Cloud', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Product tags', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + ); + + parent::__construct(); + } + + /** + * Output widget. + * + * @see WP_Widget + * + * @param array $args Arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + $current_taxonomy = $this->get_current_taxonomy( $instance ); + + if ( empty( $instance['title'] ) ) { + $taxonomy = get_taxonomy( $current_taxonomy ); + $instance['title'] = $taxonomy->labels->name; + } + + $this->widget_start( $args, $instance ); + + echo '
    '; + + wp_tag_cloud( + apply_filters( + 'woocommerce_product_tag_cloud_widget_args', + array( + 'taxonomy' => $current_taxonomy, + 'topic_count_text_callback' => array( $this, 'topic_count_text' ), + ) + ) + ); + + echo '
    '; + + $this->widget_end( $args ); + } + + /** + * Return the taxonomy being displayed. + * + * @param object $instance Widget instance. + * @return string + */ + public function get_current_taxonomy( $instance ) { + return 'product_tag'; + } + + /** + * Returns topic count text. + * + * @since 3.4.0 + * @param int $count Count text. + * @return string + */ + public function topic_count_text( $count ) { + /* translators: %s: product count */ + return sprintf( _n( '%s product', '%s products', $count, 'woocommerce' ), number_format_i18n( $count ) ); + } + + // Ignore whole block to avoid warnings about PSR2.Methods.MethodDeclaration.Underscore violation. + // @codingStandardsIgnoreStart + /** + * Return the taxonomy being displayed. + * + * @deprecated 3.4.0 + * @param object $instance Widget instance. + * @return string + */ + public function _get_current_taxonomy( $instance ) { + wc_deprecated_function( '_get_current_taxonomy', '3.4.0', 'WC_Widget_Product_Tag_Cloud->get_current_taxonomy' ); + return $this->get_current_taxonomy( $instance ); + } + + /** + * Returns topic count text. + * + * @deprecated 3.4.0 + * @since 2.6.0 + * @param int $count Count text. + * @return string + */ + public function _topic_count_text( $count ) { + wc_deprecated_function( '_topic_count_text', '3.4.0', 'WC_Widget_Product_Tag_Cloud->topic_count_text' ); + return $this->topic_count_text( $count ); + } + // @codingStandardsIgnoreEnd +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-products.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-products.php new file mode 100644 index 0000000..be37348 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-products.php @@ -0,0 +1,214 @@ +widget_cssclass = 'woocommerce widget_products'; + $this->widget_description = __( "A list of your store's products.", 'woocommerce' ); + $this->widget_id = 'woocommerce_products'; + $this->widget_name = __( 'Products', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Products', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + 'number' => array( + 'type' => 'number', + 'step' => 1, + 'min' => 1, + 'max' => '', + 'std' => 5, + 'label' => __( 'Number of products to show', 'woocommerce' ), + ), + 'show' => array( + 'type' => 'select', + 'std' => '', + 'label' => __( 'Show', 'woocommerce' ), + 'options' => array( + '' => __( 'All products', 'woocommerce' ), + 'featured' => __( 'Featured products', 'woocommerce' ), + 'onsale' => __( 'On-sale products', 'woocommerce' ), + ), + ), + 'orderby' => array( + 'type' => 'select', + 'std' => 'date', + 'label' => __( 'Order by', 'woocommerce' ), + 'options' => array( + 'date' => __( 'Date', 'woocommerce' ), + 'price' => __( 'Price', 'woocommerce' ), + 'rand' => __( 'Random', 'woocommerce' ), + 'sales' => __( 'Sales', 'woocommerce' ), + ), + ), + 'order' => array( + 'type' => 'select', + 'std' => 'desc', + 'label' => _x( 'Order', 'Sorting order', 'woocommerce' ), + 'options' => array( + 'asc' => __( 'ASC', 'woocommerce' ), + 'desc' => __( 'DESC', 'woocommerce' ), + ), + ), + 'hide_free' => array( + 'type' => 'checkbox', + 'std' => 0, + 'label' => __( 'Hide free products', 'woocommerce' ), + ), + 'show_hidden' => array( + 'type' => 'checkbox', + 'std' => 0, + 'label' => __( 'Show hidden products', 'woocommerce' ), + ), + ); + + parent::__construct(); + } + + /** + * Query the products and return them. + * + * @param array $args Arguments. + * @param array $instance Widget instance. + * + * @return WP_Query + */ + public function get_products( $args, $instance ) { + $number = ! empty( $instance['number'] ) ? absint( $instance['number'] ) : $this->settings['number']['std']; + $show = ! empty( $instance['show'] ) ? sanitize_title( $instance['show'] ) : $this->settings['show']['std']; + $orderby = ! empty( $instance['orderby'] ) ? sanitize_title( $instance['orderby'] ) : $this->settings['orderby']['std']; + $order = ! empty( $instance['order'] ) ? sanitize_title( $instance['order'] ) : $this->settings['order']['std']; + $product_visibility_term_ids = wc_get_product_visibility_term_ids(); + + $query_args = array( + 'posts_per_page' => $number, + 'post_status' => 'publish', + 'post_type' => 'product', + 'no_found_rows' => 1, + 'order' => $order, + 'meta_query' => array(), + 'tax_query' => array( + 'relation' => 'AND', + ), + ); // WPCS: slow query ok. + + if ( empty( $instance['show_hidden'] ) ) { + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => is_search() ? $product_visibility_term_ids['exclude-from-search'] : $product_visibility_term_ids['exclude-from-catalog'], + 'operator' => 'NOT IN', + ); + $query_args['post_parent'] = 0; + } + + if ( ! empty( $instance['hide_free'] ) ) { + $query_args['meta_query'][] = array( + 'key' => '_price', + 'value' => 0, + 'compare' => '>', + 'type' => 'DECIMAL', + ); + } + + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) { + $query_args['tax_query'][] = array( + array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => $product_visibility_term_ids['outofstock'], + 'operator' => 'NOT IN', + ), + ); // WPCS: slow query ok. + } + + switch ( $show ) { + case 'featured': + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => $product_visibility_term_ids['featured'], + ); + break; + case 'onsale': + $product_ids_on_sale = wc_get_product_ids_on_sale(); + $product_ids_on_sale[] = 0; + $query_args['post__in'] = $product_ids_on_sale; + break; + } + + switch ( $orderby ) { + case 'price': + $query_args['meta_key'] = '_price'; // WPCS: slow query ok. + $query_args['orderby'] = 'meta_value_num'; + break; + case 'rand': + $query_args['orderby'] = 'rand'; + break; + case 'sales': + $query_args['meta_key'] = 'total_sales'; // WPCS: slow query ok. + $query_args['orderby'] = 'meta_value_num'; + break; + default: + $query_args['orderby'] = 'date'; + } + + return new WP_Query( apply_filters( 'woocommerce_products_widget_query_args', $query_args ) ); + } + + /** + * Output widget. + * + * @param array $args Arguments. + * @param array $instance Widget instance. + * + * @see WP_Widget + */ + public function widget( $args, $instance ) { + if ( $this->get_cached_widget( $args ) ) { + return; + } + + ob_start(); + + $products = $this->get_products( $args, $instance ); + if ( $products && $products->have_posts() ) { + $this->widget_start( $args, $instance ); + + echo wp_kses_post( apply_filters( 'woocommerce_before_widget_product_list', '
      ' ) ); + + $template_args = array( + 'widget_id' => isset( $args['widget_id'] ) ? $args['widget_id'] : $this->widget_id, + 'show_rating' => true, + ); + + while ( $products->have_posts() ) { + $products->the_post(); + wc_get_template( 'content-widget-product.php', $template_args ); + } + + echo wp_kses_post( apply_filters( 'woocommerce_after_widget_product_list', '
    ' ) ); + + $this->widget_end( $args ); + } + + wp_reset_postdata(); + + echo $this->cache_widget( $args, ob_get_clean() ); // WPCS: XSS ok. + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-rating-filter.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-rating-filter.php new file mode 100644 index 0000000..6690388 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-rating-filter.php @@ -0,0 +1,147 @@ +widget_cssclass = 'woocommerce widget_rating_filter'; + $this->widget_description = __( 'Display a list of star ratings to filter products in your store.', 'woocommerce' ); + $this->widget_id = 'woocommerce_rating_filter'; + $this->widget_name = __( 'Filter Products by Rating', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Average rating', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + ); + parent::__construct(); + } + + /** + * Count products after other filters have occurred by adjusting the main query. + * + * @param int $rating Rating. + * @return int + */ + protected function get_filtered_product_count( $rating ) { + global $wpdb; + + $tax_query = WC_Query::get_main_tax_query(); + $meta_query = WC_Query::get_main_meta_query(); + + // Unset current rating filter. + foreach ( $tax_query as $key => $query ) { + if ( ! empty( $query['rating_filter'] ) ) { + unset( $tax_query[ $key ] ); + break; + } + } + + // Set new rating filter. + $product_visibility_terms = wc_get_product_visibility_term_ids(); + $tax_query[] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => $product_visibility_terms[ 'rated-' . $rating ], + 'operator' => 'IN', + 'rating_filter' => true, + ); + + $meta_query = new WP_Meta_Query( $meta_query ); + $tax_query = new WP_Tax_Query( $tax_query ); + $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); + $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); + + $sql = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) FROM {$wpdb->posts} "; + $sql .= $tax_query_sql['join'] . $meta_query_sql['join']; + $sql .= " WHERE {$wpdb->posts}.post_type = 'product' AND {$wpdb->posts}.post_status = 'publish' "; + $sql .= $tax_query_sql['where'] . $meta_query_sql['where']; + + $search = WC_Query::get_main_search_query_sql(); + if ( $search ) { + $sql .= ' AND ' . $search; + } + + return absint( $wpdb->get_var( $sql ) ); // WPCS: unprepared SQL ok. + } + + /** + * Widget function. + * + * @see WP_Widget + * @param array $args Arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + if ( ! is_shop() && ! is_product_taxonomy() ) { + return; + } + + if ( ! WC()->query->get_main_query()->post_count ) { + return; + } + + ob_start(); + + $found = false; + $rating_filter = isset( $_GET['rating_filter'] ) ? array_filter( array_map( 'absint', explode( ',', wp_unslash( $_GET['rating_filter'] ) ) ) ) : array(); // WPCS: input var ok, CSRF ok, sanitization ok. + $base_link = remove_query_arg( 'paged', $this->get_current_page_url() ); + + $this->widget_start( $args, $instance ); + + echo '
      '; + + for ( $rating = 5; $rating >= 1; $rating-- ) { + $count = $this->get_filtered_product_count( $rating ); + if ( empty( $count ) ) { + continue; + } + $found = true; + $link = $base_link; + + if ( in_array( $rating, $rating_filter, true ) ) { + $link_ratings = implode( ',', array_diff( $rating_filter, array( $rating ) ) ); + } else { + $link_ratings = implode( ',', array_merge( $rating_filter, array( $rating ) ) ); + } + + $class = in_array( $rating, $rating_filter, true ) ? 'wc-layered-nav-rating chosen' : 'wc-layered-nav-rating'; + $link = apply_filters( 'woocommerce_rating_filter_link', $link_ratings ? add_query_arg( 'rating_filter', $link_ratings, $link ) : remove_query_arg( 'rating_filter' ) ); + $rating_html = wc_get_star_rating_html( $rating ); + $count_html = wp_kses( + apply_filters( 'woocommerce_rating_filter_count', "({$count})", $count, $rating ), + array( + 'em' => array(), + 'span' => array(), + 'strong' => array(), + ) + ); + + printf( '
    • %s %s
    • ', esc_attr( $class ), esc_url( $link ), $rating_html, $count_html ); // WPCS: XSS ok. + } + + echo '
    '; + + $this->widget_end( $args ); + + if ( ! $found ) { + ob_end_clean(); + } else { + echo ob_get_clean(); // WPCS: XSS ok. + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-recent-reviews.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-recent-reviews.php new file mode 100644 index 0000000..635e269 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-recent-reviews.php @@ -0,0 +1,97 @@ +widget_cssclass = 'woocommerce widget_recent_reviews'; + $this->widget_description = __( 'Display a list of recent reviews from your store.', 'woocommerce' ); + $this->widget_id = 'woocommerce_recent_reviews'; + $this->widget_name = __( 'Recent Product Reviews', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Recent reviews', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + 'number' => array( + 'type' => 'number', + 'step' => 1, + 'min' => 1, + 'max' => '', + 'std' => 10, + 'label' => __( 'Number of reviews to show', 'woocommerce' ), + ), + ); + + parent::__construct(); + } + + /** + * Output widget. + * + * @see WP_Widget + * @param array $args Arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + global $comments, $comment; + + if ( $this->get_cached_widget( $args ) ) { + return; + } + + ob_start(); + + $number = ! empty( $instance['number'] ) ? absint( $instance['number'] ) : $this->settings['number']['std']; + $comments = get_comments( + array( + 'number' => $number, + 'status' => 'approve', + 'post_status' => 'publish', + 'post_type' => 'product', + 'parent' => 0, + ) + ); // WPCS: override ok. + + if ( $comments ) { + $this->widget_start( $args, $instance ); + + echo wp_kses_post( apply_filters( 'woocommerce_before_widget_product_review_list', '
      ' ) ); + + foreach ( (array) $comments as $comment ) { + wc_get_template( + 'content-widget-reviews.php', + array( + 'comment' => $comment, + 'product' => wc_get_product( $comment->comment_post_ID ), + ) + ); + } + + echo wp_kses_post( apply_filters( 'woocommerce_after_widget_product_review_list', '
    ' ) ); + + $this->widget_end( $args ); + + } + + $content = ob_get_clean(); + + echo $content; // WPCS: XSS ok. + + $this->cache_widget( $args, $content ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-recently-viewed.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-recently-viewed.php new file mode 100644 index 0000000..e023927 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-recently-viewed.php @@ -0,0 +1,110 @@ +widget_cssclass = 'woocommerce widget_recently_viewed_products'; + $this->widget_description = __( "Display a list of a customer's recently viewed products.", 'woocommerce' ); + $this->widget_id = 'woocommerce_recently_viewed_products'; + $this->widget_name = __( 'Recent Viewed Products', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Recently Viewed Products', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + 'number' => array( + 'type' => 'number', + 'step' => 1, + 'min' => 1, + 'max' => 15, + 'std' => 10, + 'label' => __( 'Number of products to show', 'woocommerce' ), + ), + ); + + parent::__construct(); + } + + /** + * Output widget. + * + * @see WP_Widget + * @param array $args Arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + $viewed_products = ! empty( $_COOKIE['woocommerce_recently_viewed'] ) ? (array) explode( '|', wp_unslash( $_COOKIE['woocommerce_recently_viewed'] ) ) : array(); // @codingStandardsIgnoreLine + $viewed_products = array_reverse( array_filter( array_map( 'absint', $viewed_products ) ) ); + + if ( empty( $viewed_products ) ) { + return; + } + + ob_start(); + + $number = ! empty( $instance['number'] ) ? absint( $instance['number'] ) : $this->settings['number']['std']; + + $query_args = array( + 'posts_per_page' => $number, + 'no_found_rows' => 1, + 'post_status' => 'publish', + 'post_type' => 'product', + 'post__in' => $viewed_products, + 'orderby' => 'post__in', + ); + + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) { + $query_args['tax_query'] = array( + array( + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => 'outofstock', + 'operator' => 'NOT IN', + ), + ); // WPCS: slow query ok. + } + + $r = new WP_Query( apply_filters( 'woocommerce_recently_viewed_products_widget_query_args', $query_args ) ); + + if ( $r->have_posts() ) { + + $this->widget_start( $args, $instance ); + + echo wp_kses_post( apply_filters( 'woocommerce_before_widget_product_list', '
      ' ) ); + + $template_args = array( + 'widget_id' => isset( $args['widget_id'] ) ? $args['widget_id'] : $this->widget_id, + ); + + while ( $r->have_posts() ) { + $r->the_post(); + wc_get_template( 'content-widget-product.php', $template_args ); + } + + echo wp_kses_post( apply_filters( 'woocommerce_after_widget_product_list', '
    ' ) ); + + $this->widget_end( $args ); + } + + wp_reset_postdata(); + + $content = ob_get_clean(); + + echo $content; // WPCS: XSS ok. + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-top-rated-products.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-top-rated-products.php new file mode 100644 index 0000000..a5241ec --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-top-rated-products.php @@ -0,0 +1,107 @@ +widget_cssclass = 'woocommerce widget_top_rated_products'; + $this->widget_description = __( "A list of your store's top-rated products.", 'woocommerce' ); + $this->widget_id = 'woocommerce_top_rated_products'; + $this->widget_name = __( 'Products by Rating', 'woocommerce' ); + $this->settings = array( + 'title' => array( + 'type' => 'text', + 'std' => __( 'Top rated products', 'woocommerce' ), + 'label' => __( 'Title', 'woocommerce' ), + ), + 'number' => array( + 'type' => 'number', + 'step' => 1, + 'min' => 1, + 'max' => '', + 'std' => 5, + 'label' => __( 'Number of products to show', 'woocommerce' ), + ), + ); + + parent::__construct(); + } + + /** + * Output widget. + * + * @see WP_Widget + * @param array $args Arguments. + * @param array $instance Widget instance. + */ + public function widget( $args, $instance ) { + + if ( $this->get_cached_widget( $args ) ) { + return; + } + + ob_start(); + + $number = ! empty( $instance['number'] ) ? absint( $instance['number'] ) : $this->settings['number']['std']; + + $query_args = apply_filters( + 'woocommerce_top_rated_products_widget_args', + array( + 'posts_per_page' => $number, + 'no_found_rows' => 1, + 'post_status' => 'publish', + 'post_type' => 'product', + 'meta_key' => '_wc_average_rating', + 'orderby' => 'meta_value_num', + 'order' => 'DESC', + 'meta_query' => WC()->query->get_meta_query(), + 'tax_query' => WC()->query->get_tax_query(), + ) + ); // WPCS: slow query ok. + + $r = new WP_Query( $query_args ); + + if ( $r->have_posts() ) { + + $this->widget_start( $args, $instance ); + + echo wp_kses_post( apply_filters( 'woocommerce_before_widget_product_list', '
      ' ) ); + + $template_args = array( + 'widget_id' => isset( $args['widget_id'] ) ? $args['widget_id'] : $this->widget_id, + 'show_rating' => true, + ); + + while ( $r->have_posts() ) { + $r->the_post(); + wc_get_template( 'content-widget-product.php', $template_args ); + } + + echo wp_kses_post( apply_filters( 'woocommerce_after_widget_product_list', '
    ' ) ); + + $this->widget_end( $args ); + } + + wp_reset_postdata(); + + $content = ob_get_clean(); + + echo $content; // WPCS: XSS ok. + + $this->cache_widget( $args, $content ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/license.txt b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/license.txt new file mode 100644 index 0000000..35db42d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/license.txt @@ -0,0 +1,710 @@ +WooCommerce - eCommerce for WordPress + +Copyright 2015 by the contributors + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +This program incorporates work covered by the following copyright and +permission notices: + + Jigoshop is Copyright (c) 2011 Jigowatt Ltd. + http://jigowatt.com - http://jigoshop.com + + Jigoshop is released under the GPL + +and + + WooCommerce - eCommerce for WordPress + + WooCommerce is Copyright (c) 2015 WooThemes + + WooCommerce is released under the GPL + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright © 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright © + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright © + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/action-scheduler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/action-scheduler.php new file mode 100644 index 0000000..53e9cab --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/action-scheduler.php @@ -0,0 +1,53 @@ +. + * + */ + +if ( ! function_exists( 'action_scheduler_register_3_dot_1_dot_6' ) ) { + + if ( ! class_exists( 'ActionScheduler_Versions' ) ) { + require_once( 'classes/ActionScheduler_Versions.php' ); + add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 ); + } + + add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_1_dot_6', 0, 0 ); + + function action_scheduler_register_3_dot_1_dot_6() { + $versions = ActionScheduler_Versions::instance(); + $versions->register( '3.1.6', 'action_scheduler_initialize_3_dot_1_dot_6' ); + } + + function action_scheduler_initialize_3_dot_1_dot_6() { + require_once( 'classes/abstracts/ActionScheduler.php' ); + ActionScheduler::init( __FILE__ ); + } + + // Support usage in themes - load this version if no plugin has loaded a version yet. + if ( did_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler' ) ) { + action_scheduler_initialize_3_dot_1_dot_6(); + do_action( 'action_scheduler_pre_theme_init' ); + ActionScheduler_Versions::initialize_latest_version(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_ActionClaim.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_ActionClaim.php new file mode 100644 index 0000000..8b56816 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_ActionClaim.php @@ -0,0 +1,23 @@ +id = $id; + $this->action_ids = $action_ids; + } + + public function get_id() { + return $this->id; + } + + public function get_actions() { + return $this->action_ids; + } +} + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_ActionFactory.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_ActionFactory.php new file mode 100644 index 0000000..592dbc5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_ActionFactory.php @@ -0,0 +1,179 @@ +get_date() ); + } + break; + default : + $action_class = 'ActionScheduler_FinishedAction'; + break; + } + + $action_class = apply_filters( 'action_scheduler_stored_action_class', $action_class, $status, $hook, $args, $schedule, $group ); + + $action = new $action_class( $hook, $args, $schedule, $group ); + + /** + * Allow 3rd party code to change the instantiated action for a given hook, args, schedule and group. + * + * @param ActionScheduler_Action $action The instantiated action. + * @param string $hook The instantiated action's hook. + * @param array $args The instantiated action's args. + * @param ActionScheduler_Schedule $schedule The instantiated action's schedule. + * @param string $group The instantiated action's group. + */ + return apply_filters( 'action_scheduler_stored_action_instance', $action, $hook, $args, $schedule, $group ); + } + + /** + * Enqueue an action to run one time, as soon as possible (rather a specific scheduled time). + * + * This method creates a new action with the NULLSchedule. This schedule maps to a MySQL datetime string of + * 0000-00-00 00:00:00. This is done to create a psuedo "async action" type that is fully backward compatible. + * Existing queries to claim actions claim by date, meaning actions scheduled for 0000-00-00 00:00:00 will + * always be claimed prior to actions scheduled for a specific date. This makes sure that any async action is + * given priority in queue processing. This has the added advantage of making sure async actions can be + * claimed by both the existing WP Cron and WP CLI runners, as well as a new async request runner. + * + * @param string $hook The hook to trigger when this action runs + * @param array $args Args to pass when the hook is triggered + * @param string $group A group to put the action in + * + * @return int The ID of the stored action + */ + public function async( $hook, $args = array(), $group = '' ) { + $schedule = new ActionScheduler_NullSchedule(); + $action = new ActionScheduler_Action( $hook, $args, $schedule, $group ); + return $this->store( $action ); + } + + /** + * @param string $hook The hook to trigger when this action runs + * @param array $args Args to pass when the hook is triggered + * @param int $when Unix timestamp when the action will run + * @param string $group A group to put the action in + * + * @return int The ID of the stored action + */ + public function single( $hook, $args = array(), $when = null, $group = '' ) { + $date = as_get_datetime_object( $when ); + $schedule = new ActionScheduler_SimpleSchedule( $date ); + $action = new ActionScheduler_Action( $hook, $args, $schedule, $group ); + return $this->store( $action ); + } + + /** + * Create the first instance of an action recurring on a given interval. + * + * @param string $hook The hook to trigger when this action runs + * @param array $args Args to pass when the hook is triggered + * @param int $first Unix timestamp for the first run + * @param int $interval Seconds between runs + * @param string $group A group to put the action in + * + * @return int The ID of the stored action + */ + public function recurring( $hook, $args = array(), $first = null, $interval = null, $group = '' ) { + if ( empty($interval) ) { + return $this->single( $hook, $args, $first, $group ); + } + $date = as_get_datetime_object( $first ); + $schedule = new ActionScheduler_IntervalSchedule( $date, $interval ); + $action = new ActionScheduler_Action( $hook, $args, $schedule, $group ); + return $this->store( $action ); + } + + /** + * Create the first instance of an action recurring on a Cron schedule. + * + * @param string $hook The hook to trigger when this action runs + * @param array $args Args to pass when the hook is triggered + * @param int $base_timestamp The first instance of the action will be scheduled + * to run at a time calculated after this timestamp matching the cron + * expression. This can be used to delay the first instance of the action. + * @param int $schedule A cron definition string + * @param string $group A group to put the action in + * + * @return int The ID of the stored action + */ + public function cron( $hook, $args = array(), $base_timestamp = null, $schedule = null, $group = '' ) { + if ( empty($schedule) ) { + return $this->single( $hook, $args, $base_timestamp, $group ); + } + $date = as_get_datetime_object( $base_timestamp ); + $cron = CronExpression::factory( $schedule ); + $schedule = new ActionScheduler_CronSchedule( $date, $cron ); + $action = new ActionScheduler_Action( $hook, $args, $schedule, $group ); + return $this->store( $action ); + } + + /** + * Create a successive instance of a recurring or cron action. + * + * Importantly, the action will be rescheduled to run based on the current date/time. + * That means when the action is scheduled to run in the past, the next scheduled date + * will be pushed forward. For example, if a recurring action set to run every hour + * was scheduled to run 5 seconds ago, it will be next scheduled for 1 hour in the + * future, which is 1 hour and 5 seconds from when it was last scheduled to run. + * + * Alternatively, if the action is scheduled to run in the future, and is run early, + * likely via manual intervention, then its schedule will change based on the time now. + * For example, if a recurring action set to run every day, and is run 12 hours early, + * it will run again in 24 hours, not 36 hours. + * + * This slippage is less of an issue with Cron actions, as the specific run time can + * be set for them to run, e.g. 1am each day. In those cases, and entire period would + * need to be missed before there was any change is scheduled, e.g. in the case of an + * action scheduled for 1am each day, the action would need to run an entire day late. + * + * @param ActionScheduler_Action $action The existing action. + * + * @return string The ID of the stored action + * @throws InvalidArgumentException If $action is not a recurring action. + */ + public function repeat( $action ) { + $schedule = $action->get_schedule(); + $next = $schedule->get_next( as_get_datetime_object() ); + + if ( is_null( $next ) || ! $schedule->is_recurring() ) { + throw new InvalidArgumentException( __( 'Invalid action - must be a recurring action.', 'woocommerce' ) ); + } + + $schedule_class = get_class( $schedule ); + $new_schedule = new $schedule( $next, $schedule->get_recurrence(), $schedule->get_first_date() ); + $new_action = new ActionScheduler_Action( $action->get_hook(), $action->get_args(), $new_schedule, $action->get_group() ); + return $this->store( $new_action ); + } + + /** + * @param ActionScheduler_Action $action + * + * @return int The ID of the stored action + */ + protected function store( ActionScheduler_Action $action ) { + $store = ActionScheduler_Store::instance(); + return $store->save_action( $action ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_AdminView.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_AdminView.php new file mode 100644 index 0000000..d4f25fd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_AdminView.php @@ -0,0 +1,154 @@ +render(); + } + + /** + * Registers action-scheduler into WooCommerce > System status. + * + * @param array $tabs An associative array of tab key => label. + * @return array $tabs An associative array of tab key => label, including Action Scheduler's tabs + */ + public function register_system_status_tab( array $tabs ) { + $tabs['action-scheduler'] = __( 'Scheduled Actions', 'woocommerce' ); + + return $tabs; + } + + /** + * Include Action Scheduler's administration under the Tools menu. + * + * A menu under the Tools menu is important for backward compatibility (as that's + * where it started), and also provides more convenient access than the WooCommerce + * System Status page, and for sites where WooCommerce isn't active. + */ + public function register_menu() { + $hook_suffix = add_submenu_page( + 'tools.php', + __( 'Scheduled Actions', 'woocommerce' ), + __( 'Scheduled Actions', 'woocommerce' ), + 'manage_options', + 'action-scheduler', + array( $this, 'render_admin_ui' ) + ); + add_action( 'load-' . $hook_suffix , array( $this, 'process_admin_ui' ) ); + } + + /** + * Triggers processing of any pending actions. + */ + public function process_admin_ui() { + $this->get_list_table(); + } + + /** + * Renders the Admin UI + */ + public function render_admin_ui() { + $table = $this->get_list_table(); + $table->display_page(); + } + + /** + * Get the admin UI object and process any requested actions. + * + * @return ActionScheduler_ListTable + */ + protected function get_list_table() { + if ( null === $this->list_table ) { + $this->list_table = new ActionScheduler_ListTable( ActionScheduler::store(), ActionScheduler::logger(), ActionScheduler::runner() ); + $this->list_table->process_actions(); + } + + return $this->list_table; + } + + /** + * Provide more information about the screen and its data in the help tab. + */ + public function add_help_tabs() { + $screen = get_current_screen(); + + if ( ! $screen || self::$screen_id != $screen->id ) { + return; + } + + $as_version = ActionScheduler_Versions::instance()->latest_version(); + $screen->add_help_tab( + array( + 'id' => 'action_scheduler_about', + 'title' => __( 'About', 'woocommerce' ), + 'content' => + '

    ' . sprintf( __( 'About Action Scheduler %s', 'woocommerce' ), $as_version ) . '

    ' . + '

    ' . + __( 'Action Scheduler is a scalable, traceable job queue for background processing large sets of actions. Action Scheduler works by triggering an action hook to run at some time in the future. Scheduled actions can also be scheduled to run on a recurring schedule.', 'woocommerce' ) . + '

    ', + ) + ); + + $screen->add_help_tab( + array( + 'id' => 'action_scheduler_columns', + 'title' => __( 'Columns', 'woocommerce' ), + 'content' => + '

    ' . __( 'Scheduled Action Columns', 'woocommerce' ) . '

    ' . + '
      ' . + sprintf( '
    • %1$s: %2$s
    • ', __( 'Hook', 'woocommerce' ), __( 'Name of the action hook that will be triggered.', 'woocommerce' ) ) . + sprintf( '
    • %1$s: %2$s
    • ', __( 'Status', 'woocommerce' ), __( 'Action statuses are Pending, Complete, Canceled, Failed', 'woocommerce' ) ) . + sprintf( '
    • %1$s: %2$s
    • ', __( 'Arguments', 'woocommerce' ), __( 'Optional data array passed to the action hook.', 'woocommerce' ) ) . + sprintf( '
    • %1$s: %2$s
    • ', __( 'Group', 'woocommerce' ), __( 'Optional action group.', 'woocommerce' ) ) . + sprintf( '
    • %1$s: %2$s
    • ', __( 'Recurrence', 'woocommerce' ), __( 'The action\'s schedule frequency.', 'woocommerce' ) ) . + sprintf( '
    • %1$s: %2$s
    • ', __( 'Scheduled', 'woocommerce' ), __( 'The date/time the action is/was scheduled to run.', 'woocommerce' ) ) . + sprintf( '
    • %1$s: %2$s
    • ', __( 'Log', 'woocommerce' ), __( 'Activity log for the action.', 'woocommerce' ) ) . + '
    ', + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php new file mode 100644 index 0000000..57706a2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php @@ -0,0 +1,97 @@ +store = $store; + } + + /** + * Handle async requests + * + * Run a queue, and maybe dispatch another async request to run another queue + * if there are still pending actions after completing a queue in this request. + */ + protected function handle() { + do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context + + $sleep_seconds = $this->get_sleep_seconds(); + + if ( $sleep_seconds ) { + sleep( $sleep_seconds ); + } + + $this->maybe_dispatch(); + } + + /** + * If the async request runner is needed and allowed to run, dispatch a request. + */ + public function maybe_dispatch() { + if ( ! $this->allow() ) { + return; + } + + $this->dispatch(); + ActionScheduler_QueueRunner::instance()->unhook_dispatch_async_request(); + } + + /** + * Only allow async requests when needed. + * + * Also allow 3rd party code to disable running actions via async requests. + */ + protected function allow() { + + if ( ! has_action( 'action_scheduler_run_queue' ) || ActionScheduler::runner()->has_maximum_concurrent_batches() || ! $this->store->has_pending_actions_due() ) { + $allow = false; + } else { + $allow = true; + } + + return apply_filters( 'action_scheduler_allow_async_request_runner', $allow ); + } + + /** + * Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that. + */ + protected function get_sleep_seconds() { + return apply_filters( 'action_scheduler_async_request_sleep_seconds', 5, $this ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_Compatibility.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_Compatibility.php new file mode 100644 index 0000000..c06e5a4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_Compatibility.php @@ -0,0 +1,99 @@ + $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) { + if ( false !== @ini_set( 'memory_limit', $filtered_limit ) ) { + return $filtered_limit; + } else { + return false; + } + } elseif ( -1 === $wp_max_limit_int || $wp_max_limit_int > $current_limit_int ) { + if ( false !== @ini_set( 'memory_limit', $wp_max_limit ) ) { + return $wp_max_limit; + } else { + return false; + } + } + return false; + } + + /** + * Attempts to raise the PHP timeout for time intensive processes. + * + * Only allows raising the existing limit and prevents lowering it. Wrapper for wc_set_time_limit(), when available. + * + * @param int The time limit in seconds. + */ + public static function raise_time_limit( $limit = 0 ) { + if ( $limit < ini_get( 'max_execution_time' ) ) { + return; + } + + if ( function_exists( 'wc_set_time_limit' ) ) { + wc_set_time_limit( $limit ); + } elseif ( function_exists( 'set_time_limit' ) && false === strpos( ini_get( 'disable_functions' ), 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { + @set_time_limit( $limit ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_DataController.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_DataController.php new file mode 100644 index 0000000..a9f5434 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_DataController.php @@ -0,0 +1,187 @@ +=' ); + return $php_support && apply_filters( 'action_scheduler_migration_dependencies_met', true ); + } + + /** + * Get a flag indicating whether the migration is complete. + * + * @return bool Whether the flag has been set marking the migration as complete + */ + public static function is_migration_complete() { + return get_option( self::STATUS_FLAG ) === self::STATUS_COMPLETE; + } + + /** + * Mark the migration as complete. + */ + public static function mark_migration_complete() { + update_option( self::STATUS_FLAG, self::STATUS_COMPLETE ); + } + + /** + * Unmark migration when a plugin is de-activated. Will not work in case of silent activation, for example in an update. + * We do this to mitigate the bug of lost actions which happens if there was an AS 2.x to AS 3.x migration in the past, but that plugin is now + * deactivated and the site was running on AS 2.x again. + */ + public static function mark_migration_incomplete() { + delete_option( self::STATUS_FLAG ); + } + + /** + * Set the action store class name. + * + * @param string $class Classname of the store class. + * + * @return string + */ + public static function set_store_class( $class ) { + return self::DATASTORE_CLASS; + } + + /** + * Set the action logger class name. + * + * @param string $class Classname of the logger class. + * + * @return string + */ + public static function set_logger_class( $class ) { + return self::LOGGER_CLASS; + } + + /** + * Set the sleep time in seconds. + * + * @param integer $sleep_time The number of seconds to pause before resuming operation. + */ + public static function set_sleep_time( $sleep_time ) { + self::$sleep_time = (int) $sleep_time; + } + + /** + * Set the tick count required for freeing memory. + * + * @param integer $free_ticks The number of ticks to free memory on. + */ + public static function set_free_ticks( $free_ticks ) { + self::$free_ticks = (int) $free_ticks; + } + + /** + * Free memory if conditions are met. + * + * @param int $ticks Current tick count. + */ + public static function maybe_free_memory( $ticks ) { + if ( self::$free_ticks && 0 === $ticks % self::$free_ticks ) { + self::free_memory(); + } + } + + /** + * Reduce memory footprint by clearing the database query and object caches. + */ + public static function free_memory() { + if ( 0 < self::$sleep_time ) { + /* translators: %d: amount of time */ + \WP_CLI::warning( sprintf( _n( 'Stopped the insanity for %d second', 'Stopped the insanity for %d seconds', self::$sleep_time, 'woocommerce' ), self::$sleep_time ) ); + sleep( self::$sleep_time ); + } + + \WP_CLI::warning( __( 'Attempting to reduce used memory...', 'woocommerce' ) ); + + /** + * @var $wpdb \wpdb + * @var $wp_object_cache \WP_Object_Cache + */ + global $wpdb, $wp_object_cache; + + $wpdb->queries = array(); + + if ( ! is_a( $wp_object_cache, 'WP_Object_Cache' ) ) { + return; + } + + $wp_object_cache->group_ops = array(); + $wp_object_cache->stats = array(); + $wp_object_cache->memcache_debug = array(); + $wp_object_cache->cache = array(); + + if ( is_callable( array( $wp_object_cache, '__remoteset' ) ) ) { + call_user_func( array( $wp_object_cache, '__remoteset' ) ); // important + } + } + + /** + * Connect to table datastores if migration is complete. + * Otherwise, proceed with the migration if the dependencies have been met. + */ + public static function init() { + if ( self::is_migration_complete() ) { + add_filter( 'action_scheduler_store_class', array( 'ActionScheduler_DataController', 'set_store_class' ), 100 ); + add_filter( 'action_scheduler_logger_class', array( 'ActionScheduler_DataController', 'set_logger_class' ), 100 ); + add_action( 'deactivate_plugin', array( 'ActionScheduler_DataController', 'mark_migration_incomplete' ) ); + } elseif ( self::dependencies_met() ) { + Controller::init(); + } + + add_action( 'action_scheduler/progress_tick', array( 'ActionScheduler_DataController', 'maybe_free_memory' ) ); + } + + /** + * Singleton factory. + */ + public static function instance() { + if ( ! isset( self::$instance ) ) { + self::$instance = new static(); + } + + return self::$instance; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_DateTime.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_DateTime.php new file mode 100644 index 0000000..5e8743c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_DateTime.php @@ -0,0 +1,76 @@ +format( 'U' ); + } + + /** + * Set the UTC offset. + * + * This represents a fixed offset instead of a timezone setting. + * + * @param $offset + */ + public function setUtcOffset( $offset ) { + $this->utcOffset = intval( $offset ); + } + + /** + * Returns the timezone offset. + * + * @return int + * @link http://php.net/manual/en/datetime.getoffset.php + */ + public function getOffset() { + return $this->utcOffset ? $this->utcOffset : parent::getOffset(); + } + + /** + * Set the TimeZone associated with the DateTime + * + * @param DateTimeZone $timezone + * + * @return static + * @link http://php.net/manual/en/datetime.settimezone.php + */ + public function setTimezone( $timezone ) { + $this->utcOffset = 0; + parent::setTimezone( $timezone ); + + return $this; + } + + /** + * Get the timestamp with the WordPress timezone offset added or subtracted. + * + * @since 3.0.0 + * @return int + */ + public function getOffsetTimestamp() { + return $this->getTimestamp() + $this->getOffset(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_Exception.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_Exception.php new file mode 100644 index 0000000..353d3c0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_Exception.php @@ -0,0 +1,11 @@ +store = $store; + } + + public function attach( ActionScheduler_ActionClaim $claim ) { + $this->claim = $claim; + add_action( 'shutdown', array( $this, 'handle_unexpected_shutdown' ) ); + add_action( 'action_scheduler_before_execute', array( $this, 'track_current_action' ), 0, 1 ); + add_action( 'action_scheduler_after_execute', array( $this, 'untrack_action' ), 0, 0 ); + add_action( 'action_scheduler_execution_ignored', array( $this, 'untrack_action' ), 0, 0 ); + add_action( 'action_scheduler_failed_execution', array( $this, 'untrack_action' ), 0, 0 ); + } + + public function detach() { + $this->claim = NULL; + $this->untrack_action(); + remove_action( 'shutdown', array( $this, 'handle_unexpected_shutdown' ) ); + remove_action( 'action_scheduler_before_execute', array( $this, 'track_current_action' ), 0 ); + remove_action( 'action_scheduler_after_execute', array( $this, 'untrack_action' ), 0 ); + remove_action( 'action_scheduler_execution_ignored', array( $this, 'untrack_action' ), 0 ); + remove_action( 'action_scheduler_failed_execution', array( $this, 'untrack_action' ), 0 ); + } + + public function track_current_action( $action_id ) { + $this->action_id = $action_id; + } + + public function untrack_action() { + $this->action_id = 0; + } + + public function handle_unexpected_shutdown() { + if ( $error = error_get_last() ) { + if ( in_array( $error['type'], array( E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ) ) ) { + if ( !empty($this->action_id) ) { + $this->store->mark_failure( $this->action_id ); + do_action( 'action_scheduler_unexpected_shutdown', $this->action_id, $error ); + } + } + $this->store->release_claim( $this->claim ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_InvalidActionException.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_InvalidActionException.php new file mode 100644 index 0000000..0a9b5bd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_InvalidActionException.php @@ -0,0 +1,47 @@ + label). + * + * @var array + */ + protected $columns = array(); + + /** + * Actions (name => label). + * + * @var array + */ + protected $row_actions = array(); + + /** + * The active data stores + * + * @var ActionScheduler_Store + */ + protected $store; + + /** + * A logger to use for getting action logs to display + * + * @var ActionScheduler_Logger + */ + protected $logger; + + /** + * A ActionScheduler_QueueRunner runner instance (or child class) + * + * @var ActionScheduler_QueueRunner + */ + protected $runner; + + /** + * Bulk actions. The key of the array is the method name of the implementation: + * + * bulk_(array $ids, string $sql_in). + * + * See the comments in the parent class for further details + * + * @var array + */ + protected $bulk_actions = array(); + + /** + * Flag variable to render our notifications, if any, once. + * + * @var bool + */ + protected static $did_notification = false; + + /** + * Array of seconds for common time periods, like week or month, alongside an internationalised string representation, i.e. "Day" or "Days" + * + * @var array + */ + private static $time_periods; + + /** + * Sets the current data store object into `store->action` and initialises the object. + * + * @param ActionScheduler_Store $store + * @param ActionScheduler_Logger $logger + * @param ActionScheduler_QueueRunner $runner + */ + public function __construct( ActionScheduler_Store $store, ActionScheduler_Logger $logger, ActionScheduler_QueueRunner $runner ) { + + $this->store = $store; + $this->logger = $logger; + $this->runner = $runner; + + $this->table_header = __( 'Scheduled Actions', 'woocommerce' ); + + $this->bulk_actions = array( + 'delete' => __( 'Delete', 'woocommerce' ), + ); + + $this->columns = array( + 'hook' => __( 'Hook', 'woocommerce' ), + 'status' => __( 'Status', 'woocommerce' ), + 'args' => __( 'Arguments', 'woocommerce' ), + 'group' => __( 'Group', 'woocommerce' ), + 'recurrence' => __( 'Recurrence', 'woocommerce' ), + 'schedule' => __( 'Scheduled Date', 'woocommerce' ), + 'log_entries' => __( 'Log', 'woocommerce' ), + ); + + $this->sort_by = array( + 'schedule', + 'hook', + 'group', + ); + + $this->search_by = array( + 'hook', + 'args', + 'claim_id', + ); + + $request_status = $this->get_request_status(); + + if ( empty( $request_status ) ) { + $this->sort_by[] = 'status'; + } elseif ( in_array( $request_status, array( 'in-progress', 'failed' ) ) ) { + $this->columns += array( 'claim_id' => __( 'Claim ID', 'woocommerce' ) ); + $this->sort_by[] = 'claim_id'; + } + + $this->row_actions = array( + 'hook' => array( + 'run' => array( + 'name' => __( 'Run', 'woocommerce' ), + 'desc' => __( 'Process the action now as if it were run as part of a queue', 'woocommerce' ), + ), + 'cancel' => array( + 'name' => __( 'Cancel', 'woocommerce' ), + 'desc' => __( 'Cancel the action now to avoid it being run in future', 'woocommerce' ), + 'class' => 'cancel trash', + ), + ), + ); + + self::$time_periods = array( + array( + 'seconds' => YEAR_IN_SECONDS, + /* translators: %s: amount of time */ + 'names' => _n_noop( '%s year', '%s years', 'woocommerce' ), + ), + array( + 'seconds' => MONTH_IN_SECONDS, + /* translators: %s: amount of time */ + 'names' => _n_noop( '%s month', '%s months', 'woocommerce' ), + ), + array( + 'seconds' => WEEK_IN_SECONDS, + /* translators: %s: amount of time */ + 'names' => _n_noop( '%s week', '%s weeks', 'woocommerce' ), + ), + array( + 'seconds' => DAY_IN_SECONDS, + /* translators: %s: amount of time */ + 'names' => _n_noop( '%s day', '%s days', 'woocommerce' ), + ), + array( + 'seconds' => HOUR_IN_SECONDS, + /* translators: %s: amount of time */ + 'names' => _n_noop( '%s hour', '%s hours', 'woocommerce' ), + ), + array( + 'seconds' => MINUTE_IN_SECONDS, + /* translators: %s: amount of time */ + 'names' => _n_noop( '%s minute', '%s minutes', 'woocommerce' ), + ), + array( + 'seconds' => 1, + /* translators: %s: amount of time */ + 'names' => _n_noop( '%s second', '%s seconds', 'woocommerce' ), + ), + ); + + parent::__construct( array( + 'singular' => 'action-scheduler', + 'plural' => 'action-scheduler', + 'ajax' => false, + ) ); + } + + /** + * Convert an interval of seconds into a two part human friendly string. + * + * The WordPress human_time_diff() function only calculates the time difference to one degree, meaning + * even if an action is 1 day and 11 hours away, it will display "1 day". This function goes one step + * further to display two degrees of accuracy. + * + * Inspired by the Crontrol::interval() function by Edward Dale: https://wordpress.org/plugins/wp-crontrol/ + * + * @param int $interval A interval in seconds. + * @param int $periods_to_include Depth of time periods to include, e.g. for an interval of 70, and $periods_to_include of 2, both minutes and seconds would be included. With a value of 1, only minutes would be included. + * @return string A human friendly string representation of the interval. + */ + private static function human_interval( $interval, $periods_to_include = 2 ) { + + if ( $interval <= 0 ) { + return __( 'Now!', 'woocommerce' ); + } + + $output = ''; + + for ( $time_period_index = 0, $periods_included = 0, $seconds_remaining = $interval; $time_period_index < count( self::$time_periods ) && $seconds_remaining > 0 && $periods_included < $periods_to_include; $time_period_index++ ) { + + $periods_in_interval = floor( $seconds_remaining / self::$time_periods[ $time_period_index ]['seconds'] ); + + if ( $periods_in_interval > 0 ) { + if ( ! empty( $output ) ) { + $output .= ' '; + } + $output .= sprintf( _n( self::$time_periods[ $time_period_index ]['names'][0], self::$time_periods[ $time_period_index ]['names'][1], $periods_in_interval, 'woocommerce' ), $periods_in_interval ); + $seconds_remaining -= $periods_in_interval * self::$time_periods[ $time_period_index ]['seconds']; + $periods_included++; + } + } + + return $output; + } + + /** + * Returns the recurrence of an action or 'Non-repeating'. The output is human readable. + * + * @param ActionScheduler_Action $action + * + * @return string + */ + protected function get_recurrence( $action ) { + $schedule = $action->get_schedule(); + if ( $schedule->is_recurring() ) { + $recurrence = $schedule->get_recurrence(); + + if ( is_numeric( $recurrence ) ) { + /* translators: %s: time interval */ + return sprintf( __( 'Every %s', 'woocommerce' ), self::human_interval( $recurrence ) ); + } else { + return $recurrence; + } + } + + return __( 'Non-repeating', 'woocommerce' ); + } + + /** + * Serializes the argument of an action to render it in a human friendly format. + * + * @param array $row The array representation of the current row of the table + * + * @return string + */ + public function column_args( array $row ) { + if ( empty( $row['args'] ) ) { + return apply_filters( 'action_scheduler_list_table_column_args', '', $row ); + } + + $row_html = '
      '; + foreach ( $row['args'] as $key => $value ) { + $row_html .= sprintf( '
    • %s => %s
    • ', esc_html( var_export( $key, true ) ), esc_html( var_export( $value, true ) ) ); + } + $row_html .= '
    '; + + return apply_filters( 'action_scheduler_list_table_column_args', $row_html, $row ); + } + + /** + * Prints the logs entries inline. We do so to avoid loading Javascript and other hacks to show it in a modal. + * + * @param array $row Action array. + * @return string + */ + public function column_log_entries( array $row ) { + + $log_entries_html = '
      '; + + $timezone = new DateTimezone( 'UTC' ); + + foreach ( $row['log_entries'] as $log_entry ) { + $log_entries_html .= $this->get_log_entry_html( $log_entry, $timezone ); + } + + $log_entries_html .= '
    '; + + return $log_entries_html; + } + + /** + * Prints the logs entries inline. We do so to avoid loading Javascript and other hacks to show it in a modal. + * + * @param ActionScheduler_LogEntry $log_entry + * @param DateTimezone $timezone + * @return string + */ + protected function get_log_entry_html( ActionScheduler_LogEntry $log_entry, DateTimezone $timezone ) { + $date = $log_entry->get_date(); + $date->setTimezone( $timezone ); + return sprintf( '
  • %s
    %s
  • ', esc_html( $date->format( 'Y-m-d H:i:s O' ) ), esc_html( $log_entry->get_message() ) ); + } + + /** + * Only display row actions for pending actions. + * + * @param array $row Row to render + * @param string $column_name Current row + * + * @return string + */ + protected function maybe_render_actions( $row, $column_name ) { + if ( 'pending' === strtolower( $row[ 'status_name' ] ) ) { + return parent::maybe_render_actions( $row, $column_name ); + } + + return ''; + } + + /** + * Renders admin notifications + * + * Notifications: + * 1. When the maximum number of tasks are being executed simultaneously. + * 2. Notifications when a task is manually executed. + * 3. Tables are missing. + */ + public function display_admin_notices() { + global $wpdb; + + if ( ( is_a( $this->store, 'ActionScheduler_HybridStore' ) || is_a( $this->store, 'ActionScheduler_DBStore' ) ) && apply_filters( 'action_scheduler_enable_recreate_data_store', true ) ) { + $table_list = array( + 'actionscheduler_actions', + 'actionscheduler_logs', + 'actionscheduler_groups', + 'actionscheduler_claims', + ); + + $found_tables = $wpdb->get_col( "SHOW TABLES LIKE '{$wpdb->prefix}actionscheduler%'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared + foreach ( $table_list as $table_name ) { + if ( ! in_array( $wpdb->prefix . $table_name, $found_tables ) ) { + $this->admin_notices[] = array( + 'class' => 'error', + 'message' => __( 'It appears one or more database tables were missing. Attempting to re-create the missing table(s).' , 'woocommerce' ), + ); + $this->recreate_tables(); + parent::display_admin_notices(); + + return; + } + } + } + + if ( $this->runner->has_maximum_concurrent_batches() ) { + $claim_count = $this->store->get_claim_count(); + $this->admin_notices[] = array( + 'class' => 'updated', + 'message' => sprintf( + /* translators: %s: amount of claims */ + _n( + 'Maximum simultaneous queues already in progress (%s queue). No additional queues will begin processing until the current queues are complete.', + 'Maximum simultaneous queues already in progress (%s queues). No additional queues will begin processing until the current queues are complete.', + $claim_count, + 'woocommerce' + ), + $claim_count + ), + ); + } elseif ( $this->store->has_pending_actions_due() ) { + + $async_request_lock_expiration = ActionScheduler::lock()->get_expiration( 'async-request-runner' ); + + // No lock set or lock expired + if ( false === $async_request_lock_expiration || $async_request_lock_expiration < time() ) { + $in_progress_url = add_query_arg( 'status', 'in-progress', remove_query_arg( 'status' ) ); + /* translators: %s: process URL */ + $async_request_message = sprintf( __( 'A new queue has begun processing. View actions in-progress »', 'woocommerce' ), esc_url( $in_progress_url ) ); + } else { + /* translators: %d: seconds */ + $async_request_message = sprintf( __( 'The next queue will begin processing in approximately %d seconds.', 'woocommerce' ), $async_request_lock_expiration - time() ); + } + + $this->admin_notices[] = array( + 'class' => 'notice notice-info', + 'message' => $async_request_message, + ); + } + + $notification = get_transient( 'action_scheduler_admin_notice' ); + + if ( is_array( $notification ) ) { + delete_transient( 'action_scheduler_admin_notice' ); + + $action = $this->store->fetch_action( $notification['action_id'] ); + $action_hook_html = '' . $action->get_hook() . ''; + if ( 1 == $notification['success'] ) { + $class = 'updated'; + switch ( $notification['row_action_type'] ) { + case 'run' : + /* translators: %s: action HTML */ + $action_message_html = sprintf( __( 'Successfully executed action: %s', 'woocommerce' ), $action_hook_html ); + break; + case 'cancel' : + /* translators: %s: action HTML */ + $action_message_html = sprintf( __( 'Successfully canceled action: %s', 'woocommerce' ), $action_hook_html ); + break; + default : + /* translators: %s: action HTML */ + $action_message_html = sprintf( __( 'Successfully processed change for action: %s', 'woocommerce' ), $action_hook_html ); + break; + } + } else { + $class = 'error'; + /* translators: 1: action HTML 2: action ID 3: error message */ + $action_message_html = sprintf( __( 'Could not process change for action: "%1$s" (ID: %2$d). Error: %3$s', 'woocommerce' ), $action_hook_html, esc_html( $notification['action_id'] ), esc_html( $notification['error_message'] ) ); + } + + $action_message_html = apply_filters( 'action_scheduler_admin_notice_html', $action_message_html, $action, $notification ); + + $this->admin_notices[] = array( + 'class' => $class, + 'message' => $action_message_html, + ); + } + + parent::display_admin_notices(); + } + + /** + * Prints the scheduled date in a human friendly format. + * + * @param array $row The array representation of the current row of the table + * + * @return string + */ + public function column_schedule( $row ) { + return $this->get_schedule_display_string( $row['schedule'] ); + } + + /** + * Get the scheduled date in a human friendly format. + * + * @param ActionScheduler_Schedule $schedule + * @return string + */ + protected function get_schedule_display_string( ActionScheduler_Schedule $schedule ) { + + $schedule_display_string = ''; + + if ( ! $schedule->get_date() ) { + return '0000-00-00 00:00:00'; + } + + $next_timestamp = $schedule->get_date()->getTimestamp(); + + $schedule_display_string .= $schedule->get_date()->format( 'Y-m-d H:i:s O' ); + $schedule_display_string .= '
    '; + + if ( gmdate( 'U' ) > $next_timestamp ) { + /* translators: %s: date interval */ + $schedule_display_string .= sprintf( __( ' (%s ago)', 'woocommerce' ), self::human_interval( gmdate( 'U' ) - $next_timestamp ) ); + } else { + /* translators: %s: date interval */ + $schedule_display_string .= sprintf( __( ' (%s)', 'woocommerce' ), self::human_interval( $next_timestamp - gmdate( 'U' ) ) ); + } + + return $schedule_display_string; + } + + /** + * Bulk delete + * + * Deletes actions based on their ID. This is the handler for the bulk delete. It assumes the data + * properly validated by the callee and it will delete the actions without any extra validation. + * + * @param array $ids + * @param string $ids_sql Inherited and unused + */ + protected function bulk_delete( array $ids, $ids_sql ) { + foreach ( $ids as $id ) { + $this->store->delete_action( $id ); + } + } + + /** + * Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their + * parameters are valid. + * + * @param int $action_id + */ + protected function row_action_cancel( $action_id ) { + $this->process_row_action( $action_id, 'cancel' ); + } + + /** + * Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their + * parameters are valid. + * + * @param int $action_id + */ + protected function row_action_run( $action_id ) { + $this->process_row_action( $action_id, 'run' ); + } + + /** + * Force the data store schema updates. + */ + protected function recreate_tables() { + if ( is_a( $this->store, 'ActionScheduler_HybridStore' ) ) { + $store = $this->store; + } else { + $store = new ActionScheduler_HybridStore(); + } + add_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10, 2 ); + + $store_schema = new ActionScheduler_StoreSchema(); + $logger_schema = new ActionScheduler_LoggerSchema(); + $store_schema->register_tables( true ); + $logger_schema->register_tables( true ); + + remove_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10 ); + } + /** + * Implements the logic behind processing an action once an action link is clicked on the list table. + * + * @param int $action_id + * @param string $row_action_type The type of action to perform on the action. + */ + protected function process_row_action( $action_id, $row_action_type ) { + try { + switch ( $row_action_type ) { + case 'run' : + $this->runner->process_action( $action_id, 'Admin List Table' ); + break; + case 'cancel' : + $this->store->cancel_action( $action_id ); + break; + } + $success = 1; + $error_message = ''; + } catch ( Exception $e ) { + $success = 0; + $error_message = $e->getMessage(); + } + + set_transient( 'action_scheduler_admin_notice', compact( 'action_id', 'success', 'error_message', 'row_action_type' ), 30 ); + } + + /** + * {@inheritDoc} + */ + public function prepare_items() { + $this->prepare_column_headers(); + + $per_page = $this->get_items_per_page( $this->package . '_items_per_page', $this->items_per_page ); + $query = array( + 'per_page' => $per_page, + 'offset' => $this->get_items_offset(), + 'status' => $this->get_request_status(), + 'orderby' => $this->get_request_orderby(), + 'order' => $this->get_request_order(), + 'search' => $this->get_request_search_query(), + ); + + $this->items = array(); + + $total_items = $this->store->query_actions( $query, 'count' ); + + $status_labels = $this->store->get_status_labels(); + + foreach ( $this->store->query_actions( $query ) as $action_id ) { + try { + $action = $this->store->fetch_action( $action_id ); + } catch ( Exception $e ) { + continue; + } + if ( is_a( $action, 'ActionScheduler_NullAction' ) ) { + continue; + } + $this->items[ $action_id ] = array( + 'ID' => $action_id, + 'hook' => $action->get_hook(), + 'status_name' => $this->store->get_status( $action_id ), + 'status' => $status_labels[ $this->store->get_status( $action_id ) ], + 'args' => $action->get_args(), + 'group' => $action->get_group(), + 'log_entries' => $this->logger->get_logs( $action_id ), + 'claim_id' => $this->store->get_claim_id( $action_id ), + 'recurrence' => $this->get_recurrence( $action ), + 'schedule' => $action->get_schedule(), + ); + } + + $this->set_pagination_args( array( + 'total_items' => $total_items, + 'per_page' => $per_page, + 'total_pages' => ceil( $total_items / $per_page ), + ) ); + } + + /** + * Prints the available statuses so the user can click to filter. + */ + protected function display_filter_by_status() { + $this->status_counts = $this->store->action_counts(); + parent::display_filter_by_status(); + } + + /** + * Get the text to display in the search box on the list table. + */ + protected function get_search_box_button_text() { + return __( 'Search hook, args and claim ID', 'woocommerce' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_LogEntry.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_LogEntry.php new file mode 100644 index 0000000..649636d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_LogEntry.php @@ -0,0 +1,67 @@ +comment_type + * to ActionScheduler_LogEntry::__construct(), goodness knows why, and the Follow-up Emails plugin + * hard-codes loading its own version of ActionScheduler_wpCommentLogger with that out-dated method, + * goodness knows why, so we need to guard against that here instead of using a DateTime type declaration + * for the constructor's 3rd param of $date and causing a fatal error with older versions of FUE. + */ + if ( null !== $date && ! is_a( $date, 'DateTime' ) ) { + _doing_it_wrong( __METHOD__, 'The third parameter must be a valid DateTime instance, or null.', '2.0.0' ); + $date = null; + } + + $this->action_id = $action_id; + $this->message = $message; + $this->date = $date ? $date : new Datetime; + } + + /** + * Returns the date when this log entry was created + * + * @return Datetime + */ + public function get_date() { + return $this->date; + } + + public function get_action_id() { + return $this->action_id; + } + + public function get_message() { + return $this->message; + } +} + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_NullLogEntry.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_NullLogEntry.php new file mode 100644 index 0000000..6f8f218 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_NullLogEntry.php @@ -0,0 +1,11 @@ +maybe_dispatch_async_request() uses a lock to avoid + * calling ActionScheduler_QueueRunner->has_maximum_concurrent_batches() every time the 'shutdown', + * hook is triggered, because that method calls ActionScheduler_QueueRunner->store->get_claim_count() + * to find the current number of claims in the database. + * + * @param string $lock_type A string to identify different lock types. + * @bool True if lock value has changed, false if not or if set failed. + */ + public function set( $lock_type ) { + return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) ); + } + + /** + * If a lock is set, return the timestamp it was set to expiry. + * + * @param string $lock_type A string to identify different lock types. + * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. + */ + public function get_expiration( $lock_type ) { + return get_option( $this->get_key( $lock_type ) ); + } + + /** + * Get the key to use for storing the lock in the transient + * + * @param string $lock_type A string to identify different lock types. + * @return string + */ + protected function get_key( $lock_type ) { + return sprintf( 'action_scheduler_lock_%s', $lock_type ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_QueueCleaner.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_QueueCleaner.php new file mode 100644 index 0000000..1da13ab --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_QueueCleaner.php @@ -0,0 +1,155 @@ +store = $store ? $store : ActionScheduler_Store::instance(); + $this->batch_size = $batch_size; + } + + public function delete_old_actions() { + $lifespan = apply_filters( 'action_scheduler_retention_period', $this->month_in_seconds ); + $cutoff = as_get_datetime_object($lifespan.' seconds ago'); + + $statuses_to_purge = array( + ActionScheduler_Store::STATUS_COMPLETE, + ActionScheduler_Store::STATUS_CANCELED, + ); + + foreach ( $statuses_to_purge as $status ) { + $actions_to_delete = $this->store->query_actions( array( + 'status' => $status, + 'modified' => $cutoff, + 'modified_compare' => '<=', + 'per_page' => $this->get_batch_size(), + ) ); + + foreach ( $actions_to_delete as $action_id ) { + try { + $this->store->delete_action( $action_id ); + } catch ( Exception $e ) { + + /** + * Notify 3rd party code of exceptions when deleting a completed action older than the retention period + * + * This hook provides a way for 3rd party code to log or otherwise handle exceptions relating to their + * actions. + * + * @since 2.0.0 + * + * @param int $action_id The scheduled actions ID in the data store + * @param Exception $e The exception thrown when attempting to delete the action from the data store + * @param int $lifespan The retention period, in seconds, for old actions + * @param int $count_of_actions_to_delete The number of old actions being deleted in this batch + */ + do_action( 'action_scheduler_failed_old_action_deletion', $action_id, $e, $lifespan, count( $actions_to_delete ) ); + } + } + } + } + + /** + * Unclaim pending actions that have not been run within a given time limit. + * + * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed + * as a parameter is 10x the time limit used for queue processing. + * + * @param int $time_limit The number of seconds to allow a queue to run before unclaiming its pending actions. Default 300 (5 minutes). + */ + public function reset_timeouts( $time_limit = 300 ) { + $timeout = apply_filters( 'action_scheduler_timeout_period', $time_limit ); + if ( $timeout < 0 ) { + return; + } + $cutoff = as_get_datetime_object($timeout.' seconds ago'); + $actions_to_reset = $this->store->query_actions( array( + 'status' => ActionScheduler_Store::STATUS_PENDING, + 'modified' => $cutoff, + 'modified_compare' => '<=', + 'claimed' => true, + 'per_page' => $this->get_batch_size(), + ) ); + + foreach ( $actions_to_reset as $action_id ) { + $this->store->unclaim_action( $action_id ); + do_action( 'action_scheduler_reset_action', $action_id ); + } + } + + /** + * Mark actions that have been running for more than a given time limit as failed, based on + * the assumption some uncatachable and unloggable fatal error occurred during processing. + * + * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed + * as a parameter is 10x the time limit used for queue processing. + * + * @param int $time_limit The number of seconds to allow an action to run before it is considered to have failed. Default 300 (5 minutes). + */ + public function mark_failures( $time_limit = 300 ) { + $timeout = apply_filters( 'action_scheduler_failure_period', $time_limit ); + if ( $timeout < 0 ) { + return; + } + $cutoff = as_get_datetime_object($timeout.' seconds ago'); + $actions_to_reset = $this->store->query_actions( array( + 'status' => ActionScheduler_Store::STATUS_RUNNING, + 'modified' => $cutoff, + 'modified_compare' => '<=', + 'per_page' => $this->get_batch_size(), + ) ); + + foreach ( $actions_to_reset as $action_id ) { + $this->store->mark_failure( $action_id ); + do_action( 'action_scheduler_failed_action', $action_id, $timeout ); + } + } + + /** + * Do all of the cleaning actions. + * + * @param int $time_limit The number of seconds to use as the timeout and failure period. Default 300 (5 minutes). + * @author Jeremy Pry + */ + public function clean( $time_limit = 300 ) { + $this->delete_old_actions(); + $this->reset_timeouts( $time_limit ); + $this->mark_failures( $time_limit ); + } + + /** + * Get the batch size for cleaning the queue. + * + * @author Jeremy Pry + * @return int + */ + protected function get_batch_size() { + /** + * Filter the batch size when cleaning the queue. + * + * @param int $batch_size The number of actions to clean in one batch. + */ + return absint( apply_filters( 'action_scheduler_cleanup_batch_size', $this->batch_size ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_QueueRunner.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_QueueRunner.php new file mode 100644 index 0000000..d2ac090 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_QueueRunner.php @@ -0,0 +1,197 @@ +store ); + } + + $this->async_request = $async_request; + } + + /** + * @codeCoverageIgnore + */ + public function init() { + + add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) ); + + // Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param + $next_timestamp = wp_next_scheduled( self::WP_CRON_HOOK ); + if ( $next_timestamp ) { + wp_unschedule_event( $next_timestamp, self::WP_CRON_HOOK ); + } + + $cron_context = array( 'WP Cron' ); + + if ( ! wp_next_scheduled( self::WP_CRON_HOOK, $cron_context ) ) { + $schedule = apply_filters( 'action_scheduler_run_schedule', self::WP_CRON_SCHEDULE ); + wp_schedule_event( time(), $schedule, self::WP_CRON_HOOK, $cron_context ); + } + + add_action( self::WP_CRON_HOOK, array( self::instance(), 'run' ) ); + $this->hook_dispatch_async_request(); + } + + /** + * Hook check for dispatching an async request. + */ + public function hook_dispatch_async_request() { + add_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) ); + } + + /** + * Unhook check for dispatching an async request. + */ + public function unhook_dispatch_async_request() { + remove_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) ); + } + + /** + * Check if we should dispatch an async request to process actions. + * + * This method is attached to 'shutdown', so is called frequently. To avoid slowing down + * the site, it mitigates the work performed in each request by: + * 1. checking if it's in the admin context and then + * 2. haven't run on the 'shutdown' hook within the lock time (60 seconds by default) + * 3. haven't exceeded the number of allowed batches. + * + * The order of these checks is important, because they run from a check on a value: + * 1. in memory - is_admin() maps to $GLOBALS or the WP_ADMIN constant + * 2. in memory - transients use autoloaded options by default + * 3. from a database query - has_maximum_concurrent_batches() run the query + * $this->store->get_claim_count() to find the current number of claims in the DB. + * + * If all of these conditions are met, then we request an async runner check whether it + * should dispatch a request to process pending actions. + */ + public function maybe_dispatch_async_request() { + if ( is_admin() && ! ActionScheduler::lock()->is_locked( 'async-request-runner' ) ) { + // Only start an async queue at most once every 60 seconds + ActionScheduler::lock()->set( 'async-request-runner' ); + $this->async_request->maybe_dispatch(); + } + } + + /** + * Process actions in the queue. Attached to self::WP_CRON_HOOK i.e. 'action_scheduler_run_queue' + * + * The $context param of this method defaults to 'WP Cron', because prior to Action Scheduler 3.0.0 + * that was the only context in which this method was run, and the self::WP_CRON_HOOK hook had no context + * passed along with it. New code calling this method directly, or by triggering the self::WP_CRON_HOOK, + * should set a context as the first parameter. For an example of this, refer to the code seen in + * @see ActionScheduler_AsyncRequest_QueueRunner::handle() + * + * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron' + * Generally, this should be capitalised and not localised as it's a proper noun. + * @return int The number of actions processed. + */ + public function run( $context = 'WP Cron' ) { + ActionScheduler_Compatibility::raise_memory_limit(); + ActionScheduler_Compatibility::raise_time_limit( $this->get_time_limit() ); + do_action( 'action_scheduler_before_process_queue' ); + $this->run_cleanup(); + $processed_actions = 0; + if ( false === $this->has_maximum_concurrent_batches() ) { + $batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 ); + do { + $processed_actions_in_batch = $this->do_batch( $batch_size, $context ); + $processed_actions += $processed_actions_in_batch; + } while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $processed_actions ) ); // keep going until we run out of actions, time, or memory + } + + do_action( 'action_scheduler_after_process_queue' ); + return $processed_actions; + } + + /** + * Process a batch of actions pending in the queue. + * + * Actions are processed by claiming a set of pending actions then processing each one until either the batch + * size is completed, or memory or time limits are reached, defined by @see $this->batch_limits_exceeded(). + * + * @param int $size The maximum number of actions to process in the batch. + * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron' + * Generally, this should be capitalised and not localised as it's a proper noun. + * @return int The number of actions processed. + */ + protected function do_batch( $size = 100, $context = '' ) { + $claim = $this->store->stake_claim($size); + $this->monitor->attach($claim); + $processed_actions = 0; + + foreach ( $claim->get_actions() as $action_id ) { + // bail if we lost the claim + if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $claim->get_id() ) ) ) { + break; + } + $this->process_action( $action_id, $context ); + $processed_actions++; + + if ( $this->batch_limits_exceeded( $processed_actions ) ) { + break; + } + } + $this->store->release_claim($claim); + $this->monitor->detach(); + $this->clear_caches(); + return $processed_actions; + } + + /** + * Running large batches can eat up memory, as WP adds data to its object cache. + * + * If using a persistent object store, this has the side effect of flushing that + * as well, so this is disabled by default. To enable: + * + * add_filter( 'action_scheduler_queue_runner_flush_cache', '__return_true' ); + */ + protected function clear_caches() { + if ( ! wp_using_ext_object_cache() || apply_filters( 'action_scheduler_queue_runner_flush_cache', false ) ) { + wp_cache_flush(); + } + } + + public function add_wp_cron_schedule( $schedules ) { + $schedules['every_minute'] = array( + 'interval' => 60, // in seconds + 'display' => __( 'Every minute', 'woocommerce' ), + ); + + return $schedules; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_Versions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_Versions.php new file mode 100644 index 0000000..915c2e6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_Versions.php @@ -0,0 +1,62 @@ +versions[$version_string]) ) { + return FALSE; + } + $this->versions[$version_string] = $initialization_callback; + return TRUE; + } + + public function get_versions() { + return $this->versions; + } + + public function latest_version() { + $keys = array_keys($this->versions); + if ( empty($keys) ) { + return false; + } + uasort( $keys, 'version_compare' ); + return end($keys); + } + + public function latest_version_callback() { + $latest = $this->latest_version(); + if ( empty($latest) || !isset($this->versions[$latest]) ) { + return '__return_null'; + } + return $this->versions[$latest]; + } + + /** + * @return ActionScheduler_Versions + * @codeCoverageIgnore + */ + public static function instance() { + if ( empty(self::$instance) ) { + self::$instance = new self(); + } + return self::$instance; + } + + /** + * @codeCoverageIgnore + */ + public static function initialize_latest_version() { + $self = self::instance(); + call_user_func($self->latest_version_callback()); + } +} + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php new file mode 100644 index 0000000..bad2c2c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php @@ -0,0 +1,115 @@ + Status administration screen + add_action( 'load-tools_page_action-scheduler', array( __CLASS__, 'register_admin_notice' ) ); + add_action( 'load-woocommerce_page_wc-status', array( __CLASS__, 'register_admin_notice' ) ); + } + + /** + * Determines if there are log entries in the wp comments table. + * + * Uses the flag set on migration completion set by @see self::maybe_schedule_cleanup(). + * + * @return boolean Whether there are scheduled action comments in the comments table. + */ + public static function has_logs() { + return 'yes' === get_option( self::$has_logs_option_key ); + } + + /** + * Schedules the WP Post comment table cleanup to run in 6 months if it's not already scheduled. + * Attached to the migration complete hook 'action_scheduler/migration_complete'. + */ + public static function maybe_schedule_cleanup() { + if ( (bool) get_comments( array( 'type' => ActionScheduler_wpCommentLogger::TYPE, 'number' => 1, 'fields' => 'ids' ) ) ) { + update_option( self::$has_logs_option_key, 'yes' ); + + if ( ! as_next_scheduled_action( self::$cleanup_hook ) ) { + as_schedule_single_action( gmdate( 'U' ) + ( 6 * MONTH_IN_SECONDS ), self::$cleanup_hook ); + } + } + } + + /** + * Delete all action comments from the WP Comments table. + */ + public static function delete_all_action_comments() { + global $wpdb; + $wpdb->delete( $wpdb->comments, array( 'comment_type' => ActionScheduler_wpCommentLogger::TYPE, 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT ) ); + delete_option( self::$has_logs_option_key ); + } + + /** + * Registers admin notices about the orphaned action logs. + */ + public static function register_admin_notice() { + add_action( 'admin_notices', array( __CLASS__, 'print_admin_notice' ) ); + } + + /** + * Prints details about the orphaned action logs and includes information on where to learn more. + */ + public static function print_admin_notice() { + $next_cleanup_message = ''; + $next_scheduled_cleanup_hook = as_next_scheduled_action( self::$cleanup_hook ); + + if ( $next_scheduled_cleanup_hook ) { + /* translators: %s: date interval */ + $next_cleanup_message = sprintf( __( 'This data will be deleted in %s.', 'woocommerce' ), human_time_diff( gmdate( 'U' ), $next_scheduled_cleanup_hook ) ); + } + + $notice = sprintf( + /* translators: 1: next cleanup message 2: github issue URL */ + __( 'Action Scheduler has migrated data to custom tables; however, orphaned log entries exist in the WordPress Comments table. %1$s Learn more »', 'woocommerce' ), + $next_cleanup_message, + 'https://github.com/woocommerce/action-scheduler/issues/368' + ); + + echo '

    ' . wp_kses_post( $notice ) . '

    '; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_wcSystemStatus.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_wcSystemStatus.php new file mode 100644 index 0000000..3988389 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_wcSystemStatus.php @@ -0,0 +1,152 @@ +store = $store; + } + + /** + * Display action data, including number of actions grouped by status and the oldest & newest action in each status. + * + * Helpful to identify issues, like a clogged queue. + */ + public function render() { + $action_counts = $this->store->action_counts(); + $status_labels = $this->store->get_status_labels(); + $oldest_and_newest = $this->get_oldest_and_newest( array_keys( $status_labels ) ); + + $this->get_template( $status_labels, $action_counts, $oldest_and_newest ); + } + + /** + * Get oldest and newest scheduled dates for a given set of statuses. + * + * @param array $status_keys Set of statuses to find oldest & newest action for. + * @return array + */ + protected function get_oldest_and_newest( $status_keys ) { + + $oldest_and_newest = array(); + + foreach ( $status_keys as $status ) { + $oldest_and_newest[ $status ] = array( + 'oldest' => '–', + 'newest' => '–', + ); + + if ( 'in-progress' === $status ) { + continue; + } + + $oldest_and_newest[ $status ]['oldest'] = $this->get_action_status_date( $status, 'oldest' ); + $oldest_and_newest[ $status ]['newest'] = $this->get_action_status_date( $status, 'newest' ); + } + + return $oldest_and_newest; + } + + /** + * Get oldest or newest scheduled date for a given status. + * + * @param string $status Action status label/name string. + * @param string $date_type Oldest or Newest. + * @return DateTime + */ + protected function get_action_status_date( $status, $date_type = 'oldest' ) { + + $order = 'oldest' === $date_type ? 'ASC' : 'DESC'; + + $action = $this->store->query_actions( array( + 'claimed' => false, + 'status' => $status, + 'per_page' => 1, + 'order' => $order, + ) ); + + if ( ! empty( $action ) ) { + $date_object = $this->store->get_date( $action[0] ); + $action_date = $date_object->format( 'Y-m-d H:i:s O' ); + } else { + $action_date = '–'; + } + + return $action_date; + } + + /** + * Get oldest or newest scheduled date for a given status. + * + * @param array $status_labels Set of statuses to find oldest & newest action for. + * @param array $action_counts Number of actions grouped by status. + * @param array $oldest_and_newest Date of the oldest and newest action with each status. + */ + protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) { + $as_version = ActionScheduler_Versions::instance()->latest_version(); + ?> + + + + + + + + + + + + + + + + + + + + $count ) { + // WC uses the 3rd column for export, so we need to display more data in that (hidden when viewed as part of the table) and add an empty 2nd column. + printf( + '', + esc_html( $status_labels[ $status ] ), + number_format_i18n( $count ), + $oldest_and_newest[ $status ]['oldest'], + $oldest_and_newest[ $status ]['newest'] + ); + } + ?> + +

     
    %1$s %2$s, Oldest: %3$s, Newest: %4$s%3$s%4$s
    + + run_cleanup(); + $this->add_hooks(); + + // Check to make sure there aren't too many concurrent processes running. + if ( $this->has_maximum_concurrent_batches() ) { + if ( $force ) { + WP_CLI::warning( __( 'There are too many concurrent batches, but the run is forced to continue.', 'woocommerce' ) ); + } else { + WP_CLI::error( __( 'There are too many concurrent batches.', 'woocommerce' ) ); + } + } + + // Stake a claim and store it. + $this->claim = $this->store->stake_claim( $batch_size, null, $hooks, $group ); + $this->monitor->attach( $this->claim ); + $this->actions = $this->claim->get_actions(); + + return count( $this->actions ); + } + + /** + * Add our hooks to the appropriate actions. + * + * @author Jeremy Pry + */ + protected function add_hooks() { + add_action( 'action_scheduler_before_execute', array( $this, 'before_execute' ) ); + add_action( 'action_scheduler_after_execute', array( $this, 'after_execute' ), 10, 2 ); + add_action( 'action_scheduler_failed_execution', array( $this, 'action_failed' ), 10, 2 ); + } + + /** + * Set up the WP CLI progress bar. + * + * @author Jeremy Pry + */ + protected function setup_progress_bar() { + $count = count( $this->actions ); + $this->progress_bar = new ProgressBar( + /* translators: %d: amount of actions */ + sprintf( _n( 'Running %d action', 'Running %d actions', $count, 'woocommerce' ), number_format_i18n( $count ) ), + $count + ); + } + + /** + * Process actions in the queue. + * + * @author Jeremy Pry + * + * @param string $context Optional runner context. Default 'WP CLI'. + * + * @return int The number of actions processed. + */ + public function run( $context = 'WP CLI' ) { + do_action( 'action_scheduler_before_process_queue' ); + $this->setup_progress_bar(); + foreach ( $this->actions as $action_id ) { + // Error if we lost the claim. + if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $this->claim->get_id() ) ) ) { + WP_CLI::warning( __( 'The claim has been lost. Aborting current batch.', 'woocommerce' ) ); + break; + } + + $this->process_action( $action_id, $context ); + $this->progress_bar->tick(); + } + + $completed = $this->progress_bar->current(); + $this->progress_bar->finish(); + $this->store->release_claim( $this->claim ); + do_action( 'action_scheduler_after_process_queue' ); + + return $completed; + } + + /** + * Handle WP CLI message when the action is starting. + * + * @author Jeremy Pry + * + * @param $action_id + */ + public function before_execute( $action_id ) { + /* translators: %s refers to the action ID */ + WP_CLI::log( sprintf( __( 'Started processing action %s', 'woocommerce' ), $action_id ) ); + } + + /** + * Handle WP CLI message when the action has completed. + * + * @author Jeremy Pry + * + * @param int $action_id + * @param null|ActionScheduler_Action $action The instance of the action. Default to null for backward compatibility. + */ + public function after_execute( $action_id, $action = null ) { + // backward compatibility + if ( null === $action ) { + $action = $this->store->fetch_action( $action_id ); + } + /* translators: 1: action ID 2: hook name */ + WP_CLI::log( sprintf( __( 'Completed processing action %1$s with hook: %2$s', 'woocommerce' ), $action_id, $action->get_hook() ) ); + } + + /** + * Handle WP CLI message when the action has failed. + * + * @author Jeremy Pry + * + * @param int $action_id + * @param Exception $exception + * @throws \WP_CLI\ExitException With failure message. + */ + public function action_failed( $action_id, $exception ) { + WP_CLI::error( + /* translators: 1: action ID 2: exception message */ + sprintf( __( 'Error processing action %1$s: %2$s', 'woocommerce' ), $action_id, $exception->getMessage() ), + false + ); + } + + /** + * Sleep and help avoid hitting memory limit + * + * @param int $sleep_time Amount of seconds to sleep + * @deprecated 3.0.0 + */ + protected function stop_the_insanity( $sleep_time = 0 ) { + _deprecated_function( 'ActionScheduler_WPCLI_QueueRunner::stop_the_insanity', '3.0.0', 'ActionScheduler_DataController::free_memory' ); + + ActionScheduler_DataController::free_memory(); + } + + /** + * Maybe trigger the stop_the_insanity() method to free up memory. + */ + protected function maybe_stop_the_insanity() { + // The value returned by progress_bar->current() might be padded. Remove padding, and convert to int. + $current_iteration = intval( trim( $this->progress_bar->current() ) ); + if ( 0 === $current_iteration % 50 ) { + $this->stop_the_insanity(); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php new file mode 100644 index 0000000..e66e7c6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php @@ -0,0 +1,158 @@ +] + * : The maximum number of actions to run. Defaults to 100. + * + * [--batches=] + * : Limit execution to a number of batches. Defaults to 0, meaning batches will continue being executed until all actions are complete. + * + * [--cleanup-batch-size=] + * : The maximum number of actions to clean up. Defaults to the value of --batch-size. + * + * [--hooks=] + * : Only run actions with the specified hook. Omitting this option runs actions with any hook. Define multiple hooks as a comma separated string (without spaces), e.g. `--hooks=hook_one,hook_two,hook_three` + * + * [--group=] + * : Only run actions from the specified group. Omitting this option runs actions from all groups. + * + * [--free-memory-on=] + * : The number of actions to process between freeing memory. 0 disables freeing memory. Default 50. + * + * [--pause=] + * : The number of seconds to pause when freeing memory. Default no pause. + * + * [--force] + * : Whether to force execution despite the maximum number of concurrent processes being exceeded. + * + * @param array $args Positional arguments. + * @param array $assoc_args Keyed arguments. + * @throws \WP_CLI\ExitException When an error occurs. + * + * @subcommand run + */ + public function run( $args, $assoc_args ) { + // Handle passed arguments. + $batch = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'batch-size', 100 ) ); + $batches = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'batches', 0 ) ); + $clean = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'cleanup-batch-size', $batch ) ); + $hooks = explode( ',', WP_CLI\Utils\get_flag_value( $assoc_args, 'hooks', '' ) ); + $hooks = array_filter( array_map( 'trim', $hooks ) ); + $group = \WP_CLI\Utils\get_flag_value( $assoc_args, 'group', '' ); + $free_on = \WP_CLI\Utils\get_flag_value( $assoc_args, 'free-memory-on', 50 ); + $sleep = \WP_CLI\Utils\get_flag_value( $assoc_args, 'pause', 0 ); + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force', false ); + + ActionScheduler_DataController::set_free_ticks( $free_on ); + ActionScheduler_DataController::set_sleep_time( $sleep ); + + $batches_completed = 0; + $actions_completed = 0; + $unlimited = $batches === 0; + + try { + // Custom queue cleaner instance. + $cleaner = new ActionScheduler_QueueCleaner( null, $clean ); + + // Get the queue runner instance + $runner = new ActionScheduler_WPCLI_QueueRunner( null, null, $cleaner ); + + // Determine how many tasks will be run in the first batch. + $total = $runner->setup( $batch, $hooks, $group, $force ); + + // Run actions for as long as possible. + while ( $total > 0 ) { + $this->print_total_actions( $total ); + $actions_completed += $runner->run(); + $batches_completed++; + + // Maybe set up tasks for the next batch. + $total = ( $unlimited || $batches_completed < $batches ) ? $runner->setup( $batch, $hooks, $group, $force ) : 0; + } + } catch ( Exception $e ) { + $this->print_error( $e ); + } + + $this->print_total_batches( $batches_completed ); + $this->print_success( $actions_completed ); + } + + /** + * Print WP CLI message about how many actions are about to be processed. + * + * @author Jeremy Pry + * + * @param int $total + */ + protected function print_total_actions( $total ) { + WP_CLI::log( + sprintf( + /* translators: %d refers to how many scheduled taks were found to run */ + _n( 'Found %d scheduled task', 'Found %d scheduled tasks', $total, 'woocommerce' ), + number_format_i18n( $total ) + ) + ); + } + + /** + * Print WP CLI message about how many batches of actions were processed. + * + * @author Jeremy Pry + * + * @param int $batches_completed + */ + protected function print_total_batches( $batches_completed ) { + WP_CLI::log( + sprintf( + /* translators: %d refers to the total number of batches executed */ + _n( '%d batch executed.', '%d batches executed.', $batches_completed, 'woocommerce' ), + number_format_i18n( $batches_completed ) + ) + ); + } + + /** + * Convert an exception into a WP CLI error. + * + * @author Jeremy Pry + * + * @param Exception $e The error object. + * + * @throws \WP_CLI\ExitException + */ + protected function print_error( Exception $e ) { + WP_CLI::error( + sprintf( + /* translators: %s refers to the exception error message */ + __( 'There was an error running the action scheduler: %s', 'woocommerce' ), + $e->getMessage() + ) + ); + } + + /** + * Print a success message with the number of completed actions. + * + * @author Jeremy Pry + * + * @param int $actions_completed + */ + protected function print_success( $actions_completed ) { + WP_CLI::success( + sprintf( + /* translators: %d refers to the total number of taskes completed */ + _n( '%d scheduled task completed.', '%d scheduled tasks completed.', $actions_completed, 'woocommerce' ), + number_format_i18n( $actions_completed ) + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/WP_CLI/Migration_Command.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/WP_CLI/Migration_Command.php new file mode 100644 index 0000000..066697e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/WP_CLI/Migration_Command.php @@ -0,0 +1,148 @@ + 'Migrates actions to the DB tables store', + 'synopsis' => [ + [ + 'type' => 'assoc', + 'name' => 'batch-size', + 'optional' => true, + 'default' => 100, + 'description' => 'The number of actions to process in each batch', + ], + [ + 'type' => 'assoc', + 'name' => 'free-memory-on', + 'optional' => true, + 'default' => 50, + 'description' => 'The number of actions to process between freeing memory. 0 disables freeing memory', + ], + [ + 'type' => 'assoc', + 'name' => 'pause', + 'optional' => true, + 'default' => 0, + 'description' => 'The number of seconds to pause when freeing memory', + ], + [ + 'type' => 'flag', + 'name' => 'dry-run', + 'optional' => true, + 'description' => 'Reports on the actions that would have been migrated, but does not change any data', + ], + ], + ] ); + } + + /** + * Process the data migration. + * + * @param array $positional_args Required for WP CLI. Not used in migration. + * @param array $assoc_args Optional arguments. + * + * @return void + */ + public function migrate( $positional_args, $assoc_args ) { + $this->init_logging(); + + $config = $this->get_migration_config( $assoc_args ); + $runner = new Runner( $config ); + $runner->init_destination(); + + $batch_size = isset( $assoc_args[ 'batch-size' ] ) ? (int) $assoc_args[ 'batch-size' ] : 100; + $free_on = isset( $assoc_args[ 'free-memory-on' ] ) ? (int) $assoc_args[ 'free-memory-on' ] : 50; + $sleep = isset( $assoc_args[ 'pause' ] ) ? (int) $assoc_args[ 'pause' ] : 0; + \ActionScheduler_DataController::set_free_ticks( $free_on ); + \ActionScheduler_DataController::set_sleep_time( $sleep ); + + do { + $actions_processed = $runner->run( $batch_size ); + $this->total_processed += $actions_processed; + } while ( $actions_processed > 0 ); + + if ( ! $config->get_dry_run() ) { + // let the scheduler know that there's nothing left to do + $scheduler = new Scheduler(); + $scheduler->mark_complete(); + } + + WP_CLI::success( sprintf( '%s complete. %d actions processed.', $config->get_dry_run() ? 'Dry run' : 'Migration', $this->total_processed ) ); + } + + /** + * Build the config object used to create the Runner + * + * @param array $args Optional arguments. + * + * @return ActionScheduler\Migration\Config + */ + private function get_migration_config( $args ) { + $args = wp_parse_args( $args, [ + 'dry-run' => false, + ] ); + + $config = Controller::instance()->get_migration_config_object(); + $config->set_dry_run( ! empty( $args[ 'dry-run' ] ) ); + + return $config; + } + + /** + * Hook command line logging into migration actions. + */ + private function init_logging() { + add_action( 'action_scheduler/migrate_action_dry_run', function ( $action_id ) { + WP_CLI::debug( sprintf( 'Dry-run: migrated action %d', $action_id ) ); + }, 10, 1 ); + add_action( 'action_scheduler/no_action_to_migrate', function ( $action_id ) { + WP_CLI::debug( sprintf( 'No action found to migrate for ID %d', $action_id ) ); + }, 10, 1 ); + add_action( 'action_scheduler/migrate_action_failed', function ( $action_id ) { + WP_CLI::warning( sprintf( 'Failed migrating action with ID %d', $action_id ) ); + }, 10, 1 ); + add_action( 'action_scheduler/migrate_action_incomplete', function ( $source_id, $destination_id ) { + WP_CLI::warning( sprintf( 'Unable to remove source action with ID %d after migrating to new ID %d', $source_id, $destination_id ) ); + }, 10, 2 ); + add_action( 'action_scheduler/migrated_action', function ( $source_id, $destination_id ) { + WP_CLI::debug( sprintf( 'Migrated source action with ID %d to new store with ID %d', $source_id, $destination_id ) ); + }, 10, 2 ); + add_action( 'action_scheduler/migration_batch_starting', function ( $batch ) { + WP_CLI::debug( 'Beginning migration of batch: ' . print_r( $batch, true ) ); + }, 10, 1 ); + add_action( 'action_scheduler/migration_batch_complete', function ( $batch ) { + WP_CLI::log( sprintf( 'Completed migration of %d actions', count( $batch ) ) ); + }, 10, 1 ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/WP_CLI/ProgressBar.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/WP_CLI/ProgressBar.php new file mode 100644 index 0000000..dcb6e8d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/WP_CLI/ProgressBar.php @@ -0,0 +1,119 @@ +total_ticks = 0; + $this->message = $message; + $this->count = $count; + $this->interval = $interval; + } + + /** + * Increment the progress bar ticks. + */ + public function tick() { + if ( null === $this->progress_bar ) { + $this->setup_progress_bar(); + } + + $this->progress_bar->tick(); + $this->total_ticks++; + + do_action( 'action_scheduler/progress_tick', $this->total_ticks ); + } + + /** + * Get the progress bar tick count. + * + * @return int + */ + public function current() { + return $this->progress_bar ? $this->progress_bar->current() : 0; + } + + /** + * Finish the current progress bar. + */ + public function finish() { + if ( null !== $this->progress_bar ) { + $this->progress_bar->finish(); + } + + $this->progress_bar = null; + } + + /** + * Set the message used when creating the progress bar. + * + * @param string $message The message to be used when the next progress bar is created. + */ + public function set_message( $message ) { + $this->message = $message; + } + + /** + * Set the count for a new progress bar. + * + * @param integer $count The total number of ticks expected to complete. + */ + public function set_count( $count ) { + $this->count = $count; + $this->finish(); + } + + /** + * Set up the progress bar. + */ + protected function setup_progress_bar() { + $this->progress_bar = \WP_CLI\Utils\make_progress_bar( + $this->message, + $this->count, + $this->interval + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler.php new file mode 100644 index 0000000..755b167 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler.php @@ -0,0 +1,304 @@ +init(); + $store->init(); + $logger->init(); + $runner->init(); + } + + if ( apply_filters( 'action_scheduler_load_deprecated_functions', true ) ) { + require_once( self::plugin_path( 'deprecated/functions.php' ) ); + } + + if ( defined( 'WP_CLI' ) && WP_CLI ) { + WP_CLI::add_command( 'action-scheduler', 'ActionScheduler_WPCLI_Scheduler_command' ); + if ( ! ActionScheduler_DataController::is_migration_complete() && Controller::instance()->allow_migration() ) { + $command = new Migration_Command(); + $command->register(); + } + } + + self::$data_store_initialized = true; + + /** + * Handle WP comment cleanup after migration. + */ + if ( is_a( $logger, 'ActionScheduler_DBLogger' ) && ActionScheduler_DataController::is_migration_complete() && ActionScheduler_WPCommentCleaner::has_logs() ) { + ActionScheduler_WPCommentCleaner::init(); + } + + add_action( 'action_scheduler/migration_complete', 'ActionScheduler_WPCommentCleaner::maybe_schedule_cleanup' ); + } + + /** + * Check whether the AS data store has been initialized. + * + * @param string $function_name The name of the function being called. Optional. Default `null`. + * @return bool + */ + public static function is_initialized( $function_name = null ) { + if ( ! self::$data_store_initialized && ! empty( $function_name ) ) { + $message = sprintf( __( '%s() was called before the Action Scheduler data store was initialized', 'woocommerce' ), esc_attr( $function_name ) ); + error_log( $message, E_WARNING ); + } + + return self::$data_store_initialized; + } + + /** + * Determine if the class is one of our abstract classes. + * + * @since 3.0.0 + * + * @param string $class The class name. + * + * @return bool + */ + protected static function is_class_abstract( $class ) { + static $abstracts = array( + 'ActionScheduler' => true, + 'ActionScheduler_Abstract_ListTable' => true, + 'ActionScheduler_Abstract_QueueRunner' => true, + 'ActionScheduler_Abstract_Schedule' => true, + 'ActionScheduler_Abstract_RecurringSchedule' => true, + 'ActionScheduler_Lock' => true, + 'ActionScheduler_Logger' => true, + 'ActionScheduler_Abstract_Schema' => true, + 'ActionScheduler_Store' => true, + 'ActionScheduler_TimezoneHelper' => true, + ); + + return isset( $abstracts[ $class ] ) && $abstracts[ $class ]; + } + + /** + * Determine if the class is one of our migration classes. + * + * @since 3.0.0 + * + * @param string $class The class name. + * + * @return bool + */ + protected static function is_class_migration( $class ) { + static $migration_segments = array( + 'ActionMigrator' => true, + 'BatchFetcher' => true, + 'DBStoreMigrator' => true, + 'DryRun' => true, + 'LogMigrator' => true, + 'Config' => true, + 'Controller' => true, + 'Runner' => true, + 'Scheduler' => true, + ); + + $segments = explode( '_', $class ); + $segment = isset( $segments[ 1 ] ) ? $segments[ 1 ] : $class; + + return isset( $migration_segments[ $segment ] ) && $migration_segments[ $segment ]; + } + + /** + * Determine if the class is one of our WP CLI classes. + * + * @since 3.0.0 + * + * @param string $class The class name. + * + * @return bool + */ + protected static function is_class_cli( $class ) { + static $cli_segments = array( + 'QueueRunner' => true, + 'Command' => true, + 'ProgressBar' => true, + ); + + $segments = explode( '_', $class ); + $segment = isset( $segments[ 1 ] ) ? $segments[ 1 ] : $class; + + return isset( $cli_segments[ $segment ] ) && $cli_segments[ $segment ]; + } + + final public function __clone() { + trigger_error("Singleton. No cloning allowed!", E_USER_ERROR); + } + + final public function __wakeup() { + trigger_error("Singleton. No serialization allowed!", E_USER_ERROR); + } + + final private function __construct() {} + + /** Deprecated **/ + + public static function get_datetime_object( $when = null, $timezone = 'UTC' ) { + _deprecated_function( __METHOD__, '2.0', 'wcs_add_months()' ); + return as_get_datetime_object( $when, $timezone ); + } + + /** + * Issue deprecated warning if an Action Scheduler function is called in the shutdown hook. + * + * @param string $function_name The name of the function being called. + * @deprecated 3.1.6. + */ + public static function check_shutdown_hook( $function_name ) { + _deprecated_function( __FUNCTION__, '3.1.6' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php new file mode 100644 index 0000000..1276f68 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php @@ -0,0 +1,674 @@ + value pair. The + * key must much the table column name and the value is the label, which is + * automatically translated. + */ + protected $columns = array(); + + /** + * Defines the row-actions. It expects an array where the key + * is the column name and the value is an array of actions. + * + * The array of actions are key => value, where key is the method name + * (with the prefix row_action_) and the value is the label + * and title. + */ + protected $row_actions = array(); + + /** + * The Primary key of our table + */ + protected $ID = 'ID'; + + /** + * Enables sorting, it expects an array + * of columns (the column names are the values) + */ + protected $sort_by = array(); + + protected $filter_by = array(); + + /** + * @var array The status name => count combinations for this table's items. Used to display status filters. + */ + protected $status_counts = array(); + + /** + * @var array Notices to display when loading the table. Array of arrays of form array( 'class' => {updated|error}, 'message' => 'This is the notice text display.' ). + */ + protected $admin_notices = array(); + + /** + * @var string Localised string displayed in the

    element above the able. + */ + protected $table_header; + + /** + * Enables bulk actions. It must be an array where the key is the action name + * and the value is the label (which is translated automatically). It is important + * to notice that it will check that the method exists (`bulk_$name`) and will throw + * an exception if it does not exists. + * + * This class will automatically check if the current request has a bulk action, will do the + * validations and afterwards will execute the bulk method, with two arguments. The first argument + * is the array with primary keys, the second argument is a string with a list of the primary keys, + * escaped and ready to use (with `IN`). + */ + protected $bulk_actions = array(); + + /** + * Makes translation easier, it basically just wraps + * `_x` with some default (the package name). + * + * @deprecated 3.0.0 + */ + protected function translate( $text, $context = '' ) { + return $text; + } + + /** + * Reads `$this->bulk_actions` and returns an array that WP_List_Table understands. It + * also validates that the bulk method handler exists. It throws an exception because + * this is a library meant for developers and missing a bulk method is a development-time error. + */ + protected function get_bulk_actions() { + $actions = array(); + + foreach ( $this->bulk_actions as $action => $label ) { + if ( ! is_callable( array( $this, 'bulk_' . $action ) ) ) { + throw new RuntimeException( "The bulk action $action does not have a callback method" ); + } + + $actions[ $action ] = $label; + } + + return $actions; + } + + /** + * Checks if the current request has a bulk action. If that is the case it will validate and will + * execute the bulk method handler. Regardless if the action is valid or not it will redirect to + * the previous page removing the current arguments that makes this request a bulk action. + */ + protected function process_bulk_action() { + global $wpdb; + // Detect when a bulk action is being triggered. + $action = $this->current_action(); + if ( ! $action ) { + return; + } + + check_admin_referer( 'bulk-' . $this->_args['plural'] ); + + $method = 'bulk_' . $action; + if ( array_key_exists( $action, $this->bulk_actions ) && is_callable( array( $this, $method ) ) && ! empty( $_GET['ID'] ) && is_array( $_GET['ID'] ) ) { + $ids_sql = '(' . implode( ',', array_fill( 0, count( $_GET['ID'] ), '%s' ) ) . ')'; + $this->$method( $_GET['ID'], $wpdb->prepare( $ids_sql, $_GET['ID'] ) ); + } + + wp_redirect( remove_query_arg( + array( '_wp_http_referer', '_wpnonce', 'ID', 'action', 'action2' ), + wp_unslash( $_SERVER['REQUEST_URI'] ) + ) ); + exit; + } + + /** + * Default code for deleting entries. + * validated already by process_bulk_action() + */ + protected function bulk_delete( array $ids, $ids_sql ) { + $store = ActionScheduler::store(); + foreach ( $ids as $action_id ) { + $store->delete( $action_id ); + } + } + + /** + * Prepares the _column_headers property which is used by WP_Table_List at rendering. + * It merges the columns and the sortable columns. + */ + protected function prepare_column_headers() { + $this->_column_headers = array( + $this->get_columns(), + array(), + $this->get_sortable_columns(), + ); + } + + /** + * Reads $this->sort_by and returns the columns name in a format that WP_Table_List + * expects + */ + public function get_sortable_columns() { + $sort_by = array(); + foreach ( $this->sort_by as $column ) { + $sort_by[ $column ] = array( $column, true ); + } + return $sort_by; + } + + /** + * Returns the columns names for rendering. It adds a checkbox for selecting everything + * as the first column + */ + public function get_columns() { + $columns = array_merge( + array( 'cb' => '' ), + $this->columns + ); + + return $columns; + } + + /** + * Get prepared LIMIT clause for items query + * + * @global wpdb $wpdb + * + * @return string Prepared LIMIT clause for items query. + */ + protected function get_items_query_limit() { + global $wpdb; + + $per_page = $this->get_items_per_page( $this->package . '_items_per_page', $this->items_per_page ); + return $wpdb->prepare( 'LIMIT %d', $per_page ); + } + + /** + * Returns the number of items to offset/skip for this current view. + * + * @return int + */ + protected function get_items_offset() { + $per_page = $this->get_items_per_page( $this->package . '_items_per_page', $this->items_per_page ); + $current_page = $this->get_pagenum(); + if ( 1 < $current_page ) { + $offset = $per_page * ( $current_page - 1 ); + } else { + $offset = 0; + } + + return $offset; + } + + /** + * Get prepared OFFSET clause for items query + * + * @global wpdb $wpdb + * + * @return string Prepared OFFSET clause for items query. + */ + protected function get_items_query_offset() { + global $wpdb; + + return $wpdb->prepare( 'OFFSET %d', $this->get_items_offset() ); + } + + /** + * Prepares the ORDER BY sql statement. It uses `$this->sort_by` to know which + * columns are sortable. This requests validates the orderby $_GET parameter is a valid + * column and sortable. It will also use order (ASC|DESC) using DESC by default. + */ + protected function get_items_query_order() { + if ( empty( $this->sort_by ) ) { + return ''; + } + + $orderby = esc_sql( $this->get_request_orderby() ); + $order = esc_sql( $this->get_request_order() ); + + return "ORDER BY {$orderby} {$order}"; + } + + /** + * Return the sortable column specified for this request to order the results by, if any. + * + * @return string + */ + protected function get_request_orderby() { + + $valid_sortable_columns = array_values( $this->sort_by ); + + if ( ! empty( $_GET['orderby'] ) && in_array( $_GET['orderby'], $valid_sortable_columns ) ) { + $orderby = sanitize_text_field( $_GET['orderby'] ); + } else { + $orderby = $valid_sortable_columns[0]; + } + + return $orderby; + } + + /** + * Return the sortable column order specified for this request. + * + * @return string + */ + protected function get_request_order() { + + if ( ! empty( $_GET['order'] ) && 'desc' === strtolower( $_GET['order'] ) ) { + $order = 'DESC'; + } else { + $order = 'ASC'; + } + + return $order; + } + + /** + * Return the status filter for this request, if any. + * + * @return string + */ + protected function get_request_status() { + $status = ( ! empty( $_GET['status'] ) ) ? $_GET['status'] : ''; + return $status; + } + + /** + * Return the search filter for this request, if any. + * + * @return string + */ + protected function get_request_search_query() { + $search_query = ( ! empty( $_GET['s'] ) ) ? $_GET['s'] : ''; + return $search_query; + } + + /** + * Process and return the columns name. This is meant for using with SQL, this means it + * always includes the primary key. + * + * @return array + */ + protected function get_table_columns() { + $columns = array_keys( $this->columns ); + if ( ! in_array( $this->ID, $columns ) ) { + $columns[] = $this->ID; + } + + return $columns; + } + + /** + * Check if the current request is doing a "full text" search. If that is the case + * prepares the SQL to search texts using LIKE. + * + * If the current request does not have any search or if this list table does not support + * that feature it will return an empty string. + * + * TODO: + * - Improve search doing LIKE by word rather than by phrases. + * + * @return string + */ + protected function get_items_query_search() { + global $wpdb; + + if ( empty( $_GET['s'] ) || empty( $this->search_by ) ) { + return ''; + } + + $filter = array(); + foreach ( $this->search_by as $column ) { + $filter[] = $wpdb->prepare('`' . $column . '` like "%%s%"', $wpdb->esc_like( $_GET['s'] )); + } + return implode( ' OR ', $filter ); + } + + /** + * Prepares the SQL to filter rows by the options defined at `$this->filter_by`. Before trusting + * any data sent by the user it validates that it is a valid option. + */ + protected function get_items_query_filters() { + global $wpdb; + + if ( ! $this->filter_by || empty( $_GET['filter_by'] ) || ! is_array( $_GET['filter_by'] ) ) { + return ''; + } + + $filter = array(); + + foreach ( $this->filter_by as $column => $options ) { + if ( empty( $_GET['filter_by'][ $column ] ) || empty( $options[ $_GET['filter_by'][ $column ] ] ) ) { + continue; + } + + $filter[] = $wpdb->prepare( "`$column` = %s", $_GET['filter_by'][ $column ] ); + } + + return implode( ' AND ', $filter ); + + } + + /** + * Prepares the data to feed WP_Table_List. + * + * This has the core for selecting, sorting and filting data. To keep the code simple + * its logic is split among many methods (get_items_query_*). + * + * Beside populating the items this function will also count all the records that matches + * the filtering criteria and will do fill the pagination variables. + */ + public function prepare_items() { + global $wpdb; + + $this->process_bulk_action(); + + $this->process_row_actions(); + + if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) { + // _wp_http_referer is used only on bulk actions, we remove it to keep the $_GET shorter + wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ); + exit; + } + + $this->prepare_column_headers(); + + $limit = $this->get_items_query_limit(); + $offset = $this->get_items_query_offset(); + $order = $this->get_items_query_order(); + $where = array_filter(array( + $this->get_items_query_search(), + $this->get_items_query_filters(), + )); + $columns = '`' . implode( '`, `', $this->get_table_columns() ) . '`'; + + if ( ! empty( $where ) ) { + $where = 'WHERE ('. implode( ') AND (', $where ) . ')'; + } else { + $where = ''; + } + + $sql = "SELECT $columns FROM {$this->table_name} {$where} {$order} {$limit} {$offset}"; + + $this->set_items( $wpdb->get_results( $sql, ARRAY_A ) ); + + $query_count = "SELECT COUNT({$this->ID}) FROM {$this->table_name} {$where}"; + $total_items = $wpdb->get_var( $query_count ); + $per_page = $this->get_items_per_page( $this->package . '_items_per_page', $this->items_per_page ); + $this->set_pagination_args( array( + 'total_items' => $total_items, + 'per_page' => $per_page, + 'total_pages' => ceil( $total_items / $per_page ), + ) ); + } + + public function extra_tablenav( $which ) { + if ( ! $this->filter_by || 'top' !== $which ) { + return; + } + + echo '
    '; + + foreach ( $this->filter_by as $id => $options ) { + $default = ! empty( $_GET['filter_by'][ $id ] ) ? $_GET['filter_by'][ $id ] : ''; + if ( empty( $options[ $default ] ) ) { + $default = ''; + } + + echo ''; + } + + submit_button( esc_html__( 'Filter', 'woocommerce' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) ); + echo '
    '; + } + + /** + * Set the data for displaying. It will attempt to unserialize (There is a chance that some columns + * are serialized). This can be override in child classes for futher data transformation. + */ + protected function set_items( array $items ) { + $this->items = array(); + foreach ( $items as $item ) { + $this->items[ $item[ $this->ID ] ] = array_map( 'maybe_unserialize', $item ); + } + } + + /** + * Renders the checkbox for each row, this is the first column and it is named ID regardless + * of how the primary key is named (to keep the code simpler). The bulk actions will do the proper + * name transformation though using `$this->ID`. + */ + public function column_cb( $row ) { + return ''; + } + + /** + * Renders the row-actions. + * + * This method renders the action menu, it reads the definition from the $row_actions property, + * and it checks that the row action method exists before rendering it. + * + * @param array $row Row to render + * @param $column_name Current row + * @return + */ + protected function maybe_render_actions( $row, $column_name ) { + if ( empty( $this->row_actions[ $column_name ] ) ) { + return; + } + + $row_id = $row[ $this->ID ]; + + $actions = '
    '; + $action_count = 0; + foreach ( $this->row_actions[ $column_name ] as $action_key => $action ) { + + $action_count++; + + if ( ! method_exists( $this, 'row_action_' . $action_key ) ) { + continue; + } + + $action_link = ! empty( $action['link'] ) ? $action['link'] : add_query_arg( array( 'row_action' => $action_key, 'row_id' => $row_id, 'nonce' => wp_create_nonce( $action_key . '::' . $row_id ) ) ); + $span_class = ! empty( $action['class'] ) ? $action['class'] : $action_key; + $separator = ( $action_count < count( $this->row_actions[ $column_name ] ) ) ? ' | ' : ''; + + $actions .= sprintf( '', esc_attr( $span_class ) ); + $actions .= sprintf( '%3$s', esc_url( $action_link ), esc_attr( $action['desc'] ), esc_html( $action['name'] ) ); + $actions .= sprintf( '%s', $separator ); + } + $actions .= '
    '; + return $actions; + } + + protected function process_row_actions() { + $parameters = array( 'row_action', 'row_id', 'nonce' ); + foreach ( $parameters as $parameter ) { + if ( empty( $_REQUEST[ $parameter ] ) ) { + return; + } + } + + $method = 'row_action_' . $_REQUEST['row_action']; + + if ( $_REQUEST['nonce'] === wp_create_nonce( $_REQUEST[ 'row_action' ] . '::' . $_REQUEST[ 'row_id' ] ) && method_exists( $this, $method ) ) { + $this->$method( $_REQUEST['row_id'] ); + } + + wp_redirect( remove_query_arg( + array( 'row_id', 'row_action', 'nonce' ), + wp_unslash( $_SERVER['REQUEST_URI'] ) + ) ); + exit; + } + + /** + * Default column formatting, it will escape everythig for security. + */ + public function column_default( $item, $column_name ) { + $column_html = esc_html( $item[ $column_name ] ); + $column_html .= $this->maybe_render_actions( $item, $column_name ); + return $column_html; + } + + /** + * Display the table heading and search query, if any + */ + protected function display_header() { + echo '

    ' . esc_attr( $this->table_header ) . '

    '; + if ( $this->get_request_search_query() ) { + /* translators: %s: search query */ + echo '' . esc_attr( sprintf( __( 'Search results for "%s"', 'woocommerce' ), $this->get_request_search_query() ) ) . ''; + } + echo '
    '; + } + + /** + * Display the table heading and search query, if any + */ + protected function display_admin_notices() { + foreach ( $this->admin_notices as $notice ) { + echo '
    '; + echo '

    ' . wp_kses_post( $notice['message'] ) . '

    '; + echo '
    '; + } + } + + /** + * Prints the available statuses so the user can click to filter. + */ + protected function display_filter_by_status() { + + $status_list_items = array(); + $request_status = $this->get_request_status(); + + // Helper to set 'all' filter when not set on status counts passed in + if ( ! isset( $this->status_counts['all'] ) ) { + $this->status_counts = array( 'all' => array_sum( $this->status_counts ) ) + $this->status_counts; + } + + foreach ( $this->status_counts as $status_name => $count ) { + + if ( 0 === $count ) { + continue; + } + + if ( $status_name === $request_status || ( empty( $request_status ) && 'all' === $status_name ) ) { + $status_list_item = '
  • %3$s (%4$d)
  • '; + } else { + $status_list_item = '
  • %3$s (%4$d)
  • '; + } + + $status_filter_url = ( 'all' === $status_name ) ? remove_query_arg( 'status' ) : add_query_arg( 'status', $status_name ); + $status_filter_url = remove_query_arg( array( 'paged', 's' ), $status_filter_url ); + $status_list_items[] = sprintf( $status_list_item, esc_attr( $status_name ), esc_url( $status_filter_url ), esc_html( ucfirst( $status_name ) ), absint( $count ) ); + } + + if ( $status_list_items ) { + echo '
      '; + echo implode( " | \n", $status_list_items ); + echo '
    '; + } + } + + /** + * Renders the table list, we override the original class to render the table inside a form + * and to render any needed HTML (like the search box). By doing so the callee of a function can simple + * forget about any extra HTML. + */ + protected function display_table() { + echo '
    '; + foreach ( $_GET as $key => $value ) { + if ( '_' === $key[0] || 'paged' === $key ) { + continue; + } + echo ''; + } + if ( ! empty( $this->search_by ) ) { + echo $this->search_box( $this->get_search_box_button_text(), 'plugin' ); // WPCS: XSS OK + } + parent::display(); + echo '
    '; + } + + /** + * Process any pending actions. + */ + public function process_actions() { + $this->process_bulk_action(); + $this->process_row_actions(); + + if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) { + // _wp_http_referer is used only on bulk actions, we remove it to keep the $_GET shorter + wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ); + exit; + } + } + + /** + * Render the list table page, including header, notices, status filters and table. + */ + public function display_page() { + $this->prepare_items(); + + echo '
    '; + $this->display_header(); + $this->display_admin_notices(); + $this->display_filter_by_status(); + $this->display_table(); + echo '
    '; + } + + /** + * Get the text to display in the search box on the list table. + */ + protected function get_search_box_placeholder() { + return esc_html__( 'Search', 'woocommerce' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php new file mode 100644 index 0000000..82ecbc6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php @@ -0,0 +1,240 @@ +created_time = microtime( true ); + + $this->store = $store ? $store : ActionScheduler_Store::instance(); + $this->monitor = $monitor ? $monitor : new ActionScheduler_FatalErrorMonitor( $this->store ); + $this->cleaner = $cleaner ? $cleaner : new ActionScheduler_QueueCleaner( $this->store ); + } + + /** + * Process an individual action. + * + * @param int $action_id The action ID to process. + * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron' + * Generally, this should be capitalised and not localised as it's a proper noun. + */ + public function process_action( $action_id, $context = '' ) { + try { + $valid_action = false; + do_action( 'action_scheduler_before_execute', $action_id, $context ); + + if ( ActionScheduler_Store::STATUS_PENDING !== $this->store->get_status( $action_id ) ) { + do_action( 'action_scheduler_execution_ignored', $action_id, $context ); + return; + } + + $valid_action = true; + do_action( 'action_scheduler_begin_execute', $action_id, $context ); + + $action = $this->store->fetch_action( $action_id ); + $this->store->log_execution( $action_id ); + $action->execute(); + do_action( 'action_scheduler_after_execute', $action_id, $action, $context ); + $this->store->mark_complete( $action_id ); + } catch ( Exception $e ) { + if ( $valid_action ) { + $this->store->mark_failure( $action_id ); + do_action( 'action_scheduler_failed_execution', $action_id, $e, $context ); + } else { + do_action( 'action_scheduler_failed_validation', $action_id, $e, $context ); + } + } + + if ( isset( $action ) && is_a( $action, 'ActionScheduler_Action' ) && $action->get_schedule()->is_recurring() ) { + $this->schedule_next_instance( $action, $action_id ); + } + } + + /** + * Schedule the next instance of the action if necessary. + * + * @param ActionScheduler_Action $action + * @param int $action_id + */ + protected function schedule_next_instance( ActionScheduler_Action $action, $action_id ) { + try { + ActionScheduler::factory()->repeat( $action ); + } catch ( Exception $e ) { + do_action( 'action_scheduler_failed_to_schedule_next_instance', $action_id, $e, $action ); + } + } + + /** + * Run the queue cleaner. + * + * @author Jeremy Pry + */ + protected function run_cleanup() { + $this->cleaner->clean( 10 * $this->get_time_limit() ); + } + + /** + * Get the number of concurrent batches a runner allows. + * + * @return int + */ + public function get_allowed_concurrent_batches() { + return apply_filters( 'action_scheduler_queue_runner_concurrent_batches', 1 ); + } + + /** + * Check if the number of allowed concurrent batches is met or exceeded. + * + * @return bool + */ + public function has_maximum_concurrent_batches() { + return $this->store->get_claim_count() >= $this->get_allowed_concurrent_batches(); + } + + /** + * Get the maximum number of seconds a batch can run for. + * + * @return int The number of seconds. + */ + protected function get_time_limit() { + + $time_limit = 30; + + // Apply deprecated filter from deprecated get_maximum_execution_time() method + if ( has_filter( 'action_scheduler_maximum_execution_time' ) ) { + _deprecated_function( 'action_scheduler_maximum_execution_time', '2.1.1', 'action_scheduler_queue_runner_time_limit' ); + $time_limit = apply_filters( 'action_scheduler_maximum_execution_time', $time_limit ); + } + + return absint( apply_filters( 'action_scheduler_queue_runner_time_limit', $time_limit ) ); + } + + /** + * Get the number of seconds the process has been running. + * + * @return int The number of seconds. + */ + protected function get_execution_time() { + $execution_time = microtime( true ) - $this->created_time; + + // Get the CPU time if the hosting environment uses it rather than wall-clock time to calculate a process's execution time. + if ( function_exists( 'getrusage' ) && apply_filters( 'action_scheduler_use_cpu_execution_time', defined( 'PANTHEON_ENVIRONMENT' ) ) ) { + $resource_usages = getrusage(); + + if ( isset( $resource_usages['ru_stime.tv_usec'], $resource_usages['ru_stime.tv_usec'] ) ) { + $execution_time = $resource_usages['ru_stime.tv_sec'] + ( $resource_usages['ru_stime.tv_usec'] / 1000000 ); + } + } + + return $execution_time; + } + + /** + * Check if the host's max execution time is (likely) to be exceeded if processing more actions. + * + * @param int $processed_actions The number of actions processed so far - used to determine the likelihood of exceeding the time limit if processing another action + * @return bool + */ + protected function time_likely_to_be_exceeded( $processed_actions ) { + + $execution_time = $this->get_execution_time(); + $max_execution_time = $this->get_time_limit(); + $time_per_action = $execution_time / $processed_actions; + $estimated_time = $execution_time + ( $time_per_action * 3 ); + $likely_to_be_exceeded = $estimated_time > $max_execution_time; + + return apply_filters( 'action_scheduler_maximum_execution_time_likely_to_be_exceeded', $likely_to_be_exceeded, $this, $processed_actions, $execution_time, $max_execution_time ); + } + + /** + * Get memory limit + * + * Based on WP_Background_Process::get_memory_limit() + * + * @return int + */ + protected function get_memory_limit() { + if ( function_exists( 'ini_get' ) ) { + $memory_limit = ini_get( 'memory_limit' ); + } else { + $memory_limit = '128M'; // Sensible default, and minimum required by WooCommerce + } + + if ( ! $memory_limit || -1 === $memory_limit || '-1' === $memory_limit ) { + // Unlimited, set to 32GB. + $memory_limit = '32G'; + } + + return ActionScheduler_Compatibility::convert_hr_to_bytes( $memory_limit ); + } + + /** + * Memory exceeded + * + * Ensures the batch process never exceeds 90% of the maximum WordPress memory. + * + * Based on WP_Background_Process::memory_exceeded() + * + * @return bool + */ + protected function memory_exceeded() { + + $memory_limit = $this->get_memory_limit() * 0.90; + $current_memory = memory_get_usage( true ); + $memory_exceeded = $current_memory >= $memory_limit; + + return apply_filters( 'action_scheduler_memory_exceeded', $memory_exceeded, $this ); + } + + /** + * See if the batch limits have been exceeded, which is when memory usage is almost at + * the maximum limit, or the time to process more actions will exceed the max time limit. + * + * Based on WC_Background_Process::batch_limits_exceeded() + * + * @param int $processed_actions The number of actions processed so far - used to determine the likelihood of exceeding the time limit if processing another action + * @return bool + */ + protected function batch_limits_exceeded( $processed_actions ) { + return $this->memory_exceeded() || $this->time_likely_to_be_exceeded( $processed_actions ); + } + + /** + * Process actions in the queue. + * + * @author Jeremy Pry + * @param string $context Optional identifer for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron' + * Generally, this should be capitalised and not localised as it's a proper noun. + * @return int The number of actions processed. + */ + abstract public function run( $context = '' ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php new file mode 100644 index 0000000..131d475 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php @@ -0,0 +1,102 @@ +start - and logic to calculate the next run date after + * that - @see $this->calculate_next(). The $first_date property also keeps a record of when the very + * first instance of this chain of schedules ran. + * + * @var DateTime + */ + private $first_date = NULL; + + /** + * Timestamp equivalent of @see $this->first_date + * + * @var int + */ + protected $first_timestamp = NULL; + + /** + * The recurrance between each time an action is run using this schedule. + * Used to calculate the start date & time. Can be a number of seconds, in the + * case of ActionScheduler_IntervalSchedule, or a cron expression, as in the + * case of ActionScheduler_CronSchedule. Or something else. + * + * @var mixed + */ + protected $recurrence; + + /** + * @param DateTime $date The date & time to run the action. + * @param mixed $recurrence The data used to determine the schedule's recurrance. + * @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance. + */ + public function __construct( DateTime $date, $recurrence, DateTime $first = null ) { + parent::__construct( $date ); + $this->first_date = empty( $first ) ? $date : $first; + $this->recurrence = $recurrence; + } + + /** + * @return bool + */ + public function is_recurring() { + return true; + } + + /** + * Get the date & time of the first schedule in this recurring series. + * + * @return DateTime|null + */ + public function get_first_date() { + return clone $this->first_date; + } + + /** + * @return string + */ + public function get_recurrence() { + return $this->recurrence; + } + + /** + * For PHP 5.2 compat, since DateTime objects can't be serialized + * @return array + */ + public function __sleep() { + $sleep_params = parent::__sleep(); + $this->first_timestamp = $this->first_date->getTimestamp(); + return array_merge( $sleep_params, array( + 'first_timestamp', + 'recurrence' + ) ); + } + + /** + * Unserialize recurring schedules serialized/stored prior to AS 3.0.0 + * + * Prior to Action Scheduler 3.0.0, schedules used different property names to refer + * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp + * was the same as ActionScheduler_SimpleSchedule::timestamp. This was addressed in + * Action Scheduler 3.0.0, where properties and property names were aligned for better + * inheritance. To maintain backward compatibility with scheduled serialized and stored + * prior to 3.0, we need to correctly map the old property names. + */ + public function __wakeup() { + parent::__wakeup(); + if ( $this->first_timestamp > 0 ) { + $this->first_date = as_get_datetime_object( $this->first_timestamp ); + } else { + $this->first_date = $this->get_date(); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php new file mode 100644 index 0000000..2631ef5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php @@ -0,0 +1,83 @@ +scheduled_date + * + * @var int + */ + protected $scheduled_timestamp = NULL; + + /** + * @param DateTime $date The date & time to run the action. + */ + public function __construct( DateTime $date ) { + $this->scheduled_date = $date; + } + + /** + * Check if a schedule should recur. + * + * @return bool + */ + abstract public function is_recurring(); + + /** + * Calculate when the next instance of this schedule would run based on a given date & time. + * + * @param DateTime $after + * @return DateTime + */ + abstract protected function calculate_next( DateTime $after ); + + /** + * Get the next date & time when this schedule should run after a given date & time. + * + * @param DateTime $after + * @return DateTime|null + */ + public function get_next( DateTime $after ) { + $after = clone $after; + if ( $after > $this->scheduled_date ) { + $after = $this->calculate_next( $after ); + return $after; + } + return clone $this->scheduled_date; + } + + /** + * Get the date & time the schedule is set to run. + * + * @return DateTime|null + */ + public function get_date() { + return $this->scheduled_date; + } + + /** + * For PHP 5.2 compat, since DateTime objects can't be serialized + * @return array + */ + public function __sleep() { + $this->scheduled_timestamp = $this->scheduled_date->getTimestamp(); + return array( + 'scheduled_timestamp', + ); + } + + public function __wakeup() { + $this->scheduled_date = as_get_datetime_object( $this->scheduled_timestamp ); + unset( $this->scheduled_timestamp ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php new file mode 100644 index 0000000..62699c7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php @@ -0,0 +1,135 @@ +tables as $table ) { + $wpdb->tables[] = $table; + $name = $this->get_full_table_name( $table ); + $wpdb->$table = $name; + } + + // create the tables + if ( $this->schema_update_required() || $force_update ) { + foreach ( $this->tables as $table ) { + $this->update_table( $table ); + } + $this->mark_schema_update_complete(); + } + } + + /** + * @param string $table The name of the table + * + * @return string The CREATE TABLE statement, suitable for passing to dbDelta + */ + abstract protected function get_table_definition( $table ); + + /** + * Determine if the database schema is out of date + * by comparing the integer found in $this->schema_version + * with the option set in the WordPress options table + * + * @return bool + */ + private function schema_update_required() { + $option_name = 'schema-' . static::class; + $version_found_in_db = get_option( $option_name, 0 ); + + // Check for schema option stored by the Action Scheduler Custom Tables plugin in case site has migrated from that plugin with an older schema + if ( 0 === $version_found_in_db ) { + + $plugin_option_name = 'schema-'; + + switch ( static::class ) { + case 'ActionScheduler_StoreSchema' : + $plugin_option_name .= 'Action_Scheduler\Custom_Tables\DB_Store_Table_Maker'; + break; + case 'ActionScheduler_LoggerSchema' : + $plugin_option_name .= 'Action_Scheduler\Custom_Tables\DB_Logger_Table_Maker'; + break; + } + + $version_found_in_db = get_option( $plugin_option_name, 0 ); + + delete_option( $plugin_option_name ); + } + + return version_compare( $version_found_in_db, $this->schema_version, '<' ); + } + + /** + * Update the option in WordPress to indicate that + * our schema is now up to date + * + * @return void + */ + private function mark_schema_update_complete() { + $option_name = 'schema-' . static::class; + + // work around race conditions and ensure that our option updates + $value_to_save = (string) $this->schema_version . '.0.' . time(); + + update_option( $option_name, $value_to_save ); + } + + /** + * Update the schema for the given table + * + * @param string $table The name of the table to update + * + * @return void + */ + private function update_table( $table ) { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + $definition = $this->get_table_definition( $table ); + if ( $definition ) { + $updated = dbDelta( $definition ); + foreach ( $updated as $updated_table => $update_description ) { + if ( strpos( $update_description, 'Created table' ) === 0 ) { + do_action( 'action_scheduler/created_table', $updated_table, $table ); + } + } + } + } + + /** + * @param string $table + * + * @return string The full name of the table, including the + * table prefix for the current blog + */ + protected function get_full_table_name( $table ) { + return $GLOBALS[ 'wpdb' ]->prefix . $table; + } +} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Lock.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Lock.php new file mode 100644 index 0000000..86e8528 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Lock.php @@ -0,0 +1,62 @@ +get_expiration( $lock_type ) >= time() ); + } + + /** + * Set a lock. + * + * @param string $lock_type A string to identify different lock types. + * @return bool + */ + abstract public function set( $lock_type ); + + /** + * If a lock is set, return the timestamp it was set to expiry. + * + * @param string $lock_type A string to identify different lock types. + * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. + */ + abstract public function get_expiration( $lock_type ); + + /** + * Get the amount of time to set for a given lock. 60 seconds by default. + * + * @param string $lock_type A string to identify different lock types. + * @return int + */ + protected function get_duration( $lock_type ) { + return apply_filters( 'action_scheduler_lock_duration', self::$lock_duration, $lock_type ); + } + + /** + * @return ActionScheduler_Lock + */ + public static function instance() { + if ( empty( self::$locker ) ) { + $class = apply_filters( 'action_scheduler_lock_class', 'ActionScheduler_OptionLock' ); + self::$locker = new $class(); + } + return self::$locker; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Logger.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Logger.php new file mode 100644 index 0000000..1d47201 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Logger.php @@ -0,0 +1,176 @@ +hook_stored_action(); + add_action( 'action_scheduler_canceled_action', array( $this, 'log_canceled_action' ), 10, 1 ); + add_action( 'action_scheduler_begin_execute', array( $this, 'log_started_action' ), 10, 2 ); + add_action( 'action_scheduler_after_execute', array( $this, 'log_completed_action' ), 10, 3 ); + add_action( 'action_scheduler_failed_execution', array( $this, 'log_failed_action' ), 10, 3 ); + add_action( 'action_scheduler_failed_action', array( $this, 'log_timed_out_action' ), 10, 2 ); + add_action( 'action_scheduler_unexpected_shutdown', array( $this, 'log_unexpected_shutdown' ), 10, 2 ); + add_action( 'action_scheduler_reset_action', array( $this, 'log_reset_action' ), 10, 1 ); + add_action( 'action_scheduler_execution_ignored', array( $this, 'log_ignored_action' ), 10, 2 ); + add_action( 'action_scheduler_failed_fetch_action', array( $this, 'log_failed_fetch_action' ), 10, 2 ); + add_action( 'action_scheduler_failed_to_schedule_next_instance', array( $this, 'log_failed_schedule_next_instance' ), 10, 2 ); + add_action( 'action_scheduler_bulk_cancel_actions', array( $this, 'bulk_log_cancel_actions' ), 10, 1 ); + } + + public function hook_stored_action() { + add_action( 'action_scheduler_stored_action', array( $this, 'log_stored_action' ) ); + } + + public function unhook_stored_action() { + remove_action( 'action_scheduler_stored_action', array( $this, 'log_stored_action' ) ); + } + + public function log_stored_action( $action_id ) { + $this->log( $action_id, __( 'action created', 'woocommerce' ) ); + } + + public function log_canceled_action( $action_id ) { + $this->log( $action_id, __( 'action canceled', 'woocommerce' ) ); + } + + public function log_started_action( $action_id, $context = '' ) { + if ( ! empty( $context ) ) { + /* translators: %s: context */ + $message = sprintf( __( 'action started via %s', 'woocommerce' ), $context ); + } else { + $message = __( 'action started', 'woocommerce' ); + } + $this->log( $action_id, $message ); + } + + public function log_completed_action( $action_id, $action = NULL, $context = '' ) { + if ( ! empty( $context ) ) { + /* translators: %s: context */ + $message = sprintf( __( 'action complete via %s', 'woocommerce' ), $context ); + } else { + $message = __( 'action complete', 'woocommerce' ); + } + $this->log( $action_id, $message ); + } + + public function log_failed_action( $action_id, Exception $exception, $context = '' ) { + if ( ! empty( $context ) ) { + /* translators: 1: context 2: exception message */ + $message = sprintf( __( 'action failed via %1$s: %2$s', 'woocommerce' ), $context, $exception->getMessage() ); + } else { + /* translators: %s: exception message */ + $message = sprintf( __( 'action failed: %s', 'woocommerce' ), $exception->getMessage() ); + } + $this->log( $action_id, $message ); + } + + public function log_timed_out_action( $action_id, $timeout ) { + /* translators: %s: amount of time */ + $this->log( $action_id, sprintf( __( 'action timed out after %s seconds', 'woocommerce' ), $timeout ) ); + } + + public function log_unexpected_shutdown( $action_id, $error ) { + if ( ! empty( $error ) ) { + /* translators: 1: error message 2: filename 3: line */ + $this->log( $action_id, sprintf( __( 'unexpected shutdown: PHP Fatal error %1$s in %2$s on line %3$s', 'woocommerce' ), $error['message'], $error['file'], $error['line'] ) ); + } + } + + public function log_reset_action( $action_id ) { + $this->log( $action_id, __( 'action reset', 'woocommerce' ) ); + } + + public function log_ignored_action( $action_id, $context = '' ) { + if ( ! empty( $context ) ) { + /* translators: %s: context */ + $message = sprintf( __( 'action ignored via %s', 'woocommerce' ), $context ); + } else { + $message = __( 'action ignored', 'woocommerce' ); + } + $this->log( $action_id, $message ); + } + + /** + * @param string $action_id + * @param Exception|NULL $exception The exception which occured when fetching the action. NULL by default for backward compatibility. + * + * @return ActionScheduler_LogEntry[] + */ + public function log_failed_fetch_action( $action_id, Exception $exception = NULL ) { + + if ( ! is_null( $exception ) ) { + /* translators: %s: exception message */ + $log_message = sprintf( __( 'There was a failure fetching this action: %s', 'woocommerce' ), $exception->getMessage() ); + } else { + $log_message = __( 'There was a failure fetching this action', 'woocommerce' ); + } + + $this->log( $action_id, $log_message ); + } + + public function log_failed_schedule_next_instance( $action_id, Exception $exception ) { + /* translators: %s: exception message */ + $this->log( $action_id, sprintf( __( 'There was a failure scheduling the next instance of this action: %s', 'woocommerce' ), $exception->getMessage() ) ); + } + + /** + * Bulk add cancel action log entries. + * + * Implemented here for backward compatibility. Should be implemented in parent loggers + * for more performant bulk logging. + * + * @param array $action_ids List of action ID. + */ + public function bulk_log_cancel_actions( $action_ids ) { + if ( empty( $action_ids ) ) { + return; + } + + foreach ( $action_ids as $action_id ) { + $this->log_canceled_action( $action_id ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Store.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Store.php new file mode 100644 index 0000000..f8304be --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Store.php @@ -0,0 +1,345 @@ +', '>=', '<', '<=', '=') ) ) { + return $comparison_operator; + } + return '='; + } + + /** + * Get the time MySQL formated date/time string for an action's (next) scheduled date. + * + * @param ActionScheduler_Action $action + * @param DateTime $scheduled_date (optional) + * @return string + */ + protected function get_scheduled_date_string( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) { + $next = null === $scheduled_date ? $action->get_schedule()->get_date() : $scheduled_date; + if ( ! $next ) { + return '0000-00-00 00:00:00'; + } + $next->setTimezone( new DateTimeZone( 'UTC' ) ); + + return $next->format( 'Y-m-d H:i:s' ); + } + + /** + * Get the time MySQL formated date/time string for an action's (next) scheduled date. + * + * @param ActionScheduler_Action $action + * @param DateTime $scheduled_date (optional) + * @return string + */ + protected function get_scheduled_date_string_local( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) { + $next = null === $scheduled_date ? $action->get_schedule()->get_date() : $scheduled_date; + if ( ! $next ) { + return '0000-00-00 00:00:00'; + } + + ActionScheduler_TimezoneHelper::set_local_timezone( $next ); + return $next->format( 'Y-m-d H:i:s' ); + } + + /** + * Validate that we could decode action arguments. + * + * @param mixed $args The decoded arguments. + * @param int $action_id The action ID. + * + * @throws ActionScheduler_InvalidActionException When the decoded arguments are invalid. + */ + protected function validate_args( $args, $action_id ) { + // Ensure we have an array of args. + if ( ! is_array( $args ) ) { + throw ActionScheduler_InvalidActionException::from_decoding_args( $action_id ); + } + + // Validate JSON decoding if possible. + if ( function_exists( 'json_last_error' ) && JSON_ERROR_NONE !== json_last_error() ) { + throw ActionScheduler_InvalidActionException::from_decoding_args( $action_id, $args ); + } + } + + /** + * Validate a ActionScheduler_Schedule object. + * + * @param mixed $schedule The unserialized ActionScheduler_Schedule object. + * @param int $action_id The action ID. + * + * @throws ActionScheduler_InvalidActionException When the schedule is invalid. + */ + protected function validate_schedule( $schedule, $action_id ) { + if ( empty( $schedule ) || ! is_a( $schedule, 'ActionScheduler_Schedule' ) ) { + throw ActionScheduler_InvalidActionException::from_schedule( $action_id, $schedule ); + } + } + + /** + * InnoDB indexes have a maximum size of 767 bytes by default, which is only 191 characters with utf8mb4. + * + * Previously, AS wasn't concerned about args length, as we used the (unindex) post_content column. However, + * with custom tables, we use an indexed VARCHAR column instead. + * + * @param ActionScheduler_Action $action Action to be validated. + * @throws InvalidArgumentException When json encoded args is too long. + */ + protected function validate_action( ActionScheduler_Action $action ) { + if ( strlen( json_encode( $action->get_args() ) ) > static::$max_args_length ) { + throw new InvalidArgumentException( sprintf( __( 'ActionScheduler_Action::$args too long. To ensure the args column can be indexed, action args should not be more than %d characters when encoded as JSON.', 'woocommerce' ), static::$max_args_length ) ); + } + } + + /** + * Cancel pending actions by hook. + * + * @since 3.0.0 + * + * @param string $hook Hook name. + * + * @return void + */ + public function cancel_actions_by_hook( $hook ) { + $action_ids = true; + while ( ! empty( $action_ids ) ) { + $action_ids = $this->query_actions( + array( + 'hook' => $hook, + 'status' => self::STATUS_PENDING, + 'per_page' => 1000, + ) + ); + + $this->bulk_cancel_actions( $action_ids ); + } + } + + /** + * Cancel pending actions by group. + * + * @since 3.0.0 + * + * @param string $group Group slug. + * + * @return void + */ + public function cancel_actions_by_group( $group ) { + $action_ids = true; + while ( ! empty( $action_ids ) ) { + $action_ids = $this->query_actions( + array( + 'group' => $group, + 'status' => self::STATUS_PENDING, + 'per_page' => 1000, + ) + ); + + $this->bulk_cancel_actions( $action_ids ); + } + } + + /** + * Cancel a set of action IDs. + * + * @since 3.0.0 + * + * @param array $action_ids List of action IDs. + * + * @return void + */ + private function bulk_cancel_actions( $action_ids ) { + foreach ( $action_ids as $action_id ) { + $this->cancel_action( $action_id ); + } + + do_action( 'action_scheduler_bulk_cancel_actions', $action_ids ); + } + + /** + * @return array + */ + public function get_status_labels() { + return array( + self::STATUS_COMPLETE => __( 'Complete', 'woocommerce' ), + self::STATUS_PENDING => __( 'Pending', 'woocommerce' ), + self::STATUS_RUNNING => __( 'In-progress', 'woocommerce' ), + self::STATUS_FAILED => __( 'Failed', 'woocommerce' ), + self::STATUS_CANCELED => __( 'Canceled', 'woocommerce' ), + ); + } + + /** + * Check if there are any pending scheduled actions due to run. + * + * @param ActionScheduler_Action $action + * @param DateTime $scheduled_date (optional) + * @return string + */ + public function has_pending_actions_due() { + $pending_actions = $this->query_actions( array( + 'date' => as_get_datetime_object(), + 'status' => ActionScheduler_Store::STATUS_PENDING, + ) ); + + return ! empty( $pending_actions ); + } + + /** + * Callable initialization function optionally overridden in derived classes. + */ + public function init() {} + + /** + * Callable function to mark an action as migrated optionally overridden in derived classes. + */ + public function mark_migrated( $action_id ) {} + + /** + * @return ActionScheduler_Store + */ + public static function instance() { + if ( empty( self::$store ) ) { + $class = apply_filters( 'action_scheduler_store_class', self::DEFAULT_CLASS ); + self::$store = new $class(); + } + return self::$store; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php new file mode 100644 index 0000000..fd01449 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php @@ -0,0 +1,152 @@ +format( 'U' ) ); + } + + if ( get_option( 'timezone_string' ) ) { + $date->setTimezone( new DateTimeZone( self::get_local_timezone_string() ) ); + } else { + $date->setUtcOffset( self::get_local_timezone_offset() ); + } + + return $date; + } + + /** + * Helper to retrieve the timezone string for a site until a WP core method exists + * (see https://core.trac.wordpress.org/ticket/24730). + * + * Adapted from wc_timezone_string() and https://secure.php.net/manual/en/function.timezone-name-from-abbr.php#89155. + * + * If no timezone string is set, and its not possible to match the UTC offset set for the site to a timezone + * string, then an empty string will be returned, and the UTC offset should be used to set a DateTime's + * timezone. + * + * @since 2.1.0 + * @return string PHP timezone string for the site or empty if no timezone string is available. + */ + protected static function get_local_timezone_string( $reset = false ) { + // If site timezone string exists, return it. + $timezone = get_option( 'timezone_string' ); + if ( $timezone ) { + return $timezone; + } + + // Get UTC offset, if it isn't set then return UTC. + $utc_offset = intval( get_option( 'gmt_offset', 0 ) ); + if ( 0 === $utc_offset ) { + return 'UTC'; + } + + // Adjust UTC offset from hours to seconds. + $utc_offset *= 3600; + + // Attempt to guess the timezone string from the UTC offset. + $timezone = timezone_name_from_abbr( '', $utc_offset ); + if ( $timezone ) { + return $timezone; + } + + // Last try, guess timezone string manually. + foreach ( timezone_abbreviations_list() as $abbr ) { + foreach ( $abbr as $city ) { + if ( (bool) date( 'I' ) === (bool) $city['dst'] && $city['timezone_id'] && intval( $city['offset'] ) === $utc_offset ) { + return $city['timezone_id']; + } + } + } + + // No timezone string + return ''; + } + + /** + * Get timezone offset in seconds. + * + * @since 2.1.0 + * @return float + */ + protected static function get_local_timezone_offset() { + $timezone = get_option( 'timezone_string' ); + + if ( $timezone ) { + $timezone_object = new DateTimeZone( $timezone ); + return $timezone_object->getOffset( new DateTime( 'now' ) ); + } else { + return floatval( get_option( 'gmt_offset', 0 ) ) * HOUR_IN_SECONDS; + } + } + + /** + * @deprecated 2.1.0 + */ + public static function get_local_timezone( $reset = FALSE ) { + _deprecated_function( __FUNCTION__, '2.1.0', 'ActionScheduler_TimezoneHelper::set_local_timezone()' ); + if ( $reset ) { + self::$local_timezone = NULL; + } + if ( !isset(self::$local_timezone) ) { + $tzstring = get_option('timezone_string'); + + if ( empty($tzstring) ) { + $gmt_offset = get_option('gmt_offset'); + if ( $gmt_offset == 0 ) { + $tzstring = 'UTC'; + } else { + $gmt_offset *= HOUR_IN_SECONDS; + $tzstring = timezone_name_from_abbr( '', $gmt_offset, 1 ); + + // If there's no timezone string, try again with no DST. + if ( false === $tzstring ) { + $tzstring = timezone_name_from_abbr( '', $gmt_offset, 0 ); + } + + // Try mapping to the first abbreviation we can find. + if ( false === $tzstring ) { + $is_dst = date( 'I' ); + foreach ( timezone_abbreviations_list() as $abbr ) { + foreach ( $abbr as $city ) { + if ( $city['dst'] == $is_dst && $city['offset'] == $gmt_offset ) { + // If there's no valid timezone ID, keep looking. + if ( null === $city['timezone_id'] ) { + continue; + } + + $tzstring = $city['timezone_id']; + break 2; + } + } + } + } + + // If we still have no valid string, then fall back to UTC. + if ( false === $tzstring ) { + $tzstring = 'UTC'; + } + } + } + + self::$local_timezone = new DateTimeZone($tzstring); + } + return self::$local_timezone; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_Action.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_Action.php new file mode 100644 index 0000000..6258ba1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_Action.php @@ -0,0 +1,75 @@ +set_hook($hook); + $this->set_schedule($schedule); + $this->set_args($args); + $this->set_group($group); + } + + public function execute() { + return do_action_ref_array($this->get_hook(), $this->get_args()); + } + + /** + * @param string $hook + */ + protected function set_hook( $hook ) { + $this->hook = $hook; + } + + public function get_hook() { + return $this->hook; + } + + protected function set_schedule( ActionScheduler_Schedule $schedule ) { + $this->schedule = $schedule; + } + + /** + * @return ActionScheduler_Schedule + */ + public function get_schedule() { + return $this->schedule; + } + + protected function set_args( array $args ) { + $this->args = $args; + } + + public function get_args() { + return $this->args; + } + + /** + * @param string $group + */ + protected function set_group( $group ) { + $this->group = $group; + } + + /** + * @return string + */ + public function get_group() { + return $this->group; + } + + /** + * @return bool If the action has been finished + */ + public function is_finished() { + return FALSE; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php new file mode 100644 index 0000000..8bbc5d1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_CanceledAction.php @@ -0,0 +1,23 @@ +set_schedule( new ActionScheduler_NullSchedule() ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php new file mode 100644 index 0000000..b23a56c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_FinishedAction.php @@ -0,0 +1,16 @@ +set_schedule( new ActionScheduler_NullSchedule() ); + } + + public function execute() { + // don't execute + } +} + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php new file mode 100644 index 0000000..943ef09 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php @@ -0,0 +1,146 @@ +format( 'Y-m-d H:i:s' ); + ActionScheduler_TimezoneHelper::set_local_timezone( $date ); + $date_local = $date->format( 'Y-m-d H:i:s' ); + + /** @var \wpdb $wpdb */ + global $wpdb; + $wpdb->insert( $wpdb->actionscheduler_logs, [ + 'action_id' => $action_id, + 'message' => $message, + 'log_date_gmt' => $date_gmt, + 'log_date_local' => $date_local, + ], [ '%d', '%s', '%s', '%s' ] ); + + return $wpdb->insert_id; + } + + /** + * Retrieve an action log entry. + * + * @param int $entry_id Log entry ID. + * + * @return ActionScheduler_LogEntry + */ + public function get_entry( $entry_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $entry = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE log_id=%d", $entry_id ) ); + + return $this->create_entry_from_db_record( $entry ); + } + + /** + * Create an action log entry from a database record. + * + * @param object $record Log entry database record object. + * + * @return ActionScheduler_LogEntry + */ + private function create_entry_from_db_record( $record ) { + if ( empty( $record ) ) { + return new ActionScheduler_NullLogEntry(); + } + + $date = as_get_datetime_object( $record->log_date_gmt ); + + return new ActionScheduler_LogEntry( $record->action_id, $record->message, $date ); + } + + /** + * Retrieve the an action's log entries from the database. + * + * @param int $action_id Action ID. + * + * @return ActionScheduler_LogEntry[] + */ + public function get_logs( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + + $records = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE action_id=%d", $action_id ) ); + + return array_map( [ $this, 'create_entry_from_db_record' ], $records ); + } + + /** + * Initialize the data store. + * + * @codeCoverageIgnore + */ + public function init() { + + $table_maker = new ActionScheduler_LoggerSchema(); + $table_maker->register_tables(); + + parent::init(); + + add_action( 'action_scheduler_deleted_action', [ $this, 'clear_deleted_action_logs' ], 10, 1 ); + } + + /** + * Delete the action logs for an action. + * + * @param int $action_id Action ID. + */ + public function clear_deleted_action_logs( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $wpdb->delete( $wpdb->actionscheduler_logs, [ 'action_id' => $action_id, ], [ '%d' ] ); + } + + /** + * Bulk add cancel action log entries. + * + * @param array $action_ids List of action ID. + */ + public function bulk_log_cancel_actions( $action_ids ) { + if ( empty( $action_ids ) ) { + return; + } + + /** @var \wpdb $wpdb */ + global $wpdb; + $date = as_get_datetime_object(); + $date_gmt = $date->format( 'Y-m-d H:i:s' ); + ActionScheduler_TimezoneHelper::set_local_timezone( $date ); + $date_local = $date->format( 'Y-m-d H:i:s' ); + $message = __( 'action canceled', 'woocommerce' ); + $format = '(%d, ' . $wpdb->prepare( '%s, %s, %s', $message, $date_gmt, $date_local ) . ')'; + $sql_query = "INSERT {$wpdb->actionscheduler_logs} (action_id, message, log_date_gmt, log_date_local) VALUES "; + $value_rows = []; + + foreach ( $action_ids as $action_id ) { + $value_rows[] = $wpdb->prepare( $format, $action_id ); + } + $sql_query .= implode( ',', $value_rows ); + + $wpdb->query( $sql_query ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php new file mode 100644 index 0000000..c373d5d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php @@ -0,0 +1,845 @@ +register_tables(); + } + + /** + * Save an action. + * + * @param ActionScheduler_Action $action Action object. + * @param DateTime $date Optional schedule date. Default null. + * + * @return int Action ID. + */ + public function save_action( ActionScheduler_Action $action, \DateTime $date = null ) { + try { + + $this->validate_action( $action ); + + /** @var \wpdb $wpdb */ + global $wpdb; + $data = [ + 'hook' => $action->get_hook(), + 'status' => ( $action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING ), + 'scheduled_date_gmt' => $this->get_scheduled_date_string( $action, $date ), + 'scheduled_date_local' => $this->get_scheduled_date_string_local( $action, $date ), + 'schedule' => serialize( $action->get_schedule() ), + 'group_id' => $this->get_group_id( $action->get_group() ), + ]; + $args = wp_json_encode( $action->get_args() ); + if ( strlen( $args ) <= static::$max_index_length ) { + $data['args'] = $args; + } else { + $data['args'] = $this->hash_args( $args ); + $data['extended_args'] = $args; + } + + $table_name = ! empty( $wpdb->actionscheduler_actions ) ? $wpdb->actionscheduler_actions : $wpdb->prefix . 'actionscheduler_actions'; + $wpdb->insert( $table_name, $data ); + $action_id = $wpdb->insert_id; + + if ( is_wp_error( $action_id ) ) { + throw new RuntimeException( $action_id->get_error_message() ); + } + elseif ( empty( $action_id ) ) { + throw new RuntimeException( $wpdb->last_error ? $wpdb->last_error : __( 'Database error.', 'woocommerce' ) ); + } + + do_action( 'action_scheduler_stored_action', $action_id ); + + return $action_id; + } catch ( \Exception $e ) { + /* translators: %s: error message */ + throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'woocommerce' ), $e->getMessage() ), 0 ); + } + } + + /** + * Generate a hash from json_encoded $args using MD5 as this isn't for security. + * + * @param string $args JSON encoded action args. + * @return string + */ + protected function hash_args( $args ) { + return md5( $args ); + } + + /** + * Get action args query param value from action args. + * + * @param array $args Action args. + * @return string + */ + protected function get_args_for_query( $args ) { + $encoded = wp_json_encode( $args ); + if ( strlen( $encoded ) <= static::$max_index_length ) { + return $encoded; + } + return $this->hash_args( $encoded ); + } + /** + * Get a group's ID based on its name/slug. + * + * @param string $slug The string name of a group. + * @param bool $create_if_not_exists Whether to create the group if it does not already exist. Default, true - create the group. + * + * @return int The group's ID, if it exists or is created, or 0 if it does not exist and is not created. + */ + protected function get_group_id( $slug, $create_if_not_exists = true ) { + if ( empty( $slug ) ) { + return 0; + } + /** @var \wpdb $wpdb */ + global $wpdb; + $group_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT group_id FROM {$wpdb->actionscheduler_groups} WHERE slug=%s", $slug ) ); + if ( empty( $group_id ) && $create_if_not_exists ) { + $group_id = $this->create_group( $slug ); + } + + return $group_id; + } + + /** + * Create an action group. + * + * @param string $slug Group slug. + * + * @return int Group ID. + */ + protected function create_group( $slug ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $wpdb->insert( $wpdb->actionscheduler_groups, [ 'slug' => $slug ] ); + + return (int) $wpdb->insert_id; + } + + /** + * Retrieve an action. + * + * @param int $action_id Action ID. + * + * @return ActionScheduler_Action + */ + public function fetch_action( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $data = $wpdb->get_row( $wpdb->prepare( + "SELECT a.*, g.slug AS `group` FROM {$wpdb->actionscheduler_actions} a LEFT JOIN {$wpdb->actionscheduler_groups} g ON a.group_id=g.group_id WHERE a.action_id=%d", + $action_id + ) ); + + if ( empty( $data ) ) { + return $this->get_null_action(); + } + + if ( ! empty( $data->extended_args ) ) { + $data->args = $data->extended_args; + unset( $data->extended_args ); + } + + try { + $action = $this->make_action_from_db_record( $data ); + } catch ( ActionScheduler_InvalidActionException $exception ) { + do_action( 'action_scheduler_failed_fetch_action', $action_id, $exception ); + return $this->get_null_action(); + } + + return $action; + } + + /** + * Create a null action. + * + * @return ActionScheduler_NullAction + */ + protected function get_null_action() { + return new ActionScheduler_NullAction(); + } + + /** + * Create an action from a database record. + * + * @param object $data Action database record. + * + * @return ActionScheduler_Action|ActionScheduler_CanceledAction|ActionScheduler_FinishedAction + */ + protected function make_action_from_db_record( $data ) { + + $hook = $data->hook; + $args = json_decode( $data->args, true ); + $schedule = unserialize( $data->schedule ); + + $this->validate_args( $args, $data->action_id ); + $this->validate_schedule( $schedule, $data->action_id ); + + if ( empty( $schedule ) ) { + $schedule = new ActionScheduler_NullSchedule(); + } + $group = $data->group ? $data->group : ''; + + return ActionScheduler::factory()->get_stored_action( $data->status, $data->hook, $args, $schedule, $group ); + } + + /** + * Find an action. + * + * @param string $hook Action hook. + * @param array $params Parameters of the action to find. + * + * @return string|null ID of the next action matching the criteria or NULL if not found. + */ + public function find_action( $hook, $params = [] ) { + $params = wp_parse_args( $params, [ + 'args' => null, + 'status' => self::STATUS_PENDING, + 'group' => '', + ] ); + + /** @var wpdb $wpdb */ + global $wpdb; + $query = "SELECT a.action_id FROM {$wpdb->actionscheduler_actions} a"; + $args = []; + if ( ! empty( $params[ 'group' ] ) ) { + $query .= " INNER JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id AND g.slug=%s"; + $args[] = $params[ 'group' ]; + } + $query .= " WHERE a.hook=%s"; + $args[] = $hook; + if ( ! is_null( $params[ 'args' ] ) ) { + $query .= " AND a.args=%s"; + $args[] = $this->get_args_for_query( $params[ 'args' ] ); + } + + $order = 'ASC'; + if ( ! empty( $params[ 'status' ] ) ) { + $query .= " AND a.status=%s"; + $args[] = $params[ 'status' ]; + + if ( self::STATUS_PENDING == $params[ 'status' ] ) { + $order = 'ASC'; // Find the next action that matches. + } else { + $order = 'DESC'; // Find the most recent action that matches. + } + } + + $query .= " ORDER BY scheduled_date_gmt $order LIMIT 1"; + + $query = $wpdb->prepare( $query, $args ); + + $id = $wpdb->get_var( $query ); + + return $id; + } + + /** + * Returns the SQL statement to query (or count) actions. + * + * @param array $query Filtering options. + * @param string $select_or_count Whether the SQL should select and return the IDs or just the row count. + * + * @return string SQL statement already properly escaped. + */ + protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) { + + if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) { + throw new InvalidArgumentException( __( 'Invalid value for select or count parameter. Cannot query actions.', 'woocommerce' ) ); + } + + $query = wp_parse_args( $query, [ + 'hook' => '', + 'args' => null, + 'date' => null, + 'date_compare' => '<=', + 'modified' => null, + 'modified_compare' => '<=', + 'group' => '', + 'status' => '', + 'claimed' => null, + 'per_page' => 5, + 'offset' => 0, + 'orderby' => 'date', + 'order' => 'ASC', + ] ); + + /** @var \wpdb $wpdb */ + global $wpdb; + $sql = ( 'count' === $select_or_count ) ? 'SELECT count(a.action_id)' : 'SELECT a.action_id'; + $sql .= " FROM {$wpdb->actionscheduler_actions} a"; + $sql_params = []; + + if ( ! empty( $query[ 'group' ] ) || 'group' === $query[ 'orderby' ] ) { + $sql .= " LEFT JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id"; + } + + $sql .= " WHERE 1=1"; + + if ( ! empty( $query[ 'group' ] ) ) { + $sql .= " AND g.slug=%s"; + $sql_params[] = $query[ 'group' ]; + } + + if ( $query[ 'hook' ] ) { + $sql .= " AND a.hook=%s"; + $sql_params[] = $query[ 'hook' ]; + } + if ( ! is_null( $query[ 'args' ] ) ) { + $sql .= " AND a.args=%s"; + $sql_params[] = $this->get_args_for_query( $query[ 'args' ] ); + } + + if ( $query[ 'status' ] ) { + $sql .= " AND a.status=%s"; + $sql_params[] = $query[ 'status' ]; + } + + if ( $query[ 'date' ] instanceof \DateTime ) { + $date = clone $query[ 'date' ]; + $date->setTimezone( new \DateTimeZone( 'UTC' ) ); + $date_string = $date->format( 'Y-m-d H:i:s' ); + $comparator = $this->validate_sql_comparator( $query[ 'date_compare' ] ); + $sql .= " AND a.scheduled_date_gmt $comparator %s"; + $sql_params[] = $date_string; + } + + if ( $query[ 'modified' ] instanceof \DateTime ) { + $modified = clone $query[ 'modified' ]; + $modified->setTimezone( new \DateTimeZone( 'UTC' ) ); + $date_string = $modified->format( 'Y-m-d H:i:s' ); + $comparator = $this->validate_sql_comparator( $query[ 'modified_compare' ] ); + $sql .= " AND a.last_attempt_gmt $comparator %s"; + $sql_params[] = $date_string; + } + + if ( $query[ 'claimed' ] === true ) { + $sql .= " AND a.claim_id != 0"; + } elseif ( $query[ 'claimed' ] === false ) { + $sql .= " AND a.claim_id = 0"; + } elseif ( ! is_null( $query[ 'claimed' ] ) ) { + $sql .= " AND a.claim_id = %d"; + $sql_params[] = $query[ 'claimed' ]; + } + + if ( ! empty( $query['search'] ) ) { + $sql .= " AND (a.hook LIKE %s OR (a.extended_args IS NULL AND a.args LIKE %s) OR a.extended_args LIKE %s"; + for( $i = 0; $i < 3; $i++ ) { + $sql_params[] = sprintf( '%%%s%%', $query['search'] ); + } + + $search_claim_id = (int) $query['search']; + if ( $search_claim_id ) { + $sql .= ' OR a.claim_id = %d'; + $sql_params[] = $search_claim_id; + } + + $sql .= ')'; + } + + if ( 'select' === $select_or_count ) { + switch ( $query['orderby'] ) { + case 'hook': + $orderby = 'a.hook'; + break; + case 'group': + $orderby = 'g.slug'; + break; + case 'modified': + $orderby = 'a.last_attempt_gmt'; + break; + case 'date': + default: + $orderby = 'a.scheduled_date_gmt'; + break; + } + if ( strtoupper( $query[ 'order' ] ) == 'ASC' ) { + $order = 'ASC'; + } else { + $order = 'DESC'; + } + $sql .= " ORDER BY $orderby $order"; + if ( $query[ 'per_page' ] > 0 ) { + $sql .= " LIMIT %d, %d"; + $sql_params[] = $query[ 'offset' ]; + $sql_params[] = $query[ 'per_page' ]; + } + } + + if ( ! empty( $sql_params ) ) { + $sql = $wpdb->prepare( $sql, $sql_params ); + } + + return $sql; + } + + /** + * Query for action count of list of action IDs. + * + * @param array $query Query parameters. + * @param string $query_type Whether to select or count the results. Default, select. + * + * @return null|string|array The IDs of actions matching the query + */ + public function query_actions( $query = [], $query_type = 'select' ) { + /** @var wpdb $wpdb */ + global $wpdb; + + $sql = $this->get_query_actions_sql( $query, $query_type ); + + return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql ); + } + + /** + * Get a count of all actions in the store, grouped by status. + * + * @return array Set of 'status' => int $count pairs for statuses with 1 or more actions of that status. + */ + public function action_counts() { + global $wpdb; + + $sql = "SELECT a.status, count(a.status) as 'count'"; + $sql .= " FROM {$wpdb->actionscheduler_actions} a"; + $sql .= " GROUP BY a.status"; + + $actions_count_by_status = array(); + $action_stati_and_labels = $this->get_status_labels(); + + foreach ( $wpdb->get_results( $sql ) as $action_data ) { + // Ignore any actions with invalid status + if ( array_key_exists( $action_data->status, $action_stati_and_labels ) ) { + $actions_count_by_status[ $action_data->status ] = $action_data->count; + } + } + + return $actions_count_by_status; + } + + /** + * Cancel an action. + * + * @param int $action_id Action ID. + * + * @return void + */ + public function cancel_action( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + + $updated = $wpdb->update( + $wpdb->actionscheduler_actions, + [ 'status' => self::STATUS_CANCELED ], + [ 'action_id' => $action_id ], + [ '%s' ], + [ '%d' ] + ); + if ( empty( $updated ) ) { + /* translators: %s: action ID */ + throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'woocommerce' ), $action_id ) ); + } + do_action( 'action_scheduler_canceled_action', $action_id ); + } + + /** + * Cancel pending actions by hook. + * + * @since 3.0.0 + * + * @param string $hook Hook name. + * + * @return void + */ + public function cancel_actions_by_hook( $hook ) { + $this->bulk_cancel_actions( [ 'hook' => $hook ] ); + } + + /** + * Cancel pending actions by group. + * + * @param string $group Group slug. + * + * @return void + */ + public function cancel_actions_by_group( $group ) { + $this->bulk_cancel_actions( [ 'group' => $group ] ); + } + + /** + * Bulk cancel actions. + * + * @since 3.0.0 + * + * @param array $query_args Query parameters. + */ + protected function bulk_cancel_actions( $query_args ) { + /** @var \wpdb $wpdb */ + global $wpdb; + + if ( ! is_array( $query_args ) ) { + return; + } + + // Don't cancel actions that are already canceled. + if ( isset( $query_args['status'] ) && $query_args['status'] == self::STATUS_CANCELED ) { + return; + } + + $action_ids = true; + $query_args = wp_parse_args( + $query_args, + [ + 'per_page' => 1000, + 'status' => self::STATUS_PENDING, + ] + ); + + while ( $action_ids ) { + $action_ids = $this->query_actions( $query_args ); + if ( empty( $action_ids ) ) { + break; + } + + $format = array_fill( 0, count( $action_ids ), '%d' ); + $query_in = '(' . implode( ',', $format ) . ')'; + $parameters = $action_ids; + array_unshift( $parameters, self::STATUS_CANCELED ); + + $wpdb->query( + $wpdb->prepare( // wpcs: PreparedSQLPlaceholders replacement count ok. + "UPDATE {$wpdb->actionscheduler_actions} SET status = %s WHERE action_id IN {$query_in}", + $parameters + ) + ); + + do_action( 'action_scheduler_bulk_cancel_actions', $action_ids ); + } + } + + /** + * Delete an action. + * + * @param int $action_id Action ID. + */ + public function delete_action( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $deleted = $wpdb->delete( $wpdb->actionscheduler_actions, [ 'action_id' => $action_id ], [ '%d' ] ); + if ( empty( $deleted ) ) { + throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'woocommerce' ), $action_id ) ); + } + do_action( 'action_scheduler_deleted_action', $action_id ); + } + + /** + * Get the schedule date for an action. + * + * @param string $action_id Action ID. + * + * @throws \InvalidArgumentException + * @return \DateTime The local date the action is scheduled to run, or the date that it ran. + */ + public function get_date( $action_id ) { + $date = $this->get_date_gmt( $action_id ); + ActionScheduler_TimezoneHelper::set_local_timezone( $date ); + return $date; + } + + /** + * Get the GMT schedule date for an action. + * + * @param int $action_id Action ID. + * + * @throws \InvalidArgumentException + * @return \DateTime The GMT date the action is scheduled to run, or the date that it ran. + */ + protected function get_date_gmt( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $record = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d", $action_id ) ); + if ( empty( $record ) ) { + throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'woocommerce' ), $action_id ) ); + } + if ( $record->status == self::STATUS_PENDING ) { + return as_get_datetime_object( $record->scheduled_date_gmt ); + } else { + return as_get_datetime_object( $record->last_attempt_gmt ); + } + } + + /** + * Stake a claim on actions. + * + * @param int $max_actions Maximum number of action to include in claim. + * @param \DateTime $before_date Jobs must be schedule before this date. Defaults to now. + * + * @return ActionScheduler_ActionClaim + */ + public function stake_claim( $max_actions = 10, \DateTime $before_date = null, $hooks = array(), $group = '' ) { + $claim_id = $this->generate_claim_id(); + $this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group ); + $action_ids = $this->find_actions_by_claim_id( $claim_id ); + + return new ActionScheduler_ActionClaim( $claim_id, $action_ids ); + } + + /** + * Generate a new action claim. + * + * @return int Claim ID. + */ + protected function generate_claim_id() { + /** @var \wpdb $wpdb */ + global $wpdb; + $now = as_get_datetime_object(); + $wpdb->insert( $wpdb->actionscheduler_claims, [ 'date_created_gmt' => $now->format( 'Y-m-d H:i:s' ) ] ); + + return $wpdb->insert_id; + } + + /** + * Mark actions claimed. + * + * @param string $claim_id Claim Id. + * @param int $limit Number of action to include in claim. + * @param \DateTime $before_date Should use UTC timezone. + * + * @return int The number of actions that were claimed. + * @throws \RuntimeException + */ + protected function claim_actions( $claim_id, $limit, \DateTime $before_date = null, $hooks = array(), $group = '' ) { + /** @var \wpdb $wpdb */ + global $wpdb; + + $now = as_get_datetime_object(); + $date = is_null( $before_date ) ? $now : clone $before_date; + + // can't use $wpdb->update() because of the <= condition + $update = "UPDATE {$wpdb->actionscheduler_actions} SET claim_id=%d, last_attempt_gmt=%s, last_attempt_local=%s"; + $params = array( + $claim_id, + $now->format( 'Y-m-d H:i:s' ), + current_time( 'mysql' ), + ); + + $where = "WHERE claim_id = 0 AND scheduled_date_gmt <= %s AND status=%s"; + $params[] = $date->format( 'Y-m-d H:i:s' ); + $params[] = self::STATUS_PENDING; + + if ( ! empty( $hooks ) ) { + $placeholders = array_fill( 0, count( $hooks ), '%s' ); + $where .= ' AND hook IN (' . join( ', ', $placeholders ) . ')'; + $params = array_merge( $params, array_values( $hooks ) ); + } + + if ( ! empty( $group ) ) { + + $group_id = $this->get_group_id( $group, false ); + + // throw exception if no matching group found, this matches ActionScheduler_wpPostStore's behaviour + if ( empty( $group_id ) ) { + /* translators: %s: group name */ + throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'woocommerce' ), $group ) ); + } + + $where .= ' AND group_id = %d'; + $params[] = $group_id; + } + + $order = "ORDER BY attempts ASC, scheduled_date_gmt ASC, action_id ASC LIMIT %d"; + $params[] = $limit; + + $sql = $wpdb->prepare( "{$update} {$where} {$order}", $params ); + + $rows_affected = $wpdb->query( $sql ); + if ( $rows_affected === false ) { + throw new \RuntimeException( __( 'Unable to claim actions. Database error.', 'woocommerce' ) ); + } + + return (int) $rows_affected; + } + + /** + * Get the number of active claims. + * + * @return int + */ + public function get_claim_count() { + global $wpdb; + + $sql = "SELECT COUNT(DISTINCT claim_id) FROM {$wpdb->actionscheduler_actions} WHERE claim_id != 0 AND status IN ( %s, %s)"; + $sql = $wpdb->prepare( $sql, [ self::STATUS_PENDING, self::STATUS_RUNNING ] ); + + return (int) $wpdb->get_var( $sql ); + } + + /** + * Return an action's claim ID, as stored in the claim_id column. + * + * @param string $action_id Action ID. + * @return mixed + */ + public function get_claim_id( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + + $sql = "SELECT claim_id FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d"; + $sql = $wpdb->prepare( $sql, $action_id ); + + return (int) $wpdb->get_var( $sql ); + } + + /** + * Retrieve the action IDs of action in a claim. + * + * @param string $claim_id Claim ID. + * + * @return int[] + */ + public function find_actions_by_claim_id( $claim_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + + $sql = "SELECT action_id FROM {$wpdb->actionscheduler_actions} WHERE claim_id=%d"; + $sql = $wpdb->prepare( $sql, $claim_id ); + + $action_ids = $wpdb->get_col( $sql ); + + return array_map( 'intval', $action_ids ); + } + + /** + * Release actions from a claim and delete the claim. + * + * @param ActionScheduler_ActionClaim $claim Claim object. + */ + public function release_claim( ActionScheduler_ActionClaim $claim ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $wpdb->update( $wpdb->actionscheduler_actions, [ 'claim_id' => 0 ], [ 'claim_id' => $claim->get_id() ], [ '%d' ], [ '%d' ] ); + $wpdb->delete( $wpdb->actionscheduler_claims, [ 'claim_id' => $claim->get_id() ], [ '%d' ] ); + } + + /** + * Remove the claim from an action. + * + * @param int $action_id Action ID. + * + * @return void + */ + public function unclaim_action( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $wpdb->update( + $wpdb->actionscheduler_actions, + [ 'claim_id' => 0 ], + [ 'action_id' => $action_id ], + [ '%s' ], + [ '%d' ] + ); + } + + /** + * Mark an action as failed. + * + * @param int $action_id Action ID. + */ + public function mark_failure( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $updated = $wpdb->update( + $wpdb->actionscheduler_actions, + [ 'status' => self::STATUS_FAILED ], + [ 'action_id' => $action_id ], + [ '%s' ], + [ '%d' ] + ); + if ( empty( $updated ) ) { + throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'woocommerce' ), $action_id ) ); + } + } + + /** + * Add execution message to action log. + * + * @param int $action_id Action ID. + * + * @return void + */ + public function log_execution( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + + $sql = "UPDATE {$wpdb->actionscheduler_actions} SET attempts = attempts+1, status=%s, last_attempt_gmt = %s, last_attempt_local = %s WHERE action_id = %d"; + $sql = $wpdb->prepare( $sql, self::STATUS_RUNNING, current_time( 'mysql', true ), current_time( 'mysql' ), $action_id ); + $wpdb->query( $sql ); + } + + /** + * Mark an action as complete. + * + * @param int $action_id Action ID. + * + * @return void + */ + public function mark_complete( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $updated = $wpdb->update( + $wpdb->actionscheduler_actions, + [ + 'status' => self::STATUS_COMPLETE, + 'last_attempt_gmt' => current_time( 'mysql', true ), + 'last_attempt_local' => current_time( 'mysql' ), + ], + [ 'action_id' => $action_id ], + [ '%s' ], + [ '%d' ] + ); + if ( empty( $updated ) ) { + throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'woocommerce' ), $action_id ) ); + } + } + + /** + * Get an action's status. + * + * @param int $action_id Action ID. + * + * @return string + */ + public function get_status( $action_id ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $sql = "SELECT status FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d"; + $sql = $wpdb->prepare( $sql, $action_id ); + $status = $wpdb->get_var( $sql ); + + if ( $status === null ) { + throw new \InvalidArgumentException( __( 'Invalid action ID. No status found.', 'woocommerce' ) ); + } elseif ( empty( $status ) ) { + throw new \RuntimeException( __( 'Unknown status found for action.', 'woocommerce' ) ); + } else { + return $status; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php new file mode 100644 index 0000000..22d61a6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php @@ -0,0 +1,426 @@ +demarkation_id = (int) get_option( self::DEMARKATION_OPTION, 0 ); + if ( empty( $config ) ) { + $config = Controller::instance()->get_migration_config_object(); + } + $this->primary_store = $config->get_destination_store(); + $this->secondary_store = $config->get_source_store(); + $this->migration_runner = new Runner( $config ); + } + + /** + * Initialize the table data store tables. + * + * @codeCoverageIgnore + */ + public function init() { + add_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10, 2 ); + $this->primary_store->init(); + $this->secondary_store->init(); + remove_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10 ); + } + + /** + * When the actions table is created, set its autoincrement + * value to be one higher than the posts table to ensure that + * there are no ID collisions. + * + * @param string $table_name + * @param string $table_suffix + * + * @return void + * @codeCoverageIgnore + */ + public function set_autoincrement( $table_name, $table_suffix ) { + if ( ActionScheduler_StoreSchema::ACTIONS_TABLE === $table_suffix ) { + if ( empty( $this->demarkation_id ) ) { + $this->demarkation_id = $this->set_demarkation_id(); + } + /** @var \wpdb $wpdb */ + global $wpdb; + /** + * A default date of '0000-00-00 00:00:00' is invalid in MySQL 5.7 when configured with + * sql_mode including both STRICT_TRANS_TABLES and NO_ZERO_DATE. + */ + $default_date = new DateTime( 'tomorrow' ); + $null_action = new ActionScheduler_NullAction(); + $date_gmt = $this->get_scheduled_date_string( $null_action, $default_date ); + $date_local = $this->get_scheduled_date_string_local( $null_action, $default_date ); + + $row_count = $wpdb->insert( + $wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE}, + [ + 'action_id' => $this->demarkation_id, + 'hook' => '', + 'status' => '', + 'scheduled_date_gmt' => $date_gmt, + 'scheduled_date_local' => $date_local, + 'last_attempt_gmt' => $date_gmt, + 'last_attempt_local' => $date_local, + ] + ); + if ( $row_count > 0 ) { + $wpdb->delete( + $wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE}, + [ 'action_id' => $this->demarkation_id ] + ); + } + } + } + + /** + * Store the demarkation id in WP options. + * + * @param int $id The ID to set as the demarkation point between the two stores + * Leave null to use the next ID from the WP posts table. + * + * @return int The new ID. + * + * @codeCoverageIgnore + */ + private function set_demarkation_id( $id = null ) { + if ( empty( $id ) ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $id = (int) $wpdb->get_var( "SELECT MAX(ID) FROM $wpdb->posts" ); + $id ++; + } + update_option( self::DEMARKATION_OPTION, $id ); + + return $id; + } + + /** + * Find the first matching action from the secondary store. + * If it exists, migrate it to the primary store immediately. + * After it migrates, the secondary store will logically contain + * the next matching action, so return the result thence. + * + * @param string $hook + * @param array $params + * + * @return string + */ + public function find_action( $hook, $params = [] ) { + $found_unmigrated_action = $this->secondary_store->find_action( $hook, $params ); + if ( ! empty( $found_unmigrated_action ) ) { + $this->migrate( [ $found_unmigrated_action ] ); + } + + return $this->primary_store->find_action( $hook, $params ); + } + + /** + * Find actions matching the query in the secondary source first. + * If any are found, migrate them immediately. Then the secondary + * store will contain the canonical results. + * + * @param array $query + * @param string $query_type Whether to select or count the results. Default, select. + * + * @return int[] + */ + public function query_actions( $query = [], $query_type = 'select' ) { + $found_unmigrated_actions = $this->secondary_store->query_actions( $query, 'select' ); + if ( ! empty( $found_unmigrated_actions ) ) { + $this->migrate( $found_unmigrated_actions ); + } + + return $this->primary_store->query_actions( $query, $query_type ); + } + + /** + * Get a count of all actions in the store, grouped by status + * + * @return array Set of 'status' => int $count pairs for statuses with 1 or more actions of that status. + */ + public function action_counts() { + $unmigrated_actions_count = $this->secondary_store->action_counts(); + $migrated_actions_count = $this->primary_store->action_counts(); + $actions_count_by_status = array(); + + foreach ( $this->get_status_labels() as $status_key => $status_label ) { + + $count = 0; + + if ( isset( $unmigrated_actions_count[ $status_key ] ) ) { + $count += $unmigrated_actions_count[ $status_key ]; + } + + if ( isset( $migrated_actions_count[ $status_key ] ) ) { + $count += $migrated_actions_count[ $status_key ]; + } + + $actions_count_by_status[ $status_key ] = $count; + } + + $actions_count_by_status = array_filter( $actions_count_by_status ); + + return $actions_count_by_status; + } + + /** + * If any actions would have been claimed by the secondary store, + * migrate them immediately, then ask the primary store for the + * canonical claim. + * + * @param int $max_actions + * @param DateTime|null $before_date + * + * @return ActionScheduler_ActionClaim + */ + public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) { + $claim = $this->secondary_store->stake_claim( $max_actions, $before_date, $hooks, $group ); + + $claimed_actions = $claim->get_actions(); + if ( ! empty( $claimed_actions ) ) { + $this->migrate( $claimed_actions ); + } + + $this->secondary_store->release_claim( $claim ); + + return $this->primary_store->stake_claim( $max_actions, $before_date, $hooks, $group ); + } + + /** + * Migrate a list of actions to the table data store. + * + * @param array $action_ids List of action IDs. + */ + private function migrate( $action_ids ) { + $this->migration_runner->migrate_actions( $action_ids ); + } + + /** + * Save an action to the primary store. + * + * @param ActionScheduler_Action $action Action object to be saved. + * @param DateTime $date Optional. Schedule date. Default null. + * + * @return int The action ID + */ + public function save_action( ActionScheduler_Action $action, DateTime $date = null ) { + return $this->primary_store->save_action( $action, $date ); + } + + /** + * Retrieve an existing action whether migrated or not. + * + * @param int $action_id Action ID. + */ + public function fetch_action( $action_id ) { + $store = $this->get_store_from_action_id( $action_id, true ); + if ( $store ) { + return $store->fetch_action( $action_id ); + } else { + return new ActionScheduler_NullAction(); + } + } + + /** + * Cancel an existing action whether migrated or not. + * + * @param int $action_id Action ID. + */ + public function cancel_action( $action_id ) { + $store = $this->get_store_from_action_id( $action_id ); + if ( $store ) { + $store->cancel_action( $action_id ); + } + } + + /** + * Delete an existing action whether migrated or not. + * + * @param int $action_id Action ID. + */ + public function delete_action( $action_id ) { + $store = $this->get_store_from_action_id( $action_id ); + if ( $store ) { + $store->delete_action( $action_id ); + } + } + + /** + * Get the schedule date an existing action whether migrated or not. + * + * @param int $action_id Action ID. + */ + public function get_date( $action_id ) { + $store = $this->get_store_from_action_id( $action_id ); + if ( $store ) { + return $store->get_date( $action_id ); + } else { + return null; + } + } + + /** + * Mark an existing action as failed whether migrated or not. + * + * @param int $action_id Action ID. + */ + public function mark_failure( $action_id ) { + $store = $this->get_store_from_action_id( $action_id ); + if ( $store ) { + $store->mark_failure( $action_id ); + } + } + + /** + * Log the execution of an existing action whether migrated or not. + * + * @param int $action_id Action ID. + */ + public function log_execution( $action_id ) { + $store = $this->get_store_from_action_id( $action_id ); + if ( $store ) { + $store->log_execution( $action_id ); + } + } + + /** + * Mark an existing action complete whether migrated or not. + * + * @param int $action_id Action ID. + */ + public function mark_complete( $action_id ) { + $store = $this->get_store_from_action_id( $action_id ); + if ( $store ) { + $store->mark_complete( $action_id ); + } + } + + /** + * Get an existing action status whether migrated or not. + * + * @param int $action_id Action ID. + */ + public function get_status( $action_id ) { + $store = $this->get_store_from_action_id( $action_id ); + if ( $store ) { + return $store->get_status( $action_id ); + } + return null; + } + + /** + * Return which store an action is stored in. + * + * @param int $action_id ID of the action. + * @param bool $primary_first Optional flag indicating search the primary store first. + * @return ActionScheduler_Store + */ + protected function get_store_from_action_id( $action_id, $primary_first = false ) { + if ( $primary_first ) { + $stores = [ + $this->primary_store, + $this->secondary_store, + ]; + } elseif ( $action_id < $this->demarkation_id ) { + $stores = [ + $this->secondary_store, + $this->primary_store, + ]; + } else { + $stores = [ + $this->primary_store, + ]; + } + + foreach ( $stores as $store ) { + $action = $store->fetch_action( $action_id ); + if ( ! is_a( $action, 'ActionScheduler_NullAction' ) ) { + return $store; + } + } + return null; + } + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * + * All claim-related functions should operate solely + * on the primary store. + * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * Get the claim count from the table data store. + */ + public function get_claim_count() { + return $this->primary_store->get_claim_count(); + } + + /** + * Retrieve the claim ID for an action from the table data store. + * + * @param int $action_id Action ID. + */ + public function get_claim_id( $action_id ) { + return $this->primary_store->get_claim_id( $action_id ); + } + + /** + * Release a claim in the table data store. + * + * @param ActionScheduler_ActionClaim $claim Claim object. + */ + public function release_claim( ActionScheduler_ActionClaim $claim ) { + $this->primary_store->release_claim( $claim ); + } + + /** + * Release claims on an action in the table data store. + * + * @param int $action_id Action ID. + */ + public function unclaim_action( $action_id ) { + $this->primary_store->unclaim_action( $action_id ); + } + + /** + * Retrieve a list of action IDs by claim. + * + * @param int $claim_id Claim ID. + */ + public function find_actions_by_claim_id( $claim_id ) { + return $this->primary_store->find_actions_by_claim_id( $claim_id ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php new file mode 100644 index 0000000..7215ddd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php @@ -0,0 +1,240 @@ +create_wp_comment( $action_id, $message, $date ); + return $comment_id; + } + + protected function create_wp_comment( $action_id, $message, DateTime $date ) { + + $comment_date_gmt = $date->format('Y-m-d H:i:s'); + ActionScheduler_TimezoneHelper::set_local_timezone( $date ); + $comment_data = array( + 'comment_post_ID' => $action_id, + 'comment_date' => $date->format('Y-m-d H:i:s'), + 'comment_date_gmt' => $comment_date_gmt, + 'comment_author' => self::AGENT, + 'comment_content' => $message, + 'comment_agent' => self::AGENT, + 'comment_type' => self::TYPE, + ); + return wp_insert_comment($comment_data); + } + + /** + * @param string $entry_id + * + * @return ActionScheduler_LogEntry + */ + public function get_entry( $entry_id ) { + $comment = $this->get_comment( $entry_id ); + if ( empty($comment) || $comment->comment_type != self::TYPE ) { + return new ActionScheduler_NullLogEntry(); + } + + $date = as_get_datetime_object( $comment->comment_date_gmt ); + ActionScheduler_TimezoneHelper::set_local_timezone( $date ); + return new ActionScheduler_LogEntry( $comment->comment_post_ID, $comment->comment_content, $date ); + } + + /** + * @param string $action_id + * + * @return ActionScheduler_LogEntry[] + */ + public function get_logs( $action_id ) { + $status = 'all'; + if ( get_post_status($action_id) == 'trash' ) { + $status = 'post-trashed'; + } + $comments = get_comments(array( + 'post_id' => $action_id, + 'orderby' => 'comment_date_gmt', + 'order' => 'ASC', + 'type' => self::TYPE, + 'status' => $status, + )); + $logs = array(); + foreach ( $comments as $c ) { + $entry = $this->get_entry( $c ); + if ( !empty($entry) ) { + $logs[] = $entry; + } + } + return $logs; + } + + protected function get_comment( $comment_id ) { + return get_comment( $comment_id ); + } + + + + /** + * @param WP_Comment_Query $query + */ + public function filter_comment_queries( $query ) { + foreach ( array('ID', 'parent', 'post_author', 'post_name', 'post_parent', 'type', 'post_type', 'post_id', 'post_ID') as $key ) { + if ( !empty($query->query_vars[$key]) ) { + return; // don't slow down queries that wouldn't include action_log comments anyway + } + } + $query->query_vars['action_log_filter'] = TRUE; + add_filter( 'comments_clauses', array( $this, 'filter_comment_query_clauses' ), 10, 2 ); + } + + /** + * @param array $clauses + * @param WP_Comment_Query $query + * + * @return array + */ + public function filter_comment_query_clauses( $clauses, $query ) { + if ( !empty($query->query_vars['action_log_filter']) ) { + $clauses['where'] .= $this->get_where_clause(); + } + return $clauses; + } + + /** + * Make sure Action Scheduler logs are excluded from comment feeds, which use WP_Query, not + * the WP_Comment_Query class handled by @see self::filter_comment_queries(). + * + * @param string $where + * @param WP_Query $query + * + * @return string + */ + public function filter_comment_feed( $where, $query ) { + if ( is_comment_feed() ) { + $where .= $this->get_where_clause(); + } + return $where; + } + + /** + * Return a SQL clause to exclude Action Scheduler comments. + * + * @return string + */ + protected function get_where_clause() { + global $wpdb; + return sprintf( " AND {$wpdb->comments}.comment_type != '%s'", self::TYPE ); + } + + /** + * Remove action log entries from wp_count_comments() + * + * @param array $stats + * @param int $post_id + * + * @return object + */ + public function filter_comment_count( $stats, $post_id ) { + global $wpdb; + + if ( 0 === $post_id ) { + $stats = $this->get_comment_count(); + } + + return $stats; + } + + /** + * Retrieve the comment counts from our cache, or the database if the cached version isn't set. + * + * @return object + */ + protected function get_comment_count() { + global $wpdb; + + $stats = get_transient( 'as_comment_count' ); + + if ( ! $stats ) { + $stats = array(); + + $count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A ); + + $total = 0; + $stats = array(); + $approved = array( '0' => 'moderated', '1' => 'approved', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed' ); + + foreach ( (array) $count as $row ) { + // Don't count post-trashed toward totals + if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) { + $total += $row['num_comments']; + } + if ( isset( $approved[ $row['comment_approved'] ] ) ) { + $stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments']; + } + } + + $stats['total_comments'] = $total; + $stats['all'] = $total; + + foreach ( $approved as $key ) { + if ( empty( $stats[ $key ] ) ) { + $stats[ $key ] = 0; + } + } + + $stats = (object) $stats; + set_transient( 'as_comment_count', $stats ); + } + + return $stats; + } + + /** + * Delete comment count cache whenever there is new comment or the status of a comment changes. Cache + * will be regenerated next time ActionScheduler_wpCommentLogger::filter_comment_count() is called. + */ + public function delete_comment_count_cache() { + delete_transient( 'as_comment_count' ); + } + + /** + * @codeCoverageIgnore + */ + public function init() { + add_action( 'action_scheduler_before_process_queue', array( $this, 'disable_comment_counting' ), 10, 0 ); + add_action( 'action_scheduler_after_process_queue', array( $this, 'enable_comment_counting' ), 10, 0 ); + + parent::init(); + + add_action( 'pre_get_comments', array( $this, 'filter_comment_queries' ), 10, 1 ); + add_action( 'wp_count_comments', array( $this, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs + add_action( 'comment_feed_where', array( $this, 'filter_comment_feed' ), 10, 2 ); + + // Delete comments count cache whenever there is a new comment or a comment status changes + add_action( 'wp_insert_comment', array( $this, 'delete_comment_count_cache' ) ); + add_action( 'wp_set_comment_status', array( $this, 'delete_comment_count_cache' ) ); + } + + public function disable_comment_counting() { + wp_defer_comment_counting(true); + } + public function enable_comment_counting() { + wp_defer_comment_counting(false); + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php new file mode 100644 index 0000000..e324ece --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php @@ -0,0 +1,860 @@ +validate_action( $action ); + $post_array = $this->create_post_array( $action, $scheduled_date ); + $post_id = $this->save_post_array( $post_array ); + $this->save_post_schedule( $post_id, $action->get_schedule() ); + $this->save_action_group( $post_id, $action->get_group() ); + do_action( 'action_scheduler_stored_action', $post_id ); + return $post_id; + } catch ( Exception $e ) { + throw new RuntimeException( sprintf( __( 'Error saving action: %s', 'woocommerce' ), $e->getMessage() ), 0 ); + } + } + + protected function create_post_array( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) { + $post = array( + 'post_type' => self::POST_TYPE, + 'post_title' => $action->get_hook(), + 'post_content' => json_encode($action->get_args()), + 'post_status' => ( $action->is_finished() ? 'publish' : 'pending' ), + 'post_date_gmt' => $this->get_scheduled_date_string( $action, $scheduled_date ), + 'post_date' => $this->get_scheduled_date_string_local( $action, $scheduled_date ), + ); + return $post; + } + + protected function save_post_array( $post_array ) { + add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 ); + add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 ); + + $has_kses = false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' ); + + if ( $has_kses ) { + // Prevent KSES from corrupting JSON in post_content. + kses_remove_filters(); + } + + $post_id = wp_insert_post($post_array); + + if ( $has_kses ) { + kses_init_filters(); + } + + remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 ); + remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 ); + + if ( is_wp_error($post_id) || empty($post_id) ) { + throw new RuntimeException( __( 'Unable to save action.', 'woocommerce' ) ); + } + return $post_id; + } + + public function filter_insert_post_data( $postdata ) { + if ( $postdata['post_type'] == self::POST_TYPE ) { + $postdata['post_author'] = 0; + if ( $postdata['post_status'] == 'future' ) { + $postdata['post_status'] = 'publish'; + } + } + return $postdata; + } + + /** + * Create a (probably unique) post name for scheduled actions in a more performant manner than wp_unique_post_slug(). + * + * When an action's post status is transitioned to something other than 'draft', 'pending' or 'auto-draft, like 'publish' + * or 'failed' or 'trash', WordPress will find a unique slug (stored in post_name column) using the wp_unique_post_slug() + * function. This is done to ensure URL uniqueness. The approach taken by wp_unique_post_slug() is to iterate over existing + * post_name values that match, and append a number 1 greater than the largest. This makes sense when manually creating a + * post from the Edit Post screen. It becomes a bottleneck when automatically processing thousands of actions, with a + * database containing thousands of related post_name values. + * + * WordPress 5.1 introduces the 'pre_wp_unique_post_slug' filter for plugins to address this issue. + * + * We can short-circuit WordPress's wp_unique_post_slug() approach using the 'pre_wp_unique_post_slug' filter. This + * method is available to be used as a callback on that filter. It provides a more scalable approach to generating a + * post_name/slug that is probably unique. Because Action Scheduler never actually uses the post_name field, or an + * action's slug, being probably unique is good enough. + * + * For more backstory on this issue, see: + * - https://github.com/woocommerce/action-scheduler/issues/44 and + * - https://core.trac.wordpress.org/ticket/21112 + * + * @param string $override_slug Short-circuit return value. + * @param string $slug The desired slug (post_name). + * @param int $post_ID Post ID. + * @param string $post_status The post status. + * @param string $post_type Post type. + * @return string + */ + public function set_unique_post_slug( $override_slug, $slug, $post_ID, $post_status, $post_type ) { + if ( self::POST_TYPE == $post_type ) { + $override_slug = uniqid( self::POST_TYPE . '-', true ) . '-' . wp_generate_password( 32, false ); + } + return $override_slug; + } + + protected function save_post_schedule( $post_id, $schedule ) { + update_post_meta( $post_id, self::SCHEDULE_META_KEY, $schedule ); + } + + protected function save_action_group( $post_id, $group ) { + if ( empty($group) ) { + wp_set_object_terms( $post_id, array(), self::GROUP_TAXONOMY, FALSE ); + } else { + wp_set_object_terms( $post_id, array($group), self::GROUP_TAXONOMY, FALSE ); + } + } + + public function fetch_action( $action_id ) { + $post = $this->get_post( $action_id ); + if ( empty($post) || $post->post_type != self::POST_TYPE ) { + return $this->get_null_action(); + } + + try { + $action = $this->make_action_from_post( $post ); + } catch ( ActionScheduler_InvalidActionException $exception ) { + do_action( 'action_scheduler_failed_fetch_action', $post->ID, $exception ); + return $this->get_null_action(); + } + + return $action; + } + + protected function get_post( $action_id ) { + if ( empty($action_id) ) { + return NULL; + } + return get_post($action_id); + } + + protected function get_null_action() { + return new ActionScheduler_NullAction(); + } + + protected function make_action_from_post( $post ) { + $hook = $post->post_title; + + $args = json_decode( $post->post_content, true ); + $this->validate_args( $args, $post->ID ); + + $schedule = get_post_meta( $post->ID, self::SCHEDULE_META_KEY, true ); + $this->validate_schedule( $schedule, $post->ID ); + + $group = wp_get_object_terms( $post->ID, self::GROUP_TAXONOMY, array('fields' => 'names') ); + $group = empty( $group ) ? '' : reset($group); + + return ActionScheduler::factory()->get_stored_action( $this->get_action_status_by_post_status( $post->post_status ), $hook, $args, $schedule, $group ); + } + + /** + * @param string $post_status + * + * @throws InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels() + * @return string + */ + protected function get_action_status_by_post_status( $post_status ) { + + switch ( $post_status ) { + case 'publish' : + $action_status = self::STATUS_COMPLETE; + break; + case 'trash' : + $action_status = self::STATUS_CANCELED; + break; + default : + if ( ! array_key_exists( $post_status, $this->get_status_labels() ) ) { + throw new InvalidArgumentException( sprintf( 'Invalid post status: "%s". No matching action status available.', $post_status ) ); + } + $action_status = $post_status; + break; + } + + return $action_status; + } + + /** + * @param string $action_status + * @throws InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels() + * @return string + */ + protected function get_post_status_by_action_status( $action_status ) { + + switch ( $action_status ) { + case self::STATUS_COMPLETE : + $post_status = 'publish'; + break; + case self::STATUS_CANCELED : + $post_status = 'trash'; + break; + default : + if ( ! array_key_exists( $action_status, $this->get_status_labels() ) ) { + throw new InvalidArgumentException( sprintf( 'Invalid action status: "%s".', $action_status ) ); + } + $post_status = $action_status; + break; + } + + return $post_status; + } + + /** + * @param string $hook + * @param array $params + * + * @return string ID of the next action matching the criteria or NULL if not found + */ + public function find_action( $hook, $params = array() ) { + $params = wp_parse_args( $params, array( + 'args' => NULL, + 'status' => ActionScheduler_Store::STATUS_PENDING, + 'group' => '', + )); + /** @var wpdb $wpdb */ + global $wpdb; + $query = "SELECT p.ID FROM {$wpdb->posts} p"; + $args = array(); + if ( !empty($params['group']) ) { + $query .= " INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID"; + $query .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id"; + $query .= " INNER JOIN {$wpdb->terms} t ON tt.term_id=t.term_id AND t.slug=%s"; + $args[] = $params['group']; + } + $query .= " WHERE p.post_title=%s"; + $args[] = $hook; + $query .= " AND p.post_type=%s"; + $args[] = self::POST_TYPE; + if ( !is_null($params['args']) ) { + $query .= " AND p.post_content=%s"; + $args[] = json_encode($params['args']); + } + + if ( ! empty( $params['status'] ) ) { + $query .= " AND p.post_status=%s"; + $args[] = $this->get_post_status_by_action_status( $params['status'] ); + } + + switch ( $params['status'] ) { + case self::STATUS_COMPLETE: + case self::STATUS_RUNNING: + case self::STATUS_FAILED: + $order = 'DESC'; // Find the most recent action that matches + break; + case self::STATUS_PENDING: + default: + $order = 'ASC'; // Find the next action that matches + break; + } + $query .= " ORDER BY post_date_gmt $order LIMIT 1"; + + $query = $wpdb->prepare( $query, $args ); + + $id = $wpdb->get_var($query); + return $id; + } + + /** + * Returns the SQL statement to query (or count) actions. + * + * @param array $query Filtering options + * @param string $select_or_count Whether the SQL should select and return the IDs or just the row count + * @throws InvalidArgumentException if $select_or_count not count or select + * @return string SQL statement. The returned SQL is already properly escaped. + */ + protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) { + + if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) { + throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'woocommerce' ) ); + } + + $query = wp_parse_args( $query, array( + 'hook' => '', + 'args' => NULL, + 'date' => NULL, + 'date_compare' => '<=', + 'modified' => NULL, + 'modified_compare' => '<=', + 'group' => '', + 'status' => '', + 'claimed' => NULL, + 'per_page' => 5, + 'offset' => 0, + 'orderby' => 'date', + 'order' => 'ASC', + 'search' => '', + ) ); + + /** @var wpdb $wpdb */ + global $wpdb; + $sql = ( 'count' === $select_or_count ) ? 'SELECT count(p.ID)' : 'SELECT p.ID '; + $sql .= "FROM {$wpdb->posts} p"; + $sql_params = array(); + if ( empty( $query['group'] ) && 'group' === $query['orderby'] ) { + $sql .= " LEFT JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID"; + $sql .= " LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id"; + $sql .= " LEFT JOIN {$wpdb->terms} t ON tt.term_id=t.term_id"; + } elseif ( ! empty( $query['group'] ) ) { + $sql .= " INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID"; + $sql .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id"; + $sql .= " INNER JOIN {$wpdb->terms} t ON tt.term_id=t.term_id"; + $sql .= " AND t.slug=%s"; + $sql_params[] = $query['group']; + } + $sql .= " WHERE post_type=%s"; + $sql_params[] = self::POST_TYPE; + if ( $query['hook'] ) { + $sql .= " AND p.post_title=%s"; + $sql_params[] = $query['hook']; + } + if ( !is_null($query['args']) ) { + $sql .= " AND p.post_content=%s"; + $sql_params[] = json_encode($query['args']); + } + + if ( ! empty( $query['status'] ) ) { + $sql .= " AND p.post_status=%s"; + $sql_params[] = $this->get_post_status_by_action_status( $query['status'] ); + } + + if ( $query['date'] instanceof DateTime ) { + $date = clone $query['date']; + $date->setTimezone( new DateTimeZone('UTC') ); + $date_string = $date->format('Y-m-d H:i:s'); + $comparator = $this->validate_sql_comparator($query['date_compare']); + $sql .= " AND p.post_date_gmt $comparator %s"; + $sql_params[] = $date_string; + } + + if ( $query['modified'] instanceof DateTime ) { + $modified = clone $query['modified']; + $modified->setTimezone( new DateTimeZone('UTC') ); + $date_string = $modified->format('Y-m-d H:i:s'); + $comparator = $this->validate_sql_comparator($query['modified_compare']); + $sql .= " AND p.post_modified_gmt $comparator %s"; + $sql_params[] = $date_string; + } + + if ( $query['claimed'] === TRUE ) { + $sql .= " AND p.post_password != ''"; + } elseif ( $query['claimed'] === FALSE ) { + $sql .= " AND p.post_password = ''"; + } elseif ( !is_null($query['claimed']) ) { + $sql .= " AND p.post_password = %s"; + $sql_params[] = $query['claimed']; + } + + if ( ! empty( $query['search'] ) ) { + $sql .= " AND (p.post_title LIKE %s OR p.post_content LIKE %s OR p.post_password LIKE %s)"; + for( $i = 0; $i < 3; $i++ ) { + $sql_params[] = sprintf( '%%%s%%', $query['search'] ); + } + } + + if ( 'select' === $select_or_count ) { + switch ( $query['orderby'] ) { + case 'hook': + $orderby = 'p.post_title'; + break; + case 'group': + $orderby = 't.name'; + break; + case 'status': + $orderby = 'p.post_status'; + break; + case 'modified': + $orderby = 'p.post_modified'; + break; + case 'claim_id': + $orderby = 'p.post_password'; + break; + case 'schedule': + case 'date': + default: + $orderby = 'p.post_date_gmt'; + break; + } + if ( 'ASC' === strtoupper( $query['order'] ) ) { + $order = 'ASC'; + } else { + $order = 'DESC'; + } + $sql .= " ORDER BY $orderby $order"; + if ( $query['per_page'] > 0 ) { + $sql .= " LIMIT %d, %d"; + $sql_params[] = $query['offset']; + $sql_params[] = $query['per_page']; + } + } + + return $wpdb->prepare( $sql, $sql_params ); + } + + /** + * @param array $query + * @param string $query_type Whether to select or count the results. Default, select. + * @return string|array The IDs of actions matching the query + */ + public function query_actions( $query = array(), $query_type = 'select' ) { + /** @var wpdb $wpdb */ + global $wpdb; + + $sql = $this->get_query_actions_sql( $query, $query_type ); + + return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql ); + } + + /** + * Get a count of all actions in the store, grouped by status + * + * @return array + */ + public function action_counts() { + + $action_counts_by_status = array(); + $action_stati_and_labels = $this->get_status_labels(); + $posts_count_by_status = (array) wp_count_posts( self::POST_TYPE, 'readable' ); + + foreach ( $posts_count_by_status as $post_status_name => $count ) { + + try { + $action_status_name = $this->get_action_status_by_post_status( $post_status_name ); + } catch ( Exception $e ) { + // Ignore any post statuses that aren't for actions + continue; + } + if ( array_key_exists( $action_status_name, $action_stati_and_labels ) ) { + $action_counts_by_status[ $action_status_name ] = $count; + } + } + + return $action_counts_by_status; + } + + /** + * @param string $action_id + * + * @throws InvalidArgumentException + */ + public function cancel_action( $action_id ) { + $post = get_post( $action_id ); + if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) { + throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'woocommerce' ), $action_id ) ); + } + do_action( 'action_scheduler_canceled_action', $action_id ); + add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 ); + wp_trash_post( $action_id ); + remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 ); + } + + public function delete_action( $action_id ) { + $post = get_post( $action_id ); + if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) { + throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'woocommerce' ), $action_id ) ); + } + do_action( 'action_scheduler_deleted_action', $action_id ); + + wp_delete_post( $action_id, TRUE ); + } + + /** + * @param string $action_id + * + * @throws InvalidArgumentException + * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran. + */ + public function get_date( $action_id ) { + $next = $this->get_date_gmt( $action_id ); + return ActionScheduler_TimezoneHelper::set_local_timezone( $next ); + } + + /** + * @param string $action_id + * + * @throws InvalidArgumentException + * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran. + */ + public function get_date_gmt( $action_id ) { + $post = get_post( $action_id ); + if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) { + throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'woocommerce' ), $action_id ) ); + } + if ( $post->post_status == 'publish' ) { + return as_get_datetime_object( $post->post_modified_gmt ); + } else { + return as_get_datetime_object( $post->post_date_gmt ); + } + } + + /** + * @param int $max_actions + * @param DateTime $before_date Jobs must be schedule before this date. Defaults to now. + * @param array $hooks Claim only actions with a hook or hooks. + * @param string $group Claim only actions in the given group. + * + * @return ActionScheduler_ActionClaim + * @throws RuntimeException When there is an error staking a claim. + * @throws InvalidArgumentException When the given group is not valid. + */ + public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) { + $claim_id = $this->generate_claim_id(); + $this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group ); + $action_ids = $this->find_actions_by_claim_id( $claim_id ); + + return new ActionScheduler_ActionClaim( $claim_id, $action_ids ); + } + + /** + * @return int + */ + public function get_claim_count(){ + global $wpdb; + + $sql = "SELECT COUNT(DISTINCT post_password) FROM {$wpdb->posts} WHERE post_password != '' AND post_type = %s AND post_status IN ('in-progress','pending')"; + $sql = $wpdb->prepare( $sql, array( self::POST_TYPE ) ); + + return $wpdb->get_var( $sql ); + } + + protected function generate_claim_id() { + $claim_id = md5(microtime(true) . rand(0,1000)); + return substr($claim_id, 0, 20); // to fit in db field with 20 char limit + } + + /** + * @param string $claim_id + * @param int $limit + * @param DateTime $before_date Should use UTC timezone. + * @param array $hooks Claim only actions with a hook or hooks. + * @param string $group Claim only actions in the given group. + * + * @return int The number of actions that were claimed + * @throws RuntimeException When there is a database error. + * @throws InvalidArgumentException When the group is invalid. + */ + protected function claim_actions( $claim_id, $limit, DateTime $before_date = null, $hooks = array(), $group = '' ) { + // Set up initial variables. + $date = null === $before_date ? as_get_datetime_object() : clone $before_date; + $limit_ids = ! empty( $group ); + $ids = $limit_ids ? $this->get_actions_by_group( $group, $limit, $date ) : array(); + + // If limiting by IDs and no posts found, then return early since we have nothing to update. + if ( $limit_ids && 0 === count( $ids ) ) { + return 0; + } + + /** @var wpdb $wpdb */ + global $wpdb; + + /* + * Build up custom query to update the affected posts. Parameters are built as a separate array + * to make it easier to identify where they are in the query. + * + * We can't use $wpdb->update() here because of the "ID IN ..." clause. + */ + $update = "UPDATE {$wpdb->posts} SET post_password = %s, post_modified_gmt = %s, post_modified = %s"; + $params = array( + $claim_id, + current_time( 'mysql', true ), + current_time( 'mysql' ), + ); + + // Build initial WHERE clause. + $where = "WHERE post_type = %s AND post_status = %s AND post_password = ''"; + $params[] = self::POST_TYPE; + $params[] = ActionScheduler_Store::STATUS_PENDING; + + if ( ! empty( $hooks ) ) { + $placeholders = array_fill( 0, count( $hooks ), '%s' ); + $where .= ' AND post_title IN (' . join( ', ', $placeholders ) . ')'; + $params = array_merge( $params, array_values( $hooks ) ); + } + + /* + * Add the IDs to the WHERE clause. IDs not escaped because they came directly from a prior DB query. + * + * If we're not limiting by IDs, then include the post_date_gmt clause. + */ + if ( $limit_ids ) { + $where .= ' AND ID IN (' . join( ',', $ids ) . ')'; + } else { + $where .= ' AND post_date_gmt <= %s'; + $params[] = $date->format( 'Y-m-d H:i:s' ); + } + + // Add the ORDER BY clause and,ms limit. + $order = 'ORDER BY menu_order ASC, post_date_gmt ASC, ID ASC LIMIT %d'; + $params[] = $limit; + + // Run the query and gather results. + $rows_affected = $wpdb->query( $wpdb->prepare( "{$update} {$where} {$order}", $params ) ); + if ( $rows_affected === false ) { + throw new RuntimeException( __( 'Unable to claim actions. Database error.', 'woocommerce' ) ); + } + + return (int) $rows_affected; + } + + /** + * Get IDs of actions within a certain group and up to a certain date/time. + * + * @param string $group The group to use in finding actions. + * @param int $limit The number of actions to retrieve. + * @param DateTime $date DateTime object representing cutoff time for actions. Actions retrieved will be + * up to and including this DateTime. + * + * @return array IDs of actions in the appropriate group and before the appropriate time. + * @throws InvalidArgumentException When the group does not exist. + */ + protected function get_actions_by_group( $group, $limit, DateTime $date ) { + // Ensure the group exists before continuing. + if ( ! term_exists( $group, self::GROUP_TAXONOMY )) { + throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'woocommerce' ), $group ) ); + } + + // Set up a query for post IDs to use later. + $query = new WP_Query(); + $query_args = array( + 'fields' => 'ids', + 'post_type' => self::POST_TYPE, + 'post_status' => ActionScheduler_Store::STATUS_PENDING, + 'has_password' => false, + 'posts_per_page' => $limit * 3, + 'suppress_filters' => true, + 'no_found_rows' => true, + 'orderby' => array( + 'menu_order' => 'ASC', + 'date' => 'ASC', + 'ID' => 'ASC', + ), + 'date_query' => array( + 'column' => 'post_date_gmt', + 'before' => $date->format( 'Y-m-d H:i' ), + 'inclusive' => true, + ), + 'tax_query' => array( + array( + 'taxonomy' => self::GROUP_TAXONOMY, + 'field' => 'slug', + 'terms' => $group, + 'include_children' => false, + ), + ), + ); + + return $query->query( $query_args ); + } + + /** + * @param string $claim_id + * @return array + */ + public function find_actions_by_claim_id( $claim_id ) { + /** @var wpdb $wpdb */ + global $wpdb; + $sql = "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_password = %s"; + $sql = $wpdb->prepare( $sql, array( self::POST_TYPE, $claim_id ) ); + $action_ids = $wpdb->get_col( $sql ); + return $action_ids; + } + + public function release_claim( ActionScheduler_ActionClaim $claim ) { + $action_ids = $this->find_actions_by_claim_id( $claim->get_id() ); + if ( empty( $action_ids ) ) { + return; // nothing to do + } + $action_id_string = implode( ',', array_map( 'intval', $action_ids ) ); + /** @var wpdb $wpdb */ + global $wpdb; + $sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID IN ($action_id_string) AND post_password = %s"; + $sql = $wpdb->prepare( $sql, array( $claim->get_id() ) ); + $result = $wpdb->query( $sql ); + if ( $result === false ) { + /* translators: %s: claim ID */ + throw new RuntimeException( sprintf( __( 'Unable to unlock claim %s. Database error.', 'woocommerce' ), $claim->get_id() ) ); + } + } + + /** + * @param string $action_id + */ + public function unclaim_action( $action_id ) { + /** @var wpdb $wpdb */ + global $wpdb; + $sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID = %d AND post_type = %s"; + $sql = $wpdb->prepare( $sql, $action_id, self::POST_TYPE ); + $result = $wpdb->query( $sql ); + if ( $result === false ) { + /* translators: %s: action ID */ + throw new RuntimeException( sprintf( __( 'Unable to unlock claim on action %s. Database error.', 'woocommerce' ), $action_id ) ); + } + } + + public function mark_failure( $action_id ) { + /** @var wpdb $wpdb */ + global $wpdb; + $sql = "UPDATE {$wpdb->posts} SET post_status = %s WHERE ID = %d AND post_type = %s"; + $sql = $wpdb->prepare( $sql, self::STATUS_FAILED, $action_id, self::POST_TYPE ); + $result = $wpdb->query( $sql ); + if ( $result === false ) { + /* translators: %s: action ID */ + throw new RuntimeException( sprintf( __( 'Unable to mark failure on action %s. Database error.', 'woocommerce' ), $action_id ) ); + } + } + + /** + * Return an action's claim ID, as stored in the post password column + * + * @param string $action_id + * @return mixed + */ + public function get_claim_id( $action_id ) { + return $this->get_post_column( $action_id, 'post_password' ); + } + + /** + * Return an action's status, as stored in the post status column + * + * @param string $action_id + * @return mixed + */ + public function get_status( $action_id ) { + $status = $this->get_post_column( $action_id, 'post_status' ); + + if ( $status === null ) { + throw new InvalidArgumentException( __( 'Invalid action ID. No status found.', 'woocommerce' ) ); + } + + return $this->get_action_status_by_post_status( $status ); + } + + private function get_post_column( $action_id, $column_name ) { + /** @var \wpdb $wpdb */ + global $wpdb; + return $wpdb->get_var( $wpdb->prepare( "SELECT {$column_name} FROM {$wpdb->posts} WHERE ID=%d AND post_type=%s", $action_id, self::POST_TYPE ) ); + } + + /** + * @param string $action_id + */ + public function log_execution( $action_id ) { + /** @var wpdb $wpdb */ + global $wpdb; + + $sql = "UPDATE {$wpdb->posts} SET menu_order = menu_order+1, post_status=%s, post_modified_gmt = %s, post_modified = %s WHERE ID = %d AND post_type = %s"; + $sql = $wpdb->prepare( $sql, self::STATUS_RUNNING, current_time('mysql', true), current_time('mysql'), $action_id, self::POST_TYPE ); + $wpdb->query($sql); + } + + /** + * Record that an action was completed. + * + * @param int $action_id ID of the completed action. + * @throws InvalidArgumentException|RuntimeException + */ + public function mark_complete( $action_id ) { + $post = get_post( $action_id ); + if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) { + throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'woocommerce' ), $action_id ) ); + } + add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 ); + add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 ); + $result = wp_update_post(array( + 'ID' => $action_id, + 'post_status' => 'publish', + ), TRUE); + remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 ); + remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 ); + if ( is_wp_error( $result ) ) { + throw new RuntimeException( $result->get_error_message() ); + } + } + + /** + * Mark action as migrated when there is an error deleting the action. + * + * @param int $action_id Action ID. + */ + public function mark_migrated( $action_id ) { + wp_update_post( + array( + 'ID' => $action_id, + 'post_status' => 'migrated' + ) + ); + } + + /** + * Determine whether the post store can be migrated. + * + * @return bool + */ + public function migration_dependencies_met( $setting ) { + global $wpdb; + + $dependencies_met = get_transient( self::DEPENDENCIES_MET ); + if ( empty( $dependencies_met ) ) { + $maximum_args_length = apply_filters( 'action_scheduler_maximum_args_length', 191 ); + $found_action = $wpdb->get_var( + $wpdb->prepare( + "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND CHAR_LENGTH(post_content) > %d LIMIT 1", + $maximum_args_length, + self::POST_TYPE + ) + ); + $dependencies_met = $found_action ? 'no' : 'yes'; + set_transient( self::DEPENDENCIES_MET, $dependencies_met, DAY_IN_SECONDS ); + } + + return 'yes' == $dependencies_met ? $setting : false; + } + + /** + * InnoDB indexes have a maximum size of 767 bytes by default, which is only 191 characters with utf8mb4. + * + * Previously, AS wasn't concerned about args length, as we used the (unindex) post_content column. However, + * as we prepare to move to custom tables, and can use an indexed VARCHAR column instead, we want to warn + * developers of this impending requirement. + * + * @param ActionScheduler_Action $action + */ + protected function validate_action( ActionScheduler_Action $action ) { + try { + parent::validate_action( $action ); + } catch ( Exception $e ) { + $message = sprintf( __( '%s Support for strings longer than this will be removed in a future version.', 'woocommerce' ), $e->getMessage() ); + _doing_it_wrong( 'ActionScheduler_Action::$args', $message, '2.1.0' ); + } + } + + /** + * @codeCoverageIgnore + */ + public function init() { + add_filter( 'action_scheduler_migration_dependencies_met', array( $this, 'migration_dependencies_met' ) ); + + $post_type_registrar = new ActionScheduler_wpPostStore_PostTypeRegistrar(); + $post_type_registrar->register(); + + $post_status_registrar = new ActionScheduler_wpPostStore_PostStatusRegistrar(); + $post_status_registrar->register(); + + $taxonomy_registrar = new ActionScheduler_wpPostStore_TaxonomyRegistrar(); + $taxonomy_registrar->register(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php new file mode 100644 index 0000000..4aaf896 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php @@ -0,0 +1,58 @@ +post_status_args(), $this->post_status_running_labels() ) ); + register_post_status( ActionScheduler_Store::STATUS_FAILED, array_merge( $this->post_status_args(), $this->post_status_failed_labels() ) ); + } + + /** + * Build the args array for the post type definition + * + * @return array + */ + protected function post_status_args() { + $args = array( + 'public' => false, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => true, + 'show_in_admin_status_list' => true, + ); + + return apply_filters( 'action_scheduler_post_status_args', $args ); + } + + /** + * Build the args array for the post type definition + * + * @return array + */ + protected function post_status_failed_labels() { + $labels = array( + 'label' => _x( 'Failed', 'post', 'woocommerce' ), + /* translators: %s: count */ + 'label_count' => _n_noop( 'Failed (%s)', 'Failed (%s)', 'woocommerce' ), + ); + + return apply_filters( 'action_scheduler_post_status_failed_labels', $labels ); + } + + /** + * Build the args array for the post type definition + * + * @return array + */ + protected function post_status_running_labels() { + $labels = array( + 'label' => _x( 'In-Progress', 'post', 'woocommerce' ), + /* translators: %s: count */ + 'label_count' => _n_noop( 'In-Progress (%s)', 'In-Progress (%s)', 'woocommerce' ), + ); + + return apply_filters( 'action_scheduler_post_status_running_labels', $labels ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php new file mode 100644 index 0000000..7aa29b2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php @@ -0,0 +1,50 @@ +post_type_args() ); + } + + /** + * Build the args array for the post type definition + * + * @return array + */ + protected function post_type_args() { + $args = array( + 'label' => __( 'Scheduled Actions', 'woocommerce' ), + 'description' => __( 'Scheduled actions are hooks triggered on a cetain date and time.', 'woocommerce' ), + 'public' => false, + 'map_meta_cap' => true, + 'hierarchical' => false, + 'supports' => array('title', 'editor','comments'), + 'rewrite' => false, + 'query_var' => false, + 'can_export' => true, + 'ep_mask' => EP_NONE, + 'labels' => array( + 'name' => __( 'Scheduled Actions', 'woocommerce' ), + 'singular_name' => __( 'Scheduled Action', 'woocommerce' ), + 'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'woocommerce' ), + 'add_new' => __( 'Add', 'woocommerce' ), + 'add_new_item' => __( 'Add New Scheduled Action', 'woocommerce' ), + 'edit' => __( 'Edit', 'woocommerce' ), + 'edit_item' => __( 'Edit Scheduled Action', 'woocommerce' ), + 'new_item' => __( 'New Scheduled Action', 'woocommerce' ), + 'view' => __( 'View Action', 'woocommerce' ), + 'view_item' => __( 'View Action', 'woocommerce' ), + 'search_items' => __( 'Search Scheduled Actions', 'woocommerce' ), + 'not_found' => __( 'No actions found', 'woocommerce' ), + 'not_found_in_trash' => __( 'No actions found in trash', 'woocommerce' ), + ), + ); + + $args = apply_filters('action_scheduler_post_type_args', $args); + return $args; + } +} + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php new file mode 100644 index 0000000..844e596 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php @@ -0,0 +1,26 @@ +taxonomy_args() ); + } + + protected function taxonomy_args() { + $args = array( + 'label' => __( 'Action Group', 'woocommerce' ), + 'public' => false, + 'hierarchical' => false, + 'show_admin_column' => true, + 'query_var' => false, + 'rewrite' => false, + ); + + $args = apply_filters( 'action_scheduler_taxonomy_args', $args ); + return $args; + } +} + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/ActionMigrator.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/ActionMigrator.php new file mode 100644 index 0000000..4e93e7a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/ActionMigrator.php @@ -0,0 +1,109 @@ +source = $source_store; + $this->destination = $destination_store; + $this->log_migrator = $log_migrator; + } + + /** + * Migrate an action. + * + * @param int $source_action_id Action ID. + * + * @return int 0|new action ID + */ + public function migrate( $source_action_id ) { + try { + $action = $this->source->fetch_action( $source_action_id ); + $status = $this->source->get_status( $source_action_id ); + } catch ( \Exception $e ) { + $action = null; + $status = ''; + } + + if ( is_null( $action ) || empty( $status ) || ! $action->get_schedule()->get_date() ) { + // null action or empty status means the fetch operation failed or the action didn't exist + // null schedule means it's missing vital data + // delete it and move on + try { + $this->source->delete_action( $source_action_id ); + } catch ( \Exception $e ) { + // nothing to do, it didn't exist in the first place + } + do_action( 'action_scheduler/no_action_to_migrate', $source_action_id, $this->source, $this->destination ); + + return 0; + } + + try { + + // Make sure the last attempt date is set correctly for completed and failed actions + $last_attempt_date = ( $status !== \ActionScheduler_Store::STATUS_PENDING ) ? $this->source->get_date( $source_action_id ) : null; + + $destination_action_id = $this->destination->save_action( $action, null, $last_attempt_date ); + } catch ( \Exception $e ) { + do_action( 'action_scheduler/migrate_action_failed', $source_action_id, $this->source, $this->destination ); + + return 0; // could not save the action in the new store + } + + try { + switch ( $status ) { + case \ActionScheduler_Store::STATUS_FAILED : + $this->destination->mark_failure( $destination_action_id ); + break; + case \ActionScheduler_Store::STATUS_CANCELED : + $this->destination->cancel_action( $destination_action_id ); + break; + } + + $this->log_migrator->migrate( $source_action_id, $destination_action_id ); + $this->source->delete_action( $source_action_id ); + + $test_action = $this->source->fetch_action( $source_action_id ); + if ( ! is_a( $test_action, 'ActionScheduler_NullAction' ) ) { + throw new \RuntimeException( sprintf( __( 'Unable to remove source migrated action %s', 'woocommerce' ), $source_action_id ) ); + } + do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination ); + + return $destination_action_id; + } catch ( \Exception $e ) { + // could not delete from the old store + $this->source->mark_migrated( $source_action_id ); + do_action( 'action_scheduler/migrate_action_incomplete', $source_action_id, $destination_action_id, $this->source, $this->destination ); + do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination ); + + return $destination_action_id; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php new file mode 100644 index 0000000..8a9ce4b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php @@ -0,0 +1,47 @@ + $this->get_scheduled_date_string( $action, $last_attempt_date ), + 'last_attempt_local' => $this->get_scheduled_date_string_local( $action, $last_attempt_date ), + ]; + + $wpdb->update( $wpdb->actionscheduler_actions, $data, array( 'action_id' => $action_id ), array( '%s', '%s' ), array( '%d' ) ); + } + + return $action_id; + } catch ( \Exception $e ) { + throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'woocommerce' ), $e->getMessage() ), 0 ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/BatchFetcher.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/BatchFetcher.php new file mode 100644 index 0000000..4872801 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/BatchFetcher.php @@ -0,0 +1,86 @@ +store = $source_store; + } + + /** + * Retrieve a list of actions. + * + * @param int $count The number of actions to retrieve + * + * @return int[] A list of action IDs + */ + public function fetch( $count = 10 ) { + foreach ( $this->get_query_strategies( $count ) as $query ) { + $action_ids = $this->store->query_actions( $query ); + if ( ! empty( $action_ids ) ) { + return $action_ids; + } + } + + return []; + } + + /** + * Generate a list of prioritized of action search parameters. + * + * @param int $count Number of actions to find. + * + * @return array + */ + private function get_query_strategies( $count ) { + $now = as_get_datetime_object(); + $args = [ + 'date' => $now, + 'per_page' => $count, + 'offset' => 0, + 'orderby' => 'date', + 'order' => 'ASC', + ]; + + $priorities = [ + Store::STATUS_PENDING, + Store::STATUS_FAILED, + Store::STATUS_CANCELED, + Store::STATUS_COMPLETE, + Store::STATUS_RUNNING, + '', // any other unanticipated status + ]; + + foreach ( $priorities as $status ) { + yield wp_parse_args( [ + 'status' => $status, + 'date_compare' => '<=', + ], $args ); + yield wp_parse_args( [ + 'status' => $status, + 'date_compare' => '>=', + ], $args ); + } + } +} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Config.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Config.php new file mode 100644 index 0000000..c52443e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Config.php @@ -0,0 +1,168 @@ +source_store ) ) { + throw new \RuntimeException( __( 'Source store must be configured before running a migration', 'woocommerce' ) ); + } + + return $this->source_store; + } + + /** + * Set the configured source store. + * + * @param ActionScheduler_Store $store Source store object. + */ + public function set_source_store( Store $store ) { + $this->source_store = $store; + } + + /** + * Get the configured source loger. + * + * @return ActionScheduler_Logger + */ + public function get_source_logger() { + if ( empty( $this->source_logger ) ) { + throw new \RuntimeException( __( 'Source logger must be configured before running a migration', 'woocommerce' ) ); + } + + return $this->source_logger; + } + + /** + * Set the configured source logger. + * + * @param ActionScheduler_Logger $logger + */ + public function set_source_logger( Logger $logger ) { + $this->source_logger = $logger; + } + + /** + * Get the configured destination store. + * + * @return ActionScheduler_Store + */ + public function get_destination_store() { + if ( empty( $this->destination_store ) ) { + throw new \RuntimeException( __( 'Destination store must be configured before running a migration', 'woocommerce' ) ); + } + + return $this->destination_store; + } + + /** + * Set the configured destination store. + * + * @param ActionScheduler_Store $store + */ + public function set_destination_store( Store $store ) { + $this->destination_store = $store; + } + + /** + * Get the configured destination logger. + * + * @return ActionScheduler_Logger + */ + public function get_destination_logger() { + if ( empty( $this->destination_logger ) ) { + throw new \RuntimeException( __( 'Destination logger must be configured before running a migration', 'woocommerce' ) ); + } + + return $this->destination_logger; + } + + /** + * Set the configured destination logger. + * + * @param ActionScheduler_Logger $logger + */ + public function set_destination_logger( Logger $logger ) { + $this->destination_logger = $logger; + } + + /** + * Get flag indicating whether it's a dry run. + * + * @return bool + */ + public function get_dry_run() { + return $this->dry_run; + } + + /** + * Set flag indicating whether it's a dry run. + * + * @param bool $dry_run + */ + public function set_dry_run( $dry_run ) { + $this->dry_run = (bool) $dry_run; + } + + /** + * Get progress bar object. + * + * @return ActionScheduler\WPCLI\ProgressBar + */ + public function get_progress_bar() { + return $this->progress_bar; + } + + /** + * Set progress bar object. + * + * @param ActionScheduler\WPCLI\ProgressBar $progress_bar + */ + public function set_progress_bar( ProgressBar $progress_bar ) { + $this->progress_bar = $progress_bar; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Controller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Controller.php new file mode 100644 index 0000000..431d32c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Controller.php @@ -0,0 +1,206 @@ +migration_scheduler = $migration_scheduler; + $this->store_classname = ''; + } + + /** + * Set the action store class name. + * + * @param string $class Classname of the store class. + * + * @return string + */ + public function get_store_class( $class ) { + if ( \ActionScheduler_DataController::is_migration_complete() ) { + return \ActionScheduler_DataController::DATASTORE_CLASS; + } elseif ( \ActionScheduler_Store::DEFAULT_CLASS !== $class ) { + $this->store_classname = $class; + return $class; + } else { + return 'ActionScheduler_HybridStore'; + } + } + + /** + * Set the action logger class name. + * + * @param string $class Classname of the logger class. + * + * @return string + */ + public function get_logger_class( $class ) { + \ActionScheduler_Store::instance(); + + if ( $this->has_custom_datastore() ) { + $this->logger_classname = $class; + return $class; + } else { + return \ActionScheduler_DataController::LOGGER_CLASS; + } + } + + /** + * Get flag indicating whether a custom datastore is in use. + * + * @return bool + */ + public function has_custom_datastore() { + return (bool) $this->store_classname; + } + + /** + * Set up the background migration process + * + * @return void + */ + public function schedule_migration() { + if ( \ActionScheduler_DataController::is_migration_complete() || $this->migration_scheduler->is_migration_scheduled() ) { + return; + } + + $this->migration_scheduler->schedule_migration(); + } + + /** + * Get the default migration config object + * + * @return ActionScheduler\Migration\Config + */ + public function get_migration_config_object() { + static $config = null; + + if ( ! $config ) { + $source_store = $this->store_classname ? new $this->store_classname() : new \ActionScheduler_wpPostStore(); + $source_logger = $this->logger_classname ? new $this->logger_classname() : new \ActionScheduler_wpCommentLogger(); + + $config = new Config(); + $config->set_source_store( $source_store ); + $config->set_source_logger( $source_logger ); + $config->set_destination_store( new \ActionScheduler_DBStoreMigrator() ); + $config->set_destination_logger( new \ActionScheduler_DBLogger() ); + + if ( defined( 'WP_CLI' ) && WP_CLI ) { + $config->set_progress_bar( new ProgressBar( '', 0 ) ); + } + } + + return apply_filters( 'action_scheduler/migration_config', $config ); + } + + /** + * Hook dashboard migration notice. + */ + public function hook_admin_notices() { + if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) { + return; + } + add_action( 'admin_notices', array( $this, 'display_migration_notice' ), 10, 0 ); + } + + /** + * Show a dashboard notice that migration is in progress. + */ + public function display_migration_notice() { + printf( '

    %s

    ', __( 'Action Scheduler migration in progress. The list of scheduled actions may be incomplete.', 'woocommerce' ) ); + } + + /** + * Add store classes. Hook migration. + */ + private function hook() { + add_filter( 'action_scheduler_store_class', array( $this, 'get_store_class' ), 100, 1 ); + add_filter( 'action_scheduler_logger_class', array( $this, 'get_logger_class' ), 100, 1 ); + add_action( 'init', array( $this, 'maybe_hook_migration' ) ); + add_action( 'wp_loaded', array( $this, 'schedule_migration' ) ); + + // Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen + add_action( 'load-tools_page_action-scheduler', array( $this, 'hook_admin_notices' ), 10, 0 ); + add_action( 'load-woocommerce_page_wc-status', array( $this, 'hook_admin_notices' ), 10, 0 ); + } + + /** + * Possibly hook the migration scheduler action. + * + * @author Jeremy Pry + */ + public function maybe_hook_migration() { + if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) { + return; + } + + $this->migration_scheduler->hook(); + } + + /** + * Allow datastores to enable migration to AS tables. + */ + public function allow_migration() { + if ( ! \ActionScheduler_DataController::dependencies_met() ) { + return false; + } + + if ( null === $this->migrate_custom_store ) { + $this->migrate_custom_store = apply_filters( 'action_scheduler_migrate_data_store', false ); + } + + return ( ! $this->has_custom_datastore() ) || $this->migrate_custom_store; + } + + /** + * Proceed with the migration if the dependencies have been met. + */ + public static function init() { + if ( \ActionScheduler_DataController::dependencies_met() ) { + self::instance()->hook(); + } + } + + /** + * Singleton factory. + */ + public static function instance() { + if ( ! isset( self::$instance ) ) { + self::$instance = new static( new Scheduler() ); + } + + return self::$instance; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/DryRun_ActionMigrator.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/DryRun_ActionMigrator.php new file mode 100644 index 0000000..ffc21c2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/DryRun_ActionMigrator.php @@ -0,0 +1,28 @@ +source = $source_logger; + $this->destination = $destination_Logger; + } + + /** + * Migrate an action log. + * + * @param int $source_action_id Source logger object. + * @param int $destination_action_id Destination logger object. + */ + public function migrate( $source_action_id, $destination_action_id ) { + $logs = $this->source->get_logs( $source_action_id ); + foreach ( $logs as $log ) { + if ( $log->get_action_id() == $source_action_id ) { + $this->destination->log( $destination_action_id, $log->get_message(), $log->get_date() ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Runner.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Runner.php new file mode 100644 index 0000000..d1c41dc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Runner.php @@ -0,0 +1,136 @@ +source_store = $config->get_source_store(); + $this->destination_store = $config->get_destination_store(); + $this->source_logger = $config->get_source_logger(); + $this->destination_logger = $config->get_destination_logger(); + + $this->batch_fetcher = new BatchFetcher( $this->source_store ); + if ( $config->get_dry_run() ) { + $this->log_migrator = new DryRun_LogMigrator( $this->source_logger, $this->destination_logger ); + $this->action_migrator = new DryRun_ActionMigrator( $this->source_store, $this->destination_store, $this->log_migrator ); + } else { + $this->log_migrator = new LogMigrator( $this->source_logger, $this->destination_logger ); + $this->action_migrator = new ActionMigrator( $this->source_store, $this->destination_store, $this->log_migrator ); + } + + if ( defined( 'WP_CLI' ) && WP_CLI ) { + $this->progress_bar = $config->get_progress_bar(); + } + } + + /** + * Run migration batch. + * + * @param int $batch_size Optional batch size. Default 10. + * + * @return int Size of batch processed. + */ + public function run( $batch_size = 10 ) { + $batch = $this->batch_fetcher->fetch( $batch_size ); + $batch_size = count( $batch ); + + if ( ! $batch_size ) { + return 0; + } + + if ( $this->progress_bar ) { + /* translators: %d: amount of actions */ + $this->progress_bar->set_message( sprintf( _n( 'Migrating %d action', 'Migrating %d actions', $batch_size, 'woocommerce' ), number_format_i18n( $batch_size ) ) ); + $this->progress_bar->set_count( $batch_size ); + } + + $this->migrate_actions( $batch ); + + return $batch_size; + } + + /** + * Migration a batch of actions. + * + * @param array $action_ids List of action IDs to migrate. + */ + public function migrate_actions( array $action_ids ) { + do_action( 'action_scheduler/migration_batch_starting', $action_ids ); + + \ActionScheduler::logger()->unhook_stored_action(); + $this->destination_logger->unhook_stored_action(); + + foreach ( $action_ids as $source_action_id ) { + $destination_action_id = $this->action_migrator->migrate( $source_action_id ); + if ( $destination_action_id ) { + $this->destination_logger->log( $destination_action_id, sprintf( + /* translators: 1: source action ID 2: source store class 3: destination action ID 4: destination store class */ + __( 'Migrated action with ID %1$d in %2$s to ID %3$d in %4$s', 'woocommerce' ), + $source_action_id, + get_class( $this->source_store ), + $destination_action_id, + get_class( $this->destination_store ) + ) ); + } + + if ( $this->progress_bar ) { + $this->progress_bar->tick(); + } + } + + if ( $this->progress_bar ) { + $this->progress_bar->finish(); + } + + \ActionScheduler::logger()->hook_stored_action(); + + do_action( 'action_scheduler/migration_batch_complete', $action_ids ); + } + + /** + * Initialize destination store and logger. + */ + public function init_destination() { + $this->destination_store->init(); + $this->destination_logger->init(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Scheduler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Scheduler.php new file mode 100644 index 0000000..dcbe2db --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/migration/Scheduler.php @@ -0,0 +1,128 @@ +get_migration_runner(); + $count = $migration_runner->run( $this->get_batch_size() ); + + if ( $count === 0 ) { + $this->mark_complete(); + } else { + $this->schedule_migration( time() + $this->get_schedule_interval() ); + } + } + + /** + * Mark the migration complete. + */ + public function mark_complete() { + $this->unschedule_migration(); + + \ActionScheduler_DataController::mark_migration_complete(); + do_action( 'action_scheduler/migration_complete' ); + } + + /** + * Get a flag indicating whether the migration is scheduled. + * + * @return bool Whether there is a pending action in the store to handle the migration + */ + public function is_migration_scheduled() { + $next = as_next_scheduled_action( self::HOOK ); + + return ! empty( $next ); + } + + /** + * Schedule the migration. + * + * @param int $when Optional timestamp to run the next migration batch. Defaults to now. + * + * @return string The action ID + */ + public function schedule_migration( $when = 0 ) { + $next = as_next_scheduled_action( self::HOOK ); + + if ( ! empty( $next ) ) { + return $next; + } + + if ( empty( $when ) ) { + $when = time() + MINUTE_IN_SECONDS; + } + + return as_schedule_single_action( $when, self::HOOK, array(), self::GROUP ); + } + + /** + * Remove the scheduled migration action. + */ + public function unschedule_migration() { + as_unschedule_action( self::HOOK, null, self::GROUP ); + } + + /** + * Get migration batch schedule interval. + * + * @return int Seconds between migration runs. Defaults to 0 seconds to allow chaining migration via Async Runners. + */ + private function get_schedule_interval() { + return (int) apply_filters( 'action_scheduler/migration_interval', 0 ); + } + + /** + * Get migration batch size. + * + * @return int Number of actions to migrate in each batch. Defaults to 250. + */ + private function get_batch_size() { + return (int) apply_filters( 'action_scheduler/migration_batch_size', 250 ); + } + + /** + * Get migration runner object. + * + * @return Runner + */ + private function get_migration_runner() { + $config = Controller::instance()->get_migration_config_object(); + + return new Runner( $config ); + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_CanceledSchedule.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_CanceledSchedule.php new file mode 100644 index 0000000..840e482 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_CanceledSchedule.php @@ -0,0 +1,57 @@ +__wakeup() for details. + **/ + private $timestamp = NULL; + + /** + * @param DateTime $after + * + * @return DateTime|null + */ + public function calculate_next( DateTime $after ) { + return null; + } + + /** + * Cancelled actions should never have a next schedule, even if get_next() + * is called with $after < $this->scheduled_date. + * + * @param DateTime $after + * @return DateTime|null + */ + public function get_next( DateTime $after ) { + return null; + } + + /** + * @return bool + */ + public function is_recurring() { + return false; + } + + /** + * Unserialize recurring schedules serialized/stored prior to AS 3.0.0 + * + * Prior to Action Scheduler 3.0.0, schedules used different property names to refer + * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 + * aligned properties and property names for better inheritance. To maintain backward + * compatibility with schedules serialized and stored prior to 3.0, we need to correctly + * map the old property names with matching visibility. + */ + public function __wakeup() { + if ( ! is_null( $this->timestamp ) ) { + $this->scheduled_timestamp = $this->timestamp; + unset( $this->timestamp ); + } + parent::__wakeup(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php new file mode 100644 index 0000000..7859307 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_CronSchedule.php @@ -0,0 +1,102 @@ +__wakeup() for details. + **/ + private $start_timestamp = NULL; + + /** + * Deprecated property @see $this->__wakeup() for details. + **/ + private $cron = NULL; + + /** + * Wrapper for parent constructor to accept a cron expression string and map it to a CronExpression for this + * objects $recurrence property. + * + * @param DateTime $start The date & time to run the action at or after. If $start aligns with the CronSchedule passed via $recurrence, it will be used. If it does not align, the first matching date after it will be used. + * @param CronExpression|string $recurrence The CronExpression used to calculate the schedule's next instance. + * @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance. + */ + public function __construct( DateTime $start, $recurrence, DateTime $first = null ) { + if ( ! is_a( $recurrence, 'CronExpression' ) ) { + $recurrence = CronExpression::factory( $recurrence ); + } + + // For backward compatibility, we need to make sure the date is set to the first matching cron date, not whatever date is passed in. Importantly, by passing true as the 3rd param, if $start matches the cron expression, then it will be used. This was previously handled in the now deprecated next() method. + $date = $recurrence->getNextRunDate( $start, 0, true ); + + // parent::__construct() will set this to $date by default, but that may be different to $start now. + $first = empty( $first ) ? $start : $first; + + parent::__construct( $date, $recurrence, $first ); + } + + /** + * Calculate when an instance of this schedule would start based on a given + * date & time using its the CronExpression. + * + * @param DateTime $after + * @return DateTime + */ + protected function calculate_next( DateTime $after ) { + return $this->recurrence->getNextRunDate( $after, 0, false ); + } + + /** + * @return string + */ + public function get_recurrence() { + return strval( $this->recurrence ); + } + + /** + * Serialize cron schedules with data required prior to AS 3.0.0 + * + * Prior to Action Scheduler 3.0.0, reccuring schedules used different property names to + * refer to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 + * aligned properties and property names for better inheritance. To guard against the + * possibility of infinite loops if downgrading to Action Scheduler < 3.0.0, we need to + * also store the data with the old property names so if it's unserialized in AS < 3.0, + * the schedule doesn't end up with a null recurrence. + * + * @return array + */ + public function __sleep() { + + $sleep_params = parent::__sleep(); + + $this->start_timestamp = $this->scheduled_timestamp; + $this->cron = $this->recurrence; + + return array_merge( $sleep_params, array( + 'start_timestamp', + 'cron' + ) ); + } + + /** + * Unserialize cron schedules serialized/stored prior to AS 3.0.0 + * + * For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup(). + */ + public function __wakeup() { + if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) { + $this->scheduled_timestamp = $this->start_timestamp; + unset( $this->start_timestamp ); + } + + if ( is_null( $this->recurrence ) && ! is_null( $this->cron ) ) { + $this->recurrence = $this->cron; + unset( $this->cron ); + } + parent::__wakeup(); + } +} + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php new file mode 100644 index 0000000..11a591e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_IntervalSchedule.php @@ -0,0 +1,81 @@ +__wakeup() for details. + **/ + private $start_timestamp = NULL; + + /** + * Deprecated property @see $this->__wakeup() for details. + **/ + private $interval_in_seconds = NULL; + + /** + * Calculate when this schedule should start after a given date & time using + * the number of seconds between recurrences. + * + * @param DateTime $after + * @return DateTime + */ + protected function calculate_next( DateTime $after ) { + $after->modify( '+' . (int) $this->get_recurrence() . ' seconds' ); + return $after; + } + + /** + * @return int + */ + public function interval_in_seconds() { + _deprecated_function( __METHOD__, '3.0.0', '(int)ActionScheduler_Abstract_RecurringSchedule::get_recurrence()' ); + return (int) $this->get_recurrence(); + } + + /** + * Serialize interval schedules with data required prior to AS 3.0.0 + * + * Prior to Action Scheduler 3.0.0, reccuring schedules used different property names to + * refer to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 + * aligned properties and property names for better inheritance. To guard against the + * possibility of infinite loops if downgrading to Action Scheduler < 3.0.0, we need to + * also store the data with the old property names so if it's unserialized in AS < 3.0, + * the schedule doesn't end up with a null/false/0 recurrence. + * + * @return array + */ + public function __sleep() { + + $sleep_params = parent::__sleep(); + + $this->start_timestamp = $this->scheduled_timestamp; + $this->interval_in_seconds = $this->recurrence; + + return array_merge( $sleep_params, array( + 'start_timestamp', + 'interval_in_seconds' + ) ); + } + + /** + * Unserialize interval schedules serialized/stored prior to AS 3.0.0 + * + * For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup(). + */ + public function __wakeup() { + if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) { + $this->scheduled_timestamp = $this->start_timestamp; + unset( $this->start_timestamp ); + } + + if ( is_null( $this->recurrence ) && ! is_null( $this->interval_in_seconds ) ) { + $this->recurrence = $this->interval_in_seconds; + unset( $this->interval_in_seconds ); + } + parent::__wakeup(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php new file mode 100644 index 0000000..0ca9f7c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_NullSchedule.php @@ -0,0 +1,28 @@ +scheduled_date = null; + } + + /** + * This schedule has no scheduled DateTime, so we need to override the parent __sleep() + * @return array + */ + public function __sleep() { + return array(); + } + + public function __wakeup() { + $this->scheduled_date = null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_Schedule.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_Schedule.php new file mode 100644 index 0000000..d61a9f7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schedules/ActionScheduler_Schedule.php @@ -0,0 +1,18 @@ +__wakeup() for details. + **/ + private $timestamp = NULL; + + /** + * @param DateTime $after + * + * @return DateTime|null + */ + public function calculate_next( DateTime $after ) { + return null; + } + + /** + * @return bool + */ + public function is_recurring() { + return false; + } + + /** + * Serialize schedule with data required prior to AS 3.0.0 + * + * Prior to Action Scheduler 3.0.0, schedules used different property names to refer + * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 + * aligned properties and property names for better inheritance. To guard against the + * scheduled date for single actions always being seen as "now" if downgrading to + * Action Scheduler < 3.0.0, we need to also store the data with the old property names + * so if it's unserialized in AS < 3.0, the schedule doesn't end up with a null recurrence. + * + * @return array + */ + public function __sleep() { + + $sleep_params = parent::__sleep(); + + $this->timestamp = $this->scheduled_timestamp; + + return array_merge( $sleep_params, array( + 'timestamp', + ) ); + } + + /** + * Unserialize recurring schedules serialized/stored prior to AS 3.0.0 + * + * Prior to Action Scheduler 3.0.0, schedules used different property names to refer + * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 + * aligned properties and property names for better inheritance. To maintain backward + * compatibility with schedules serialized and stored prior to 3.0, we need to correctly + * map the old property names with matching visibility. + */ + public function __wakeup() { + + if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->timestamp ) ) { + $this->scheduled_timestamp = $this->timestamp; + unset( $this->timestamp ); + } + parent::__wakeup(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php new file mode 100644 index 0000000..0db5fbd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php @@ -0,0 +1,47 @@ +tables = [ + self::LOG_TABLE, + ]; + } + + protected function get_table_definition( $table ) { + global $wpdb; + $table_name = $wpdb->$table; + $charset_collate = $wpdb->get_charset_collate(); + switch ( $table ) { + + case self::LOG_TABLE: + + return "CREATE TABLE {$table_name} ( + log_id bigint(20) unsigned NOT NULL auto_increment, + action_id bigint(20) unsigned NOT NULL, + message text NOT NULL, + log_date_gmt datetime NOT NULL default '0000-00-00 00:00:00', + log_date_local datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (log_id), + KEY action_id (action_id), + KEY log_date_gmt (log_date_gmt) + ) $charset_collate"; + + default: + return ''; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php new file mode 100644 index 0000000..c36783c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php @@ -0,0 +1,83 @@ +tables = [ + self::ACTIONS_TABLE, + self::CLAIMS_TABLE, + self::GROUPS_TABLE, + ]; + } + + protected function get_table_definition( $table ) { + global $wpdb; + $table_name = $wpdb->$table; + $charset_collate = $wpdb->get_charset_collate(); + $max_index_length = 191; // @see wp_get_db_schema() + switch ( $table ) { + + case self::ACTIONS_TABLE: + + return "CREATE TABLE {$table_name} ( + action_id bigint(20) unsigned NOT NULL auto_increment, + hook varchar(191) NOT NULL, + status varchar(20) NOT NULL, + scheduled_date_gmt datetime NOT NULL default '0000-00-00 00:00:00', + scheduled_date_local datetime NOT NULL default '0000-00-00 00:00:00', + args varchar($max_index_length), + schedule longtext, + group_id bigint(20) unsigned NOT NULL default '0', + attempts int(11) NOT NULL default '0', + last_attempt_gmt datetime NOT NULL default '0000-00-00 00:00:00', + last_attempt_local datetime NOT NULL default '0000-00-00 00:00:00', + claim_id bigint(20) unsigned NOT NULL default '0', + extended_args varchar(8000) DEFAULT NULL, + PRIMARY KEY (action_id), + KEY hook (hook($max_index_length)), + KEY status (status), + KEY scheduled_date_gmt (scheduled_date_gmt), + KEY args (args($max_index_length)), + KEY group_id (group_id), + KEY last_attempt_gmt (last_attempt_gmt), + KEY claim_id (claim_id) + ) $charset_collate"; + + case self::CLAIMS_TABLE: + + return "CREATE TABLE {$table_name} ( + claim_id bigint(20) unsigned NOT NULL auto_increment, + date_created_gmt datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (claim_id), + KEY date_created_gmt (date_created_gmt) + ) $charset_collate"; + + case self::GROUPS_TABLE: + + return "CREATE TABLE {$table_name} ( + group_id bigint(20) unsigned NOT NULL auto_increment, + slug varchar(255) NOT NULL, + PRIMARY KEY (group_id), + KEY slug (slug($max_index_length)) + ) $charset_collate"; + + default: + return ''; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php new file mode 100644 index 0000000..dac17aa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php @@ -0,0 +1,27 @@ +get_date(); + $replacement_method = 'get_date()'; + } else { + $return_value = $this->get_next( $after ); + $replacement_method = 'get_next( $after )'; + } + + _deprecated_function( __METHOD__, '3.0.0', __CLASS__ . '::' . $replacement_method ); + + return $return_value; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php new file mode 100644 index 0000000..002dc75 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/deprecated/ActionScheduler_Store_Deprecated.php @@ -0,0 +1,49 @@ +mark_failure( $action_id ); + } + + /** + * Add base hooks + * + * @since 2.2.6 + */ + protected static function hook() { + _deprecated_function( __METHOD__, '3.0.0' ); + } + + /** + * Remove base hooks + * + * @since 2.2.6 + */ + protected static function unhook() { + _deprecated_function( __METHOD__, '3.0.0' ); + } + + /** + * Get the site's local time. + * + * @deprecated 2.1.0 + * @return DateTimeZone + */ + protected function get_local_timezone() { + _deprecated_function( __FUNCTION__, '2.1.0', 'ActionScheduler_TimezoneHelper::set_local_timezone()' ); + return ActionScheduler_TimezoneHelper::get_local_timezone(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/deprecated/functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/deprecated/functions.php new file mode 100644 index 0000000..f782c4b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/deprecated/functions.php @@ -0,0 +1,126 @@ + '' - the name of the action that will be triggered + * 'args' => NULL - the args array that will be passed with the action + * 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. + * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '=' + * 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. + * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '=' + * 'group' => '' - the group the action belongs to + * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING + * 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID + * 'per_page' => 5 - Number of results to return + * 'offset' => 0 + * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date' + * 'order' => 'ASC' + * @param string $return_format OBJECT, ARRAY_A, or ids + * + * @deprecated 2.1.0 + * + * @return array + */ +function wc_get_scheduled_actions( $args = array(), $return_format = OBJECT ) { + _deprecated_function( __FUNCTION__, '2.1.0', 'as_get_scheduled_actions()' ); + return as_get_scheduled_actions( $args, $return_format ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/functions.php new file mode 100644 index 0000000..241c387 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/functions.php @@ -0,0 +1,275 @@ +async( $hook, $args, $group ); +} + +/** + * Schedule an action to run one time + * + * @param int $timestamp When the job will run. + * @param string $hook The hook to trigger. + * @param array $args Arguments to pass when the hook triggers. + * @param string $group The group to assign this job to. + * + * @return int The action ID. + */ +function as_schedule_single_action( $timestamp, $hook, $args = array(), $group = '' ) { + if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) { + return 0; + } + return ActionScheduler::factory()->single( $hook, $args, $timestamp, $group ); +} + +/** + * Schedule a recurring action + * + * @param int $timestamp When the first instance of the job will run. + * @param int $interval_in_seconds How long to wait between runs. + * @param string $hook The hook to trigger. + * @param array $args Arguments to pass when the hook triggers. + * @param string $group The group to assign this job to. + * + * @return int The action ID. + */ +function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '' ) { + if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) { + return 0; + } + return ActionScheduler::factory()->recurring( $hook, $args, $timestamp, $interval_in_seconds, $group ); +} + +/** + * Schedule an action that recurs on a cron-like schedule. + * + * @param int $base_timestamp The first instance of the action will be scheduled + * to run at a time calculated after this timestamp matching the cron + * expression. This can be used to delay the first instance of the action. + * @param string $schedule A cron-link schedule string + * @see http://en.wikipedia.org/wiki/Cron + * * * * * * * + * ┬ ┬ ┬ ┬ ┬ ┬ + * | | | | | | + * | | | | | + year [optional] + * | | | | +----- day of week (0 - 7) (Sunday=0 or 7) + * | | | +---------- month (1 - 12) + * | | +--------------- day of month (1 - 31) + * | +-------------------- hour (0 - 23) + * +------------------------- min (0 - 59) + * @param string $hook The hook to trigger. + * @param array $args Arguments to pass when the hook triggers. + * @param string $group The group to assign this job to. + * + * @return int The action ID. + */ +function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(), $group = '' ) { + if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) { + return 0; + } + return ActionScheduler::factory()->cron( $hook, $args, $timestamp, $schedule, $group ); +} + +/** + * Cancel the next occurrence of a scheduled action. + * + * While only the next instance of a recurring or cron action is unscheduled by this method, that will also prevent + * all future instances of that recurring or cron action from being run. Recurring and cron actions are scheduled in + * a sequence instead of all being scheduled at once. Each successive occurrence of a recurring action is scheduled + * only after the former action is run. If the next instance is never run, because it's unscheduled by this function, + * then the following instance will never be scheduled (or exist), which is effectively the same as being unscheduled + * by this method also. + * + * @param string $hook The hook that the job will trigger. + * @param array $args Args that would have been passed to the job. + * @param string $group The group the job is assigned to. + * + * @return string|null The scheduled action ID if a scheduled action was found, or null if no matching action found. + */ +function as_unschedule_action( $hook, $args = array(), $group = '' ) { + if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) { + return 0; + } + $params = array(); + if ( is_array($args) ) { + $params['args'] = $args; + } + if ( !empty($group) ) { + $params['group'] = $group; + } + $job_id = ActionScheduler::store()->find_action( $hook, $params ); + + if ( ! empty( $job_id ) ) { + ActionScheduler::store()->cancel_action( $job_id ); + } + + return $job_id; +} + +/** + * Cancel all occurrences of a scheduled action. + * + * @param string $hook The hook that the job will trigger. + * @param array $args Args that would have been passed to the job. + * @param string $group The group the job is assigned to. + */ +function as_unschedule_all_actions( $hook, $args = array(), $group = '' ) { + if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) { + return; + } + if ( empty( $args ) ) { + if ( ! empty( $hook ) && empty( $group ) ) { + ActionScheduler_Store::instance()->cancel_actions_by_hook( $hook ); + return; + } + if ( ! empty( $group ) && empty( $hook ) ) { + ActionScheduler_Store::instance()->cancel_actions_by_group( $group ); + return; + } + } + do { + $unscheduled_action = as_unschedule_action( $hook, $args, $group ); + } while ( ! empty( $unscheduled_action ) ); +} + +/** + * Check if there is an existing action in the queue with a given hook, args and group combination. + * + * An action in the queue could be pending, in-progress or async. If the is pending for a time in + * future, its scheduled date will be returned as a timestamp. If it is currently being run, or an + * async action sitting in the queue waiting to be processed, in which case boolean true will be + * returned. Or there may be no async, in-progress or pending action for this hook, in which case, + * boolean false will be the return value. + * + * @param string $hook + * @param array $args + * @param string $group + * + * @return int|bool The timestamp for the next occurrence of a pending scheduled action, true for an async or in-progress action or false if there is no matching action. + */ +function as_next_scheduled_action( $hook, $args = NULL, $group = '' ) { + if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) { + return false; + } + $params = array(); + if ( is_array($args) ) { + $params['args'] = $args; + } + if ( !empty($group) ) { + $params['group'] = $group; + } + + $params['status'] = ActionScheduler_Store::STATUS_RUNNING; + $job_id = ActionScheduler::store()->find_action( $hook, $params ); + if ( ! empty( $job_id ) ) { + return true; + } + + $params['status'] = ActionScheduler_Store::STATUS_PENDING; + $job_id = ActionScheduler::store()->find_action( $hook, $params ); + if ( empty($job_id) ) { + return false; + } + $job = ActionScheduler::store()->fetch_action( $job_id ); + $scheduled_date = $job->get_schedule()->get_date(); + if ( $scheduled_date ) { + return (int) $scheduled_date->format( 'U' ); + } elseif ( NULL === $scheduled_date ) { // pending async action with NullSchedule + return true; + } + return false; +} + +/** + * Find scheduled actions + * + * @param array $args Possible arguments, with their default values: + * 'hook' => '' - the name of the action that will be triggered + * 'args' => NULL - the args array that will be passed with the action + * 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. + * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '=' + * 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. + * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '=' + * 'group' => '' - the group the action belongs to + * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING + * 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID + * 'per_page' => 5 - Number of results to return + * 'offset' => 0 + * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date' + * 'order' => 'ASC' + * + * @param string $return_format OBJECT, ARRAY_A, or ids. + * + * @return array + */ +function as_get_scheduled_actions( $args = array(), $return_format = OBJECT ) { + if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) { + return array(); + } + $store = ActionScheduler::store(); + foreach ( array('date', 'modified') as $key ) { + if ( isset($args[$key]) ) { + $args[$key] = as_get_datetime_object($args[$key]); + } + } + $ids = $store->query_actions( $args ); + + if ( $return_format == 'ids' || $return_format == 'int' ) { + return $ids; + } + + $actions = array(); + foreach ( $ids as $action_id ) { + $actions[$action_id] = $store->fetch_action( $action_id ); + } + + if ( $return_format == ARRAY_A ) { + foreach ( $actions as $action_id => $action_object ) { + $actions[$action_id] = get_object_vars($action_object); + } + } + + return $actions; +} + +/** + * Helper function to create an instance of DateTime based on a given + * string and timezone. By default, will return the current date/time + * in the UTC timezone. + * + * Needed because new DateTime() called without an explicit timezone + * will create a date/time in PHP's timezone, but we need to have + * assurance that a date/time uses the right timezone (which we almost + * always want to be UTC), which means we need to always include the + * timezone when instantiating datetimes rather than leaving it up to + * the PHP default. + * + * @param mixed $date_string A date/time string. Valid formats are explained in http://php.net/manual/en/datetime.formats.php. + * @param string $timezone A timezone identifier, like UTC or Europe/Lisbon. The list of valid identifiers is available http://php.net/manual/en/timezones.php. + * + * @return ActionScheduler_DateTime + */ +function as_get_datetime_object( $date_string = null, $timezone = 'UTC' ) { + if ( is_object( $date_string ) && $date_string instanceof DateTime ) { + $date = new ActionScheduler_DateTime( $date_string->format( 'Y-m-d H:i:s' ), new DateTimeZone( $timezone ) ); + } elseif ( is_numeric( $date_string ) ) { + $date = new ActionScheduler_DateTime( '@' . $date_string, new DateTimeZone( $timezone ) ); + } else { + $date = new ActionScheduler_DateTime( $date_string, new DateTimeZone( $timezone ) ); + } + return $date; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/WP_Async_Request.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/WP_Async_Request.php new file mode 100644 index 0000000..d7dea1c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/WP_Async_Request.php @@ -0,0 +1,170 @@ +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(); + + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression.php new file mode 100644 index 0000000..7f33c37 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression.php @@ -0,0 +1,318 @@ + + * @link http://en.wikipedia.org/wiki/Cron + */ +class CronExpression +{ + const MINUTE = 0; + const HOUR = 1; + const DAY = 2; + const MONTH = 3; + const WEEKDAY = 4; + const YEAR = 5; + + /** + * @var array CRON expression parts + */ + private $cronParts; + + /** + * @var CronExpression_FieldFactory CRON field factory + */ + private $fieldFactory; + + /** + * @var array Order in which to test of cron parts + */ + private static $order = array(self::YEAR, self::MONTH, self::DAY, self::WEEKDAY, self::HOUR, self::MINUTE); + + /** + * Factory method to create a new CronExpression. + * + * @param string $expression The CRON expression to create. There are + * several special predefined values which can be used to substitute the + * CRON expression: + * + * @yearly, @annually) - Run once a year, midnight, Jan. 1 - 0 0 1 1 * + * @monthly - Run once a month, midnight, first of month - 0 0 1 * * + * @weekly - Run once a week, midnight on Sun - 0 0 * * 0 + * @daily - Run once a day, midnight - 0 0 * * * + * @hourly - Run once an hour, first minute - 0 * * * * + * +*@param CronExpression_FieldFactory $fieldFactory (optional) Field factory to use + * + * @return CronExpression + */ + public static function factory($expression, CronExpression_FieldFactory $fieldFactory = null) + { + $mappings = array( + '@yearly' => '0 0 1 1 *', + '@annually' => '0 0 1 1 *', + '@monthly' => '0 0 1 * *', + '@weekly' => '0 0 * * 0', + '@daily' => '0 0 * * *', + '@hourly' => '0 * * * *' + ); + + if (isset($mappings[$expression])) { + $expression = $mappings[$expression]; + } + + return new self($expression, $fieldFactory ? $fieldFactory : new CronExpression_FieldFactory()); + } + + /** + * Parse a CRON expression + * + * @param string $expression CRON expression (e.g. '8 * * * *') + * @param CronExpression_FieldFactory $fieldFactory Factory to create cron fields + */ + public function __construct($expression, CronExpression_FieldFactory $fieldFactory) + { + $this->fieldFactory = $fieldFactory; + $this->setExpression($expression); + } + + /** + * Set or change the CRON expression + * + * @param string $value CRON expression (e.g. 8 * * * *) + * + * @return CronExpression + * @throws InvalidArgumentException if not a valid CRON expression + */ + public function setExpression($value) + { + $this->cronParts = preg_split('/\s/', $value, -1, PREG_SPLIT_NO_EMPTY); + if (count($this->cronParts) < 5) { + throw new InvalidArgumentException( + $value . ' is not a valid CRON expression' + ); + } + + foreach ($this->cronParts as $position => $part) { + $this->setPart($position, $part); + } + + return $this; + } + + /** + * Set part of the CRON expression + * + * @param int $position The position of the CRON expression to set + * @param string $value The value to set + * + * @return CronExpression + * @throws InvalidArgumentException if the value is not valid for the part + */ + public function setPart($position, $value) + { + if (!$this->fieldFactory->getField($position)->validate($value)) { + throw new InvalidArgumentException( + 'Invalid CRON field value ' . $value . ' as position ' . $position + ); + } + + $this->cronParts[$position] = $value; + + return $this; + } + + /** + * Get a next run date relative to the current date or a specific date + * + * @param string|DateTime $currentTime (optional) Relative calculation date + * @param int $nth (optional) Number of matches to skip before returning a + * matching next run date. 0, the default, will return the current + * date and time if the next run date falls on the current date and + * time. Setting this value to 1 will skip the first match and go to + * the second match. Setting this value to 2 will skip the first 2 + * matches and so on. + * @param bool $allowCurrentDate (optional) Set to TRUE to return the + * current date if it matches the cron expression + * + * @return DateTime + * @throws RuntimeException on too many iterations + */ + public function getNextRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false) + { + return $this->getRunDate($currentTime, $nth, false, $allowCurrentDate); + } + + /** + * Get a previous run date relative to the current date or a specific date + * + * @param string|DateTime $currentTime (optional) Relative calculation date + * @param int $nth (optional) Number of matches to skip before returning + * @param bool $allowCurrentDate (optional) Set to TRUE to return the + * current date if it matches the cron expression + * + * @return DateTime + * @throws RuntimeException on too many iterations + * @see CronExpression::getNextRunDate + */ + public function getPreviousRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false) + { + return $this->getRunDate($currentTime, $nth, true, $allowCurrentDate); + } + + /** + * Get multiple run dates starting at the current date or a specific date + * + * @param int $total Set the total number of dates to calculate + * @param string|DateTime $currentTime (optional) Relative calculation date + * @param bool $invert (optional) Set to TRUE to retrieve previous dates + * @param bool $allowCurrentDate (optional) Set to TRUE to return the + * current date if it matches the cron expression + * + * @return array Returns an array of run dates + */ + public function getMultipleRunDates($total, $currentTime = 'now', $invert = false, $allowCurrentDate = false) + { + $matches = array(); + for ($i = 0; $i < max(0, $total); $i++) { + $matches[] = $this->getRunDate($currentTime, $i, $invert, $allowCurrentDate); + } + + return $matches; + } + + /** + * Get all or part of the CRON expression + * + * @param string $part (optional) Specify the part to retrieve or NULL to + * get the full cron schedule string. + * + * @return string|null Returns the CRON expression, a part of the + * CRON expression, or NULL if the part was specified but not found + */ + public function getExpression($part = null) + { + if (null === $part) { + return implode(' ', $this->cronParts); + } elseif (array_key_exists($part, $this->cronParts)) { + return $this->cronParts[$part]; + } + + return null; + } + + /** + * Helper method to output the full expression. + * + * @return string Full CRON expression + */ + public function __toString() + { + return $this->getExpression(); + } + + /** + * Determine if the cron is due to run based on the current date or a + * specific date. This method assumes that the current number of + * seconds are irrelevant, and should be called once per minute. + * + * @param string|DateTime $currentTime (optional) Relative calculation date + * + * @return bool Returns TRUE if the cron is due to run or FALSE if not + */ + public function isDue($currentTime = 'now') + { + if ('now' === $currentTime) { + $currentDate = date('Y-m-d H:i'); + $currentTime = strtotime($currentDate); + } elseif ($currentTime instanceof DateTime) { + $currentDate = $currentTime->format('Y-m-d H:i'); + $currentTime = strtotime($currentDate); + } else { + $currentTime = new DateTime($currentTime); + $currentTime->setTime($currentTime->format('H'), $currentTime->format('i'), 0); + $currentDate = $currentTime->format('Y-m-d H:i'); + $currentTime = (int)($currentTime->getTimestamp()); + } + + return $this->getNextRunDate($currentDate, 0, true)->getTimestamp() == $currentTime; + } + + /** + * Get the next or previous run date of the expression relative to a date + * + * @param string|DateTime $currentTime (optional) Relative calculation date + * @param int $nth (optional) Number of matches to skip before returning + * @param bool $invert (optional) Set to TRUE to go backwards in time + * @param bool $allowCurrentDate (optional) Set to TRUE to return the + * current date if it matches the cron expression + * + * @return DateTime + * @throws RuntimeException on too many iterations + */ + protected function getRunDate($currentTime = null, $nth = 0, $invert = false, $allowCurrentDate = false) + { + if ($currentTime instanceof DateTime) { + $currentDate = $currentTime; + } else { + $currentDate = new DateTime($currentTime ? $currentTime : 'now'); + $currentDate->setTimezone(new DateTimeZone(date_default_timezone_get())); + } + + $currentDate->setTime($currentDate->format('H'), $currentDate->format('i'), 0); + $nextRun = clone $currentDate; + $nth = (int) $nth; + + // Set a hard limit to bail on an impossible date + for ($i = 0; $i < 1000; $i++) { + + foreach (self::$order as $position) { + $part = $this->getExpression($position); + if (null === $part) { + continue; + } + + $satisfied = false; + // Get the field object used to validate this part + $field = $this->fieldFactory->getField($position); + // Check if this is singular or a list + if (strpos($part, ',') === false) { + $satisfied = $field->isSatisfiedBy($nextRun, $part); + } else { + foreach (array_map('trim', explode(',', $part)) as $listPart) { + if ($field->isSatisfiedBy($nextRun, $listPart)) { + $satisfied = true; + break; + } + } + } + + // If the field is not satisfied, then start over + if (!$satisfied) { + $field->increment($nextRun, $invert); + continue 2; + } + } + + // Skip this match if needed + if ((!$allowCurrentDate && $nextRun == $currentDate) || --$nth > -1) { + $this->fieldFactory->getField(0)->increment($nextRun, $invert); + continue; + } + + return $nextRun; + } + + // @codeCoverageIgnoreStart + throw new RuntimeException('Impossible CRON expression'); + // @codeCoverageIgnoreEnd + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_AbstractField.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_AbstractField.php new file mode 100644 index 0000000..f8d5c00 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_AbstractField.php @@ -0,0 +1,100 @@ + + */ +abstract class CronExpression_AbstractField implements CronExpression_FieldInterface +{ + /** + * Check to see if a field is satisfied by a value + * + * @param string $dateValue Date value to check + * @param string $value Value to test + * + * @return bool + */ + public function isSatisfied($dateValue, $value) + { + if ($this->isIncrementsOfRanges($value)) { + return $this->isInIncrementsOfRanges($dateValue, $value); + } elseif ($this->isRange($value)) { + return $this->isInRange($dateValue, $value); + } + + return $value == '*' || $dateValue == $value; + } + + /** + * Check if a value is a range + * + * @param string $value Value to test + * + * @return bool + */ + public function isRange($value) + { + return strpos($value, '-') !== false; + } + + /** + * Check if a value is an increments of ranges + * + * @param string $value Value to test + * + * @return bool + */ + public function isIncrementsOfRanges($value) + { + return strpos($value, '/') !== false; + } + + /** + * Test if a value is within a range + * + * @param string $dateValue Set date value + * @param string $value Value to test + * + * @return bool + */ + public function isInRange($dateValue, $value) + { + $parts = array_map('trim', explode('-', $value, 2)); + + return $dateValue >= $parts[0] && $dateValue <= $parts[1]; + } + + /** + * Test if a value is within an increments of ranges (offset[-to]/step size) + * + * @param string $dateValue Set date value + * @param string $value Value to test + * + * @return bool + */ + public function isInIncrementsOfRanges($dateValue, $value) + { + $parts = array_map('trim', explode('/', $value, 2)); + $stepSize = isset($parts[1]) ? $parts[1] : 0; + if ($parts[0] == '*' || $parts[0] === '0') { + return (int) $dateValue % $stepSize == 0; + } + + $range = explode('-', $parts[0], 2); + $offset = $range[0]; + $to = isset($range[1]) ? $range[1] : $dateValue; + // Ensure that the date value is within the range + if ($dateValue < $offset || $dateValue > $to) { + return false; + } + + for ($i = $offset; $i <= $to; $i+= $stepSize) { + if ($i == $dateValue) { + return true; + } + } + + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_DayOfMonthField.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_DayOfMonthField.php new file mode 100644 index 0000000..40c1d6c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_DayOfMonthField.php @@ -0,0 +1,110 @@ + + */ +class CronExpression_DayOfMonthField extends CronExpression_AbstractField +{ + /** + * Get the nearest day of the week for a given day in a month + * + * @param int $currentYear Current year + * @param int $currentMonth Current month + * @param int $targetDay Target day of the month + * + * @return DateTime Returns the nearest date + */ + private static function getNearestWeekday($currentYear, $currentMonth, $targetDay) + { + $tday = str_pad($targetDay, 2, '0', STR_PAD_LEFT); + $target = new DateTime("$currentYear-$currentMonth-$tday"); + $currentWeekday = (int) $target->format('N'); + + if ($currentWeekday < 6) { + return $target; + } + + $lastDayOfMonth = $target->format('t'); + + foreach (array(-1, 1, -2, 2) as $i) { + $adjusted = $targetDay + $i; + if ($adjusted > 0 && $adjusted <= $lastDayOfMonth) { + $target->setDate($currentYear, $currentMonth, $adjusted); + if ($target->format('N') < 6 && $target->format('m') == $currentMonth) { + return $target; + } + } + } + } + + /** + * {@inheritdoc} + */ + public function isSatisfiedBy(DateTime $date, $value) + { + // ? states that the field value is to be skipped + if ($value == '?') { + return true; + } + + $fieldValue = $date->format('d'); + + // Check to see if this is the last day of the month + if ($value == 'L') { + return $fieldValue == $date->format('t'); + } + + // Check to see if this is the nearest weekday to a particular value + if (strpos($value, 'W')) { + // Parse the target day + $targetDay = substr($value, 0, strpos($value, 'W')); + // Find out if the current day is the nearest day of the week + return $date->format('j') == self::getNearestWeekday( + $date->format('Y'), + $date->format('m'), + $targetDay + )->format('j'); + } + + return $this->isSatisfied($date->format('d'), $value); + } + + /** + * {@inheritdoc} + */ + public function increment(DateTime $date, $invert = false) + { + if ($invert) { + $date->modify('previous day'); + $date->setTime(23, 59); + } else { + $date->modify('next day'); + $date->setTime(0, 0); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function validate($value) + { + return (bool) preg_match('/[\*,\/\-\?LW0-9A-Za-z]+/', $value); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_DayOfWeekField.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_DayOfWeekField.php new file mode 100644 index 0000000..e9f68a7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_DayOfWeekField.php @@ -0,0 +1,124 @@ + + */ +class CronExpression_DayOfWeekField extends CronExpression_AbstractField +{ + /** + * {@inheritdoc} + */ + public function isSatisfiedBy(DateTime $date, $value) + { + if ($value == '?') { + return true; + } + + // Convert text day of the week values to integers + $value = str_ireplace( + array('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'), + range(0, 6), + $value + ); + + $currentYear = $date->format('Y'); + $currentMonth = $date->format('m'); + $lastDayOfMonth = $date->format('t'); + + // Find out if this is the last specific weekday of the month + if (strpos($value, 'L')) { + $weekday = str_replace('7', '0', substr($value, 0, strpos($value, 'L'))); + $tdate = clone $date; + $tdate->setDate($currentYear, $currentMonth, $lastDayOfMonth); + while ($tdate->format('w') != $weekday) { + $tdate->setDate($currentYear, $currentMonth, --$lastDayOfMonth); + } + + return $date->format('j') == $lastDayOfMonth; + } + + // Handle # hash tokens + if (strpos($value, '#')) { + list($weekday, $nth) = explode('#', $value); + // Validate the hash fields + if ($weekday < 1 || $weekday > 5) { + throw new InvalidArgumentException("Weekday must be a value between 1 and 5. {$weekday} given"); + } + if ($nth > 5) { + throw new InvalidArgumentException('There are never more than 5 of a given weekday in a month'); + } + // The current weekday must match the targeted weekday to proceed + if ($date->format('N') != $weekday) { + return false; + } + + $tdate = clone $date; + $tdate->setDate($currentYear, $currentMonth, 1); + $dayCount = 0; + $currentDay = 1; + while ($currentDay < $lastDayOfMonth + 1) { + if ($tdate->format('N') == $weekday) { + if (++$dayCount >= $nth) { + break; + } + } + $tdate->setDate($currentYear, $currentMonth, ++$currentDay); + } + + return $date->format('j') == $currentDay; + } + + // Handle day of the week values + if (strpos($value, '-')) { + $parts = explode('-', $value); + if ($parts[0] == '7') { + $parts[0] = '0'; + } elseif ($parts[1] == '0') { + $parts[1] = '7'; + } + $value = implode('-', $parts); + } + + // Test to see which Sunday to use -- 0 == 7 == Sunday + $format = in_array(7, str_split($value)) ? 'N' : 'w'; + $fieldValue = $date->format($format); + + return $this->isSatisfied($fieldValue, $value); + } + + /** + * {@inheritdoc} + */ + public function increment(DateTime $date, $invert = false) + { + if ($invert) { + $date->modify('-1 day'); + $date->setTime(23, 59, 0); + } else { + $date->modify('+1 day'); + $date->setTime(0, 0, 0); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function validate($value) + { + return (bool) preg_match('/[\*,\/\-0-9A-Z]+/', $value); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_FieldFactory.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_FieldFactory.php new file mode 100644 index 0000000..556ba1a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_FieldFactory.php @@ -0,0 +1,55 @@ + + * @link http://en.wikipedia.org/wiki/Cron + */ +class CronExpression_FieldFactory +{ + /** + * @var array Cache of instantiated fields + */ + private $fields = array(); + + /** + * Get an instance of a field object for a cron expression position + * + * @param int $position CRON expression position value to retrieve + * + * @return CronExpression_FieldInterface + * @throws InvalidArgumentException if a position is not valid + */ + public function getField($position) + { + if (!isset($this->fields[$position])) { + switch ($position) { + case 0: + $this->fields[$position] = new CronExpression_MinutesField(); + break; + case 1: + $this->fields[$position] = new CronExpression_HoursField(); + break; + case 2: + $this->fields[$position] = new CronExpression_DayOfMonthField(); + break; + case 3: + $this->fields[$position] = new CronExpression_MonthField(); + break; + case 4: + $this->fields[$position] = new CronExpression_DayOfWeekField(); + break; + case 5: + $this->fields[$position] = new CronExpression_YearField(); + break; + default: + throw new InvalidArgumentException( + $position . ' is not a valid position' + ); + } + } + + return $this->fields[$position]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_FieldInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_FieldInterface.php new file mode 100644 index 0000000..5d5109b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_FieldInterface.php @@ -0,0 +1,39 @@ + + */ +interface CronExpression_FieldInterface +{ + /** + * Check if the respective value of a DateTime field satisfies a CRON exp + * + * @param DateTime $date DateTime object to check + * @param string $value CRON expression to test against + * + * @return bool Returns TRUE if satisfied, FALSE otherwise + */ + public function isSatisfiedBy(DateTime $date, $value); + + /** + * When a CRON expression is not satisfied, this method is used to increment + * or decrement a DateTime object by the unit of the cron field + * + * @param DateTime $date DateTime object to change + * @param bool $invert (optional) Set to TRUE to decrement + * + * @return CronExpression_FieldInterface + */ + public function increment(DateTime $date, $invert = false); + + /** + * Validates a CRON expression for a given field + * + * @param string $value CRON expression value to validate + * + * @return bool Returns TRUE if valid, FALSE otherwise + */ + public function validate($value); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_HoursField.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_HoursField.php new file mode 100644 index 0000000..088ca73 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_HoursField.php @@ -0,0 +1,47 @@ + + */ +class CronExpression_HoursField extends CronExpression_AbstractField +{ + /** + * {@inheritdoc} + */ + public function isSatisfiedBy(DateTime $date, $value) + { + return $this->isSatisfied($date->format('H'), $value); + } + + /** + * {@inheritdoc} + */ + public function increment(DateTime $date, $invert = false) + { + // Change timezone to UTC temporarily. This will + // allow us to go back or forwards and hour even + // if DST will be changed between the hours. + $timezone = $date->getTimezone(); + $date->setTimezone(new DateTimeZone('UTC')); + if ($invert) { + $date->modify('-1 hour'); + $date->setTime($date->format('H'), 59); + } else { + $date->modify('+1 hour'); + $date->setTime($date->format('H'), 0); + } + $date->setTimezone($timezone); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function validate($value) + { + return (bool) preg_match('/[\*,\/\-0-9]+/', $value); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_MinutesField.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_MinutesField.php new file mode 100644 index 0000000..436acf2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_MinutesField.php @@ -0,0 +1,39 @@ + + */ +class CronExpression_MinutesField extends CronExpression_AbstractField +{ + /** + * {@inheritdoc} + */ + public function isSatisfiedBy(DateTime $date, $value) + { + return $this->isSatisfied($date->format('i'), $value); + } + + /** + * {@inheritdoc} + */ + public function increment(DateTime $date, $invert = false) + { + if ($invert) { + $date->modify('-1 minute'); + } else { + $date->modify('+1 minute'); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function validate($value) + { + return (bool) preg_match('/[\*,\/\-0-9]+/', $value); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_MonthField.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_MonthField.php new file mode 100644 index 0000000..d3deb12 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_MonthField.php @@ -0,0 +1,55 @@ + + */ +class CronExpression_MonthField extends CronExpression_AbstractField +{ + /** + * {@inheritdoc} + */ + public function isSatisfiedBy(DateTime $date, $value) + { + // Convert text month values to integers + $value = str_ireplace( + array( + 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', + 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC' + ), + range(1, 12), + $value + ); + + return $this->isSatisfied($date->format('m'), $value); + } + + /** + * {@inheritdoc} + */ + public function increment(DateTime $date, $invert = false) + { + if ($invert) { + // $date->modify('last day of previous month'); // remove for php 5.2 compat + $date->modify('previous month'); + $date->modify($date->format('Y-m-t')); + $date->setTime(23, 59); + } else { + //$date->modify('first day of next month'); // remove for php 5.2 compat + $date->modify('next month'); + $date->modify($date->format('Y-m-01')); + $date->setTime(0, 0); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function validate($value) + { + return (bool) preg_match('/[\*,\/\-0-9A-Z]+/', $value); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_YearField.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_YearField.php new file mode 100644 index 0000000..f11562e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/CronExpression_YearField.php @@ -0,0 +1,43 @@ + + */ +class CronExpression_YearField extends CronExpression_AbstractField +{ + /** + * {@inheritdoc} + */ + public function isSatisfiedBy(DateTime $date, $value) + { + return $this->isSatisfied($date->format('Y'), $value); + } + + /** + * {@inheritdoc} + */ + public function increment(DateTime $date, $invert = false) + { + if ($invert) { + $date->modify('-1 year'); + $date->setDate($date->format('Y'), 12, 31); + $date->setTime(23, 59, 0); + } else { + $date->modify('+1 year'); + $date->setDate($date->format('Y'), 1, 1); + $date->setTime(0, 0, 0); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function validate($value) + { + return (bool) preg_match('/[\*,\/\-0-9]+/', $value); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/LICENSE b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/LICENSE new file mode 100644 index 0000000..c6d88ac --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/lib/cron-expression/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Michael Dowling and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/license.txt b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/license.txt new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/action-scheduler/license.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/chunk-src-version-param.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/chunk-src-version-param.js new file mode 100644 index 0000000..4eaef44 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/chunk-src-version-param.js @@ -0,0 +1,77 @@ +const pluginName = 'AsyncChunkSrcVersionParameterPlugin'; +/** + * Inspired by: https://github.com/webpack/webpack/issues/8115#issuecomment-663902035. + * + * This plugin modifies the webpack bootstrap code generated by the plugin at + * webpack/lib/web/JsonpMainTemplatePlugin.js and the CSS chunk loading code generated + * by @automattic/mini-css-extract-plugin-with-rtl. + * + * It will rename the function jsonpScriptSrc generated by that to webpackJsonpScriptSrc + * and install a new version that checks a user provided variable containing a script + * version parameter to specify in async chunk URLs. + * + * The jsonpScriptSrc override is only for webpack 4 (tested with 4.43 and 4.44). + * + * Webpack 5 has official support for this https://github.com/webpack/webpack/pull/8462 + * so it won't be necessary. + * + * It will also append the ?ver parameter to CSS chunk hrefs loaded by @automattic/mini-css-extract-plugin-with-rtl. + */ +class AsyncChunkSrcVersionParameterPlugin { + _applyMainTemplate( mainTemplate ) { + // Append script version to all async JS chunks loaded with jsonpScriptSrc(). + mainTemplate.hooks.localVars.tap( + // Use stage 1 to ensure this executes after webpack/lib/web/JsonpMainTemplatePlugin.js. + { name: pluginName, stage: 1 }, + ( source ) => { + if ( source.includes( 'function jsonpScriptSrc' ) ) { + const modSource = source.replace( + 'function jsonpScriptSrc', + 'function webpackJsonpScriptSrc' + ); + return `${ modSource } + +function jsonpScriptSrc(chunkId) { + var src = webpackJsonpScriptSrc(chunkId); + if ( window.wcAdminAssets && window.wcAdminAssets.version ) { + src += '?ver=' + window.wcAdminAssets.version; + } + return src; +} +`; + } + + return source; + } + ); + + // Append script version to all async CSS chunks loaded by @automattic/mini-css-extract-plugin-with-rtl. + mainTemplate.hooks.requireEnsure.tap( + // Use stage 1 to ensure this executes after @automattic/mini-css-extract-plugin-with-rtl. + { name: pluginName, stage: 1 }, + ( source ) => { + if ( + source.includes( '// mini-css-extract-plugin CSS loading' ) + ) { + return source.replace( + 'linkTag.href = fullhref;', + `linkTag.href = fullhref; +if ( window.wcAdminAssets && window.wcAdminAssets.version ) { + linkTag.href += '?ver=' + window.wcAdminAssets.version; +}` + ); + } + + return source; + } + ); + } + + apply( compiler ) { + compiler.hooks.thisCompilation.tap( pluginName, ( compilation ) => { + this._applyMainTemplate( compilation.mainTemplate ); + } ); + } +} + +module.exports = AsyncChunkSrcVersionParameterPlugin; diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/app/index.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/app/index.js new file mode 100644 index 0000000..3074679 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/app/index.js @@ -0,0 +1,2 @@ +/*! For license information please see index.js.LICENSE.txt */ +this.wc=this.wc||{},this.wc.app=function(e){function t(t){for(var n,r,i=t[0],a=t[1],c=0,u=[];c=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}},125:function(e,t,n){var r=n(6),o={display:"block",opacity:0,position:"absolute",top:0,left:0,height:"100%",width:"100%",overflow:"hidden",pointerEvents:"none",zIndex:-1},i=function(e){var t=e.onResize,n=r.useRef();return function(e,t){var n=function(){return e.current&&e.current.contentDocument&&e.current.contentDocument.defaultView};function o(){t();var e=n();e&&e.addEventListener("resize",t)}r.useEffect((function(){return n()?o():e.current&&e.current.addEventListener&&e.current.addEventListener("load",o),function(){var e=n();e&&"function"==typeof e.removeEventListener&&e.removeEventListener("resize",t)}}),[])}(n,(function(){return t(n)})),r.createElement("iframe",{style:o,src:"about:blank",ref:n,"aria-hidden":!0,tabIndex:-1,frameBorder:0})},a=function(e){return{width:null!=e?e.offsetWidth:null,height:null!=e?e.offsetHeight:null}};e.exports=function(e){void 0===e&&(e=a);var t=r.useState(e(null)),n=t[0],o=t[1],c=r.useCallback((function(t){return o(e(t.current))}),[e]);return[r.useMemo((function(){return r.createElement(i,{onResize:c})}),[c]),n]}},126:function(e,t,n){"use strict";var r=n(7),o=n(12),i=n(0);t.a=function(e){var t=e.icon,n=e.size,a=void 0===n?20:n,c=e.className,u=Object(o.a)(e,["icon","size","className"]),s=["dashicon","dashicons","dashicons-"+t,c].filter(Boolean).join(" ");return Object(i.createElement)("span",Object(r.a)({className:s,width:a,height:a},u))}},127:function(e,t,n){"use strict";n.d(t,"a",(function(){return O})),n.d(t,"c",(function(){return j})),n.d(t,"b",(function(){return m})),n.d(t,"e",(function(){return h})),n.d(t,"d",(function(){return p}));var r=n(7);function o(e){return"/"===e.charAt(0)}function i(e,t){for(var n=t,r=n+1,o=e.length;r=0;d--){var p=a[d];"."===p?i(a,d):".."===p?(i(a,d),f++):f&&(i(a,d),f--)}if(!s)for(;f--;f)a.unshift("..");!s||""===a[0]||a[0]&&o(a[0])||a.unshift("");var m=a.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};function c(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}var u=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"==typeof t||"object"==typeof n){var r=c(t),o=c(n);return r!==t||o!==n?e(r,o):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1},s=n(103);function l(e){return"/"===e.charAt(0)?e:"/"+e}function f(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function m(e,t,n,o){var i;"string"==typeof e?(i=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var i=t.indexOf("?");return-1!==i&&(n=t.substr(i),t=t.substr(0,i)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e)).state=t:(void 0===(i=Object(r.a)({},e)).pathname&&(i.pathname=""),i.search?"?"!==i.search.charAt(0)&&(i.search="?"+i.search):i.search="",i.hash?"#"!==i.hash.charAt(0)&&(i.hash="#"+i.hash):i.hash="",void 0!==t&&void 0===i.state&&(i.state=t));try{i.pathname=decodeURI(i.pathname)}catch(e){throw e instanceof URIError?new URIError('Pathname "'+i.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):e}return n&&(i.key=n),o?i.pathname?"/"!==i.pathname.charAt(0)&&(i.pathname=a(i.pathname,o.pathname)):i.pathname=o.pathname:i.pathname||(i.pathname="/"),i}function h(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&u(e.state,t.state)}function b(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var i="function"==typeof e?e(t,n):e;"string"==typeof i?"function"==typeof r?r(i,o):o(!0):o(!1!==i)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,r):n.push(r),f({action:"PUSH",location:r,index:t,entries:n})}}))},replace:function(e,t){var r=m(e,t,d(),O.location);l.confirmTransitionTo(r,"REPLACE",n,(function(e){e&&(O.entries[O.index]=r,f({action:"REPLACE",location:r}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=O.index+e;return t>=0&&t0?c/2:s)+(s+c/2>window.innerWidth?window.innerWidth-s:c/2)},f=e.left;"right"===r?f=e.right:"middle"!==i&&(f=s);var d=e.right;"left"===r?d=e.left:"middle"!==i&&(d=s);var p,m={popoverLeft:f,contentWidth:f-c>0?c:f},h={popoverLeft:d,contentWidth:d+c>window.innerWidth?window.innerWidth-d:c},b=n,v=null;if(!o)if("center"===n&&l.contentWidth===c)b="center";else if("left"===n&&m.contentWidth===c)b="left";else if("right"===n&&h.contentWidth===c)b="right";else{var g="left"===(b=m.contentWidth>h.contentWidth?"left":"right")?m.contentWidth:h.contentWidth;v=g!==c?g:null}if(p="center"===b?l.popoverLeft:"left"===b?m.popoverLeft:h.popoverLeft,a){var y=a.getBoundingClientRect();p=Math.min(p,y.right-c)}return{xAxis:b,popoverLeft:p,contentWidth:v}}function w(e,t,n,r,o,i,a){var c=t.height;if(o){var u=(Object(s.b)(i)||document.body).getBoundingClientRect().top+c-a;if(e.top<=u)return{yAxis:n,popoverTop:Math.min(e.bottom,u)}}var l=e.top+e.height/2;"bottom"===r?l=e.bottom:"top"===r&&(l=e.top);var f={popoverTop:l,contentHeight:(l-c/2>0?c/2:l)+(l+c/2>window.innerHeight?window.innerHeight-l:c/2)},d={popoverTop:e.top,contentHeight:e.top-10-c>0?c:e.top-10},p={popoverTop:e.bottom,contentHeight:e.bottom+10+c>window.innerHeight?window.innerHeight-10-e.bottom:c},m=n,h=null;if(!o)if("middle"===n&&f.contentHeight===c)m="middle";else if("top"===n&&d.contentHeight===c)m="top";else if("bottom"===n&&p.contentHeight===c)m="bottom";else{var b="top"===(m=d.contentHeight>p.contentHeight?"top":"bottom")?d.contentHeight:p.contentHeight;h=b!==c?b:null}return{yAxis:m,popoverTop:"middle"===m?f.popoverTop:"top"===m?d.popoverTop:p.popoverTop,contentHeight:h}}var j=n(132),k=n(129),E=n(21),_=n(22),x=n(23),C=n(24),S=n(10),P=n(130);function A(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=Object(S.a)(e);if(t){var o=Object(S.a)(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return Object(C.a)(this,n)}}var N=function(e){Object(x.a)(n,e);var t=A(n);function n(){return Object(E.a)(this,n),t.apply(this,arguments)}return Object(_.a)(n,[{key:"handleFocusOutside",value:function(e){this.props.onFocusOutside(e)}},{key:"render",value:function(){return this.props.children}}]),n}(a.Component),R=Object(P.a)(N),T=n(72);function D(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=Object(S.a)(e);if(t){var o=Object(S.a)(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return Object(C.a)(this,n)}}var M=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.htmlDocument,n=void 0===t?document:t,r=e.className,o=void 0===r?"lockscroll":r,i=0,c=0;function u(e){var t=n.scrollingElement||n.body;e&&(c=t.scrollTop);var r=e?"add":"remove";t.classList[r](o),n.documentElement.classList[r](o),e||(t.scrollTop=c)}function s(){0===i&&u(!0),++i}function l(){1===i&&u(!1),--i}return function(e){Object(x.a)(n,e);var t=D(n);function n(){return Object(E.a)(this,n),t.apply(this,arguments)}return Object(_.a)(n,[{key:"componentDidMount",value:function(){s()}},{key:"componentWillUnmount",value:function(){l()}},{key:"render",value:function(){return null}}]),n}(a.Component)}(),L=n(131),F=n(76),I=n(114),z=n(134),H=Object(k.a)(Object(j.a)((function(e){return e.children})));function B(e,t){var n,r=(n=t).ownerDocument.defaultView.getComputedStyle(n),o=r.paddingTop,i=r.paddingBottom,a=r.paddingLeft,c=r.paddingRight,u=o?parseInt(o,10):0,s=i?parseInt(i,10):0,l=a?parseInt(a,10):0,f=c?parseInt(c,10):0;return{x:e.left+l,y:e.top+u,width:e.width-l-f,height:e.height-u-s,left:e.left+l,right:e.right-f,top:e.top+u,bottom:e.bottom-s}}function U(e,t,n){n?e.getAttribute(t)!==n&&e.setAttribute(t,n):e.hasAttribute(t)&&e.removeAttribute(t)}function V(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";e.style[t]!==n&&(e.style[t]=n)}function q(e,t,n){n?e.classList.contains(t)||e.classList.add(t):e.classList.contains(t)&&e.classList.remove(t)}var W=function(e){var t=e.headerTitle,n=e.onClose,c=e.onKeyDown,m=e.children,v=e.className,g=e.noArrow,j=void 0===g||g,k=e.isAlternate,E=e.position,_=void 0===E?"bottom right":E,x=(e.range,e.focusOnMount),C=void 0===x?"firstElement":x,S=e.anchorRef,P=e.shouldAnchorIncludePadding,A=e.anchorRect,N=e.getAnchorRect,D=e.expandOnMobile,W=e.animate,$=void 0===W||W,G=e.onClickOutside,K=e.onFocusOutside,Q=e.__unstableSticky,Z=e.__unstableSlotName,Y=void 0===Z?"Popover":Z,X=e.__unstableObserveElement,J=e.__unstableBoundaryParent,ee=Object(i.a)(e,["headerTitle","onClose","onKeyDown","children","className","noArrow","isAlternate","position","range","focusOnMount","anchorRef","shouldAnchorIncludePadding","anchorRect","getAnchorRect","expandOnMobile","animate","onClickOutside","onFocusOutside","__unstableSticky","__unstableSlotName","__unstableObserveElement","__unstableBoundaryParent"]),te=Object(a.useRef)(null),ne=Object(a.useRef)(null),re=Object(a.useRef)(),oe=Object(p.a)("medium","<"),ie=Object(a.useState)(),ae=Object(o.a)(ie,2),ce=ae[0],ue=ae[1],se=Object(F.a)(Y),le=D&&oe,fe=h(),de=Object(o.a)(fe,2),pe=de[0],me=de[1];j=le||j,Object(a.useLayoutEffect)((function(){if(le)return q(re.current,"is-without-arrow",j),q(re.current,"is-alternate",k),U(re.current,"data-x-axis"),U(re.current,"data-y-axis"),V(re.current,"top"),V(re.current,"left"),V(ne.current,"maxHeight"),void V(ne.current,"maxWidth");var e=function(){if(re.current&&ne.current){var e=function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]&&arguments[3],o=arguments.length>4?arguments[4]:void 0;if(t)return t;if(n){if(!e.current)return;return n(e.current)}if(!1!==r){if(!(r&&window.Range&&window.Element&&window.DOMRect))return;if(r instanceof window.Range)return Object(s.a)(r);if(r instanceof window.Element){var i=r.getBoundingClientRect();return o?i:B(i,r)}var a=r.top,c=r.bottom,u=a.getBoundingClientRect(),l=c.getBoundingClientRect(),f=new window.DOMRect(u.left,u.top,u.width,l.bottom-u.top);return o?f:B(f,r)}if(e.current){var d=e.current.parentNode,p=d.getBoundingClientRect();return o?p:B(p,d)}}(te,A,N,S,P);if(e){var t,n,r=re.current,i=r.offsetParent,a=r.ownerDocument,c=0;if(i&&i!==a.body){var u=i.getBoundingClientRect();c=u.top,e=new window.DOMRect(e.left-u.left,e.top-u.top,e.width,e.height)}if(J)t=null===(n=re.current.closest(".popover-slot"))||void 0===n?void 0:n.parentNode;var l=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"top",r=arguments.length>3?arguments[3]:void 0,i=arguments.length>4?arguments[4]:void 0,a=arguments.length>5?arguments[5]:void 0,c=arguments.length>6?arguments[6]:void 0,u=n.split(" "),s=Object(o.a)(u,3),l=s[0],f=s[1],d=void 0===f?"center":f,p=s[2],m=w(e,t,l,p,r,i,a),h=O(e,t,d,p,r,m.yAxis,c);return y(y({},h),m)}(e,me.height?me:ne.current.getBoundingClientRect(),_,Q,re.current,c,t),f=l.popoverTop,d=l.popoverLeft,p=l.xAxis,m=l.yAxis,h=l.contentHeight,b=l.contentWidth;"number"==typeof f&&"number"==typeof d&&(V(re.current,"top",f+"px"),V(re.current,"left",d+"px")),q(re.current,"is-without-arrow",j||"center"===p&&"middle"===m),q(re.current,"is-alternate",k),U(re.current,"data-x-axis",p),U(re.current,"data-y-axis",m),V(ne.current,"maxHeight","number"==typeof h?h+"px":""),V(ne.current,"maxWidth","number"==typeof b?b+"px":"");ue(({left:"right",right:"left"}[p]||"center")+" "+({top:"bottom",bottom:"top"}[m]||"middle"))}}};e();var t,n,r=window.setInterval(e,500),i=function(){window.cancelAnimationFrame(t),t=window.requestAnimationFrame(e)};return window.addEventListener("click",i),window.addEventListener("resize",e),window.addEventListener("scroll",e,!0),X&&(n=new window.MutationObserver(e)).observe(X,{attributes:!0}),function(){window.clearInterval(r),window.removeEventListener("resize",e),window.removeEventListener("scroll",e,!0),window.removeEventListener("click",i),window.cancelAnimationFrame(t),n&&n.disconnect()}}),[le,A,N,S,P,_,me,Q,X,J]),function(e,t){Object(a.useEffect)((function(){var n=setTimeout((function(){if(e&&t.current)if("firstElement"!==e)"container"===e&&t.current.focus();else{var n=l.a.tabbable.find(t.current)[0];n?n.focus():t.current.focus()}}),0);return function(){return clearTimeout(n)}}),[])}(C,ne);var he=function(e){e.keyCode===f.b&&n&&(e.stopPropagation(),n()),c&&c(e)};var be=Object(a.createElement)(R,{onFocusOutside:function(e){if(K)K(e);else if(G){var t;try{t=new window.MouseEvent("click")}catch(e){(t=document.createEvent("MouseEvent")).initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null)}Object.defineProperty(t,"target",{get:function(){return e.relatedTarget}}),Object(d.a)("Popover onClickOutside prop",{alternative:"onFocusOutside"}),G(t)}else n&&n()}},Object(a.createElement)(z.a,{type:$&&ce?"appear":null,options:{origin:ce}},(function(e){var o=e.className;return Object(a.createElement)(L.a,Object(r.a)({className:u()("components-popover",v,o,{"is-expanded":le,"is-without-arrow":j,"is-alternate":k})},ee,{onKeyDown:he,ref:re}),le&&Object(a.createElement)(M,null),le&&Object(a.createElement)("div",{className:"components-popover__header"},Object(a.createElement)("span",{className:"components-popover__header-title"},t),Object(a.createElement)(T.a,{className:"components-popover__close",icon:b.a,onClick:n})),Object(a.createElement)("div",{ref:ne,className:"components-popover__content",tabIndex:"-1"},Object(a.createElement)("div",{style:{position:"relative"}},pe,m)))})));return C&&(be=Object(a.createElement)(H,null,be)),se.ref&&(be=Object(a.createElement)(I.a,{name:Y},be)),S||A?be:Object(a.createElement)("span",{ref:te},be)};W.Slot=function(e){var t=e.name,n=void 0===t?"Popover":t;return Object(a.createElement)(I.b,{bubblesVirtually:!0,name:n,className:"popover-slot"})};t.a=W},137:function(e,t,n){var r=function(e){"use strict";var t=Object.prototype,n=t.hasOwnProperty,r="function"==typeof Symbol?Symbol:{},o=r.iterator||"@@iterator",i=r.asyncIterator||"@@asyncIterator",a=r.toStringTag||"@@toStringTag";function c(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{c({},"")}catch(e){c=function(e,t,n){return e[t]=n}}function u(e,t,n,r){var o=t&&t.prototype instanceof f?t:f,i=Object.create(o.prototype),a=new k(r||[]);return i._invoke=function(e,t,n){var r="suspendedStart";return function(o,i){if("executing"===r)throw new Error("Generator is already running");if("completed"===r){if("throw"===o)throw i;return _()}for(n.method=o,n.arg=i;;){var a=n.delegate;if(a){var c=O(a,n);if(c){if(c===l)continue;return c}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===r)throw r="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r="executing";var u=s(e,t,n);if("normal"===u.type){if(r=n.done?"completed":"suspendedYield",u.arg===l)continue;return{value:u.arg,done:n.done}}"throw"===u.type&&(r="completed",n.method="throw",n.arg=u.arg)}}}(e,n,a),i}function s(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}e.wrap=u;var l={};function f(){}function d(){}function p(){}var m={};m[o]=function(){return this};var h=Object.getPrototypeOf,b=h&&h(h(E([])));b&&b!==t&&n.call(b,o)&&(m=b);var v=p.prototype=f.prototype=Object.create(m);function g(e){["next","throw","return"].forEach((function(t){c(e,t,(function(e){return this._invoke(t,e)}))}))}function y(e,t){var r;this._invoke=function(o,i){function a(){return new t((function(r,a){!function r(o,i,a,c){var u=s(e[o],e,i);if("throw"!==u.type){var l=u.arg,f=l.value;return f&&"object"==typeof f&&n.call(f,"__await")?t.resolve(f.__await).then((function(e){r("next",e,a,c)}),(function(e){r("throw",e,a,c)})):t.resolve(f).then((function(e){l.value=e,a(l)}),(function(e){return r("throw",e,a,c)}))}c(u.arg)}(o,i,r,a)}))}return r=r?r.then(a,a):a()}}function O(e,t){var n=e.iterator[t.method];if(void 0===n){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=void 0,O(e,t),"throw"===t.method))return l;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return l}var r=s(n,e.iterator,t.arg);if("throw"===r.type)return t.method="throw",t.arg=r.arg,t.delegate=null,l;var o=r.arg;return o?o.done?(t[e.resultName]=o.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=void 0),t.delegate=null,l):o:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,l)}function w(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function j(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function k(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(w,this),this.reset(!0)}function E(e){if(e){var t=e[o];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var r=-1,i=function t(){for(;++r=0;--o){var i=this.tryEntries[o],a=i.completion;if("root"===i.tryLoc)return r("end");if(i.tryLoc<=this.prev){var c=n.call(i,"catchLoc"),u=n.call(i,"finallyLoc");if(c&&u){if(this.prev=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),j(n),l}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var o=r.arg;j(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,n){return this.delegate={iterator:E(e),resultName:t,nextLoc:n},"next"===this.method&&(this.arg=void 0),l}},e}(e.exports);try{regeneratorRuntime=r}catch(e){Function("r","regeneratorRuntime = r")(r)}},138:function(e,t,n){"use strict";var r=n(139);function o(){}function i(){}i.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,i,a){if(a!==r){var c=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw c.name="Invariant Violation",c}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:o};return n.PropTypes=n,n}},139:function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},14:function(e,t,n){e.exports=n(137)},140:function(e,t,n){var r=n(79);e.exports=function(e){if(Array.isArray(e))return r(e)}},141:function(e,t){e.exports=function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}},142:function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}},143:function(e,t,n){"use strict";var r=Object.keys;e.exports=function(e,t){var n,o,i,a,c;if(e===t)return!0;if(n=r(e),o=r(t),n.length!==o.length)return!1;for(i=0;ie.clientHeight){var t=r(e).overflowY;if(/(auto|scroll)/.test(t))return e}return i(e.parentNode)}}},159:function(e,t,n){"use strict";var r=n(21),o=n(22),i=n(23),a=n(24),c=n(10),u=n(0),s=n(2),l=n(136),f=n(135);function d(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=Object(c.a)(e);if(t){var o=Object(c.a)(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return Object(a.a)(this,n)}}var p=function(e){Object(i.a)(n,e);var t=d(n);function n(){var e;return Object(r.a)(this,n),(e=t.apply(this,arguments)).delayedSetIsOver=Object(s.debounce)((function(t){return e.setState({isOver:t})}),700),e.cancelIsMouseDown=e.createSetIsMouseDown(!1),e.isInMouseDown=!1,e.state={isOver:!1},e}return Object(o.a)(n,[{key:"componentWillUnmount",value:function(){this.delayedSetIsOver.cancel(),document.removeEventListener("mouseup",this.cancelIsMouseDown)}},{key:"emitToChild",value:function(e,t){var n=this.props.children;if(1===u.Children.count(n)){var r=u.Children.only(n);"function"==typeof r.props[e]&&r.props[e](t)}}},{key:"createToggleIsOver",value:function(e,t){var n=this;return function(r){if(n.emitToChild(e,r),!(r.currentTarget.disabled||"focus"===r.type&&n.isInMouseDown)){n.delayedSetIsOver.cancel();var o=Object(s.includes)(["focus","mouseenter"],r.type);o!==n.state.isOver&&(t?n.delayedSetIsOver(o):n.setState({isOver:o}))}}}},{key:"createSetIsMouseDown",value:function(e){var t=this;return function(n){t.emitToChild(e?"onMouseDown":"onMouseUp",n),document[e?"addEventListener":"removeEventListener"]("mouseup",t.cancelIsMouseDown),t.isInMouseDown=e}}},{key:"render",value:function(){var e=this.props,t=e.children,n=e.position,r=e.text,o=e.shortcut;if(1!==u.Children.count(t))return t;var i=u.Children.only(t),a=this.state.isOver;return Object(u.cloneElement)(i,{onMouseEnter:this.createToggleIsOver("onMouseEnter",!0),onMouseLeave:this.createToggleIsOver("onMouseLeave"),onClick:this.createToggleIsOver("onClick"),onFocus:this.createToggleIsOver("onFocus"),onBlur:this.createToggleIsOver("onBlur"),onMouseDown:this.createSetIsMouseDown(!0),children:Object(u.concatChildren)(i.props.children,a&&Object(u.createElement)(l.a,{focusOnMount:!1,position:n,className:"components-tooltip","aria-hidden":"true",animate:!1,noArrow:!0},r,Object(u.createElement)(f.a,{className:"components-tooltip__shortcut",shortcut:o})))})}}]),n}(u.Component);t.a=p},16:function(e,t){!function(){e.exports=this.moment}()},160:function(e,t,n){!function(t){var n=/^\s+/,r=/\s+$/,o=0,i=t.round,a=t.min,c=t.max,u=t.random;function s(e,u){if(u=u||{},(e=e||"")instanceof s)return e;if(!(this instanceof s))return new s(e,u);var l=function(e){var o={r:0,g:0,b:0},i=1,u=null,s=null,l=null,f=!1,d=!1;"string"==typeof e&&(e=function(e){e=e.replace(n,"").replace(r,"").toLowerCase();var t,o=!1;if(C[e])e=C[e],o=!0;else if("transparent"==e)return{r:0,g:0,b:0,a:0,format:"name"};if(t=H.rgb.exec(e))return{r:t[1],g:t[2],b:t[3]};if(t=H.rgba.exec(e))return{r:t[1],g:t[2],b:t[3],a:t[4]};if(t=H.hsl.exec(e))return{h:t[1],s:t[2],l:t[3]};if(t=H.hsla.exec(e))return{h:t[1],s:t[2],l:t[3],a:t[4]};if(t=H.hsv.exec(e))return{h:t[1],s:t[2],v:t[3]};if(t=H.hsva.exec(e))return{h:t[1],s:t[2],v:t[3],a:t[4]};if(t=H.hex8.exec(e))return{r:R(t[1]),g:R(t[2]),b:R(t[3]),a:L(t[4]),format:o?"name":"hex8"};if(t=H.hex6.exec(e))return{r:R(t[1]),g:R(t[2]),b:R(t[3]),format:o?"name":"hex"};if(t=H.hex4.exec(e))return{r:R(t[1]+""+t[1]),g:R(t[2]+""+t[2]),b:R(t[3]+""+t[3]),a:L(t[4]+""+t[4]),format:o?"name":"hex8"};if(t=H.hex3.exec(e))return{r:R(t[1]+""+t[1]),g:R(t[2]+""+t[2]),b:R(t[3]+""+t[3]),format:o?"name":"hex"};return!1}(e));"object"==typeof e&&(B(e.r)&&B(e.g)&&B(e.b)?(p=e.r,m=e.g,h=e.b,o={r:255*A(p,255),g:255*A(m,255),b:255*A(h,255)},f=!0,d="%"===String(e.r).substr(-1)?"prgb":"rgb"):B(e.h)&&B(e.s)&&B(e.v)?(u=D(e.s),s=D(e.v),o=function(e,n,r){e=6*A(e,360),n=A(n,100),r=A(r,100);var o=t.floor(e),i=e-o,a=r*(1-n),c=r*(1-i*n),u=r*(1-(1-i)*n),s=o%6;return{r:255*[r,c,a,a,u,r][s],g:255*[u,r,r,c,a,a][s],b:255*[a,a,u,r,r,c][s]}}(e.h,u,s),f=!0,d="hsv"):B(e.h)&&B(e.s)&&B(e.l)&&(u=D(e.s),l=D(e.l),o=function(e,t,n){var r,o,i;function a(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}if(e=A(e,360),t=A(t,100),n=A(n,100),0===t)r=o=i=n;else{var c=n<.5?n*(1+t):n+t-n*t,u=2*n-c;r=a(u,c,e+1/3),o=a(u,c,e),i=a(u,c,e-1/3)}return{r:255*r,g:255*o,b:255*i}}(e.h,u,l),f=!0,d="hsl"),e.hasOwnProperty("a")&&(i=e.a));var p,m,h;return i=P(i),{ok:f,format:e.format||d,r:a(255,c(o.r,0)),g:a(255,c(o.g,0)),b:a(255,c(o.b,0)),a:i}}(e);this._originalInput=e,this._r=l.r,this._g=l.g,this._b=l.b,this._a=l.a,this._roundA=i(100*this._a)/100,this._format=u.format||l.format,this._gradientType=u.gradientType,this._r<1&&(this._r=i(this._r)),this._g<1&&(this._g=i(this._g)),this._b<1&&(this._b=i(this._b)),this._ok=l.ok,this._tc_id=o++}function l(e,t,n){e=A(e,255),t=A(t,255),n=A(n,255);var r,o,i=c(e,t,n),u=a(e,t,n),s=(i+u)/2;if(i==u)r=o=0;else{var l=i-u;switch(o=s>.5?l/(2-i-u):l/(i+u),i){case e:r=(t-n)/l+(t>1)+720)%360;--t;)r.h=(r.h+o)%360,i.push(s(r));return i}function x(e,t){t=t||6;for(var n=s(e).toHsv(),r=n.h,o=n.s,i=n.v,a=[],c=1/t;t--;)a.push(s({h:r,s:o,v:i})),i=(i+c)%1;return a}s.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var e=this.toRgb();return(299*e.r+587*e.g+114*e.b)/1e3},getLuminance:function(){var e,n,r,o=this.toRgb();return e=o.r/255,n=o.g/255,r=o.b/255,.2126*(e<=.03928?e/12.92:t.pow((e+.055)/1.055,2.4))+.7152*(n<=.03928?n/12.92:t.pow((n+.055)/1.055,2.4))+.0722*(r<=.03928?r/12.92:t.pow((r+.055)/1.055,2.4))},setAlpha:function(e){return this._a=P(e),this._roundA=i(100*this._a)/100,this},toHsv:function(){var e=f(this._r,this._g,this._b);return{h:360*e.h,s:e.s,v:e.v,a:this._a}},toHsvString:function(){var e=f(this._r,this._g,this._b),t=i(360*e.h),n=i(100*e.s),r=i(100*e.v);return 1==this._a?"hsv("+t+", "+n+"%, "+r+"%)":"hsva("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHsl:function(){var e=l(this._r,this._g,this._b);return{h:360*e.h,s:e.s,l:e.l,a:this._a}},toHslString:function(){var e=l(this._r,this._g,this._b),t=i(360*e.h),n=i(100*e.s),r=i(100*e.l);return 1==this._a?"hsl("+t+", "+n+"%, "+r+"%)":"hsla("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHex:function(e){return d(this._r,this._g,this._b,e)},toHexString:function(e){return"#"+this.toHex(e)},toHex8:function(e){return function(e,t,n,r,o){var a=[T(i(e).toString(16)),T(i(t).toString(16)),T(i(n).toString(16)),T(M(r))];if(o&&a[0].charAt(0)==a[0].charAt(1)&&a[1].charAt(0)==a[1].charAt(1)&&a[2].charAt(0)==a[2].charAt(1)&&a[3].charAt(0)==a[3].charAt(1))return a[0].charAt(0)+a[1].charAt(0)+a[2].charAt(0)+a[3].charAt(0);return a.join("")}(this._r,this._g,this._b,this._a,e)},toHex8String:function(e){return"#"+this.toHex8(e)},toRgb:function(){return{r:i(this._r),g:i(this._g),b:i(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+i(this._r)+", "+i(this._g)+", "+i(this._b)+")":"rgba("+i(this._r)+", "+i(this._g)+", "+i(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:i(100*A(this._r,255))+"%",g:i(100*A(this._g,255))+"%",b:i(100*A(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+i(100*A(this._r,255))+"%, "+i(100*A(this._g,255))+"%, "+i(100*A(this._b,255))+"%)":"rgba("+i(100*A(this._r,255))+"%, "+i(100*A(this._g,255))+"%, "+i(100*A(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(S[d(this._r,this._g,this._b,!0)]||!1)},toFilter:function(e){var t="#"+p(this._r,this._g,this._b,this._a),n=t,r=this._gradientType?"GradientType = 1, ":"";if(e){var o=s(e);n="#"+p(o._r,o._g,o._b,o._a)}return"progid:DXImageTransform.Microsoft.gradient("+r+"startColorstr="+t+",endColorstr="+n+")"},toString:function(e){var t=!!e;e=e||this._format;var n=!1,r=this._a<1&&this._a>=0;return t||!r||"hex"!==e&&"hex6"!==e&&"hex3"!==e&&"hex4"!==e&&"hex8"!==e&&"name"!==e?("rgb"===e&&(n=this.toRgbString()),"prgb"===e&&(n=this.toPercentageRgbString()),"hex"!==e&&"hex6"!==e||(n=this.toHexString()),"hex3"===e&&(n=this.toHexString(!0)),"hex4"===e&&(n=this.toHex8String(!0)),"hex8"===e&&(n=this.toHex8String()),"name"===e&&(n=this.toName()),"hsl"===e&&(n=this.toHslString()),"hsv"===e&&(n=this.toHsvString()),n||this.toHexString()):"name"===e&&0===this._a?this.toName():this.toRgbString()},clone:function(){return s(this.toString())},_applyModification:function(e,t){var n=e.apply(null,[this].concat([].slice.call(t)));return this._r=n._r,this._g=n._g,this._b=n._b,this.setAlpha(n._a),this},lighten:function(){return this._applyModification(v,arguments)},brighten:function(){return this._applyModification(g,arguments)},darken:function(){return this._applyModification(y,arguments)},desaturate:function(){return this._applyModification(m,arguments)},saturate:function(){return this._applyModification(h,arguments)},greyscale:function(){return this._applyModification(b,arguments)},spin:function(){return this._applyModification(O,arguments)},_applyCombination:function(e,t){return e.apply(null,[this].concat([].slice.call(t)))},analogous:function(){return this._applyCombination(_,arguments)},complement:function(){return this._applyCombination(w,arguments)},monochromatic:function(){return this._applyCombination(x,arguments)},splitcomplement:function(){return this._applyCombination(E,arguments)},triad:function(){return this._applyCombination(j,arguments)},tetrad:function(){return this._applyCombination(k,arguments)}},s.fromRatio=function(e,t){if("object"==typeof e){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]="a"===r?e[r]:D(e[r]));e=n}return s(e,t)},s.equals=function(e,t){return!(!e||!t)&&s(e).toRgbString()==s(t).toRgbString()},s.random=function(){return s.fromRatio({r:u(),g:u(),b:u()})},s.mix=function(e,t,n){n=0===n?0:n||50;var r=s(e).toRgb(),o=s(t).toRgb(),i=n/100;return s({r:(o.r-r.r)*i+r.r,g:(o.g-r.g)*i+r.g,b:(o.b-r.b)*i+r.b,a:(o.a-r.a)*i+r.a})},s.readability=function(e,n){var r=s(e),o=s(n);return(t.max(r.getLuminance(),o.getLuminance())+.05)/(t.min(r.getLuminance(),o.getLuminance())+.05)},s.isReadable=function(e,t,n){var r,o,i=s.readability(e,t);switch(o=!1,(r=function(e){var t,n;t=((e=e||{level:"AA",size:"small"}).level||"AA").toUpperCase(),n=(e.size||"small").toLowerCase(),"AA"!==t&&"AAA"!==t&&(t="AA");"small"!==n&&"large"!==n&&(n="small");return{level:t,size:n}}(n)).level+r.size){case"AAsmall":case"AAAlarge":o=i>=4.5;break;case"AAlarge":o=i>=3;break;case"AAAsmall":o=i>=7}return o},s.mostReadable=function(e,t,n){var r,o,i,a,c=null,u=0;o=(n=n||{}).includeFallbackColors,i=n.level,a=n.size;for(var l=0;lu&&(u=r,c=s(t[l]));return s.isReadable(e,c,{level:i,size:a})||!o?c:(n.includeFallbackColors=!1,s.mostReadable(e,["#fff","#000"],n))};var C=s.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},S=s.hexNames=function(e){var t={};for(var n in e)e.hasOwnProperty(n)&&(t[e[n]]=n);return t}(C);function P(e){return e=parseFloat(e),(isNaN(e)||e<0||e>1)&&(e=1),e}function A(e,n){(function(e){return"string"==typeof e&&-1!=e.indexOf(".")&&1===parseFloat(e)})(e)&&(e="100%");var r=function(e){return"string"==typeof e&&-1!=e.indexOf("%")}(e);return e=a(n,c(0,parseFloat(e))),r&&(e=parseInt(e*n,10)/100),t.abs(e-n)<1e-6?1:e%n/parseFloat(n)}function N(e){return a(1,c(0,e))}function R(e){return parseInt(e,16)}function T(e){return 1==e.length?"0"+e:""+e}function D(e){return e<=1&&(e=100*e+"%"),e}function M(e){return t.round(255*parseFloat(e)).toString(16)}function L(e){return R(e)/255}var F,I,z,H=(I="[\\s|\\(]+("+(F="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+F+")[,|\\s]+("+F+")\\s*\\)?",z="[\\s|\\(]+("+F+")[,|\\s]+("+F+")[,|\\s]+("+F+")[,|\\s]+("+F+")\\s*\\)?",{CSS_UNIT:new RegExp(F),rgb:new RegExp("rgb"+I),rgba:new RegExp("rgba"+z),hsl:new RegExp("hsl"+I),hsla:new RegExp("hsla"+z),hsv:new RegExp("hsv"+I),hsva:new RegExp("hsva"+z),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});function B(e){return!!H.CSS_UNIT.exec(e)}e.exports?e.exports=s:"function"==typeof define&&define.amd?define((function(){return s})):window.tinycolor=s}(Math)},162:function(e,t){function n(t,r){return e.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(t,r)}e.exports=n},163:function(e,t,n){"use strict";var r=n(92),o=n(115),i=Object.prototype.hasOwnProperty,a={brackets:function(e){return e+"[]"},comma:"comma",indices:function(e,t){return e+"["+t+"]"},repeat:function(e){return e}},c=Array.isArray,u=Array.prototype.push,s=function(e,t){u.apply(e,c(t)?t:[t])},l=Date.prototype.toISOString,f=o.default,d={addQueryPrefix:!1,allowDots:!1,charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encoder:r.encode,encodeValuesOnly:!1,format:f,formatter:o.formatters[f],indices:!1,serializeDate:function(e){return l.call(e)},skipNulls:!1,strictNullHandling:!1},p=function e(t,n,o,i,a,u,l,f,p,m,h,b,v){var g,y=t;if("function"==typeof l?y=l(n,y):y instanceof Date?y=m(y):"comma"===o&&c(y)&&(y=r.maybeMap(y,(function(e){return e instanceof Date?m(e):e})).join(",")),null===y){if(i)return u&&!b?u(n,d.encoder,v,"key"):n;y=""}if("string"==typeof(g=y)||"number"==typeof g||"boolean"==typeof g||"symbol"==typeof g||"bigint"==typeof g||r.isBuffer(y))return u?[h(b?n:u(n,d.encoder,v,"key"))+"="+h(u(y,d.encoder,v,"value"))]:[h(n)+"="+h(String(y))];var O,w=[];if(void 0===y)return w;if(c(l))O=l;else{var j=Object.keys(y);O=f?j.sort(f):j}for(var k=0;k0?g+v:""}},164:function(e,t,n){"use strict";var r=n(92),o=Object.prototype.hasOwnProperty,i=Array.isArray,a={allowDots:!1,allowPrototypes:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decoder:r.decode,delimiter:"&",depth:5,ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictNullHandling:!1},c=function(e){return e.replace(/&#(\d+);/g,(function(e,t){return String.fromCharCode(parseInt(t,10))}))},u=function(e,t){return e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1?e.split(","):e},s=function(e,t,n,r){if(e){var i=n.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e,a=/(\[[^[\]]*])/g,c=n.depth>0&&/(\[[^[\]]*])/.exec(i),s=c?i.slice(0,c.index):i,l=[];if(s){if(!n.plainObjects&&o.call(Object.prototype,s)&&!n.allowPrototypes)return;l.push(s)}for(var f=0;n.depth>0&&null!==(c=a.exec(i))&&f=0;--i){var a,c=e[i];if("[]"===c&&n.parseArrays)a=[].concat(o);else{a=n.plainObjects?Object.create(null):{};var s="["===c.charAt(0)&&"]"===c.charAt(c.length-1)?c.slice(1,-1):c,l=parseInt(s,10);n.parseArrays||""!==s?!isNaN(l)&&c!==s&&String(l)===s&&l>=0&&n.parseArrays&&l<=n.arrayLimit?(a=[])[l]=o:a[s]=o:a={0:o}}o=a}return o}(l,t,n,r)}};e.exports=function(e,t){var n=function(e){if(!e)return a;if(null!==e.decoder&&void 0!==e.decoder&&"function"!=typeof e.decoder)throw new TypeError("Decoder has to be a function.");if(void 0!==e.charset&&"utf-8"!==e.charset&&"iso-8859-1"!==e.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var t=void 0===e.charset?a.charset:e.charset;return{allowDots:void 0===e.allowDots?a.allowDots:!!e.allowDots,allowPrototypes:"boolean"==typeof e.allowPrototypes?e.allowPrototypes:a.allowPrototypes,arrayLimit:"number"==typeof e.arrayLimit?e.arrayLimit:a.arrayLimit,charset:t,charsetSentinel:"boolean"==typeof e.charsetSentinel?e.charsetSentinel:a.charsetSentinel,comma:"boolean"==typeof e.comma?e.comma:a.comma,decoder:"function"==typeof e.decoder?e.decoder:a.decoder,delimiter:"string"==typeof e.delimiter||r.isRegExp(e.delimiter)?e.delimiter:a.delimiter,depth:"number"==typeof e.depth||!1===e.depth?+e.depth:a.depth,ignoreQueryPrefix:!0===e.ignoreQueryPrefix,interpretNumericEntities:"boolean"==typeof e.interpretNumericEntities?e.interpretNumericEntities:a.interpretNumericEntities,parameterLimit:"number"==typeof e.parameterLimit?e.parameterLimit:a.parameterLimit,parseArrays:!1!==e.parseArrays,plainObjects:"boolean"==typeof e.plainObjects?e.plainObjects:a.plainObjects,strictNullHandling:"boolean"==typeof e.strictNullHandling?e.strictNullHandling:a.strictNullHandling}}(t);if(""===e||null==e)return n.plainObjects?Object.create(null):{};for(var l="string"==typeof e?function(e,t){var n,s={},l=t.ignoreQueryPrefix?e.replace(/^\?/,""):e,f=t.parameterLimit===1/0?void 0:t.parameterLimit,d=l.split(t.delimiter,f),p=-1,m=t.charset;if(t.charsetSentinel)for(n=0;n-1&&(b=i(b)?[b]:b),o.call(s,h)?s[h]=r.combine(s[h],b):s[h]=b}return s}(e,n):e,f=n.plainObjects?Object.create(null):{},d=Object.keys(l),p=0;p0&&void 0!==arguments[0]?arguments[0]:"polite",t=document.createElement("div");t.id="a11y-speak-".concat(e),t.className="a11y-speak-region",t.setAttribute("style","position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"),t.setAttribute("aria-live",e),t.setAttribute("aria-relevant","additions text"),t.setAttribute("aria-atomic","true");var n=document,r=n.body;return r&&r.appendChild(t),t}var a="";function c(e,t){!function(){for(var e=document.getElementsByClassName("a11y-speak-region"),t=document.getElementById("a11y-speak-intro-text"),n=0;n]+>/g," "),a===e&&(e+=" "),a=e,e}(e);var n=document.getElementById("a11y-speak-intro-text"),r=document.getElementById("a11y-speak-assertive"),o=document.getElementById("a11y-speak-polite");r&&"assertive"===t?r.textContent=e:o&&(o.textContent=e),n&&n.removeAttribute("hidden")}Object(r.a)((function(){var e=document.getElementById("a11y-speak-intro-text"),t=document.getElementById("a11y-speak-assertive"),n=document.getElementById("a11y-speak-polite");null===e&&function(){var e=document.createElement("p");e.id="a11y-speak-intro-text",e.className="a11y-speak-intro-text",e.textContent=Object(o.__)("Notifications"),e.setAttribute("style","position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"),e.setAttribute("hidden","hidden");var t=document.body;t&&t.appendChild(e)}(),null===t&&i("assertive"),null===n&&i("polite")}))},19:function(e,t,n){var r=n(48),o=n(11);e.exports=function(e,t){return!t||"object"!==r(t)&&"function"!=typeof t?o(e):t}},190:function(e,t,n){"use strict";var r=n(41),o=n(51),i=n(67).b;function a(){var e=Object(o.a)(["\n\t","\n\t","\n"]);return a=function(){return e},e}function c(){var e=Object(o.a)(["\n\t\t\t\t","\n\t\t\t\t","\n\t\t\t"]);return c=function(){return e},e}function u(){var e=Object(o.a)(["\n\t\t\t\t","\n\t\t\t\t","\n\t\t\t"]);return u=function(){return e},e}function s(){var e=Object(o.a)(["\n\t\t\t\t","\n\t\t\t"]);return s=function(){return e},e}function l(){var e=Object(o.a)(["\n\t\t\t\t","\n\t\t\t\t","\n\t\t\t"]);return l=function(){return e},e}function f(){var e=Object(o.a)(["\n\t\t\t\t","\n\t\t\t\t","\n\t\t\t"]);return f=function(){return e},e}function d(){var e=Object(o.a)(["\n\t\t\t\t","\n\t\t\t\t","\n\t\t\t"]);return d=function(){return e},e}function p(){var e=Object(o.a)(["\n\t\t\t\t","\n\t\t\t\t","\n\t\t\t"]);return p=function(){return e},e}function m(){var e=Object(o.a)(["\n\t\t\t\t","\n\t\t\t\t","\n\t\t\t"]);return m=function(){return e},e}var h="\n ".concat("font-weight: 400;","\n"),b="\n\tfont-size: 32px;\n\tline-height: 40px;\n",v="\n\tfont-size: 24px;\n\tline-height: 32px;\n",g="\n\tfont-size: 20px;\n\tline-height: 28px;\n",y="\n\t".concat("font-weight: 600;","\n\tfont-size: 14px;\n\tline-height: 20px;\n"),O="\n\t".concat("font-weight: 400;","\n"),w="\n\tfont-size: 16px;\n\tline-height: 24px;\n",j="\n\tfont-size: 14px;\n\tline-height: 20px;\n",k="\n ".concat("font-weight: 600;","\n font-size: 14px;\n line-height: 20px;\n"),E="\n\t".concat("font-weight: 400;","\n\tfont-size: 12px;\n\tline-height: 16px;\n"),_="\n\t".concat("font-weight: 600;","\n\tfont-size: 12px;\n\tline-height: 16px;\n"),x=Object(r.a)("p",{target:"e15wbhsk0",label:"Text"})("\n\tbox-sizing: border-box;\n\tmargin: 0;\n",(function(e){return i(a(),'font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,\nOxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;',function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"body";switch(e){case"title.large":return i(m(),h,b);case"title.medium":return i(p(),h,v);case"title.small":return i(d(),h,g);case"subtitle":return i(f(),y,"\n\tfont-size: 16px;\n\tline-height: 24px;\n");case"subtitle.small":return i(l(),y,"\n\tfont-size: 14px;\n\tline-height: 20px;\n");case"body":return i(s(),O);case"body.large":return i(u(),O,w);case"body.small":return i(c(),O,j);case"button":return k;case"caption":return E;case"label":return _}}(e.variant))}),"");t.a=x},191:function(e,t,n){"use strict";n.d(t,"b",(function(){return u})),n.d(t,"c",(function(){return s})),n.d(t,"e",(function(){return l})),n.d(t,"a",(function(){return f})),n.d(t,"d",(function(){return p})),n.d(t,"f",(function(){return m}));var r=n(30),o=n.n(r),i=n(81),a=n(2),c=n(36);function u(e){return e?e.split(":")[0]:null}function s(e){var t=u(e);return Object(a.without)(Object(c.g)("onboarding",{euCountries:[]}).euCountries,"GB").includes(t)&&(t="EU"),t}function l(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2?arguments[2]:void 0,r=d(e,t,n),o=r.map((function(e){return e.id||e.product}));return o}function f(e,t){var n={};n.products=d(e,!0,t),n.remainingProducts=d(e,!1,t);var r=o()(new Set([].concat(o()(n.products),o()(n.remainingProducts))));return n.uniqueItemsList=r.map((function(e){return e.label?{type:"extension",name:e.label}:{type:"theme",name:e.title}})),n}function d(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2?arguments[2]:void 0,r=Object(c.g)("onboarding",{}),o=[];if(!r.productTypes)return o;var i=e.product_types||[];i.forEach((function(e){r.productTypes[e]&&r.productTypes[e].product&&(t||!n.includes(r.productTypes[e].slug))&&o.push(r.productTypes[e])}));var a=r.themes.find((function(t){return t.slug===e.theme}));return a&&a.id&&p(a.price)>0&&(t||!a.is_installed)&&o.push(a),o}function p(e){return Number(Object(i.decodeEntities)(e).replace(/[^0-9.-]+/g,""))}function m(e){return/admin.php\?page=wc-admin/.test(e)}},197:function(e,t){e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}},2:function(e,t){!function(){e.exports=this.lodash}()},20:function(e,t){!function(){e.exports=this.wp.data}()},21:function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}n.d(t,"a",(function(){return r}))},214:function(e,t){!function(){e.exports=this.wc.currency}()},22:function(e,t,n){"use strict";function r(e,t){for(var n=0;n=0||(o[n]=e[n]);return o}},281:function(e,t,n){"use strict";e.exports=n(307)},29:function(e,t){!function(){e.exports=this.wp.dataControls}()},292:function(e,t,n){"use strict";var r=n(3),o=n(55),i=n(0),a=n(36),c=Object(a.g)("manageStock","no"),u=Object(i.lazy)((function(){return Promise.all([n.e(1),n.e(0),n.e(20)]).then(n.bind(null,745))})),s=Object(i.lazy)((function(){return Promise.all([n.e(1),n.e(0),n.e(7),n.e(19)]).then(n.bind(null,741))})),l=Object(i.lazy)((function(){return Promise.all([n.e(1),n.e(0),n.e(23)]).then(n.bind(null,746))})),f=Object(i.lazy)((function(){return Promise.all([n.e(1),n.e(0),n.e(8),n.e(18)]).then(n.bind(null,747))})),d=Object(i.lazy)((function(){return Promise.all([n.e(1),n.e(0),n.e(7),n.e(14)]).then(n.bind(null,743))})),p=Object(i.lazy)((function(){return Promise.all([n.e(1),n.e(0),n.e(15)]).then(n.bind(null,748))})),m=Object(i.lazy)((function(){return Promise.all([n.e(1),n.e(0),n.e(22)]).then(n.bind(null,749))})),h=Object(i.lazy)((function(){return Promise.all([n.e(1),n.e(0),n.e(17)]).then(n.bind(null,750))})),b=Object(i.lazy)((function(){return Promise.all([n.e(0),n.e(21)]).then(n.bind(null,742))})),v=Object(i.lazy)((function(){return Promise.all([n.e(0),n.e(16)]).then(n.bind(null,744))}));t.a=function(){var e=[{report:"revenue",title:Object(r.__)("Revenue",'woocommerce'),component:u,id:"woocommerce-analytics-revenue"},{report:"products",title:Object(r.__)("Products",'woocommerce'),component:s,id:"woocommerce-analytics-products"},{report:"variations",title:Object(r.__)("Variations",'woocommerce'),component:l,id:"woocommerce-analytics-variations"},{report:"orders",title:Object(r.__)("Orders",'woocommerce'),component:f,id:"woocommerce-analytics-orders"},{report:"categories",title:Object(r.__)("Categories",'woocommerce'),component:d,id:"woocommerce-analytics-categories"},{report:"coupons",title:Object(r.__)("Coupons",'woocommerce'),component:p,id:"woocommerce-analytics-coupons"},{report:"taxes",title:Object(r.__)("Taxes",'woocommerce'),component:m,id:"woocommerce-analytics-taxes"},"yes"===c?{report:"stock",title:Object(r.__)("Stock",'woocommerce'),component:b,id:"woocommerce-analytics-stock"}:null,{report:"customers",title:Object(r.__)("Customers",'woocommerce'),component:v,id:null},{report:"downloads",title:Object(r.__)("Downloads",'woocommerce'),component:h,id:"woocommerce-analytics-downloads"}].filter(Boolean);return Object(o.applyFilters)("woocommerce_admin_reports_list",e)}},293:function(e,t,n){"use strict";var r=n(281),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},i={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},c={};function u(e){return r.isMemo(e)?a:c[e.$$typeof]||o}c[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},c[r.Memo]=a;var s=Object.defineProperty,l=Object.getOwnPropertyNames,f=Object.getOwnPropertySymbols,d=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var o=p(n);o&&o!==m&&e(t,o,r)}var a=l(n);f&&(a=a.concat(f(n)));for(var c=u(t),h=u(n),b=0;b20)},t=function(){a.current=window.requestAnimationFrame(e)};return window.addEventListener("scroll",t),function(){window.removeEventListener("scroll",t),window.cancelAnimationFrame(a.current)}}),[]),n}},296:function(e,t){!function(){e.exports=this.wp.plugins}()},297:function(e,t,n){"use strict";n.d(t,"c",(function(){return Mt})),n.d(t,"b",(function(){return zt})),n.d(t,"a",(function(){return Ht}));var r=n(38),o=n.n(r),i=n(62),a=n.n(i),c=n(5),u=n.n(c),s=n(17),l=n.n(s),f=n(15),d=n.n(f),p=n(18),m=n.n(p),h=n(19),b=n.n(h),v=n(9),g=n.n(v),y=n(0),O=n(277),w=n(20),j=n(56),k=n(6),E=n.n(k),_=n(1),x=n.n(_),C=n(127),S=n(537),P=n(103),A=n(7),N=n(437),R=n.n(N),T=(n(281),n(58)),D=(n(293),function(e){var t=Object(S.a)();return t.displayName=e,t}("Router")),M=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._isMounted?n.setState({location:e}):n._pendingLocation=e}))),n}Object(j.a)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){this._isMounted=!0,this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&this.unlisten()},n.render=function(){return E.a.createElement(D.Provider,{children:this.props.children||null,value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}})},t}(E.a.Component);E.a.Component;E.a.Component;var L={},F=0;function I(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,o=n.exact,i=void 0!==o&&o,a=n.strict,c=void 0!==a&&a,u=n.sensitive,s=void 0!==u&&u;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=L[n]||(L[n]={});if(r[e])return r[e];var o=[],i={regexp:R()(e,o,t),keys:o};return F<1e4&&(r[e]=i,F++),i}(n,{end:i,strict:c,sensitive:s}),o=r.regexp,a=r.keys,u=o.exec(e);if(!u)return null;var l=u[0],f=u.slice(1),d=e===l;return i&&!d?null:{path:n,url:"/"===n&&""===l?"/":l,isExact:d,params:a.reduce((function(e,t,n){return e[t.name]=f[n],e}),{})}}),null)}var z=function(e){function t(){return e.apply(this,arguments)||this}return Object(j.a)(t,e),t.prototype.render=function(){var e=this;return E.a.createElement(D.Consumer,null,(function(t){t||Object(P.a)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?I(n.pathname,e.props):t.match,o=Object(A.a)({},t,{location:n,match:r}),i=e.props,a=i.children,c=i.component,u=i.render;return Array.isArray(a)&&0===a.length&&(a=null),E.a.createElement(D.Provider,{value:o},o.match?a?"function"==typeof a?a(o):a:c?E.a.createElement(c,o):u?u(o):null:"function"==typeof a?a(o):null)}))},t}(E.a.Component);function H(e){return"/"===e.charAt(0)?e:"/"+e}function B(e,t){if(!e)return t;var n=H(e);return 0!==t.pathname.indexOf(n)?t:Object(A.a)({},t,{pathname:t.pathname.substr(n.length)})}function U(e){return"string"==typeof e?e:Object(C.d)(e)}function V(e){return function(){Object(P.a)(!1)}}function q(){}E.a.Component;var W=function(e){function t(){return e.apply(this,arguments)||this}return Object(j.a)(t,e),t.prototype.render=function(){var e=this;return E.a.createElement(D.Consumer,null,(function(t){t||Object(P.a)(!1);var n,r,o=e.props.location||t.location;return E.a.Children.forEach(e.props.children,(function(e){if(null==r&&E.a.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?I(o.pathname,Object(A.a)({},e.props,{path:i})):t.match}})),r?E.a.cloneElement(n,{location:o,computedMatch:r}):null}))},t}(E.a.Component);E.a.useContext;var $=n(2),G=n(87),K=n(77),Q=n(32),Z=n(36),Y=n(35),X=n(64),J=(n(566),n(55)),ee=n(3),te=n(292),ne=n(191);function re(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=g()(e);if(t){var o=g()(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return b()(this,n)}}var oe=Object(y.lazy)((function(){return n.e(13).then(n.bind(null,840))})),ie=Object(y.lazy)((function(){return Promise.all([n.e(3),n.e(24)]).then(n.bind(null,850))})),ae=Object(y.lazy)((function(){return n.e(31).then(n.bind(null,841))})),ce=Object(y.lazy)((function(){return Promise.all([n.e(2),n.e(4),n.e(5),n.e(6),n.e(35)]).then(n.bind(null,847))})),ue=Object(y.lazy)((function(){return Promise.all([n.e(2),n.e(5),n.e(6),n.e(39)]).then(n.bind(null,852))})),se=Object(y.lazy)((function(){return Promise.all([n.e(2),n.e(5),n.e(53),n.e(47)]).then(n.bind(null,848))})),le=function(){var e=[],t=[["",wcSettings.woocommerceTranslation]];return e.push({container:ce,path:"/",breadcrumbs:[].concat(t,[Object(ee.__)("Home",'woocommerce')]),wpOpenMenu:"toplevel_page_woocommerce",id:"home"}),window.wcAdminFeatures.analytics&&(e.push({container:ae,path:"/analytics/overview",breadcrumbs:[].concat(t,[["/analytics/overview",Object(ee.__)("Analytics",'woocommerce')],Object(ee.__)("Overview",'woocommerce')]),wpOpenMenu:"toplevel_page_wc-admin-path--analytics-overview",id:"woocommerce-analytics-overview"}),e.push({container:ie,path:"/analytics/settings",breadcrumbs:[].concat(t,[["/analytics/revenue",Object(ee.__)("Analytics",'woocommerce')],Object(ee.__)("Settings",'woocommerce')]),wpOpenMenu:"toplevel_page_wc-admin-path--analytics-overview",id:"woocommerce-analytics-settings"}),e.push({container:oe,path:"/customers",breadcrumbs:[].concat(t,[Object(ee.__)("Customers",'woocommerce')]),wpOpenMenu:"toplevel_page_woocommerce",id:"woocommerce-analytics-customers"}),e.push({container:oe,path:"/analytics/:report",breadcrumbs:function(e){var n=e.match,r=Object($.find)(Object(te.a)(),{report:n.params.report});return r?[].concat(t,[["/analytics/revenue",Object(ee.__)("Analytics",'woocommerce')],r.title]):[]},wpOpenMenu:"toplevel_page_wc-admin-path--analytics-overview"})),window.wcAdminFeatures.marketing&&e.push({container:ue,path:"/marketing",breadcrumbs:[].concat(t,[["/marketing",Object(ee.__)("Marketing",'woocommerce')],Object(ee.__)("Overview",'woocommerce')]),wpOpenMenu:"toplevel_page_woocommerce-marketing",id:"woocommerce-marketing"}),window.wcAdminFeatures.onboarding&&e.push({container:se,path:"/setup-wizard",breadcrumbs:[].concat(t,[["/setup-wizard",Object(ee.__)("Setup Wizard",'woocommerce')]])}),Object(J.applyFilters)("woocommerce_admin_pages_list",e)},fe=function(e){m()(n,e);var t=re(n);function n(){return l()(this,n),t.apply(this,arguments)}return d()(n,[{key:"componentDidMount",value:function(){window.document.documentElement.scrollTop=0,window.document.body.classList.remove("woocommerce-admin-is-loading")}},{key:"componentDidUpdate",value:function(e){var t=Object($.omit)(e.query,"chartType","filter","paged"),n=Object($.omit)(this.props.query,"chartType","filter","paged");e.query.paged>1&&!Object($.isEqual)(t,n)&&Object(Q.getHistory)().replace(Object(Q.getNewPath)({paged:1})),e.match.url!==this.props.match.url&&(window.document.documentElement.scrollTop=0)}},{key:"render",value:function(){var e=this.props,t=e.page,n=e.match,r=e.query,o=n.url,i=n.params;return window.wpNavMenuUrlUpdate(r),window.wpNavMenuClassChange(t,o),Object(y.createElement)(y.Suspense,{fallback:Object(y.createElement)(K.Spinner,null)},Object(y.createElement)(t.container,{params:i,path:o,pathMatch:t.path,query:r}))}}]),n}(y.Component);window.wpNavMenuUrlUpdate=function(e){var t=Object(J.applyFilters)("woocommerce_admin_time_excluded_screens",["stock","settings","customers","homescreen"]),n=Object(Q.getPersistedQuery)(e);Array.from(document.querySelectorAll("#adminmenu a")).forEach((function(e){return function(e,t,n){if(Object(ne.f)(e.href)){var r=Object($.last)(e.href.split("?")),o=Object(G.parse)(r),i=(o.path||"homescreen").replace("/analytics","").replace("/",""),a=n.includes(i),c="admin.php?"+Object(G.stringify)(Object.assign(o,a?{}:t));e.href=c,e.onclick=function(e){e.preventDefault(),Object(Q.getHistory)().push(c)}}}(e,n,t)}))},window.wpNavMenuClassChange=function(e,t){Array.from(document.getElementsByClassName("current")).forEach((function(e){e.classList.remove("current")})),Array.from(document.querySelectorAll(".wp-has-current-submenu")).forEach((function(e){e.classList.remove("wp-has-current-submenu"),e.classList.remove("wp-menu-open"),e.classList.remove("selected"),e.classList.add("wp-not-current-submenu"),e.classList.add("menu-top")}));var n="/"===t?"admin.php?page=wc-admin":"admin.php?page=wc-admin&path="+encodeURIComponent(t),r="/"===t?'li > a[href$="'.concat(n,'"], li > a[href*="').concat(n,'?"]'):'li > a[href*="'.concat(n,'"]'),o=document.querySelectorAll(r);if(Array.from(o).forEach((function(e){e.parentElement.classList.add("current")})),e.wpOpenMenu){var i=document.querySelector("#"+e.wpOpenMenu);i&&(i.classList.remove("wp-not-current-submenu"),i.classList.add("wp-has-current-submenu"),i.classList.add("wp-menu-open"),i.classList.add("current"))}document.querySelector("#wpwrap").classList.remove("wp-responsive-open")};var de=n(4),pe=n.n(de),me=n(81),he=n(190),be=(n(567),n(30)),ve=n.n(be),ge=n(533),ye=n.n(ge),Oe=n(72),we=n(534),je=n.n(we),ke=n(570),Ee=n(88),_e=Object(y.createElement)(Ee.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(y.createElement)(Ee.b,{fillRule:"evenodd",d:"M17.375 15.656A6.47 6.47 0 0018.5 12a6.47 6.47 0 00-.943-3.374l-1.262.813c.448.749.705 1.625.705 2.561a4.977 4.977 0 01-.887 2.844l1.262.813zm-1.951 1.87l-.813-1.261A4.976 4.976 0 0112 17c-.958 0-1.852-.27-2.613-.736l-.812 1.261A6.47 6.47 0 0012 18.5a6.47 6.47 0 003.424-.974zm-8.8-1.87A6.47 6.47 0 015.5 12c0-1.235.344-2.39.943-3.373l1.261.812A4.977 4.977 0 007 12c0 1.056.328 2.036.887 2.843l-1.262.813zm2.581-7.803A4.977 4.977 0 0112 7c1.035 0 1.996.314 2.794.853l.812-1.262A6.47 6.47 0 0012 5.5a6.47 6.47 0 00-3.607 1.092l.812 1.261zM12 20a8 8 0 100-16 8 8 0 000 16zm0-4.5a3.5 3.5 0 100-7 3.5 3.5 0 000 7z",clipRule:"evenodd"})),xe=(n(569),function(e){var t=e.height,n=void 0===t?24:t,r=e.width,o=void 0===r?24:r,i=e.hasUnread,a=void 0!==i&&i,c=pe()("woocommerce-layout__activity-panel-toggle-bubble",{"has-unread":a});return Object(y.createElement)("div",{className:c},Object(y.createElement)("svg",{height:n,width:o,viewBox:"0 0 24 24"},Object(y.createElement)("path",{d:"M18.9 2H5.1C3.4 2 2 3.4 2 5.1v10.7C2 17.6 3.4 19 5.1 19H9l6 3-1-3h4.9c1.7 0 3.1-1.4 3.1-3.1V5.1C22 3.4 20.6 2 18.9 2zm-1.5 4.5c-.4.8-.8 2.1-1 3.9-.3 1.8-.4 3.1-.3 4.1 0 .3 0 .5-.1.7-.1.2-.3.4-.6.4s-.6-.1-.9-.4c-1-1-1.8-2.6-2.4-4.6-.7 1.4-1.2 2.4-1.6 3.1-.6 1.2-1.2 1.8-1.6 1.9-.3 0-.5-.2-.8-.7-.5-1.4-1.1-4.2-1.7-8.2 0-.3 0-.5.2-.7.1-.2.4-.3.7-.4.5 0 .9.2.9.8.3 2.3.7 4.2 1.1 5.7l2.4-4.5c.2-.4.4-.6.8-.6.5 0 .8.3.9.9.3 1.4.6 2.6 1 3.7.3-2.7.8-4.7 1.4-5.9.2-.3.4-.5.7-.5.2 0 .5.1.7.2.2.2.3.4.3.6 0 .2 0 .4-.1.5z"})))});xe.propTypes={height:x.a.number,width:x.a.number,hasUnread:x.a.bool};var Ce=xe,Se=n(446);var Pe=n(34),Ae=n.n(Pe),Ne=n(761),Re=function(e){var t=e.icon,n=e.title,r=e.name,o=e.unread,i=e.selected,a=e.isPanelOpen,c=e.onTabClick,u=e.index,s=pe()("woocommerce-layout__activity-panel-tab",{"is-active":a&&i,"has-unread":o}),l=-1;(i||!a&&0===u)&&(l=null);var f="activity-panel-tab-".concat(r);return Object(y.createElement)(Oe.a,{role:"tab",className:s,tabIndex:l,"aria-selected":i,"aria-controls":"activity-panel-".concat(r),key:f,id:f,onClick:function(){c(r)}},t,n," ",o&&Object(y.createElement)("span",{className:"screen-reader-text"},Object(ee.__)("unread activity",'woocommerce')))},Te=n(8),De=n(54),Me=n(57),Le=n(535);function Fe(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ie(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=Ie(Ie({},e),t);return t.className&&e.className&&(n.className=pe()(t.className,e.className)),n}var He=function(e){var t,n=e.children,r=e.className,o=e.controls,i=e.icon,a=void 0===i?"menu":i,c=e.label,u=e.popoverProps,s=e.toggleProps,l=e.menuProps,f=e.disableOpenOnArrowDown,d=void 0!==f&&f,p=e.menuLabel,m=e.position,h=e.noIcons;if(p&&Object(Me.a)("`menuLabel` prop in `DropdownComponent`",{alternative:"`menuProps` object and its `aria-label` property",plugin:"Gutenberg"}),m&&Object(Me.a)("`position` prop in `DropdownComponent`",{alternative:"`popoverProps` object and its `position` property",plugin:"Gutenberg"}),Object($.isEmpty)(o)&&!Object($.isFunction)(n))return null;Object($.isEmpty)(o)||(t=o,Array.isArray(t[0])||(t=[t]));var b=ze({className:"components-dropdown-menu__popover",position:m},u);return Object(y.createElement)(Le.a,{className:pe()("components-dropdown-menu",r),popoverProps:b,renderToggle:function(e){var t,n=e.isOpen,r=e.onToggle,o=ze({className:pe()("components-dropdown-menu__toggle",{"is-opened":n})},s);return Object(y.createElement)(Oe.a,Object(A.a)({},o,{icon:a,onClick:function(e){r(e),o.onClick&&o.onClick(e)},onKeyDown:function(e){!function(e){d||n||e.keyCode!==De.a||(e.preventDefault(),e.stopPropagation(),r())}(e),o.onKeyDown&&o.onKeyDown(e)},"aria-haspopup":"true","aria-expanded":n,label:c,showTooltip:null===(t=null==s?void 0:s.showTooltip)||void 0===t||t}),o.children)},renderContent:function(e){var r=ze({"aria-label":p||c,className:pe()("components-dropdown-menu__menu",{"no-icons":h})},l);return Object(y.createElement)(Ne.a,Object(A.a)({},r,{role:"menu"}),Object($.isFunction)(n)?n(e):null,Object($.flatMap)(t,(function(t,n){return t.map((function(t,r){return Object(y.createElement)(Oe.a,{key:[n,r].join(),onClick:function(n){n.stopPropagation(),e.onClose(),t.onClick&&t.onClick()},className:pe()("components-dropdown-menu__menu-item",{"has-separator":n>0&&0===r,"is-active":t.isActive}),icon:t.icon,"aria-checked":"menuitemcheckbox"===t.role||"menuitemradio"===t.role?t.isActive:void 0,role:"menuitemcheckbox"===t.role||"menuitemradio"===t.role?t.role:"menuitem",disabled:t.isDisabled},t.title)}))})))}})},Be=n(300);var Ue=function e(t){var n=t.children,r=t.className,o=void 0===r?"":r,i=t.label,a=Object(Be.a)(e);if(!y.Children.count(n))return null;var c="components-menu-group-label-".concat(a),u=pe()(o,"components-menu-group");return Object(y.createElement)("div",{className:u},i&&Object(y.createElement)("div",{className:"components-menu-group__label",id:c,"aria-hidden":"true"},i),Object(y.createElement)("div",{role:"group","aria-labelledby":i?c:null},n))},Ve=n(759),qe=n(12),We=n(135),$e=n(133);var Ge=Object(y.forwardRef)((function(e,t){var n=e.children,r=e.info,o=e.className,i=e.icon,a=e.shortcut,c=e.isSelected,u=e.role,s=void 0===u?"menuitem":u,l=Object(qe.a)(e,["children","info","className","icon","shortcut","isSelected","role"]);return o=pe()("components-menu-item__button",o),r&&(n=Object(y.createElement)("span",{className:"components-menu-item__info-wrapper"},n,Object(y.createElement)("span",{className:"components-menu-item__info"},r))),i&&!Object($.isString)(i)&&(i=Object(y.cloneElement)(i,{className:"components-menu-items__item-icon"})),Object(y.createElement)(Oe.a,Object(A.a)({ref:t,"aria-checked":"menuitemcheckbox"===s||"menuitemradio"===s?c:void 0,role:s,className:o},l),n,Object(y.createElement)(We.a,{className:"components-menu-item__shortcut",shortcut:a}),i&&Object(y.createElement)($e.a,{icon:i}))}));function Ke(e){var t=e.choices,n=void 0===t?[]:t,r=e.onHover,o=void 0===r?$.noop:r,i=e.onSelect,a=e.value;return n.map((function(e){var t=a===e.value;return Object(y.createElement)(Ge,{key:e.value,role:"menuitemradio",icon:t&&Ve.a,isSelected:t,shortcut:e.shortcut,className:"components-menu-items-choice",onClick:function(){t||i(e.value)},onMouseEnter:function(){return o(e.value)},onMouseLeave:function(){return o(null)}},e.label)}))}var Qe=function(){return Object(y.createElement)(y.Fragment,null,Object(y.createElement)("svg",{className:"woocommerce-layout__activity-panel-tab-icon",width:"24",height:"24",viewBox:"3 3 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(y.createElement)("path",{d:"M13.8053 15.3982C13.8053 15.7965 13.4867 16.1947 13.0089 16.1947H6.79646C6.55752 16.1947 6.39823 16.115 6.23894 15.9558C6.07965 15.7965 6 15.6372 6 15.3982V6.79646C6 6.63717 6.15929 6.39823 6.23894 6.23894C6.39823 6.07965 6.55752 6 6.79646 6H13.0089C13.4071 6 13.8053 6.31858 13.8053 6.79646V15.3982Z",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),Object(y.createElement)("path",{d:"M23.9203 10.6195C23.9203 11.0177 23.6017 11.4159 23.1238 11.4159H16.9115C16.6725 11.4159 16.5132 11.3363 16.3539 11.177C16.1946 11.0177 16.115 10.8584 16.115 10.6195V6.79646C16.115 6.39823 16.4336 6 16.9115 6H23.1238C23.5221 6 23.9203 6.31858 23.9203 6.79646V10.6195Z",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),Object(y.createElement)("path",{d:"M13.8053 23.2035C13.8053 23.4424 13.7257 23.6017 13.5664 23.761C13.4071 23.9203 13.2478 23.9999 13.0089 23.9999H6.79646C6.39823 23.9999 6 23.6813 6 23.2035V19.3804C6 19.1415 6.07965 18.9822 6.23894 18.8229C6.39823 18.6636 6.55752 18.584 6.79646 18.584H13.0089C13.4071 18.584 13.8053 18.9026 13.8053 19.3804V23.2035Z",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),Object(y.createElement)("path",{d:"M16.9912 23.9999C16.7522 23.9999 16.5929 23.9202 16.4336 23.7609C16.2743 23.6016 16.1947 23.4423 16.1947 23.2034V14.6016C16.1947 14.3627 16.2743 14.2034 16.4336 14.0441C16.5929 13.8848 16.7522 13.8052 16.9912 13.8052H23.2036C23.4425 13.8052 23.6018 13.8848 23.7611 14.0441C23.9204 14.2034 24 14.3627 24 14.6016V23.2034C24 23.6016 23.6814 23.9999 23.2036 23.9999H16.9912Z",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})),Object(ee.__)("Display",'woocommerce'))},Ze=[{value:"single_column",label:Object(y.createElement)(y.Fragment,null,Object(y.createElement)((function(){return Object(y.createElement)("svg",{className:"woocommerce-layout__activity-panel-tab-icon",width:"12",height:"14",viewBox:"0 0 12 14",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(y.createElement)("rect",{x:"0.5",y:"0.5",width:"11",height:"13",strokeWidth:"1"}))}),null),Object(ee.__)("Single column",'woocommerce'))},{value:"two_columns",label:Object(y.createElement)(y.Fragment,null,Object(y.createElement)((function(){return Object(y.createElement)("svg",{className:"woocommerce-layout__activity-panel-tab-icon",width:"18",height:"14",viewBox:"0 0 18 14",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(y.createElement)("rect",{x:"0.5",y:"0.5",width:"7",height:"13",strokeWidth:"1"}),Object(y.createElement)("rect",{x:"9.5",y:"0.5",width:"7",height:"13",strokeWidth:"1"}))}),null),Object(ee.__)("Two columns",'woocommerce'))}],Ye=function(){var e=Object(w.useSelect)((function(e){return(0,e(Y.OPTIONS_STORE_NAME).getOption)("woocommerce_default_homepage_layout")||"single_column"})),t=Object(Y.useUserPreferences)(),n=t.updateUserPreferences,r=t.homepage_layout;return Object(y.createElement)(He,{icon:Object(y.createElement)(Qe,null),label:Object(ee.__)("Display options",'woocommerce'),toggleProps:{className:"woocommerce-layout__activity-panel-tab display-options",onClick:function(){return Object(X.recordEvent)("homescreen_display_click")}},popoverProps:{className:"woocommerce-layout__activity-panel-popover"}},(function(t){var o=t.onClose;return Object(y.createElement)(Ue,{className:"woocommerce-layout__homescreen-display-options",label:Object(ee.__)("Layout",'woocommerce')},Object(y.createElement)(Ke,{choices:Ze,onSelect:function(e){n({homepage_layout:e}),o(),Object(X.recordEvent)("homescreen_display_option",{display_option:e})},value:r||e}))}))},Xe=function(e){var t=e.tabs,n=e.onTabClick,r=e.selectedTab,i=e.showDisplayOptions,a=e.tabOpen,c=void 0!==a&&a,u=Object(y.useState)({tabOpen:c,currentTab:r}),s=Ae()(u,2),l=s[0],f=l.tabOpen,d=l.currentTab,p=s[1];return Object(y.useEffect)((function(){p({tabOpen:c,currentTab:r})}),[c,r]),Object(y.createElement)(Ne.a,{role:"tablist",orientation:"horizontal",className:"woocommerce-layout__activity-panel-tabs"},t&&t.map((function(e,t){return Object(y.createElement)(Re,o()({key:t,index:t,isPanelOpen:f,selected:d===e.name},e,{onTabClick:function(){var t=d!==e.name&&""!==d||!f;t&&d===e.name||Object(X.recordEvent)("activity_panel_open",{tab:e.name}),p({tabOpen:t,currentTab:e.name}),n(e,t)}}))})),i&&Object(y.createElement)(Ye,null))},Je=function(){return Object(y.createElement)("svg",{className:"woocommerce-layout__activity-panel-tab-icon setup-progress",width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(y.createElement)("path",{d:"M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20Z",stroke:"#DCDCDE",strokeWidth:"2"}),Object(y.createElement)("path",{d:"M4 12V12C4 16.4183 7.58172 20 12 20V20C16.4183 20 20 16.4183 20 12V12C20 7.58172 16.4183 4 12 4V4",strokeWidth:"2",strokeLinecap:"round"}))};function et(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=g()(e);if(t){var o=g()(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return b()(this,n)}}var tt=Object(y.lazy)((function(){return Promise.all([n.e(52),n.e(9),n.e(10)]).then(n.bind(null,843))})),nt=Object(y.lazy)((function(){return Promise.all([n.e(2),n.e(4),n.e(6),n.e(54),n.e(11)]).then(n.bind(null,798))})),rt=Object(y.lazy)((function(){return Promise.all([n.e(2),n.e(12)]).then(n.bind(null,856))})),ot=Object(y.lazy)((function(){return Promise.all([n.e(2),n.e(4),n.e(6),n.e(54),n.e(11)]).then(n.bind(null,845))})),it=Object(Z.g)("manageStock","no"),at=Object(Z.g)("reviewsEnabled","no"),ct=function(e){m()(n,e);var t=et(n);function n(e){var r;return l()(this,n),(r=t.call(this,e)).state={isPanelOpen:!1,mobileOpen:!1,currentTab:"",isPanelSwitching:!1},r}return d()(n,[{key:"togglePanel",value:function(e,t){var n=e.name;this.setState((function(e){var r=n!==e.currentTab&&""!==e.currentTab&&t&&e.isPanelOpen;return{isPanelOpen:t,mobileOpen:t,currentTab:n,isPanelSwitching:r}}))}},{key:"closePanel",value:function(){this.setState((function(){return{isPanelOpen:!1,currentTab:""}}))}},{key:"clearPanel",value:function(){this.setState((function(){return{isPanelSwitching:!1}}))}},{key:"toggleMobile",value:function(){var e=this.getTabs();this.setState((function(t){return{mobileOpen:!t.mobileOpen,currentTab:t.mobileOpen?"":e[0].name,isPanelOpen:!t.mobileOpen}}))}},{key:"handleClickOutside",value:function(e){var t=this.state.isPanelOpen,n=e.target.closest(".woocommerce-inbox-dismiss-confirmation_modal")||e.target.closest(".components-snackbar__action");t&&!n&&this.closePanel()}},{key:"isHomescreen",value:function(){return"/"===this.props.getHistory().location.pathname}},{key:"isPerformingSetupTask",value:function(){var e=this.props,t=e.requestingTaskListOptions,n=e.taskListComplete,r=e.taskListHidden,o=e.query,i=o.task&&!o.path&&(!0===t||!1===r&&!1===n);return i}},{key:"getTabs",value:function(){var e=this.props,t=e.hasUnreadNotes,n=e.hasUnapprovedReviews,r=e.hasUnreadStock,o=e.isEmbedded,i=e.taskListComplete,a=e.taskListHidden,c=this.isPerformingSetupTask(),u=(o||!this.isHomescreen())&&!c,s=(i||a)&&!c,l=!i&&!a&&!c&&(!this.isHomescreen()||o),f=u?{name:"inbox",title:Object(ee.__)("Inbox",'woocommerce'),icon:Object(y.createElement)("i",{className:"material-icons-outlined"},"inbox"),unread:t}:null,d=l?{name:"setup",title:Object(ee.__)("Store Setup",'woocommerce'),icon:Object(y.createElement)(Je,null)}:null,p=s?["yes"===it&&{name:"stock",title:Object(ee.__)("Stock",'woocommerce'),icon:Object(y.createElement)("i",{className:"material-icons-outlined"},"widgets"),unread:r},"yes"===at&&{name:"reviews",title:Object(ee.__)("Reviews",'woocommerce'),icon:Object(y.createElement)("i",{className:"material-icons-outlined"},"star_border"),unread:n}].filter(Boolean):[],m=c?{name:"help",title:Object(ee.__)("Help",'woocommerce'),icon:Object(y.createElement)(ke.a,{icon:_e})}:null;return[f].concat(ve()(p),[d,m]).filter(Boolean)}},{key:"getPanelContent",value:function(e){var t=this.props,n=t.query,r=t.hasUnapprovedReviews,o=n.task;switch(e){case"inbox":return Object(y.createElement)(nt,null);case"stock":return Object(y.createElement)(rt,null);case"reviews":return Object(y.createElement)(ot,{hasUnapprovedReviews:r});case"help":return Object(y.createElement)(tt,{taskName:o});default:return null}}},{key:"renderPanel",value:function(){var e=this,t=this.props,n=t.updateOptions,r=t.taskListHidden,o=this.state,i=o.isPanelOpen,a=o.currentTab,c=o.isPanelSwitching,u=Object($.find)(this.getTabs(),{name:a});if(!u)return Object(y.createElement)("div",{className:"woocommerce-layout__activity-panel-wrapper"});var s=function(){e.clearPanel()};if("display-options"===a)return null;if("setup"===a)return window.location.href!==Object(Z.f)("admin.php?page=wc-admin")&&("no"===r?this.redirectToHomeScreen():n({woocommerce_task_list_hidden:"no"}).then(this.redirectToHomeScreen)),null;var l=pe()("woocommerce-layout__activity-panel-wrapper",{"is-open":i,"is-switching":c});return Object(y.createElement)("div",{className:l,tabIndex:0,role:"tabpanel","aria-label":u.title,onTransitionEnd:s,onAnimationEnd:s},Object(y.createElement)("div",{className:"woocommerce-layout__activity-panel-content",key:"activity-panel-"+a,id:"activity-panel-"+a},Object(y.createElement)(y.Suspense,{fallback:Object(y.createElement)(K.Spinner,null)},this.getPanelContent(a))))}},{key:"redirectToHomeScreen",value:function(){Object(ne.f)(window.location.href)?Object(Q.getHistory)().push(Object(Q.getNewPath)({},"/",{})):window.location.href=Object(Z.f)("admin.php?page=wc-admin")}},{key:"render",value:function(){var e=this,t=this.getTabs(),n=this.props.isEmbedded,r=this.state,o=r.mobileOpen,i=r.currentTab,a=r.isPanelOpen,c=Object($.uniqueId)("activity-panel-header_"),u=pe()("woocommerce-layout__activity-panel",{"is-mobile-open":this.state.mobileOpen}),s=t.some((function(e){return e.unread})),l=s?Object(ee.__)("View Activity Panel, you have unread activity",'woocommerce'):Object(ee.__)("View Activity Panel",'woocommerce'),f=this.isPerformingSetupTask(),d=!n&&this.isHomescreen()&&!f;return Object(y.createElement)("div",null,Object(y.createElement)(K.H,{id:c,className:"screen-reader-text"},Object(ee.__)("Store Activity",'woocommerce')),Object(y.createElement)(K.Section,{component:"aside",id:"woocommerce-activity-panel","aria-labelledby":c},Object(y.createElement)(Oe.a,{onClick:function(){e.toggleMobile()},label:o?Object(ee.__)("Close Activity Panel",'woocommerce'):l,"aria-expanded":o,className:"woocommerce-layout__activity-panel-mobile-toggle"},o?Object(y.createElement)(je.a,null):Object(y.createElement)(Ce,{hasUnread:s})),Object(y.createElement)("div",{className:u},Object(y.createElement)(Xe,{tabs:t,tabOpen:a,selectedTab:i,onTabClick:function(t,n){e.togglePanel(t,n)},showDisplayOptions:d}),this.renderPanel())))}}]),n}(y.Component);ct.defaultProps={getHistory:Q.getHistory};var ut=Object(O.a)(Object(w.withSelect)((function(e){var t=function(e){var t=e(Y.NOTES_STORE_NAME),n=t.getNotes,r=t.getNotesError,o=t.isResolving,i=(0,e(Y.USER_STORE_NAME).getCurrentUser)(),a=parseInt(i&&i.woocommerce_meta&&i.woocommerce_meta.activity_panel_inbox_last_read,10);if(!a)return null;var c={page:1,per_page:Y.QUERY_DEFAULTS.pageSize,status:"unactioned",type:Y.QUERY_DEFAULTS.noteTypes,orderby:"date",order:"desc"},u=n(c),s=Boolean(r("getNotes",[c])),l=o("getNotes",[c]);return s||l?null:Object(Se.a)(u,a)>0}(e),n=Object(Z.g)("hasLowStock",!1),r=function(e){var t=e(Y.REVIEWS_STORE_NAME),n=t.getReviewsTotalCount,r=t.getReviewsError,o=t.isResolving;if("yes"===Object(Z.g)("reviewsEnabled")){var i={page:1,per_page:1,status:"hold"},a=n(i),c=Boolean(r(i)),u=o("getReviewsTotalCount",[i]);if(!c&&!u)return a>0}return!1}(e),o=e(Y.OPTIONS_STORE_NAME),i=o.getOption,a=o.isResolving,c="yes"===i("woocommerce_task_list_complete"),u="yes"===i("woocommerce_task_list_hidden");return{hasUnreadNotes:t,hasUnreadStock:n,hasUnapprovedReviews:r,requestingTaskListOptions:a("getOption",["woocommerce_task_list_complete"])||a("getOption",["woocommerce_task_list_hidden"]),taskListComplete:c,taskListHidden:u}})),Object(w.withDispatch)((function(e){return{updateOptions:e(Y.OPTIONS_STORE_NAME).updateOptions}})),ye.a)(ct),st=function(){return/iPhone|iPad|iPod/i.test(window.navigator.userAgent)?"ios":/Android/i.test(window.navigator.userAgent)?"android":"unknown"},lt=function(){return Object(y.createElement)("svg",{width:"37",height:"37",viewBox:"0 0 92 92",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(y.createElement)("rect",{width:"92",height:"92",rx:"21.3953",fill:"#7F54B3"}),Object(y.createElement)("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M72.5937 28.043H19.8094C16.4781 28.0459 13.7783 30.7705 13.7754 34.1324V54.4501C13.7783 57.812 16.4781 60.5366 19.8094 60.5395H44.8229L56.2573 66.9607L53.6672 60.5395H72.599C74.2009 60.5402 75.7374 59.8983 76.8702 58.7552C78.0029 57.612 78.639 56.0614 78.6383 54.4447V34.1324C78.6376 32.5157 78.0002 30.9657 76.8664 29.8235C75.7327 28.6814 74.1956 28.0408 72.5937 28.043ZM19.1057 32.4208C18.4658 32.4324 17.8646 32.7359 17.467 33.2482C17.0888 33.7635 16.9404 34.4175 17.058 35.0502C18.5962 45.0986 20.0338 51.8757 21.371 55.3816C21.8779 56.658 22.4896 57.2703 23.2063 57.2185C24.3075 57.1489 25.6263 55.5968 27.1627 52.5621C27.9964 50.8412 29.2602 48.2662 30.9539 44.837C32.3785 49.88 34.309 53.6787 36.7456 56.2331C37.4291 56.9436 38.1204 57.2748 38.8195 57.2266C39.4185 57.1931 39.953 56.8315 40.217 56.2813C40.4753 55.7358 40.5806 55.1278 40.5211 54.5248C40.3516 52.0703 40.5919 48.667 41.2421 44.3149C41.9081 39.8057 42.7523 36.5818 43.7749 34.6432C43.9822 34.2526 44.0733 33.8087 44.037 33.366C44.0039 32.7587 43.7116 32.1969 43.2374 31.829C42.7745 31.4367 42.1799 31.2446 41.5803 31.2935C40.8334 31.3325 40.1682 31.7885 39.8499 32.4797C38.2331 35.5019 37.0812 40.4109 36.3943 47.2068C35.2823 44.2394 34.4509 41.1703 33.9114 38.0412C33.623 36.4613 32.9037 35.7125 31.7536 35.7946C30.9592 35.8589 30.3063 36.3944 29.7819 37.4012L24.0348 48.5643C23.0997 44.6692 22.2205 39.9289 21.3972 34.3433C21.1997 32.9652 20.4358 32.3244 19.1057 32.4208ZM69.9089 34.6877C71.6969 35.0381 73.2407 36.2 74.1186 37.8559C74.9693 39.3247 75.3946 41.1161 75.3946 43.23C75.4148 45.9567 74.7062 48.6357 73.3477 50.9687C71.7778 53.7023 69.7195 55.0691 67.1727 55.0691C66.6933 55.0668 66.2153 55.0128 65.7467 54.9078C63.9584 54.5581 62.4143 53.396 61.5371 51.7396C60.6864 50.2452 60.261 48.4411 60.261 46.3272C60.2357 43.6127 60.945 40.9454 62.3079 38.6295C63.9023 35.8959 65.9607 34.5291 68.4829 34.5291C68.9623 34.5304 69.4402 34.5836 69.9089 34.6877ZM68.7937 49.4848C69.7707 48.5773 70.4399 47.2269 70.8012 45.4337V45.4419C70.9315 44.7826 70.9959 44.1112 70.9933 43.4382C70.986 42.5849 70.8291 41.74 70.5302 40.9452C70.1443 39.901 69.6304 39.3124 68.9884 39.1793C68.0378 38.9643 67.1239 39.5256 66.2469 40.8632C65.5812 41.8393 65.109 42.9432 64.8577 44.1106C64.7276 44.7708 64.6632 45.4432 64.6657 46.1171C64.6739 46.9677 64.8308 47.8096 65.1287 48.6019C65.5146 49.6388 66.0294 50.2274 66.6731 50.3678C67.3169 50.5081 68.0237 50.2138 68.7937 49.4848ZM57.9079 37.8559C57.0291 36.2008 55.4854 35.0392 53.6976 34.6877C53.2279 34.5837 52.749 34.5306 52.2687 34.5291C49.7443 34.5291 47.6856 35.8959 46.0927 38.6295C44.7295 40.9454 44.0201 43.6127 44.0454 46.3272C44.0454 48.4411 44.4699 50.2452 45.319 51.7396C46.1976 53.3949 47.7414 54.5566 49.5294 54.9078C49.999 55.0126 50.4779 55.0667 50.9582 55.0691C53.5055 55.0691 55.5642 53.7023 57.1343 50.9687C58.4922 48.6355 59.2001 45.9565 59.1789 43.23C59.1789 41.1161 58.7544 39.3247 57.9053 37.8559H57.9079ZM54.5903 45.4337C54.2307 47.2269 53.5614 48.5773 52.5825 49.4848C51.8115 50.2065 51.101 50.5017 50.4589 50.3678C49.8169 50.2338 49.3011 49.6461 48.9169 48.6019C48.6181 47.8097 48.4603 46.9678 48.4511 46.1171C48.4495 45.4431 48.5148 44.7707 48.6459 44.1106C48.8971 42.9432 49.3694 41.8393 50.0353 40.8632C50.9124 39.5256 51.8264 38.9643 52.7773 39.1793C53.4193 39.3124 53.9333 39.901 54.3193 40.9452C54.617 41.7404 54.7739 42.585 54.7824 43.4382C54.785 44.1112 54.7207 44.7826 54.5903 45.4419V45.4337Z",fill:"white"}))},ft=(n(571),function(e){var t=e.onInstall,n=e.onDismiss;Object(y.useEffect)((function(){var e=document.getElementsByClassName("woocommerce-layout")[0];return"android"===st()&&e&&e.classList.add("woocommerce-layout__show-app-banner"),function(){e&&e.classList.remove("woocommerce-layout__show-app-banner")}}),[]);var r=Object(y.useState)(!1),o=Ae()(r,2),i=o[0],a=o[1];return"android"!==st()||i?null:Object(y.createElement)("div",{className:"woocommerce-mobile-app-banner"},Object(y.createElement)($e.a,{icon:"no-alt","data-testid":"dismiss-btn",onClick:function(){n(),a(!0),Object(X.recordEvent)("wcadmin_mobile_android_banner_click",{action:"dismiss"})}}),Object(y.createElement)(lt,null),Object(y.createElement)("div",{className:"woocommerce-mobile-app-banner__description"},Object(y.createElement)("p",{className:"woocommerce-mobile-app-banner__description__text"},Object(ee.__)("Run your store from anywhere",'woocommerce')),Object(y.createElement)("p",{className:"woocommerce-mobile-app-banner__description__text"},Object(ee.__)("Download the WooCommerce app",'woocommerce'))),Object(y.createElement)(Oe.a,{href:"https://play.google.com/store/apps/details?id=com.woocommerce.android",isSecondary:!0,onClick:function(){t(),a(!0),Object(X.recordEvent)("wcadmin_mobile_android_banner_click",{action:"install"})}},Object(ee.__)("Install",'woocommerce')))}),dt=n(295),pt=function(e){var t=e.sections,n=e.isEmbedded,r=void 0!==n&&n,o=e.query,i=Object(y.useRef)(null),c=Object(Z.g)("siteTitle",""),u=t.slice(-1)[0],s=Object(dt.a)(),l=Object(Y.useUserPreferences)(),f=l.updateUserPreferences,d="yes"===a()(l,["updateUserPreferences"]).android_app_banner_dismissed,p=pe()("woocommerce-layout__header",{"is-scrolled":s});Object(y.useEffect)((function(){if(!r){var e=t.map((function(e){return Array.isArray(e)?e[1]:e})).reverse().join(" ‹ "),n=Object(me.decodeEntities)(Object(ee.sprintf)(Object(ee.__)("%1$s ‹ %2$s — WooCommerce",'woocommerce'),e,c));document.title!==n&&(document.title=n)}}),[r,t,c]);var m=function(){f({android_app_banner_dismissed:"yes"})};return Object(y.createElement)("div",{className:p,ref:i},!d&&Object(y.createElement)(ft,{onDismiss:m,onInstall:m}),Object(y.createElement)(he.a,{className:"woocommerce-layout__header-heading",as:"h1",variant:"subtitle.small"},Object(me.decodeEntities)(u)),window.wcAdminFeatures["activity-panels"]&&Object(y.createElement)(ut,{isEmbedded:r,query:o}))};function mt(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=g()(e);if(t){var o=g()(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return b()(this,n)}}var ht=function(e){m()(n,e);var t=mt(n);function n(){return l()(this,n),t.apply(this,arguments)}return d()(n,[{key:"render",value:function(){return Object(y.createElement)("div",{id:"woocommerce-layout__notice-list",className:"woocommerce-layout__notice-list"})}}]),n}(y.Component),bt=n(14),vt=n.n(bt);function gt(e,t,n,r,o,i,a){try{var c=e[i](a),u=c.value}catch(e){return void n(e)}c.done?t(u):Promise.resolve(u).then(r,o)}function yt(e){return function(){var t=this,n=arguments;return new Promise((function(r,o){var i=e.apply(t,n);function a(e){gt(i,r,o,a,c,"next",e)}function c(e){gt(i,r,o,a,c,"throw",e)}a(void 0)}))}}var Ot=n(26),wt=n(436),jt=n(760),kt=n(536);var Et=function(e){var t=e.notices,n=e.className,r=e.children,o=e.onRemove,i=void 0===o?$.noop:o,a=Object(jt.a)(),c=Object(y.useState)((function(){return new WeakMap})),u=Object(Ot.a)(c,1)[0],s=Object(wt.useTransition)(t,(function(e){return e.id}),{from:{opacity:0,height:0},enter:function(e){return function(){var t=yt(vt.a.mark((function t(n){return vt.a.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,n({opacity:1,height:u.get(e).offsetHeight});case 2:return t.abrupt("return",t.sent);case 3:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}()},leave:function(){return function(){var e=yt(vt.a.mark((function e(t){return vt.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,t({opacity:0});case 2:return e.next=4,t({height:0});case 4:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()},immediate:a});n=pe()("components-snackbar-list",n);var l=function(e){return function(){return i(e.id)}};return Object(y.createElement)("div",{className:n},r,s.map((function(e){var t=e.item,n=e.key,r=e.props;return Object(y.createElement)(wt.animated.div,{key:n,style:r},Object(y.createElement)("div",{className:"components-snackbar-list__notice-container",ref:function(e){return e&&u.set(t,e)}},Object(y.createElement)(kt.a,Object(A.a)({},Object($.omit)(t,["content"]),{onRemove:l(t)}),t.content)))})))};n(572);function _t(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=g()(e);if(t){var o=g()(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return b()(this,n)}}var xt=function(e){m()(n,e);var t=_t(n);function n(){return l()(this,n),t.apply(this,arguments)}return d()(n,[{key:"render",value:function(){var e=this.props,t=e.className,n=e.notices,r=e.onRemove,o=pe()("woocommerce-transient-notices","components-notices__snackbar",t);return Object(y.createElement)(Et,{notices:n,className:o,onRemove:r})}}]),n}(y.Component);xt.propTypes={className:x.a.string,notices:x.a.array};var Ct=Object(O.a)(Object(w.withSelect)((function(e){return{notices:e("core/notices").getNotices()}})),Object(w.withDispatch)((function(e){return{onRemove:e("core/notices").removeNotice}})))(xt),St=n(296);function Pt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function At(e){for(var t=1;t=":"min-width","<":"max-width"},c={">=":function(e,t){return t>=e},"<":function(e,t){return t1&&void 0!==arguments[1]?arguments[1]:">=",n=Object(r.useContext)(u),s=!n&&"(".concat(a[t],": ").concat(i[e],"px)"),l=Object(o.a)(s);return n?c[t](i[e],n):l};s.__experimentalWidthProvider=u.Provider,t.a=s},307:function(e,t,n){"use strict";var r="function"==typeof Symbol&&Symbol.for,o=r?Symbol.for("react.element"):60103,i=r?Symbol.for("react.portal"):60106,a=r?Symbol.for("react.fragment"):60107,c=r?Symbol.for("react.strict_mode"):60108,u=r?Symbol.for("react.profiler"):60114,s=r?Symbol.for("react.provider"):60109,l=r?Symbol.for("react.context"):60110,f=r?Symbol.for("react.async_mode"):60111,d=r?Symbol.for("react.concurrent_mode"):60111,p=r?Symbol.for("react.forward_ref"):60112,m=r?Symbol.for("react.suspense"):60113,h=r?Symbol.for("react.suspense_list"):60120,b=r?Symbol.for("react.memo"):60115,v=r?Symbol.for("react.lazy"):60116,g=r?Symbol.for("react.block"):60121,y=r?Symbol.for("react.fundamental"):60117,O=r?Symbol.for("react.responder"):60118,w=r?Symbol.for("react.scope"):60119;function j(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case o:switch(e=e.type){case f:case d:case a:case u:case c:case m:return e;default:switch(e=e&&e.$$typeof){case l:case p:case v:case b:case s:return e;default:return t}}case i:return t}}}function k(e){return j(e)===d}t.AsyncMode=f,t.ConcurrentMode=d,t.ContextConsumer=l,t.ContextProvider=s,t.Element=o,t.ForwardRef=p,t.Fragment=a,t.Lazy=v,t.Memo=b,t.Portal=i,t.Profiler=u,t.StrictMode=c,t.Suspense=m,t.isAsyncMode=function(e){return k(e)||j(e)===f},t.isConcurrentMode=k,t.isContextConsumer=function(e){return j(e)===l},t.isContextProvider=function(e){return j(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===o},t.isForwardRef=function(e){return j(e)===p},t.isFragment=function(e){return j(e)===a},t.isLazy=function(e){return j(e)===v},t.isMemo=function(e){return j(e)===b},t.isPortal=function(e){return j(e)===i},t.isProfiler=function(e){return j(e)===u},t.isStrictMode=function(e){return j(e)===c},t.isSuspense=function(e){return j(e)===m},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===d||e===u||e===c||e===m||e===h||"object"==typeof e&&null!==e&&(e.$$typeof===v||e.$$typeof===b||e.$$typeof===s||e.$$typeof===l||e.$$typeof===p||e.$$typeof===y||e.$$typeof===O||e.$$typeof===w||e.$$typeof===g)},t.typeOf=j},31:function(e,t,n){"use strict";n.d(t,"b",(function(){return c})),n.d(t,"a",(function(){return u}));var r=n(2),o=n(160),i=n.n(o),a=n(91);function c(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=i()(e).toRgb(),r=n.r,o=n.g,a=n.b;return"rgba(".concat(r,", ").concat(o,", ").concat(a,", ").concat(t,")")}function u(e){return Object(r.get)(a.a,e,"#000")}},32:function(e,t){!function(){e.exports=this.wc.navigation}()},33:function(e,t){var n,r,o=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function c(e){if(n===setTimeout)return setTimeout(e,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(e){n=i}try{r="function"==typeof clearTimeout?clearTimeout:a}catch(e){r=a}}();var u,s=[],l=!1,f=-1;function d(){l&&u&&(l=!1,u.length?s=u.concat(s):f=-1,s.length&&p())}function p(){if(!l){var e=c(d);l=!0;for(var t=s.length;t;){for(u=s,s=[];++f1)for(var n=1;n1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(e){return e};if(a.includes(e))throw new Error(Object(i.__)("Mutable settings should be accessed via data store."));var r=u.hasOwnProperty(e)?u[e]:t;return n(r,t)}function h(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(e){return e};if(a.includes(e))throw new Error(Object(i.__)("Mutable settings should be mutated via data store."));u[e]=n(t)}function b(e){return(s||"")+e}},37:function(e,t){!function(){e.exports=this.wp.url}()},38:function(e,t){function n(){return e.exports=n=Object.assign||function(e){for(var t=1;t96?d:p};function h(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function b(e){for(var t=1;t1?t-1:0),r=1;r=n.length)break;i=n[o++]}else{if((o=n.next()).done)break;i=o.value}for(var a=i,c=!1,u=0;u=p.startTime+s.duration;else if(s.decay)b=m+y/(1-.998)*(1-Math.exp(-(1-.998)*(t-p.startTime))),(l=Math.abs(p.lastPosition-b)<.1)&&(h=b);else{f=void 0!==p.lastTime?p.lastTime:t,y=void 0!==p.lastVelocity?p.lastVelocity:s.initialVelocity,t>f+64&&(f=t);for(var O=Math.floor(t-f),w=0;wh:b=e);++n);return n-1}(e,i);return function(e,t,n,r,o,i,a,c,u){var s=u?u(e):e;if(sn){if("identity"===c)return s;"clamp"===c&&(s=n)}if(r===o)return r;if(t===n)return e<=t?r:o;t===-1/0?s=-s:n===1/0?s-=t:s=(s-t)/(n-t);s=i(s),r===-1/0?s=-s:o===1/0?s+=r:s=s*(o-r)+r;return s}(e,i[t],i[t+1],o[t],o[t+1],u,a,c,r.map)}}var H=function(e){function t(n,r,o,i){var a;return(a=e.call(this)||this).calc=void 0,a.payload=n instanceof y&&!(n instanceof t)?n.getPayload():Array.isArray(n)?n:[n],a.calc=z(r,o,i),a}u(t,e);var n=t.prototype;return n.getValue=function(){return this.calc.apply(this,this.payload.map((function(e){return e.getValue()})))},n.updateConfig=function(e,t,n){this.calc=z(e,t,n)},n.interpolate=function(e,n,r){return new t(this,e,n,r)},t}(y);var B=function(e){function t(t){var n;return(n=e.call(this)||this).animatedStyles=new Set,n.value=void 0,n.startPosition=void 0,n.lastPosition=void 0,n.lastVelocity=void 0,n.startTime=void 0,n.lastTime=void 0,n.done=!1,n.setValue=function(e,t){void 0===t&&(t=!0),n.value=e,t&&n.flush()},n.value=t,n.startPosition=t,n.lastPosition=t,n}u(t,e);var n=t.prototype;return n.flush=function(){0===this.animatedStyles.size&&function e(t,n){"update"in t?n.add(t):t.getChildren().forEach((function(t){return e(t,n)}))}(this,this.animatedStyles),this.animatedStyles.forEach((function(e){return e.update()}))},n.clearStyles=function(){this.animatedStyles.clear()},n.getValue=function(){return this.value},n.interpolate=function(e,t,n){return new H(this,e,t,n)},t}(g),U=function(e){function t(t){var n;return(n=e.call(this)||this).payload=t.map((function(e){return new B(e)})),n}u(t,e);var n=t.prototype;return n.setValue=function(e,t){var n=this;void 0===t&&(t=!0),Array.isArray(e)?e.length===this.payload.length&&e.forEach((function(e,r){return n.payload[r].setValue(e,t)})):this.payload.forEach((function(n){return n.setValue(e,t)}))},n.getValue=function(){return this.payload.map((function(e){return e.getValue()}))},n.interpolate=function(e,t){return new H(this,e,t)},t}(y),V=0,q=function(){function e(){var e=this;this.id=void 0,this.idle=!0,this.hasChanged=!1,this.guid=0,this.local=0,this.props={},this.merged={},this.animations={},this.interpolations={},this.values={},this.configs=[],this.listeners=[],this.queue=[],this.localQueue=void 0,this.getValues=function(){return e.interpolations},this.id=V++}var t=e.prototype;return t.update=function(e){if(!e)return this;var t=h(e),n=t.delay,r=void 0===n?0:n,a=t.to,c=i(t,["delay","to"]);if(l.arr(a)||l.fun(a))this.queue.push(o({},c,{delay:r,to:a}));else if(a){var u={};Object.entries(a).forEach((function(e){var t,n=e[0],i=e[1],a=o({to:(t={},t[n]=i,t),delay:m(r,n)},c),s=u[a.delay]&&u[a.delay].to;u[a.delay]=o({},u[a.delay],a,{to:o({},s,a.to)})})),this.queue=Object.values(u)}return this.queue=this.queue.sort((function(e,t){return e.delay-t.delay})),this.diff(c),this},t.start=function(e){var t,n=this;if(this.queue.length){this.idle=!1,this.localQueue&&this.localQueue.forEach((function(e){var t=e.from,r=void 0===t?{}:t,i=e.to,a=void 0===i?{}:i;l.obj(r)&&(n.merged=o({},r,n.merged)),l.obj(a)&&(n.merged=o({},n.merged,a))}));var r=this.local=++this.guid,a=this.localQueue=this.queue;this.queue=[],a.forEach((function(t,o){var c=t.delay,u=i(t,["delay"]),s=function(t){o===a.length-1&&r===n.guid&&t&&(n.idle=!0,n.props.onRest&&n.props.onRest(n.merged)),e&&e()},f=l.arr(u.to)||l.fun(u.to);c?setTimeout((function(){r===n.guid&&(f?n.runAsync(u,s):n.diff(u).start(s))}),c):f?n.runAsync(u,s):n.diff(u).start(s)}))}else l.fun(e)&&this.listeners.push(e),this.props.onStart&&this.props.onStart(),t=this,F.has(t)||F.add(t),L||(L=!0,E(N||I));return this},t.stop=function(e){return this.listeners.forEach((function(t){return t(e)})),this.listeners=[],this},t.pause=function(e){var t;return this.stop(!0),e&&(t=this,F.has(t)&&F.delete(t)),this},t.runAsync=function(e,t){var n=this,r=(e.delay,i(e,["delay"])),a=this.local,c=Promise.resolve(void 0);if(l.arr(r.to))for(var u=function(e){var t=e,i=o({},r,h(r.to[t]));l.arr(i.config)&&(i.config=i.config[t]),c=c.then((function(){if(a===n.guid)return new Promise((function(e){return n.diff(i).start(e)}))}))},s=0;s=r.length)return"break";a=r[i++]}else{if((i=r.next()).done)return"break";a=i.value}var n=a.key,c=function(e){return e.key!==n};(l.und(t)||t===n)&&(e.current.instances.delete(n),e.current.transitions=e.current.transitions.filter(c),e.current.deleted=e.current.deleted.filter(c))},r=e.current.deleted,o=Array.isArray(r),i=0;for(r=o?r:r[Symbol.iterator]();;){var a;if("break"===n())break}e.current.forceUpdate()}var Z=function(e){function t(t){var n;return void 0===t&&(t={}),n=e.call(this)||this,!t.transform||t.transform instanceof g||(t=b.transform(t)),n.payload=t,n}return u(t,e),t}(O),Y={transparent:0,aliceblue:4042850303,antiquewhite:4209760255,aqua:16777215,aquamarine:2147472639,azure:4043309055,beige:4126530815,bisque:4293182719,black:255,blanchedalmond:4293643775,blue:65535,blueviolet:2318131967,brown:2771004159,burlywood:3736635391,burntsienna:3934150143,cadetblue:1604231423,chartreuse:2147418367,chocolate:3530104575,coral:4286533887,cornflowerblue:1687547391,cornsilk:4294499583,crimson:3692313855,cyan:16777215,darkblue:35839,darkcyan:9145343,darkgoldenrod:3095792639,darkgray:2846468607,darkgreen:6553855,darkgrey:2846468607,darkkhaki:3182914559,darkmagenta:2332068863,darkolivegreen:1433087999,darkorange:4287365375,darkorchid:2570243327,darkred:2332033279,darksalmon:3918953215,darkseagreen:2411499519,darkslateblue:1211993087,darkslategray:793726975,darkslategrey:793726975,darkturquoise:13554175,darkviolet:2483082239,deeppink:4279538687,deepskyblue:12582911,dimgray:1768516095,dimgrey:1768516095,dodgerblue:512819199,firebrick:2988581631,floralwhite:4294635775,forestgreen:579543807,fuchsia:4278255615,gainsboro:3705462015,ghostwhite:4177068031,gold:4292280575,goldenrod:3668254975,gray:2155905279,green:8388863,greenyellow:2919182335,grey:2155905279,honeydew:4043305215,hotpink:4285117695,indianred:3445382399,indigo:1258324735,ivory:4294963455,khaki:4041641215,lavender:3873897215,lavenderblush:4293981695,lawngreen:2096890111,lemonchiffon:4294626815,lightblue:2916673279,lightcoral:4034953471,lightcyan:3774873599,lightgoldenrodyellow:4210742015,lightgray:3553874943,lightgreen:2431553791,lightgrey:3553874943,lightpink:4290167295,lightsalmon:4288707327,lightseagreen:548580095,lightskyblue:2278488831,lightslategray:2005441023,lightslategrey:2005441023,lightsteelblue:2965692159,lightyellow:4294959359,lime:16711935,limegreen:852308735,linen:4210091775,magenta:4278255615,maroon:2147483903,mediumaquamarine:1724754687,mediumblue:52735,mediumorchid:3126187007,mediumpurple:2473647103,mediumseagreen:1018393087,mediumslateblue:2070474495,mediumspringgreen:16423679,mediumturquoise:1221709055,mediumvioletred:3340076543,midnightblue:421097727,mintcream:4127193855,mistyrose:4293190143,moccasin:4293178879,navajowhite:4292783615,navy:33023,oldlace:4260751103,olive:2155872511,olivedrab:1804477439,orange:4289003775,orangered:4282712319,orchid:3664828159,palegoldenrod:4008225535,palegreen:2566625535,paleturquoise:2951671551,palevioletred:3681588223,papayawhip:4293907967,peachpuff:4292524543,peru:3448061951,pink:4290825215,plum:3718307327,powderblue:2967529215,purple:2147516671,rebeccapurple:1714657791,red:4278190335,rosybrown:3163525119,royalblue:1097458175,saddlebrown:2336560127,salmon:4202722047,sandybrown:4104413439,seagreen:780883967,seashell:4294307583,sienna:2689740287,silver:3233857791,skyblue:2278484991,slateblue:1784335871,slategray:1887473919,slategrey:1887473919,snow:4294638335,springgreen:16744447,steelblue:1182971135,tan:3535047935,teal:8421631,thistle:3636451583,tomato:4284696575,turquoise:1088475391,violet:4001558271,wheat:4125012991,white:4294967295,whitesmoke:4126537215,yellow:4294902015,yellowgreen:2597139199},X="[-+]?\\d*\\.?\\d+";function J(){for(var e=arguments.length,t=new Array(e),n=0;n1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}function se(e,t,n){var r=n<.5?n*(1+t):n+t-n*t,o=2*n-r,i=ue(o,r,e+1/3),a=ue(o,r,e),c=ue(o,r,e-1/3);return Math.round(255*i)<<24|Math.round(255*a)<<16|Math.round(255*c)<<8}function le(e){var t=parseInt(e,10);return t<0?0:t>255?255:t}function fe(e){return(parseFloat(e)%360+360)%360/360}function de(e){var t=parseFloat(e);return t<0?0:t>1?255:Math.round(255*t)}function pe(e){var t=parseFloat(e);return t<0?0:t>100?1:t/100}function me(e){var t,n,r="number"==typeof(t=e)?t>>>0===t&&t>=0&&t<=4294967295?t:null:(n=ae.exec(t))?parseInt(n[1]+"ff",16)>>>0:Y.hasOwnProperty(t)?Y[t]:(n=ee.exec(t))?(le(n[1])<<24|le(n[2])<<16|le(n[3])<<8|255)>>>0:(n=te.exec(t))?(le(n[1])<<24|le(n[2])<<16|le(n[3])<<8|de(n[4]))>>>0:(n=oe.exec(t))?parseInt(n[1]+n[1]+n[2]+n[2]+n[3]+n[3]+"ff",16)>>>0:(n=ce.exec(t))?parseInt(n[1],16)>>>0:(n=ie.exec(t))?parseInt(n[1]+n[1]+n[2]+n[2]+n[3]+n[3]+n[4]+n[4],16)>>>0:(n=ne.exec(t))?(255|se(fe(n[1]),pe(n[2]),pe(n[3])))>>>0:(n=re.exec(t))?(se(fe(n[1]),pe(n[2]),pe(n[3]))|de(n[4]))>>>0:null;return null===r?e:"rgba("+((4278190080&(r=r||0))>>>24)+", "+((16711680&r)>>>16)+", "+((65280&r)>>>8)+", "+(255&r)/255+")"}var he=/[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,be=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi,ve=new RegExp("("+Object.keys(Y).join("|")+")","g"),ge={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ye=["Webkit","Ms","Moz","O"];function Oe(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ge.hasOwnProperty(e)&&ge[e]?(""+t).trim():t+"px"}ge=Object.keys(ge).reduce((function(e,t){return ye.forEach((function(n){return e[function(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}(n,t)]=e[t]})),e}),ge);var we={};T((function(e){return new Z(e)})),P("div"),x((function(e){var t=e.output.map((function(e){return e.replace(be,me)})).map((function(e){return e.replace(ve,me)})),n=t[0].match(he).map((function(){return[]}));t.forEach((function(e){e.match(he).forEach((function(e,t){return n[t].push(+e)}))}));var r=t[0].match(he).map((function(t,r){return z(o({},e,{output:n[r]}))}));return function(e){var n=0;return t[0].replace(he,(function(){return r[n++](e)})).replace(/rgba\(([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+)\)/gi,(function(e,t,n,r,o){return"rgba("+Math.round(t)+", "+Math.round(n)+", "+Math.round(r)+", "+o+")"}))}})),j(Y),w((function(e,t){if(!e.nodeType||void 0===e.setAttribute)return!1;var n=t.style,r=t.children,o=t.scrollTop,a=t.scrollLeft,c=i(t,["style","children","scrollTop","scrollLeft"]),u="filter"===e.nodeName||e.parentNode&&"filter"===e.parentNode.nodeName;for(var s in void 0!==o&&(e.scrollTop=o),void 0!==a&&(e.scrollLeft=a),void 0!==r&&(e.textContent=r),n)if(n.hasOwnProperty(s)){var l=0===s.indexOf("--"),f=Oe(s,n[s],l);"float"===s&&(s="cssFloat"),l?e.style.setProperty(s,f):e.style[s]=f}for(var d in c){var p=u?d:we[d]||(we[d]=d.replace(/([A-Z])/g,(function(e){return"-"+e.toLowerCase()})));void 0!==e.getAttribute(p)&&e.setAttribute(p,c[d])}}),(function(e){return e}));var je,ke,Ee=(je=function(e){return a.forwardRef((function(t,n){var r=f(),u=a.useRef(!0),s=a.useRef(null),d=a.useRef(null),p=a.useCallback((function(e){var t=s.current;s.current=new M(e,(function(){var e=!1;d.current&&(e=b.fn(d.current,s.current.getAnimatedValue())),d.current&&!1!==e||r()})),t&&t.detach()}),[]);a.useEffect((function(){return function(){u.current=!1,s.current&&s.current.detach()}}),[]),a.useImperativeHandle(n,(function(){return R(d,u,r)})),p(t);var m,h=s.current.getValue(),v=(h.scrollTop,h.scrollLeft,i(h,["scrollTop","scrollLeft"])),g=(m=e,!l.fun(m)||m.prototype instanceof c.Component?function(e){return d.current=function(e,t){return t&&(l.fun(t)?t(e):l.obj(t)&&(t.current=e)),e}(e,n)}:void 0);return c.createElement(e,o({},v,{ref:g}))}))},void 0===(ke=!1)&&(ke=!0),function(e){return(l.arr(e)?e:Object.keys(e)).reduce((function(e,t){var n=ke?t[0].toLowerCase()+t.substring(1):t;return e[n]=je(n),e}),je)}),_e=Ee(["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","tspan"]);t.apply=Ee,t.config={default:{tension:170,friction:26},gentle:{tension:120,friction:14},wobbly:{tension:180,friction:12},stiff:{tension:210,friction:20},slow:{tension:280,friction:60},molasses:{tension:280,friction:120}},t.update=I,t.animated=_e,t.a=_e,t.interpolate=function(e,t,n){return e&&new H(e,t,n)},t.Globals=D,t.useSpring=function(e){var t=l.fun(e),n=W(1,t?e:[e]),r=n[0],o=n[1],i=n[2];return t?[r[0],o,i]:r},t.useTrail=function(e,t){var n=a.useRef(!1),r=l.fun(t),i=m(t),c=a.useRef(),u=W(e,(function(e,t){return 0===e&&(c.current=[]),c.current.push(t),o({},i,{config:m(i.config,e),attach:e>0&&function(){return c.current[e-1]}})})),s=u[0],f=u[1],d=u[2],p=a.useMemo((function(){return function(e){return f((function(t,n){e.reverse;var r=e.reverse?t+1:t-1,a=c.current[r];return o({},e,{config:m(e.config||i.config,t),attach:a&&function(){return a}})}))}}),[e,i.reverse]);return a.useEffect((function(){n.current&&!r&&p(t)})),a.useEffect((function(){n.current=!0}),[]),r?[s,p,d]:s},t.useTransition=function(e,t,n){var r=o({items:e,keys:t||function(e){return e}},n),c=K(r),u=c.lazy,s=void 0!==u&&u,l=(c.unique,c.reset),d=void 0!==l&&l,p=(c.enter,c.leave,c.update,c.onDestroyed),h=(c.keys,c.items,c.onFrame),b=c.onRest,v=c.onStart,g=c.ref,y=i(c,["lazy","unique","reset","enter","leave","update","onDestroyed","keys","items","onFrame","onRest","onStart","ref"]),O=f(),w=a.useRef(!1),j=a.useRef({mounted:!1,first:!0,deleted:[],current:{},transitions:[],prevProps:{},paused:!!r.ref,instances:!w.current&&new Map,forceUpdate:O});return a.useImperativeHandle(r.ref,(function(){return{start:function(){return Promise.all(Array.from(j.current.instances).map((function(e){var t=e[1];return new Promise((function(e){return t.start(e)}))})))},stop:function(e){return Array.from(j.current.instances).forEach((function(t){return t[1].stop(e)}))},get controllers(){return Array.from(j.current.instances).map((function(e){return e[1]}))}}})),j.current=function(e,t){var n=e.first,r=e.prevProps,a=i(e,["first","prevProps"]),c=K(t),u=c.items,s=c.keys,l=c.initial,f=c.from,d=c.enter,p=c.leave,h=c.update,b=c.trail,v=void 0===b?0:b,g=c.unique,y=c.config,O=c.order,w=void 0===O?["enter","leave","update"]:O,j=K(r),k=j.keys,E=j.items,_=o({},a.current),x=[].concat(a.deleted),C=Object.keys(_),S=new Set(C),P=new Set(s),A=s.filter((function(e){return!S.has(e)})),N=a.transitions.filter((function(e){return!e.destroyed&&!P.has(e.originalKey)})).map((function(e){return e.originalKey})),R=s.filter((function(e){return S.has(e)})),T=-v;for(;w.length;){switch(w.shift()){case"enter":A.forEach((function(e,t){g&&x.find((function(t){return t.originalKey===e}))&&(x=x.filter((function(t){return t.originalKey!==e})));var r=s.indexOf(e),o=u[r],i=n&&void 0!==l?"initial":"enter";_[e]={slot:i,originalKey:e,key:g?String(e):$++,item:o,trail:T+=v,config:m(y,o,i),from:m(n&&void 0!==l?l||{}:f,o),to:m(d,o)}}));break;case"leave":N.forEach((function(e){var t=k.indexOf(e),n=E[t];x.unshift(o({},_[e],{slot:"leave",destroyed:!0,left:k[Math.max(0,t-1)],right:k[Math.min(k.length,t+1)],trail:T+=v,config:m(y,n,"leave"),to:m(p,n)})),delete _[e]}));break;case"update":R.forEach((function(e){var t=s.indexOf(e),n=u[t];_[e]=o({},_[e],{item:n,slot:"update",trail:T+=v,config:m(y,n,"update"),to:m(h,n)})}))}}var D=s.map((function(e){return _[e]}));return x.forEach((function(e){var t,n=e.left,r=(e.right,i(e,["left","right"]));-1!==(t=D.findIndex((function(e){return e.originalKey===n})))&&(t+=1),t=Math.max(0,t),D=[].concat(D.slice(0,t),[r],D.slice(t))})),o({},a,{changed:A.length||N.length||R.length,first:n&&0===A.length,transitions:D,current:_,deleted:x,prevProps:t})}(j.current,r),j.current.changed&&j.current.transitions.forEach((function(e){var t=e.slot,n=e.from,r=e.to,i=e.config,a=e.trail,c=e.key,u=e.item;j.current.instances.has(c)||j.current.instances.set(c,new q);var l=j.current.instances.get(c),f=o({},y,{to:r,from:n,config:i,ref:g,onRest:function(n){j.current.mounted&&(e.destroyed&&(g||s||Q(j,c),p&&p(u)),!Array.from(j.current.instances).some((function(e){return!e[1].idle}))&&(g||s)&&j.current.deleted.length>0&&Q(j),b&&b(u,t,n))},onStart:v&&function(){return v(u,t)},onFrame:h&&function(e){return h(u,t,e)},delay:a,reset:d&&"enter"===t});l.update(f),j.current.paused||l.start()})),a.useEffect((function(){return j.current.mounted=w.current=!0,function(){j.current.mounted=w.current=!1,Array.from(j.current.instances).map((function(e){return e[1].destroy()})),j.current.instances.clear()}}),[]),j.current.transitions.map((function(e){var t=e.item,n=e.slot,r=e.key;return{item:t,key:r,state:n,props:j.current.instances.get(r).getValues()}}))},t.useChain=function(e,t,n){void 0===n&&(n=1e3);var r=a.useRef();a.useEffect((function(){l.equ(e,r.current)?e.forEach((function(e){var t=e.current;return t&&t.start()})):t?e.forEach((function(e,r){var i=e.current;if(i){var a=i.controllers;if(a.length){var c=n*t[r];a.forEach((function(e){e.queue=e.queue.map((function(e){return o({},e,{delay:e.delay+c})})),e.start()}))}}})):e.reduce((function(e,t,n){var r=t.current;return e.then((function(){return r.start()}))}),Promise.resolve()),r.current=e}))},t.useSprings=W},437:function(e,t,n){var r=n(573);e.exports=p,e.exports.parse=i,e.exports.compile=function(e,t){return c(i(e,t),t)},e.exports.tokensToFunction=c,e.exports.tokensToRegExp=d;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function i(e,t){for(var n,r=[],i=0,a=0,c="",l=t&&t.delimiter||"/";null!=(n=o.exec(e));){var f=n[0],d=n[1],p=n.index;if(c+=e.slice(a,p),a=p+f.length,d)c+=d[1];else{var m=e[a],h=n[2],b=n[3],v=n[4],g=n[5],y=n[6],O=n[7];c&&(r.push(c),c="");var w=null!=h&&null!=m&&m!==h,j="+"===y||"*"===y,k="?"===y||"*"===y,E=n[2]||l,_=v||g;r.push({name:b||i++,prefix:h||"",delimiter:E,optional:k,repeat:j,partial:w,asterisk:!!O,pattern:_?s(_):O?".*":"[^"+u(E)+"]+?"})}}return at)&&"unactioned"===o})).length}function i(e){return Object(r.filter)(e,(function(e){return!e.is_deleted})).length>0}},451:function(e,t,n){"use strict";var r=n(0),o=n(88),i=Object(r.createElement)(o.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(r.createElement)(o.b,{d:"M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"}));t.a=i},46:function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},47:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}n.d(t,"a",(function(){return r}))},48:function(e,t){function n(t){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?e.exports=n=function(e){return typeof e}:e.exports=n=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(t)}e.exports=n},49:function(e,t,n){"use strict";n.d(t,"a",(function(){return h}));var r=function(e){for(var t,n=0,r=0,o=e.length;o>=4;++r,o-=4)t=1540483477*(65535&(t=255&e.charCodeAt(r)|(255&e.charCodeAt(++r))<<8|(255&e.charCodeAt(++r))<<16|(255&e.charCodeAt(++r))<<24))+(59797*(t>>>16)<<16),n=1540483477*(65535&(t^=t>>>24))+(59797*(t>>>16)<<16)^1540483477*(65535&n)+(59797*(n>>>16)<<16);switch(o){case 3:n^=(255&e.charCodeAt(r+2))<<16;case 2:n^=(255&e.charCodeAt(r+1))<<8;case 1:n=1540483477*(65535&(n^=255&e.charCodeAt(r)))+(59797*(n>>>16)<<16)}return(((n=1540483477*(65535&(n^=n>>>13))+(59797*(n>>>16)<<16))^n>>>15)>>>0).toString(36)},o={animationIterationCount:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},i=n(102),a=/[A-Z]|^ms/g,c=/_EMO_([^_]+?)_([^]*?)_EMO_/g,u=function(e){return 45===e.charCodeAt(1)},s=function(e){return null!=e&&"boolean"!=typeof e},l=Object(i.a)((function(e){return u(e)?e:e.replace(a,"-$&").toLowerCase()})),f=function(e,t){switch(e){case"animation":case"animationName":if("string"==typeof t)return t.replace(c,(function(e,t,n){return p={name:t,styles:n,next:p},t}))}return 1===o[e]||u(e)||"number"!=typeof t||0===t?t:t+"px"};function d(e,t,n,r){if(null==n)return"";if(void 0!==n.__emotion_styles)return n;switch(typeof n){case"boolean":return"";case"object":if(1===n.anim)return p={name:n.name,styles:n.styles,next:p},n.name;if(void 0!==n.styles){var o=n.next;if(void 0!==o)for(;void 0!==o;)p={name:o.name,styles:o.styles,next:p},o=o.next;return n.styles+";"}return function(e,t,n){var r="";if(Array.isArray(n))for(var o=0;o=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}(n,["wrappedRef"]);return a.createElement(e,r({},i,{ref:function(e){t.__wrappedInstance=e,t.__domNode=c.findDOMNode(e),o&&o(e)}}))}}]),n}(a.Component);return n.displayName="clickOutside("+t+")",i(n,e)}},534:function(e,t,n){"use strict";var r=Object.assign||function(e){for(var t,n=1;n1&&(void 0!==e&&e.env,b=[b[0]]),Object(r.createElement)("div",{ref:n,className:y,onClick:g,tabIndex:"0",role:"button",onKeyPress:g,"aria-label":Object(u.__)("Dismiss this notice")},Object(r.createElement)("div",{className:"components-snackbar__content"},l,b.map((function(e,t){var n=e.label,o=e.onClick,i=e.url;return Object(r.createElement)(s.a,{key:t,href:i,isTertiary:!0,onClick:function(e){e.stopPropagation(),o&&o(e)},className:"components-snackbar__action"},n)}))))}))}).call(this,n(33))},537:function(e,t,n){"use strict";(function(e){var r=n(6),o=n.n(r),i=n(56),a=n(1),c=n.n(a),u="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==e?e:{};function s(e){var t=[];return{on:function(e){t.push(e)},off:function(e){t=t.filter((function(t){return t!==e}))},get:function(){return e},set:function(n,r){e=n,t.forEach((function(t){return t(e,r)}))}}}var l=o.a.createContext||function(e,t){var n,o,a,l="__create-react-context-"+((u[a="__global_unique_id__"]=(u[a]||0)+1)+"__"),f=function(e){function n(){var t;return(t=e.apply(this,arguments)||this).emitter=s(t.props.value),t}Object(i.a)(n,e);var r=n.prototype;return r.getChildContext=function(){var e;return(e={})[l]=this.emitter,e},r.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,o=e.value;((i=r)===(a=o)?0!==i||1/i==1/a:i!=i&&a!=a)?n=0:(n="function"==typeof t?t(r,o):1073741823,0!==(n|=0)&&this.emitter.set(e.value,n))}var i,a},r.render=function(){return this.props.children},n}(r.Component);f.childContextTypes=((n={})[l]=c.a.object.isRequired,n);var d=function(t){function n(){var e;return(e=t.apply(this,arguments)||this).state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}Object(i.a)(n,t);var r=n.prototype;return r.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?1073741823:t},r.componentDidMount=function(){this.context[l]&&this.context[l].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?1073741823:e},r.componentWillUnmount=function(){this.context[l]&&this.context[l].off(this.onUpdate)},r.getValue=function(){return this.context[l]?this.context[l].get():e},r.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(r.Component);return d.contextTypes=((o={})[l]=c.a.object,o),{Provider:f,Consumer:d}};t.a=l}).call(this,n(46))},538:function(e,t){!function(){e.exports=this.wc.customerEffortScore}()},54:function(e,t,n){"use strict";n.d(t,"e",(function(){return u})),n.d(t,"b",(function(){return s})),n.d(t,"c",(function(){return l})),n.d(t,"f",(function(){return f})),n.d(t,"d",(function(){return d})),n.d(t,"a",(function(){return p}));var r=n(8),o=n(27),i=n(2),a=n(3);function c(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:window,t=e.navigator.platform;return-1!==t.indexOf("Mac")||Object(i.includes)(["iPad","iPhone"],t)}var u=9,s=27,l=37,f=38,d=39,p=40,m="alt",h="ctrl",b="meta",v="shift",g={primary:function(e){return e()?[b]:[h]},primaryShift:function(e){return e()?[v,b]:[h,v]},primaryAlt:function(e){return e()?[m,b]:[h,m]},secondary:function(e){return e()?[v,m,b]:[h,v,m]},access:function(e){return e()?[h,m]:[v,m]},ctrl:function(){return[h]},alt:function(){return[m]},ctrlShift:function(){return[h,v]},shift:function(){return[v]},shiftAlt:function(){return[v,m]}},y=(Object(i.mapValues)(g,(function(e){return function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:c;return[].concat(Object(o.a)(e(n)),[t.toLowerCase()]).join("+")}})),Object(i.mapValues)(g,(function(e){return function(t){var n,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:c,u=a(),s=(n={},Object(r.a)(n,m,u?"⌥":"Alt"),Object(r.a)(n,h,u?"⌃":"Ctrl"),Object(r.a)(n,b,"⌘"),Object(r.a)(n,v,u?"⇧":"Shift"),n),l=e(a).reduce((function(e,t){var n=Object(i.get)(s,t,t);return[].concat(Object(o.a)(e),u?[n]:[n,"+"])}),[]),f=Object(i.capitalize)(t);return[].concat(Object(o.a)(l),[f])}})));Object(i.mapValues)(y,(function(e){return function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:c;return e(t,n).join("")}})),Object(i.mapValues)(g,(function(e){return function(t){var n,u=arguments.length>1&&void 0!==arguments[1]?arguments[1]:c,s=u(),l=(n={},Object(r.a)(n,v,"Shift"),Object(r.a)(n,b,s?"Command":"Control"),Object(r.a)(n,h,"Control"),Object(r.a)(n,m,s?"Option":"Alt"),Object(r.a)(n,",",Object(a.__)("Comma")),Object(r.a)(n,".",Object(a.__)("Period")),Object(r.a)(n,"`",Object(a.__)("Backtick")),n);return[].concat(Object(o.a)(e(u)),[t]).map((function(e){return Object(i.capitalize)(Object(i.get)(l,e,e))})).join(s?" ":" + ")}}));function O(e){return[m,h,b,v].filter((function(t){return e["".concat(t,"Key")]}))}Object(i.mapValues)(g,(function(e){return function(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:c,o=e(r),a=O(t);return!Object(i.xor)(o,a).length&&(n?t.key===n:Object(i.includes)(o,t.key.toLowerCase()))}}))},543:function(e,t,n){"use strict";var r=n(0),o=n(296),i=n(32),a=n(35),c=(n(574),n(34)),u=n.n(c),s=n(3),l=n(277),f=n(8),d=n(26),p=n(4),m=n.n(p),h=n(2),b=n(134),v=Object(r.createContext)({activeItem:void 0,activeMenu:"root",setActiveMenu:h.noop,navigationTree:{items:{},getItem:h.noop,addItem:h.noop,removeItem:h.noop,menus:{},getMenu:h.noop,addMenu:h.noop,removeMenu:h.noop}}),g=function(){return Object(r.useContext)(v)},y=n(41),O=n(91),w=n(72),j=n(190);var k=Object(y.a)("div",{target:"ejwewyf0",label:"NavigationUI"})("width:100%;background-color:",O.b.darkGray.primary,";color:#f0f0f0;padding:0 8px;overflow:hidden;"),E=Object(y.a)("div",{target:"ejwewyf1",label:"MenuUI"})({name:"1wlvkgj",styles:"margin-top:24px;margin-bottom:24px;display:flex;flex-direction:column;ul{padding:0;margin:0;list-style:none;}.components-navigation__back-button{margin-bottom:24px;}"}),_=Object(y.a)(w.a,{target:"ejwewyf2",label:"MenuBackButtonUI"})("&.is-tertiary{color:",O.b.lightGray.ui,";&:hover:not(:disabled ){color:#ddd;box-shadow:none;}&:active:not(:disabled ){background:transparent;color:#ddd;}}"),x=Object(y.a)(j.a,{target:"ejwewyf3",label:"MenuTitleUI"})("padding:4px 0 4px 16px;margin-bottom:8px;color:",O.b.gray[100],";"),C=Object(y.a)(j.a,{target:"ejwewyf4",label:"GroupTitleUI"})("margin-top:8px;padding:4px 0 4px 16px;text-transform:uppercase;color:",O.b.gray[100],";"),S=Object(y.a)("li",{target:"ejwewyf5",label:"ItemUI"})("border-radius:2px;color:",O.b.lightGray.ui,";button,a{margin:0;font-weight:400;font-size:14px;line-height:20px;padding-left:16px;padding-right:16px;width:100%;color:",O.b.lightGray.ui,";&:hover,&:focus:not( [aria-disabled='true'] ):active,&:active:not( [aria-disabled='true'] ):active{color:#ddd;}}&.is-active{background-color:",O.c.theme,";color:",O.c.textDark,";button,a{color:",O.c.textDark,";}}svg path{color:",O.b.lightGray.ui,";}"),P=Object(y.a)("span",{target:"ejwewyf6",label:"ItemBadgeUI"})("margin-left:8px;display:inline-flex;padding:4px 12px;border-radius:2px;animation:fade-in 250ms ease-out;@keyframes fade-in{from{opacity:0;}to{opacity:1;}}",function(){var e,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"transition";switch(t){case"transition":e="transition-duration: 0ms;";break;case"animation":e="animation-duration: 1ms;";break;default:e="\n\t\t\t\tanimation-duration: 1ms;\n\t\t\t\ttransition-duration: 0ms;\n\t\t\t"}return"\n\t\t@media ( prefers-reduced-motion: reduce ) {\n\t\t\t".concat(e,";\n\t\t}\n\t")}("animation"),";"),A=Object(y.a)(j.a,{target:"ejwewyf7",label:"ItemTitleUI"})({name:"zs804i",styles:"margin-right:auto;text-align:left;"});function N(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function R(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:"left";A.getMenu(e)&&(P(t),_(e),O(e))},R=Object(r.useRef)(!1);Object(r.useEffect)((function(){R.current||(R.current=!0)}),[]),Object(r.useEffect)((function(){l!==E&&N(l)}),[l]);var D={activeItem:u,activeMenu:E,setActiveMenu:N,navigationTree:A},M=m()("components-navigation",g);return Object(r.createElement)(k,{className:M},Object(r.createElement)(b.a,{key:E,type:"slide-in",options:{origin:S}},(function(e){var t=e.className;return Object(r.createElement)("div",{className:m()(Object(f.a)({},t,R.current&&S))},Object(r.createElement)(v.Provider,{value:D},p))})))}var M=n(575),L=n(88),F=Object(r.createElement)(L.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(r.createElement)(L.b,{d:"M14.6 7l-1.2-1L8 12l5.4 6 1.2-1-4.6-5z"}));function I(e){var t,n=e.backButtonLabel,o=e.className,i=e.href,a=e.onClick,c=e.parentMenu,u=g(),l=u.setActiveMenu,f=u.navigationTree,d=m()("components-navigation__back-button",o),p=null===(t=f.getMenu(c))||void 0===t?void 0:t.title;return Object(r.createElement)(_,{className:d,isTertiary:!0,href:i,onClick:function(){return c?l(c,"right"):a}},Object(r.createElement)(M.a,{icon:F}),n||p||Object(s.__)("Back"))}var z=Object(r.createContext)({menu:void 0,isActive:!1}),H=function(){return Object(r.useContext)(z)};function B(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function U(e){for(var t=1;t=0&&c===o)return Number.MAX_SAFE_INTEGER-2;var f=0,d=G(e);return Object.keys(l).forEach((function(e){l[e]===d[e]&&f++})),c===o&&u===i?f:0}},Q=function(e){var t=null,n=0;return e.forEach((function(e){var r=K(window.location,Object(W.f)(e.url));r>=n&&r>0&&(t=e,n=r)})),t||null},Z=n(570),Y=Object(r.createElement)(L.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},Object(r.createElement)(L.b,{d:"M20 10c0-5.51-4.49-10-10-10C4.48 0 0 4.49 0 10c0 5.52 4.48 10 10 10 5.51 0 10-4.48 10-10zM7.78 15.37L4.37 6.22c.55-.02 1.17-.08 1.17-.08.5-.06.44-1.13-.06-1.11 0 0-1.45.11-2.37.11-.18 0-.37 0-.58-.01C4.12 2.69 6.87 1.11 10 1.11c2.33 0 4.45.87 6.05 2.34-.68-.11-1.65.39-1.65 1.58 0 .74.45 1.36.9 2.1.35.61.55 1.36.55 2.46 0 1.49-1.4 5-1.4 5l-3.03-8.37c.54-.02.82-.17.82-.17.5-.05.44-1.25-.06-1.22 0 0-1.44.12-2.38.12-.87 0-2.33-.12-2.33-.12-.5-.03-.56 1.2-.06 1.22l.92.08 1.26 3.41zM17.41 10c.24-.64.74-1.87.43-4.25.7 1.29 1.05 2.71 1.05 4.25 0 3.29-1.73 6.24-4.4 7.78.97-2.59 1.94-5.2 2.92-7.78zM6.1 18.09C3.12 16.65 1.11 13.53 1.11 10c0-1.3.23-2.48.72-3.59C3.25 10.3 4.67 14.2 6.1 18.09zm4.03-6.63l2.58 6.98c-.86.29-1.76.45-2.71.45-.79 0-1.57-.11-2.29-.33.81-2.38 1.62-4.74 2.42-7.1z"})),X=n(6),J=n(295),ee=function(){var e=Object(W.g)("siteTitle",""),t=Object(W.g)("siteUrl",""),n=Object(J.a)(),o=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.body.clientWidth,t=e<=960;document.body.classList[t?"add":"remove"]("is-folded")};Object(X.useEffect)((function(){o();for(var e=0,t=[{eventName:"orientationchange",handler:function(e){return o(e.target.screen.availWidth)}},{eventName:"resize",handler:Object(h.debounce)((function(){return o()}),200)}];e1&&void 0!==arguments[1]?arguments[1]:{},n=t.version,i=t.alternative,a=t.plugin,c=t.link,u=t.hint,s=a?" from ".concat(a):"",l=n?" and will be removed".concat(s," in version ").concat(n):"",f=i?" Please use ".concat(i," instead."):"",d=c?" See: ".concat(c):"",p=u?" Note: ".concat(u):"",m="".concat(e," is deprecated").concat(l,".").concat(f).concat(d).concat(p);m in o||(Object(r.doAction)("deprecated",e,t,m),console.warn(m),o[m]=!0)}},570:function(e,t,n){"use strict";var r=n(8),o=n(12),i=n(0);function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}t.a=function(e){var t=e.icon,n=e.size,c=void 0===n?24:n,u=Object(o.a)(e,["icon","size"]);return Object(i.cloneElement)(t,function(e){for(var t=1;t=0||(o[n]=e[n]);return o}n.d(t,"a",(function(){return r}))},59:function(e,t,n){"use strict";function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}},63:function(e,t,n){"use strict";(function(e){var r=n(0),o=(n(90),Object(r.createContext)({slots:{},fills:{},registerSlot:function(){void 0!==e&&e.env},updateSlot:function(){},unregisterSlot:function(){},registerFill:function(){},unregisterFill:function(){}}));t.a=o}).call(this,n(33))},64:function(e,t){!function(){e.exports=this.wc.tracks}()},67:function(e,t,n){"use strict";n.d(t,"a",(function(){return m})),n.d(t,"c",(function(){return h})),n.d(t,"b",(function(){return b}));var r=n(56),o=n(6);var i=function(){function e(e){this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.before=null}var t=e.prototype;return t.insert=function(e){if(this.ctr%(this.isSpeedy?65e3:1)==0){var t,n=function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t}(this);t=0===this.tags.length?this.before:this.tags[this.tags.length-1].nextSibling,this.container.insertBefore(n,t),this.tags.push(n)}var r=this.tags[this.tags.length-1];if(this.isSpeedy){var o=function(e){if(e.sheet)return e.sheet;for(var t=0;tr&&(r=(t=t.trim()).charCodeAt(0)),r){case 38:return t.replace(h,"$1"+e.trim());case 58:return e.trim()+t.replace(h,"$1"+e.trim());default:if(0<1*n&&0u.charCodeAt(8))break;case 115:a=a.replace(u,"-webkit-"+u)+";"+a;break;case 207:case 102:a=a.replace(u,"-webkit-"+(102c.charCodeAt(0)&&(c=c.trim()),c=[c],0p)&&(z=(U=U.replace(" ",":")).length),0=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,c=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return a=e.done,e},e:function(e){c=!0,i=e},f:function(){try{a||null==n.return||n.return()}finally{if(c)throw i}}}}function p(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0||e.offsetHeight>0||e.getClientRects().length>0}function c(e){var t=e.querySelectorAll(i);return Array.from(t).filter((function(e){return!(!a(e)||function(e){return"iframe"===e.nodeName.toLowerCase()&&"-1"===e.getAttribute("tabindex")}(e))&&("AREA"!==e.nodeName||function(e){var t=e.closest("map[name]");if(!t)return!1;var n=e.ownerDocument.querySelector('img[usemap="#'+t.name+'"]');return!!n&&a(n)}(e))}))}var u=n(2);function s(e){var t=e.getAttribute("tabindex");return null===t?0:parseInt(t,10)}function l(e){return-1!==s(e)}function f(e,t){return{element:e,index:t}}function d(e){return e.element}function p(e,t){var n=s(e.element),r=s(t.element);return n===r?e.index-t.index:n-r}function m(e){return e.filter(l).map(f).sort(p).map(d).reduce((t={},function(e,n){var r=n.nodeName,o=n.type,i=n.checked,a=n.name;if("INPUT"!==r||"radio"!==o||!a)return e.concat(n);var c=t.hasOwnProperty(a);if(!i&&c)return e;if(c){var s=t[a];e=Object(u.without)(e,s)}return t[a]=n,e.concat(n)}),[]);var t}function h(e){return m(c(e))}function b(e){var t=c(e.ownerDocument.body),n=t.indexOf(e);return t.length=n,Object(u.last)(m(t))}function v(e){var t=c(e.ownerDocument.body),n=t.indexOf(e),r=t.slice(n+1).filter((function(t){return!e.contains(t)}));return Object(u.first)(m(r))}var g={focusable:r,tabbable:o}},732:function(e,t,n){"use strict";var r={};n.r(r),n.d(r,"createNotice",(function(){return h})),n.d(r,"createSuccessNotice",(function(){return b})),n.d(r,"createInfoNotice",(function(){return v})),n.d(r,"createErrorNotice",(function(){return g})),n.d(r,"createWarningNotice",(function(){return y})),n.d(r,"removeNotice",(function(){return O}));var o={};n.r(o),n.d(o,"getNotices",(function(){return j}));var i=n(20),a=n(27),c=n(2),u=n(8);function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0,o=r[e];if(void 0===o)return n;var i=t(n[o],r);return i===n[o]?n:l({},n,Object(u.a)({},o,i))}}}("context")((function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1?arguments[1]:void 0;switch(t.type){case"CREATE_NOTICE":return[].concat(Object(a.a)(Object(c.reject)(e,{id:t.notice.id})),[t.notice]);case"REMOVE_NOTICE":return Object(c.reject)(e,{id:t.id})}return e})),d=n(14),p=n.n(d),m=p.a.mark(h);function h(){var e,t,n,r,o,i,a,u,s,l,f,d,h,b,v,g,y=arguments;return p.a.wrap((function(p){for(;;)switch(p.prev=p.next){case 0:if(e=y.length>0&&void 0!==y[0]?y[0]:"info",t=y.length>1?y[1]:void 0,n=y.length>2&&void 0!==y[2]?y[2]:{},r=n.speak,o=void 0===r||r,i=n.isDismissible,a=void 0===i||i,u=n.context,s=void 0===u?"global":u,l=n.id,f=void 0===l?Object(c.uniqueId)(s):l,d=n.actions,h=void 0===d?[]:d,b=n.type,v=void 0===b?"default":b,g=n.__unstableHTML,t=String(t),!o){p.next=8;break}return p.next=8,{type:"SPEAK",message:t,ariaLive:"snackbar"===v?"polite":"assertive"};case 8:return p.next=10,{type:"CREATE_NOTICE",context:s,notice:{id:f,status:e,content:t,__unstableHTML:g,isDismissible:a,actions:h,type:v}};case 10:case"end":return p.stop()}}),m)}function b(e,t){return h("success",e,t)}function v(e,t){return h("info",e,t)}function g(e,t){return h("error",e,t)}function y(e,t){return h("warning",e,t)}function O(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"global";return{type:"REMOVE_NOTICE",id:e,context:t}}var w=[];function j(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"global";return e[t]||w}var k=n(189),E={SPEAK:function(e){Object(k.a)(e.message,e.ariaLive||"assertive")}};Object(i.registerStore)("core/notices",{reducer:f,actions:r,selectors:o,controls:E})},74:function(e,t,n){"use strict";n.d(t,"a",(function(){return s}));var r=n(8),o=n(2);function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0,i=e.env.FORCE_REDUCED_MOTION||o?function(){return!0}:function(){return Object(r.a)("(prefers-reduced-motion: reduce)")};t.a=i}).call(this,n(33))},761:function(e,t,n){"use strict";var r=n(7),o=n(12),i=n(0),a=n(2),c=n(54),u=n(21),s=n(22),l=n(13),f=n(23),d=n(24),p=n(10),m=n(73);function h(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=Object(p.a)(e);if(t){var o=Object(p.a)(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return Object(d.a)(this,n)}}var b=["menuitem","menuitemradio","menuitemcheckbox"];var v=function(e){Object(f.a)(n,e);var t=h(n);function n(){var e;return Object(u.a)(this,n),(e=t.apply(this,arguments)).onKeyDown=e.onKeyDown.bind(Object(l.a)(e)),e.bindContainer=e.bindContainer.bind(Object(l.a)(e)),e.getFocusableContext=e.getFocusableContext.bind(Object(l.a)(e)),e.getFocusableIndex=e.getFocusableIndex.bind(Object(l.a)(e)),e}return Object(s.a)(n,[{key:"componentDidMount",value:function(){this.container.addEventListener("keydown",this.onKeyDown),this.container.addEventListener("focus",this.onFocus)}},{key:"componentWillUnmount",value:function(){this.container.removeEventListener("keydown",this.onKeyDown),this.container.removeEventListener("focus",this.onFocus)}},{key:"bindContainer",value:function(e){var t=this.props.forwardedRef;this.container=e,Object(a.isFunction)(t)?t(e):t&&"current"in t&&(t.current=e)}},{key:"getFocusableContext",value:function(e){var t=(this.props.onlyBrowserTabstops?m.a.tabbable:m.a.focusable).find(this.container),n=this.getFocusableIndex(t,e);return n>-1&&e?{index:n,target:e,focusables:t}:null}},{key:"getFocusableIndex",value:function(e,t){var n=e.indexOf(t);if(-1!==n)return n}},{key:"onKeyDown",value:function(e){this.props.onKeyDown&&this.props.onKeyDown(e);var t=this.getFocusableContext,n=this.props,r=n.cycle,o=void 0===r||r,i=n.eventToOffset,c=n.onNavigate,u=void 0===c?a.noop:c,s=n.stopNavigationEvents,l=i(e);if(void 0!==l&&s){e.stopImmediatePropagation();var f=e.target.getAttribute("role");b.includes(f)&&e.preventDefault()}if(l){var d=t(e.target.ownerDocument.activeElement);if(d){var p=d.index,m=d.focusables,h=o?function(e,t,n){var r=e+n;return r<0?t+r:r>=t?r-t:r}(p,m.length,l):p+l;h>=0&&he.length)&&(t=e.length);for(var n=0,r=new Array(t);n1;){var t=e.pop(),n=t.obj[t.prop];if(o(n)){for(var r=[],i=0;i=48&&c<=57||c>=65&&c<=90||c>=97&&c<=122?o+=r.charAt(a):c<128?o+=i[c]:c<2048?o+=i[192|c>>6]+i[128|63&c]:c<55296||c>=57344?o+=i[224|c>>12]+i[128|c>>6&63]+i[128|63&c]:(a+=1,c=65536+((1023&c)<<10|1023&r.charCodeAt(a)),o+=i[240|c>>18]+i[128|c>>12&63]+i[128|c>>6&63]+i[128|63&c])}return o},isBuffer:function(e){return!(!e||"object"!=typeof e)&&!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))},isRegExp:function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},maybeMap:function(e,t){if(o(e)){for(var n=[],r=0;ra:focus,.woocommerce-page #toplevel_page_woocommerce.menu-top>a:focus{padding-bottom:1px}}.woocommerce-layout *{box-sizing:border-box}#wpfooter{display:none}.woocommerce_page_wc-admin .wp-responsive-open .woocommerce-layout__header{margin-left:2px}.woocommerce_page_wc-admin .woocommerce-filters-date__content:not(.is-mobile){z-index:2}@media (max-width:600px){#wpadminbar{position:fixed}}@media (max-width:782px){.jetpack-masterbar #wpadminbar #wp-admin-bar-menu-toggle{margin-top:-10px}.jetpack-masterbar #wpwrap .woocommerce-layout__header-heading{padding-left:60px}.jetpack-masterbar.wp-admin .wrap h1,.jetpack-masterbar.wp-admin .wrap h2{padding-left:0}}.woocommerce-page .wp-has-current-submenu:after{right:0;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:8px solid transparent;border-right-color:#f1f1f1;top:0;margin-top:10px}@media (max-width:960px){.woocommerce-page .wp-has-current-submenu:after{border-width:4px;margin-top:14px}}:root{--large-gap:40px;--main-gap:24px}@media (max-width:960px){:root{--large-gap:24px}}@media (max-width:782px){:root{--large-gap:16px;--main-gap:16px}}@keyframes loading-fade{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}.woocommerce-layout select:hover{color:#1e1e1e}.woocommerce-layout select.components-select-control__input{max-width:100%;line-height:1}body.woocommerce-page .components-button.is-primary,body.woocommerce-page .components-button.is-primary:not(:disabled):active,body.woocommerce-page .components-button.is-primary:not(:disabled):focus,body.woocommerce-page .components-button.is-primary:not(:disabled):hover,body.woocommerce-page .components-snackbar .components-button.is-tertiary,body.woocommerce-page .components-snackbar .components-button.is-tertiary:not(:disabled):not([aria-disabled=true]):hover{color:#fff}.woocommerce-embed-page #wpbody .woocommerce-layout,.woocommerce-embed-page .woocommerce-layout__notice-list-hide+.wrap{padding-top:70px}.woocommerce-embed-page #wpbody-content,.woocommerce-embed-page #wpcontent{overflow-x:initial!important}.woocommerce-embed-page #wpbody-content{padding-top:0}.woocommerce-embed-page #wpbody-content .notice{margin-top:15px}.woocommerce-embed-page .wrap{padding:0 20px}@media (max-width:782px){.woocommerce-embed-page .wrap p.search-box{width:calc(100% - 40px)}}.woocommerce-embed-page .wrap .wrap{padding:0}.woocommerce-embed-page #woocommerce-embedded-root.is-embed-loading+#wpbody .wrap{padding-top:100px}@media (max-width:782px){.woocommerce-embed-page #woocommerce-embedded-root.is-embed-loading+#wpbody .wrap{padding-top:30px}}.woocommerce-embed-page #screen-meta,.woocommerce-embed-page #screen-meta-links{top:60px}.woocommerce-embed-page #screen-meta{border-right:0;margin:0}.woocommerce-embed-page #screen-meta-links{position:relative}.woocommerce-embed-page .notice{padding:1px 12px}.woocommerce-embed-page .woocommerce-layout__header{height:60px}.woocommerce-embed-page .woocommerce-layout__header.is-scrolled{box-shadow:0 8px 16px 0 rgba(85,93,102,.3)}.woocommerce-embed-page .woocommerce-layout__header .woocommerce-layout__header-heading{margin-top:0;margin-bottom:0}.woocommerce-embed-page #screen-meta-links.is-hidden-by-notices,.woocommerce-embed-page #screen-meta.is-hidden-by-notices{display:none!important}.woocommerce-embed-page .woocommerce-layout__primary{margin:0}@media (max-width:782px){.woocommerce-embed-page .woocommerce-layout__primary{padding-top:10px}}@keyframes isLoaded{0%{opacity:0}to{opacity:1}}.woocommerce-embed-page .woocommerce-layout__activity-panel-tabs{animation:isLoaded;animation-duration:2s}.woocommerce-embed-page .woocommerce-layout__notice-list-show{margin-top:10px;margin-bottom:16px}@media (max-width:600px){.woocommerce-embed-page .woocommerce-layout__notice-list-show{margin-top:80px;margin-bottom:-16px}}@media (min-width:601px) and (max-width:782px){.woocommerce-embed-page .woocommerce-layout__notice-list-show{margin-top:32px}}@media (min-width:783px){.woocommerce-embed-page .woocommerce-layout__activity-panel-mobile-toggle{display:none}}.woocommerce-embed-page .woocommerce-activity-card__actions a.components-button:not(.is-primary){color:#757575}.components-button{display:inline-flex;text-decoration:none;font-size:13px;margin:0;border:0;cursor:pointer;-webkit-appearance:none;background:none;transition:box-shadow .1s linear;height:36px;align-items:center;box-sizing:border-box;padding:6px 12px;border-radius:2px;color:#1e1e1e}@media (prefers-reduced-motion:reduce){.components-button{transition-duration:0s}}.components-button:hover,.components-button[aria-expanded=true]{color:#007cba;color:var(--wp-admin-theme-color)}.components-button[aria-disabled=true]:hover{color:initial}.components-button:focus:not(:disabled){box-shadow:0 0 0 1.5px #007cba;box-shadow:0 0 0 1.5px var(--wp-admin-theme-color);outline:1px solid transparent}.components-button.is-primary{white-space:nowrap;background:#007cba;background:var(--wp-admin-theme-color);color:#fff;text-decoration:none;text-shadow:none}.components-button.is-primary:hover:not(:disabled){background:#006ba1;background:var(--wp-admin-theme-color-darker-10);color:#fff}.components-button.is-primary:active:not(:disabled){background:#005a87;background:var(--wp-admin-theme-color-darker-20);border-color:#005a87;border-color:var(--wp-admin-theme-color-darker-20);color:#fff}.components-button.is-primary:focus:not(:disabled){box-shadow:inset 0 0 0 1px #fff,0 0 0 1.5px #007cba;box-shadow:inset 0 0 0 1px #fff,0 0 0 1.5px var(--wp-admin-theme-color);outline:1px solid transparent}.components-button.is-primary:disabled,.components-button.is-primary:disabled:active:enabled,.components-button.is-primary[aria-disabled=true],.components-button.is-primary[aria-disabled=true]:active:enabled,.components-button.is-primary[aria-disabled=true]:enabled{color:hsla(0,0%,100%,.4);background:#007cba;background:var(--wp-admin-theme-color);border-color:#007cba;border-color:var(--wp-admin-theme-color);opacity:1}.components-button.is-primary:disabled:active:enabled:focus:enabled,.components-button.is-primary:disabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:active:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:focus:enabled{box-shadow:0 0 0 1px #fff,0 0 0 3px #007cba;box-shadow:0 0 0 1px #fff,0 0 0 3px var(--wp-admin-theme-color)}.components-button.is-primary.is-busy,.components-button.is-primary.is-busy:disabled,.components-button.is-primary.is-busy[aria-disabled=true]{color:#fff;background-size:100px 100%;background-image:linear-gradient(-45deg,#007cba 28%,#005a87 0,#005a87 72%,#007cba 0);background-image:linear-gradient(-45deg,var(--wp-admin-theme-color) 28%,var(--wp-admin-theme-color-darker-20) 0,var(--wp-admin-theme-color-darker-20) 72%,var(--wp-admin-theme-color) 0);border-color:#007cba;border-color:var(--wp-admin-theme-color)}.components-button.is-secondary:active:not(:disabled),.components-button.is-tertiary:active:not(:disabled){background:#ddd;color:#006ba1;color:var(--wp-admin-theme-color-darker-10);box-shadow:none}.components-button.is-secondary:hover:not(:disabled),.components-button.is-tertiary:hover:not(:disabled){color:#006ba1;color:var(--wp-admin-theme-color-darker-10);box-shadow:inset 0 0 0 1px #006ba1;box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color-darker-10)}.components-button.is-secondary:disabled,.components-button.is-secondary[aria-disabled=true],.components-button.is-secondary[aria-disabled=true]:hover,.components-button.is-tertiary:disabled,.components-button.is-tertiary[aria-disabled=true],.components-button.is-tertiary[aria-disabled=true]:hover{color:#828282;background:#eaeaea;transform:none;opacity:1;box-shadow:none}.components-button.is-secondary{box-shadow:inset 0 0 0 1px #007cba;box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color);outline:1px solid transparent}.components-button.is-secondary,.components-button.is-tertiary{white-space:nowrap;color:#007cba;color:var(--wp-admin-theme-color);background:transparent}.components-button.is-tertiary{padding:6px;outline:1px dotted transparent}.components-button.is-tertiary .dashicon{display:inline-block;flex:0 0 auto}.components-button.is-destructive{color:#d94f4f;box-shadow:inset 0 0 0 1px #d94f4f}.components-button.is-destructive:hover:not(:disabled){color:#a02222;box-shadow:inset 0 0 0 1px #a02222}.components-button.is-destructive:focus:not(:disabled){color:#007cba;color:var(--wp-admin-theme-color)}.components-button.is-destructive:active:not(:disabled){background:#ccc}.components-button.is-link{margin:0;padding:0;box-shadow:none;border:0;border-radius:0;background:none;outline:none;text-align:left;color:#0073aa;text-decoration:underline;transition-property:border,background,color;transition-duration:.05s;transition-timing-function:ease-in-out;height:auto}@media (prefers-reduced-motion:reduce){.components-button.is-link{transition-duration:0s}}.components-button.is-link:active:not(:disabled),.components-button.is-link:hover:not(:disabled){color:#00a0d2;box-shadow:none}.components-button.is-link:focus{color:#124964;box-shadow:0 0 0 1px #5b9dd9,0 0 1.5px 1px rgba(30,140,190,.8)}.components-button.is-link.is-destructive{color:#d94f4f}.components-button.is-link.is-destructive:active:not(:disabled),.components-button.is-link.is-destructive:hover:not(:disabled){color:#a02222;background:none}.components-button.is-link.is-destructive:focus:not(:disabled){color:#007cba;color:var(--wp-admin-theme-color)}.components-button:not([aria-disabled=true]):active{color:inherit}.components-button:disabled,.components-button[aria-disabled=true]{cursor:default;opacity:.3}.components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{animation:components-button__busy-animation 2.5s linear infinite;opacity:1;background-size:100px 100%;background-image:linear-gradient(-45deg,#fafafa 28%,#e0e0e0 0,#e0e0e0 72%,#fafafa 0)}.components-button.is-small{height:24px;line-height:22px;padding:0 8px;font-size:11px}.components-button.is-small.has-icon:not(.has-text){padding:0 8px;width:24px}.components-button.has-icon{padding:6px;min-width:36px;justify-content:center}.components-button.has-icon .dashicon{display:inline-block;flex:0 0 auto}.components-button.has-icon.has-text{justify-content:left}.components-button.has-icon.has-text svg{margin-right:8px}.components-button.is-pressed{color:#fff;background:#1e1e1e}.components-button.is-pressed:focus:not(:disabled){box-shadow:inset 0 0 0 1px #fff,0 0 0 1.5px #007cba;box-shadow:inset 0 0 0 1px #fff,0 0 0 1.5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-button.is-pressed:hover:not(:disabled){background:#1e1e1e}.components-button svg{fill:currentColor;outline:none}.components-button .components-visually-hidden{height:auto}@keyframes components-button__busy-animation{0%{background-position:200px 0}}.components-checkbox-control__input[type=checkbox]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;padding:6px 8px;box-shadow:0 0 0 transparent;transition:box-shadow .1s linear;font-size:16px;line-height:normal;border:1px solid #1e1e1e;transition:none;border-radius:2px;background:#fff;color:#1e1e1e;clear:none;cursor:pointer;display:inline-block;line-height:0;margin:0 4px 0 0;outline:0;padding:0!important;text-align:center;vertical-align:top;width:24px;height:24px;-webkit-appearance:none;appearance:none;transition:border-color .1s ease-in-out}@media (min-width:600px){.components-checkbox-control__input[type=checkbox]{font-size:13px;line-height:normal}}.components-checkbox-control__input[type=checkbox]:focus{border-color:#007cba;border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px #007cba;box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]::-webkit-input-placeholder{color:rgba(30,30,30,.62)}.components-checkbox-control__input[type=checkbox]::-moz-placeholder{opacity:1;color:rgba(30,30,30,.62)}.components-checkbox-control__input[type=checkbox]:-ms-input-placeholder{color:rgba(30,30,30,.62)}.is-dark-theme .components-checkbox-control__input[type=checkbox]::-webkit-input-placeholder{color:hsla(0,0%,100%,.65)}.is-dark-theme .components-checkbox-control__input[type=checkbox]::-moz-placeholder{opacity:1;color:hsla(0,0%,100%,.65)}.is-dark-theme .components-checkbox-control__input[type=checkbox]:-ms-input-placeholder{color:hsla(0,0%,100%,.65)}.components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{margin:-3px -5px;color:#fff}@media (min-width:782px){.components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{margin:-4px 0 0 -5px}}.components-checkbox-control__input[type=checkbox][aria-checked=mixed]{background:#007cba;background:var(--wp-admin-theme-color);border-color:#007cba;border-color:var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{content:"\f460";float:left;display:inline-block;vertical-align:middle;width:16px;font:normal 30px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (min-width:782px){.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{float:none;font-size:21px}}@media (min-width:600px){.components-checkbox-control__input[type=checkbox]{height:20px;width:20px}}@media (prefers-reduced-motion:reduce){.components-checkbox-control__input[type=checkbox]{transition-duration:0s}}.components-checkbox-control__input[type=checkbox]:focus{box-shadow:0 0 0 2px #fff,0 0 0 3.5px #007cba;box-shadow:0 0 0 2px #fff,0 0 0 3.5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-checkbox-control__input[type=checkbox]:checked{background:#007cba;background:var(--wp-admin-theme-color);border-color:#007cba;border-color:var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]:checked::-ms-check{opacity:0}.components-checkbox-control__input[type=checkbox]:checked:before{content:none}.components-checkbox-control__input-container{position:relative;display:inline-block;margin-right:12px;vertical-align:middle;width:24px;height:24px}@media (min-width:600px){.components-checkbox-control__input-container{width:20px;height:20px}}svg.components-checkbox-control__checked{fill:#fff;cursor:pointer;position:absolute;left:0;top:0;width:24px;height:24px;-webkit-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none}@media (min-width:600px){svg.components-checkbox-control__checked{left:-2px;top:-2px}}.components-form-toggle{position:relative;display:inline-block}.components-form-toggle .components-form-toggle__track{content:"";display:inline-block;box-sizing:border-box;vertical-align:top;background-color:#fff;border:1px solid #1e1e1e;width:36px;height:18px;border-radius:9px;transition:background .2s ease}@media (prefers-reduced-motion:reduce){.components-form-toggle .components-form-toggle__track{transition-duration:0s}}.components-form-toggle .components-form-toggle__thumb{display:block;position:absolute;box-sizing:border-box;top:3px;left:3px;width:12px;height:12px;border-radius:50%;transition:transform .1s ease;background-color:#1e1e1e;border:5px solid #1e1e1e}@media (prefers-reduced-motion:reduce){.components-form-toggle .components-form-toggle__thumb{transition-duration:0s}}.components-form-toggle.is-checked .components-form-toggle__track{background-color:#007cba;background-color:var(--wp-admin-theme-color);border:9px solid transparent}.components-form-toggle .components-form-toggle__input:focus+.components-form-toggle__track{box-shadow:0 0 0 2px #fff,0 0 0 3.5px #007cba;box-shadow:0 0 0 2px #fff,0 0 0 3.5px var(--wp-admin-theme-color);outline:2px solid transparent;outline-offset:2px}.components-form-toggle.is-checked .components-form-toggle__thumb{background-color:#fff;border-width:0;transform:translateX(18px)}.components-disabled .components-form-toggle{opacity:.3}.components-form-toggle input.components-form-toggle__input[type=checkbox]{position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;margin:0;padding:0;z-index:1;border:none}.components-form-toggle input.components-form-toggle__input[type=checkbox]:checked{background:none}.components-form-toggle input.components-form-toggle__input[type=checkbox]:before{content:""}.components-notice{display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;background-color:#fff;border-left:4px solid #007cba;border-left:4px solid var(--wp-admin-theme-color);margin:5px 15px 2px;padding:8px 12px;align-items:center}.components-notice.is-dismissible{padding-right:36px;position:relative}.components-notice.is-success{border-left-color:#4ab866;background-color:#eff9f1}.components-notice.is-warning{border-left-color:#ffb900;background-color:#ffeab3}.components-notice.is-error{border-left-color:#d94f4f;background-color:#f9e2e2}.components-notice__content{flex-grow:1;margin:4px 25px 4px 0}.components-notice__action.components-button,.components-notice__action.components-button.is-link{margin-left:12px}.components-notice__action.components-button.is-secondary{vertical-align:initial}.components-notice__dismiss{color:#757575;align-self:flex-start;flex-shrink:0}.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):focus,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):active,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{color:#1e1e1e;background-color:transparent}.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{box-shadow:none}.components-notice-list{max-width:100vw;box-sizing:border-box;z-index:29}.components-notice-list .components-notice__content{margin-top:12px;margin-bottom:12px;line-height:2}.components-notice-list .components-notice__action.components-button{display:block;margin-left:0;margin-top:8px}.components-select-control__input{background:#fff;height:36px;line-height:36px;margin:1px;outline:0;width:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)!important}@media (min-width:782px){.components-select-control__input{height:28px;line-height:28px}}@media (max-width:782px){.components-base-control .components-base-control__field .components-select-control__input{font-size:16px}}.components-snackbar{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;background-color:#1e1e1e;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.3);color:#fff;padding:16px 24px;width:100%;max-width:600px;box-sizing:border-box;cursor:pointer}@media (min-width:600px){.components-snackbar{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}}.components-snackbar:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px #007cba;box-shadow:0 0 0 1px #fff,0 0 0 3px var(--wp-admin-theme-color)}.components-snackbar__action.components-button{margin-left:32px;color:#fff;height:auto;flex-shrink:0;line-height:1.4;padding:0}.components-snackbar__action.components-button:not(:disabled):not([aria-disabled=true]):not(.is-secondary){text-decoration:underline;background-color:transparent}.components-snackbar__action.components-button:not(:disabled):not([aria-disabled=true]):not(.is-secondary):focus{color:#fff;box-shadow:none;outline:1px dotted #fff}.components-snackbar__action.components-button:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{color:#007cba;color:var(--wp-admin-theme-color)}.components-snackbar__content{display:flex;align-items:baseline;justify-content:space-between;line-height:1.4}.components-snackbar-list{position:absolute;z-index:100000;width:100%;box-sizing:border-box}.components-snackbar-list__notice-container{position:relative;padding-top:8px}.components-spinner{display:inline-block;background-color:#949494;width:18px;height:18px;opacity:.7;margin:5px 11px 0;border-radius:100%;position:relative}.components-spinner:before{content:"";position:absolute;background-color:#fff;top:3px;left:3px;width:4px;height:4px;border-radius:100%;transform-origin:6px 6px;animation:components-spinner__animation 1s linear infinite}@keyframes components-spinner__animation{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{width:100%;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;padding:6px 8px;box-shadow:0 0 0 transparent;transition:box-shadow .1s linear;border-radius:2px;border:1px solid #757575;font-size:16px;line-height:normal}@media (prefers-reduced-motion:reduce){.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{transition-duration:0s}}@media (min-width:600px){.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{font-size:13px;line-height:normal}}.components-text-control__input:focus,.components-text-control__input[type=color]:focus,.components-text-control__input[type=date]:focus,.components-text-control__input[type=datetime-local]:focus,.components-text-control__input[type=datetime]:focus,.components-text-control__input[type=email]:focus,.components-text-control__input[type=month]:focus,.components-text-control__input[type=number]:focus,.components-text-control__input[type=password]:focus,.components-text-control__input[type=tel]:focus,.components-text-control__input[type=text]:focus,.components-text-control__input[type=time]:focus,.components-text-control__input[type=url]:focus,.components-text-control__input[type=week]:focus{border-color:#007cba;border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px #007cba;box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-text-control__input::-webkit-input-placeholder,.components-text-control__input[type=color]::-webkit-input-placeholder,.components-text-control__input[type=date]::-webkit-input-placeholder,.components-text-control__input[type=datetime-local]::-webkit-input-placeholder,.components-text-control__input[type=datetime]::-webkit-input-placeholder,.components-text-control__input[type=email]::-webkit-input-placeholder,.components-text-control__input[type=month]::-webkit-input-placeholder,.components-text-control__input[type=number]::-webkit-input-placeholder,.components-text-control__input[type=password]::-webkit-input-placeholder,.components-text-control__input[type=tel]::-webkit-input-placeholder,.components-text-control__input[type=text]::-webkit-input-placeholder,.components-text-control__input[type=time]::-webkit-input-placeholder,.components-text-control__input[type=url]::-webkit-input-placeholder,.components-text-control__input[type=week]::-webkit-input-placeholder{color:rgba(30,30,30,.62)}.components-text-control__input::-moz-placeholder,.components-text-control__input[type=color]::-moz-placeholder,.components-text-control__input[type=date]::-moz-placeholder,.components-text-control__input[type=datetime-local]::-moz-placeholder,.components-text-control__input[type=datetime]::-moz-placeholder,.components-text-control__input[type=email]::-moz-placeholder,.components-text-control__input[type=month]::-moz-placeholder,.components-text-control__input[type=number]::-moz-placeholder,.components-text-control__input[type=password]::-moz-placeholder,.components-text-control__input[type=tel]::-moz-placeholder,.components-text-control__input[type=text]::-moz-placeholder,.components-text-control__input[type=time]::-moz-placeholder,.components-text-control__input[type=url]::-moz-placeholder,.components-text-control__input[type=week]::-moz-placeholder{opacity:1;color:rgba(30,30,30,.62)}.components-text-control__input:-ms-input-placeholder,.components-text-control__input[type=color]:-ms-input-placeholder,.components-text-control__input[type=date]:-ms-input-placeholder,.components-text-control__input[type=datetime-local]:-ms-input-placeholder,.components-text-control__input[type=datetime]:-ms-input-placeholder,.components-text-control__input[type=email]:-ms-input-placeholder,.components-text-control__input[type=month]:-ms-input-placeholder,.components-text-control__input[type=number]:-ms-input-placeholder,.components-text-control__input[type=password]:-ms-input-placeholder,.components-text-control__input[type=tel]:-ms-input-placeholder,.components-text-control__input[type=text]:-ms-input-placeholder,.components-text-control__input[type=time]:-ms-input-placeholder,.components-text-control__input[type=url]:-ms-input-placeholder,.components-text-control__input[type=week]:-ms-input-placeholder{color:rgba(30,30,30,.62)}.is-dark-theme .components-text-control__input::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=color]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=date]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=datetime-local]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=datetime]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=email]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=month]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=number]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=password]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=tel]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=text]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=time]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=url]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=week]::-webkit-input-placeholder{color:hsla(0,0%,100%,.65)}.is-dark-theme .components-text-control__input::-moz-placeholder,.is-dark-theme .components-text-control__input[type=color]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=date]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=datetime-local]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=datetime]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=email]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=month]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=number]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=password]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=tel]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=text]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=time]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=url]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=week]::-moz-placeholder{opacity:1;color:hsla(0,0%,100%,.65)}.is-dark-theme .components-text-control__input:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=color]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=date]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=datetime-local]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=datetime]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=email]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=month]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=number]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=password]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=tel]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=text]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=time]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=url]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=week]:-ms-input-placeholder{color:hsla(0,0%,100%,.65)}.components-tooltip.components-popover{z-index:1000002}.components-tooltip.components-popover .components-popover__content{min-width:0}.components-tooltip .components-popover__content{background:#1e1e1e;border-radius:2px;border-width:0;color:#fff;white-space:nowrap;text-align:center;line-height:1.4;font-size:12px;box-shadow:none}.components-tooltip .components-popover__content>div{padding:4px 8px}.components-tooltip__shortcut{display:inline-block;margin-left:8px}/*!rtl:begin:ignore*/.components-popover{position:fixed;z-index:1000000;top:0;left:0;opacity:0}.components-popover.is-expanded,.components-popover[data-x-axis][data-y-axis]{opacity:1}.components-popover.is-expanded{top:0;left:0;right:0;bottom:0;z-index:1000000!important}.components-popover:not(.is-without-arrow){margin-left:2px}.components-popover:not(.is-without-arrow):before{border:8px solid #ccc}.components-popover:not(.is-without-arrow).is-alternate:before{border-color:#1e1e1e}.components-popover:not(.is-without-arrow):after{border:8px solid #fff}.components-popover:not(.is-without-arrow):after,.components-popover:not(.is-without-arrow):before{content:"";position:absolute;height:0;width:0;line-height:0}.components-popover:not(.is-without-arrow)[data-y-axis=top]{margin-top:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=top]:before{bottom:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=top]:after{bottom:-6px}.components-popover:not(.is-without-arrow)[data-y-axis=top]:after,.components-popover:not(.is-without-arrow)[data-y-axis=top]:before{border-bottom:none;border-left-color:transparent;border-right-color:transparent;border-top-style:solid;margin-left:-10px}.components-popover:not(.is-without-arrow)[data-y-axis=bottom]{margin-top:8px}.components-popover:not(.is-without-arrow)[data-y-axis=bottom]:before{top:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=bottom]:after{top:-6px}.components-popover:not(.is-without-arrow)[data-y-axis=bottom]:after,.components-popover:not(.is-without-arrow)[data-y-axis=bottom]:before{border-bottom-style:solid;border-left-color:transparent;border-right-color:transparent;border-top:none;margin-left:-10px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]{margin-left:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]:before{right:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]:after{right:-6px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]:after,.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]:before{border-bottom-color:transparent;border-left-style:solid;border-right:none;border-top-color:transparent}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]{margin-left:8px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]:before{left:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]:after{left:-6px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]:after,.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]:before{border-bottom-color:transparent;border-left:none;border-right-style:solid;border-top-color:transparent}.components-popover[data-y-axis=top]{bottom:100%}.components-popover[data-y-axis=bottom]{top:100%}.components-popover[data-y-axis=middle]{align-items:center;display:flex}.components-popover.is-from-top{margin-top:12px}.components-popover.is-from-bottom{margin-top:-12px}.components-popover.is-from-left:not(.is-from-top):not(.is-from-bottom){margin-left:12px}.components-popover.is-from-right:not(.is-from-top):not(.is-from-bottom){margin-right:12px}.components-popover__content{height:100%;background:#fff;border:1px solid #ccc;box-shadow:0 2px 6px rgba(0,0,0,.05);border-radius:2px}.is-alternate .components-popover__content{border:1px solid #1e1e1e;box-shadow:none}.components-popover .components-popover__content{position:absolute;height:auto;overflow-y:auto;min-width:260px}.components-popover.is-expanded .components-popover__content{position:static;height:calc(100% - 48px);overflow-y:visible;min-width:auto;border:none;border-top:1px solid #1e1e1e}.components-popover[data-y-axis=top] .components-popover__content{bottom:100%}.components-popover[data-x-axis=center] .components-popover__content{left:50%;transform:translateX(-50%)}.components-popover[data-x-axis=right] .components-popover__content{position:absolute;left:100%}.components-popover:not([data-y-axis=middle])[data-x-axis=right] .components-popover__content{margin-left:-25px}.components-popover[data-x-axis=left] .components-popover__content{position:absolute;right:100%}.components-popover:not([data-y-axis=middle])[data-x-axis=left] .components-popover__content{margin-right:-25px}.components-popover__header{align-items:center;background:#fff;display:flex;height:48px;justify-content:space-between;padding:0 8px 0 16px}.components-popover__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.components-popover__close.components-button{z-index:5}/*!rtl:end:ignore*/.components-radio-control{display:flex;flex-direction:column}.components-radio-control .components-base-control__help{margin-top:0}.components-radio-control .components-base-control__field{margin-bottom:0}.components-radio-control__option:not(:last-child){margin-bottom:4px}.components-radio-control__input[type=radio]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;padding:6px 8px;box-shadow:0 0 0 transparent;transition:box-shadow .1s linear;border-radius:2px;font-size:16px;line-height:normal;border:1px solid #1e1e1e;transition:none;border-radius:50%;margin-top:0;margin-right:6px}@media (prefers-reduced-motion:reduce){.components-radio-control__input[type=radio]{transition-duration:0s}}@media (min-width:600px){.components-radio-control__input[type=radio]{font-size:13px;line-height:normal}}.components-radio-control__input[type=radio]:focus{border-color:#007cba;border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px #007cba;box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.components-radio-control__input[type=radio]::-webkit-input-placeholder{color:rgba(30,30,30,.62)}.components-radio-control__input[type=radio]::-moz-placeholder{opacity:1;color:rgba(30,30,30,.62)}.components-radio-control__input[type=radio]:-ms-input-placeholder{color:rgba(30,30,30,.62)}.is-dark-theme .components-radio-control__input[type=radio]::-webkit-input-placeholder{color:hsla(0,0%,100%,.65)}.is-dark-theme .components-radio-control__input[type=radio]::-moz-placeholder{opacity:1;color:hsla(0,0%,100%,.65)}.is-dark-theme .components-radio-control__input[type=radio]:-ms-input-placeholder{color:hsla(0,0%,100%,.65)}.components-radio-control__input[type=radio]:checked:before{width:7px;height:7px;margin:8px 0 0 8px;background-color:#fff;border:3px solid #fff}@media (min-width:782px){.components-radio-control__input[type=radio]:checked:before{width:6px;height:6px;margin:4px 0 0 4px}}.components-radio-control__input[type=radio]:focus{box-shadow:0 0 0 2px #fff,0 0 0 3.5px #007cba;box-shadow:0 0 0 2px #fff,0 0 0 3.5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-radio-control__input[type=radio]:checked{background:#007cba;background:var(--wp-admin-theme-color);border-color:#007cba;border-color:var(--wp-admin-theme-color)}.components-menu-group+.components-menu-group{margin-top:8px;padding-top:8px;border-top:1px solid #1e1e1e}.components-menu-group__label{padding:0 8px;margin-top:4px;margin-bottom:12px;color:#757575;text-transform:uppercase;font-size:11px;font-weight:500}.components-menu-item__button,.components-menu-item__button.components-button{width:100%}.components-menu-item__button.components-button .components-menu-items__item-icon,.components-menu-item__button .components-menu-items__item-icon{margin-right:-2px;margin-left:auto;display:inline-block;flex:0 0 auto}.components-menu-item__button.components-button .components-menu-item__shortcut+.components-menu-items__item-icon,.components-menu-item__button .components-menu-item__shortcut+.components-menu-items__item-icon{margin-left:8px}.components-menu-item__button .block-editor-block-icon,.components-menu-item__button.components-button .block-editor-block-icon{margin-left:-2px;margin-right:8px}.components-menu-item__info-wrapper{display:flex;flex-direction:column}.components-menu-item__info{margin-top:4px;font-size:12px;color:#757575}.components-menu-item__shortcut{-ms-grid-row-align:center;align-self:center;margin-right:0;margin-left:auto;padding-left:12px;color:currentColor;display:none}@media (min-width:480px){.components-menu-item__shortcut{display:inline}}.components-modal__screen-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,.7);z-index:100000;animation:edit-post__fade-in-animation .2s ease-out 0s;animation-fill-mode:forwards}@media (prefers-reduced-motion:reduce){.components-modal__screen-overlay{animation-duration:1ms}}.components-modal__frame{position:absolute;top:0;right:0;bottom:0;left:0;box-sizing:border-box;margin:0;border:1px solid #ddd;background:#fff;box-shadow:0 3px 30px rgba(0,0,0,.2);overflow:auto}@media (min-width:600px){.components-modal__frame{top:50%;right:auto;bottom:auto;left:50%;min-width:360px;max-width:calc(100% - 32px);max-height:calc(100% - 120px);transform:translate(-50%,-50%);animation:components-modal__appear-animation .1s ease-out;animation-fill-mode:forwards}}@media (min-width:600px) and (prefers-reduced-motion:reduce){.components-modal__frame{animation-duration:1ms}}@keyframes components-modal__appear-animation{0%{margin-top:32px}to{margin-top:0}}.components-modal__header{box-sizing:border-box;border-bottom:1px solid #ddd;padding:0 24px;display:flex;flex-direction:row;justify-content:space-between;background:#fff;align-items:center;height:60px;z-index:10;position:relative;position:-webkit-sticky;position:sticky;top:0;margin:0 -24px 24px}@supports (-ms-ime-align:auto){.components-modal__header{position:fixed;width:100%}}.components-modal__header .components-modal__header-heading{font-size:1rem;font-weight:600}.components-modal__header h1{line-height:1;margin:0}.components-modal__header .components-button{position:relative;left:8px}.components-modal__header-heading-container{align-items:center;flex-grow:1;display:flex;flex-direction:row;justify-content:left}.components-modal__header-icon-container{display:inline-block}.components-modal__header-icon-container svg{max-width:36px;max-height:36px;padding:8px}.components-modal__content{box-sizing:border-box;height:100%;padding:0 24px 24px}@supports (-ms-ime-align:auto){.components-modal__content{padding-top:60px}}.components-base-control{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.components-base-control .components-base-control__field{margin-bottom:8px}.components-panel__row .components-base-control .components-base-control__field{margin-bottom:inherit}.components-base-control .components-base-control__label{display:inline-block;margin-bottom:8px}.components-base-control .components-base-control__help{margin-top:-8px;font-style:italic}.PresetDateRangePicker_panel{padding:0 22px 11px}.PresetDateRangePicker_button{position:relative;height:100%;text-align:center;background:0 0;border:2px solid #00a699;color:#00a699;padding:4px 12px;margin-right:8px;font:inherit;font-weight:700;line-height:normal;overflow:visible;box-sizing:border-box;cursor:pointer}.PresetDateRangePicker_button:active{outline:0}.PresetDateRangePicker_button__selected{color:#fff;background:#00a699}.SingleDatePickerInput{display:inline-block;background-color:#fff}.SingleDatePickerInput__withBorder{border-radius:2px;border:1px solid #dbdbdb}.SingleDatePickerInput__rtl{direction:rtl}.SingleDatePickerInput__disabled{background-color:#f2f2f2}.SingleDatePickerInput__block{display:block}.SingleDatePickerInput__showClearDate{padding-right:30px}.SingleDatePickerInput_clearDate{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;padding:10px;margin:0 10px 0 5px;position:absolute;right:0;top:50%;transform:translateY(-50%)}.SingleDatePickerInput_clearDate__default:focus,.SingleDatePickerInput_clearDate__default:hover{background:#dbdbdb;border-radius:50%}.SingleDatePickerInput_clearDate__small{padding:6px}.SingleDatePickerInput_clearDate__hide{visibility:hidden}.SingleDatePickerInput_clearDate_svg{fill:#82888a;height:12px;width:15px;vertical-align:middle}.SingleDatePickerInput_clearDate_svg__small{height:9px}.SingleDatePickerInput_calendarIcon{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;display:inline-block;vertical-align:middle;padding:10px;margin:0 5px 0 10px}.SingleDatePickerInput_calendarIcon_svg{fill:#82888a;height:15px;width:14px;vertical-align:middle}.SingleDatePicker{position:relative;display:inline-block}.SingleDatePicker__block{display:block}.SingleDatePicker_picker{z-index:1;background-color:#fff;position:absolute}.SingleDatePicker_picker__rtl{direction:rtl}.SingleDatePicker_picker__directionLeft{left:0}.SingleDatePicker_picker__directionRight{right:0}.SingleDatePicker_picker__portal{background-color:rgba(0,0,0,.3);position:fixed;top:0;left:0;height:100%;width:100%}.SingleDatePicker_picker__fullScreenPortal{background-color:#fff}.SingleDatePicker_closeButton{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;position:absolute;top:0;right:0;padding:15px;z-index:2}.SingleDatePicker_closeButton:focus,.SingleDatePicker_closeButton:hover{color:#b0b3b4;text-decoration:none}.SingleDatePicker_closeButton_svg{height:15px;width:15px;fill:#cacccd}.DayPickerKeyboardShortcuts_buttonReset{background:0 0;border:0;border-radius:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;cursor:pointer;font-size:14px}.DayPickerKeyboardShortcuts_buttonReset:active{outline:0}.DayPickerKeyboardShortcuts_show{width:22px;position:absolute;z-index:2}.DayPickerKeyboardShortcuts_show__bottomRight{border-top:26px solid transparent;border-right:33px solid #00a699;bottom:0;right:0}.DayPickerKeyboardShortcuts_show__bottomRight:hover{border-right:33px solid #008489}.DayPickerKeyboardShortcuts_show__topRight{border-bottom:26px solid transparent;border-right:33px solid #00a699;top:0;right:0}.DayPickerKeyboardShortcuts_show__topRight:hover{border-right:33px solid #008489}.DayPickerKeyboardShortcuts_show__topLeft{border-bottom:26px solid transparent;border-left:33px solid #00a699;top:0;left:0}.DayPickerKeyboardShortcuts_show__topLeft:hover{border-left:33px solid #008489}.DayPickerKeyboardShortcuts_showSpan{color:#fff;position:absolute}.DayPickerKeyboardShortcuts_showSpan__bottomRight{bottom:0;right:-28px}.DayPickerKeyboardShortcuts_showSpan__topRight{top:1px;right:-28px}.DayPickerKeyboardShortcuts_showSpan__topLeft{top:1px;left:-28px}.DayPickerKeyboardShortcuts_panel{overflow:auto;background:#fff;border:1px solid #dbdbdb;border-radius:2px;position:absolute;top:0;bottom:0;right:0;left:0;z-index:2;padding:22px;margin:33px}.DayPickerKeyboardShortcuts_title{font-size:16px;font-weight:700;margin:0}.DayPickerKeyboardShortcuts_list{list-style:none;padding:0;font-size:14px}.DayPickerKeyboardShortcuts_close{position:absolute;right:22px;top:22px;z-index:2}.DayPickerKeyboardShortcuts_close:active{outline:0}.DayPickerKeyboardShortcuts_closeSvg{height:15px;width:15px;fill:#cacccd}.DayPickerKeyboardShortcuts_closeSvg:focus,.DayPickerKeyboardShortcuts_closeSvg:hover{fill:#82888a}.CalendarDay{box-sizing:border-box;cursor:pointer;font-size:14px;text-align:center}.CalendarDay:active{outline:0}.CalendarDay__defaultCursor{cursor:default}.CalendarDay__default{border:1px solid #e4e7e7;color:#484848;background:#fff}.CalendarDay__default:hover{background:#e4e7e7;border:1px double #e4e7e7;color:inherit}.CalendarDay__hovered_offset{background:#f4f5f5;border:1px double #e4e7e7;color:inherit}.CalendarDay__outside{border:0;background:#fff;color:#484848}.CalendarDay__outside:hover{border:0}.CalendarDay__blocked_minimum_nights{background:#fff;border:1px solid #eceeee;color:#cacccd}.CalendarDay__blocked_minimum_nights:active,.CalendarDay__blocked_minimum_nights:hover{background:#fff;color:#cacccd}.CalendarDay__highlighted_calendar{background:#ffe8bc;color:#484848}.CalendarDay__highlighted_calendar:active,.CalendarDay__highlighted_calendar:hover{background:#ffce71;color:#484848}.CalendarDay__selected_span{background:#66e2da;border:1px solid #33dacd;color:#fff}.CalendarDay__selected_span:active,.CalendarDay__selected_span:hover{background:#33dacd;border:1px solid #33dacd;color:#fff}.CalendarDay__last_in_range{border-right:#00a699}.CalendarDay__selected,.CalendarDay__selected:active,.CalendarDay__selected:hover{background:#00a699;border:1px solid #00a699;color:#fff}.CalendarDay__hovered_span,.CalendarDay__hovered_span:hover{background:#b2f1ec;border:1px solid #80e8e0;color:#007a87}.CalendarDay__hovered_span:active{background:#80e8e0;border:1px solid #80e8e0;color:#007a87}.CalendarDay__blocked_calendar,.CalendarDay__blocked_calendar:active,.CalendarDay__blocked_calendar:hover{background:#cacccd;border:1px solid #cacccd;color:#82888a}.CalendarDay__blocked_out_of_range,.CalendarDay__blocked_out_of_range:active,.CalendarDay__blocked_out_of_range:hover{background:#fff;border:1px solid #e4e7e7;color:#cacccd}.CalendarMonth{background:#fff;text-align:center;vertical-align:top;-webkit-user-select:none;-ms-user-select:none;user-select:none}.CalendarMonth_table{border-collapse:collapse;border-spacing:0}.CalendarMonth_verticalSpacing{border-collapse:separate}.CalendarMonth_caption{color:#484848;font-size:18px;text-align:center;padding-top:22px;padding-bottom:37px;caption-side:top}.CalendarMonth_caption__verticalScrollable{padding-top:12px;padding-bottom:7px}.CalendarMonthGrid{background:#fff;text-align:left;z-index:0}.CalendarMonthGrid__animating{z-index:1}.CalendarMonthGrid__horizontal{position:absolute;left:9px}.CalendarMonthGrid__vertical{margin:0 auto}.CalendarMonthGrid__vertical_scrollable{margin:0 auto;overflow-y:scroll}.CalendarMonthGrid_month__horizontal{display:inline-block;vertical-align:top;min-height:100%}.CalendarMonthGrid_month__hideForAnimation{position:absolute;z-index:-1;opacity:0;pointer-events:none}.CalendarMonthGrid_month__hidden{visibility:hidden}.DayPickerNavigation{position:relative;z-index:2}.DayPickerNavigation__horizontal{height:0}.DayPickerNavigation__verticalDefault{position:absolute;width:100%;height:52px;bottom:0;left:0}.DayPickerNavigation__verticalScrollableDefault{position:relative}.DayPickerNavigation_button{cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:0;padding:0;margin:0}.DayPickerNavigation_button__default{border:1px solid #e4e7e7;background-color:#fff;color:#757575}.DayPickerNavigation_button__default:focus,.DayPickerNavigation_button__default:hover{border:1px solid #c4c4c4}.DayPickerNavigation_button__default:active{background:#f2f2f2}.DayPickerNavigation_button__horizontalDefault{position:absolute;top:18px;line-height:.78;border-radius:3px;padding:6px 9px}.DayPickerNavigation_leftButton__horizontalDefault{left:22px}.DayPickerNavigation_rightButton__horizontalDefault{right:22px}.DayPickerNavigation_button__verticalDefault{padding:5px;background:#fff;box-shadow:0 0 5px 2px rgba(0,0,0,.1);position:relative;display:inline-block;height:100%;width:50%}.DayPickerNavigation_nextButton__verticalDefault{border-left:0}.DayPickerNavigation_nextButton__verticalScrollableDefault{width:100%}.DayPickerNavigation_svg__horizontal{height:19px;width:19px;fill:#82888a;display:block}.DayPickerNavigation_svg__vertical{height:42px;width:42px;fill:#484848;display:block}.DayPicker{position:relative;text-align:left}.DayPicker,.DayPicker__horizontal{background:#fff}.DayPicker__verticalScrollable{height:100%}.DayPicker__hidden{visibility:hidden}.DayPicker__withBorder{box-shadow:0 2px 6px rgba(0,0,0,.05),0 0 0 1px rgba(0,0,0,.07);border-radius:3px}.DayPicker_portal__horizontal{box-shadow:none;position:absolute;left:50%;top:50%}.DayPicker_portal__vertical{position:static}.DayPicker_focusRegion{outline:0}.DayPicker_calendarInfo__horizontal,.DayPicker_wrapper__horizontal{display:inline-block;vertical-align:top}.DayPicker_weekHeaders{position:relative}.DayPicker_weekHeaders__horizontal{margin-left:9px}.DayPicker_weekHeader{color:#757575;position:absolute;top:62px;z-index:2;text-align:left}.DayPicker_weekHeader__vertical{left:50%}.DayPicker_weekHeader__verticalScrollable{top:0;display:table-row;border-bottom:1px solid #dbdbdb;background:#fff;margin-left:0;left:0;width:100%;text-align:center}.DayPicker_weekHeader_ul{list-style:none;margin:1px 0;padding-left:0;padding-right:0;font-size:14px}.DayPicker_weekHeader_li{display:inline-block;text-align:center}.DayPicker_transitionContainer{position:relative;overflow:hidden;border-radius:3px}.DayPicker_transitionContainer__horizontal{transition:height .2s ease-in-out}.DayPicker_transitionContainer__vertical{width:100%}.DayPicker_transitionContainer__verticalScrollable{padding-top:20px;height:100%;position:absolute;top:0;bottom:0;right:0;left:0;overflow-y:scroll}.DateInput{margin:0;padding:0;background:#fff;position:relative;display:inline-block;width:130px;vertical-align:middle}.DateInput__small{width:97px}.DateInput__block{width:100%}.DateInput__disabled{background:#f2f2f2;color:#dbdbdb}.DateInput_input{font-weight:200;font-size:19px;line-height:24px;color:#484848;background-color:#fff;width:100%;padding:11px 11px 9px;border:0;border-bottom:2px solid transparent;border-radius:0}.DateInput_input__small{font-size:15px;line-height:18px;letter-spacing:.2px;padding:7px 7px 5px}.DateInput_input__regular{font-weight:auto}.DateInput_input__readOnly{-webkit-user-select:none;-ms-user-select:none;user-select:none}.DateInput_input__focused{outline:0;background:#fff;border:0;border-bottom:2px solid #008489}.DateInput_input__disabled{background:#f2f2f2;font-style:italic}.DateInput_screenReaderMessage{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.DateInput_fang{position:absolute;width:20px;height:10px;left:22px;z-index:2}.DateInput_fangShape{fill:#fff}.DateInput_fangStroke{stroke:#dbdbdb;fill:transparent}.DateRangePickerInput{background-color:#fff;display:inline-block}.DateRangePickerInput__disabled{background:#f2f2f2}.DateRangePickerInput__withBorder{border-radius:2px;border:1px solid #dbdbdb}.DateRangePickerInput__rtl{direction:rtl}.DateRangePickerInput__block{display:block}.DateRangePickerInput__showClearDates{padding-right:30px}.DateRangePickerInput_arrow{display:inline-block;vertical-align:middle;color:#484848}.DateRangePickerInput_arrow_svg{vertical-align:middle;fill:#484848;height:24px;width:24px}.DateRangePickerInput_clearDates{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;padding:10px;margin:0 10px 0 5px;position:absolute;right:0;top:50%;transform:translateY(-50%)}.DateRangePickerInput_clearDates__small{padding:6px}.DateRangePickerInput_clearDates_default:focus,.DateRangePickerInput_clearDates_default:hover{background:#dbdbdb;border-radius:50%}.DateRangePickerInput_clearDates__hide{visibility:hidden}.DateRangePickerInput_clearDates_svg{fill:#82888a;height:12px;width:15px;vertical-align:middle}.DateRangePickerInput_clearDates_svg__small{height:9px}.DateRangePickerInput_calendarIcon{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;display:inline-block;vertical-align:middle;padding:10px;margin:0 5px 0 10px}.DateRangePickerInput_calendarIcon_svg{fill:#82888a;height:15px;width:14px;vertical-align:middle}.DateRangePicker{position:relative;display:inline-block}.DateRangePicker__block{display:block}.DateRangePicker_picker{z-index:1;background-color:#fff;position:absolute}.DateRangePicker_picker__rtl{direction:rtl}.DateRangePicker_picker__directionLeft{left:0}.DateRangePicker_picker__directionRight{right:0}.DateRangePicker_picker__portal{background-color:rgba(0,0,0,.3);position:fixed;top:0;left:0;height:100%;width:100%}.DateRangePicker_picker__fullScreenPortal{background-color:#fff}.DateRangePicker_closeButton{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;position:absolute;top:0;right:0;padding:15px;z-index:2}.DateRangePicker_closeButton:focus,.DateRangePicker_closeButton:hover{color:#b0b3b4;text-decoration:none}.DateRangePicker_closeButton_svg{height:15px;width:15px;fill:#cacccd}.components-datetime{padding:0}.components-datetime .components-datetime__calendar-help{padding:16px}.components-datetime .components-datetime__calendar-help h4{margin:0}.components-datetime .components-datetime__buttons{display:flex;justify-content:space-between}.components-datetime .components-datetime__date-help-toggle{display:block;margin-left:auto}.components-datetime fieldset{border:0;padding:0;margin:0}.components-datetime input,.components-datetime select{box-shadow:0 0 0 transparent;transition:box-shadow .1s linear;border-radius:2px;border:1px solid #757575}@media (prefers-reduced-motion:reduce){.components-datetime input,.components-datetime select{transition-duration:0s}}.components-datetime .components-button,.components-datetime input[type=number],.components-datetime select{height:30px;margin-top:0;margin-bottom:0}.components-datetime__date{min-height:236px;border-top:1px solid #ddd}.components-datetime__date .DayPickerNavigation_leftButton__horizontalDefault{left:0}.components-datetime__date .CalendarMonth_caption{font-size:13px}.components-datetime__date .CalendarMonth_table{border-collapse:separate;border-spacing:2px}.components-datetime__date .CalendarDay{font-size:13px;border:none;border-radius:50%;text-align:center}.components-datetime__date .CalendarDay:focus{box-shadow:inset 0 0 0 1.5px #007cba,inset 0 0 0 2.5px #fff;box-shadow:inset 0 0 0 1.5px var(--wp-admin-theme-color),inset 0 0 0 2.5px #fff;outline:2px solid transparent}.components-datetime__date .CalendarDay__selected{background:#007cba;background:var(--wp-admin-theme-color);border:2px solid transparent}.components-datetime__date .CalendarDay__selected:hover{background:#005a87;background:var(--wp-admin-theme-color-darker-20)}.components-datetime__date .CalendarDay__selected:focus{box-shadow:inset 0 0 0 1px #fff}.components-datetime__date .DayPickerNavigation_button__horizontalDefault{padding:2px 8px;top:20px}.components-datetime__date .DayPickerNavigation_button__horizontalDefault:focus{border-color:#007cba;border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px #007cba;box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-datetime__date .DayPicker_weekHeader{top:50px}.components-datetime__date .DayPicker_weekHeader .DayPicker_weekHeader_ul{margin:1px 0;padding-left:0;padding-right:0}.components-datetime__date.is-description-visible .DayPicker{visibility:hidden}.components-datetime__time{padding-bottom:16px}.components-datetime__time fieldset{position:relative;margin-bottom:.5em}.components-datetime__time fieldset+fieldset{margin-bottom:0}.components-datetime__time .components-datetime__time-field-am-pm fieldset{margin-top:0}.components-datetime__time .components-datetime__time-wrapper{display:flex}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-separator{display:inline-block;padding:0 3px 0 0}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field-time{direction:ltr}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field select{margin-right:4px}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field select:focus{position:relative;z-index:1}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field input[type=number]{padding:2px;margin-right:4px;text-align:center;-moz-appearance:textfield}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field input[type=number]:focus{position:relative;z-index:1}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.components-datetime__time.is-12-hour .components-datetime__time-field-day input{margin:-4px 0 0!important;border-radius:2px 0 0 2px!important}.components-datetime__time.is-12-hour .components-datetime__time-field-year input{border-radius:0 2px 2px 0!important}.components-datetime__timezone{line-height:30px;margin-left:4px;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.components-datetime__time-legend{font-weight:600;margin-top:.5em}.components-datetime__time-legend.invisible{position:absolute;top:-999em;left:-999em}.components-datetime__time-field-day-input,.components-datetime__time-field-hours-input,.components-datetime__time-field-minutes-input{width:35px}.components-datetime__time-field-year-input{width:55px}.components-datetime__time-field-month-select{max-width:145px}.components-popover .components-datetime__date{padding-left:4px}.components-drop-zone{position:absolute;top:0;right:0;bottom:0;left:0;z-index:40;visibility:hidden;opacity:0;transition:opacity .3s,background-color .3s,visibility 0s .3s;border:2px solid #007cba;border:2px solid var(--wp-admin-theme-color);border-radius:2px}@media (prefers-reduced-motion:reduce){.components-drop-zone{transition-duration:0s}}.components-drop-zone.is-active{opacity:1;visibility:visible;transition:opacity .3s,background-color .3s}@media (prefers-reduced-motion:reduce){.components-drop-zone.is-active{transition-duration:0s}}.components-drop-zone.is-dragging-over-element{background-color:#007cba;background-color:var(--wp-admin-theme-color)}.components-drop-zone__content{position:absolute;top:50%;left:0;right:0;z-index:50;transform:translateY(-50%);width:100%;text-align:center;color:#fff;transition:transform .2s ease-in-out}@media (prefers-reduced-motion:reduce){.components-drop-zone__content{transition-duration:0s}}.components-drop-zone.is-dragging-over-element .components-drop-zone__content{transform:translateY(-50%) scale(1.05)}.components-drop-zone__content-icon,.components-drop-zone__content-text{display:block}.components-drop-zone__content-icon{margin:0 auto;line-height:0;fill:currentColor}.components-drop-zone__content-text{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}.components-drop-zone__provider{height:100%}.components-tab-panel__tabs{display:flex;align-items:stretch}.components-tab-panel__tabs-item{background:transparent;border:none;box-shadow:none;border-radius:0;cursor:pointer;height:48px;padding:3px 16px;margin-left:0;font-weight:500;transition:box-shadow .1s linear;box-sizing:border-box}.components-tab-panel__tabs-item:after{content:attr(data-label);display:block;height:0;overflow:hidden;speak:none;visibility:hidden}.components-tab-panel__tabs-item:focus:not(:disabled){box-shadow:inset 0 1.5px #007cba;box-shadow:inset 0 1.5px var(--wp-admin-theme-color)}.components-tab-panel__tabs-item.is-active{box-shadow:inset 0 0 0 1.5px transparent,inset 0 -4px 0 0 #007cba;box-shadow:inset 0 0 0 1.5px transparent,inset 0 -4px 0 0 var(--wp-admin-theme-color);position:relative}.components-tab-panel__tabs-item.is-active:before{content:"";position:absolute;top:0;bottom:1px;right:0;left:0;border-bottom:4px solid transparent}.components-tab-panel__tabs-item:focus{box-shadow:inset 0 0 0 1.5px #007cba;box-shadow:inset 0 0 0 1.5px var(--wp-admin-theme-color)}.components-tab-panel__tabs-item.is-active:focus{box-shadow:inset 0 0 0 1.5px #007cba,inset 0 -4px 0 0 #007cba;box-shadow:inset 0 0 0 1.5px var(--wp-admin-theme-color),inset 0 -4px 0 0 var(--wp-admin-theme-color)}@media (min-width:600px){.components-guide{width:600px}}.components-guide .components-modal__header{background:none;border-bottom:none;width:100%;padding:0;margin:0}.components-guide .components-modal__header .components-button{align-self:flex-start;margin:8px 8px 0 0;position:static}.components-guide .components-modal__header .components-button:hover svg{fill:#fff}.components-guide__container{display:flex;flex-direction:column;justify-content:space-between;margin-top:-60px;min-height:100%}.components-guide__page{display:flex;flex-direction:column;justify-content:center;position:relative}@media (min-width:600px){.components-guide__page{min-height:300px}}.components-guide__footer{align-content:center;display:flex;height:30px;justify-content:center;margin:0 0 24px;padding:0 32px;position:relative;width:100%}@media (max-width:600px){.components-guide__footer{position:absolute;bottom:0}}.components-guide__page-control{margin:8px 0;text-align:center}.components-guide__page-control li{display:inline-block}.components-guide__page-control .components-button{height:30px;min-width:20px}.components-guide .components-modal__content{padding:0}.components-modal__frame.components-guide{border:none;min-width:312px;height:80vh;max-height:575px}@media (max-width:600px){.components-modal__frame.components-guide{bottom:5%;left:16px;right:16px;top:5%;margin:0 auto}}.components-button.components-guide__back-button,.components-button.components-guide__finish-button,.components-button.components-guide__forward-button{height:30px;position:absolute}.components-button.components-guide__back-button,.components-button.components-guide__forward-button{font-size:13px;padding:4px 2px}.components-button.components-guide__back-button.has-text svg,.components-button.components-guide__forward-button.has-text svg{margin:0}.components-button.components-guide__back-button:hover,.components-button.components-guide__forward-button:hover{text-decoration:underline}.components-button.components-guide__back-button{left:32px}.components-button.components-guide__forward-button{right:32px;color:#1386bf;font-weight:700}.components-button.components-guide__finish-button{right:32px}.components-button.components-guide__inline-finish-button{display:none}.components-animate__appear{animation:components-animate__appear-animation .1s cubic-bezier(0,0,.2,1) 0s;animation-fill-mode:forwards}@media (prefers-reduced-motion:reduce){.components-animate__appear{animation-duration:1ms}}.components-animate__appear.is-from-top,.components-animate__appear.is-from-top.is-from-left{transform-origin:top left}.components-animate__appear.is-from-top.is-from-right{transform-origin:top right}.components-animate__appear.is-from-bottom,.components-animate__appear.is-from-bottom.is-from-left{transform-origin:bottom left}.components-animate__appear.is-from-bottom.is-from-right{transform-origin:bottom right}@keyframes components-animate__appear-animation{0%{transform:translateY(-2em) scaleY(0) scaleX(0)}to{transform:translateY(0) scaleY(1) scaleX(1)}}.components-animate__slide-in{animation:components-animate__slide-in-animation .1s cubic-bezier(0,0,.2,1);animation-fill-mode:forwards}@media (prefers-reduced-motion:reduce){.components-animate__slide-in{animation-duration:1ms}}.components-animate__slide-in.is-from-left{transform:translateX(100%)}.components-animate__slide-in.is-from-right{transform:translateX(-100%)}@keyframes components-animate__slide-in-animation{to{transform:translateX(0)}}.components-animate__loading{animation:components-animate__loading 1.6s ease-in-out infinite}@keyframes components-animate__loading{0%{opacity:.5}50%{opacity:1}to{opacity:.5}}.woocommerce-layout{margin:0;padding:0}.woocommerce-layout__primary{margin:80px 0 0 40px;margin:80px 0 0 var(--large-gap)}@media (min-width:961px){.woocommerce-layout__primary{margin-top:100px}}@media (max-width:782px){.woocommerce-layout__primary{margin-top:60px}}.woocommerce-layout .woocommerce-layout__main{padding-right:40px;padding-right:var(--large-gap);max-width:100%}.woocommerce-admin-is-loading #adminmenumain,.woocommerce-admin-is-loading #wpadminbar,.woocommerce-admin-is-loading #wpbody-content,.woocommerce-admin-is-loading #wpcontent,.woocommerce-admin-is-loading #wpfooter,.woocommerce-admin-is-loading .components-modal__screen-overlay,.woocommerce-admin-is-loading .error,.woocommerce-admin-is-loading .notice,.woocommerce-admin-is-loading .update-nag,.woocommerce-admin-is-loading .updated,.woocommerce-admin-is-loading .woocommerce-layout__header,.woocommerce-admin-is-loading .woocommerce-message,.woocommerce-admin-is-loading .woocommerce-store-alerts,.woocommerce-page .update-nag{display:none}.woocommerce-admin-full-screen{background:#f6f7f7;color:#50575e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;margin-top:-32px}.woocommerce-admin-full-screen #wpwrap{top:0}.woocommerce-admin-full-screen #wpbody-content{min-height:100vh}.woocommerce-admin-full-screen #adminmenumain,.woocommerce-admin-full-screen #wpcontent>*,.woocommerce-admin-full-screen .error,.woocommerce-admin-full-screen .notice,.woocommerce-admin-full-screen .update-nag,.woocommerce-admin-full-screen .updated,.woocommerce-admin-full-screen .woocommerce-layout__header,.woocommerce-admin-full-screen .woocommerce-message,.woocommerce-admin-full-screen .woocommerce-store-alerts{display:none}.woocommerce-admin-full-screen #wpcontent{margin-left:0!important}.woocommerce-admin-full-screen #wpcontent>#wpbody{display:block}.woocommerce-onboarding .muriel-component{margin-top:16px;margin-bottom:16px}.woocommerce-onboarding .components-base-control.has-error{margin-bottom:32px!important;border-color:#d63638}@media (max-width:782px){.woocommerce-onboarding .components-base-control.has-error{margin-bottom:44px!important}}.woocommerce-onboarding .components-base-control.has-error .components-base-control__help{top:100%;left:12px;position:absolute;margin-top:4px;font-size:12px;font-style:normal;color:#d63638}.woocommerce-onboarding .components-form-toggle{display:inline-block}.woocommerce-onboarding .components-form-toggle label{font-size:14px}.woocommerce-onboarding .components-form-toggle .components-base-control{display:inline-block}.woocommerce-onboarding .components-form-toggle .components-base-control__field{margin-bottom:0}.woocommerce-page .components-modal__frame .components-button.is-button,.woocommerce-profile-wizard__body .components-button.is-button,.woocommerce-task-dashboard__container .components-button.is-button{height:48px;padding-left:25px;padding-right:25px;text-align:center;font-size:14px;line-height:36px;font-weight:500;align-items:center}.woocommerce-page .components-modal__frame .components-button.is-button:disabled,.woocommerce-profile-wizard__body .components-button.is-button:disabled,.woocommerce-task-dashboard__container .components-button.is-button:disabled{cursor:not-allowed}.components-modal__frame.woocommerce-cart-modal{width:600px;max-width:100%}.components-modal__frame.woocommerce-cart-modal .components-modal__header{border-bottom:0;margin-bottom:16px;margin-top:16px}.components-modal__frame.woocommerce-cart-modal .components-modal__header button{display:none}.components-modal__frame.woocommerce-cart-modal .components-modal__header-heading{font-style:normal;font-weight:400;font-size:24px;line-height:32px}.components-modal__frame.woocommerce-cart-modal .woocommerce-list{margin-top:4px}.components-modal__frame.woocommerce-cart-modal .woocommerce-list .woocommerce-list__item:first-child{border-top:1px solid #dcdcde}.components-modal__frame.woocommerce-cart-modal .woocommerce-list__item{border-bottom:1px solid #dcdcde}.components-modal__frame.woocommerce-cart-modal .woocommerce-cart-modal__help-text{font-size:16px;line-height:24px}.components-modal__frame.woocommerce-cart-modal .woocommerce-cart-modal__actions{text-align:right}.components-modal__frame.woocommerce-cart-modal .woocommerce-cart-modal__actions button.is-link{margin-right:16px;text-decoration:none;font-weight:600;font-size:14px}.components-modal__frame.woocommerce-cart-modal .woocommerce-cart-modal__actions button.is-primary{align-self:flex-end}.woocommerce-layout__header{background:#fff;box-sizing:border-box;padding:0;min-height:60px;position:fixed;width:100%;top:32px;z-index:1001}.woocommerce-layout__header.is-scrolled{box-shadow:0 8px 8px 0 rgba(85,93,102,.3)}@media (max-width:782px){.woocommerce-layout__header{flex-flow:row wrap;top:46px}}.woocommerce-layout__header .woocommerce-layout__header-breadcrumbs-wrapper{display:flex;justify-content:space-between;flex-direction:row}.woocommerce-layout__header .woocommerce-layout__header-heading{display:flex;align-items:center;padding:0 0 0 40px;padding:0 0 0 var(--large-gap);flex:1 auto;height:60px;line-height:60px;background:#fff;font-weight:600;font-size:14px;text-transform:capitalize}.has-woocommerce-navigation .woocommerce-layout__header{top:0}.woocommerce-page #contextual-help-link-wrap,.woocommerce-page #screen-options-link-wrap{margin-top:-1px}.woocommerce-layout__activity-panel{display:flex;flex-direction:row;align-items:center;position:fixed;right:0;top:32px;height:60px}@media (max-width:782px){.woocommerce-layout__activity-panel{position:relative;background:#fff;margin:0;padding:0;width:100vw;display:none;flex:1 100%}}@media (min-width:783px) and (max-width:960px){.woocommerce-layout__activity-panel{max-width:280px}}@media (min-width:1281px){.woocommerce-layout__activity-panel{max-width:400px}}.woocommerce-layout__activity-panel.is-mobile-open{display:flex}.woocommerce-layout__activity-panel-tabs{width:100%;display:flex;height:60px;justify-content:flex-end}.woocommerce-layout__activity-panel-tabs .dashicon,.woocommerce-layout__activity-panel-tabs .gridicon{width:100%}.woocommerce-layout__activity-panel-tabs svg{width:24px;height:24px}.woocommerce-layout__activity-panel-tabs svg.woocommerce-layout__activity-panel-tab-icon{fill:none}.woocommerce-layout__activity-panel-tabs svg.woocommerce-layout__activity-panel-tab-icon path,.woocommerce-layout__activity-panel-tabs svg.woocommerce-layout__activity-panel-tab-icon rect{stroke:currentColor}.woocommerce-layout__activity-panel-tabs svg.setup-progress path:first-child{stroke:"#DCDCDE"}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__homescreen-display-options svg.woocommerce-layout__activity-panel-tab-icon{height:14px}.woocommerce-layout__activity-panel-tabs .components-icon-button{display:initial;text-indent:0;border-radius:0}.woocommerce-layout__activity-panel-tabs .components-icon-button.has-text svg{margin:0}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab{display:flex;flex-direction:column;justify-content:center;align-items:center;position:relative;border:none;outline:none;cursor:pointer;background-color:#fff;max-width:-webkit-min-content;max-width:min-content;min-width:80px;width:100%;height:60px;color:#757575;white-space:nowrap}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:before{background-color:#007cba;background-color:var(--wp-admin-theme-color);bottom:0;content:"";height:0;opacity:0;transition-property:height,opacity;transition-duration:.3s;transition-timing-function:ease-in-out;left:0;position:absolute;right:0}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.is-active,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.is-opened{color:#1e1e1e;box-shadow:none}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.is-active:before,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.is-opened:before{height:3px;opacity:1}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.woocommerce-layout__activity-panel-tab-wordpress-notices:after{content:" ";position:absolute;padding:1px;background:#d94f4f;border:2px solid #fff;width:4px;height:4px;display:inline-block;border-radius:50%;top:8px;left:50%}@media (min-width:783px) and (max-width:960px){.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.woocommerce-layout__activity-panel-tab-wordpress-notices:after{right:18px;left:auto;margin-left:0}}@media (min-width:961px){.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.woocommerce-layout__activity-panel-tab-wordpress-notices:after{right:28px;left:auto;margin-left:0}}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.components-button:not(:disabled):not([aria-disabled=true]):hover,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:hover{background-color:#f0f0f0;box-shadow:none}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.components-button:not(:disabled):not([aria-disabled=true]):hover.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.components-button:not(:disabled):not([aria-disabled=true]):hover.woocommerce-layout__activity-panel-tab-wordpress-notices:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:hover.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:hover.woocommerce-layout__activity-panel-tab-wordpress-notices:after{border-color:#e0e0e0}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.components-button:not(:disabled):not([aria-disabled=true]):focus,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:focus{box-shadow:inset -1px -1px 0 #757575,inset 1px 1px 0 #757575}@media (max-width:782px){.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.display-options{display:none}}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-popover{margin-top:0;z-index:1001}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-popover .components-menu-group{padding:12px}.woocommerce-layout__activity-panel-mobile-toggle{margin-right:10px;max-width:48px;height:60px;position:absolute;right:0;bottom:0}@media (min-width:783px){.woocommerce-layout__activity-panel-mobile-toggle{display:none}}.wp-responsive-open .woocommerce-layout__activity-panel-mobile-toggle{display:none}.woocommerce-layout__activity-panel-toggle-bubble.has-unread:after{content:" ";position:absolute;padding:1px;background:#ca4a1f;border:2px solid #fff;width:4px;height:4px;display:inline-block;border-radius:50%;top:6px;right:4px}@keyframes tabSwitch{0%,to{transform:translateX(0)}50%{transform:translateX(100px)}}.woocommerce-layout__activity-panel-wrapper{height:calc(100vh - 166px);background:#f0f0f0;width:510px;transform:translateX(100%);transition-property:transform box-shadow;transition-duration:.3s;transition-timing-function:ease-in-out;position:fixed;right:0;top:166px;z-index:1000;overflow-x:hidden;overflow-y:auto}@media (max-width:782px){.woocommerce-layout__activity-panel-wrapper{width:100%}}@media screen and (prefers-reduced-motion:reduce){.woocommerce-layout__activity-panel-wrapper{transition-duration:1ms}}@media (min-width:783px){.woocommerce-layout__activity-panel-wrapper{height:calc(100vh - 92px);top:92px}}.woocommerce-layout__activity-panel-wrapper.is-open{transform:none;box-shadow:0 12px 12px 0 rgba(85,93,102,.3)}.woocommerce-layout__activity-panel-wrapper.is-switching{animation:tabSwitch;animation-duration:.3s}@media screen and (prefers-reduced-motion:reduce){.woocommerce-layout__activity-panel-wrapper.is-switching{animation:none}}.woocommerce-layout__activity-panel-wrapper .woocommerce-empty-content{padding-left:24px;padding-right:24px}.woocommerce-layout__activity-panel-avatar-flag-overlay{position:relative;top:-12px}.woocommerce-layout__activity-panel-avatar-flag-overlay .woocommerce-flag{position:relative;top:16px;border:2px solid #fff}.woocommerce-layout__notice-list-hide{display:none}.has-woocommerce-navigation .woocommerce-layout__activity-panel{top:0}.woocommerce-layout__show-app-banner{padding-top:56px}@media (min-width:783px){.woocommerce-layout__show-app-banner{padding-top:0}}.woocommerce-mobile-app-banner{background-color:#3c2861;width:100%;display:flex;height:56px;align-items:center;padding:0 6px 0 4px}@media (min-width:401px){.woocommerce-mobile-app-banner{padding:0 13px 0 10px}}@media (min-width:783px){.woocommerce-mobile-app-banner{display:none}}.woocommerce-mobile-app-banner .dashicon{fill:#fff;margin-right:10px}.woocommerce-mobile-app-banner .components-button.is-secondary{margin-left:auto;color:#fff;box-shadow:inset 0 0 0 1px #fff}.woocommerce-mobile-app-banner .components-button.is-secondary:active,.woocommerce-mobile-app-banner .components-button.is-secondary:hover{color:#fff;box-shadow:inset 0 0 0 1px #fff;background:none}.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description{color:#fff;margin-left:8px}@media (min-width:401px){.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description{margin-left:13px}}.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description .woocommerce-mobile-app-banner__description__text{margin:0;font-size:10px}.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description .woocommerce-mobile-app-banner__description__text:first-child{font-weight:700}@media (min-width:401px){.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description .woocommerce-mobile-app-banner__description__text{margin-left:13px;font-size:13px}}.woocommerce-transient-notices{position:fixed;bottom:12px;left:176px;z-index:99999}@media (max-width:960px){.woocommerce-transient-notices{left:50px}}@media (max-width:782px){.woocommerce-transient-notices{left:16px}}.woocommerce-profile-wizard__body .woocommerce-transient-notices{left:unset}.woocommerce-profile-wizard__body .woocommerce-transient-notices .components-snackbar{margin-left:auto;margin-right:auto}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-navigation h2{color:inherit}.woocommerce-navigation .components-navigation__menu{display:flex;flex-direction:column;height:100%}.woocommerce-navigation .components-navigation__group+.components-navigation__group{margin-top:24px}.woocommerce-navigation .components-navigation__item{margin-bottom:0}.woocommerce-navigation .woocommerce-navigation__back-to-dashboard{margin-top:24px}.woocommerce-navigation-header{display:flex;align-items:center;border:none;border-radius:0;height:auto}.woocommerce-navigation-header .woocommerce-navigation-header__site-icon.components-button{padding:12px;height:60px;color:#fff}.woocommerce-navigation-header .woocommerce-navigation-header__site-icon.components-button:focus,.woocommerce-navigation-header .woocommerce-navigation-header__site-icon.components-button:hover,.woocommerce-navigation-header .woocommerce-navigation-header__site-icon.components-button:not([aria-disabled=true]):active{color:#fff}.woocommerce-navigation-header .woocommerce-navigation-header__site-title.components-button{padding-left:0;color:#ccc;font-weight:600}.woocommerce-navigation-header .woocommerce-navigation-header__site-title.components-button:active,.woocommerce-navigation-header .woocommerce-navigation-header__site-title.components-button:focus,.woocommerce-navigation-header .woocommerce-navigation-header__site-title.components-button:hover{color:#e0e0e0}.has-woocommerce-navigation{margin-top:-32px}.has-woocommerce-navigation #adminmenuback,.has-woocommerce-navigation #adminmenuwrap,.has-woocommerce-navigation #wpadminbar{display:none!important}.has-woocommerce-navigation #woocommerce-embedded-navigation{position:fixed;top:0;left:0;width:240px;height:100%;box-sizing:border-box;background-color:#1e1e1e;z-index:1100}.has-woocommerce-navigation .components-navigation{overflow-y:auto;height:calc(100vh - 60px);box-sizing:border-box}.has-woocommerce-navigation:not(.is-folded) #wpcontent,.has-woocommerce-navigation:not(.is-folded) #wpfooter{margin-left:240px}@media (max-width:960px){.has-woocommerce-navigation:not(.is-folded) #wpcontent,.has-woocommerce-navigation:not(.is-folded) #wpfooter{margin-left:0}}.has-woocommerce-navigation.is-folded #wpcontent,.has-woocommerce-navigation.is-folded #wpfooter{margin-left:0}.has-woocommerce-navigation.is-folded .woocommerce-layout__header{margin-left:60px}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation{width:60px;height:60px}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation .woocommerce-navigation-header.is-scrolled{box-shadow:0 8px 8px 0 rgba(85,93,102,.3)}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation .woocommerce-navigation-header>*{display:none}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation .woocommerce-navigation-header__site-icon{display:block}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation .components-navigation{display:none} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/app/style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/app/style.rtl.css new file mode 100644 index 0000000..0adec87 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/app/style.rtl.css @@ -0,0 +1 @@ +.woocommerce-page .wrap{margin:0}.woocommerce-page #wpcontent,.woocommerce-page.woocommerce_page_wc-admin #wpbody-content{padding:0;overflow-x:hidden!important;min-height:calc(100vh - 32px)}@media (min-width:783px){.woocommerce-page #wpbody-content{padding-right:0}}@media (max-width:782px){.woocommerce-page .wp-responsive-open #woocommerce-embedded-root,.woocommerce-page .wp-responsive-open #wpbody{position:relative;left:-14.5em}.woocommerce-page #wpbody-content,.woocommerce-page #wpcontent{min-height:calc(100vh - 46px)}}@media (min-width:961px){.woocommerce-page #toplevel_page_wcadmin--analytics.menu-top>a:focus,.woocommerce-page #toplevel_page_woocommerce.menu-top>a:focus{padding-bottom:1px}}.woocommerce-layout *{box-sizing:border-box}#wpfooter{display:none}.woocommerce_page_wc-admin .wp-responsive-open .woocommerce-layout__header{margin-right:2px}.woocommerce_page_wc-admin .woocommerce-filters-date__content:not(.is-mobile){z-index:2}@media (max-width:600px){#wpadminbar{position:fixed}}@media (max-width:782px){.jetpack-masterbar #wpadminbar #wp-admin-bar-menu-toggle{margin-top:-10px}.jetpack-masterbar #wpwrap .woocommerce-layout__header-heading{padding-right:60px}.jetpack-masterbar.wp-admin .wrap h1,.jetpack-masterbar.wp-admin .wrap h2{padding-right:0}}.woocommerce-page .wp-has-current-submenu:after{left:0;content:" ";height:0;width:0;position:absolute;pointer-events:none;border:8px solid transparent;border-left-color:#f1f1f1;top:0;margin-top:10px}@media (max-width:960px){.woocommerce-page .wp-has-current-submenu:after{border-width:4px;margin-top:14px}}:root{--large-gap:40px;--main-gap:24px}@media (max-width:960px){:root{--large-gap:24px}}@media (max-width:782px){:root{--large-gap:16px;--main-gap:16px}}@keyframes loading-fade{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}.woocommerce-layout select:hover{color:#1e1e1e}.woocommerce-layout select.components-select-control__input{max-width:100%;line-height:1}body.woocommerce-page .components-button.is-primary,body.woocommerce-page .components-button.is-primary:not(:disabled):active,body.woocommerce-page .components-button.is-primary:not(:disabled):focus,body.woocommerce-page .components-button.is-primary:not(:disabled):hover,body.woocommerce-page .components-snackbar .components-button.is-tertiary,body.woocommerce-page .components-snackbar .components-button.is-tertiary:not(:disabled):not([aria-disabled=true]):hover{color:#fff}.woocommerce-embed-page #wpbody .woocommerce-layout,.woocommerce-embed-page .woocommerce-layout__notice-list-hide+.wrap{padding-top:70px}.woocommerce-embed-page #wpbody-content,.woocommerce-embed-page #wpcontent{overflow-x:initial!important}.woocommerce-embed-page #wpbody-content{padding-top:0}.woocommerce-embed-page #wpbody-content .notice{margin-top:15px}.woocommerce-embed-page .wrap{padding:0 20px}@media (max-width:782px){.woocommerce-embed-page .wrap p.search-box{width:calc(100% - 40px)}}.woocommerce-embed-page .wrap .wrap{padding:0}.woocommerce-embed-page #woocommerce-embedded-root.is-embed-loading+#wpbody .wrap{padding-top:100px}@media (max-width:782px){.woocommerce-embed-page #woocommerce-embedded-root.is-embed-loading+#wpbody .wrap{padding-top:30px}}.woocommerce-embed-page #screen-meta,.woocommerce-embed-page #screen-meta-links{top:60px}.woocommerce-embed-page #screen-meta{border-left:0;margin:0}.woocommerce-embed-page #screen-meta-links{position:relative}.woocommerce-embed-page .notice{padding:1px 12px}.woocommerce-embed-page .woocommerce-layout__header{height:60px}.woocommerce-embed-page .woocommerce-layout__header.is-scrolled{box-shadow:0 8px 16px 0 rgba(85,93,102,.3)}.woocommerce-embed-page .woocommerce-layout__header .woocommerce-layout__header-heading{margin-top:0;margin-bottom:0}.woocommerce-embed-page #screen-meta-links.is-hidden-by-notices,.woocommerce-embed-page #screen-meta.is-hidden-by-notices{display:none!important}.woocommerce-embed-page .woocommerce-layout__primary{margin:0}@media (max-width:782px){.woocommerce-embed-page .woocommerce-layout__primary{padding-top:10px}}@keyframes isLoaded{0%{opacity:0}to{opacity:1}}.woocommerce-embed-page .woocommerce-layout__activity-panel-tabs{animation:isLoaded;animation-duration:2s}.woocommerce-embed-page .woocommerce-layout__notice-list-show{margin-top:10px;margin-bottom:16px}@media (max-width:600px){.woocommerce-embed-page .woocommerce-layout__notice-list-show{margin-top:80px;margin-bottom:-16px}}@media (min-width:601px) and (max-width:782px){.woocommerce-embed-page .woocommerce-layout__notice-list-show{margin-top:32px}}@media (min-width:783px){.woocommerce-embed-page .woocommerce-layout__activity-panel-mobile-toggle{display:none}}.woocommerce-embed-page .woocommerce-activity-card__actions a.components-button:not(.is-primary){color:#757575}.components-button{display:inline-flex;text-decoration:none;font-size:13px;margin:0;border:0;cursor:pointer;-webkit-appearance:none;background:none;transition:box-shadow .1s linear;height:36px;align-items:center;box-sizing:border-box;padding:6px 12px;border-radius:2px;color:#1e1e1e}@media (prefers-reduced-motion:reduce){.components-button{transition-duration:0s}}.components-button:hover,.components-button[aria-expanded=true]{color:#007cba;color:var(--wp-admin-theme-color)}.components-button[aria-disabled=true]:hover{color:initial}.components-button:focus:not(:disabled){box-shadow:0 0 0 1.5px #007cba;box-shadow:0 0 0 1.5px var(--wp-admin-theme-color);outline:1px solid transparent}.components-button.is-primary{white-space:nowrap;background:#007cba;background:var(--wp-admin-theme-color);color:#fff;text-decoration:none;text-shadow:none}.components-button.is-primary:hover:not(:disabled){background:#006ba1;background:var(--wp-admin-theme-color-darker-10);color:#fff}.components-button.is-primary:active:not(:disabled){background:#005a87;background:var(--wp-admin-theme-color-darker-20);border-color:#005a87;border-color:var(--wp-admin-theme-color-darker-20);color:#fff}.components-button.is-primary:focus:not(:disabled){box-shadow:inset 0 0 0 1px #fff,0 0 0 1.5px #007cba;box-shadow:inset 0 0 0 1px #fff,0 0 0 1.5px var(--wp-admin-theme-color);outline:1px solid transparent}.components-button.is-primary:disabled,.components-button.is-primary:disabled:active:enabled,.components-button.is-primary[aria-disabled=true],.components-button.is-primary[aria-disabled=true]:active:enabled,.components-button.is-primary[aria-disabled=true]:enabled{color:hsla(0,0%,100%,.4);background:#007cba;background:var(--wp-admin-theme-color);border-color:#007cba;border-color:var(--wp-admin-theme-color);opacity:1}.components-button.is-primary:disabled:active:enabled:focus:enabled,.components-button.is-primary:disabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:active:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:focus:enabled{box-shadow:0 0 0 1px #fff,0 0 0 3px #007cba;box-shadow:0 0 0 1px #fff,0 0 0 3px var(--wp-admin-theme-color)}.components-button.is-primary.is-busy,.components-button.is-primary.is-busy:disabled,.components-button.is-primary.is-busy[aria-disabled=true]{color:#fff;background-size:100px 100%;background-image:linear-gradient(45deg,#007cba 28%,#005a87 0,#005a87 72%,#007cba 0);background-image:linear-gradient(45deg,var(--wp-admin-theme-color) 28%,var(--wp-admin-theme-color-darker-20) 0,var(--wp-admin-theme-color-darker-20) 72%,var(--wp-admin-theme-color) 0);border-color:#007cba;border-color:var(--wp-admin-theme-color)}.components-button.is-secondary:active:not(:disabled),.components-button.is-tertiary:active:not(:disabled){background:#ddd;color:#006ba1;color:var(--wp-admin-theme-color-darker-10);box-shadow:none}.components-button.is-secondary:hover:not(:disabled),.components-button.is-tertiary:hover:not(:disabled){color:#006ba1;color:var(--wp-admin-theme-color-darker-10);box-shadow:inset 0 0 0 1px #006ba1;box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color-darker-10)}.components-button.is-secondary:disabled,.components-button.is-secondary[aria-disabled=true],.components-button.is-secondary[aria-disabled=true]:hover,.components-button.is-tertiary:disabled,.components-button.is-tertiary[aria-disabled=true],.components-button.is-tertiary[aria-disabled=true]:hover{color:#828282;background:#eaeaea;transform:none;opacity:1;box-shadow:none}.components-button.is-secondary{box-shadow:inset 0 0 0 1px #007cba;box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color);outline:1px solid transparent}.components-button.is-secondary,.components-button.is-tertiary{white-space:nowrap;color:#007cba;color:var(--wp-admin-theme-color);background:transparent}.components-button.is-tertiary{padding:6px;outline:1px dotted transparent}.components-button.is-tertiary .dashicon{display:inline-block;flex:0 0 auto}.components-button.is-destructive{color:#d94f4f;box-shadow:inset 0 0 0 1px #d94f4f}.components-button.is-destructive:hover:not(:disabled){color:#a02222;box-shadow:inset 0 0 0 1px #a02222}.components-button.is-destructive:focus:not(:disabled){color:#007cba;color:var(--wp-admin-theme-color)}.components-button.is-destructive:active:not(:disabled){background:#ccc}.components-button.is-link{margin:0;padding:0;box-shadow:none;border:0;border-radius:0;background:none;outline:none;text-align:right;color:#0073aa;text-decoration:underline;transition-property:border,background,color;transition-duration:.05s;transition-timing-function:ease-in-out;height:auto}@media (prefers-reduced-motion:reduce){.components-button.is-link{transition-duration:0s}}.components-button.is-link:active:not(:disabled),.components-button.is-link:hover:not(:disabled){color:#00a0d2;box-shadow:none}.components-button.is-link:focus{color:#124964;box-shadow:0 0 0 1px #5b9dd9,0 0 1.5px 1px rgba(30,140,190,.8)}.components-button.is-link.is-destructive{color:#d94f4f}.components-button.is-link.is-destructive:active:not(:disabled),.components-button.is-link.is-destructive:hover:not(:disabled){color:#a02222;background:none}.components-button.is-link.is-destructive:focus:not(:disabled){color:#007cba;color:var(--wp-admin-theme-color)}.components-button:not([aria-disabled=true]):active{color:inherit}.components-button:disabled,.components-button[aria-disabled=true]{cursor:default;opacity:.3}.components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{animation:components-button__busy-animation 2.5s linear infinite;opacity:1;background-size:100px 100%;background-image:linear-gradient(45deg,#fafafa 28%,#e0e0e0 0,#e0e0e0 72%,#fafafa 0)}.components-button.is-small{height:24px;line-height:22px;padding:0 8px;font-size:11px}.components-button.is-small.has-icon:not(.has-text){padding:0 8px;width:24px}.components-button.has-icon{padding:6px;min-width:36px;justify-content:center}.components-button.has-icon .dashicon{display:inline-block;flex:0 0 auto}.components-button.has-icon.has-text{justify-content:left}.components-button.has-icon.has-text svg{margin-left:8px}.components-button.is-pressed{color:#fff;background:#1e1e1e}.components-button.is-pressed:focus:not(:disabled){box-shadow:inset 0 0 0 1px #fff,0 0 0 1.5px #007cba;box-shadow:inset 0 0 0 1px #fff,0 0 0 1.5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-button.is-pressed:hover:not(:disabled){background:#1e1e1e}.components-button svg{fill:currentColor;outline:none}.components-button .components-visually-hidden{height:auto}@keyframes components-button__busy-animation{0%{background-position:200px 0}}.components-checkbox-control__input[type=checkbox]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;padding:6px 8px;box-shadow:0 0 0 transparent;transition:box-shadow .1s linear;font-size:16px;line-height:normal;border:1px solid #1e1e1e;transition:none;border-radius:2px;background:#fff;color:#1e1e1e;clear:none;cursor:pointer;display:inline-block;line-height:0;margin:0 0 0 4px;outline:0;padding:0!important;text-align:center;vertical-align:top;width:24px;height:24px;-webkit-appearance:none;appearance:none;transition:border-color .1s ease-in-out}@media (min-width:600px){.components-checkbox-control__input[type=checkbox]{font-size:13px;line-height:normal}}.components-checkbox-control__input[type=checkbox]:focus{border-color:#007cba;border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px #007cba;box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]::-webkit-input-placeholder{color:rgba(30,30,30,.62)}.components-checkbox-control__input[type=checkbox]::-moz-placeholder{opacity:1;color:rgba(30,30,30,.62)}.components-checkbox-control__input[type=checkbox]:-ms-input-placeholder{color:rgba(30,30,30,.62)}.is-dark-theme .components-checkbox-control__input[type=checkbox]::-webkit-input-placeholder{color:hsla(0,0%,100%,.65)}.is-dark-theme .components-checkbox-control__input[type=checkbox]::-moz-placeholder{opacity:1;color:hsla(0,0%,100%,.65)}.is-dark-theme .components-checkbox-control__input[type=checkbox]:-ms-input-placeholder{color:hsla(0,0%,100%,.65)}.components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{margin:-3px -5px;color:#fff}@media (min-width:782px){.components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{margin:-4px -5px 0 0}}.components-checkbox-control__input[type=checkbox][aria-checked=mixed]{background:#007cba;background:var(--wp-admin-theme-color);border-color:#007cba;border-color:var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{content:"\f460";float:right;display:inline-block;vertical-align:middle;width:16px;font:normal 30px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (min-width:782px){.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{float:none;font-size:21px}}@media (min-width:600px){.components-checkbox-control__input[type=checkbox]{height:20px;width:20px}}@media (prefers-reduced-motion:reduce){.components-checkbox-control__input[type=checkbox]{transition-duration:0s}}.components-checkbox-control__input[type=checkbox]:focus{box-shadow:0 0 0 2px #fff,0 0 0 3.5px #007cba;box-shadow:0 0 0 2px #fff,0 0 0 3.5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-checkbox-control__input[type=checkbox]:checked{background:#007cba;background:var(--wp-admin-theme-color);border-color:#007cba;border-color:var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]:checked::-ms-check{opacity:0}.components-checkbox-control__input[type=checkbox]:checked:before{content:none}.components-checkbox-control__input-container{position:relative;display:inline-block;margin-left:12px;vertical-align:middle;width:24px;height:24px}@media (min-width:600px){.components-checkbox-control__input-container{width:20px;height:20px}}svg.components-checkbox-control__checked{fill:#fff;cursor:pointer;position:absolute;right:0;top:0;width:24px;height:24px;-webkit-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none}@media (min-width:600px){svg.components-checkbox-control__checked{right:-2px;top:-2px}}.components-form-toggle{position:relative;display:inline-block}.components-form-toggle .components-form-toggle__track{content:"";display:inline-block;box-sizing:border-box;vertical-align:top;background-color:#fff;border:1px solid #1e1e1e;width:36px;height:18px;border-radius:9px;transition:background .2s ease}@media (prefers-reduced-motion:reduce){.components-form-toggle .components-form-toggle__track{transition-duration:0s}}.components-form-toggle .components-form-toggle__thumb{display:block;position:absolute;box-sizing:border-box;top:3px;right:3px;width:12px;height:12px;border-radius:50%;transition:transform .1s ease;background-color:#1e1e1e;border:5px solid #1e1e1e}@media (prefers-reduced-motion:reduce){.components-form-toggle .components-form-toggle__thumb{transition-duration:0s}}.components-form-toggle.is-checked .components-form-toggle__track{background-color:#007cba;background-color:var(--wp-admin-theme-color);border:9px solid transparent}.components-form-toggle .components-form-toggle__input:focus+.components-form-toggle__track{box-shadow:0 0 0 2px #fff,0 0 0 3.5px #007cba;box-shadow:0 0 0 2px #fff,0 0 0 3.5px var(--wp-admin-theme-color);outline:2px solid transparent;outline-offset:2px}.components-form-toggle.is-checked .components-form-toggle__thumb{background-color:#fff;border-width:0;transform:translateX(-18px)}.components-disabled .components-form-toggle{opacity:.3}.components-form-toggle input.components-form-toggle__input[type=checkbox]{position:absolute;top:0;right:0;width:100%;height:100%;opacity:0;margin:0;padding:0;z-index:1;border:none}.components-form-toggle input.components-form-toggle__input[type=checkbox]:checked{background:none}.components-form-toggle input.components-form-toggle__input[type=checkbox]:before{content:""}.components-notice{display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;background-color:#fff;border-right:4px solid #007cba;border-right:4px solid var(--wp-admin-theme-color);margin:5px 15px 2px;padding:8px 12px;align-items:center}.components-notice.is-dismissible{padding-left:36px;position:relative}.components-notice.is-success{border-right-color:#4ab866;background-color:#eff9f1}.components-notice.is-warning{border-right-color:#ffb900;background-color:#ffeab3}.components-notice.is-error{border-right-color:#d94f4f;background-color:#f9e2e2}.components-notice__content{flex-grow:1;margin:4px 0 4px 25px}.components-notice__action.components-button,.components-notice__action.components-button.is-link{margin-right:12px}.components-notice__action.components-button.is-secondary{vertical-align:initial}.components-notice__dismiss{color:#757575;align-self:flex-start;flex-shrink:0}.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):focus,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):active,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{color:#1e1e1e;background-color:transparent}.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{box-shadow:none}.components-notice-list{max-width:100vw;box-sizing:border-box;z-index:29}.components-notice-list .components-notice__content{margin-top:12px;margin-bottom:12px;line-height:2}.components-notice-list .components-notice__action.components-button{display:block;margin-right:0;margin-top:8px}.components-select-control__input{background:#fff;height:36px;line-height:36px;margin:1px;outline:0;width:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)!important}@media (min-width:782px){.components-select-control__input{height:28px;line-height:28px}}@media (max-width:782px){.components-base-control .components-base-control__field .components-select-control__input{font-size:16px}}.components-snackbar{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;background-color:#1e1e1e;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.3);color:#fff;padding:16px 24px;width:100%;max-width:600px;box-sizing:border-box;cursor:pointer}@media (min-width:600px){.components-snackbar{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}}.components-snackbar:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px #007cba;box-shadow:0 0 0 1px #fff,0 0 0 3px var(--wp-admin-theme-color)}.components-snackbar__action.components-button{margin-right:32px;color:#fff;height:auto;flex-shrink:0;line-height:1.4;padding:0}.components-snackbar__action.components-button:not(:disabled):not([aria-disabled=true]):not(.is-secondary){text-decoration:underline;background-color:transparent}.components-snackbar__action.components-button:not(:disabled):not([aria-disabled=true]):not(.is-secondary):focus{color:#fff;box-shadow:none;outline:1px dotted #fff}.components-snackbar__action.components-button:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{color:#007cba;color:var(--wp-admin-theme-color)}.components-snackbar__content{display:flex;align-items:baseline;justify-content:space-between;line-height:1.4}.components-snackbar-list{position:absolute;z-index:100000;width:100%;box-sizing:border-box}.components-snackbar-list__notice-container{position:relative;padding-top:8px}.components-spinner{display:inline-block;background-color:#949494;width:18px;height:18px;opacity:.7;margin:5px 11px 0;border-radius:100%;position:relative}.components-spinner:before{content:"";position:absolute;background-color:#fff;top:3px;right:3px;width:4px;height:4px;border-radius:100%;transform-origin:6px 6px;animation:components-spinner__animation 1s linear infinite}@keyframes components-spinner__animation{0%{transform:rotate(0deg)}to{transform:rotate(-1turn)}}.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{width:100%;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;padding:6px 8px;box-shadow:0 0 0 transparent;transition:box-shadow .1s linear;border-radius:2px;border:1px solid #757575;font-size:16px;line-height:normal}@media (prefers-reduced-motion:reduce){.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{transition-duration:0s}}@media (min-width:600px){.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{font-size:13px;line-height:normal}}.components-text-control__input:focus,.components-text-control__input[type=color]:focus,.components-text-control__input[type=date]:focus,.components-text-control__input[type=datetime-local]:focus,.components-text-control__input[type=datetime]:focus,.components-text-control__input[type=email]:focus,.components-text-control__input[type=month]:focus,.components-text-control__input[type=number]:focus,.components-text-control__input[type=password]:focus,.components-text-control__input[type=tel]:focus,.components-text-control__input[type=text]:focus,.components-text-control__input[type=time]:focus,.components-text-control__input[type=url]:focus,.components-text-control__input[type=week]:focus{border-color:#007cba;border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px #007cba;box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-text-control__input::-webkit-input-placeholder,.components-text-control__input[type=color]::-webkit-input-placeholder,.components-text-control__input[type=date]::-webkit-input-placeholder,.components-text-control__input[type=datetime-local]::-webkit-input-placeholder,.components-text-control__input[type=datetime]::-webkit-input-placeholder,.components-text-control__input[type=email]::-webkit-input-placeholder,.components-text-control__input[type=month]::-webkit-input-placeholder,.components-text-control__input[type=number]::-webkit-input-placeholder,.components-text-control__input[type=password]::-webkit-input-placeholder,.components-text-control__input[type=tel]::-webkit-input-placeholder,.components-text-control__input[type=text]::-webkit-input-placeholder,.components-text-control__input[type=time]::-webkit-input-placeholder,.components-text-control__input[type=url]::-webkit-input-placeholder,.components-text-control__input[type=week]::-webkit-input-placeholder{color:rgba(30,30,30,.62)}.components-text-control__input::-moz-placeholder,.components-text-control__input[type=color]::-moz-placeholder,.components-text-control__input[type=date]::-moz-placeholder,.components-text-control__input[type=datetime-local]::-moz-placeholder,.components-text-control__input[type=datetime]::-moz-placeholder,.components-text-control__input[type=email]::-moz-placeholder,.components-text-control__input[type=month]::-moz-placeholder,.components-text-control__input[type=number]::-moz-placeholder,.components-text-control__input[type=password]::-moz-placeholder,.components-text-control__input[type=tel]::-moz-placeholder,.components-text-control__input[type=text]::-moz-placeholder,.components-text-control__input[type=time]::-moz-placeholder,.components-text-control__input[type=url]::-moz-placeholder,.components-text-control__input[type=week]::-moz-placeholder{opacity:1;color:rgba(30,30,30,.62)}.components-text-control__input:-ms-input-placeholder,.components-text-control__input[type=color]:-ms-input-placeholder,.components-text-control__input[type=date]:-ms-input-placeholder,.components-text-control__input[type=datetime-local]:-ms-input-placeholder,.components-text-control__input[type=datetime]:-ms-input-placeholder,.components-text-control__input[type=email]:-ms-input-placeholder,.components-text-control__input[type=month]:-ms-input-placeholder,.components-text-control__input[type=number]:-ms-input-placeholder,.components-text-control__input[type=password]:-ms-input-placeholder,.components-text-control__input[type=tel]:-ms-input-placeholder,.components-text-control__input[type=text]:-ms-input-placeholder,.components-text-control__input[type=time]:-ms-input-placeholder,.components-text-control__input[type=url]:-ms-input-placeholder,.components-text-control__input[type=week]:-ms-input-placeholder{color:rgba(30,30,30,.62)}.is-dark-theme .components-text-control__input::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=color]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=date]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=datetime-local]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=datetime]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=email]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=month]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=number]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=password]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=tel]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=text]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=time]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=url]::-webkit-input-placeholder,.is-dark-theme .components-text-control__input[type=week]::-webkit-input-placeholder{color:hsla(0,0%,100%,.65)}.is-dark-theme .components-text-control__input::-moz-placeholder,.is-dark-theme .components-text-control__input[type=color]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=date]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=datetime-local]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=datetime]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=email]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=month]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=number]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=password]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=tel]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=text]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=time]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=url]::-moz-placeholder,.is-dark-theme .components-text-control__input[type=week]::-moz-placeholder{opacity:1;color:hsla(0,0%,100%,.65)}.is-dark-theme .components-text-control__input:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=color]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=date]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=datetime-local]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=datetime]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=email]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=month]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=number]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=password]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=tel]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=text]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=time]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=url]:-ms-input-placeholder,.is-dark-theme .components-text-control__input[type=week]:-ms-input-placeholder{color:hsla(0,0%,100%,.65)}.components-tooltip.components-popover{z-index:1000002}.components-tooltip.components-popover .components-popover__content{min-width:0}.components-tooltip .components-popover__content{background:#1e1e1e;border-radius:2px;border-width:0;color:#fff;white-space:nowrap;text-align:center;line-height:1.4;font-size:12px;box-shadow:none}.components-tooltip .components-popover__content>div{padding:4px 8px}.components-tooltip__shortcut{display:inline-block;margin-right:8px}.components-popover{position:fixed;z-index:1000000;top:0;left:0;opacity:0}.components-popover.is-expanded,.components-popover[data-x-axis][data-y-axis]{opacity:1}.components-popover.is-expanded{top:0;left:0;right:0;bottom:0;z-index:1000000!important}.components-popover:not(.is-without-arrow){margin-left:2px}.components-popover:not(.is-without-arrow):before{border:8px solid #ccc}.components-popover:not(.is-without-arrow).is-alternate:before{border-color:#1e1e1e}.components-popover:not(.is-without-arrow):after{border:8px solid #fff}.components-popover:not(.is-without-arrow):after,.components-popover:not(.is-without-arrow):before{content:"";position:absolute;height:0;width:0;line-height:0}.components-popover:not(.is-without-arrow)[data-y-axis=top]{margin-top:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=top]:before{bottom:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=top]:after{bottom:-6px}.components-popover:not(.is-without-arrow)[data-y-axis=top]:after,.components-popover:not(.is-without-arrow)[data-y-axis=top]:before{border-bottom:none;border-left-color:transparent;border-right-color:transparent;border-top-style:solid;margin-left:-10px}.components-popover:not(.is-without-arrow)[data-y-axis=bottom]{margin-top:8px}.components-popover:not(.is-without-arrow)[data-y-axis=bottom]:before{top:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=bottom]:after{top:-6px}.components-popover:not(.is-without-arrow)[data-y-axis=bottom]:after,.components-popover:not(.is-without-arrow)[data-y-axis=bottom]:before{border-bottom-style:solid;border-left-color:transparent;border-right-color:transparent;border-top:none;margin-left:-10px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]{margin-left:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]:before{right:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]:after{right:-6px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]:after,.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=left]:before{border-bottom-color:transparent;border-left-style:solid;border-right:none;border-top-color:transparent}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]{margin-left:8px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]:before{left:-8px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]:after{left:-6px}.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]:after,.components-popover:not(.is-without-arrow)[data-y-axis=middle][data-x-axis=right]:before{border-bottom-color:transparent;border-left:none;border-right-style:solid;border-top-color:transparent}.components-popover[data-y-axis=top]{bottom:100%}.components-popover[data-y-axis=bottom]{top:100%}.components-popover[data-y-axis=middle]{align-items:center;display:flex}.components-popover.is-from-top{margin-top:12px}.components-popover.is-from-bottom{margin-top:-12px}.components-popover.is-from-left:not(.is-from-top):not(.is-from-bottom){margin-left:12px}.components-popover.is-from-right:not(.is-from-top):not(.is-from-bottom){margin-right:12px}.components-popover__content{height:100%;background:#fff;border:1px solid #ccc;box-shadow:0 2px 6px rgba(0,0,0,.05);border-radius:2px}.is-alternate .components-popover__content{border:1px solid #1e1e1e;box-shadow:none}.components-popover .components-popover__content{position:absolute;height:auto;overflow-y:auto;min-width:260px}.components-popover.is-expanded .components-popover__content{position:static;height:calc(100% - 48px);overflow-y:visible;min-width:auto;border:none;border-top:1px solid #1e1e1e}.components-popover[data-y-axis=top] .components-popover__content{bottom:100%}.components-popover[data-x-axis=center] .components-popover__content{left:50%;transform:translateX(-50%)}.components-popover[data-x-axis=right] .components-popover__content{position:absolute;left:100%}.components-popover:not([data-y-axis=middle])[data-x-axis=right] .components-popover__content{margin-left:-25px}.components-popover[data-x-axis=left] .components-popover__content{position:absolute;right:100%}.components-popover:not([data-y-axis=middle])[data-x-axis=left] .components-popover__content{margin-right:-25px}.components-popover__header{align-items:center;background:#fff;display:flex;height:48px;justify-content:space-between;padding:0 8px 0 16px}.components-popover__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.components-popover__close.components-button{z-index:5}.components-radio-control{display:flex;flex-direction:column}.components-radio-control .components-base-control__help{margin-top:0}.components-radio-control .components-base-control__field{margin-bottom:0}.components-radio-control__option:not(:last-child){margin-bottom:4px}.components-radio-control__input[type=radio]{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;padding:6px 8px;box-shadow:0 0 0 transparent;transition:box-shadow .1s linear;border-radius:2px;font-size:16px;line-height:normal;border:1px solid #1e1e1e;transition:none;border-radius:50%;margin-top:0;margin-left:6px}@media (prefers-reduced-motion:reduce){.components-radio-control__input[type=radio]{transition-duration:0s}}@media (min-width:600px){.components-radio-control__input[type=radio]{font-size:13px;line-height:normal}}.components-radio-control__input[type=radio]:focus{border-color:#007cba;border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px #007cba;box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.components-radio-control__input[type=radio]::-webkit-input-placeholder{color:rgba(30,30,30,.62)}.components-radio-control__input[type=radio]::-moz-placeholder{opacity:1;color:rgba(30,30,30,.62)}.components-radio-control__input[type=radio]:-ms-input-placeholder{color:rgba(30,30,30,.62)}.is-dark-theme .components-radio-control__input[type=radio]::-webkit-input-placeholder{color:hsla(0,0%,100%,.65)}.is-dark-theme .components-radio-control__input[type=radio]::-moz-placeholder{opacity:1;color:hsla(0,0%,100%,.65)}.is-dark-theme .components-radio-control__input[type=radio]:-ms-input-placeholder{color:hsla(0,0%,100%,.65)}.components-radio-control__input[type=radio]:checked:before{width:7px;height:7px;margin:8px 8px 0 0;background-color:#fff;border:3px solid #fff}@media (min-width:782px){.components-radio-control__input[type=radio]:checked:before{width:6px;height:6px;margin:4px 4px 0 0}}.components-radio-control__input[type=radio]:focus{box-shadow:0 0 0 2px #fff,0 0 0 3.5px #007cba;box-shadow:0 0 0 2px #fff,0 0 0 3.5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-radio-control__input[type=radio]:checked{background:#007cba;background:var(--wp-admin-theme-color);border-color:#007cba;border-color:var(--wp-admin-theme-color)}.components-menu-group+.components-menu-group{margin-top:8px;padding-top:8px;border-top:1px solid #1e1e1e}.components-menu-group__label{padding:0 8px;margin-top:4px;margin-bottom:12px;color:#757575;text-transform:uppercase;font-size:11px;font-weight:500}.components-menu-item__button,.components-menu-item__button.components-button{width:100%}.components-menu-item__button.components-button .components-menu-items__item-icon,.components-menu-item__button .components-menu-items__item-icon{margin-left:-2px;margin-right:auto;display:inline-block;flex:0 0 auto}.components-menu-item__button.components-button .components-menu-item__shortcut+.components-menu-items__item-icon,.components-menu-item__button .components-menu-item__shortcut+.components-menu-items__item-icon{margin-right:8px}.components-menu-item__button .block-editor-block-icon,.components-menu-item__button.components-button .block-editor-block-icon{margin-right:-2px;margin-left:8px}.components-menu-item__info-wrapper{display:flex;flex-direction:column}.components-menu-item__info{margin-top:4px;font-size:12px;color:#757575}.components-menu-item__shortcut{-ms-grid-row-align:center;align-self:center;margin-left:0;margin-right:auto;padding-right:12px;color:currentColor;display:none}@media (min-width:480px){.components-menu-item__shortcut{display:inline}}.components-modal__screen-overlay{position:fixed;top:0;left:0;bottom:0;right:0;background-color:rgba(0,0,0,.7);z-index:100000;animation:edit-post__fade-in-animation .2s ease-out 0s;animation-fill-mode:forwards}@media (prefers-reduced-motion:reduce){.components-modal__screen-overlay{animation-duration:1ms}}.components-modal__frame{position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;margin:0;border:1px solid #ddd;background:#fff;box-shadow:0 3px 30px rgba(0,0,0,.2);overflow:auto}@media (min-width:600px){.components-modal__frame{top:50%;left:auto;bottom:auto;right:50%;min-width:360px;max-width:calc(100% - 32px);max-height:calc(100% - 120px);transform:translate(50%,-50%);animation:components-modal__appear-animation .1s ease-out;animation-fill-mode:forwards}}@media (min-width:600px) and (prefers-reduced-motion:reduce){.components-modal__frame{animation-duration:1ms}}@keyframes components-modal__appear-animation{0%{margin-top:32px}to{margin-top:0}}.components-modal__header{box-sizing:border-box;border-bottom:1px solid #ddd;padding:0 24px;display:flex;flex-direction:row;justify-content:space-between;background:#fff;align-items:center;height:60px;z-index:10;position:relative;position:-webkit-sticky;position:sticky;top:0;margin:0 -24px 24px}@supports (-ms-ime-align:auto){.components-modal__header{position:fixed;width:100%}}.components-modal__header .components-modal__header-heading{font-size:1rem;font-weight:600}.components-modal__header h1{line-height:1;margin:0}.components-modal__header .components-button{position:relative;right:8px}.components-modal__header-heading-container{align-items:center;flex-grow:1;display:flex;flex-direction:row;justify-content:left}.components-modal__header-icon-container{display:inline-block}.components-modal__header-icon-container svg{max-width:36px;max-height:36px;padding:8px}.components-modal__content{box-sizing:border-box;height:100%;padding:0 24px 24px}@supports (-ms-ime-align:auto){.components-modal__content{padding-top:60px}}.components-base-control{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.components-base-control .components-base-control__field{margin-bottom:8px}.components-panel__row .components-base-control .components-base-control__field{margin-bottom:inherit}.components-base-control .components-base-control__label{display:inline-block;margin-bottom:8px}.components-base-control .components-base-control__help{margin-top:-8px;font-style:italic}.PresetDateRangePicker_panel{padding:0 22px 11px}.PresetDateRangePicker_button{position:relative;height:100%;text-align:center;background:100% 0;border:2px solid #00a699;color:#00a699;padding:4px 12px;margin-left:8px;font:inherit;font-weight:700;line-height:normal;overflow:visible;box-sizing:border-box;cursor:pointer}.PresetDateRangePicker_button:active{outline:0}.PresetDateRangePicker_button__selected{color:#fff;background:#00a699}.SingleDatePickerInput{display:inline-block;background-color:#fff}.SingleDatePickerInput__withBorder{border-radius:2px;border:1px solid #dbdbdb}.SingleDatePickerInput__rtl{direction:ltr}.SingleDatePickerInput__disabled{background-color:#f2f2f2}.SingleDatePickerInput__block{display:block}.SingleDatePickerInput__showClearDate{padding-left:30px}.SingleDatePickerInput_clearDate{background:100% 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;padding:10px;margin:0 5px 0 10px;position:absolute;left:0;top:50%;transform:translateY(-50%)}.SingleDatePickerInput_clearDate__default:focus,.SingleDatePickerInput_clearDate__default:hover{background:#dbdbdb;border-radius:50%}.SingleDatePickerInput_clearDate__small{padding:6px}.SingleDatePickerInput_clearDate__hide{visibility:hidden}.SingleDatePickerInput_clearDate_svg{fill:#82888a;height:12px;width:15px;vertical-align:middle}.SingleDatePickerInput_clearDate_svg__small{height:9px}.SingleDatePickerInput_calendarIcon{background:100% 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;display:inline-block;vertical-align:middle;padding:10px;margin:0 10px 0 5px}.SingleDatePickerInput_calendarIcon_svg{fill:#82888a;height:15px;width:14px;vertical-align:middle}.SingleDatePicker{position:relative;display:inline-block}.SingleDatePicker__block{display:block}.SingleDatePicker_picker{z-index:1;background-color:#fff;position:absolute}.SingleDatePicker_picker__rtl{direction:ltr}.SingleDatePicker_picker__directionLeft{right:0}.SingleDatePicker_picker__directionRight{left:0}.SingleDatePicker_picker__portal{background-color:rgba(0,0,0,.3);position:fixed;top:0;right:0;height:100%;width:100%}.SingleDatePicker_picker__fullScreenPortal{background-color:#fff}.SingleDatePicker_closeButton{background:100% 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;position:absolute;top:0;left:0;padding:15px;z-index:2}.SingleDatePicker_closeButton:focus,.SingleDatePicker_closeButton:hover{color:#b0b3b4;text-decoration:none}.SingleDatePicker_closeButton_svg{height:15px;width:15px;fill:#cacccd}.DayPickerKeyboardShortcuts_buttonReset{background:100% 0;border:0;border-radius:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;cursor:pointer;font-size:14px}.DayPickerKeyboardShortcuts_buttonReset:active{outline:0}.DayPickerKeyboardShortcuts_show{width:22px;position:absolute;z-index:2}.DayPickerKeyboardShortcuts_show__bottomRight{border-top:26px solid transparent;border-left:33px solid #00a699;bottom:0;left:0}.DayPickerKeyboardShortcuts_show__bottomRight:hover{border-left:33px solid #008489}.DayPickerKeyboardShortcuts_show__topRight{border-bottom:26px solid transparent;border-left:33px solid #00a699;top:0;left:0}.DayPickerKeyboardShortcuts_show__topRight:hover{border-left:33px solid #008489}.DayPickerKeyboardShortcuts_show__topLeft{border-bottom:26px solid transparent;border-right:33px solid #00a699;top:0;right:0}.DayPickerKeyboardShortcuts_show__topLeft:hover{border-right:33px solid #008489}.DayPickerKeyboardShortcuts_showSpan{color:#fff;position:absolute}.DayPickerKeyboardShortcuts_showSpan__bottomRight{bottom:0;left:-28px}.DayPickerKeyboardShortcuts_showSpan__topRight{top:1px;left:-28px}.DayPickerKeyboardShortcuts_showSpan__topLeft{top:1px;right:-28px}.DayPickerKeyboardShortcuts_panel{overflow:auto;background:#fff;border:1px solid #dbdbdb;border-radius:2px;position:absolute;top:0;bottom:0;left:0;right:0;z-index:2;padding:22px;margin:33px}.DayPickerKeyboardShortcuts_title{font-size:16px;font-weight:700;margin:0}.DayPickerKeyboardShortcuts_list{list-style:none;padding:0;font-size:14px}.DayPickerKeyboardShortcuts_close{position:absolute;left:22px;top:22px;z-index:2}.DayPickerKeyboardShortcuts_close:active{outline:0}.DayPickerKeyboardShortcuts_closeSvg{height:15px;width:15px;fill:#cacccd}.DayPickerKeyboardShortcuts_closeSvg:focus,.DayPickerKeyboardShortcuts_closeSvg:hover{fill:#82888a}.CalendarDay{box-sizing:border-box;cursor:pointer;font-size:14px;text-align:center}.CalendarDay:active{outline:0}.CalendarDay__defaultCursor{cursor:default}.CalendarDay__default{border:1px solid #e4e7e7;color:#484848;background:#fff}.CalendarDay__default:hover{background:#e4e7e7;border:1px double #e4e7e7;color:inherit}.CalendarDay__hovered_offset{background:#f4f5f5;border:1px double #e4e7e7;color:inherit}.CalendarDay__outside{border:0;background:#fff;color:#484848}.CalendarDay__outside:hover{border:0}.CalendarDay__blocked_minimum_nights{background:#fff;border:1px solid #eceeee;color:#cacccd}.CalendarDay__blocked_minimum_nights:active,.CalendarDay__blocked_minimum_nights:hover{background:#fff;color:#cacccd}.CalendarDay__highlighted_calendar{background:#ffe8bc;color:#484848}.CalendarDay__highlighted_calendar:active,.CalendarDay__highlighted_calendar:hover{background:#ffce71;color:#484848}.CalendarDay__selected_span{background:#66e2da;border:1px solid #33dacd;color:#fff}.CalendarDay__selected_span:active,.CalendarDay__selected_span:hover{background:#33dacd;border:1px solid #33dacd;color:#fff}.CalendarDay__last_in_range{border-left:#00a699}.CalendarDay__selected,.CalendarDay__selected:active,.CalendarDay__selected:hover{background:#00a699;border:1px solid #00a699;color:#fff}.CalendarDay__hovered_span,.CalendarDay__hovered_span:hover{background:#b2f1ec;border:1px solid #80e8e0;color:#007a87}.CalendarDay__hovered_span:active{background:#80e8e0;border:1px solid #80e8e0;color:#007a87}.CalendarDay__blocked_calendar,.CalendarDay__blocked_calendar:active,.CalendarDay__blocked_calendar:hover{background:#cacccd;border:1px solid #cacccd;color:#82888a}.CalendarDay__blocked_out_of_range,.CalendarDay__blocked_out_of_range:active,.CalendarDay__blocked_out_of_range:hover{background:#fff;border:1px solid #e4e7e7;color:#cacccd}.CalendarMonth{background:#fff;text-align:center;vertical-align:top;-webkit-user-select:none;-ms-user-select:none;user-select:none}.CalendarMonth_table{border-collapse:collapse;border-spacing:0}.CalendarMonth_verticalSpacing{border-collapse:separate}.CalendarMonth_caption{color:#484848;font-size:18px;text-align:center;padding-top:22px;padding-bottom:37px;caption-side:top}.CalendarMonth_caption__verticalScrollable{padding-top:12px;padding-bottom:7px}.CalendarMonthGrid{background:#fff;text-align:right;z-index:0}.CalendarMonthGrid__animating{z-index:1}.CalendarMonthGrid__horizontal{position:absolute;right:9px}.CalendarMonthGrid__vertical{margin:0 auto}.CalendarMonthGrid__vertical_scrollable{margin:0 auto;overflow-y:scroll}.CalendarMonthGrid_month__horizontal{display:inline-block;vertical-align:top;min-height:100%}.CalendarMonthGrid_month__hideForAnimation{position:absolute;z-index:-1;opacity:0;pointer-events:none}.CalendarMonthGrid_month__hidden{visibility:hidden}.DayPickerNavigation{position:relative;z-index:2}.DayPickerNavigation__horizontal{height:0}.DayPickerNavigation__verticalDefault{position:absolute;width:100%;height:52px;bottom:0;right:0}.DayPickerNavigation__verticalScrollableDefault{position:relative}.DayPickerNavigation_button{cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:0;padding:0;margin:0}.DayPickerNavigation_button__default{border:1px solid #e4e7e7;background-color:#fff;color:#757575}.DayPickerNavigation_button__default:focus,.DayPickerNavigation_button__default:hover{border:1px solid #c4c4c4}.DayPickerNavigation_button__default:active{background:#f2f2f2}.DayPickerNavigation_button__horizontalDefault{position:absolute;top:18px;line-height:.78;border-radius:3px;padding:6px 9px}.DayPickerNavigation_leftButton__horizontalDefault{right:22px}.DayPickerNavigation_rightButton__horizontalDefault{left:22px}.DayPickerNavigation_button__verticalDefault{padding:5px;background:#fff;box-shadow:0 0 5px 2px rgba(0,0,0,.1);position:relative;display:inline-block;height:100%;width:50%}.DayPickerNavigation_nextButton__verticalDefault{border-right:0}.DayPickerNavigation_nextButton__verticalScrollableDefault{width:100%}.DayPickerNavigation_svg__horizontal{height:19px;width:19px;fill:#82888a;display:block}.DayPickerNavigation_svg__vertical{height:42px;width:42px;fill:#484848;display:block}.DayPicker{position:relative;text-align:right}.DayPicker,.DayPicker__horizontal{background:#fff}.DayPicker__verticalScrollable{height:100%}.DayPicker__hidden{visibility:hidden}.DayPicker__withBorder{box-shadow:0 2px 6px rgba(0,0,0,.05),0 0 0 1px rgba(0,0,0,.07);border-radius:3px}.DayPicker_portal__horizontal{box-shadow:none;position:absolute;right:50%;top:50%}.DayPicker_portal__vertical{position:static}.DayPicker_focusRegion{outline:0}.DayPicker_calendarInfo__horizontal,.DayPicker_wrapper__horizontal{display:inline-block;vertical-align:top}.DayPicker_weekHeaders{position:relative}.DayPicker_weekHeaders__horizontal{margin-right:9px}.DayPicker_weekHeader{color:#757575;position:absolute;top:62px;z-index:2;text-align:right}.DayPicker_weekHeader__vertical{right:50%}.DayPicker_weekHeader__verticalScrollable{top:0;display:table-row;border-bottom:1px solid #dbdbdb;background:#fff;margin-right:0;right:0;width:100%;text-align:center}.DayPicker_weekHeader_ul{list-style:none;margin:1px 0;padding-right:0;padding-left:0;font-size:14px}.DayPicker_weekHeader_li{display:inline-block;text-align:center}.DayPicker_transitionContainer{position:relative;overflow:hidden;border-radius:3px}.DayPicker_transitionContainer__horizontal{transition:height .2s ease-in-out}.DayPicker_transitionContainer__vertical{width:100%}.DayPicker_transitionContainer__verticalScrollable{padding-top:20px;height:100%;position:absolute;top:0;bottom:0;left:0;right:0;overflow-y:scroll}.DateInput{margin:0;padding:0;background:#fff;position:relative;display:inline-block;width:130px;vertical-align:middle}.DateInput__small{width:97px}.DateInput__block{width:100%}.DateInput__disabled{background:#f2f2f2;color:#dbdbdb}.DateInput_input{font-weight:200;font-size:19px;line-height:24px;color:#484848;background-color:#fff;width:100%;padding:11px 11px 9px;border:0;border-bottom:2px solid transparent;border-radius:0}.DateInput_input__small{font-size:15px;line-height:18px;letter-spacing:.2px;padding:7px 7px 5px}.DateInput_input__regular{font-weight:auto}.DateInput_input__readOnly{-webkit-user-select:none;-ms-user-select:none;user-select:none}.DateInput_input__focused{outline:0;background:#fff;border:0;border-bottom:2px solid #008489}.DateInput_input__disabled{background:#f2f2f2;font-style:italic}.DateInput_screenReaderMessage{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.DateInput_fang{position:absolute;width:20px;height:10px;right:22px;z-index:2}.DateInput_fangShape{fill:#fff}.DateInput_fangStroke{stroke:#dbdbdb;fill:transparent}.DateRangePickerInput{background-color:#fff;display:inline-block}.DateRangePickerInput__disabled{background:#f2f2f2}.DateRangePickerInput__withBorder{border-radius:2px;border:1px solid #dbdbdb}.DateRangePickerInput__rtl{direction:ltr}.DateRangePickerInput__block{display:block}.DateRangePickerInput__showClearDates{padding-left:30px}.DateRangePickerInput_arrow{display:inline-block;vertical-align:middle;color:#484848}.DateRangePickerInput_arrow_svg{vertical-align:middle;fill:#484848;height:24px;width:24px}.DateRangePickerInput_clearDates{background:100% 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;padding:10px;margin:0 5px 0 10px;position:absolute;left:0;top:50%;transform:translateY(-50%)}.DateRangePickerInput_clearDates__small{padding:6px}.DateRangePickerInput_clearDates_default:focus,.DateRangePickerInput_clearDates_default:hover{background:#dbdbdb;border-radius:50%}.DateRangePickerInput_clearDates__hide{visibility:hidden}.DateRangePickerInput_clearDates_svg{fill:#82888a;height:12px;width:15px;vertical-align:middle}.DateRangePickerInput_clearDates_svg__small{height:9px}.DateRangePickerInput_calendarIcon{background:100% 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;display:inline-block;vertical-align:middle;padding:10px;margin:0 10px 0 5px}.DateRangePickerInput_calendarIcon_svg{fill:#82888a;height:15px;width:14px;vertical-align:middle}.DateRangePicker{position:relative;display:inline-block}.DateRangePicker__block{display:block}.DateRangePicker_picker{z-index:1;background-color:#fff;position:absolute}.DateRangePicker_picker__rtl{direction:ltr}.DateRangePicker_picker__directionLeft{right:0}.DateRangePicker_picker__directionRight{left:0}.DateRangePicker_picker__portal{background-color:rgba(0,0,0,.3);position:fixed;top:0;right:0;height:100%;width:100%}.DateRangePicker_picker__fullScreenPortal{background-color:#fff}.DateRangePicker_closeButton{background:100% 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;position:absolute;top:0;left:0;padding:15px;z-index:2}.DateRangePicker_closeButton:focus,.DateRangePicker_closeButton:hover{color:#b0b3b4;text-decoration:none}.DateRangePicker_closeButton_svg{height:15px;width:15px;fill:#cacccd}.components-datetime{padding:0}.components-datetime .components-datetime__calendar-help{padding:16px}.components-datetime .components-datetime__calendar-help h4{margin:0}.components-datetime .components-datetime__buttons{display:flex;justify-content:space-between}.components-datetime .components-datetime__date-help-toggle{display:block;margin-right:auto}.components-datetime fieldset{border:0;padding:0;margin:0}.components-datetime input,.components-datetime select{box-shadow:0 0 0 transparent;transition:box-shadow .1s linear;border-radius:2px;border:1px solid #757575}@media (prefers-reduced-motion:reduce){.components-datetime input,.components-datetime select{transition-duration:0s}}.components-datetime .components-button,.components-datetime input[type=number],.components-datetime select{height:30px;margin-top:0;margin-bottom:0}.components-datetime__date{min-height:236px;border-top:1px solid #ddd}.components-datetime__date .DayPickerNavigation_leftButton__horizontalDefault{right:0}.components-datetime__date .CalendarMonth_caption{font-size:13px}.components-datetime__date .CalendarMonth_table{border-collapse:separate;border-spacing:2px}.components-datetime__date .CalendarDay{font-size:13px;border:none;border-radius:50%;text-align:center}.components-datetime__date .CalendarDay:focus{box-shadow:inset 0 0 0 1.5px #007cba,inset 0 0 0 2.5px #fff;box-shadow:inset 0 0 0 1.5px var(--wp-admin-theme-color),inset 0 0 0 2.5px #fff;outline:2px solid transparent}.components-datetime__date .CalendarDay__selected{background:#007cba;background:var(--wp-admin-theme-color);border:2px solid transparent}.components-datetime__date .CalendarDay__selected:hover{background:#005a87;background:var(--wp-admin-theme-color-darker-20)}.components-datetime__date .CalendarDay__selected:focus{box-shadow:inset 0 0 0 1px #fff}.components-datetime__date .DayPickerNavigation_button__horizontalDefault{padding:2px 8px;top:20px}.components-datetime__date .DayPickerNavigation_button__horizontalDefault:focus{border-color:#007cba;border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px #007cba;box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid transparent}.components-datetime__date .DayPicker_weekHeader{top:50px}.components-datetime__date .DayPicker_weekHeader .DayPicker_weekHeader_ul{margin:1px 0;padding-right:0;padding-left:0}.components-datetime__date.is-description-visible .DayPicker{visibility:hidden}.components-datetime__time{padding-bottom:16px}.components-datetime__time fieldset{position:relative;margin-bottom:.5em}.components-datetime__time fieldset+fieldset{margin-bottom:0}.components-datetime__time .components-datetime__time-field-am-pm fieldset{margin-top:0}.components-datetime__time .components-datetime__time-wrapper{display:flex}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-separator{display:inline-block;padding:0 0 0 3px}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field-time{direction:rtl}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field select{margin-left:4px}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field select:focus{position:relative;z-index:1}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field input[type=number]{padding:2px;margin-left:4px;text-align:center;-moz-appearance:textfield}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field input[type=number]:focus{position:relative;z-index:1}.components-datetime__time .components-datetime__time-wrapper .components-datetime__time-field input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.components-datetime__time.is-12-hour .components-datetime__time-field-day input{margin:-4px 0 0!important;border-radius:0 2px 2px 0!important}.components-datetime__time.is-12-hour .components-datetime__time-field-year input{border-radius:2px 0 0 2px!important}.components-datetime__timezone{line-height:30px;margin-right:4px;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.components-datetime__time-legend{font-weight:600;margin-top:.5em}.components-datetime__time-legend.invisible{position:absolute;top:-999em;right:-999em}.components-datetime__time-field-day-input,.components-datetime__time-field-hours-input,.components-datetime__time-field-minutes-input{width:35px}.components-datetime__time-field-year-input{width:55px}.components-datetime__time-field-month-select{max-width:145px}.components-popover .components-datetime__date{padding-right:4px}.components-drop-zone{position:absolute;top:0;left:0;bottom:0;right:0;z-index:40;visibility:hidden;opacity:0;transition:opacity .3s,background-color .3s,visibility 0s .3s;border:2px solid #007cba;border:2px solid var(--wp-admin-theme-color);border-radius:2px}@media (prefers-reduced-motion:reduce){.components-drop-zone{transition-duration:0s}}.components-drop-zone.is-active{opacity:1;visibility:visible;transition:opacity .3s,background-color .3s}@media (prefers-reduced-motion:reduce){.components-drop-zone.is-active{transition-duration:0s}}.components-drop-zone.is-dragging-over-element{background-color:#007cba;background-color:var(--wp-admin-theme-color)}.components-drop-zone__content{position:absolute;top:50%;right:0;left:0;z-index:50;transform:translateY(-50%);width:100%;text-align:center;color:#fff;transition:transform .2s ease-in-out}@media (prefers-reduced-motion:reduce){.components-drop-zone__content{transition-duration:0s}}.components-drop-zone.is-dragging-over-element .components-drop-zone__content{transform:translateY(-50%) scale(1.05)}.components-drop-zone__content-icon,.components-drop-zone__content-text{display:block}.components-drop-zone__content-icon{margin:0 auto;line-height:0;fill:currentColor}.components-drop-zone__content-text{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}.components-drop-zone__provider{height:100%}.components-tab-panel__tabs{display:flex;align-items:stretch}.components-tab-panel__tabs-item{background:transparent;border:none;box-shadow:none;border-radius:0;cursor:pointer;height:48px;padding:3px 16px;margin-right:0;font-weight:500;transition:box-shadow .1s linear;box-sizing:border-box}.components-tab-panel__tabs-item:after{content:attr(data-label);display:block;height:0;overflow:hidden;speak:none;visibility:hidden}.components-tab-panel__tabs-item:focus:not(:disabled){box-shadow:inset 0 1.5px #007cba;box-shadow:inset 0 1.5px var(--wp-admin-theme-color)}.components-tab-panel__tabs-item.is-active{box-shadow:inset 0 0 0 1.5px transparent,inset 0 -4px 0 0 #007cba;box-shadow:inset 0 0 0 1.5px transparent,inset 0 -4px 0 0 var(--wp-admin-theme-color);position:relative}.components-tab-panel__tabs-item.is-active:before{content:"";position:absolute;top:0;bottom:1px;left:0;right:0;border-bottom:4px solid transparent}.components-tab-panel__tabs-item:focus{box-shadow:inset 0 0 0 1.5px #007cba;box-shadow:inset 0 0 0 1.5px var(--wp-admin-theme-color)}.components-tab-panel__tabs-item.is-active:focus{box-shadow:inset 0 0 0 1.5px #007cba,inset 0 -4px 0 0 #007cba;box-shadow:inset 0 0 0 1.5px var(--wp-admin-theme-color),inset 0 -4px 0 0 var(--wp-admin-theme-color)}@media (min-width:600px){.components-guide{width:600px}}.components-guide .components-modal__header{background:none;border-bottom:none;width:100%;padding:0;margin:0}.components-guide .components-modal__header .components-button{align-self:flex-start;margin:8px 0 0 8px;position:static}.components-guide .components-modal__header .components-button:hover svg{fill:#fff}.components-guide__container{display:flex;flex-direction:column;justify-content:space-between;margin-top:-60px;min-height:100%}.components-guide__page{display:flex;flex-direction:column;justify-content:center;position:relative}@media (min-width:600px){.components-guide__page{min-height:300px}}.components-guide__footer{align-content:center;display:flex;height:30px;justify-content:center;margin:0 0 24px;padding:0 32px;position:relative;width:100%}@media (max-width:600px){.components-guide__footer{position:absolute;bottom:0}}.components-guide__page-control{margin:8px 0;text-align:center}.components-guide__page-control li{display:inline-block}.components-guide__page-control .components-button{height:30px;min-width:20px}.components-guide .components-modal__content{padding:0}.components-modal__frame.components-guide{border:none;min-width:312px;height:80vh;max-height:575px}@media (max-width:600px){.components-modal__frame.components-guide{bottom:5%;right:16px;left:16px;top:5%;margin:0 auto}}.components-button.components-guide__back-button,.components-button.components-guide__finish-button,.components-button.components-guide__forward-button{height:30px;position:absolute}.components-button.components-guide__back-button,.components-button.components-guide__forward-button{font-size:13px;padding:4px 2px}.components-button.components-guide__back-button.has-text svg,.components-button.components-guide__forward-button.has-text svg{margin:0}.components-button.components-guide__back-button:hover,.components-button.components-guide__forward-button:hover{text-decoration:underline}.components-button.components-guide__back-button{right:32px}.components-button.components-guide__forward-button{left:32px;color:#1386bf;font-weight:700}.components-button.components-guide__finish-button{left:32px}.components-button.components-guide__inline-finish-button{display:none}.components-animate__appear{animation:components-animate__appear-animation .1s cubic-bezier(0,0,.2,1) 0s;animation-fill-mode:forwards}@media (prefers-reduced-motion:reduce){.components-animate__appear{animation-duration:1ms}}.components-animate__appear.is-from-top,.components-animate__appear.is-from-top.is-from-left{transform-origin:top right}.components-animate__appear.is-from-top.is-from-right{transform-origin:top left}.components-animate__appear.is-from-bottom,.components-animate__appear.is-from-bottom.is-from-left{transform-origin:bottom right}.components-animate__appear.is-from-bottom.is-from-right{transform-origin:bottom left}@keyframes components-animate__appear-animation{0%{transform:translateY(-2em) scaleY(0) scaleX(0)}to{transform:translateY(0) scaleY(1) scaleX(1)}}.components-animate__slide-in{animation:components-animate__slide-in-animation .1s cubic-bezier(0,0,.2,1);animation-fill-mode:forwards}@media (prefers-reduced-motion:reduce){.components-animate__slide-in{animation-duration:1ms}}.components-animate__slide-in.is-from-left{transform:translateX(-100%)}.components-animate__slide-in.is-from-right{transform:translateX(100%)}@keyframes components-animate__slide-in-animation{to{transform:translateX(0)}}.components-animate__loading{animation:components-animate__loading 1.6s ease-in-out infinite}@keyframes components-animate__loading{0%{opacity:.5}50%{opacity:1}to{opacity:.5}}.woocommerce-layout{margin:0;padding:0}.woocommerce-layout__primary{margin:80px 40px 0 0;margin:80px var(--large-gap) 0 0}@media (min-width:961px){.woocommerce-layout__primary{margin-top:100px}}@media (max-width:782px){.woocommerce-layout__primary{margin-top:60px}}.woocommerce-layout .woocommerce-layout__main{padding-left:40px;padding-left:var(--large-gap);max-width:100%}.woocommerce-admin-is-loading #adminmenumain,.woocommerce-admin-is-loading #wpadminbar,.woocommerce-admin-is-loading #wpbody-content,.woocommerce-admin-is-loading #wpcontent,.woocommerce-admin-is-loading #wpfooter,.woocommerce-admin-is-loading .components-modal__screen-overlay,.woocommerce-admin-is-loading .error,.woocommerce-admin-is-loading .notice,.woocommerce-admin-is-loading .update-nag,.woocommerce-admin-is-loading .updated,.woocommerce-admin-is-loading .woocommerce-layout__header,.woocommerce-admin-is-loading .woocommerce-message,.woocommerce-admin-is-loading .woocommerce-store-alerts,.woocommerce-page .update-nag{display:none}.woocommerce-admin-full-screen{background:#f6f7f7;color:#50575e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;margin-top:-32px}.woocommerce-admin-full-screen #wpwrap{top:0}.woocommerce-admin-full-screen #wpbody-content{min-height:100vh}.woocommerce-admin-full-screen #adminmenumain,.woocommerce-admin-full-screen #wpcontent>*,.woocommerce-admin-full-screen .error,.woocommerce-admin-full-screen .notice,.woocommerce-admin-full-screen .update-nag,.woocommerce-admin-full-screen .updated,.woocommerce-admin-full-screen .woocommerce-layout__header,.woocommerce-admin-full-screen .woocommerce-message,.woocommerce-admin-full-screen .woocommerce-store-alerts{display:none}.woocommerce-admin-full-screen #wpcontent{margin-right:0!important}.woocommerce-admin-full-screen #wpcontent>#wpbody{display:block}.woocommerce-onboarding .muriel-component{margin-top:16px;margin-bottom:16px}.woocommerce-onboarding .components-base-control.has-error{margin-bottom:32px!important;border-color:#d63638}@media (max-width:782px){.woocommerce-onboarding .components-base-control.has-error{margin-bottom:44px!important}}.woocommerce-onboarding .components-base-control.has-error .components-base-control__help{top:100%;right:12px;position:absolute;margin-top:4px;font-size:12px;font-style:normal;color:#d63638}.woocommerce-onboarding .components-form-toggle{display:inline-block}.woocommerce-onboarding .components-form-toggle label{font-size:14px}.woocommerce-onboarding .components-form-toggle .components-base-control{display:inline-block}.woocommerce-onboarding .components-form-toggle .components-base-control__field{margin-bottom:0}.woocommerce-page .components-modal__frame .components-button.is-button,.woocommerce-profile-wizard__body .components-button.is-button,.woocommerce-task-dashboard__container .components-button.is-button{height:48px;padding-right:25px;padding-left:25px;text-align:center;font-size:14px;line-height:36px;font-weight:500;align-items:center}.woocommerce-page .components-modal__frame .components-button.is-button:disabled,.woocommerce-profile-wizard__body .components-button.is-button:disabled,.woocommerce-task-dashboard__container .components-button.is-button:disabled{cursor:not-allowed}.components-modal__frame.woocommerce-cart-modal{width:600px;max-width:100%}.components-modal__frame.woocommerce-cart-modal .components-modal__header{border-bottom:0;margin-bottom:16px;margin-top:16px}.components-modal__frame.woocommerce-cart-modal .components-modal__header button{display:none}.components-modal__frame.woocommerce-cart-modal .components-modal__header-heading{font-style:normal;font-weight:400;font-size:24px;line-height:32px}.components-modal__frame.woocommerce-cart-modal .woocommerce-list{margin-top:4px}.components-modal__frame.woocommerce-cart-modal .woocommerce-list .woocommerce-list__item:first-child{border-top:1px solid #dcdcde}.components-modal__frame.woocommerce-cart-modal .woocommerce-list__item{border-bottom:1px solid #dcdcde}.components-modal__frame.woocommerce-cart-modal .woocommerce-cart-modal__help-text{font-size:16px;line-height:24px}.components-modal__frame.woocommerce-cart-modal .woocommerce-cart-modal__actions{text-align:left}.components-modal__frame.woocommerce-cart-modal .woocommerce-cart-modal__actions button.is-link{margin-left:16px;text-decoration:none;font-weight:600;font-size:14px}.components-modal__frame.woocommerce-cart-modal .woocommerce-cart-modal__actions button.is-primary{align-self:flex-end}.woocommerce-layout__header{background:#fff;box-sizing:border-box;padding:0;min-height:60px;position:fixed;width:100%;top:32px;z-index:1001}.woocommerce-layout__header.is-scrolled{box-shadow:0 8px 8px 0 rgba(85,93,102,.3)}@media (max-width:782px){.woocommerce-layout__header{flex-flow:row wrap;top:46px}}.woocommerce-layout__header .woocommerce-layout__header-breadcrumbs-wrapper{display:flex;justify-content:space-between;flex-direction:row}.woocommerce-layout__header .woocommerce-layout__header-heading{display:flex;align-items:center;padding:0 40px 0 0;padding:0 var(--large-gap) 0 0;flex:1 auto;height:60px;line-height:60px;background:#fff;font-weight:600;font-size:14px;text-transform:capitalize}.has-woocommerce-navigation .woocommerce-layout__header{top:0}.woocommerce-page #contextual-help-link-wrap,.woocommerce-page #screen-options-link-wrap{margin-top:-1px}.woocommerce-layout__activity-panel{display:flex;flex-direction:row;align-items:center;position:fixed;left:0;top:32px;height:60px}@media (max-width:782px){.woocommerce-layout__activity-panel{position:relative;background:#fff;margin:0;padding:0;width:100vw;display:none;flex:1 100%}}@media (min-width:783px) and (max-width:960px){.woocommerce-layout__activity-panel{max-width:280px}}@media (min-width:1281px){.woocommerce-layout__activity-panel{max-width:400px}}.woocommerce-layout__activity-panel.is-mobile-open{display:flex}.woocommerce-layout__activity-panel-tabs{width:100%;display:flex;height:60px;justify-content:flex-end}.woocommerce-layout__activity-panel-tabs .dashicon,.woocommerce-layout__activity-panel-tabs .gridicon{width:100%}.woocommerce-layout__activity-panel-tabs svg{width:24px;height:24px}.woocommerce-layout__activity-panel-tabs svg.woocommerce-layout__activity-panel-tab-icon{fill:none}.woocommerce-layout__activity-panel-tabs svg.woocommerce-layout__activity-panel-tab-icon path,.woocommerce-layout__activity-panel-tabs svg.woocommerce-layout__activity-panel-tab-icon rect{stroke:currentColor}.woocommerce-layout__activity-panel-tabs svg.setup-progress path:first-child{stroke:"#DCDCDE"}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__homescreen-display-options svg.woocommerce-layout__activity-panel-tab-icon{height:14px}.woocommerce-layout__activity-panel-tabs .components-icon-button{display:initial;text-indent:0;border-radius:0}.woocommerce-layout__activity-panel-tabs .components-icon-button.has-text svg{margin:0}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab{display:flex;flex-direction:column;justify-content:center;align-items:center;position:relative;border:none;outline:none;cursor:pointer;background-color:#fff;max-width:-webkit-min-content;max-width:min-content;min-width:80px;width:100%;height:60px;color:#757575;white-space:nowrap}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:before{background-color:#007cba;background-color:var(--wp-admin-theme-color);bottom:0;content:"";height:0;opacity:0;transition-property:height,opacity;transition-duration:.3s;transition-timing-function:ease-in-out;right:0;position:absolute;left:0}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.is-active,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.is-opened{color:#1e1e1e;box-shadow:none}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.is-active:before,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.is-opened:before{height:3px;opacity:1}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.woocommerce-layout__activity-panel-tab-wordpress-notices:after{content:" ";position:absolute;padding:1px;background:#d94f4f;border:2px solid #fff;width:4px;height:4px;display:inline-block;border-radius:50%;top:8px;right:50%}@media (min-width:783px) and (max-width:960px){.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.woocommerce-layout__activity-panel-tab-wordpress-notices:after{left:18px;right:auto;margin-right:0}}@media (min-width:961px){.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.woocommerce-layout__activity-panel-tab-wordpress-notices:after{left:28px;right:auto;margin-right:0}}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.components-button:not(:disabled):not([aria-disabled=true]):hover,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:hover{background-color:#f0f0f0;box-shadow:none}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.components-button:not(:disabled):not([aria-disabled=true]):hover.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.components-button:not(:disabled):not([aria-disabled=true]):hover.woocommerce-layout__activity-panel-tab-wordpress-notices:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:hover.has-unread:after,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:hover.woocommerce-layout__activity-panel-tab-wordpress-notices:after{border-color:#e0e0e0}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.components-button:not(:disabled):not([aria-disabled=true]):focus,.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab:focus{box-shadow:inset 1px -1px 0 #757575,inset -1px 1px 0 #757575}@media (max-width:782px){.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-tab.display-options{display:none}}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-popover{margin-top:0;z-index:1001}.woocommerce-layout__activity-panel-tabs .woocommerce-layout__activity-panel-popover .components-menu-group{padding:12px}.woocommerce-layout__activity-panel-mobile-toggle{margin-left:10px;max-width:48px;height:60px;position:absolute;left:0;bottom:0}@media (min-width:783px){.woocommerce-layout__activity-panel-mobile-toggle{display:none}}.wp-responsive-open .woocommerce-layout__activity-panel-mobile-toggle{display:none}.woocommerce-layout__activity-panel-toggle-bubble.has-unread:after{content:" ";position:absolute;padding:1px;background:#ca4a1f;border:2px solid #fff;width:4px;height:4px;display:inline-block;border-radius:50%;top:6px;left:4px}@keyframes tabSwitch{0%,to{transform:translateX(0)}50%{transform:translateX(-100px)}}.woocommerce-layout__activity-panel-wrapper{height:calc(100vh - 166px);background:#f0f0f0;width:510px;transform:translateX(-100%);transition-property:transform box-shadow;transition-duration:.3s;transition-timing-function:ease-in-out;position:fixed;left:0;top:166px;z-index:1000;overflow-x:hidden;overflow-y:auto}@media (max-width:782px){.woocommerce-layout__activity-panel-wrapper{width:100%}}@media screen and (prefers-reduced-motion:reduce){.woocommerce-layout__activity-panel-wrapper{transition-duration:1ms}}@media (min-width:783px){.woocommerce-layout__activity-panel-wrapper{height:calc(100vh - 92px);top:92px}}.woocommerce-layout__activity-panel-wrapper.is-open{transform:none;box-shadow:0 12px 12px 0 rgba(85,93,102,.3)}.woocommerce-layout__activity-panel-wrapper.is-switching{animation:tabSwitch;animation-duration:.3s}@media screen and (prefers-reduced-motion:reduce){.woocommerce-layout__activity-panel-wrapper.is-switching{animation:none}}.woocommerce-layout__activity-panel-wrapper .woocommerce-empty-content{padding-right:24px;padding-left:24px}.woocommerce-layout__activity-panel-avatar-flag-overlay{position:relative;top:-12px}.woocommerce-layout__activity-panel-avatar-flag-overlay .woocommerce-flag{position:relative;top:16px;border:2px solid #fff}.woocommerce-layout__notice-list-hide{display:none}.has-woocommerce-navigation .woocommerce-layout__activity-panel{top:0}.woocommerce-layout__show-app-banner{padding-top:56px}@media (min-width:783px){.woocommerce-layout__show-app-banner{padding-top:0}}.woocommerce-mobile-app-banner{background-color:#3c2861;width:100%;display:flex;height:56px;align-items:center;padding:0 4px 0 6px}@media (min-width:401px){.woocommerce-mobile-app-banner{padding:0 10px 0 13px}}@media (min-width:783px){.woocommerce-mobile-app-banner{display:none}}.woocommerce-mobile-app-banner .dashicon{fill:#fff;margin-left:10px}.woocommerce-mobile-app-banner .components-button.is-secondary{margin-right:auto;color:#fff;box-shadow:inset 0 0 0 1px #fff}.woocommerce-mobile-app-banner .components-button.is-secondary:active,.woocommerce-mobile-app-banner .components-button.is-secondary:hover{color:#fff;box-shadow:inset 0 0 0 1px #fff;background:none}.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description{color:#fff;margin-right:8px}@media (min-width:401px){.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description{margin-right:13px}}.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description .woocommerce-mobile-app-banner__description__text{margin:0;font-size:10px}.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description .woocommerce-mobile-app-banner__description__text:first-child{font-weight:700}@media (min-width:401px){.woocommerce-mobile-app-banner .woocommerce-mobile-app-banner__description .woocommerce-mobile-app-banner__description__text{margin-right:13px;font-size:13px}}.woocommerce-transient-notices{position:fixed;bottom:12px;right:176px;z-index:99999}@media (max-width:960px){.woocommerce-transient-notices{right:50px}}@media (max-width:782px){.woocommerce-transient-notices{right:16px}}.woocommerce-profile-wizard__body .woocommerce-transient-notices{right:unset}.woocommerce-profile-wizard__body .woocommerce-transient-notices .components-snackbar{margin-right:auto;margin-left:auto}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-navigation h2{color:inherit}.woocommerce-navigation .components-navigation__menu{display:flex;flex-direction:column;height:100%}.woocommerce-navigation .components-navigation__group+.components-navigation__group{margin-top:24px}.woocommerce-navigation .components-navigation__item{margin-bottom:0}.woocommerce-navigation .woocommerce-navigation__back-to-dashboard{margin-top:24px}.woocommerce-navigation-header{display:flex;align-items:center;border:none;border-radius:0;height:auto}.woocommerce-navigation-header .woocommerce-navigation-header__site-icon.components-button{padding:12px;height:60px;color:#fff}.woocommerce-navigation-header .woocommerce-navigation-header__site-icon.components-button:focus,.woocommerce-navigation-header .woocommerce-navigation-header__site-icon.components-button:hover,.woocommerce-navigation-header .woocommerce-navigation-header__site-icon.components-button:not([aria-disabled=true]):active{color:#fff}.woocommerce-navigation-header .woocommerce-navigation-header__site-title.components-button{padding-right:0;color:#ccc;font-weight:600}.woocommerce-navigation-header .woocommerce-navigation-header__site-title.components-button:active,.woocommerce-navigation-header .woocommerce-navigation-header__site-title.components-button:focus,.woocommerce-navigation-header .woocommerce-navigation-header__site-title.components-button:hover{color:#e0e0e0}.has-woocommerce-navigation{margin-top:-32px}.has-woocommerce-navigation #adminmenuback,.has-woocommerce-navigation #adminmenuwrap,.has-woocommerce-navigation #wpadminbar{display:none!important}.has-woocommerce-navigation #woocommerce-embedded-navigation{position:fixed;top:0;right:0;width:240px;height:100%;box-sizing:border-box;background-color:#1e1e1e;z-index:1100}.has-woocommerce-navigation .components-navigation{overflow-y:auto;height:calc(100vh - 60px);box-sizing:border-box}.has-woocommerce-navigation:not(.is-folded) #wpcontent,.has-woocommerce-navigation:not(.is-folded) #wpfooter{margin-right:240px}@media (max-width:960px){.has-woocommerce-navigation:not(.is-folded) #wpcontent,.has-woocommerce-navigation:not(.is-folded) #wpfooter{margin-right:0}}.has-woocommerce-navigation.is-folded #wpcontent,.has-woocommerce-navigation.is-folded #wpfooter{margin-right:0}.has-woocommerce-navigation.is-folded .woocommerce-layout__header{margin-right:60px}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation{width:60px;height:60px}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation .woocommerce-navigation-header.is-scrolled{box-shadow:0 8px 8px 0 rgba(85,93,102,.3)}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation .woocommerce-navigation-header>*{display:none}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation .woocommerce-navigation-header__site-icon{display:block}.has-woocommerce-navigation.is-folded #woocommerce-embedded-navigation .components-navigation{display:none} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/0.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/0.js new file mode 100644 index 0000000..06ffa9b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/0.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[0],{439:function(e,t,r){"use strict";var n=r(8),a=r(12),c=r(4),o=r.n(c),i=r(0);function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}t.a=function(e){var t=e.as,r=void 0===t?"div":t,c=e.className,s=Object(a.a)(e,["as","className"]);return function(e){var t=e.as,r=void 0===t?"div":t,n=Object(a.a)(e,["as"]);return"function"==typeof n.children?n.children(n):Object(i.createElement)(r,n)}(function(e){for(var t=1;t0||e.offsetHeight>0||e.getClientRects().length>0}function i(e){var t=e.querySelectorAll(c);return Array.from(t).filter((function(e){return!!o(e)&&("AREA"!==e.nodeName||function(e){var t=e.closest("map[name]");if(!t)return!1;var r=document.querySelector('img[usemap="#'+t.name+'"]');return!!r&&o(r)}(e))}))}var l=r(2);function s(e){var t=e.getAttribute("tabindex");return null===t?0:parseInt(t,10)}function u(e){return-1!==s(e)}function d(e,t){return{element:e,index:t}}function b(e){return e.element}function m(e,t){var r=s(e.element),n=s(t.element);return r===n?e.index-t.index:r-n}function p(e){return e.filter(u).map(d).sort(m).map(b).reduce((t={},function(e,r){var n=r.nodeName,a=r.type,c=r.checked,o=r.name;if("INPUT"!==n||"radio"!==a||!o)return e.concat(r);var i=t.hasOwnProperty(o);if(!c&&i)return e;if(i){var s=t[o];e=Object(l.without)(e,s)}return t[o]=r,e.concat(r)}),[]);var t}function f(e){return p(i(e))}function y(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.activeElement,t=i(document.body),r=t.indexOf(e);return t.length=r,Object(l.last)(p(t))}function O(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.activeElement,t=i(document.body),r=t.indexOf(e),n=t.slice(r+1).filter((function(t){return!e.contains(t)}));return Object(l.first)(p(n))}var h={focusable:n,tabbable:a}},762:function(e,t,r){"use strict";r.d(t,"b",(function(){return s})),r.d(t,"a",(function(){return u}));var n=r(0),a=r(55),c=r(214),o=r.n(c),i=r(36),l=o()(i.b),s=function(e){var t=l.getCurrencyConfig(),r=Object(a.applyFilters)("woocommerce_admin_report_currency",t,e);return o()(r)},u=Object(n.createContext)(l)},763:function(e,t,r){"use strict";var n=r(17),a=r.n(n),c=r(15),o=r.n(c),i=r(18),l=r.n(i),s=r(19),u=r.n(s),d=r(9),b=r.n(d),m=r(0),p=r(3),f=r(1),y=r.n(f),O=r(77),h=r(36);function g(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,n=b()(e);if(t){var a=b()(this).constructor;r=Reflect.construct(n,arguments,a)}else r=n.apply(this,arguments);return u()(this,r)}}var j=function(e){l()(r,e);var t=g(r);function r(){return a()(this,r),t.apply(this,arguments)}return o()(r,[{key:"render",value:function(){var e,t,r,n,a=this.props,c=a.className,o=a.isError,i=a.isEmpty;return o?(e=Object(p.__)("There was an error getting your stats. Please try again.",'woocommerce'),t=Object(p.__)("Reload",'woocommerce'),n=function(){window.location.reload()}):i&&(e=Object(p.__)("No results could be found for this date range.",'woocommerce'),t=Object(p.__)("View Orders",'woocommerce'),r=Object(h.f)("edit.php?post_type=shop_order")),Object(m.createElement)(O.EmptyContent,{className:c,title:e,actionLabel:t,actionURL:r,actionCallback:n})}}]),r}(m.Component);j.propTypes={className:y.a.string,isError:y.a.bool,isEmpty:y.a.bool},j.defaultProps={className:""},t.a=j},767:function(e,t,r){"use strict";var n=r(0),a=r(4),c=r.n(a),o=r(439);function i(e){var t=e.id,r=e.label,a=e.hideLabelFromVision,l=e.help,s=e.className,u=e.children;return Object(n.createElement)("div",{className:c()("components-base-control",s)},Object(n.createElement)("div",{className:"components-base-control__field"},r&&t&&(a?Object(n.createElement)(o.a,{as:"label",htmlFor:t},r):Object(n.createElement)("label",{className:"components-base-control__label",htmlFor:t},r)),r&&!t&&(a?Object(n.createElement)(o.a,{as:"label"},r):Object(n.createElement)(i.VisualLabel,null,r)),u),!!l&&Object(n.createElement)("p",{id:t+"__help",className:"components-base-control__help"},l))}i.VisualLabel=function(e){var t=e.className,r=e.children;return t=c()("components-base-control__label",t),Object(n.createElement)("span",{className:t},r)},t.a=i},770:function(e,t,r){"use strict";var n=r(5),a=r.n(n),c=r(17),o=r.n(c),i=r(15),l=r.n(i),s=r(11),u=r.n(s),d=r(18),b=r.n(d),m=r(19),p=r.n(m),f=r(9),y=r.n(f),O=r(0),h=r(1),g=r.n(h),j=r(2),v=r(20),_=r(77),w=r(36),E=r(35),k=r(40),S=r(64),P=r(762);function D(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function R(e){for(var t=1;t0,oe=Object(P.getSearchWords)(q).map((function(e){return{key:e,label:e}})),ie=Object(y.applyFilters)("woocommerce_admin_report_table",{endpoint:d,headers:t(),rows:r(Q.data),totals:ne,summary:n?n(ne,ae):null,items:Q}),le=ie.headers,se=ie.rows,ue=ie.summary;O&&(se=se.map((function(e,t){return[te(t)].concat(o()(e))})),le=[(W=e.ids,Y=void 0===W?[]:W,X=Y.length>0,Z=X&&Y.length===U.length,{cellClassName:"is-checkbox-column",key:"compare",label:Object(m.createElement)(p.a,{onChange:$,"aria-label":Object(v.__)("Select All"),checked:Z,disabled:!X}),required:!0})].concat(o()(le)));var de=function(e,t){return t?e.map((function(e){return A(A({},e),{},{visible:e.required||!t.includes(e.key)})})):e.map((function(e){return A(A({},e),{},{visible:e.required||!e.hiddenByDefault})}))}(le,K),be=w()("woocommerce-report-table",{"has-compare":!!O,"has-search":!!_});return Object(m.createElement)(m.Fragment,null,Object(m.createElement)("div",{className:"woocommerce-report-table__scroll-point",ref:H,"aria-hidden":!0}),Object(m.createElement)(S.TableCard,a()({className:be,actions:[O&&Object(m.createElement)(S.CompareButton,{key:"compare",className:"woocommerce-table__compare",count:U.length,helpText:k.helpText||Object(v.__)("Check at least two items below to compare",'woocommerce'),onClick:function(){O&&Object(P.onQueryChange)("compare")(O,g,U.join(","))},disabled:!ce},k.compareButton||Object(v.__)("Compare",'woocommerce')),_&&Object(m.createElement)(S.Search,{allowFreeTextSearch:!0,inlineTags:!0,key:"search",onChange:function(t){var r,n=e.baseSearchQuery,a=t.map((function(e){return e.label.replace(",","%2C")}));a.length?Object(P.updateQueryString)(A(A((r={filter:void 0},l()(r,g,void 0),l()(r,_,void 0),r),n),{},{search:Object(j.uniq)(a).join(",")})):Object(P.updateQueryString)({search:void 0});Object(C.recordEvent)("analytics_table_filter",{report:d})},placeholder:k.placeholder||Object(v.__)("Search by item name",'woocommerce'),selected:oe,showClearButton:!0,type:_,disabled:!ce}),ce&&Object(m.createElement)(f.a,{key:"download",className:"woocommerce-table__download-button",disabled:re,onClick:function(){var n=e.createNotice,a=e.startExport,c=e.title,o=Object.assign({},q),i=Q.data,l=Q.totalResults,s="browser";delete o.extended_info,o.search&&delete o[_],i&&i.length===l?Object(D.downloadCSVFile)(Object(D.generateCSVFileName)(c,o),Object(D.generateCSVDataFromTable)(t(),r(i))):(s="email",a(d,I).then((function(){return n("success",Object(v.sprintf)(Object(v.__)("Your %s Report will be emailed to you.",'woocommerce'),c))})).catch((function(e){return n("error",e.message||Object(v.sprintf)(Object(v.__)("There was a problem exporting your %s Report. Please try again.",'woocommerce'),c))}))),Object(C.recordEvent)("analytics_table_download",{report:d,rows:l,downloadType:s})}},Object(m.createElement)(N,null),Object(m.createElement)("span",{className:"woocommerce-table__download-button__label"},k.downloadButton||Object(v.__)("Download",'woocommerce')))],headers:de,isLoading:re,onQueryChange:P.onQueryChange,onColumnsChange:function(e,t){var r=le.map((function(e){return e.key})).filter((function(t){return!e.includes(t)}));if(T){var n=l()({},T,r);G(n)}if(t){var a={report:d,column:t,status:e.includes(t)?"on":"off"};Object(C.recordEvent)("analytics_table_header_toggle",a)}},onSort:function(e,t){Object(P.onQueryChange)("sort")(e,t);var r={report:d,column:e,direction:t};Object(C.recordEvent)("analytics_table_sort",r)},onPageChange:function(e,t){H.current.scrollIntoView();var r=H.current.nextSibling.querySelector(".woocommerce-table__table"),n=h.a.focusable.find(r);n.length&&n[0].focus(),t&&("goto"===t?Object(C.recordEvent)("analytics_table_go_to_page",{report:d,page:e}):Object(C.recordEvent)("analytics_table_page_click",{report:d,direction:t}))},rows:se,rowsPerPage:parseInt(I.per_page,10)||R.QUERY_DEFAULTS.pageSize,summary:ue,totalRows:ae},F)))};Q.propTypes={baseSearchQuery:k.a.object,compareBy:k.a.string,compareParam:k.a.string,columnPrefsKey:k.a.string,endpoint:k.a.string,extendItemsMethodNames:k.a.shape({getError:k.a.string,isRequesting:k.a.string,load:k.a.string}),extendedItemsStoreName:k.a.string,getHeadersContent:k.a.func.isRequired,getRowsContent:k.a.func.isRequired,getSummary:k.a.func,itemIdField:k.a.string,labels:k.a.shape({compareButton:k.a.string,downloadButton:k.a.string,helpText:k.a.string,placeholder:k.a.string}),primaryData:k.a.object,searchBy:k.a.string,summaryFields:k.a.arrayOf(k.a.string),tableData:k.a.object.isRequired,tableQuery:k.a.object,title:k.a.string.isRequired},Q.defaultProps={primaryData:{},tableData:{items:{data:[],totalResults:0},query:{}},tableQuery:{},compareParam:"filter",downloadable:!1,onSearch:j.noop,baseSearchQuery:{}};t.a=Object(O.a)(Object(g.withSelect)((function(e,t){var r=t.endpoint,n=t.getSummary,a=t.isRequesting,c=t.itemIdField,o=t.query,i=t.tableData,l=t.tableQuery,s=t.filters,u=t.advancedFilters,d=t.summaryFields;if(a||o.search&&(!o[r]||!o[r].length))return{};var b=e(R.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,m="categories"===r?"products":r,p=n?Object(R.getReportChartData)({endpoint:m,dataType:"primary",query:o,select:e,filters:s,advancedFilters:u,tableQuery:l,defaultDateRange:b,fields:d}):{},f=function(e,t,r){var n=t.extendItemsMethodNames,a=t.extendedItemsStoreName,c=t.itemIdField,o=r.items.data;if(!(Array.isArray(o)&&o.length&&n&&c))return r;var i=e(a),l=i[n.getError],s=i[n.isRequesting],u=i[n.load],d={include:o.map((function(e){return e[c]})).join(","),per_page:o.length},b=u(d),m=!!s&&s(d),p=!!l&&l(d),f=o.map((function(e){var t=Object(j.first)(b.filter((function(t){return e.id===t.id})));return q(q({},e),t)})),y=r.isRequesting||m,O=r.isError||p;return q(q({},r),{},{isRequesting:y,isError:O,items:q(q({},r.items),{},{data:f})})}(e,t,i||Object(R.getReportTableData)({endpoint:r,query:o,select:e,tableQuery:l,filters:s,advancedFilters:u,defaultDateRange:b}));return{primaryData:p,ids:c&&f.items.data?f.items.data.map((function(e){return e[c]})):[],tableData:f,query:A(A({},l),o)}})),Object(g.withDispatch)((function(e){var t=e(R.EXPORT_STORE_NAME).startExport;return{createNotice:e("core/notices").createNotice,startExport:t}})))(Q)},779:function(e,t,r){"use strict";r.d(t,"a",(function(){return u}));var n=r(7),a=r(12),c=r(0),o=r(300),i=r(575),l=r(759),s=r(767);function u(e){var t=e.label,r=e.className,d=e.heading,b=e.checked,m=e.help,p=e.onChange,f=Object(a.a)(e,["label","className","heading","checked","help","onChange"]),y=Object(o.a)(u),O="inspector-checkbox-control-".concat(y);return Object(c.createElement)(s.a,{label:d,id:O,help:m,className:r},Object(c.createElement)("span",{className:"components-checkbox-control__input-container"},Object(c.createElement)("input",Object(n.a)({id:O,className:"components-checkbox-control__input",type:"checkbox",value:"1",onChange:function(e){return p(e.target.checked)},checked:b,"aria-describedby":m?O+"__help":void 0},f)),b?Object(c.createElement)(i.a,{icon:l.a,className:"components-checkbox-control__checked",role:"presentation"}):null),Object(c.createElement)("label",{className:"components-checkbox-control__label",htmlFor:O},t))}},827:function(e,t,r){}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/0.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/0.style.css new file mode 100644 index 0000000..226bae1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/0.style.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-report-table__scroll-point{position:relative;top:-48px}@media (max-width:782px){.woocommerce-report-table__scroll-point{top:-62px}}.woocommerce-feature-enabled-activity-panels .woocommerce-report-table__scroll-point{top:-108px}@media (max-width:782px){.woocommerce-feature-enabled-activity-panels .woocommerce-report-table__scroll-point{top:-122px}}.woocommerce-report-table .woocommerce-search{flex-grow:1}.woocommerce-report-table .woocommerce-card__header{position:relative}.woocommerce-report-table .woocommerce-table__compare.components-button{padding:8px}.woocommerce-report-table.has-compare .woocommerce-card__action,.woocommerce-report-table.has-search .woocommerce-card__action{align-items:center;text-align:left;display:-ms-grid;display:grid;width:100%;-ms-grid-columns:auto 1fr auto;grid-template-columns:auto 1fr auto}@media (max-width:960px){.woocommerce-report-table.has-compare .woocommerce-card__action,.woocommerce-report-table.has-search .woocommerce-card__action{grid-gap:12px;-ms-grid-columns:auto 1fr;grid-template-columns:auto 1fr;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:0;grid-row-end:2;-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:3;grid-column-end:4;margin:0}.woocommerce-report-table.has-compare .woocommerce-card__action .woocommerce-table__compare,.woocommerce-report-table.has-search .woocommerce-card__action .woocommerce-table__compare{display:flex}.woocommerce-report-table.has-compare .woocommerce-card__action .woocommerce-search,.woocommerce-report-table.has-search .woocommerce-card__action .woocommerce-search{-ms-grid-row:2;-ms-grid-row-span:1;-ms-grid-column:2;-ms-grid-column-span:2;grid-area:2/2/3/4;margin-right:0}.woocommerce-report-table.has-compare .woocommerce-card__action .woocommerce-table__download-button,.woocommerce-report-table.has-search .woocommerce-card__action .woocommerce-table__download-button{-ms-grid-row:1;-ms-grid-row-span:1;-ms-grid-column:2;-ms-grid-column-span:1;grid-area:1/2/2/3;-ms-grid-column-align:end;justify-self:end;margin:-6px 0;position:absolute}}.woocommerce-report-table.has-compare.has-compare:not(.has-search) .woocommerce-table__download-button,.woocommerce-report-table.has-search.has-compare:not(.has-search) .woocommerce-table__download-button{-ms-grid-row-align:center;align-self:center;-ms-grid-column:3;grid-column-start:3}@media (max-width:960px){.woocommerce-report-table.has-compare.has-compare:not(.has-search) .woocommerce-table__download-button,.woocommerce-report-table.has-search.has-compare:not(.has-search) .woocommerce-table__download-button{-ms-grid-row:1;-ms-grid-row-span:1;-ms-grid-column:2;-ms-grid-column-span:1;grid-area:1/2/2/3}.woocommerce-report-table.has-compare.has-compare:not(.has-search) .woocommerce-card__action,.woocommerce-report-table.has-search.has-compare:not(.has-search) .woocommerce-card__action{-ms-grid-columns:auto;grid-template-columns:auto}.woocommerce-report-table.has-compare.has-compare:not(.has-search) .woocommerce-card__action .woocommerce-table__compare,.woocommerce-report-table.has-search.has-compare:not(.has-search) .woocommerce-card__action .woocommerce-table__compare{-ms-grid-row:1;-ms-grid-column:2;grid-area:1/2/1/2;-ms-grid-column-align:left;justify-self:left;position:absolute}}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action{-ms-grid-columns:1fr auto;grid-template-columns:1fr auto}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-search,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-search{-ms-grid-row-align:center;align-self:center;-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-table__download-button,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-table__download-button{-ms-grid-row-align:center;align-self:center;-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3}@media (max-width:960px){.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action{-ms-grid-columns:auto;grid-template-columns:auto}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-search,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-search{-ms-grid-row:2;-ms-grid-row-span:1;-ms-grid-column:1;-ms-grid-column-span:3;grid-area:2/1/3/4;margin-left:0}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-table__download-button,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-table__download-button{-ms-grid-row:1;-ms-grid-row-span:1;-ms-grid-column:2;-ms-grid-column-span:1;grid-area:1/2/2/3}}.woocommerce-report-table.has-compare .woocommerce-search,.woocommerce-report-table.has-search .woocommerce-search{margin:0 16px}.woocommerce-report-table.has-compare .woocommerce-search .woocommerce-select-control__control,.woocommerce-report-table.has-search .woocommerce-search .woocommerce-select-control__control{height:38px}.woocommerce-report-table.has-compare .woocommerce-compare-button,.woocommerce-report-table.has-search .woocommerce-compare-button{padding:3px 12px;height:auto} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/0.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/0.style.rtl.css new file mode 100644 index 0000000..f58abba --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/0.style.rtl.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-report-table__scroll-point{position:relative;top:-48px}@media (max-width:782px){.woocommerce-report-table__scroll-point{top:-62px}}.woocommerce-feature-enabled-activity-panels .woocommerce-report-table__scroll-point{top:-108px}@media (max-width:782px){.woocommerce-feature-enabled-activity-panels .woocommerce-report-table__scroll-point{top:-122px}}.woocommerce-report-table .woocommerce-search{flex-grow:1}.woocommerce-report-table .woocommerce-card__header{position:relative}.woocommerce-report-table .woocommerce-table__compare.components-button{padding:8px}.woocommerce-report-table.has-compare .woocommerce-card__action,.woocommerce-report-table.has-search .woocommerce-card__action{align-items:center;text-align:right;display:-ms-grid;display:grid;width:100%;-ms-grid-columns:auto 1fr auto;grid-template-columns:auto 1fr auto}@media (max-width:960px){.woocommerce-report-table.has-compare .woocommerce-card__action,.woocommerce-report-table.has-search .woocommerce-card__action{grid-gap:12px;-ms-grid-columns:auto 1fr;grid-template-columns:auto 1fr;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:0;grid-row-end:2;-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:3;grid-column-end:4;margin:0}.woocommerce-report-table.has-compare .woocommerce-card__action .woocommerce-table__compare,.woocommerce-report-table.has-search .woocommerce-card__action .woocommerce-table__compare{display:flex}.woocommerce-report-table.has-compare .woocommerce-card__action .woocommerce-search,.woocommerce-report-table.has-search .woocommerce-card__action .woocommerce-search{-ms-grid-row:2;-ms-grid-row-span:1;-ms-grid-column:2;-ms-grid-column-span:2;grid-area:2/2/3/4;margin-left:0}.woocommerce-report-table.has-compare .woocommerce-card__action .woocommerce-table__download-button,.woocommerce-report-table.has-search .woocommerce-card__action .woocommerce-table__download-button{-ms-grid-row:1;-ms-grid-row-span:1;-ms-grid-column:2;-ms-grid-column-span:1;grid-area:1/2/2/3;-ms-grid-column-align:end;justify-self:end;margin:-6px 0;position:absolute}}.woocommerce-report-table.has-compare.has-compare:not(.has-search) .woocommerce-table__download-button,.woocommerce-report-table.has-search.has-compare:not(.has-search) .woocommerce-table__download-button{-ms-grid-row-align:center;align-self:center;-ms-grid-column:3;grid-column-start:3}@media (max-width:960px){.woocommerce-report-table.has-compare.has-compare:not(.has-search) .woocommerce-table__download-button,.woocommerce-report-table.has-search.has-compare:not(.has-search) .woocommerce-table__download-button{-ms-grid-row:1;-ms-grid-row-span:1;-ms-grid-column:2;-ms-grid-column-span:1;grid-area:1/2/2/3}.woocommerce-report-table.has-compare.has-compare:not(.has-search) .woocommerce-card__action,.woocommerce-report-table.has-search.has-compare:not(.has-search) .woocommerce-card__action{-ms-grid-columns:auto;grid-template-columns:auto}.woocommerce-report-table.has-compare.has-compare:not(.has-search) .woocommerce-card__action .woocommerce-table__compare,.woocommerce-report-table.has-search.has-compare:not(.has-search) .woocommerce-card__action .woocommerce-table__compare{-ms-grid-row:1;-ms-grid-column:2;grid-area:1/2/1/2;-ms-grid-column-align:left;justify-self:left;position:absolute}}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action{-ms-grid-columns:1fr auto;grid-template-columns:1fr auto}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-search,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-search{-ms-grid-row-align:center;align-self:center;-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-table__download-button,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-table__download-button{-ms-grid-row-align:center;align-self:center;-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3}@media (max-width:960px){.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action{-ms-grid-columns:auto;grid-template-columns:auto}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-search,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-search{-ms-grid-row:2;-ms-grid-row-span:1;-ms-grid-column:1;-ms-grid-column-span:3;grid-area:2/1/3/4;margin-right:0}.woocommerce-report-table.has-compare.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-table__download-button,.woocommerce-report-table.has-search.has-search:not(.has-compare) .woocommerce-card__action .woocommerce-table__download-button{-ms-grid-row:1;-ms-grid-row-span:1;-ms-grid-column:2;-ms-grid-column-span:1;grid-area:1/2/2/3}}.woocommerce-report-table.has-compare .woocommerce-search,.woocommerce-report-table.has-search .woocommerce-search{margin:0 16px}.woocommerce-report-table.has-compare .woocommerce-search .woocommerce-select-control__control,.woocommerce-report-table.has-search .woocommerce-search .woocommerce-select-control__control{height:38px}.woocommerce-report-table.has-compare .woocommerce-compare-button,.woocommerce-report-table.has-search .woocommerce-compare-button{padding:3px 12px;height:auto} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/1.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/1.js new file mode 100644 index 0000000..1844502 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/1.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[1],{154:function(a,i,e){"use strict";e.d(i,"a",(function(){return M}));var r=e(16),o=e.n(r),A=(e(443),e(548),{l10n:{locale:"en",months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdays:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],meridiem:{am:"am",pm:"pm",AM:"AM",PM:"PM"},relative:{future:"%s from now",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"}},formats:{time:"g: i a",date:"F j, Y",datetime:"F j, Y g: i a",datetimeAbbreviated:"M j, Y g: i a"},timezone:{offset:"0",string:""}});function c(){o.a.tz.add(o.a.tz.pack({name:"WP",abbrs:["WP"],untils:[null],offsets:[60*-A.timezone.offset||0]}))}var n={d:"DD",D:"ddd",j:"D",l:"dddd",N:"E",S:function(a){var i=a.format("D");return a.format("Do").replace(i,"")},w:"d",z:function(a){return""+parseInt(a.format("DDD"),10)-1},W:"W",F:"MMMM",m:"MM",M:"MMM",n:"M",t:function(a){return a.daysInMonth()},L:function(a){return a.isLeapYear()?"1":"0"},o:"GGGG",Y:"YYYY",y:"YY",a:"a",A:"A",B:function(a){var i=o()(a).utcOffset(60),e=parseInt(i.format("s"),10),r=parseInt(i.format("m"),10),A=parseInt(i.format("H"),10);return parseInt((e+60*r+3600*A)/86.4,10)},g:"h",G:"H",h:"hh",H:"HH",i:"mm",s:"ss",u:"SSSSSS",v:"SSS",e:"zz",I:function(a){return a.isDST()?"1":"0"},O:"ZZ",P:"Z",T:"z",Z:function(a){var i=a.format("Z"),e="-"===i[0]?-1:1,r=i.substring(1).split(":");return e*(60*r[0]+r[1])*60},c:"YYYY-MM-DDTHH:mm:ssZ",r:"ddd, D MMM YYYY HH:mm:ss ZZ",U:"X"};function M(a){var i,e,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new Date,A=[],c=o()(r);for(i=0;i96?a-87:a>64?a-29:a-48}function t(a){var i=0,e=a.split("."),r=e[0],o=e[1]||"",A=1,c=0,n=1;for(45===a.charCodeAt(0)&&(i=1,n=-1);i3){var i=A[h(a)];if(i)return i;L("Moment Timezone found "+a+" from the Intl api, but did not have that data loaded.")}}catch(a){}var e,r,o,c=function(){var a,i,e,r=(new Date).getFullYear()-2,o=new m(new Date(r,0,1)),A=[o];for(e=1;e<48;e++)(i=new m(new Date(r,e,1))).offset!==o.offset&&(a=l(o,i),A.push(a),A.push(new m(new Date(a.at+6e4)))),o=i;for(e=0;e<4;e++)A.push(new m(new Date(r+e,0,1))),A.push(new m(new Date(r+e,6,1)));return A}(),n=c.length,M=E(c),p=[];for(r=0;r0?p[0].zone.name:void 0}function h(a){return(a||"").toLowerCase().replace(/\//g,"_")}function T(a){var i,r,o,c;for("string"==typeof a&&(a=[a]),i=0;i= 2.6.0. You are using Moment.js "+a.version+". See momentjs.com"),f.prototype={_set:function(a){this.name=a.name,this.abbrs=a.abbrs,this.untils=a.untils,this.offsets=a.offsets,this.population=a.population},_index:function(a){var i,e=+a,r=this.untils;for(i=0;ir&&X.moveInvalidForward&&(i=r),A0&&(this._z=null),R.apply(this,arguments)}),a.tz.setDefault=function(i){return(M<2||2===M&&p<9)&&L("Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js "+a.version+"."),a.defaultZone=i?g(i):null,a};var k=a.momentProperties;return"[object Array]"===Object.prototype.toString.call(k)?(k.push("_z"),k.push("_a")):k&&(k._z=null),a}))},548:function(a,i,e){!function(i,r){"use strict";a.exports?a.exports=r(e(549)):"function"==typeof define&&define.amd?define(["moment"],r):r(i.moment)}(this,(function(a){"use strict";if(!a.tz)throw new Error("moment-timezone-utils.js must be loaded after moment-timezone.js");var i="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX";function e(a,e){for(var r="",o=Math.abs(a),A=Math.floor(o),c=function(a,e){for(var r,o=".",A="";e>0;)e-=1,a*=60,r=Math.floor(a+1e-6),o+=i[r],a-=r,r&&(A+=o,o="");return A}(o-A,Math.min(~~e,10));A>0;)r=i[A%60]+r,A=Math.floor(A/60);return a<0&&(r="-"+r),r&&c?r+c:(c||"-"!==r)&&(r||c)||"0"}function r(a){var i,r=[],o=0;for(i=0;in.population||c.population===n.population&&r&&r[c.name]?M.unshift(c):M.push(c),b=!0);b||t.push([c])}for(o=0;oe&&(o=i,i=e,e=o),o=0;oe&&(c=Math.min(c,o+1)));return[A,c]}(a.untils,i,e),A=r.apply(a.untils,o);return A[A.length-1]=null,{name:a.name,abbrs:r.apply(a.abbrs,o),untils:A,offsets:r.apply(a.offsets,o),population:a.population,countries:a.countries}}return a.tz.pack=c,a.tz.packBase60=e,a.tz.createLinks=b,a.tz.filterYears=t,a.tz.filterLinkPack=function(a,i,e,r){var o,A,M=a.zones,p=[];for(o=0;o.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__title{grid-area:title}.woocommerce-activity-card__header .woocommerce-activity-card__date{display:block;grid-area:date;-ms-grid-column-align:end;justify-self:end;margin-bottom:0}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{grid-area:subtitle}}@media (min-width:783px){.woocommerce-activity-card__header .woocommerce-activity-card__title{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__date{-ms-grid-row:1;-ms-grid-row-span:2;-ms-grid-column:2}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{-ms-grid-row:2;-ms-grid-column:1}}.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:2;grid-area:body}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:1}.woocommerce-activity-card__body>p:first-child{margin-top:0}.woocommerce-activity-card__body>p:last-child{margin-bottom:0}.woocommerce-empty-activity-card .woocommerce-activity-card__body{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:2;grid-area:actions;margin-top:16px}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:1}.woocommerce-activity-card__actions>*+*{margin-left:.5em}.woocommerce-activity-card.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-activity-card.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-activity-card.is-loading .is-placeholder{animation:none}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__title{width:80%}.woocommerce-activity-card.is-loading .woocommerce-activity-card__subtitle{margin-top:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{width:100%;margin-bottom:16px}@media (min-width:783px){.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{text-align:right;margin-bottom:0}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date .is-placeholder{width:68px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon{margin-right:24px;margin-right:var(--main-gap)}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon .is-placeholder{height:48px;width:48px}.woocommerce-activity-card.is-loading.woocommerce-review-activity-card .woocommerce-activity-card__icon .is-placeholder,.woocommerce-activity-card.is-loading.woocommerce-stock-activity-card .woocommerce-activity-card__icon .is-placeholder{height:60px;width:60px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder{width:100%;margin-bottom:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder:last-of-type{width:65%;margin-bottom:0}.woocommerce-activity-card.is-loading .woocommerce-activity-card__actions .is-placeholder{width:91px;height:34px}.woocommerce-activity-card.woocommerce-order-activity-card{-ms-grid-columns:1fr;grid-template-columns:1fr;grid-template-areas:"header" "body" "actions"}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__icon{display:none}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-flag{display:inline-block}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__subtitle span+span:before{content:" \2022\ "}.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:72px 1fr;grid-template-columns:72px 1fr;height:100%;opacity:1;padding:24px;padding:var(--main-gap)}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card{transition:opacity .3s,height 0s,padding 0s}}@media (max-width:782px){.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:64px 1fr;grid-template-columns:64px 1fr}}.woocommerce-activity-card.woocommerce-inbox-activity-card .woocommerce-activity-card__header{margin-bottom:12px}.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{height:0;opacity:0;padding:0}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{transition:opacity .3s,height 0s .3s,padding 0s .3s}}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:first-child{margin-top:0}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:last-child{margin-bottom:0}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified{margin-left:12px;display:inline-flex;position:relative;top:4px;color:#4ab866;font-size:12px;font-size:.75rem}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified .gridicon{margin-right:4px;fill:#4ab866}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{position:relative}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay img.woocommerce-gravatar{border:2px solid #fff;left:0;position:absolute;top:-6px;z-index:2}@media (max-width:782px){.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{margin-top:4px}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay__product .woocommerce-gravatar{margin-left:0;width:18px;height:18px;left:32px;top:-28px;z-index:1}}.woocommerce-review-activity-card__image-overlay__product,.woocommerce-stock-activity-card__image-overlay__product{height:60px;position:relative;width:60px}.woocommerce-review-activity-card__image-overlay__product.is-placeholder:before,.woocommerce-stock-activity-card__image-overlay__product.is-placeholder:before{background-color:#757575;border-radius:50%;content:"";position:absolute;left:0;right:0;bottom:0;top:0;opacity:.1}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-stock-activity-card{transition:opacity .3s}}.woocommerce-stock-activity-card.is-dimmed{opacity:.7}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__stock-quantity{background:#f0f0f0;color:#757575;padding:3px 8px;border-radius:3px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity{display:inline-flex;width:50px;margin-right:10px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input{border-radius:4px;height:36px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]{-moz-appearance:textfield}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-inner-spin-button,.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.woocommerce-stock-activity-card .components-button{min-height:34px;padding:2px 10px;line-height:26px}.woocommerce-stock-activity-card .woocommerce-activity-card__title{font-size:15px;font-size:.9375rem}.woocommerce-stock-activity-card .woocommerce-activity-card__subtitle{color:#757575;font-size:12px;font-size:.75rem}.woocommerce-empty-activity-card{background:#f0f0f0;margin:20px;border-bottom:unset}.woocommerce-inbox-message{position:relative;color:#757575;background:#f0f0f0;border-radius:2px;font-size:13px;font-size:.8125rem;margin:0 0 24px;-ms-box-orient:horizontal}.woocommerce-inbox-message.banner{flex-direction:column}.woocommerce-inbox-message.banner img{width:100%;height:120px}.woocommerce-inbox-message.thumbnail{display:flex;flex-direction:row-reverse}.woocommerce-inbox-message.thumbnail img{width:128px;height:100%}.woocommerce-homepage-column .woocommerce-inbox-message{margin:20px 0}.woocommerce-inbox-message:not(.is-placeholder){border:1px solid #e0e0e0}.woocommerce-inbox-message.message-is-unread{background:#fff}.woocommerce-inbox-message .line{width:100%}.woocommerce-inbox-message .third-line{width:33%}.woocommerce-inbox-message .fifth-line{width:20%}.woocommerce-inbox-message .sixth-line{width:16%}.woocommerce-inbox-message__content .woocommerce-inbox-message__title{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:1.5;font-weight:400;margin:8px 0}.message-is-unread .woocommerce-inbox-message__content .woocommerce-inbox-message__title{font-weight:700}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title{margin-bottom:10px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;margin:5px 0}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div{animation:none}}.woocommerce-inbox-message__content .woocommerce-inbox-message__date{color:#757575;font-size:12px;font-size:.75rem;margin-bottom:16px;font-style:normal;font-weight:400;line-height:16px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date{margin-bottom:10px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div{animation:none}}.woocommerce-inbox-message__text{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-inbox-message__text>p:first-child{margin-top:0}.woocommerce-inbox-message__text>p:last-child{margin-bottom:0}.is-placeholder .woocommerce-inbox-message__text>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;margin:5px 0}.is-placeholder .woocommerce-inbox-message__text>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__text>div{animation:none}}.woocommerce-inbox-message__actions{padding-top:16px;border-top:1px solid #e0e0e0}.woocommerce-inbox-message__actions>*+*{margin-left:.5em}.woocommerce-inbox-message__actions a,.woocommerce-inbox-message__actions button{cursor:pointer}.woocommerce-inbox-message__actions .components-dropdown{display:inline}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content{min-width:195px}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content ul{text-align:center}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content li{margin:0;cursor:pointer}.is-placeholder .woocommerce-inbox-message__actions>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;float:left;height:28px;margin-right:8px}.is-placeholder .woocommerce-inbox-message__actions>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__actions>div{animation:none}}.woocommerce-inbox-dismiss-confirmation_modal{text-align:left}.woocommerce-inbox-dismiss-confirmation_wrapper p{font-size:16px;color:#757575}.woocommerce-inbox-dismiss-confirmation_wrapper .woocommerce-inbox-dismiss-confirmation_buttons{text-align:right}.woocommerce-inbox-dismiss-confirmation_wrapper .woocommerce-inbox-dismiss-confirmation_buttons button{margin-left:10px}.woocommerce-inbox-message__wrapper>div{padding:16px 24px}.is-placeholder .woocommerce-inbox-message__wrapper>div{padding:10px 24px;display:flow-root}.is-placeholder .woocommerce-inbox-message__image .banner-block{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;width:100%;height:120px}.is-placeholder .woocommerce-inbox-message__image .banner-block:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__image .banner-block{animation:none}}#activity-panel-inbox{margin:0 24px}.woocommerce-layout__inbox-panel-header{padding:24px}.woocommerce-homepage-column .woocommerce-layout__inbox-panel-header{padding:0 24px}@media (-ms-high-contrast:active),(-ms-high-contrast:none){.woocommerce-admin-dismiss-dropdown{margin-top:0}.is-placeholder .woocommerce-inbox-message__wrapper{padding-bottom:10px}}.woocommerce-inbox-message-enter{opacity:0;max-height:0;transform:translateX(50%)}.woocommerce-inbox-message-enter-active{transition:opacity .5s,transform .5s,max-height .5s}.woocommerce-inbox-message-enter-active,.woocommerce-inbox-message-exit{opacity:1;max-height:100vh;transform:translateX(0)}.woocommerce-inbox-message-exit-active{opacity:0;max-height:0;transform:translateX(50%);transition:opacity .5s,transform .5s,max-height .5s}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-layout__activity-panel-header{height:50px;background:#e0e0e0;padding:16px;display:flex;justify-content:space-between;align-items:center}@media (min-width:783px){.woocommerce-layout__activity-panel-header{padding:16px 24px}}.woocommerce-layout__activity-panel-header h3{font-size:13px;font-weight:600;line-height:16px;margin:0;padding:0}.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):focus,.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):hover{box-shadow:none;border-radius:10px;background:#ccc}.woocommerce-layout__inbox-title{color:#1e1e1e;display:flex;align-items:center}.woocommerce-layout__inbox-subtitle{color:#757575}.woocommerce-layout__inbox-badge{margin-left:6px;background-color:#757575;border-radius:13px;padding:0 6px;color:#fff;display:inline-block;text-align:center;vertical-align:top} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/11.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/11.style.rtl.css new file mode 100644 index 0000000..5243a2f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/11.style.rtl.css @@ -0,0 +1 @@ +.woocommerce-activity-card{position:relative;padding:24px;padding:var(--main-gap);background:#fff;border-bottom:1px solid #e0e0e0;color:#757575;font-size:13px;font-size:.8125rem}.woocommerce-activity-card:not(.woocommerce-empty-activity-card){display:-ms-grid;display:grid;-ms-grid-columns:84px 1fr;grid-template-columns:84px 1fr;grid-template-areas:"icon header" "icon body" "icon actions"}@media (max-width:782px){.woocommerce-activity-card:not(.woocommerce-empty-activity-card){-ms-grid-columns:76px 1fr;grid-template-columns:76px 1fr}}.woocommerce-activity-card__button{display:block;height:unset;background:none;align-items:unset;transition:unset;text-align:right;width:100%;padding:0}.woocommerce-activity-card__unread{position:absolute;top:18px;top:calc(var(--main-gap) - 6px);left:18px;left:calc(var(--main-gap) - 6px);width:6px;height:6px;border-radius:50%;background:#ca4a1f}.woocommerce-activity-card__icon{-ms-grid-row:1;-ms-grid-row-span:3;-ms-grid-column:1;grid-area:icon;fill:#e0e0e0}.woocommerce-activity-card__header{margin-bottom:16px;display:flex;flex-direction:column}.woocommerce-activity-card__header .woocommerce-activity-card__title{margin:0;font-size:13px;font-size:.8125rem;order:2}.woocommerce-empty-activity-card .woocommerce-activity-card__header .woocommerce-activity-card__title{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:24px;font-weight:400}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__title{margin-bottom:8px}.woocommerce-activity-card__header .woocommerce-activity-card__date{color:#757575;text-transform:uppercase;font-size:11px;font-size:.6875rem;margin-bottom:12px;order:1}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{order:3}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__subtitle{margin-bottom:4px}@media (min-width:783px){.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:2;grid-area:header;display:-ms-grid;display:grid;-ms-grid-rows:auto auto;-ms-grid-columns:1fr auto;grid-template:"title date" "subtitle date"/1fr auto}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__title{grid-area:title}.woocommerce-activity-card__header .woocommerce-activity-card__date{display:block;grid-area:date;-ms-grid-column-align:end;justify-self:end;margin-bottom:0}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{grid-area:subtitle}}@media (min-width:783px){.woocommerce-activity-card__header .woocommerce-activity-card__title{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__date{-ms-grid-row:1;-ms-grid-row-span:2;-ms-grid-column:2}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{-ms-grid-row:2;-ms-grid-column:1}}.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:2;grid-area:body}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:1}.woocommerce-activity-card__body>p:first-child{margin-top:0}.woocommerce-activity-card__body>p:last-child{margin-bottom:0}.woocommerce-empty-activity-card .woocommerce-activity-card__body{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:2;grid-area:actions;margin-top:16px}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:1}.woocommerce-activity-card__actions>*+*{margin-right:.5em}.woocommerce-activity-card.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-activity-card.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-activity-card.is-loading .is-placeholder{animation:none}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__title{width:80%}.woocommerce-activity-card.is-loading .woocommerce-activity-card__subtitle{margin-top:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{width:100%;margin-bottom:16px}@media (min-width:783px){.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{text-align:left;margin-bottom:0}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date .is-placeholder{width:68px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon{margin-left:24px;margin-left:var(--main-gap)}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon .is-placeholder{height:48px;width:48px}.woocommerce-activity-card.is-loading.woocommerce-review-activity-card .woocommerce-activity-card__icon .is-placeholder,.woocommerce-activity-card.is-loading.woocommerce-stock-activity-card .woocommerce-activity-card__icon .is-placeholder{height:60px;width:60px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder{width:100%;margin-bottom:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder:last-of-type{width:65%;margin-bottom:0}.woocommerce-activity-card.is-loading .woocommerce-activity-card__actions .is-placeholder{width:91px;height:34px}.woocommerce-activity-card.woocommerce-order-activity-card{-ms-grid-columns:1fr;grid-template-columns:1fr;grid-template-areas:"header" "body" "actions"}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__icon{display:none}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-flag{display:inline-block}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__subtitle span+span:before{content:" \2022\ "}.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:72px 1fr;grid-template-columns:72px 1fr;height:100%;opacity:1;padding:24px;padding:var(--main-gap)}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card{transition:opacity .3s,height 0s,padding 0s}}@media (max-width:782px){.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:64px 1fr;grid-template-columns:64px 1fr}}.woocommerce-activity-card.woocommerce-inbox-activity-card .woocommerce-activity-card__header{margin-bottom:12px}.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{height:0;opacity:0;padding:0}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{transition:opacity .3s,height 0s .3s,padding 0s .3s}}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:first-child{margin-top:0}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:last-child{margin-bottom:0}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified{margin-right:12px;display:inline-flex;position:relative;top:4px;color:#4ab866;font-size:12px;font-size:.75rem}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified .gridicon{margin-left:4px;fill:#4ab866}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{position:relative}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay img.woocommerce-gravatar{border:2px solid #fff;right:0;position:absolute;top:-6px;z-index:2}@media (max-width:782px){.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{margin-top:4px}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay__product .woocommerce-gravatar{margin-right:0;width:18px;height:18px;right:32px;top:-28px;z-index:1}}.woocommerce-review-activity-card__image-overlay__product,.woocommerce-stock-activity-card__image-overlay__product{height:60px;position:relative;width:60px}.woocommerce-review-activity-card__image-overlay__product.is-placeholder:before,.woocommerce-stock-activity-card__image-overlay__product.is-placeholder:before{background-color:#757575;border-radius:50%;content:"";position:absolute;right:0;left:0;bottom:0;top:0;opacity:.1}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-stock-activity-card{transition:opacity .3s}}.woocommerce-stock-activity-card.is-dimmed{opacity:.7}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__stock-quantity{background:#f0f0f0;color:#757575;padding:3px 8px;border-radius:3px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity{display:inline-flex;width:50px;margin-left:10px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input{border-radius:4px;height:36px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]{-moz-appearance:textfield}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-inner-spin-button,.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.woocommerce-stock-activity-card .components-button{min-height:34px;padding:2px 10px;line-height:26px}.woocommerce-stock-activity-card .woocommerce-activity-card__title{font-size:15px;font-size:.9375rem}.woocommerce-stock-activity-card .woocommerce-activity-card__subtitle{color:#757575;font-size:12px;font-size:.75rem}.woocommerce-empty-activity-card{background:#f0f0f0;margin:20px;border-bottom:unset}.woocommerce-inbox-message{position:relative;color:#757575;background:#f0f0f0;border-radius:2px;font-size:13px;font-size:.8125rem;margin:0 0 24px;-ms-box-orient:horizontal}.woocommerce-inbox-message.banner{flex-direction:column}.woocommerce-inbox-message.banner img{width:100%;height:120px}.woocommerce-inbox-message.thumbnail{display:flex;flex-direction:row-reverse}.woocommerce-inbox-message.thumbnail img{width:128px;height:100%}.woocommerce-homepage-column .woocommerce-inbox-message{margin:20px 0}.woocommerce-inbox-message:not(.is-placeholder){border:1px solid #e0e0e0}.woocommerce-inbox-message.message-is-unread{background:#fff}.woocommerce-inbox-message .line{width:100%}.woocommerce-inbox-message .third-line{width:33%}.woocommerce-inbox-message .fifth-line{width:20%}.woocommerce-inbox-message .sixth-line{width:16%}.woocommerce-inbox-message__content .woocommerce-inbox-message__title{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:1.5;font-weight:400;margin:8px 0}.message-is-unread .woocommerce-inbox-message__content .woocommerce-inbox-message__title{font-weight:700}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title{margin-bottom:10px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;margin:5px 0}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div{animation:none}}.woocommerce-inbox-message__content .woocommerce-inbox-message__date{color:#757575;font-size:12px;font-size:.75rem;margin-bottom:16px;font-style:normal;font-weight:400;line-height:16px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date{margin-bottom:10px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div{animation:none}}.woocommerce-inbox-message__text{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-inbox-message__text>p:first-child{margin-top:0}.woocommerce-inbox-message__text>p:last-child{margin-bottom:0}.is-placeholder .woocommerce-inbox-message__text>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;margin:5px 0}.is-placeholder .woocommerce-inbox-message__text>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__text>div{animation:none}}.woocommerce-inbox-message__actions{padding-top:16px;border-top:1px solid #e0e0e0}.woocommerce-inbox-message__actions>*+*{margin-right:.5em}.woocommerce-inbox-message__actions a,.woocommerce-inbox-message__actions button{cursor:pointer}.woocommerce-inbox-message__actions .components-dropdown{display:inline}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content{min-width:195px}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content ul{text-align:center}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content li{margin:0;cursor:pointer}.is-placeholder .woocommerce-inbox-message__actions>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;float:right;height:28px;margin-left:8px}.is-placeholder .woocommerce-inbox-message__actions>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__actions>div{animation:none}}.woocommerce-inbox-dismiss-confirmation_modal{text-align:right}.woocommerce-inbox-dismiss-confirmation_wrapper p{font-size:16px;color:#757575}.woocommerce-inbox-dismiss-confirmation_wrapper .woocommerce-inbox-dismiss-confirmation_buttons{text-align:left}.woocommerce-inbox-dismiss-confirmation_wrapper .woocommerce-inbox-dismiss-confirmation_buttons button{margin-right:10px}.woocommerce-inbox-message__wrapper>div{padding:16px 24px}.is-placeholder .woocommerce-inbox-message__wrapper>div{padding:10px 24px;display:flow-root}.is-placeholder .woocommerce-inbox-message__image .banner-block{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;width:100%;height:120px}.is-placeholder .woocommerce-inbox-message__image .banner-block:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__image .banner-block{animation:none}}#activity-panel-inbox{margin:0 24px}.woocommerce-layout__inbox-panel-header{padding:24px}.woocommerce-homepage-column .woocommerce-layout__inbox-panel-header{padding:0 24px}@media (-ms-high-contrast:active),(-ms-high-contrast:none){.woocommerce-admin-dismiss-dropdown{margin-top:0}.is-placeholder .woocommerce-inbox-message__wrapper{padding-bottom:10px}}.woocommerce-inbox-message-enter{opacity:0;max-height:0;transform:translateX(-50%)}.woocommerce-inbox-message-enter-active{transition:opacity .5s,transform .5s,max-height .5s}.woocommerce-inbox-message-enter-active,.woocommerce-inbox-message-exit{opacity:1;max-height:100vh;transform:translateX(0)}.woocommerce-inbox-message-exit-active{opacity:0;max-height:0;transform:translateX(-50%);transition:opacity .5s,transform .5s,max-height .5s}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-layout__activity-panel-header{height:50px;background:#e0e0e0;padding:16px;display:flex;justify-content:space-between;align-items:center}@media (min-width:783px){.woocommerce-layout__activity-panel-header{padding:16px 24px}}.woocommerce-layout__activity-panel-header h3{font-size:13px;font-weight:600;line-height:16px;margin:0;padding:0}.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):focus,.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):hover{box-shadow:none;border-radius:10px;background:#ccc}.woocommerce-layout__inbox-title{color:#1e1e1e;display:flex;align-items:center}.woocommerce-layout__inbox-subtitle{color:#757575}.woocommerce-layout__inbox-badge{margin-right:6px;background-color:#757575;border-radius:13px;padding:0 6px;color:#fff;display:inline-block;text-align:center;vertical-align:top} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/12.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/12.style.css new file mode 100644 index 0000000..cd53417 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/12.style.css @@ -0,0 +1 @@ +.woocommerce-activity-card{position:relative;padding:24px;padding:var(--main-gap);background:#fff;border-bottom:1px solid #e0e0e0;color:#757575;font-size:13px;font-size:.8125rem}.woocommerce-activity-card:not(.woocommerce-empty-activity-card){display:-ms-grid;display:grid;-ms-grid-columns:84px 1fr;grid-template-columns:84px 1fr;grid-template-areas:"icon header" "icon body" "icon actions"}@media (max-width:782px){.woocommerce-activity-card:not(.woocommerce-empty-activity-card){-ms-grid-columns:76px 1fr;grid-template-columns:76px 1fr}}.woocommerce-activity-card__button{display:block;height:unset;background:none;align-items:unset;transition:unset;text-align:left;width:100%;padding:0}.woocommerce-activity-card__unread{position:absolute;top:18px;top:calc(var(--main-gap) - 6px);right:18px;right:calc(var(--main-gap) - 6px);width:6px;height:6px;border-radius:50%;background:#ca4a1f}.woocommerce-activity-card__icon{-ms-grid-row:1;-ms-grid-row-span:3;-ms-grid-column:1;grid-area:icon;fill:#e0e0e0}.woocommerce-activity-card__header{margin-bottom:16px;display:flex;flex-direction:column}.woocommerce-activity-card__header .woocommerce-activity-card__title{margin:0;font-size:13px;font-size:.8125rem;order:2}.woocommerce-empty-activity-card .woocommerce-activity-card__header .woocommerce-activity-card__title{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:24px;font-weight:400}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__title{margin-bottom:8px}.woocommerce-activity-card__header .woocommerce-activity-card__date{color:#757575;text-transform:uppercase;font-size:11px;font-size:.6875rem;margin-bottom:12px;order:1}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{order:3}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__subtitle{margin-bottom:4px}@media (min-width:783px){.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:2;grid-area:header;display:-ms-grid;display:grid;-ms-grid-rows:auto auto;-ms-grid-columns:1fr auto;grid-template:"title date" "subtitle date"/1fr auto}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__title{grid-area:title}.woocommerce-activity-card__header .woocommerce-activity-card__date{display:block;grid-area:date;-ms-grid-column-align:end;justify-self:end;margin-bottom:0}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{grid-area:subtitle}}@media (min-width:783px){.woocommerce-activity-card__header .woocommerce-activity-card__title{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__date{-ms-grid-row:1;-ms-grid-row-span:2;-ms-grid-column:2}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{-ms-grid-row:2;-ms-grid-column:1}}.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:2;grid-area:body}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:1}.woocommerce-activity-card__body>p:first-child{margin-top:0}.woocommerce-activity-card__body>p:last-child{margin-bottom:0}.woocommerce-empty-activity-card .woocommerce-activity-card__body{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:2;grid-area:actions;margin-top:16px}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:1}.woocommerce-activity-card__actions>*+*{margin-left:.5em}.woocommerce-activity-card.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-activity-card.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-activity-card.is-loading .is-placeholder{animation:none}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__title{width:80%}.woocommerce-activity-card.is-loading .woocommerce-activity-card__subtitle{margin-top:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{width:100%;margin-bottom:16px}@media (min-width:783px){.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{text-align:right;margin-bottom:0}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date .is-placeholder{width:68px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon{margin-right:24px;margin-right:var(--main-gap)}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon .is-placeholder{height:48px;width:48px}.woocommerce-activity-card.is-loading.woocommerce-review-activity-card .woocommerce-activity-card__icon .is-placeholder,.woocommerce-activity-card.is-loading.woocommerce-stock-activity-card .woocommerce-activity-card__icon .is-placeholder{height:60px;width:60px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder{width:100%;margin-bottom:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder:last-of-type{width:65%;margin-bottom:0}.woocommerce-activity-card.is-loading .woocommerce-activity-card__actions .is-placeholder{width:91px;height:34px}.woocommerce-activity-card.woocommerce-order-activity-card{-ms-grid-columns:1fr;grid-template-columns:1fr;grid-template-areas:"header" "body" "actions"}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__icon{display:none}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-flag{display:inline-block}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__subtitle span+span:before{content:" \2022\ "}.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:72px 1fr;grid-template-columns:72px 1fr;height:100%;opacity:1;padding:24px;padding:var(--main-gap)}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card{transition:opacity .3s,height 0s,padding 0s}}@media (max-width:782px){.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:64px 1fr;grid-template-columns:64px 1fr}}.woocommerce-activity-card.woocommerce-inbox-activity-card .woocommerce-activity-card__header{margin-bottom:12px}.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{height:0;opacity:0;padding:0}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{transition:opacity .3s,height 0s .3s,padding 0s .3s}}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:first-child{margin-top:0}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:last-child{margin-bottom:0}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified{margin-left:12px;display:inline-flex;position:relative;top:4px;color:#4ab866;font-size:12px;font-size:.75rem}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified .gridicon{margin-right:4px;fill:#4ab866}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{position:relative}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay img.woocommerce-gravatar{border:2px solid #fff;left:0;position:absolute;top:-6px;z-index:2}@media (max-width:782px){.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{margin-top:4px}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay__product .woocommerce-gravatar{margin-left:0;width:18px;height:18px;left:32px;top:-28px;z-index:1}}.woocommerce-review-activity-card__image-overlay__product,.woocommerce-stock-activity-card__image-overlay__product{height:60px;position:relative;width:60px}.woocommerce-review-activity-card__image-overlay__product.is-placeholder:before,.woocommerce-stock-activity-card__image-overlay__product.is-placeholder:before{background-color:#757575;border-radius:50%;content:"";position:absolute;left:0;right:0;bottom:0;top:0;opacity:.1}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-stock-activity-card{transition:opacity .3s}}.woocommerce-stock-activity-card.is-dimmed{opacity:.7}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__stock-quantity{background:#f0f0f0;color:#757575;padding:3px 8px;border-radius:3px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity{display:inline-flex;width:50px;margin-right:10px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input{border-radius:4px;height:36px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]{-moz-appearance:textfield}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-inner-spin-button,.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.woocommerce-stock-activity-card .components-button{min-height:34px;padding:2px 10px;line-height:26px}.woocommerce-stock-activity-card .woocommerce-activity-card__title{font-size:15px;font-size:.9375rem}.woocommerce-stock-activity-card .woocommerce-activity-card__subtitle{color:#757575;font-size:12px;font-size:.75rem}.woocommerce-empty-activity-card{background:#f0f0f0;margin:20px;border-bottom:unset}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-layout__activity-panel-header{height:50px;background:#e0e0e0;padding:16px;display:flex;justify-content:space-between;align-items:center}@media (min-width:783px){.woocommerce-layout__activity-panel-header{padding:16px 24px}}.woocommerce-layout__activity-panel-header h3{font-size:13px;font-weight:600;line-height:16px;margin:0;padding:0}.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):focus,.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):hover{box-shadow:none;border-radius:10px;background:#ccc}.woocommerce-layout__inbox-title{color:#1e1e1e;display:flex;align-items:center}.woocommerce-layout__inbox-subtitle{color:#757575}.woocommerce-layout__inbox-badge{margin-left:6px;background-color:#757575;border-radius:13px;padding:0 6px;color:#fff;display:inline-block;text-align:center;vertical-align:top} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/12.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/12.style.rtl.css new file mode 100644 index 0000000..cf38b5b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/12.style.rtl.css @@ -0,0 +1 @@ +.woocommerce-activity-card{position:relative;padding:24px;padding:var(--main-gap);background:#fff;border-bottom:1px solid #e0e0e0;color:#757575;font-size:13px;font-size:.8125rem}.woocommerce-activity-card:not(.woocommerce-empty-activity-card){display:-ms-grid;display:grid;-ms-grid-columns:84px 1fr;grid-template-columns:84px 1fr;grid-template-areas:"icon header" "icon body" "icon actions"}@media (max-width:782px){.woocommerce-activity-card:not(.woocommerce-empty-activity-card){-ms-grid-columns:76px 1fr;grid-template-columns:76px 1fr}}.woocommerce-activity-card__button{display:block;height:unset;background:none;align-items:unset;transition:unset;text-align:right;width:100%;padding:0}.woocommerce-activity-card__unread{position:absolute;top:18px;top:calc(var(--main-gap) - 6px);left:18px;left:calc(var(--main-gap) - 6px);width:6px;height:6px;border-radius:50%;background:#ca4a1f}.woocommerce-activity-card__icon{-ms-grid-row:1;-ms-grid-row-span:3;-ms-grid-column:1;grid-area:icon;fill:#e0e0e0}.woocommerce-activity-card__header{margin-bottom:16px;display:flex;flex-direction:column}.woocommerce-activity-card__header .woocommerce-activity-card__title{margin:0;font-size:13px;font-size:.8125rem;order:2}.woocommerce-empty-activity-card .woocommerce-activity-card__header .woocommerce-activity-card__title{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:24px;font-weight:400}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__title{margin-bottom:8px}.woocommerce-activity-card__header .woocommerce-activity-card__date{color:#757575;text-transform:uppercase;font-size:11px;font-size:.6875rem;margin-bottom:12px;order:1}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{order:3}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__subtitle{margin-bottom:4px}@media (min-width:783px){.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:2;grid-area:header;display:-ms-grid;display:grid;-ms-grid-rows:auto auto;-ms-grid-columns:1fr auto;grid-template:"title date" "subtitle date"/1fr auto}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__title{grid-area:title}.woocommerce-activity-card__header .woocommerce-activity-card__date{display:block;grid-area:date;-ms-grid-column-align:end;justify-self:end;margin-bottom:0}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{grid-area:subtitle}}@media (min-width:783px){.woocommerce-activity-card__header .woocommerce-activity-card__title{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__date{-ms-grid-row:1;-ms-grid-row-span:2;-ms-grid-column:2}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{-ms-grid-row:2;-ms-grid-column:1}}.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:2;grid-area:body}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:1}.woocommerce-activity-card__body>p:first-child{margin-top:0}.woocommerce-activity-card__body>p:last-child{margin-bottom:0}.woocommerce-empty-activity-card .woocommerce-activity-card__body{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:2;grid-area:actions;margin-top:16px}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:1}.woocommerce-activity-card__actions>*+*{margin-right:.5em}.woocommerce-activity-card.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-activity-card.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-activity-card.is-loading .is-placeholder{animation:none}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__title{width:80%}.woocommerce-activity-card.is-loading .woocommerce-activity-card__subtitle{margin-top:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{width:100%;margin-bottom:16px}@media (min-width:783px){.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{text-align:left;margin-bottom:0}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date .is-placeholder{width:68px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon{margin-left:24px;margin-left:var(--main-gap)}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon .is-placeholder{height:48px;width:48px}.woocommerce-activity-card.is-loading.woocommerce-review-activity-card .woocommerce-activity-card__icon .is-placeholder,.woocommerce-activity-card.is-loading.woocommerce-stock-activity-card .woocommerce-activity-card__icon .is-placeholder{height:60px;width:60px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder{width:100%;margin-bottom:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder:last-of-type{width:65%;margin-bottom:0}.woocommerce-activity-card.is-loading .woocommerce-activity-card__actions .is-placeholder{width:91px;height:34px}.woocommerce-activity-card.woocommerce-order-activity-card{-ms-grid-columns:1fr;grid-template-columns:1fr;grid-template-areas:"header" "body" "actions"}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__icon{display:none}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-flag{display:inline-block}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__subtitle span+span:before{content:" \2022\ "}.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:72px 1fr;grid-template-columns:72px 1fr;height:100%;opacity:1;padding:24px;padding:var(--main-gap)}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card{transition:opacity .3s,height 0s,padding 0s}}@media (max-width:782px){.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:64px 1fr;grid-template-columns:64px 1fr}}.woocommerce-activity-card.woocommerce-inbox-activity-card .woocommerce-activity-card__header{margin-bottom:12px}.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{height:0;opacity:0;padding:0}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{transition:opacity .3s,height 0s .3s,padding 0s .3s}}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:first-child{margin-top:0}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:last-child{margin-bottom:0}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified{margin-right:12px;display:inline-flex;position:relative;top:4px;color:#4ab866;font-size:12px;font-size:.75rem}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified .gridicon{margin-left:4px;fill:#4ab866}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{position:relative}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay img.woocommerce-gravatar{border:2px solid #fff;right:0;position:absolute;top:-6px;z-index:2}@media (max-width:782px){.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{margin-top:4px}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay__product .woocommerce-gravatar{margin-right:0;width:18px;height:18px;right:32px;top:-28px;z-index:1}}.woocommerce-review-activity-card__image-overlay__product,.woocommerce-stock-activity-card__image-overlay__product{height:60px;position:relative;width:60px}.woocommerce-review-activity-card__image-overlay__product.is-placeholder:before,.woocommerce-stock-activity-card__image-overlay__product.is-placeholder:before{background-color:#757575;border-radius:50%;content:"";position:absolute;right:0;left:0;bottom:0;top:0;opacity:.1}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-stock-activity-card{transition:opacity .3s}}.woocommerce-stock-activity-card.is-dimmed{opacity:.7}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__stock-quantity{background:#f0f0f0;color:#757575;padding:3px 8px;border-radius:3px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity{display:inline-flex;width:50px;margin-left:10px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input{border-radius:4px;height:36px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]{-moz-appearance:textfield}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-inner-spin-button,.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.woocommerce-stock-activity-card .components-button{min-height:34px;padding:2px 10px;line-height:26px}.woocommerce-stock-activity-card .woocommerce-activity-card__title{font-size:15px;font-size:.9375rem}.woocommerce-stock-activity-card .woocommerce-activity-card__subtitle{color:#757575;font-size:12px;font-size:.75rem}.woocommerce-empty-activity-card{background:#f0f0f0;margin:20px;border-bottom:unset}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-layout__activity-panel-header{height:50px;background:#e0e0e0;padding:16px;display:flex;justify-content:space-between;align-items:center}@media (min-width:783px){.woocommerce-layout__activity-panel-header{padding:16px 24px}}.woocommerce-layout__activity-panel-header h3{font-size:13px;font-weight:600;line-height:16px;margin:0;padding:0}.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):focus,.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):hover{box-shadow:none;border-radius:10px;background:#ccc}.woocommerce-layout__inbox-title{color:#1e1e1e;display:flex;align-items:center}.woocommerce-layout__inbox-subtitle{color:#757575}.woocommerce-layout__inbox-badge{margin-right:6px;background-color:#757575;border-radius:13px;padding:0 6px;color:#fff;display:inline-block;text-align:center;vertical-align:top} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/13.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/13.style.css new file mode 100644 index 0000000..a6291ee --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/13.style.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-analytics__table-placeholder .woocommerce-card__body{padding:0}.woocommerce-analytics__table-placeholder .woocommerce-table__table{margin-bottom:0}.woocommerce-analytics__table-placeholder .woocommerce-table__table tr:last-child{border-bottom-style:none}.woocommerce-analytics__card{border-radius:0;border:1px solid #ccc;box-shadow:none;margin-bottom:24px}.woocommerce-analytics__card:hover{box-shadow:none}@media (max-width:782px){.woocommerce-analytics__card{border-left:none;border-right:none;margin-left:-16px;margin-right:-16px}}.woocommerce-analytics__card>.woocommerce-card__header{padding:13px 16px;border-bottom:1px solid #ccc;border-radius:0}.woocommerce-analytics__card>.woocommerce-card__header>.woocommerce-card__title-wrapper>.woocommerce-card__title{padding:3px 0;font-size:15px;font-size:.9375rem;font-weight:600} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/13.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/13.style.rtl.css new file mode 100644 index 0000000..e8f19cf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/13.style.rtl.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-analytics__table-placeholder .woocommerce-card__body{padding:0}.woocommerce-analytics__table-placeholder .woocommerce-table__table{margin-bottom:0}.woocommerce-analytics__table-placeholder .woocommerce-table__table tr:last-child{border-bottom-style:none}.woocommerce-analytics__card{border-radius:0;border:1px solid #ccc;box-shadow:none;margin-bottom:24px}.woocommerce-analytics__card:hover{box-shadow:none}@media (max-width:782px){.woocommerce-analytics__card{border-right:none;border-left:none;margin-right:-16px;margin-left:-16px}}.woocommerce-analytics__card>.woocommerce-card__header{padding:13px 16px;border-bottom:1px solid #ccc;border-radius:0}.woocommerce-analytics__card>.woocommerce-card__header>.woocommerce-card__title-wrapper>.woocommerce-card__title{padding:3px 0;font-size:15px;font-size:.9375rem;font-weight:600} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/18.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/18.style.css new file mode 100644 index 0000000..7c6e64f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/18.style.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-orders-table__status{flex-direction:row-reverse}.woocommerce-orders-table__status .woocommerce-order-status__indicator{margin-right:0;margin-left:8px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/18.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/18.style.rtl.css new file mode 100644 index 0000000..cf53e37 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/18.style.rtl.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-orders-table__status{flex-direction:row-reverse}.woocommerce-orders-table__status .woocommerce-order-status__indicator{margin-left:0;margin-right:8px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/2.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/2.js new file mode 100644 index 0000000..a33f5b4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/2.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[2],{104:function(e,t,l){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=Object.assign||function(e){for(var t,l=1;l.components-base-control__field{margin-bottom:0}.woocommerce-settings-historical-data__skip-checkbox>.components-base-control__field>.components-checkbox-control__label{display:inline-block;margin-bottom:0;width:auto}.woocommerce-settings-historical-data__progress-label{display:inline-block;font-weight:700;margin-bottom:12px;margin-top:24px}.woocommerce-settings-historical-data__progress-label+.woocommerce-settings-historical-data__progress-label{margin-left:.25em}.woocommerce-settings-historical-data__progress-bar{-webkit-appearance:none;appearance:none;border:0;height:8px;width:100%;background-color:#c4c4c4}.woocommerce-settings-historical-data__progress-bar::-moz-progress-bar{background-color:#0085ba}.woocommerce-settings-historical-data__progress-bar::-webkit-progress-bar{background-color:#c4c4c4}.woocommerce-settings-historical-data__progress-bar::-webkit-progress-value{background-color:#0085ba}.woocommerce-settings-historical-data__status{display:block;font-weight:700;margin-top:24px}.woocommerce-settings-historical-data__status>.components-spinner{float:none;height:12px;margin-left:6px;margin-right:6px;width:12px}.woocommerce-settings-historical-data__status>.components-spinner:before{left:2px;height:3px;top:2px;transform-origin:4px 4px;width:3px}.woocommerce-settings-historical-data__actions{align-items:center;display:flex} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/24.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/24.style.rtl.css new file mode 100644 index 0000000..5c6af70 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/24.style.rtl.css @@ -0,0 +1 @@ +@media (min-width:783px){.woocommerce-settings__wrapper{padding:0 13px}}.woocommerce-settings__actions{margin-bottom:40px}@media (min-width:1281px){.woocommerce-settings__actions{margin-right:15%}}.woocommerce-settings__actions button{margin-left:16px}.woocommerce-setting{display:flex;margin-bottom:24px}@media (max-width:1280px){.woocommerce-setting{flex-direction:column}}.woocommerce-setting__label{font-size:16px;font-size:1rem;margin-bottom:16px;padding-left:16px;font-weight:700}@media (min-width:1281px){.woocommerce-setting__label{width:15%}}.woocommerce-setting__input{display:flex;flex-direction:column}@media (min-width:1281px){.woocommerce-setting__input{width:35%}.woocommerce-setting__input .woocommerce-filters-filter{width:100%}}.woocommerce-setting__input label{width:100%;display:block;margin-bottom:12px;color:#757575}.woocommerce-setting__input .woocommerce-filters-filter label{margin-bottom:0}.woocommerce-setting__input button:not(.components-tab-panel__tabs-item){margin-bottom:12px;align-self:flex-start}.woocommerce-setting__input .components-base-control__field{display:flex}.woocommerce-setting__input .woocommerce-filters-date__content-controls{padding-bottom:0}.woocommerce-setting__options-group-label{display:block;font-weight:700;margin-bottom:12px}.woocommerce-setting__help{font-style:italic;color:#757575}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-settings-historical-data__columns{display:-ms-grid;display:grid;grid-column-gap:24px;-ms-grid-columns:calc(50% - 12px) calc(50% - 12px);grid-template-columns:calc(50% - 12px) calc(50% - 12px)}.woocommerce-settings-historical-data__columns .woocommerce-settings-historical-data__column{-ms-grid-row-align:end;align-self:end;margin-top:12px}.woocommerce-settings-historical-data__columns .woocommerce-settings-historical-data__column:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-settings-historical-data__columns .woocommerce-settings-historical-data__column:nth-child(2){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}@media (max-width:960px){.woocommerce-settings-historical-data__columns{-ms-grid-columns:100%;grid-template-columns:100%}.woocommerce-settings-historical-data__columns .woocommerce-settings-historical-data__column:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-settings-historical-data__columns .woocommerce-settings-historical-data__column:nth-child(2){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}}.woocommerce-settings-historical-data__columns .components-base-control__label,.woocommerce-settings-historical-data__columns .woocommerce-settings-historical-data__column-label{margin-bottom:12px}.woocommerce-settings-historical-data__columns .components-select-control__input{height:38px;padding:8px 2px}.woocommerce-settings-historical-data__columns .components-base-control__field{margin-bottom:0}.woocommerce-settings-historical-data__skip-checkbox{margin-top:24px}.woocommerce-settings-historical-data__skip-checkbox>.components-base-control__field{margin-bottom:0}.woocommerce-settings-historical-data__skip-checkbox>.components-base-control__field>.components-checkbox-control__label{display:inline-block;margin-bottom:0;width:auto}.woocommerce-settings-historical-data__progress-label{display:inline-block;font-weight:700;margin-bottom:12px;margin-top:24px}.woocommerce-settings-historical-data__progress-label+.woocommerce-settings-historical-data__progress-label{margin-right:.25em}.woocommerce-settings-historical-data__progress-bar{-webkit-appearance:none;appearance:none;border:0;height:8px;width:100%;background-color:#c4c4c4}.woocommerce-settings-historical-data__progress-bar::-moz-progress-bar{background-color:#0085ba}.woocommerce-settings-historical-data__progress-bar::-webkit-progress-bar{background-color:#c4c4c4}.woocommerce-settings-historical-data__progress-bar::-webkit-progress-value{background-color:#0085ba}.woocommerce-settings-historical-data__status{display:block;font-weight:700;margin-top:24px}.woocommerce-settings-historical-data__status>.components-spinner{float:none;height:12px;margin-right:6px;margin-left:6px;width:12px}.woocommerce-settings-historical-data__status>.components-spinner:before{right:2px;height:3px;top:2px;transform-origin:4px 4px;width:3px}.woocommerce-settings-historical-data__actions{align-items:center;display:flex} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/3.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/3.js new file mode 100644 index 0000000..8f2c0d2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/3.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[3],{301:function(e,t,n){"use strict";var i=n(7),a=n(12),r=n(0),o=n(4),l=n.n(o),c=n(441);var s=Object(r.forwardRef)((function(e,t){var n=e.align,o=void 0===n?"center":n,s=e.className,b=e.gap,d=void 0===b?2:b,u=e.justify,p=void 0===u?"space-between":u,m=e.isReversed,f=void 0!==m&&m,g=Object(a.a)(e,["align","className","gap","justify","isReversed"]),h=l()("components-flex",s);return Object(r.createElement)(c.a,Object(i.a)({},g,{align:o,className:h,ref:t,gap:d,justify:p,isReversed:f}))}));t.a=s},441:function(e,t,n){"use strict";n.d(t,"a",(function(){return o})),n.d(t,"b",(function(){return l}));var i=n(41),a=n(67);var r={name:"8kj89b",styles:"flex-direction:row-reverse;"},o=Object(i.a)("div",{target:"eboqfv50",label:"Flex"})("box-sizing:border-box;display:flex;",(function(e){var t=e.align,n={top:"flex-start",bottom:"flex-end"}[t]||t;return Object(a.b)({alignItems:n},"")}),";",(function(e){var t=e.justify,n=e.isReversed,i={left:"flex-start",right:"flex-end"},r=i[t]||t;return n&&i[t]&&(r="left"===t?i.right:i.left),Object(a.b)({justifyContent:r},"")}),";",(function(e){var t=e.gap,n=e.isReversed,i="number"==typeof t?4*t:4,r="margin-".concat(n?"left":"right");return Object(a.b)("> *{",r,":",i,"px;&:last-child{",r,":0;}}")}),";",(function(e){return e.isReversed?r:""}),";"),l=Object(i.a)("div",{target:"eboqfv51",label:"Item"})({name:"13luw5d",styles:"box-sizing:border-box;min-width:0;max-width:100%;"})},545:function(e,t,n){"use strict";var i=n(7),a=n(12),r=n(0),o=n(4),l=n.n(o),c=n(441);t.a=Object(r.forwardRef)((function(e,t){var n=e.className,o=Object(a.a)(e,["className"]),s=l()("components-flex__item",n);return Object(r.createElement)(c.b,Object(i.a)({},o,{className:s,ref:t}))}))},851:function(e,t,n){"use strict";var i=n(7),a=n(27),r=n(26),o=n(12),l=n(0),c=n(2),s=n(4),b=n.n(s),d=n(300),u=n(575),p=n(88),m=Object(l.createElement)(p.c,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg"},Object(l.createElement)(p.b,{d:"M17.5 11.6L12 16l-5.5-4.4.9-1.2L12 14l4.5-3.6 1 1.2z"})),f=n(767),g=n(41),h=n(67),v=n(301),j=n(545),O=n(190),x=n(31),w=new RegExp(/-left/g),z=new RegExp(/-right/g),y=new RegExp(/Left/g),F=new RegExp(/Right/g);function k(){return!(!document||"rtl"!==document.documentElement.dir)}function E(e){return"left"===e?"right":"right"===e?"left":w.test(e)?e.replace(w,"-right"):z.test(e)?e.replace(z,"-left"):y.test(e)?e.replace(y,"Right"):F.test(e)?e.replace(F,"Left"):e}var _=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return Object(c.mapKeys)(e,(function(e,t){return E(t)}))};function N(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;return function(){var n=k();return t?n?Object(h.b)(t,""):Object(h.b)(e,""):n?Object(h.b)(_(e),""):Object(h.b)(e,"")}}var R={name:"1dacand",styles:"padding-top:0;"},L=function(){return R},C={name:"r6z5ec",styles:"z-index:1;"},H=function(e){return e.isFocused?C:""},V={name:"uz6002",styles:"align-items:flex-start;flex-direction:column;"},B={name:"53hdd7",styles:"align-items:flex-start;flex-direction:column-reverse;"},D=function(e){switch(e.labelPosition){case"top":return V;case"bottom":return B;default:return""}},P=Object(g.a)(v.a,{target:"e1cr7zh10",label:"Root"})("position:relative;border-radius:2px;",L,";",H,";",D,";"),S={name:"8atqhb",styles:"width:100%;"},I=Object(g.a)("div",{target:"e1cr7zh11",label:"Container"})("align-items:center;box-sizing:border-box;border-radius:inherit;display:flex;flex:1;position:relative;",(function(e){var t=e.disabled?Object(x.a)("ui.backgroundDisabled"):Object(x.a)("ui.background");return Object(h.b)({backgroundColor:t},"")}),";",(function(e){return"side"===e.labelPosition?"":S}),";"),q={name:"103r1kr",styles:"&::-webkit-input-placeholder{line-height:normal;}"},A=(Object(g.a)("input",{target:"e1cr7zh12",label:"Input"})("&&&{background-color:transparent;box-sizing:border-box;border:none;box-shadow:none !important;color:",Object(x.a)("black"),";display:block;margin:0;outline:none;padding-left:8px;padding-right:8px;width:100%;",(function(e){var t=e.isDragging,n=e.dragCursor,i="",a="";return t&&(i=Object(h.b)("cursor:",n,";user-select:none;&::-webkit-outer-spin-button,&::-webkit-inner-spin-button{-webkit-appearance:none !important;margin:0 !important;}")),t&&n&&(a=Object(h.b)("&:active{cursor:",n,";}")),Object(h.b)(i,";",a,";")}),";",(function(e){return e.disabled?Object(h.b)({color:Object(x.a)("ui.textDisabled")},""):""}),";",(function(e){var t={default:"13px",small:"11px"}[e.size];return t?Object(h.b)("font-size:","16px",";@media ( min-width:600px ){font-size:",t,";}"):""}),";",(function(e){var t={default:{height:30,lineHeight:1,minHeight:30},small:{height:24,lineHeight:1,minHeight:24}},n=t[e.size]||t.default;return Object(h.b)(n,"")}),";",(function(){return q}),";}"),{name:"8uhtka",styles:"overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"}),W=function(){return A},J=Object(g.a)(O.a,{target:"e1cr7zh13",label:"BaseLabel"})("&&&{box-sizing:border-box;color:currentColor;display:block;margin:0;max-width:100%;padding-bottom:4px;padding-top:0;z-index:1;",W,";}"),K=function(e){return Object(l.createElement)(J,Object(i.a)({},e,{as:"label"}))},M=Object(g.a)(j.a,{target:"e1cr7zh14",label:"LabelWrapper"})({name:"120o8im",styles:"max-width:calc( 100% - 10px );"}),U=Object(g.a)("div",{target:"e1cr7zh15",label:"BackdropUI"})("&&&{box-sizing:border-box;border-radius:inherit;bottom:0;left:0;margin:0;padding:0;pointer-events:none;position:absolute;right:0;top:0;",(function(e){var t=e.disabled,n=e.isFocused,i=n?Object(x.a)("ui.borderFocus"):Object(x.a)("ui.border"),a=null;return n&&(a="0 0 0 1px ".concat(Object(x.a)("ui.borderFocus")," inset")),t&&(i=Object(x.a)("ui.borderDisabled")),Object(h.b)({boxShadow:a,borderColor:i,borderStyle:"solid",borderWidth:1},"")}),";",N({paddingLeft:2}),"}"),G=Object(g.a)("span",{target:"e1cr7zh16",label:"Prefix"})({name:"1pxuk39",styles:"box-sizing:border-box;display:block;"}),Q=Object(g.a)("span",{target:"e1cr7zh17",label:"Suffix"})({name:"1pxuk39",styles:"box-sizing:border-box;display:block;"});var T=Object(l.memo)((function(e){var t=e.disabled,n=void 0!==t&&t,i=e.isFocused,a=void 0!==i&&i;return Object(l.createElement)(U,{"aria-hidden":"true",className:"components-input-control__backdrop",disabled:n,isFocused:a})})),X=n(439);function Y(e){var t=e.children,n=e.hideLabelFromVision,a=e.htmlFor,r=Object(o.a)(e,["children","hideLabelFromVision","htmlFor"]);return t?n?Object(l.createElement)(X.a,{as:"label",htmlFor:a},t):Object(l.createElement)(K,Object(i.a)({htmlFor:a},r),t):null}function Z(e,t){var n=e.children,a=e.className,r=e.disabled,c=void 0!==r&&r,s=e.hideLabelFromVision,b=void 0!==s&&s,u=e.id,p=e.isFocused,m=void 0!==p&&p,f=e.label,g=e.prefix,h=e.size,v=void 0===h?"default":h,j=e.suffix,O=Object(o.a)(e,["children","className","disabled","hideLabelFromVision","id","isFocused","label","prefix","size","suffix"]),x=function(e){var t=Object(d.a)(Z),n="input-base-control-".concat(t);return e||n}(u);return Object(l.createElement)(P,Object(i.a)({},O,{className:a,isFocused:m,ref:t}),Object(l.createElement)(M,null,Object(l.createElement)(Y,{className:"components-input-control__label",hideLabelFromVision:b,htmlFor:x,size:v},f)),Object(l.createElement)(I,{className:"components-input-control__container",disabled:c,isFocused:m},g&&Object(l.createElement)(G,{className:"components-input-control__prefix"},g),n,j&&Object(l.createElement)(Q,{className:"components-input-control__suffix"},j),Object(l.createElement)(T,{"aria-hidden":"true",disabled:c,isFocused:m,label:f,size:v})))}var $=Object(l.forwardRef)(Z),ee=Object(g.a)("select",{target:"e12x0a390",label:"Select"})("&&&{appearance:none;background:transparent;box-sizing:border-box;border:none;box-shadow:none !important;color:",Object(x.a)("black"),";display:block;margin:0;outline:none;width:100%;",(function(e){return e.disabled?Object(h.b)({color:Object(x.a)("ui.textDisabled")},""):""}),";",(function(e){var t={default:"13px",small:"11px"}[e.size];return t?Object(h.b)("font-size:","16px",";@media ( min-width:600px ){font-size:",t,";}"):""}),";",(function(e){var t={default:{height:30,lineHeight:1,minHeight:30},small:{height:24,lineHeight:1,minHeight:24}},n=t[e.size]||t.default;return Object(h.b)(n,"")}),";",N({paddingLeft:8,paddingRight:24})(),"}"),te=Object(g.a)("div",{target:"e12x0a391",label:"DownArrowWrapper"})("align-items:center;bottom:0;box-sizing:border-box;display:flex;padding:0 4px;pointer-events:none;position:absolute;top:0;",N({right:0})()," svg{display:block;}");function ne(e,t){var n=e.className,s=e.disabled,p=void 0!==s&&s,g=e.help,h=e.hideLabelFromVision,v=e.id,j=e.label,O=e.multiple,x=void 0!==O&&O,w=e.onBlur,z=void 0===w?c.noop:w,y=e.onChange,F=void 0===y?c.noop:y,k=e.onFocus,E=void 0===k?c.noop:k,_=e.options,N=void 0===_?[]:_,R=e.size,L=void 0===R?"default":R,C=e.value,H=e.labelPosition,V=void 0===H?"top":H,B=Object(o.a)(e,["className","disabled","help","hideLabelFromVision","id","label","multiple","onBlur","onChange","onFocus","options","size","value","labelPosition"]),D=Object(l.useState)(!1),P=Object(r.a)(D,2),S=P[0],I=P[1],q=function(e){var t=Object(d.a)(ne),n="inspector-select-control-".concat(t);return e||n}(v),A=g?"".concat(q,"__help"):void 0;if(Object(c.isEmpty)(N))return null;var W=b()("components-select-control",n);return Object(l.createElement)(f.a,{help:g},Object(l.createElement)($,{className:W,disabled:p,hideLabelFromVision:h,id:q,isFocused:S,label:j,size:L,suffix:Object(l.createElement)(te,null,Object(l.createElement)(u.a,{icon:m,size:18})),labelPosition:V},Object(l.createElement)(ee,Object(i.a)({},B,{"aria-describedby":A,className:"components-select-control__input",disabled:p,id:q,multiple:x,onBlur:function(e){z(e),I(!1)},onChange:function(e){if(x){var t=Object(a.a)(e.target.options).filter((function(e){return e.selected})).map((function(e){return e.value}));F(t)}else F(e.target.value,{event:e})},onFocus:function(e){E(e),I(!0)},ref:t,size:L,value:C}),N.map((function(e,t){var n=e.id||"".concat(e.label,"-").concat(e.value,"-").concat(t);return Object(l.createElement)("option",{key:n,value:e.value,disabled:e.disabled},e.label)})))))}var ie=Object(l.forwardRef)(ne);t.a=ie}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/31.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/31.style.css new file mode 100644 index 0000000..06db996 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/31.style.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}#klarna-kp-banner,.woocommerce-page:not(.woocommerce-embed-page) #klarna-banner{display:none}.woocommerce-dashboard__columns{display:-ms-grid;display:grid;-ms-grid-columns:calc(50% - 12px) calc(50% - 12px);grid-template-columns:calc(50% - 12px) calc(50% - 12px);grid-column-gap:24px}.woocommerce-dashboard__columns>div:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(2){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(3){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(4){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(5){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(6){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(7){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(8){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(9){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(10){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(11){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(12){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(13){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}.woocommerce-dashboard__columns>div:nth-child(14){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}@media (max-width:960px){.woocommerce-dashboard__columns{-ms-grid-columns:100%;grid-template-columns:100%}.woocommerce-dashboard__columns>div:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(2){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(3){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(4){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(5){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(6){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(7){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}.woocommerce-dashboard__columns>div:nth-child(8){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:8;grid-row-start:8;-ms-grid-row-span:1;grid-row-end:9}.woocommerce-dashboard__columns>div:nth-child(9){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:9;grid-row-start:9;-ms-grid-row-span:1;grid-row-end:10}.woocommerce-dashboard__columns>div:nth-child(10){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:10;grid-row-start:10;-ms-grid-row-span:1;grid-row-end:11}.woocommerce-dashboard__columns>div:nth-child(11){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:11;grid-row-start:11;-ms-grid-row-span:1;grid-row-end:12}.woocommerce-dashboard__columns>div:nth-child(12){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:12;grid-row-start:12;-ms-grid-row-span:1;grid-row-end:13}.woocommerce-dashboard__columns>div:nth-child(13){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:13;grid-row-start:13;-ms-grid-row-span:1;grid-row-end:14}.woocommerce-dashboard__columns>div:nth-child(14){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:14;grid-row-start:14;-ms-grid-row-span:1;grid-row-end:15}}.woocommerce-dashboard__widget{display:flex;align-items:center;text-align:center}.woocommerce-dashboard__widget-item{flex:1}.woocommerce-dashboard-section__add-more{margin:0 auto;width:84px;padding:0 24px 24px}.woocommerce-dashboard-section__add-more .components-popover__content{padding:0 16px 8px}.woocommerce-dashboard-section__add-more>button svg{fill:#757575}.woocommerce-dashboard-section__add-more-choices{display:flex;justify-content:center}.woocommerce-dashboard-section__add-more-btn{display:flex;flex-direction:column;align-items:center;padding:16px;margin:8px}.woocommerce-dashboard-section__add-more-btn.components-button{height:auto}.woocommerce-dashboard-section__add-more-btn .dashicons-arrow-right-alt{transform:rotate(-45deg)}.woocommerce-dashboard-section__add-more-btn-title{color:#757575;padding-top:8px}.woocommerce-dashboard-section-controls{border-top:1px solid #f0f0f0;padding-top:8px}.woocommerce-dashboard-section-controls .dashicon{margin:0 8px 0 0;vertical-align:bottom}.woocommerce-dashboard-section-controls .woocommerce-ellipsis-menu__item{padding-bottom:10px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-card__header.is-size-large{padding-bottom:12px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-card__header.is-size-large .woocommerce-card__menu{margin-top:8px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/31.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/31.style.rtl.css new file mode 100644 index 0000000..cfa1829 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/31.style.rtl.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}#klarna-kp-banner,.woocommerce-page:not(.woocommerce-embed-page) #klarna-banner{display:none}.woocommerce-dashboard__columns{display:-ms-grid;display:grid;-ms-grid-columns:calc(50% - 12px) calc(50% - 12px);grid-template-columns:calc(50% - 12px) calc(50% - 12px);grid-column-gap:24px}.woocommerce-dashboard__columns>div:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(2){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(3){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(4){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(5){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(6){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(7){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(8){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(9){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(10){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(11){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(12){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(13){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}.woocommerce-dashboard__columns>div:nth-child(14){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}@media (max-width:960px){.woocommerce-dashboard__columns{-ms-grid-columns:100%;grid-template-columns:100%}.woocommerce-dashboard__columns>div:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(2){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(3){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(4){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(5){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(6){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(7){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}.woocommerce-dashboard__columns>div:nth-child(8){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:8;grid-row-start:8;-ms-grid-row-span:1;grid-row-end:9}.woocommerce-dashboard__columns>div:nth-child(9){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:9;grid-row-start:9;-ms-grid-row-span:1;grid-row-end:10}.woocommerce-dashboard__columns>div:nth-child(10){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:10;grid-row-start:10;-ms-grid-row-span:1;grid-row-end:11}.woocommerce-dashboard__columns>div:nth-child(11){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:11;grid-row-start:11;-ms-grid-row-span:1;grid-row-end:12}.woocommerce-dashboard__columns>div:nth-child(12){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:12;grid-row-start:12;-ms-grid-row-span:1;grid-row-end:13}.woocommerce-dashboard__columns>div:nth-child(13){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:13;grid-row-start:13;-ms-grid-row-span:1;grid-row-end:14}.woocommerce-dashboard__columns>div:nth-child(14){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:14;grid-row-start:14;-ms-grid-row-span:1;grid-row-end:15}}.woocommerce-dashboard__widget{display:flex;align-items:center;text-align:center}.woocommerce-dashboard__widget-item{flex:1}.woocommerce-dashboard-section__add-more{margin:0 auto;width:84px;padding:0 24px 24px}.woocommerce-dashboard-section__add-more .components-popover__content{padding:0 16px 8px}.woocommerce-dashboard-section__add-more>button svg{fill:#757575}.woocommerce-dashboard-section__add-more-choices{display:flex;justify-content:center}.woocommerce-dashboard-section__add-more-btn{display:flex;flex-direction:column;align-items:center;padding:16px;margin:8px}.woocommerce-dashboard-section__add-more-btn.components-button{height:auto}.woocommerce-dashboard-section__add-more-btn .dashicons-arrow-right-alt{transform:rotate(45deg)}.woocommerce-dashboard-section__add-more-btn-title{color:#757575;padding-top:8px}.woocommerce-dashboard-section-controls{border-top:1px solid #f0f0f0;padding-top:8px}.woocommerce-dashboard-section-controls .dashicon{margin:0 0 0 8px;vertical-align:bottom}.woocommerce-dashboard-section-controls .woocommerce-ellipsis-menu__item{padding-bottom:10px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-card__header.is-size-large{padding-bottom:12px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-card__header.is-size-large .woocommerce-card__menu{margin-top:8px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/32.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/32.style.css new file mode 100644 index 0000000..e00059e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/32.style.css @@ -0,0 +1 @@ +.woocommerce-dashboard__chart-block-wrapper{cursor:pointer}.woocommerce-dashboard__chart-block-wrapper:hover .woocommerce-card__header,.woocommerce-dashboard__chart-block-wrapper:hover .woocommerce-chart{background:#f8f9f9}.woocommerce-dashboard__chart-block-wrapper:hover .woocommerce-legend__item button{background:transparent}.woocommerce-dashboard__chart-block-wrapper .woocommerce-chart__footer{position:relative}.woocommerce-dashboard__chart-block-wrapper .woocommerce-chart__footer:after{content:"";position:absolute;width:100%;height:100%;left:0;top:0;cursor:pointer;z-index:1}.woocommerce-dashboard__chart-block .woocommerce-card__body{padding:0;position:relative}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart{border:none;margin:0}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart .woocommerce-legend__item>button{cursor:default}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart .woocommerce-legend__item>button:hover{background:#f0f0f0}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart .woocommerce-legend__item>button .woocommerce-legend__item-container{cursor:default}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart .woocommerce-legend__item>button .woocommerce-legend__item-container .woocommerce-legend__item-checkmark.woocommerce-legend__item-checkmark-checked:after{display:none}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart:hover,.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart:hover .woocommerce-legend__item>button,.woocommerce-dashboard__chart-block:hover{background:#f0f0f0}.woocommerce-dashboard__chart-block .screen-reader-text:focus{clip:auto;-webkit-clip-path:none;clip-path:none;z-index:1;left:6px;top:7px;height:auto;width:auto;display:block;font-size:14px;font-size:.875rem;font-weight:600;padding:15px 23px 14px;background:#f1f1f1;color:#0073aa;text-decoration:none;box-shadow:0 0 2px 2px rgba(0,0,0,.6)}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-dashboard__dashboard-charts{border-bottom:0;border-right:0}.woocommerce-dashboard__dashboard-charts .woocommerce-section-header__actions{flex-grow:0}.woocommerce-dashboard__dashboard-charts .woocommerce-card__body{padding:0}.woocommerce-dashboard__dashboard-charts .woocommerce-summary{margin:0} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/32.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/32.style.rtl.css new file mode 100644 index 0000000..51a46d8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/32.style.rtl.css @@ -0,0 +1 @@ +.woocommerce-dashboard__chart-block-wrapper{cursor:pointer}.woocommerce-dashboard__chart-block-wrapper:hover .woocommerce-card__header,.woocommerce-dashboard__chart-block-wrapper:hover .woocommerce-chart{background:#f8f9f9}.woocommerce-dashboard__chart-block-wrapper:hover .woocommerce-legend__item button{background:transparent}.woocommerce-dashboard__chart-block-wrapper .woocommerce-chart__footer{position:relative}.woocommerce-dashboard__chart-block-wrapper .woocommerce-chart__footer:after{content:"";position:absolute;width:100%;height:100%;right:0;top:0;cursor:pointer;z-index:1}.woocommerce-dashboard__chart-block .woocommerce-card__body{padding:0;position:relative}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart{border:none;margin:0}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart .woocommerce-legend__item>button{cursor:default}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart .woocommerce-legend__item>button:hover{background:#f0f0f0}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart .woocommerce-legend__item>button .woocommerce-legend__item-container{cursor:default}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart .woocommerce-legend__item>button .woocommerce-legend__item-container .woocommerce-legend__item-checkmark.woocommerce-legend__item-checkmark-checked:after{display:none}.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart:hover,.woocommerce-dashboard__chart-block .woocommerce-card__body .woocommerce-chart:hover .woocommerce-legend__item>button,.woocommerce-dashboard__chart-block:hover{background:#f0f0f0}.woocommerce-dashboard__chart-block .screen-reader-text:focus{clip:auto;-webkit-clip-path:none;clip-path:none;z-index:1;right:6px;top:7px;height:auto;width:auto;display:block;font-size:14px;font-size:.875rem;font-weight:600;padding:15px 23px 14px;background:#f1f1f1;color:#0073aa;text-decoration:none;box-shadow:0 0 2px 2px rgba(0,0,0,.6)}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-dashboard__dashboard-charts{border-bottom:0;border-left:0}.woocommerce-dashboard__dashboard-charts .woocommerce-section-header__actions{flex-grow:0}.woocommerce-dashboard__dashboard-charts .woocommerce-card__body{padding:0}.woocommerce-dashboard__dashboard-charts .woocommerce-summary{margin:0} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/35.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/35.style.css new file mode 100644 index 0000000..68d55e5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/35.style.css @@ -0,0 +1 @@ +.woocommerce-stats-overview .woocommerce-card__body{padding:0}.woocommerce-stats-overview .woocommerce-summary{margin:0}.woocommerce-stats-overview__more-btn{display:inline-block;padding:16px}.woocommerce-stats-overview__tabs .components-tab-panel__tabs{display:flex;justify-content:space-between;border-bottom:1px solid #e0e0e0}.woocommerce-stats-overview__tabs .components-tab-panel__tabs .components-button{width:33.33%;padding-right:24px;padding-left:24px}.woocommerce-stats-overview__stats{margin:0}.woocommerce-stats-overview__stats .woocommerce-summary__item-container{width:50%;display:inline-block}.woocommerce-stats-overview__stats.is-even .woocommerce-summary__item-container:nth-last-of-type(2) .woocommerce-summary__item,.woocommerce-stats-overview__stats .woocommerce-summary__item-container:last-of-type .woocommerce-summary__item{border-bottom:none}.woocommerce-stats-overview__stats .woocommerce-summary__item-container:nth-of-type(2n) .woocommerce-summary__item{border-right:none}.woocommerce-stats-overview__stats .woocommerce-summary__item{background-color:#fff}.woocommerce-stats-overview__stats .woocommerce-summary__item:active,.woocommerce-stats-overview__stats .woocommerce-summary__item:hover{background-color:#f0f0f0}article.woocommerce-stats-overview__install-jetpack-promo .woocommerce-stats-overview__install-jetpack-promo__content{padding:16px 24px}article.woocommerce-stats-overview__install-jetpack-promo h2{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:1.5;font-weight:400;margin:8px 0}article.woocommerce-stats-overview__install-jetpack-promo p{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px;margin:8px 0}article.woocommerce-stats-overview__install-jetpack-promo footer{padding:16px 24px;border-top:1px solid #f0f0f0;border-bottom:1px solid #f0f0f0}article.woocommerce-stats-overview__install-jetpack-promo footer button{margin-left:8px}article.woocommerce-stats-overview__install-jetpack-promo footer button:first-child{margin-left:0}.woocommerce-task-dashboard__body .woocommerce-card__description{color:#646970}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .wooocommerce-task-card__header{display:flex}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .wooocommerce-task-card__header .woocommerce-badge{margin-left:16px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .woocommerce-list__item:not(.is-complete) .woocommerce-task__icon{border:1px solid #f0f0f0;background:#fff}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .woocommerce-list__item.is-complete .woocommerce-list__item-title{color:#757575}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .woocommerce-list__item-before .woocommerce-task__icon{border-radius:50%;width:32px;height:32px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .woocommerce-list__item-before svg{fill:#fff;position:relative;top:4px;left:5px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-popover__content{min-width:unset}.woocommerce-task-dashboard__body .woocommerce-task__additional-info,.woocommerce-task-dashboard__body .woocommerce-task__estimated-time{color:#757575;font-weight:400;font-size:12px}.woocommerce-task-dashboard__body .woocommerce-card.is-narrow{max-width:680px;margin-left:auto;margin-right:auto}.woocommerce-task-dashboard__body #wpbody-content{position:relative}.woocommerce-task-dashboard__body .components-modal__screen-overlay{background:rgba(43,45,47,.4)}.woocommerce-task-dashboard__body .components-modal__frame .components-modal__header{border-bottom:0;margin-bottom:0}.woocommerce-task-dashboard__body .components-modal__frame .woocommerce-task-payments__stripe-error-wrapper{align-items:flex-end;flex-grow:1;display:flex;flex-direction:column}.woocommerce-shipping-rate{display:flex;padding-top:12px;padding-bottom:12px}.woocommerce-shipping-rate .woocommerce-shipping-rate__main{width:100%}.woocommerce-shipping-rate .woocommerce-shipping-rate__icon{padding-top:16px;margin-right:24px}.woocommerce-shipping-rate .woocommerce-shipping-rate__name{align-items:center;display:flex;padding-top:16px;font-size:16px;line-height:22px;color:#1d2327;margin-bottom:12px;border-top:1px solid #dcdcde}.woocommerce-shipping-rate .woocommerce-shipping-rate__name .components-form-toggle{margin-left:auto;height:18px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .components-base-control{margin-bottom:0}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .components-base-control__label{display:block;position:relative;top:-8px;width:100%;font-size:12px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .text-control-with-affixes__prefix,.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .text-control-with-affixes__suffix{font-size:16px;line-height:24px;color:#646970;border:0;padding:0;align-items:center;display:flex;top:-12px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .components-text-control__input{position:relative;top:-12px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .text-control-with-affixes__prefix{margin-right:4px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .text-control-with-affixes__suffix{margin-left:4px}.woocommerce-task-tax__automated-tax-control{display:flex;align-items:center;margin-top:16px}.woocommerce-task-tax__automated-tax-control i{margin-left:16px;margin-right:24px}.woocommerce-task-tax__automated-tax-control .woocommerce-task-tax__automated-tax-control-inner{border-top:1px solid #dcdcde;display:flex;align-items:center;flex:1;font-size:16px;padding-top:16px;padding-bottom:16px}.woocommerce-task-tax__automated-tax-control .components-form-toggle{margin-left:auto}.woocommerce-task-tax__success{display:flex;flex-direction:column;align-items:center;padding:40px;text-align:center}.woocommerce-task-tax__success .woocommerce-task-tax__success-icon{font-size:48px;height:48px;align-items:center;display:flex}.woocommerce-task-tax__success #woocommerce-task-tax__success-message{font-size:32px;font-weight:400}.woocommerce-task-tax__success p{margin-top:0;font-size:16px}.woocommerce-task-payment .woocommerce-card__body{display:flex;padding:24px 36px;align-items:center;position:relative;overflow:hidden}.woocommerce-task-payment .woocommerce-task-payment__recommended-ribbon{transform:rotate(-45deg) translate(-50%,-50%);background:#2c3338;color:#fff;font-size:11px;line-height:20px;position:absolute;top:0;left:0;line-height:1;padding:7px 40px;transform-origin:top left;margin-top:36px;margin-left:36px}.woocommerce-task-payment .woocommerce-task-payment__recommended-ribbon span{max-width:70px}.woocommerce-task-payment .woocommerce-task-payment__recommended-pill{border:1px solid #dcdcde;border-radius:28px;display:inline-block;font-size:13px;margin-left:12px;padding:1px 10px}.woocommerce-task-payment .woocommerce-task-payment__recommended-pill span{max-width:70px}.woocommerce-task-payment .woocommerce-task-payment__before{margin-right:36px}.woocommerce-task-payment .woocommerce-task-payment__before img{max-width:100px}.woocommerce-task-payment .woocommerce-task-payment__title{font-size:16px;font-weight:400;color:#2c3338;margin-top:0;margin-bottom:8px}.woocommerce-task-payment .woocommerce-task-payment__content{font-size:14px;color:#50575e;margin:0 36px 0 0}.woocommerce-task-payment .woocommerce-task-payment__content .text-style-strong{font-weight:700}.woocommerce-task-payment .woocommerce-task-payment__content p{font-size:12px}.woocommerce-task-payment .woocommerce-task-payment__after{margin-left:auto}.woocommerce-task-payment .woocommerce-task-payment__after .components-button.is-button{margin:0}@media (max-width:600px){.woocommerce-task-payment .woocommerce-card__body{flex-direction:column}.woocommerce-task-payment .woocommerce-task-payment__recommended-pill,.woocommerce-task-payment .woocommerce-task-payment__recommended-ribbon{display:none}.woocommerce-task-payment .woocommerce-task-payment__before{order:1;margin-right:auto;margin-bottom:24px}.woocommerce-task-payment .woocommerce-task-payment__after{position:absolute;right:36px;top:24px}.woocommerce-task-payment .woocommerce-task-payment__after .components-form-toggle{margin-top:4px}.woocommerce-task-payment .woocommerce-task-payment__text{order:3;margin-top:16px}}.woocommerce-task-payment-method .woocommerce-card__body{padding:24px}.woocommerce-task-payment-method .woocommerce-card__body>h3{margin:0;color:#1d2327}.woocommerce-task-payment-method .woocommerce-card__body p{font-size:14px;color:#646970;font-weight:400;margin-top:2px;margin-bottom:8px}.woocommerce-task-payment-method__fields{display:-ms-grid;display:grid;-ms-grid-columns:1fr 1fr;grid-template-columns:1fr 1fr;grid-gap:0 16px;margin-bottom:8px}.woocommerce-task-payment-method__fields .components-base-control{margin-bottom:0}.woocommerce-task-dashboard__container button.components-button.is-primary{margin:0}.woocommerce-task-dashboard__container button.components-button.is-link{margin:0;height:auto;color:#50575e;font-weight:400}.woocommerce-task-payments__paypal-auto-create-account{margin-top:16px;margin-bottom:16px}.woocommerce-task-payment-wcpay.woocommerce-task-payment-not-configured{background-color:#3c2861}.woocommerce-task-payment-wcpay.woocommerce-task-payment-not-configured .woocommerce-task-payment__content,.woocommerce-task-payment-wcpay.woocommerce-task-payment-not-configured .woocommerce-task-payment__content a,.woocommerce-task-payment-wcpay.woocommerce-task-payment-not-configured .woocommerce-task-payment__title{color:#fff}.woocommerce-task-card__prompt{width:100%;min-width:100%;margin-bottom:24px;margin-top:-4px;cursor:default}.woocommerce-task-card__prompt .components-snackbar__content{display:block;align-items:unset;justify-content:unset}.woocommerce-task-card__prompt .components-snackbar__content span{margin-left:-24px}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions button.is-link,.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions button.is-link:active,.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions button.is-link:focus{color:#fff;margin-left:24px;background:transparent}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions button.is-link:hover{color:#fff}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-pointer{border-bottom:10px solid #1e1e1e;border-left:10px solid transparent;border-right:10px solid transparent;position:relative;width:0;height:0;display:inline-block;top:-30px}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-content{display:flex;align-items:baseline;justify-content:space-between;max-height:10px;margin-left:24px;position:relative;top:-40px}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions{margin-right:-16px}.woocommerce-task-card__prompt:hover .woocommerce-task-card__prompt-pointer{border-bottom-color:#1e1e1e}.woocommerce-task-card__section-controls{text-align:center}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-card__body{border-top:1px solid #dcdcde;padding:0}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .is-placeholder{animation:none}}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-card__title .is-placeholder{width:70%;height:28px}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-list__item-before .is-placeholder{height:36px;width:36px}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-list__item-text{width:100%}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-list__item-text .woocommerce-list__item-title .is-placeholder{height:22px;width:60%}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-list__item-after .is-placeholder{height:18px;width:60px}.woocommerce-task__caption{color:#757575;margin-top:16px}.woocommerce-activity-card{position:relative;padding:24px;padding:var(--main-gap);background:#fff;border-bottom:1px solid #e0e0e0;color:#757575;font-size:13px;font-size:.8125rem}.woocommerce-activity-card:not(.woocommerce-empty-activity-card){display:-ms-grid;display:grid;-ms-grid-columns:84px 1fr;grid-template-columns:84px 1fr;grid-template-areas:"icon header" "icon body" "icon actions"}@media (max-width:782px){.woocommerce-activity-card:not(.woocommerce-empty-activity-card){-ms-grid-columns:76px 1fr;grid-template-columns:76px 1fr}}.woocommerce-activity-card__button{display:block;height:unset;background:none;align-items:unset;transition:unset;text-align:left;width:100%;padding:0}.woocommerce-activity-card__unread{position:absolute;top:18px;top:calc(var(--main-gap) - 6px);right:18px;right:calc(var(--main-gap) - 6px);width:6px;height:6px;border-radius:50%;background:#ca4a1f}.woocommerce-activity-card__icon{-ms-grid-row:1;-ms-grid-row-span:3;-ms-grid-column:1;grid-area:icon;fill:#e0e0e0}.woocommerce-activity-card__header{margin-bottom:16px;display:flex;flex-direction:column}.woocommerce-activity-card__header .woocommerce-activity-card__title{margin:0;font-size:13px;font-size:.8125rem;order:2}.woocommerce-empty-activity-card .woocommerce-activity-card__header .woocommerce-activity-card__title{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:24px;font-weight:400}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__title{margin-bottom:8px}.woocommerce-activity-card__header .woocommerce-activity-card__date{color:#757575;text-transform:uppercase;font-size:11px;font-size:.6875rem;margin-bottom:12px;order:1}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{order:3}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__subtitle{margin-bottom:4px}@media (min-width:783px){.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:2;grid-area:header;display:-ms-grid;display:grid;-ms-grid-rows:auto auto;-ms-grid-columns:1fr auto;grid-template:"title date" "subtitle date"/1fr auto}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__title{grid-area:title}.woocommerce-activity-card__header .woocommerce-activity-card__date{display:block;grid-area:date;-ms-grid-column-align:end;justify-self:end;margin-bottom:0}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{grid-area:subtitle}}@media (min-width:783px){.woocommerce-activity-card__header .woocommerce-activity-card__title{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__date{-ms-grid-row:1;-ms-grid-row-span:2;-ms-grid-column:2}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{-ms-grid-row:2;-ms-grid-column:1}}.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:2;grid-area:body}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:1}.woocommerce-activity-card__body>p:first-child{margin-top:0}.woocommerce-activity-card__body>p:last-child{margin-bottom:0}.woocommerce-empty-activity-card .woocommerce-activity-card__body{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:2;grid-area:actions;margin-top:16px}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:1}.woocommerce-activity-card__actions>*+*{margin-left:.5em}.woocommerce-activity-card.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-activity-card.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-activity-card.is-loading .is-placeholder{animation:none}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__title{width:80%}.woocommerce-activity-card.is-loading .woocommerce-activity-card__subtitle{margin-top:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{width:100%;margin-bottom:16px}@media (min-width:783px){.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{text-align:right;margin-bottom:0}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date .is-placeholder{width:68px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon{margin-right:24px;margin-right:var(--main-gap)}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon .is-placeholder{height:48px;width:48px}.woocommerce-activity-card.is-loading.woocommerce-review-activity-card .woocommerce-activity-card__icon .is-placeholder,.woocommerce-activity-card.is-loading.woocommerce-stock-activity-card .woocommerce-activity-card__icon .is-placeholder{height:60px;width:60px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder{width:100%;margin-bottom:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder:last-of-type{width:65%;margin-bottom:0}.woocommerce-activity-card.is-loading .woocommerce-activity-card__actions .is-placeholder{width:91px;height:34px}.woocommerce-activity-card.woocommerce-order-activity-card{-ms-grid-columns:1fr;grid-template-columns:1fr;grid-template-areas:"header" "body" "actions"}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__icon{display:none}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-flag{display:inline-block}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__subtitle span+span:before{content:" \2022\ "}.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:72px 1fr;grid-template-columns:72px 1fr;height:100%;opacity:1;padding:24px;padding:var(--main-gap)}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card{transition:opacity .3s,height 0s,padding 0s}}@media (max-width:782px){.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:64px 1fr;grid-template-columns:64px 1fr}}.woocommerce-activity-card.woocommerce-inbox-activity-card .woocommerce-activity-card__header{margin-bottom:12px}.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{height:0;opacity:0;padding:0}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{transition:opacity .3s,height 0s .3s,padding 0s .3s}}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:first-child{margin-top:0}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:last-child{margin-bottom:0}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified{margin-left:12px;display:inline-flex;position:relative;top:4px;color:#4ab866;font-size:12px;font-size:.75rem}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified .gridicon{margin-right:4px;fill:#4ab866}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{position:relative}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay img.woocommerce-gravatar{border:2px solid #fff;left:0;position:absolute;top:-6px;z-index:2}@media (max-width:782px){.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{margin-top:4px}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay__product .woocommerce-gravatar{margin-left:0;width:18px;height:18px;left:32px;top:-28px;z-index:1}}.woocommerce-review-activity-card__image-overlay__product,.woocommerce-stock-activity-card__image-overlay__product{height:60px;position:relative;width:60px}.woocommerce-review-activity-card__image-overlay__product.is-placeholder:before,.woocommerce-stock-activity-card__image-overlay__product.is-placeholder:before{background-color:#757575;border-radius:50%;content:"";position:absolute;left:0;right:0;bottom:0;top:0;opacity:.1}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-stock-activity-card{transition:opacity .3s}}.woocommerce-stock-activity-card.is-dimmed{opacity:.7}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__stock-quantity{background:#f0f0f0;color:#757575;padding:3px 8px;border-radius:3px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity{display:inline-flex;width:50px;margin-right:10px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input{border-radius:4px;height:36px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]{-moz-appearance:textfield}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-inner-spin-button,.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.woocommerce-stock-activity-card .components-button{min-height:34px;padding:2px 10px;line-height:26px}.woocommerce-stock-activity-card .woocommerce-activity-card__title{font-size:15px;font-size:.9375rem}.woocommerce-stock-activity-card .woocommerce-activity-card__subtitle{color:#757575;font-size:12px;font-size:.75rem}.woocommerce-empty-activity-card{background:#f0f0f0;margin:20px;border-bottom:unset}.woocommerce-inbox-message{position:relative;color:#757575;background:#f0f0f0;border-radius:2px;font-size:13px;font-size:.8125rem;margin:0 0 24px;-ms-box-orient:horizontal}.woocommerce-inbox-message.banner{flex-direction:column}.woocommerce-inbox-message.banner img{width:100%;height:120px}.woocommerce-inbox-message.thumbnail{display:flex;flex-direction:row-reverse}.woocommerce-inbox-message.thumbnail img{width:128px;height:100%}.woocommerce-homepage-column .woocommerce-inbox-message{margin:20px 0}.woocommerce-inbox-message:not(.is-placeholder){border:1px solid #e0e0e0}.woocommerce-inbox-message.message-is-unread{background:#fff}.woocommerce-inbox-message .line{width:100%}.woocommerce-inbox-message .third-line{width:33%}.woocommerce-inbox-message .fifth-line{width:20%}.woocommerce-inbox-message .sixth-line{width:16%}.woocommerce-inbox-message__content .woocommerce-inbox-message__title{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:1.5;font-weight:400;margin:8px 0}.message-is-unread .woocommerce-inbox-message__content .woocommerce-inbox-message__title{font-weight:700}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title{margin-bottom:10px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;margin:5px 0}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div{animation:none}}.woocommerce-inbox-message__content .woocommerce-inbox-message__date{color:#757575;font-size:12px;font-size:.75rem;margin-bottom:16px;font-style:normal;font-weight:400;line-height:16px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date{margin-bottom:10px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div{animation:none}}.woocommerce-inbox-message__text{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-inbox-message__text>p:first-child{margin-top:0}.woocommerce-inbox-message__text>p:last-child{margin-bottom:0}.is-placeholder .woocommerce-inbox-message__text>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;margin:5px 0}.is-placeholder .woocommerce-inbox-message__text>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__text>div{animation:none}}.woocommerce-inbox-message__actions{padding-top:16px;border-top:1px solid #e0e0e0}.woocommerce-inbox-message__actions>*+*{margin-left:.5em}.woocommerce-inbox-message__actions a,.woocommerce-inbox-message__actions button{cursor:pointer}.woocommerce-inbox-message__actions .components-dropdown{display:inline}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content{min-width:195px}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content ul{text-align:center}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content li{margin:0;cursor:pointer}.is-placeholder .woocommerce-inbox-message__actions>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;float:left;height:28px;margin-right:8px}.is-placeholder .woocommerce-inbox-message__actions>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__actions>div{animation:none}}.woocommerce-inbox-dismiss-confirmation_modal{text-align:left}.woocommerce-inbox-dismiss-confirmation_wrapper p{font-size:16px;color:#757575}.woocommerce-inbox-dismiss-confirmation_wrapper .woocommerce-inbox-dismiss-confirmation_buttons{text-align:right}.woocommerce-inbox-dismiss-confirmation_wrapper .woocommerce-inbox-dismiss-confirmation_buttons button{margin-left:10px}.woocommerce-inbox-message__wrapper>div{padding:16px 24px}.is-placeholder .woocommerce-inbox-message__wrapper>div{padding:10px 24px;display:flow-root}.is-placeholder .woocommerce-inbox-message__image .banner-block{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;width:100%;height:120px}.is-placeholder .woocommerce-inbox-message__image .banner-block:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__image .banner-block{animation:none}}#activity-panel-inbox{margin:0 24px}.woocommerce-layout__inbox-panel-header{padding:24px}.woocommerce-homepage-column .woocommerce-layout__inbox-panel-header{padding:0 24px}@media (-ms-high-contrast:active),(-ms-high-contrast:none){.woocommerce-admin-dismiss-dropdown{margin-top:0}.is-placeholder .woocommerce-inbox-message__wrapper{padding-bottom:10px}}.woocommerce-inbox-message-enter{opacity:0;max-height:0;transform:translateX(50%)}.woocommerce-inbox-message-enter-active{transition:opacity .5s,transform .5s,max-height .5s}.woocommerce-inbox-message-enter-active,.woocommerce-inbox-message-exit{opacity:1;max-height:100vh;transform:translateX(0)}.woocommerce-inbox-message-exit-active{opacity:0;max-height:0;transform:translateX(50%);transition:opacity .5s,transform .5s,max-height .5s}.components-guide.woocommerce__welcome-modal{max-width:517px;height:460px}.components-guide.woocommerce__welcome-modal .components-modal__header{height:0}.components-guide.woocommerce__welcome-modal .components-modal__header .components-button{color:#fff}.components-guide.woocommerce__welcome-modal .components-guide__container{margin-top:0}.components-guide.woocommerce__welcome-modal .components-guide__container .woocommerce__welcome-modal__page-content{padding:0 24px}.components-guide.woocommerce__welcome-modal .components-guide__container .woocommerce__welcome-modal__page-content .woocommerce__welcome-modal__page-content__header{font-size:24px;line-height:32px;margin:0 0 24px}.components-guide.woocommerce__welcome-modal .components-guide__container .woocommerce__welcome-modal__page-content .woocommerce__welcome-modal__page-content__body{font-size:16px;line-height:24px;margin:0 0 24px}.components-guide.woocommerce__welcome-modal .components-guide__footer{padding:0;margin:0 24px 24px;justify-content:flex-end;width:auto}.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__back-button,.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__finish-button,.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__forward-button{position:static;padding:0 16px;font-weight:500;font-size:14px;line-height:18px}.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__back-button,.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__forward-button{color:#007cba;color:var(--wp-admin-theme-color)}.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__finish-button,.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__forward-button{margin-left:10px}.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__forward-button{box-shadow:inset 0 0 0 1px #007cba;box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color);outline:1px solid transparent}.components-guide.woocommerce__welcome-modal .fill-theme-color{fill:#007cba;fill:var(--wp-admin-theme-color)}.woocommerce-layout__activity-panel-header{height:50px;background:#e0e0e0;padding:16px;display:flex;justify-content:space-between;align-items:center}@media (min-width:783px){.woocommerce-layout__activity-panel-header{padding:16px 24px}}.woocommerce-layout__activity-panel-header h3{font-size:13px;font-weight:600;line-height:16px;margin:0;padding:0}.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):focus,.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):hover{box-shadow:none;border-radius:10px;background:#ccc}.woocommerce-layout__inbox-title{color:#1e1e1e;display:flex;align-items:center}.woocommerce-layout__inbox-subtitle{color:#757575}.woocommerce-layout__inbox-badge{margin-left:6px;background-color:#757575;border-radius:13px;padding:0 6px;color:#fff;display:inline-block;text-align:center;vertical-align:top}.woocommerce-accordion-card .components-panel__body-title{margin:0;padding:1em 0}.woocommerce-accordion-card .components-panel__body-title .components-button{display:flex;flex-direction:row;width:100%;padding-left:24px;font-style:normal;font-weight:400;font-size:20px;line-height:28px;color:#1e1e1e}.woocommerce-accordion-card .components-panel__body-title .components-button:focus{box-shadow:unset;outline:unset}.woocommerce-accordion-card .components-panel__body-title .components-button .woocommerce-accordion-header{order:1;text-align:left;width:50%}.woocommerce-accordion-card .components-panel__body-title .components-button .woocommerce-accordion-header .woocommerce-accordion-title{vertical-align:bottom;margin-right:16px}.woocommerce-accordion-card .components-panel__body-title .components-button>span{order:2;width:50%;text-align:right}.woocommerce-accordion-card .components-panel__body-title .components-button>span .components-panel__arrow{width:30px;height:30px;vertical-align:text-top}.woocommerce-accordion-card .woocommerce-activity-card__actions{margin:0}.woocommerce-accordion-card .woocommerce-activity-card__actions .components-button{background:#f0f0f0;border-radius:12px;height:24px;padding-left:16px;width:65px}.woocommerce-accordion-card .woocommerce-activity-card{padding:20px var(--main-gap) var(--main-gap)}.woocommerce-accordion-card .woocommerce-activity-card__header{margin-bottom:8px}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link{display:flex;justify-content:space-between;align-items:center;height:50px;border-bottom:1px solid #f0f0f0;padding:16px 24px;padding:16px var(--main-gap);font-size:13px;font-weight:500;line-height:18px;margin:0;text-decoration:none}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link .gridicon{display:none}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:hover{background:#e0e0e0}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:active{background:#f0f0f0}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:focus{background:#e0e0e0;box-shadow:inset 0 0 0 1px #5b9dd9,inset 0 0 0 2px #e0e0e0}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:active .gridicon,.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:focus .gridicon,.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:hover .gridicon{display:initial}.woocommerce-accordion-card .woocommerce-layout__activity-panel-empty{border-top:1px solid #e0e0e0}.woocommerce-accordion-card .woocommerce-activity-card__button:focus{box-shadow:unset;outline:unset;border:1px solid #e0e0e0}.woocommerce-accordion-card .is-opened .components-panel__body-title{border-bottom:1px solid #e0e0e0}.woocommerce-accordion-card .woocommerce-empty-activity-card{background:unset;text-align:center;padding:12px var(--main-gap) 0}.woocommerce-accordion-card .woocommerce-empty-activity-card h4{color:#1e1e1e}.woocommerce-accordion-card .woocommerce-order-empty__success-icon{font-size:36px}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__header{margin-bottom:4px}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__header .woocommerce-activity-card__title.is-placeholder{width:45%}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__body>.is-placeholder{width:30%}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__actions>.is-placeholder{height:24px;margin-top:4px;width:65px}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-order-activity-card{cursor:pointer}.woocommerce-page #wpcontent,.woocommerce-page.woocommerce_page_wc-admin #wpbody-content{overflow-x:inherit!important}.woocommerce-homescreen{display:flex;max-width:1032px;margin:0 auto;justify-content:space-between;flex-direction:column}.woocommerce-homescreen .woocommerce-task-dashboard__container{width:100%;margin-bottom:24px}.woocommerce-homescreen.two-columns{flex-direction:row}.woocommerce-homescreen.two-columns .woocommerce-homescreen-column{width:calc(50% - 12px);margin:0}@media (max-width:782px){.woocommerce-homescreen.two-columns .woocommerce-homescreen-column{width:100%;position:inherit;top:auto}}.woocommerce-homescreen.two-columns .your-store-today{display:block}@media (max-width:782px){.woocommerce-homescreen.two-columns{flex-direction:column}.woocommerce-homescreen.two-columns .your-store-today{display:none}}@media (max-width:782px){.woocommerce-homescreen{margin-left:-16px;margin-right:-16px}}.woocommerce-homescreen-column{width:662px;top:100px;margin:0 auto;align-self:flex-start}.woocommerce-homescreen-column>div{margin-bottom:24px}@media (max-width:782px){.woocommerce-homescreen-column{width:100%;position:inherit;top:auto}}.woocommerce-homescreen-card .components-card__header.is-size-large,.woocommerce-homescreen-card .components-card__header.is-size-medium{min-height:63px;min-height:unset;display:-ms-grid;display:grid;-ms-grid-columns:auto 24px;grid-template-columns:auto 24px}.woocommerce-homescreen-card .components-card__header.is-size-large>*,.woocommerce-homescreen-card .components-card__header.is-size-medium>*{-ms-grid-row-align:center;align-self:center}.woocommerce-homescreen-card .components-card__body.is-size-large{padding:0}.woocommerce-homescreen-card .components-card__footer.is-size-large{padding:0 8px}#klarna-kp-banner,.woocommerce-layout__inbox-panel-header.your-store-today,.woocommerce-page:not(.woocommerce-embed-page) #klarna-banner{display:none}.woocommerce-dashboard__columns{display:-ms-grid;display:grid;-ms-grid-columns:calc(50% - 12px) calc(50% - 12px);grid-template-columns:calc(50% - 12px) calc(50% - 12px);grid-column-gap:24px}.woocommerce-dashboard__columns>div:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(2){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(3){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(4){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(5){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(6){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(7){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(8){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(9){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(10){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(11){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(12){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(13){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}.woocommerce-dashboard__columns>div:nth-child(14){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}@media (max-width:960px){.woocommerce-dashboard__columns{-ms-grid-columns:100%;grid-template-columns:100%}.woocommerce-dashboard__columns>div:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(2){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(3){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(4){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(5){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(6){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(7){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}.woocommerce-dashboard__columns>div:nth-child(8){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:8;grid-row-start:8;-ms-grid-row-span:1;grid-row-end:9}.woocommerce-dashboard__columns>div:nth-child(9){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:9;grid-row-start:9;-ms-grid-row-span:1;grid-row-end:10}.woocommerce-dashboard__columns>div:nth-child(10){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:10;grid-row-start:10;-ms-grid-row-span:1;grid-row-end:11}.woocommerce-dashboard__columns>div:nth-child(11){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:11;grid-row-start:11;-ms-grid-row-span:1;grid-row-end:12}.woocommerce-dashboard__columns>div:nth-child(12){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:12;grid-row-start:12;-ms-grid-row-span:1;grid-row-end:13}.woocommerce-dashboard__columns>div:nth-child(13){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:13;grid-row-start:13;-ms-grid-row-span:1;grid-row-end:14}.woocommerce-dashboard__columns>div:nth-child(14){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:14;grid-row-start:14;-ms-grid-row-span:1;grid-row-end:15}}.woocommerce-dashboard__widget{display:flex;align-items:center;text-align:center}.woocommerce-dashboard__widget-item{flex:1}.woocommerce-dashboard-section__add-more{margin:0 auto;width:84px;padding:0 24px 24px}.woocommerce-dashboard-section__add-more .components-popover__content{padding:0 16px 8px}.woocommerce-dashboard-section__add-more>button svg{fill:#757575}.woocommerce-dashboard-section__add-more-choices{display:flex;justify-content:center}.woocommerce-dashboard-section__add-more-btn{display:flex;flex-direction:column;align-items:center;padding:16px;margin:8px}.woocommerce-dashboard-section__add-more-btn.components-button{height:auto}.woocommerce-dashboard-section__add-more-btn .dashicons-arrow-right-alt{transform:rotate(-45deg)}.woocommerce-dashboard-section__add-more-btn-title{color:#757575;padding-top:8px}.woocommerce-dashboard-section-controls{border-top:1px solid #f0f0f0;padding-top:8px}.woocommerce-dashboard-section-controls .dashicon{margin:0 8px 0 0;vertical-align:bottom}.woocommerce-dashboard-section-controls .woocommerce-ellipsis-menu__item{padding-bottom:10px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-card__header.is-size-large{padding-bottom:12px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-card__header.is-size-large .woocommerce-card__menu{margin-top:8px}.woocommerce-store-management-links__card-body.is-size-custom{padding:24px 0 8px}.woocommerce-quick-links__category{display:flex;flex-flow:row wrap;margin-bottom:8px}.woocommerce-quick-links__category .woocommerce-quick-links__category-header{margin:0 24px 8px;text-transform:uppercase;color:#757575;line-height:16px;font-size:11px;flex:1 100%}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-quick-links__item{display:flex;flex:1 50%}.woocommerce-quick-links__item:hover{background-color:#f0f0f0}.woocommerce-quick-links__item .woocommerce-quick-links__item-link{width:100%;display:flex;align-items:center;text-decoration:none;padding:16px 27px 16px 24px}.woocommerce-quick-links__item .woocommerce-quick-links__item-link .woocommerce-quick-links__item-link__icon{fill:#007cba;fill:var(--wp-admin-theme-color)}.woocommerce-quick-links__item .woocommerce-quick-links__item-link .woocommerce-quick-links__item-link__text{margin-left:16px;flex:1;line-height:16px;font-size:13px}.woocommerce-homescreen.two-columns .woocommerce-quick-links__item{flex:1 100%} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/35.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/35.style.rtl.css new file mode 100644 index 0000000..cee99ec --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/35.style.rtl.css @@ -0,0 +1 @@ +.woocommerce-stats-overview .woocommerce-card__body{padding:0}.woocommerce-stats-overview .woocommerce-summary{margin:0}.woocommerce-stats-overview__more-btn{display:inline-block;padding:16px}.woocommerce-stats-overview__tabs .components-tab-panel__tabs{display:flex;justify-content:space-between;border-bottom:1px solid #e0e0e0}.woocommerce-stats-overview__tabs .components-tab-panel__tabs .components-button{width:33.33%;padding-left:24px;padding-right:24px}.woocommerce-stats-overview__stats{margin:0}.woocommerce-stats-overview__stats .woocommerce-summary__item-container{width:50%;display:inline-block}.woocommerce-stats-overview__stats.is-even .woocommerce-summary__item-container:nth-last-of-type(2) .woocommerce-summary__item,.woocommerce-stats-overview__stats .woocommerce-summary__item-container:last-of-type .woocommerce-summary__item{border-bottom:none}.woocommerce-stats-overview__stats .woocommerce-summary__item-container:nth-of-type(2n) .woocommerce-summary__item{border-left:none}.woocommerce-stats-overview__stats .woocommerce-summary__item{background-color:#fff}.woocommerce-stats-overview__stats .woocommerce-summary__item:active,.woocommerce-stats-overview__stats .woocommerce-summary__item:hover{background-color:#f0f0f0}article.woocommerce-stats-overview__install-jetpack-promo .woocommerce-stats-overview__install-jetpack-promo__content{padding:16px 24px}article.woocommerce-stats-overview__install-jetpack-promo h2{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:1.5;font-weight:400;margin:8px 0}article.woocommerce-stats-overview__install-jetpack-promo p{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px;margin:8px 0}article.woocommerce-stats-overview__install-jetpack-promo footer{padding:16px 24px;border-top:1px solid #f0f0f0;border-bottom:1px solid #f0f0f0}article.woocommerce-stats-overview__install-jetpack-promo footer button{margin-right:8px}article.woocommerce-stats-overview__install-jetpack-promo footer button:first-child{margin-right:0}.woocommerce-task-dashboard__body .woocommerce-card__description{color:#646970}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .wooocommerce-task-card__header{display:flex}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .wooocommerce-task-card__header .woocommerce-badge{margin-right:16px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .woocommerce-list__item:not(.is-complete) .woocommerce-task__icon{border:1px solid #f0f0f0;background:#fff}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .woocommerce-list__item.is-complete .woocommerce-list__item-title{color:#757575}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .woocommerce-list__item-before .woocommerce-task__icon{border-radius:50%;width:32px;height:32px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .woocommerce-list__item-before svg{fill:#fff;position:relative;top:4px;right:5px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-popover__content{min-width:unset}.woocommerce-task-dashboard__body .woocommerce-task__additional-info,.woocommerce-task-dashboard__body .woocommerce-task__estimated-time{color:#757575;font-weight:400;font-size:12px}.woocommerce-task-dashboard__body .woocommerce-card.is-narrow{max-width:680px;margin-right:auto;margin-left:auto}.woocommerce-task-dashboard__body #wpbody-content{position:relative}.woocommerce-task-dashboard__body .components-modal__screen-overlay{background:rgba(43,45,47,.4)}.woocommerce-task-dashboard__body .components-modal__frame .components-modal__header{border-bottom:0;margin-bottom:0}.woocommerce-task-dashboard__body .components-modal__frame .woocommerce-task-payments__stripe-error-wrapper{align-items:flex-end;flex-grow:1;display:flex;flex-direction:column}.woocommerce-shipping-rate{display:flex;padding-top:12px;padding-bottom:12px}.woocommerce-shipping-rate .woocommerce-shipping-rate__main{width:100%}.woocommerce-shipping-rate .woocommerce-shipping-rate__icon{padding-top:16px;margin-left:24px}.woocommerce-shipping-rate .woocommerce-shipping-rate__name{align-items:center;display:flex;padding-top:16px;font-size:16px;line-height:22px;color:#1d2327;margin-bottom:12px;border-top:1px solid #dcdcde}.woocommerce-shipping-rate .woocommerce-shipping-rate__name .components-form-toggle{margin-right:auto;height:18px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .components-base-control{margin-bottom:0}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .components-base-control__label{display:block;position:relative;top:-8px;width:100%;font-size:12px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .text-control-with-affixes__prefix,.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .text-control-with-affixes__suffix{font-size:16px;line-height:24px;color:#646970;border:0;padding:0;align-items:center;display:flex;top:-12px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .components-text-control__input{position:relative;top:-12px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .text-control-with-affixes__prefix{margin-left:4px}.woocommerce-shipping-rate .woocommerce-shipping-rate__control-wrapper .text-control-with-affixes__suffix{margin-right:4px}.woocommerce-task-tax__automated-tax-control{display:flex;align-items:center;margin-top:16px}.woocommerce-task-tax__automated-tax-control i{margin-right:16px;margin-left:24px}.woocommerce-task-tax__automated-tax-control .woocommerce-task-tax__automated-tax-control-inner{border-top:1px solid #dcdcde;display:flex;align-items:center;flex:1;font-size:16px;padding-top:16px;padding-bottom:16px}.woocommerce-task-tax__automated-tax-control .components-form-toggle{margin-right:auto}.woocommerce-task-tax__success{display:flex;flex-direction:column;align-items:center;padding:40px;text-align:center}.woocommerce-task-tax__success .woocommerce-task-tax__success-icon{font-size:48px;height:48px;align-items:center;display:flex}.woocommerce-task-tax__success #woocommerce-task-tax__success-message{font-size:32px;font-weight:400}.woocommerce-task-tax__success p{margin-top:0;font-size:16px}.woocommerce-task-payment .woocommerce-card__body{display:flex;padding:24px 36px;align-items:center;position:relative;overflow:hidden}.woocommerce-task-payment .woocommerce-task-payment__recommended-ribbon{transform:rotate(45deg) translate(50%,-50%);background:#2c3338;color:#fff;font-size:11px;line-height:20px;position:absolute;top:0;right:0;line-height:1;padding:7px 40px;transform-origin:top right;margin-top:36px;margin-right:36px}.woocommerce-task-payment .woocommerce-task-payment__recommended-ribbon span{max-width:70px}.woocommerce-task-payment .woocommerce-task-payment__recommended-pill{border:1px solid #dcdcde;border-radius:28px;display:inline-block;font-size:13px;margin-right:12px;padding:1px 10px}.woocommerce-task-payment .woocommerce-task-payment__recommended-pill span{max-width:70px}.woocommerce-task-payment .woocommerce-task-payment__before{margin-left:36px}.woocommerce-task-payment .woocommerce-task-payment__before img{max-width:100px}.woocommerce-task-payment .woocommerce-task-payment__title{font-size:16px;font-weight:400;color:#2c3338;margin-top:0;margin-bottom:8px}.woocommerce-task-payment .woocommerce-task-payment__content{font-size:14px;color:#50575e;margin:0 0 0 36px}.woocommerce-task-payment .woocommerce-task-payment__content .text-style-strong{font-weight:700}.woocommerce-task-payment .woocommerce-task-payment__content p{font-size:12px}.woocommerce-task-payment .woocommerce-task-payment__after{margin-right:auto}.woocommerce-task-payment .woocommerce-task-payment__after .components-button.is-button{margin:0}@media (max-width:600px){.woocommerce-task-payment .woocommerce-card__body{flex-direction:column}.woocommerce-task-payment .woocommerce-task-payment__recommended-pill,.woocommerce-task-payment .woocommerce-task-payment__recommended-ribbon{display:none}.woocommerce-task-payment .woocommerce-task-payment__before{order:1;margin-left:auto;margin-bottom:24px}.woocommerce-task-payment .woocommerce-task-payment__after{position:absolute;left:36px;top:24px}.woocommerce-task-payment .woocommerce-task-payment__after .components-form-toggle{margin-top:4px}.woocommerce-task-payment .woocommerce-task-payment__text{order:3;margin-top:16px}}.woocommerce-task-payment-method .woocommerce-card__body{padding:24px}.woocommerce-task-payment-method .woocommerce-card__body>h3{margin:0;color:#1d2327}.woocommerce-task-payment-method .woocommerce-card__body p{font-size:14px;color:#646970;font-weight:400;margin-top:2px;margin-bottom:8px}.woocommerce-task-payment-method__fields{display:-ms-grid;display:grid;-ms-grid-columns:1fr 1fr;grid-template-columns:1fr 1fr;grid-gap:0 16px;margin-bottom:8px}.woocommerce-task-payment-method__fields .components-base-control{margin-bottom:0}.woocommerce-task-dashboard__container button.components-button.is-primary{margin:0}.woocommerce-task-dashboard__container button.components-button.is-link{margin:0;height:auto;color:#50575e;font-weight:400}.woocommerce-task-payments__paypal-auto-create-account{margin-top:16px;margin-bottom:16px}.woocommerce-task-payment-wcpay.woocommerce-task-payment-not-configured{background-color:#3c2861}.woocommerce-task-payment-wcpay.woocommerce-task-payment-not-configured .woocommerce-task-payment__content,.woocommerce-task-payment-wcpay.woocommerce-task-payment-not-configured .woocommerce-task-payment__content a,.woocommerce-task-payment-wcpay.woocommerce-task-payment-not-configured .woocommerce-task-payment__title{color:#fff}.woocommerce-task-card__prompt{width:100%;min-width:100%;margin-bottom:24px;margin-top:-4px;cursor:default}.woocommerce-task-card__prompt .components-snackbar__content{display:block;align-items:unset;justify-content:unset}.woocommerce-task-card__prompt .components-snackbar__content span{margin-right:-24px}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions button.is-link,.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions button.is-link:active,.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions button.is-link:focus{color:#fff;margin-right:24px;background:transparent}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions button.is-link:hover{color:#fff}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-pointer{border-bottom:10px solid #1e1e1e;border-right:10px solid transparent;border-left:10px solid transparent;position:relative;width:0;height:0;display:inline-block;top:-30px}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-content{display:flex;align-items:baseline;justify-content:space-between;max-height:10px;margin-right:24px;position:relative;top:-40px}.woocommerce-task-card__prompt .woocommerce-task-card__prompt-actions{margin-left:-16px}.woocommerce-task-card__prompt:hover .woocommerce-task-card__prompt-pointer{border-bottom-color:#1e1e1e}.woocommerce-task-card__section-controls{text-align:center}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-card__body{border-top:1px solid #dcdcde;padding:0}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .is-placeholder{animation:none}}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-card__title .is-placeholder{width:70%;height:28px}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-list__item-before .is-placeholder{height:36px;width:36px}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-list__item-text{width:100%}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-list__item-text .woocommerce-list__item-title .is-placeholder{height:22px;width:60%}.woocommerce-task-dashboard__container .woocommerce-task-card.is-loading .woocommerce-list__item-after .is-placeholder{height:18px;width:60px}.woocommerce-task__caption{color:#757575;margin-top:16px}.woocommerce-activity-card{position:relative;padding:24px;padding:var(--main-gap);background:#fff;border-bottom:1px solid #e0e0e0;color:#757575;font-size:13px;font-size:.8125rem}.woocommerce-activity-card:not(.woocommerce-empty-activity-card){display:-ms-grid;display:grid;-ms-grid-columns:84px 1fr;grid-template-columns:84px 1fr;grid-template-areas:"icon header" "icon body" "icon actions"}@media (max-width:782px){.woocommerce-activity-card:not(.woocommerce-empty-activity-card){-ms-grid-columns:76px 1fr;grid-template-columns:76px 1fr}}.woocommerce-activity-card__button{display:block;height:unset;background:none;align-items:unset;transition:unset;text-align:right;width:100%;padding:0}.woocommerce-activity-card__unread{position:absolute;top:18px;top:calc(var(--main-gap) - 6px);left:18px;left:calc(var(--main-gap) - 6px);width:6px;height:6px;border-radius:50%;background:#ca4a1f}.woocommerce-activity-card__icon{-ms-grid-row:1;-ms-grid-row-span:3;-ms-grid-column:1;grid-area:icon;fill:#e0e0e0}.woocommerce-activity-card__header{margin-bottom:16px;display:flex;flex-direction:column}.woocommerce-activity-card__header .woocommerce-activity-card__title{margin:0;font-size:13px;font-size:.8125rem;order:2}.woocommerce-empty-activity-card .woocommerce-activity-card__header .woocommerce-activity-card__title{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:24px;font-weight:400}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__title{margin-bottom:8px}.woocommerce-activity-card__header .woocommerce-activity-card__date{color:#757575;text-transform:uppercase;font-size:11px;font-size:.6875rem;margin-bottom:12px;order:1}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{order:3}.woocommerce-activity-card__button .woocommerce-activity-card__header .woocommerce-activity-card__subtitle{margin-bottom:4px}@media (min-width:783px){.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:2;grid-area:header;display:-ms-grid;display:grid;-ms-grid-rows:auto auto;-ms-grid-columns:1fr auto;grid-template:"title date" "subtitle date"/1fr auto}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__header{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__title{grid-area:title}.woocommerce-activity-card__header .woocommerce-activity-card__date{display:block;grid-area:date;-ms-grid-column-align:end;justify-self:end;margin-bottom:0}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{grid-area:subtitle}}@media (min-width:783px){.woocommerce-activity-card__header .woocommerce-activity-card__title{-ms-grid-row:1;-ms-grid-column:1}.woocommerce-activity-card__header .woocommerce-activity-card__date{-ms-grid-row:1;-ms-grid-row-span:2;-ms-grid-column:2}.woocommerce-activity-card__header .woocommerce-activity-card__subtitle{-ms-grid-row:2;-ms-grid-column:1}}.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:2;grid-area:body}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__body{-ms-grid-row:2;-ms-grid-column:1}.woocommerce-activity-card__body>p:first-child{margin-top:0}.woocommerce-activity-card__body>p:last-child{margin-bottom:0}.woocommerce-empty-activity-card .woocommerce-activity-card__body{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:2;grid-area:actions;margin-top:16px}.woocommerce-activity-card.woocommerce-order-activity-card>.woocommerce-activity-card__actions{-ms-grid-row:3;-ms-grid-column:1}.woocommerce-activity-card__actions>*+*{margin-right:.5em}.woocommerce-activity-card.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-activity-card.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-activity-card.is-loading .is-placeholder{animation:none}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__title{width:80%}.woocommerce-activity-card.is-loading .woocommerce-activity-card__subtitle{margin-top:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{width:100%;margin-bottom:16px}@media (min-width:783px){.woocommerce-activity-card.is-loading .woocommerce-activity-card__date{text-align:left;margin-bottom:0}}.woocommerce-activity-card.is-loading .woocommerce-activity-card__date .is-placeholder{width:68px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon{margin-left:24px;margin-left:var(--main-gap)}.woocommerce-activity-card.is-loading .woocommerce-activity-card__icon .is-placeholder{height:48px;width:48px}.woocommerce-activity-card.is-loading.woocommerce-review-activity-card .woocommerce-activity-card__icon .is-placeholder,.woocommerce-activity-card.is-loading.woocommerce-stock-activity-card .woocommerce-activity-card__icon .is-placeholder{height:60px;width:60px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder{width:100%;margin-bottom:4px}.woocommerce-activity-card.is-loading .woocommerce-activity-card__body .is-placeholder:last-of-type{width:65%;margin-bottom:0}.woocommerce-activity-card.is-loading .woocommerce-activity-card__actions .is-placeholder{width:91px;height:34px}.woocommerce-activity-card.woocommerce-order-activity-card{-ms-grid-columns:1fr;grid-template-columns:1fr;grid-template-areas:"header" "body" "actions"}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__icon{display:none}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-flag{display:inline-block}.woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__subtitle span+span:before{content:" \2022\ "}.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:72px 1fr;grid-template-columns:72px 1fr;height:100%;opacity:1;padding:24px;padding:var(--main-gap)}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card{transition:opacity .3s,height 0s,padding 0s}}@media (max-width:782px){.woocommerce-activity-card.woocommerce-inbox-activity-card{-ms-grid-columns:64px 1fr;grid-template-columns:64px 1fr}}.woocommerce-activity-card.woocommerce-inbox-activity-card .woocommerce-activity-card__header{margin-bottom:12px}.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{height:0;opacity:0;padding:0}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-activity-card.woocommerce-inbox-activity-card.actioned{transition:opacity .3s,height 0s .3s,padding 0s .3s}}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:first-child{margin-top:0}.woocommerce-review-activity-card .woocommerce-activity-card__body>span>p:last-child{margin-bottom:0}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified{margin-right:12px;display:inline-flex;position:relative;top:4px;color:#4ab866;font-size:12px;font-size:.75rem}.woocommerce-review-activity-card .woocommerce-review-activity-card__verified .gridicon{margin-left:4px;fill:#4ab866}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{position:relative}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay img.woocommerce-gravatar{border:2px solid #fff;right:0;position:absolute;top:-6px;z-index:2}@media (max-width:782px){.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay{margin-top:4px}.woocommerce-review-activity-card .woocommerce-review-activity-card__image-overlay__product .woocommerce-gravatar{margin-right:0;width:18px;height:18px;right:32px;top:-28px;z-index:1}}.woocommerce-review-activity-card__image-overlay__product,.woocommerce-stock-activity-card__image-overlay__product{height:60px;position:relative;width:60px}.woocommerce-review-activity-card__image-overlay__product.is-placeholder:before,.woocommerce-stock-activity-card__image-overlay__product.is-placeholder:before{background-color:#757575;border-radius:50%;content:"";position:absolute;right:0;left:0;bottom:0;top:0;opacity:.1}@media screen and (prefers-reduced-motion:no-preference){.woocommerce-stock-activity-card{transition:opacity .3s}}.woocommerce-stock-activity-card.is-dimmed{opacity:.7}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__stock-quantity{background:#f0f0f0;color:#757575;padding:3px 8px;border-radius:3px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity{display:inline-flex;width:50px;margin-left:10px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input{border-radius:4px;height:36px}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]{-moz-appearance:textfield}.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-inner-spin-button,.woocommerce-stock-activity-card .woocommerce-stock-activity-card__edit-quantity input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.woocommerce-stock-activity-card .components-button{min-height:34px;padding:2px 10px;line-height:26px}.woocommerce-stock-activity-card .woocommerce-activity-card__title{font-size:15px;font-size:.9375rem}.woocommerce-stock-activity-card .woocommerce-activity-card__subtitle{color:#757575;font-size:12px;font-size:.75rem}.woocommerce-empty-activity-card{background:#f0f0f0;margin:20px;border-bottom:unset}.woocommerce-inbox-message{position:relative;color:#757575;background:#f0f0f0;border-radius:2px;font-size:13px;font-size:.8125rem;margin:0 0 24px;-ms-box-orient:horizontal}.woocommerce-inbox-message.banner{flex-direction:column}.woocommerce-inbox-message.banner img{width:100%;height:120px}.woocommerce-inbox-message.thumbnail{display:flex;flex-direction:row-reverse}.woocommerce-inbox-message.thumbnail img{width:128px;height:100%}.woocommerce-homepage-column .woocommerce-inbox-message{margin:20px 0}.woocommerce-inbox-message:not(.is-placeholder){border:1px solid #e0e0e0}.woocommerce-inbox-message.message-is-unread{background:#fff}.woocommerce-inbox-message .line{width:100%}.woocommerce-inbox-message .third-line{width:33%}.woocommerce-inbox-message .fifth-line{width:20%}.woocommerce-inbox-message .sixth-line{width:16%}.woocommerce-inbox-message__content .woocommerce-inbox-message__title{color:#1e1e1e;font-size:16px;font-size:1rem;font-style:normal;line-height:1.5;font-weight:400;margin:8px 0}.message-is-unread .woocommerce-inbox-message__content .woocommerce-inbox-message__title{font-weight:700}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title{margin-bottom:10px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;margin:5px 0}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__title>div{animation:none}}.woocommerce-inbox-message__content .woocommerce-inbox-message__date{color:#757575;font-size:12px;font-size:.75rem;margin-bottom:16px;font-style:normal;font-weight:400;line-height:16px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date{margin-bottom:10px}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent}.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__content .woocommerce-inbox-message__date>div{animation:none}}.woocommerce-inbox-message__text{color:#757575;font-style:normal;font-weight:400;font-size:14px;font-size:.875rem;line-height:20px}.woocommerce-inbox-message__text>p:first-child{margin-top:0}.woocommerce-inbox-message__text>p:last-child{margin-bottom:0}.is-placeholder .woocommerce-inbox-message__text>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;margin:5px 0}.is-placeholder .woocommerce-inbox-message__text>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__text>div{animation:none}}.woocommerce-inbox-message__actions{padding-top:16px;border-top:1px solid #e0e0e0}.woocommerce-inbox-message__actions>*+*{margin-right:.5em}.woocommerce-inbox-message__actions a,.woocommerce-inbox-message__actions button{cursor:pointer}.woocommerce-inbox-message__actions .components-dropdown{display:inline}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content{min-width:195px}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content ul{text-align:center}.woocommerce-inbox-message__actions .components-dropdown .components-popover__content li{margin:0;cursor:pointer}.is-placeholder .woocommerce-inbox-message__actions>div{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;float:right;height:28px;margin-left:8px}.is-placeholder .woocommerce-inbox-message__actions>div:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__actions>div{animation:none}}.woocommerce-inbox-dismiss-confirmation_modal{text-align:right}.woocommerce-inbox-dismiss-confirmation_wrapper p{font-size:16px;color:#757575}.woocommerce-inbox-dismiss-confirmation_wrapper .woocommerce-inbox-dismiss-confirmation_buttons{text-align:left}.woocommerce-inbox-dismiss-confirmation_wrapper .woocommerce-inbox-dismiss-confirmation_buttons button{margin-right:10px}.woocommerce-inbox-message__wrapper>div{padding:16px 24px}.is-placeholder .woocommerce-inbox-message__wrapper>div{padding:10px 24px;display:flow-root}.is-placeholder .woocommerce-inbox-message__image .banner-block{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;width:100%;height:120px}.is-placeholder .woocommerce-inbox-message__image .banner-block:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.is-placeholder .woocommerce-inbox-message__image .banner-block{animation:none}}#activity-panel-inbox{margin:0 24px}.woocommerce-layout__inbox-panel-header{padding:24px}.woocommerce-homepage-column .woocommerce-layout__inbox-panel-header{padding:0 24px}@media (-ms-high-contrast:active),(-ms-high-contrast:none){.woocommerce-admin-dismiss-dropdown{margin-top:0}.is-placeholder .woocommerce-inbox-message__wrapper{padding-bottom:10px}}.woocommerce-inbox-message-enter{opacity:0;max-height:0;transform:translateX(-50%)}.woocommerce-inbox-message-enter-active{transition:opacity .5s,transform .5s,max-height .5s}.woocommerce-inbox-message-enter-active,.woocommerce-inbox-message-exit{opacity:1;max-height:100vh;transform:translateX(0)}.woocommerce-inbox-message-exit-active{opacity:0;max-height:0;transform:translateX(-50%);transition:opacity .5s,transform .5s,max-height .5s}.components-guide.woocommerce__welcome-modal{max-width:517px;height:460px}.components-guide.woocommerce__welcome-modal .components-modal__header{height:0}.components-guide.woocommerce__welcome-modal .components-modal__header .components-button{color:#fff}.components-guide.woocommerce__welcome-modal .components-guide__container{margin-top:0}.components-guide.woocommerce__welcome-modal .components-guide__container .woocommerce__welcome-modal__page-content{padding:0 24px}.components-guide.woocommerce__welcome-modal .components-guide__container .woocommerce__welcome-modal__page-content .woocommerce__welcome-modal__page-content__header{font-size:24px;line-height:32px;margin:0 0 24px}.components-guide.woocommerce__welcome-modal .components-guide__container .woocommerce__welcome-modal__page-content .woocommerce__welcome-modal__page-content__body{font-size:16px;line-height:24px;margin:0 0 24px}.components-guide.woocommerce__welcome-modal .components-guide__footer{padding:0;margin:0 24px 24px;justify-content:flex-end;width:auto}.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__back-button,.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__finish-button,.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__forward-button{position:static;padding:0 16px;font-weight:500;font-size:14px;line-height:18px}.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__back-button,.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__forward-button{color:#007cba;color:var(--wp-admin-theme-color)}.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__finish-button,.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__forward-button{margin-right:10px}.components-guide.woocommerce__welcome-modal .components-guide__footer .components-guide__forward-button{box-shadow:inset 0 0 0 1px #007cba;box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color);outline:1px solid transparent}.components-guide.woocommerce__welcome-modal .fill-theme-color{fill:#007cba;fill:var(--wp-admin-theme-color)}.woocommerce-layout__activity-panel-header{height:50px;background:#e0e0e0;padding:16px;display:flex;justify-content:space-between;align-items:center}@media (min-width:783px){.woocommerce-layout__activity-panel-header{padding:16px 24px}}.woocommerce-layout__activity-panel-header h3{font-size:13px;font-weight:600;line-height:16px;margin:0;padding:0}.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):focus,.woocommerce-layout__activity-panel-header .woocommerce-ellipsis-menu__toggle.components-button:not(:disabled):not([aria-disabled=true]):hover{box-shadow:none;border-radius:10px;background:#ccc}.woocommerce-layout__inbox-title{color:#1e1e1e;display:flex;align-items:center}.woocommerce-layout__inbox-subtitle{color:#757575}.woocommerce-layout__inbox-badge{margin-right:6px;background-color:#757575;border-radius:13px;padding:0 6px;color:#fff;display:inline-block;text-align:center;vertical-align:top}.woocommerce-accordion-card .components-panel__body-title{margin:0;padding:1em 0}.woocommerce-accordion-card .components-panel__body-title .components-button{display:flex;flex-direction:row;width:100%;padding-right:24px;font-style:normal;font-weight:400;font-size:20px;line-height:28px;color:#1e1e1e}.woocommerce-accordion-card .components-panel__body-title .components-button:focus{box-shadow:unset;outline:unset}.woocommerce-accordion-card .components-panel__body-title .components-button .woocommerce-accordion-header{order:1;text-align:right;width:50%}.woocommerce-accordion-card .components-panel__body-title .components-button .woocommerce-accordion-header .woocommerce-accordion-title{vertical-align:bottom;margin-left:16px}.woocommerce-accordion-card .components-panel__body-title .components-button>span{order:2;width:50%;text-align:left}.woocommerce-accordion-card .components-panel__body-title .components-button>span .components-panel__arrow{width:30px;height:30px;vertical-align:text-top}.woocommerce-accordion-card .woocommerce-activity-card__actions{margin:0}.woocommerce-accordion-card .woocommerce-activity-card__actions .components-button{background:#f0f0f0;border-radius:12px;height:24px;padding-right:16px;width:65px}.woocommerce-accordion-card .woocommerce-activity-card{padding:20px var(--main-gap) var(--main-gap)}.woocommerce-accordion-card .woocommerce-activity-card__header{margin-bottom:8px}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link{display:flex;justify-content:space-between;align-items:center;height:50px;border-bottom:1px solid #f0f0f0;padding:16px 24px;padding:16px var(--main-gap);font-size:13px;font-weight:500;line-height:18px;margin:0;text-decoration:none}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link .gridicon{display:none}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:hover{background:#e0e0e0}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:active{background:#f0f0f0}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:focus{background:#e0e0e0;box-shadow:inset 0 0 0 1px #5b9dd9,inset 0 0 0 2px #e0e0e0}.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:active .gridicon,.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:focus .gridicon,.woocommerce-accordion-card .woocommerce-layout__activity-panel-outbound-link:hover .gridicon{display:initial}.woocommerce-accordion-card .woocommerce-layout__activity-panel-empty{border-top:1px solid #e0e0e0}.woocommerce-accordion-card .woocommerce-activity-card__button:focus{box-shadow:unset;outline:unset;border:1px solid #e0e0e0}.woocommerce-accordion-card .is-opened .components-panel__body-title{border-bottom:1px solid #e0e0e0}.woocommerce-accordion-card .woocommerce-empty-activity-card{background:unset;text-align:center;padding:12px var(--main-gap) 0}.woocommerce-accordion-card .woocommerce-empty-activity-card h4{color:#1e1e1e}.woocommerce-accordion-card .woocommerce-order-empty__success-icon{font-size:36px}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__header{margin-bottom:4px}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__header .woocommerce-activity-card__title.is-placeholder{width:45%}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__body>.is-placeholder{width:30%}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-activity-card__actions>.is-placeholder{height:24px;margin-top:4px;width:65px}.woocommerce-accordion-card .woocommerce-activity-card.woocommerce-order-activity-card .woocommerce-order-activity-card{cursor:pointer}.woocommerce-page #wpcontent,.woocommerce-page.woocommerce_page_wc-admin #wpbody-content{overflow-x:inherit!important}.woocommerce-homescreen{display:flex;max-width:1032px;margin:0 auto;justify-content:space-between;flex-direction:column}.woocommerce-homescreen .woocommerce-task-dashboard__container{width:100%;margin-bottom:24px}.woocommerce-homescreen.two-columns{flex-direction:row}.woocommerce-homescreen.two-columns .woocommerce-homescreen-column{width:calc(50% - 12px);margin:0}@media (max-width:782px){.woocommerce-homescreen.two-columns .woocommerce-homescreen-column{width:100%;position:inherit;top:auto}}.woocommerce-homescreen.two-columns .your-store-today{display:block}@media (max-width:782px){.woocommerce-homescreen.two-columns{flex-direction:column}.woocommerce-homescreen.two-columns .your-store-today{display:none}}@media (max-width:782px){.woocommerce-homescreen{margin-right:-16px;margin-left:-16px}}.woocommerce-homescreen-column{width:662px;top:100px;margin:0 auto;align-self:flex-start}.woocommerce-homescreen-column>div{margin-bottom:24px}@media (max-width:782px){.woocommerce-homescreen-column{width:100%;position:inherit;top:auto}}.woocommerce-homescreen-card .components-card__header.is-size-large,.woocommerce-homescreen-card .components-card__header.is-size-medium{min-height:63px;min-height:unset;display:-ms-grid;display:grid;-ms-grid-columns:auto 24px;grid-template-columns:auto 24px}.woocommerce-homescreen-card .components-card__header.is-size-large>*,.woocommerce-homescreen-card .components-card__header.is-size-medium>*{-ms-grid-row-align:center;align-self:center}.woocommerce-homescreen-card .components-card__body.is-size-large{padding:0}.woocommerce-homescreen-card .components-card__footer.is-size-large{padding:0 8px}#klarna-kp-banner,.woocommerce-layout__inbox-panel-header.your-store-today,.woocommerce-page:not(.woocommerce-embed-page) #klarna-banner{display:none}.woocommerce-dashboard__columns{display:-ms-grid;display:grid;-ms-grid-columns:calc(50% - 12px) calc(50% - 12px);grid-template-columns:calc(50% - 12px) calc(50% - 12px);grid-column-gap:24px}.woocommerce-dashboard__columns>div:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(2){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(3){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(4){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(5){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(6){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(7){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(8){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(9){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(10){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(11){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(12){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(13){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}.woocommerce-dashboard__columns>div:nth-child(14){-ms-grid-column:2;grid-column-start:2;-ms-grid-column-span:1;grid-column-end:3;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}@media (max-width:960px){.woocommerce-dashboard__columns{-ms-grid-columns:100%;grid-template-columns:100%}.woocommerce-dashboard__columns>div:first-child{-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:1;grid-row-start:1;-ms-grid-row-span:1;grid-row-end:2}.woocommerce-dashboard__columns>div:nth-child(2){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:2;grid-row-start:2;-ms-grid-row-span:1;grid-row-end:3}.woocommerce-dashboard__columns>div:nth-child(3){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:3;grid-row-start:3;-ms-grid-row-span:1;grid-row-end:4}.woocommerce-dashboard__columns>div:nth-child(4){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:4;grid-row-start:4;-ms-grid-row-span:1;grid-row-end:5}.woocommerce-dashboard__columns>div:nth-child(5){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:5;grid-row-start:5;-ms-grid-row-span:1;grid-row-end:6}.woocommerce-dashboard__columns>div:nth-child(6){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:6;grid-row-start:6;-ms-grid-row-span:1;grid-row-end:7}.woocommerce-dashboard__columns>div:nth-child(7){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:7;grid-row-start:7;-ms-grid-row-span:1;grid-row-end:8}.woocommerce-dashboard__columns>div:nth-child(8){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:8;grid-row-start:8;-ms-grid-row-span:1;grid-row-end:9}.woocommerce-dashboard__columns>div:nth-child(9){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:9;grid-row-start:9;-ms-grid-row-span:1;grid-row-end:10}.woocommerce-dashboard__columns>div:nth-child(10){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:10;grid-row-start:10;-ms-grid-row-span:1;grid-row-end:11}.woocommerce-dashboard__columns>div:nth-child(11){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:11;grid-row-start:11;-ms-grid-row-span:1;grid-row-end:12}.woocommerce-dashboard__columns>div:nth-child(12){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:12;grid-row-start:12;-ms-grid-row-span:1;grid-row-end:13}.woocommerce-dashboard__columns>div:nth-child(13){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:13;grid-row-start:13;-ms-grid-row-span:1;grid-row-end:14}.woocommerce-dashboard__columns>div:nth-child(14){-ms-grid-column:1;grid-column-start:1;-ms-grid-column-span:1;grid-column-end:2;-ms-grid-row:14;grid-row-start:14;-ms-grid-row-span:1;grid-row-end:15}}.woocommerce-dashboard__widget{display:flex;align-items:center;text-align:center}.woocommerce-dashboard__widget-item{flex:1}.woocommerce-dashboard-section__add-more{margin:0 auto;width:84px;padding:0 24px 24px}.woocommerce-dashboard-section__add-more .components-popover__content{padding:0 16px 8px}.woocommerce-dashboard-section__add-more>button svg{fill:#757575}.woocommerce-dashboard-section__add-more-choices{display:flex;justify-content:center}.woocommerce-dashboard-section__add-more-btn{display:flex;flex-direction:column;align-items:center;padding:16px;margin:8px}.woocommerce-dashboard-section__add-more-btn.components-button{height:auto}.woocommerce-dashboard-section__add-more-btn .dashicons-arrow-right-alt{transform:rotate(45deg)}.woocommerce-dashboard-section__add-more-btn-title{color:#757575;padding-top:8px}.woocommerce-dashboard-section-controls{border-top:1px solid #f0f0f0;padding-top:8px}.woocommerce-dashboard-section-controls .dashicon{margin:0 0 0 8px;vertical-align:bottom}.woocommerce-dashboard-section-controls .woocommerce-ellipsis-menu__item{padding-bottom:10px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-card__header.is-size-large{padding-bottom:12px}.woocommerce-task-dashboard__body .woocommerce-task-dashboard__container .woocommerce-task-card .components-card__header.is-size-large .woocommerce-card__menu{margin-top:8px}.woocommerce-store-management-links__card-body.is-size-custom{padding:24px 0 8px}.woocommerce-quick-links__category{display:flex;flex-flow:row wrap;margin-bottom:8px}.woocommerce-quick-links__category .woocommerce-quick-links__category-header{margin:0 24px 8px;text-transform:uppercase;color:#757575;line-height:16px;font-size:11px;flex:1 100%}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-quick-links__item{display:flex;flex:1 50%}.woocommerce-quick-links__item:hover{background-color:#f0f0f0}.woocommerce-quick-links__item .woocommerce-quick-links__item-link{width:100%;display:flex;align-items:center;text-decoration:none;padding:16px 24px 16px 27px}.woocommerce-quick-links__item .woocommerce-quick-links__item-link .woocommerce-quick-links__item-link__icon{fill:#007cba;fill:var(--wp-admin-theme-color)}.woocommerce-quick-links__item .woocommerce-quick-links__item-link .woocommerce-quick-links__item-link__text{margin-right:16px;flex:1;line-height:16px;font-size:13px}.woocommerce-homescreen.two-columns .woocommerce-quick-links__item{flex:1 100%} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/37.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/37.style.css new file mode 100644 index 0000000..d921b6f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/37.style.css @@ -0,0 +1 @@ +.woocommerce-leaderboard.woocommerce-empty-content{margin-bottom:24px}.woocommerce-leaderboard .woocommerce-card__body{padding:0}.woocommerce-leaderboard .woocommerce-table__table{margin-bottom:0}.woocommerce-leaderboard .woocommerce-table__table tr:last-child{border-bottom-style:none}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-dashboard__dashboard-leaderboards .components-base-control__field{width:100%}.woocommerce-dashboard__dashboard-leaderboards .components-select-control__input{border:1px solid #ccc;height:34px}.woocommerce-dashboard__dashboard-leaderboards .woocommerce-dashboard__dashboard-leaderboards__select .components-base-control__field{padding:0 12px 4px}.woocommerce-dashboard__dashboard-leaderboards .woocommerce-dashboard__dashboard-leaderboards__select .woocommerce-ellipsis-menu__title{padding:10px 0 14px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/37.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/37.style.rtl.css new file mode 100644 index 0000000..d921b6f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/37.style.rtl.css @@ -0,0 +1 @@ +.woocommerce-leaderboard.woocommerce-empty-content{margin-bottom:24px}.woocommerce-leaderboard .woocommerce-card__body{padding:0}.woocommerce-leaderboard .woocommerce-table__table{margin-bottom:0}.woocommerce-leaderboard .woocommerce-table__table tr:last-child{border-bottom-style:none}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-dashboard__dashboard-leaderboards .components-base-control__field{width:100%}.woocommerce-dashboard__dashboard-leaderboards .components-select-control__input{border:1px solid #ccc;height:34px}.woocommerce-dashboard__dashboard-leaderboards .woocommerce-dashboard__dashboard-leaderboards__select .components-base-control__field{padding:0 12px 4px}.woocommerce-dashboard__dashboard-leaderboards .woocommerce-dashboard__dashboard-leaderboards__select .woocommerce-ellipsis-menu__title{padding:10px 0 14px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/39.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/39.style.css new file mode 100644 index 0000000..e72a3bf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/39.style.css @@ -0,0 +1 @@ +.woocommerce-marketing-overview{max-width:1032px;margin:0 auto}.woocommerce-marketing-overview .components-card{margin-bottom:24px}.woocommerce-marketing-installed-extensions-card__item{display:flex;align-items:center;padding:18px 24px}.woocommerce-marketing-installed-extensions-card__item h4{font-weight:400;font-size:16px;margin:0 0 5px;color:#1e1e1e}.woocommerce-marketing-installed-extensions-card__item p{color:#757575;margin:0}.woocommerce-marketing-installed-extensions-card__item:not(:last-child){border-bottom:1px solid #e0e0e0}.woocommerce-marketing-installed-extensions-card__item-text-and-actions{display:flex;flex-wrap:wrap;align-items:center;flex-grow:2;min-width:0}@media (min-width:601px){.woocommerce-marketing-installed-extensions-card__item-text-and-actions{flex-wrap:nowrap}}@media (min-width:601px){.woocommerce-marketing-installed-extensions-card__item-actions{text-align:right;white-space:nowrap;padding-left:25px}}@media (min-width:961px){.woocommerce-marketing-installed-extensions-card__item-description{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:550px}}.woocommerce-marketing-installed-extensions-card__item-links{margin:0;padding:0}.woocommerce-marketing-installed-extensions-card__item-links li{display:inline-block;margin:0 25px 0 0}@media (min-width:601px){.woocommerce-marketing-installed-extensions-card__item-links li{margin:0 0 0 30px}}.woocommerce-marketing-installed-extensions-card__item-links a{font-weight:600;color:#007cba!important;color:var(--wp-admin-theme-color)!important;text-decoration:none;font-size:14px}.woocommerce-marketing-installed-extensions-card .woocommerce-admin-marketing-product-icon{align-self:flex-start;margin-right:14px;margin-top:2px}.woocommerce-marketing-installed-extensions-card__item-text{min-width:0;flex-grow:2;margin:0 0 10px;width:100%}@media (min-width:601px){.woocommerce-marketing-installed-extensions-card__item-text{margin:0;width:auto}}.components-button.woocommerce-admin-marketing-button:not([disabled]){border-color:#007cba!important;border-color:var(--wp-admin-theme-color)!important;color:#007cba!important;color:var(--wp-admin-theme-color)!important}.woocommerce-admin-marketing-card .components-card__header .woocommerce-admin-marketing-card-subtitle{font-weight:400;margin-top:4px;color:#757575}.woocommerce-admin-marketing-product-icon{position:relative;overflow:hidden;width:36px;height:36px;border-radius:8px;background:#f0f0f0;color:#f0f0f0}.woocommerce-admin-marketing-product-icon svg{width:36px;height:36px}.woocommerce-marketing-slider,.woocommerce-marketing-slider>div{display:block;width:100%;overflow:hidden}.woocommerce-marketing-slider>div{white-space:normal;position:relative;height:100%}.woocommerce-marketing-slider__slide{top:0;left:0;width:100%;transition:transform .3s ease-in;position:relative}.woocommerce-marketing-slider .slide-enter,.woocommerce-marketing-slider .slide-exit{position:absolute}.woocommerce-marketing-slider.animate-right .slide-enter{transform:translateX(-100%)}.woocommerce-marketing-slider.animate-right .slide-enter-active,.woocommerce-marketing-slider.animate-right .slide-exit{transform:translateX(0)}.woocommerce-marketing-slider.animate-left .slide-enter,.woocommerce-marketing-slider.animate-right .slide-exit-active{transform:translateX(100%)}.woocommerce-marketing-slider.animate-left .slide-enter-active,.woocommerce-marketing-slider.animate-left .slide-exit{transform:translateX(0)}.woocommerce-marketing-slider.animate-left .slide-exit-active{transform:translateX(-100%)}@media screen and (prefers-reduced-motion:reduce){.woocommerce-marketing-slider .slide-enter-active,.woocommerce-marketing-slider .slide-exit-active{transition:none!important}}.woocommerce-marketing-recommended-extensions-card .components-card__body{padding:12px}.woocommerce-marketing-recommended-extensions-card .components-spinner{float:none;margin:45px auto 50px;display:block}.woocommerce-marketing-recommended-extensions-card__items{display:flex;flex-wrap:wrap}@media (min-width:601px){.woocommerce-marketing-recommended-extensions-card__items>a{width:50%}}@media (min-width:961px){.woocommerce-marketing-recommended-extensions-card__items>a{width:33.3%}.woocommerce-marketing-recommended-extensions-card__items--count-1>a{width:100%}.woocommerce-marketing-recommended-extensions-card__items--count-2>a{width:50%}.woocommerce-marketing-recommended-extensions-card__items--count-4>a{width:25%}}.woocommerce-marketing-recommended-extensions-item{display:block;padding:12px;text-decoration:none;position:relative}.woocommerce-marketing-recommended-extensions-item h4{color:#1e1e1e;margin:-2px 0 3px;font-size:16px;line-height:1.3;transition:color .2s ease}.woocommerce-marketing-recommended-extensions-item p{color:#757575;margin:0}.woocommerce-marketing-recommended-extensions-item:hover h4{color:#007cba;color:var(--wp-admin-theme-color)}.woocommerce-marketing-recommended-extensions-item:hover p{color:#1e1e1e}.woocommerce-marketing-recommended-extensions-item__text{padding-left:46px}.woocommerce-marketing-recommended-extensions-item .woocommerce-admin-marketing-product-icon{position:absolute;top:12px;left:12px}.woocommerce-marketing-knowledgebase-card .woocommerce-marketing-slider{margin:0 0 14px}.woocommerce-marketing-knowledgebase-card .woocommerce-pagination{justify-content:flex-start;flex-direction:row}.woocommerce-marketing-knowledgebase-card__page{width:100%;display:flex}@media (max-width:960px){.woocommerce-marketing-knowledgebase-card__page{display:block}}.woocommerce-marketing-knowledgebase-card .components-spinner{float:none;margin:45px auto 50px;display:block}.woocommerce-marketing-knowledgebase-card__post{display:flex;flex-wrap:wrap;width:100%;text-decoration:none}.woocommerce-marketing-knowledgebase-card__post:not(:last-child){margin-bottom:16px}@media (min-width:961px){.woocommerce-marketing-knowledgebase-card__post{flex-wrap:nowrap;width:50%}.woocommerce-marketing-knowledgebase-card__post:not(:last-child){margin-bottom:0;padding-right:16px}}.woocommerce-marketing-knowledgebase-card__post-img{width:100%;padding-bottom:52%;overflow:hidden;position:relative;flex:none;border-radius:3px}@media (min-width:961px){.woocommerce-marketing-knowledgebase-card__post-img{width:144px;height:103px;margin-right:16px;padding-bottom:0}}.woocommerce-marketing-knowledgebase-card__post-img img{position:absolute;top:0;right:0;display:block;width:100%}@media (min-width:961px){.woocommerce-marketing-knowledgebase-card__post-img img{position:absolute;top:0;right:0;height:100%;width:auto}}.woocommerce-marketing-knowledgebase-card__post-text{margin:10px 0 0}@media (min-width:961px){.woocommerce-marketing-knowledgebase-card__post-text{margin:0}}.woocommerce-marketing-knowledgebase-card__post h3{margin-top:0;margin-bottom:6px;font-size:16px;line-height:24px;font-weight:600;white-space:normal;color:#1e1e1e;transition:color .2s ease}.woocommerce-marketing-knowledgebase-card__post:hover h3{color:#007cba;color:var(--wp-admin-theme-color)}.woocommerce-marketing-knowledgebase-card__post-meta{display:flex;justify-content:flex-start;align-items:center;font-size:12px;line-height:17px;color:#757575;margin:0;padding:0;height:17px}.woocommerce-marketing-knowledgebase-card__post-meta .woocommerce-gravatar{margin:1px 0 0 5px}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-marketing-overview-welcome-card{position:relative}.woocommerce-marketing-overview-welcome-card .components-card__body{display:flex;justify-content:center;align-items:center;flex-wrap:wrap;padding:22px}@media (min-width:601px){.woocommerce-marketing-overview-welcome-card .components-card__body{flex-wrap:nowrap}}@media (min-width:961px){.woocommerce-marketing-overview-welcome-card .components-card__body{padding:32px 108px}}.woocommerce-marketing-overview-welcome-card__hide-button{display:flex;align-items:center;padding:8px;margin:0;border:none;background:none;color:#757575;overflow:hidden;border-radius:4px;position:absolute;top:10px;right:10px}.woocommerce-marketing-overview-welcome-card__hide-button svg{fill:currentColor;outline:none}.woocommerce-marketing-overview-welcome-card__hide-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover{background-color:#fff;color:#1e1e1e;box-shadow:inset 0 0 0 1px #ccc,inset 0 0 0 2px #fff,0 1px 1px rgba(30,30,30,.2)}.woocommerce-marketing-overview-welcome-card__hide-button:not(:disabled):not([aria-disabled=true]):not(.is-default):active{outline:none;background-color:#fff;color:#1e1e1e;box-shadow:inset 0 0 0 1px #ccc,inset 0 0 0 2px #fff}.woocommerce-marketing-overview-welcome-card__hide-button:disabled:focus,.woocommerce-marketing-overview-welcome-card__hide-button[aria-disabled=true]:focus{box-shadow:none}.woocommerce-marketing-overview-welcome-card h3{font-size:20px;line-height:26px;font-weight:400;text-align:center;margin:1em 0 0}@media (min-width:601px){.woocommerce-marketing-overview-welcome-card h3{text-align:left;margin:0 0 0 20px}}@media (min-width:961px){.woocommerce-marketing-overview-welcome-card h3{font-size:24px;line-height:32px}}.woocommerce-marketing-overview-welcome-card img{width:231px;flex:none} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/39.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/39.style.rtl.css new file mode 100644 index 0000000..ec235bf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/39.style.rtl.css @@ -0,0 +1 @@ +.woocommerce-marketing-overview{max-width:1032px;margin:0 auto}.woocommerce-marketing-overview .components-card{margin-bottom:24px}.woocommerce-marketing-installed-extensions-card__item{display:flex;align-items:center;padding:18px 24px}.woocommerce-marketing-installed-extensions-card__item h4{font-weight:400;font-size:16px;margin:0 0 5px;color:#1e1e1e}.woocommerce-marketing-installed-extensions-card__item p{color:#757575;margin:0}.woocommerce-marketing-installed-extensions-card__item:not(:last-child){border-bottom:1px solid #e0e0e0}.woocommerce-marketing-installed-extensions-card__item-text-and-actions{display:flex;flex-wrap:wrap;align-items:center;flex-grow:2;min-width:0}@media (min-width:601px){.woocommerce-marketing-installed-extensions-card__item-text-and-actions{flex-wrap:nowrap}}@media (min-width:601px){.woocommerce-marketing-installed-extensions-card__item-actions{text-align:left;white-space:nowrap;padding-right:25px}}@media (min-width:961px){.woocommerce-marketing-installed-extensions-card__item-description{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:550px}}.woocommerce-marketing-installed-extensions-card__item-links{margin:0;padding:0}.woocommerce-marketing-installed-extensions-card__item-links li{display:inline-block;margin:0 0 0 25px}@media (min-width:601px){.woocommerce-marketing-installed-extensions-card__item-links li{margin:0 30px 0 0}}.woocommerce-marketing-installed-extensions-card__item-links a{font-weight:600;color:#007cba!important;color:var(--wp-admin-theme-color)!important;text-decoration:none;font-size:14px}.woocommerce-marketing-installed-extensions-card .woocommerce-admin-marketing-product-icon{align-self:flex-start;margin-left:14px;margin-top:2px}.woocommerce-marketing-installed-extensions-card__item-text{min-width:0;flex-grow:2;margin:0 0 10px;width:100%}@media (min-width:601px){.woocommerce-marketing-installed-extensions-card__item-text{margin:0;width:auto}}.components-button.woocommerce-admin-marketing-button:not([disabled]){border-color:#007cba!important;border-color:var(--wp-admin-theme-color)!important;color:#007cba!important;color:var(--wp-admin-theme-color)!important}.woocommerce-admin-marketing-card .components-card__header .woocommerce-admin-marketing-card-subtitle{font-weight:400;margin-top:4px;color:#757575}.woocommerce-admin-marketing-product-icon{position:relative;overflow:hidden;width:36px;height:36px;border-radius:8px;background:#f0f0f0;color:#f0f0f0}.woocommerce-admin-marketing-product-icon svg{width:36px;height:36px}.woocommerce-marketing-slider,.woocommerce-marketing-slider>div{display:block;width:100%;overflow:hidden}.woocommerce-marketing-slider>div{white-space:normal;position:relative;height:100%}.woocommerce-marketing-slider__slide{top:0;right:0;width:100%;transition:transform .3s ease-in;position:relative}.woocommerce-marketing-slider .slide-enter,.woocommerce-marketing-slider .slide-exit{position:absolute}.woocommerce-marketing-slider.animate-right .slide-enter{transform:translateX(100%)}.woocommerce-marketing-slider.animate-right .slide-enter-active,.woocommerce-marketing-slider.animate-right .slide-exit{transform:translateX(0)}.woocommerce-marketing-slider.animate-left .slide-enter,.woocommerce-marketing-slider.animate-right .slide-exit-active{transform:translateX(-100%)}.woocommerce-marketing-slider.animate-left .slide-enter-active,.woocommerce-marketing-slider.animate-left .slide-exit{transform:translateX(0)}.woocommerce-marketing-slider.animate-left .slide-exit-active{transform:translateX(100%)}@media screen and (prefers-reduced-motion:reduce){.woocommerce-marketing-slider .slide-enter-active,.woocommerce-marketing-slider .slide-exit-active{transition:none!important}}.woocommerce-marketing-recommended-extensions-card .components-card__body{padding:12px}.woocommerce-marketing-recommended-extensions-card .components-spinner{float:none;margin:45px auto 50px;display:block}.woocommerce-marketing-recommended-extensions-card__items{display:flex;flex-wrap:wrap}@media (min-width:601px){.woocommerce-marketing-recommended-extensions-card__items>a{width:50%}}@media (min-width:961px){.woocommerce-marketing-recommended-extensions-card__items>a{width:33.3%}.woocommerce-marketing-recommended-extensions-card__items--count-1>a{width:100%}.woocommerce-marketing-recommended-extensions-card__items--count-2>a{width:50%}.woocommerce-marketing-recommended-extensions-card__items--count-4>a{width:25%}}.woocommerce-marketing-recommended-extensions-item{display:block;padding:12px;text-decoration:none;position:relative}.woocommerce-marketing-recommended-extensions-item h4{color:#1e1e1e;margin:-2px 0 3px;font-size:16px;line-height:1.3;transition:color .2s ease}.woocommerce-marketing-recommended-extensions-item p{color:#757575;margin:0}.woocommerce-marketing-recommended-extensions-item:hover h4{color:#007cba;color:var(--wp-admin-theme-color)}.woocommerce-marketing-recommended-extensions-item:hover p{color:#1e1e1e}.woocommerce-marketing-recommended-extensions-item__text{padding-right:46px}.woocommerce-marketing-recommended-extensions-item .woocommerce-admin-marketing-product-icon{position:absolute;top:12px;right:12px}.woocommerce-marketing-knowledgebase-card .woocommerce-marketing-slider{margin:0 0 14px}.woocommerce-marketing-knowledgebase-card .woocommerce-pagination{justify-content:flex-start;flex-direction:row}.woocommerce-marketing-knowledgebase-card__page{width:100%;display:flex}@media (max-width:960px){.woocommerce-marketing-knowledgebase-card__page{display:block}}.woocommerce-marketing-knowledgebase-card .components-spinner{float:none;margin:45px auto 50px;display:block}.woocommerce-marketing-knowledgebase-card__post{display:flex;flex-wrap:wrap;width:100%;text-decoration:none}.woocommerce-marketing-knowledgebase-card__post:not(:last-child){margin-bottom:16px}@media (min-width:961px){.woocommerce-marketing-knowledgebase-card__post{flex-wrap:nowrap;width:50%}.woocommerce-marketing-knowledgebase-card__post:not(:last-child){margin-bottom:0;padding-left:16px}}.woocommerce-marketing-knowledgebase-card__post-img{width:100%;padding-bottom:52%;overflow:hidden;position:relative;flex:none;border-radius:3px}@media (min-width:961px){.woocommerce-marketing-knowledgebase-card__post-img{width:144px;height:103px;margin-left:16px;padding-bottom:0}}.woocommerce-marketing-knowledgebase-card__post-img img{position:absolute;top:0;left:0;display:block;width:100%}@media (min-width:961px){.woocommerce-marketing-knowledgebase-card__post-img img{position:absolute;top:0;left:0;height:100%;width:auto}}.woocommerce-marketing-knowledgebase-card__post-text{margin:10px 0 0}@media (min-width:961px){.woocommerce-marketing-knowledgebase-card__post-text{margin:0}}.woocommerce-marketing-knowledgebase-card__post h3{margin-top:0;margin-bottom:6px;font-size:16px;line-height:24px;font-weight:600;white-space:normal;color:#1e1e1e;transition:color .2s ease}.woocommerce-marketing-knowledgebase-card__post:hover h3{color:#007cba;color:var(--wp-admin-theme-color)}.woocommerce-marketing-knowledgebase-card__post-meta{display:flex;justify-content:flex-start;align-items:center;font-size:12px;line-height:17px;color:#757575;margin:0;padding:0;height:17px}.woocommerce-marketing-knowledgebase-card__post-meta .woocommerce-gravatar{margin:1px 5px 0 0}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-marketing-overview-welcome-card{position:relative}.woocommerce-marketing-overview-welcome-card .components-card__body{display:flex;justify-content:center;align-items:center;flex-wrap:wrap;padding:22px}@media (min-width:601px){.woocommerce-marketing-overview-welcome-card .components-card__body{flex-wrap:nowrap}}@media (min-width:961px){.woocommerce-marketing-overview-welcome-card .components-card__body{padding:32px 108px}}.woocommerce-marketing-overview-welcome-card__hide-button{display:flex;align-items:center;padding:8px;margin:0;border:none;background:none;color:#757575;overflow:hidden;border-radius:4px;position:absolute;top:10px;left:10px}.woocommerce-marketing-overview-welcome-card__hide-button svg{fill:currentColor;outline:none}.woocommerce-marketing-overview-welcome-card__hide-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover{background-color:#fff;color:#1e1e1e;box-shadow:inset 0 0 0 1px #ccc,inset 0 0 0 2px #fff,0 1px 1px rgba(30,30,30,.2)}.woocommerce-marketing-overview-welcome-card__hide-button:not(:disabled):not([aria-disabled=true]):not(.is-default):active{outline:none;background-color:#fff;color:#1e1e1e;box-shadow:inset 0 0 0 1px #ccc,inset 0 0 0 2px #fff}.woocommerce-marketing-overview-welcome-card__hide-button:disabled:focus,.woocommerce-marketing-overview-welcome-card__hide-button[aria-disabled=true]:focus{box-shadow:none}.woocommerce-marketing-overview-welcome-card h3{font-size:20px;line-height:26px;font-weight:400;text-align:center;margin:1em 0 0}@media (min-width:601px){.woocommerce-marketing-overview-welcome-card h3{text-align:right;margin:0 20px 0 0}}@media (min-width:961px){.woocommerce-marketing-overview-welcome-card h3{font-size:24px;line-height:32px}}.woocommerce-marketing-overview-welcome-card img{width:231px;flex:none} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/4.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/4.js new file mode 100644 index 0000000..13c3d15 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/4.js @@ -0,0 +1,2 @@ +/*! For license information please see 4.js.LICENSE.txt */ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[4],{778:function(e,t,n){e.exports=function(){"use strict";var e=Object.hasOwnProperty,t=Object.setPrototypeOf,n=Object.isFrozen,r=Object.freeze,o=Object.seal,i=Object.create,a="undefined"!=typeof Reflect&&Reflect,l=a.apply,c=a.construct;l||(l=function(e,t,n){return e.apply(t,n)}),r||(r=function(e){return e}),o||(o=function(e){return e}),c||(c=function(e,t){return new(Function.prototype.bind.apply(e,[null].concat(function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t1?n-1:0),o=1;o/gm),F=o(/^data-[\-\w.\u00B7-\uFFFF]/),C=o(/^aria-[\-\w]+$/),H=o(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),z=o(/^(?:\w+script|data):/i),I=o(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),U="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function j(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t0&&void 0!==arguments[0]?arguments[0]:P(),n=function(t){return e(t)};if(n.version="2.2.0",n.removed=[],!t||!t.document||9!==t.document.nodeType)return n.isSupported=!1,n;var o=t.document,i=t.document,a=t.DocumentFragment,l=t.HTMLTemplateElement,c=t.Node,s=t.NodeFilter,T=t.NamedNodeMap,B=void 0===T?t.NamedNodeMap||t.MozNamedAttrMap:T,G=t.Text,q=t.Comment,K=t.DOMParser,V=t.trustedTypes;if("function"==typeof l){var Y=i.createElement("template");Y.content&&Y.content.ownerDocument&&(i=Y.content.ownerDocument)}var J=W(V,o),X=J&&De?J.createHTML(""):"",$=i,Z=$.implementation,Q=$.createNodeIterator,ee=$.getElementsByTagName,te=$.createDocumentFragment,ne=o.importNode,re={};try{re=x(i).documentMode?i.documentMode:{}}catch(e){}var oe={};n.isSupported=Z&&void 0!==Z.createHTMLDocument&&9!==re;var ie=O,ae=R,le=F,ce=C,se=z,ue=I,de=H,pe=null,fe=A({},[].concat(j(S),j(_),j(k),j(w),j(E))),me=null,ye=A({},[].concat(j(D),j(L),j(M),j(N))),he=null,ge=null,ve=!0,be=!0,Te=!1,Ae=!1,xe=!1,Se=!1,_e=!1,ke=!1,we=!1,Ee=!0,De=!1,Le=!0,Me=!0,Ne=!1,Oe={},Re=A({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","plaintext","script","style","svg","template","thead","title","video","xmp"]),Fe=null,Ce=A({},["audio","video","img","source","image","track"]),He=null,ze=A({},["alt","class","for","id","label","name","pattern","placeholder","summary","title","value","style","xmlns"]),Ie=null,Ue=i.createElement("form"),je=function(e){Ie&&Ie===e||(e&&"object"===(void 0===e?"undefined":U(e))||(e={}),e=x(e),pe="ALLOWED_TAGS"in e?A({},e.ALLOWED_TAGS):fe,me="ALLOWED_ATTR"in e?A({},e.ALLOWED_ATTR):ye,He="ADD_URI_SAFE_ATTR"in e?A(x(ze),e.ADD_URI_SAFE_ATTR):ze,Fe="ADD_DATA_URI_TAGS"in e?A(x(Ce),e.ADD_DATA_URI_TAGS):Ce,he="FORBID_TAGS"in e?A({},e.FORBID_TAGS):{},ge="FORBID_ATTR"in e?A({},e.FORBID_ATTR):{},Oe="USE_PROFILES"in e&&e.USE_PROFILES,ve=!1!==e.ALLOW_ARIA_ATTR,be=!1!==e.ALLOW_DATA_ATTR,Te=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Ae=e.SAFE_FOR_TEMPLATES||!1,xe=e.WHOLE_DOCUMENT||!1,ke=e.RETURN_DOM||!1,we=e.RETURN_DOM_FRAGMENT||!1,Ee=!1!==e.RETURN_DOM_IMPORT,De=e.RETURN_TRUSTED_TYPE||!1,_e=e.FORCE_BODY||!1,Le=!1!==e.SANITIZE_DOM,Me=!1!==e.KEEP_CONTENT,Ne=e.IN_PLACE||!1,de=e.ALLOWED_URI_REGEXP||de,Ae&&(be=!1),we&&(ke=!0),Oe&&(pe=A({},[].concat(j(E))),me=[],!0===Oe.html&&(A(pe,S),A(me,D)),!0===Oe.svg&&(A(pe,_),A(me,L),A(me,N)),!0===Oe.svgFilters&&(A(pe,k),A(me,L),A(me,N)),!0===Oe.mathMl&&(A(pe,w),A(me,M),A(me,N))),e.ADD_TAGS&&(pe===fe&&(pe=x(pe)),A(pe,e.ADD_TAGS)),e.ADD_ATTR&&(me===ye&&(me=x(me)),A(me,e.ADD_ATTR)),e.ADD_URI_SAFE_ATTR&&A(He,e.ADD_URI_SAFE_ATTR),Me&&(pe["#text"]=!0),xe&&A(pe,["html","head","body"]),pe.table&&(A(pe,["tbody"]),delete he.tbody),r&&r(e),Ie=e)},Pe=function(e){p(n.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){e.outerHTML=X}},We=function(e,t){try{p(n.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){p(n.removed,{attribute:null,from:t})}t.removeAttribute(e)},Be=function(e){var t=void 0,n=void 0;if(_e)e=""+e;else{var r=m(e,/^[\r\n\t ]+/);n=r&&r[0]}var o=J?J.createHTML(e):e;try{t=(new K).parseFromString(o,"text/html")}catch(e){}if(!t||!t.documentElement){var a=(t=Z.createHTMLDocument("")).body;a.parentNode.removeChild(a.parentNode.firstElementChild),a.outerHTML=o}return e&&n&&t.body.insertBefore(i.createTextNode(n),t.body.childNodes[0]||null),ee.call(t,xe?"html":"body")[0]},Ge=function(e){return Q.call(e.ownerDocument||e,e,s.SHOW_ELEMENT|s.SHOW_COMMENT|s.SHOW_TEXT,(function(){return s.FILTER_ACCEPT}),!1)},qe=function(e){return!(e instanceof G||e instanceof q||"string"==typeof e.nodeName&&"string"==typeof e.textContent&&"function"==typeof e.removeChild&&e.attributes instanceof B&&"function"==typeof e.removeAttribute&&"function"==typeof e.setAttribute&&"string"==typeof e.namespaceURI)},Ke=function(e){return"object"===(void 0===c?"undefined":U(c))?e instanceof c:e&&"object"===(void 0===e?"undefined":U(e))&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName},Ve=function(e,t,r){oe[e]&&u(oe[e],(function(e){e.call(n,t,r,Ie)}))},Ye=function(e){var t=void 0;if(Ve("beforeSanitizeElements",e,null),qe(e))return Pe(e),!0;if(m(e.nodeName,/[\u0080-\uFFFF]/))return Pe(e),!0;var r=f(e.nodeName);if(Ve("uponSanitizeElement",e,{tagName:r,allowedTags:pe}),("svg"===r||"math"===r)&&0!==e.querySelectorAll("p, br").length)return Pe(e),!0;if(!Ke(e.firstElementChild)&&(!Ke(e.content)||!Ke(e.content.firstElementChild))&&v(/<[!/\w]/g,e.innerHTML)&&v(/<[!/\w]/g,e.textContent))return Pe(e),!0;if(!pe[r]||he[r]){if(Me&&!Re[r]&&"function"==typeof e.insertAdjacentHTML)try{var o=e.innerHTML;e.insertAdjacentHTML("AfterEnd",J?J.createHTML(o):o)}catch(e){}return Pe(e),!0}return"noscript"!==r&&"noembed"!==r||!v(/<\/no(script|embed)/i,e.innerHTML)?(Ae&&3===e.nodeType&&(t=e.textContent,t=y(t,ie," "),t=y(t,ae," "),e.textContent!==t&&(p(n.removed,{element:e.cloneNode()}),e.textContent=t)),Ve("afterSanitizeElements",e,null),!1):(Pe(e),!0)},Je=function(e,t,n){if(Le&&("id"===t||"name"===t)&&(n in i||n in Ue))return!1;if(be&&v(le,t));else if(ve&&v(ce,t));else{if(!me[t]||ge[t])return!1;if(He[t]);else if(v(de,y(n,ue,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==h(n,"data:")||!Fe[e])if(Te&&!v(se,y(n,ue,"")));else if(n)return!1}return!0},Xe=function(e){var t=void 0,r=void 0,o=void 0,i=void 0;Ve("beforeSanitizeAttributes",e,null);var a=e.attributes;if(a){var l={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:me};for(i=a.length;i--;){var c=t=a[i],s=c.name,u=c.namespaceURI;if(r=g(t.value),o=f(s),l.attrName=o,l.attrValue=r,l.keepAttr=!0,l.forceKeepAttr=void 0,Ve("uponSanitizeAttribute",e,l),r=l.attrValue,!l.forceKeepAttr&&(We(s,e),l.keepAttr))if(v(/\/>/i,r))We(s,e);else{Ae&&(r=y(r,ie," "),r=y(r,ae," "));var p=e.nodeName.toLowerCase();if(Je(p,o,r))try{u?e.setAttributeNS(u,s,r):e.setAttribute(s,r),d(n.removed)}catch(e){}}}Ve("afterSanitizeAttributes",e,null)}},$e=function e(t){var n=void 0,r=Ge(t);for(Ve("beforeSanitizeShadowDOM",t,null);n=r.nextNode();)Ve("uponSanitizeShadowNode",n,null),Ye(n)||(n.content instanceof a&&e(n.content),Xe(n));Ve("afterSanitizeShadowDOM",t,null)};return n.sanitize=function(e,r){var i=void 0,l=void 0,s=void 0,u=void 0,d=void 0;if(e||(e="\x3c!--\x3e"),"string"!=typeof e&&!Ke(e)){if("function"!=typeof e.toString)throw b("toString is not a function");if("string"!=typeof(e=e.toString()))throw b("dirty is not a string, aborting")}if(!n.isSupported){if("object"===U(t.toStaticHTML)||"function"==typeof t.toStaticHTML){if("string"==typeof e)return t.toStaticHTML(e);if(Ke(e))return t.toStaticHTML(e.outerHTML)}return e}if(Se||je(r),n.removed=[],"string"==typeof e&&(Ne=!1),Ne);else if(e instanceof c)1===(l=(i=Be("\x3c!----\x3e")).ownerDocument.importNode(e,!0)).nodeType&&"BODY"===l.nodeName||"HTML"===l.nodeName?i=l:i.appendChild(l);else{if(!ke&&!Ae&&!xe&&-1===e.indexOf("<"))return J&&De?J.createHTML(e):e;if(!(i=Be(e)))return ke?null:X}i&&_e&&Pe(i.firstChild);for(var p=Ge(Ne?e:i);s=p.nextNode();)3===s.nodeType&&s===u||Ye(s)||(s.content instanceof a&&$e(s.content),Xe(s),u=s);if(u=null,Ne)return e;if(ke){if(we)for(d=te.call(i.ownerDocument);i.firstChild;)d.appendChild(i.firstChild);else d=i;return Ee&&(d=ne.call(o,d,!0)),d}var f=xe?i.outerHTML:i.innerHTML;return Ae&&(f=y(f,ie," "),f=y(f,ae," ")),J&&De?J.createHTML(f):f},n.setConfig=function(e){je(e),Se=!0},n.clearConfig=function(){Ie=null,Se=!1},n.isValidAttribute=function(e,t,n){Ie||je({});var r=f(e),o=f(t);return Je(r,o,n)},n.addHook=function(e,t){"function"==typeof t&&(oe[e]=oe[e]||[],p(oe[e],t))},n.removeHook=function(e){oe[e]&&d(oe[e])},n.removeHooks=function(e){oe[e]&&(oe[e]=[])},n.removeAllHooks=function(){oe={}},n}()}()}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/4.js.LICENSE.txt b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/4.js.LICENSE.txt new file mode 100644 index 0000000..f3cfed1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/4.js.LICENSE.txt @@ -0,0 +1 @@ +/*! @license DOMPurify | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.0.8/LICENSE */ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/47.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/47.style.css new file mode 100644 index 0000000..d1cbc15 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/47.style.css @@ -0,0 +1 @@ +.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-product-wizard__product-types-label{display:inline-block;margin-right:4px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox{display:flex;align-items:center;min-height:64px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox .components-button{padding:0;height:auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .components-base-control__field,.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .components-checkbox-control__label{display:flex;width:100%;align-items:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .components-checkbox-control__label .woocommerce-pill{margin-left:auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .components-popover .components-popover__content{min-width:360px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__product-types-pricing-toggle.woocommerce-profile-wizard__checkbox{display:flex;align-items:center;justify-content:flex-end;color:#949494}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__product-types-pricing-toggle.woocommerce-profile-wizard__checkbox label{display:inline-flex;align-items:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__product-types-pricing-toggle.woocommerce-profile-wizard__checkbox .components-form-toggle{display:inline-flex;margin-left:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__card-actions .components-button.is-primary{margin-top:16px}.woocommerce-profile-wizard__store-details .components-popover .components-popover__content{min-width:360px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container>.woocommerce-profile-wizard__themes-tab-panel{margin-bottom:24px}@media (min-width:783px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container>.woocommerce-profile-wizard__themes-tab-panel{max-width:810px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container>.woocommerce-profile-wizard__themes-tab-panel .woocommerce-profile-wizard__themes{display:-ms-grid;display:grid;grid-gap:24px;-ms-grid-columns:1fr 1fr;grid-template-columns:1fr 1fr}}.woocommerce-profile-wizard__themes-tab-panel .components-tab-panel__tabs{display:flex;justify-content:space-between;background:#fff;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:3px;margin-top:24px;margin-bottom:24px}.woocommerce-profile-wizard__themes-tab-panel .components-tab-panel__tabs button{border:0;color:#646970;display:flex;align-items:center;justify-content:center;background:transparent;height:48px;width:100%;font-size:14px;font-size:.875rem;font-weight:500;outline:none;padding:0 24px}p.woocommerce-profile-wizard__themes-skip-this-step{text-align:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card{overflow:hidden}@media (min-width:783px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card{margin:0}}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-card__body{padding:0;display:flex;flex-direction:column;height:100%}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-image{width:100%;height:300px;background-size:cover}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-name{margin-top:auto;margin-bottom:8px;font-size:24px;font-size:1.5rem;font-weight:400}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-name svg{max-width:18px;height:18px;margin-left:8px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-name svg path{fill:#d63638}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-details{padding:16px;display:flex;flex-direction:column;margin-top:auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-status{margin:0;font-size:14px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-learn-more{display:inline-block}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-actions button.components-button{margin:13px auto 0;display:block;width:auto;min-width:106px;height:40px;line-height:1}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-actions button.components-button.is-primary{color:#fff}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-actions button.components-button.is-tertiary{font-size:14px;font-weight:500}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card{margin:0;position:relative}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .woocommerce-card__body{height:100%}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card.is-uploading .components-drop-zone__provider{min-height:382px}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-drop-zone__provider{display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:2px;background:#f6f6f6;border:1px dashed #b0b5b8}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload{flex:1;width:100%}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload>.components-button{flex:1;flex-direction:column;justify-content:center;margin:0;width:100%;height:100%;min-height:380px}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload>.components-button>.gridicon{width:48px;height:48px}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload>.components-button>.gridicon path{fill:#50575d}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload>.components-button .dashicons-upload{display:none}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .woocommerce-theme-uploader__title{margin:8px 0;font-size:24px;font-size:1.5rem;font-weight:400}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card p{font-size:14px;font-size:.875rem;margin:0}.woocommerce-theme-preview{position:fixed;top:0;left:0;width:100%;height:100%;max-width:100%!important;display:flex;flex-direction:column}.woocommerce-theme-preview .woocommerce-theme-preview__toolbar{background:#fff;flex-direction:row;display:flex;height:60px;border-bottom:1px solid #dcdcde;padding-left:16px;padding-right:16px;align-items:center}.woocommerce-theme-preview .woocommerce-theme-preview__toolbar .is-button.is-primary{height:40px;margin:0}@media (max-width:782px){.woocommerce-theme-preview .woocommerce-theme-preview__toolbar .is-button.is-primary{margin-left:auto}}.woocommerce-theme-preview .woocommerce-theme-preview__theme-name{padding-left:16px;color:#1d2327;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:50%}.woocommerce-theme-preview .woocommerce-theme-preview__close{padding:0 16px 0 0;color:#646970}.woocommerce-theme-preview .woocommerce-theme-preview__devices{margin-left:auto;margin-right:16px}.woocommerce-theme-preview .woocommerce-theme-preview__devices .woocommerce-theme-preview__device{padding:12px;color:#646970;margin:0;border-radius:50%}.woocommerce-theme-preview .woocommerce-theme-preview__devices .woocommerce-theme-preview__device.is-selected,.woocommerce-theme-preview .woocommerce-theme-preview__devices .woocommerce-theme-preview__device:focus{background:#646970;color:#fff}@media (max-width:782px){.woocommerce-theme-preview .woocommerce-theme-preview__devices{display:none}}.woocommerce-theme-preview .woocommerce-web-preview{flex:1;padding:40px 16px;overflow:scroll}.woocommerce-theme-preview .woocommerce-web-preview .woocommerce-web-preview__iframe-wrapper{height:100%;border-radius:3px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);overflow:hidden;margin:0 auto}.woocommerce-theme-preview .woocommerce-web-preview .woocommerce-web-preview__iframe-wrapper iframe{display:block}.woocommerce-theme-preview .woocommerce-web-preview.is-mobile .woocommerce-web-preview__iframe-wrapper{max-width:360px}.woocommerce-theme-preview .woocommerce-web-preview.is-tablet .woocommerce-web-preview__iframe-wrapper{max-width:768px}.woocommerce-theme-preview .woocommerce-web-preview.is-desktop{width:100%;padding:0}.woocommerce-theme-preview .woocommerce-web-preview.is-desktop .woocommerce-web-preview__iframe-wrapper{border-radius:0;box-shadow:none}.woocommerce-theme-preview-active{overflow:hidden}.woocommerce-theme-preview-active .woocommerce-profile-wizard__header{display:none}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__step-header{text-align:center;margin:16px 0 24px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__step-header h2{margin-bottom:4px;color:#1e1e1e}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__step-header p{color:#757575;display:flex;align-items:center;justify-content:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__step-header p .woocommerce-profile-wizard__tooltip-icon{height:16px}.woocommerce-profile-wizard__body .woocommerce-card{margin-top:16px;color:#757575;text-align:left}.woocommerce-profile-wizard__body .woocommerce-card h1,.woocommerce-profile-wizard__body .woocommerce-card h2,.woocommerce-profile-wizard__body .woocommerce-card h3{color:#1e1e1e}.woocommerce-profile-wizard__body .woocommerce-card button.is-button{display:flex;margin:8px auto 0;width:310px;max-width:100%;justify-content:center}.woocommerce-profile-wizard__body .woocommerce-card .business-competitors .woocommerce-select-control__listbox{max-height:unset}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__card-actions{text-align:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__card-actions .components-button{margin-top:12px}.woocommerce-profile-wizard__body .woocommerce-card+.woocommerce-profile-wizard__card-help-text{font-size:14px;color:#949494;text-align:center;margin-top:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__header{height:60px;border-bottom:1px solid #dcdcde;display:flex;align-items:center;justify-content:center;background:#fff}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__header-subtitle{font-weight:400;text-align:center;color:#757575;font-size:16px;line-height:24px;margin-top:8px;margin-bottom:32px;margin-right:8px;display:flex;justify-content:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__intro-paragraph{margin-top:5px;margin-bottom:18px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container{margin-top:36px;margin-left:auto;margin-right:auto;text-align:left}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container>*{max-width:504px;margin-left:auto;margin-right:auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container.benefits{text-align:center}@media (max-width:782px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container{padding-left:16px;padding-right:16px;margin-bottom:72px;margin-top:0}}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .components-popover__content>div{padding:16px 24px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .woocommerce-card~p{color:#949494;text-align:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .woocommerce-profile-wizard__footer{margin:34px auto;display:flex;justify-content:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .woocommerce-profile-wizard__footer-link{display:flex;text-decoration:none}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .woocommerce-profile-wizard__footnote p{color:#757575;text-align:left;margin-bottom:12px}.woocommerce-profile-wizard__body #woocommerce-layout__primary{text-align:center;margin:0;width:100%}.woocommerce-profile-wizard__body .woocommerce-layout .woocommerce-layout__main{padding-right:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__error{display:block;padding:16px;font-size:12px;color:#d63638}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit{display:flex}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit svg:first-child{width:24px;min-width:24px;margin-right:24px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit .woocommerce-profile-wizard__benefit-title{font-size:16px;font-weight:400;margin-top:0;margin-bottom:8px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit .woocommerce-profile-wizard__benefit-content{margin-left:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit .woocommerce-profile-wizard__benefit-content p{padding-bottom:16px;margin-top:0;border-bottom:1px solid #dcdcde;font-size:14px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit .woocommerce-profile-wizard__benefit-toggle{padding-top:36px;margin-left:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit:last-child p{border-bottom:0;margin-bottom:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefits{display:-ms-grid;display:grid;grid-gap:16px;grid-auto-columns:1fr;grid-auto-flow:column}@media (max-width:960px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefits{justify-items:center;grid-auto-flow:row}}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefits-logo{display:block;margin:0 auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit-card{display:flex;flex-direction:column;background:#f6f7f7;width:100%;max-width:295px;overflow:hidden;text-align:left}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit-card .woocommerce-profile-wizard__benefit-card-title{font-size:16px;font-weight:600;margin-top:0;margin-bottom:8px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit-card .woocommerce-profile-wizard__benefit-card-content{padding:24px 32px 32px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit-card .woocommerce-profile-wizard__benefit-card-content p{padding:0;margin:0;font-size:14px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__business-extension{background:#f6f6f6;height:100%;padding:12px 4px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__business-extension img{box-sizing:unset;max-width:100px;max-height:50%;vertical-align:middle}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking .woocommerce-profile-wizard__tracking-checkbox{margin-top:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking .components-form-toggle{display:none}@media (max-width:782px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking{display:flex;flex-direction:row-reverse;align-items:center;justify-content:flex-end}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking .components-form-toggle{display:inline-block}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking .components-checkbox-control__input{display:none}}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__client{margin:8px 0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group{margin:-16px -16px 0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox{margin-top:0;margin-bottom:0;position:relative;padding:12px 24px;min-height:46px;border-bottom:1px solid #f0f0f0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox .components-base-control{position:relative}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox .components-base-control__field{margin:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox label.components-checkbox-control__label{font-size:16px;margin-left:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox .components-base-control__help{margin-left:48px;font-style:normal;color:#949494;font-size:14px;line-height:20px;margin-top:3px;margin-bottom:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox:last-of-type:after{display:none}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__text{margin:0 16px 10px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group svg.dashicon.components-checkbox-control__checked{left:1px;top:-1px}@media (max-width:600px){.woocommerce-profile-wizard__body svg.dashicon.components-checkbox-control__checked{left:-2px;top:-1px;width:21px;height:21px}}.woocommerce-profile-wizard__body .woocommerce-select-control__control{margin:16px 0;padding-right:40px;box-shadow:0 2px 6px rgba(0,0,0,.05)}.woocommerce-profile-wizard__body .woocommerce-select-control__control.is-active{border-color:#007cba;border-color:var(--wp-admin-theme-color)}.woocommerce-profile-wizard__body .woocommerce-select-control__control .components-base-control__label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - 56px)}.woocommerce-profile-wizard__body .woocommerce-select-control__control:after{display:block;pointer-events:none;cursor:pointer;position:absolute;float:right;line-height:56px;font-family:dashicons,sans-serif;font-size:20px;content:"\f140";z-index:1;height:24px;width:24px;margin-top:0;top:0;right:16px;bottom:16px;color:#000}.woocommerce-profile-wizard__body #wpadminbar{display:none}.woocommerce-profile-wizard__body #wpbody{padding-top:0}.woocommerce-profile-wizard__benefits-card.woocommerce-card{display:inline-block;max-width:100%;text-align:center}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-card__body{padding:48px}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-profile-wizard__card-actions{margin-top:16px;display:inline-flex}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-profile-wizard__card-actions .components-button{width:auto}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-profile-wizard__card-actions .components-button:first-child{margin-right:16px}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-profile-wizard__benefits-install-notice{margin-top:24px;margin-bottom:0;font-size:14px;color:#787c82}.woocommerce-profile-wizard__plugins-card .woocommerce-profile-wizard__plugins-actions{text-align:left;margin-left:44px}.woocommerce-profile-wizard__plugins-card .woocommerce-profile-wizard__plugins-actions button.is-button{height:40px;min-width:auto;display:initial;margin:16px 12px 0 0}.woocommerce-profile-wizard__header svg>g{transform:none}@media (max-width:782px){.woocommerce-profile-wizard__header{position:fixed;z-index:999;width:100%;bottom:0;border-top:1px solid #dcdcde;border-bottom:none}}.woocommerce-profile-wizard__header .woocommerce-stepper{margin:0 16px;width:100%}.woocommerce-profile-wizard__header .woocommerce-stepper__steps{margin:0}.woocommerce-profile-wizard__submit{margin-bottom:12px}.woocommerce-profile-wizard__tooltip-icon{color:#50575e;display:flex;align-items:center;margin-left:4px;cursor:help}.components-modal__frame.woocommerce-profile-wizard__usage-modal{width:600px;max-width:100%}.components-modal__frame.woocommerce-profile-wizard__usage-modal .components-modal__header{border-bottom:0;margin-bottom:0}.components-modal__frame.woocommerce-profile-wizard__usage-modal .woocommerce-profile-wizard__usage-wrapper{flex-grow:1;display:flex;flex-direction:column}.components-modal__frame.woocommerce-profile-wizard__usage-modal .woocommerce-profile-wizard__usage-wrapper a{color:#50575e}.components-modal__frame.woocommerce-profile-wizard__usage-modal .woocommerce-profile-wizard__usage-wrapper button.is-primary{align-self:flex-end}.woocommerce-business-extensions{margin-left:-16px;margin-right:-16px;padding:16px 24px;border-top:1px solid #f0f0f0;border-bottom:1px solid #f0f0f0;display:flex;align-items:center}.woocommerce-business-extensions label{display:flex;align-items:center}.woocommerce-business-extensions .components-checkbox-control__input-container{margin-right:16px}.woocommerce-business-extensions .woocommerce-business-extensions__label-subtext{display:block;color:#949494}.woocommerce-business-extensions .woocommerce-business-extensions__popover-wrapper{margin-left:auto}.woocommerce-business-extensions .woocommerce-business-extensions__benefits{padding:4px;display:-ms-grid;display:grid;-ms-grid-columns:1fr 1fr;grid-template-columns:1fr 1fr;max-width:100%;min-width:580px;font-size:14px}@media (max-width:782px){.woocommerce-business-extensions .woocommerce-business-extensions__benefits{-ms-grid-columns:1fr;grid-template-columns:1fr;min-width:300px}}.woocommerce-business-extensions .woocommerce-business-extensions__benefits .woocommerce-business-extensions__benefit{padding:10px;font-size:14px;display:inline-flex}.woocommerce-business-extensions .woocommerce-business-extensions__benefits .woocommerce-business-extensions__benefit i{color:#007cba;color:var(--wp-admin-theme-color);margin-right:16px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/47.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/47.style.rtl.css new file mode 100644 index 0000000..7d630e7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/47.style.rtl.css @@ -0,0 +1 @@ +.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-product-wizard__product-types-label{display:inline-block;margin-left:4px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox{display:flex;align-items:center;min-height:64px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox .components-button{padding:0;height:auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .components-base-control__field,.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .components-checkbox-control__label{display:flex;width:100%;align-items:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .components-checkbox-control__label .woocommerce-pill{margin-right:auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .components-popover .components-popover__content{min-width:360px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__product-types-pricing-toggle.woocommerce-profile-wizard__checkbox{display:flex;align-items:center;justify-content:flex-end;color:#949494}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__product-types-pricing-toggle.woocommerce-profile-wizard__checkbox label{display:inline-flex;align-items:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__product-types-pricing-toggle.woocommerce-profile-wizard__checkbox .components-form-toggle{display:inline-flex;margin-right:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__product-types .woocommerce-profile-wizard__card-actions .components-button.is-primary{margin-top:16px}.woocommerce-profile-wizard__store-details .components-popover .components-popover__content{min-width:360px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container>.woocommerce-profile-wizard__themes-tab-panel{margin-bottom:24px}@media (min-width:783px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container>.woocommerce-profile-wizard__themes-tab-panel{max-width:810px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container>.woocommerce-profile-wizard__themes-tab-panel .woocommerce-profile-wizard__themes{display:-ms-grid;display:grid;grid-gap:24px;-ms-grid-columns:1fr 1fr;grid-template-columns:1fr 1fr}}.woocommerce-profile-wizard__themes-tab-panel .components-tab-panel__tabs{display:flex;justify-content:space-between;background:#fff;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border-radius:3px;margin-top:24px;margin-bottom:24px}.woocommerce-profile-wizard__themes-tab-panel .components-tab-panel__tabs button{border:0;color:#646970;display:flex;align-items:center;justify-content:center;background:transparent;height:48px;width:100%;font-size:14px;font-size:.875rem;font-weight:500;outline:none;padding:0 24px}p.woocommerce-profile-wizard__themes-skip-this-step{text-align:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card{overflow:hidden}@media (min-width:783px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card{margin:0}}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-card__body{padding:0;display:flex;flex-direction:column;height:100%}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-image{width:100%;height:300px;background-size:cover}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-name{margin-top:auto;margin-bottom:8px;font-size:24px;font-size:1.5rem;font-weight:400}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-name svg{max-width:18px;height:18px;margin-right:8px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-name svg path{fill:#d63638}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-details{padding:16px;display:flex;flex-direction:column;margin-top:auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-status{margin:0;font-size:14px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-learn-more{display:inline-block}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-actions button.components-button{margin:13px auto 0;display:block;width:auto;min-width:106px;height:40px;line-height:1}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-actions button.components-button.is-primary{color:#fff}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__theme.woocommerce-card .woocommerce-profile-wizard__theme-actions button.components-button.is-tertiary{font-size:14px;font-weight:500}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card{margin:0;position:relative}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .woocommerce-card__body{height:100%}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card.is-uploading .components-drop-zone__provider{min-height:382px}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-drop-zone__provider{display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:2px;background:#f6f6f6;border:1px dashed #b0b5b8}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload{flex:1;width:100%}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload>.components-button{flex:1;flex-direction:column;justify-content:center;margin:0;width:100%;height:100%;min-height:380px}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload>.components-button>.gridicon{width:48px;height:48px}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload>.components-button>.gridicon path{fill:#50575d}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .components-form-file-upload>.components-button .dashicons-upload{display:none}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card .woocommerce-theme-uploader__title{margin:8px 0;font-size:24px;font-size:1.5rem;font-weight:400}.woocommerce-profile-wizard__body .woocommerce-theme-uploader.woocommerce-card p{font-size:14px;font-size:.875rem;margin:0}.woocommerce-theme-preview{position:fixed;top:0;right:0;width:100%;height:100%;max-width:100%!important;display:flex;flex-direction:column}.woocommerce-theme-preview .woocommerce-theme-preview__toolbar{background:#fff;flex-direction:row;display:flex;height:60px;border-bottom:1px solid #dcdcde;padding-right:16px;padding-left:16px;align-items:center}.woocommerce-theme-preview .woocommerce-theme-preview__toolbar .is-button.is-primary{height:40px;margin:0}@media (max-width:782px){.woocommerce-theme-preview .woocommerce-theme-preview__toolbar .is-button.is-primary{margin-right:auto}}.woocommerce-theme-preview .woocommerce-theme-preview__theme-name{padding-right:16px;color:#1d2327;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:50%}.woocommerce-theme-preview .woocommerce-theme-preview__close{padding:0 0 0 16px;color:#646970}.woocommerce-theme-preview .woocommerce-theme-preview__devices{margin-right:auto;margin-left:16px}.woocommerce-theme-preview .woocommerce-theme-preview__devices .woocommerce-theme-preview__device{padding:12px;color:#646970;margin:0;border-radius:50%}.woocommerce-theme-preview .woocommerce-theme-preview__devices .woocommerce-theme-preview__device.is-selected,.woocommerce-theme-preview .woocommerce-theme-preview__devices .woocommerce-theme-preview__device:focus{background:#646970;color:#fff}@media (max-width:782px){.woocommerce-theme-preview .woocommerce-theme-preview__devices{display:none}}.woocommerce-theme-preview .woocommerce-web-preview{flex:1;padding:40px 16px;overflow:scroll}.woocommerce-theme-preview .woocommerce-web-preview .woocommerce-web-preview__iframe-wrapper{height:100%;border-radius:3px;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);overflow:hidden;margin:0 auto}.woocommerce-theme-preview .woocommerce-web-preview .woocommerce-web-preview__iframe-wrapper iframe{display:block}.woocommerce-theme-preview .woocommerce-web-preview.is-mobile .woocommerce-web-preview__iframe-wrapper{max-width:360px}.woocommerce-theme-preview .woocommerce-web-preview.is-tablet .woocommerce-web-preview__iframe-wrapper{max-width:768px}.woocommerce-theme-preview .woocommerce-web-preview.is-desktop{width:100%;padding:0}.woocommerce-theme-preview .woocommerce-web-preview.is-desktop .woocommerce-web-preview__iframe-wrapper{border-radius:0;box-shadow:none}.woocommerce-theme-preview-active{overflow:hidden}.woocommerce-theme-preview-active .woocommerce-profile-wizard__header{display:none}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__step-header{text-align:center;margin:16px 0 24px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__step-header h2{margin-bottom:4px;color:#1e1e1e}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__step-header p{color:#757575;display:flex;align-items:center;justify-content:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__step-header p .woocommerce-profile-wizard__tooltip-icon{height:16px}.woocommerce-profile-wizard__body .woocommerce-card{margin-top:16px;color:#757575;text-align:right}.woocommerce-profile-wizard__body .woocommerce-card h1,.woocommerce-profile-wizard__body .woocommerce-card h2,.woocommerce-profile-wizard__body .woocommerce-card h3{color:#1e1e1e}.woocommerce-profile-wizard__body .woocommerce-card button.is-button{display:flex;margin:8px auto 0;width:310px;max-width:100%;justify-content:center}.woocommerce-profile-wizard__body .woocommerce-card .business-competitors .woocommerce-select-control__listbox{max-height:unset}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__card-actions{text-align:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__card-actions .components-button{margin-top:12px}.woocommerce-profile-wizard__body .woocommerce-card+.woocommerce-profile-wizard__card-help-text{font-size:14px;color:#949494;text-align:center;margin-top:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__header{height:60px;border-bottom:1px solid #dcdcde;display:flex;align-items:center;justify-content:center;background:#fff}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__header-subtitle{font-weight:400;text-align:center;color:#757575;font-size:16px;line-height:24px;margin-top:8px;margin-bottom:32px;margin-left:8px;display:flex;justify-content:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__intro-paragraph{margin-top:5px;margin-bottom:18px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container{margin-top:36px;margin-right:auto;margin-left:auto;text-align:right}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container>*{max-width:504px;margin-right:auto;margin-left:auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container.benefits{text-align:center}@media (max-width:782px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container{padding-right:16px;padding-left:16px;margin-bottom:72px;margin-top:0}}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .components-popover__content>div{padding:16px 24px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .woocommerce-card~p{color:#949494;text-align:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .woocommerce-profile-wizard__footer{margin:34px auto;display:flex;justify-content:center}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .woocommerce-profile-wizard__footer-link{display:flex;text-decoration:none}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__container .woocommerce-profile-wizard__footnote p{color:#757575;text-align:right;margin-bottom:12px}.woocommerce-profile-wizard__body #woocommerce-layout__primary{text-align:center;margin:0;width:100%}.woocommerce-profile-wizard__body .woocommerce-layout .woocommerce-layout__main{padding-left:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__error{display:block;padding:16px;font-size:12px;color:#d63638}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit{display:flex}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit svg:first-child{width:24px;min-width:24px;margin-left:24px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit .woocommerce-profile-wizard__benefit-title{font-size:16px;font-weight:400;margin-top:0;margin-bottom:8px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit .woocommerce-profile-wizard__benefit-content{margin-right:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit .woocommerce-profile-wizard__benefit-content p{padding-bottom:16px;margin-top:0;border-bottom:1px solid #dcdcde;font-size:14px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit .woocommerce-profile-wizard__benefit-toggle{padding-top:36px;margin-right:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit:last-child p{border-bottom:0;margin-bottom:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefits{display:-ms-grid;display:grid;grid-gap:16px;grid-auto-columns:1fr;grid-auto-flow:column}@media (max-width:960px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefits{justify-items:center;grid-auto-flow:row}}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefits-logo{display:block;margin:0 auto}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit-card{display:flex;flex-direction:column;background:#f6f7f7;width:100%;max-width:295px;overflow:hidden;text-align:right}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit-card .woocommerce-profile-wizard__benefit-card-title{font-size:16px;font-weight:600;margin-top:0;margin-bottom:8px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit-card .woocommerce-profile-wizard__benefit-card-content{padding:24px 32px 32px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__benefit-card .woocommerce-profile-wizard__benefit-card-content p{padding:0;margin:0;font-size:14px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__business-extension{background:#f6f6f6;height:100%;padding:12px 4px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__business-extension img{box-sizing:unset;max-width:100px;max-height:50%;vertical-align:middle}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking .woocommerce-profile-wizard__tracking-checkbox{margin-top:16px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking .components-form-toggle{display:none}@media (max-width:782px){.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking{display:flex;flex-direction:row-reverse;align-items:center;justify-content:flex-end}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking .components-form-toggle{display:inline-block}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__tracking .components-checkbox-control__input{display:none}}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__client{margin:8px 0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group{margin:-16px -16px 0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox{margin-top:0;margin-bottom:0;position:relative;padding:12px 24px;min-height:46px;border-bottom:1px solid #f0f0f0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox .components-base-control{position:relative}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox .components-base-control__field{margin:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox label.components-checkbox-control__label{font-size:16px;margin-right:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox .components-base-control__help{margin-right:48px;font-style:normal;color:#949494;font-size:14px;line-height:20px;margin-top:3px;margin-bottom:0}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__checkbox:last-of-type:after{display:none}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group .woocommerce-profile-wizard__text{margin:0 16px 10px}.woocommerce-profile-wizard__body .woocommerce-profile-wizard__checkbox-group svg.dashicon.components-checkbox-control__checked{right:1px;top:-1px}@media (max-width:600px){.woocommerce-profile-wizard__body svg.dashicon.components-checkbox-control__checked{right:-2px;top:-1px;width:21px;height:21px}}.woocommerce-profile-wizard__body .woocommerce-select-control__control{margin:16px 0;padding-left:40px;box-shadow:0 2px 6px rgba(0,0,0,.05)}.woocommerce-profile-wizard__body .woocommerce-select-control__control.is-active{border-color:#007cba;border-color:var(--wp-admin-theme-color)}.woocommerce-profile-wizard__body .woocommerce-select-control__control .components-base-control__label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - 56px)}.woocommerce-profile-wizard__body .woocommerce-select-control__control:after{display:block;pointer-events:none;cursor:pointer;position:absolute;float:left;line-height:56px;font-family:dashicons,sans-serif;font-size:20px;content:"\f140";z-index:1;height:24px;width:24px;margin-top:0;top:0;left:16px;bottom:16px;color:#000}.woocommerce-profile-wizard__body #wpadminbar{display:none}.woocommerce-profile-wizard__body #wpbody{padding-top:0}.woocommerce-profile-wizard__benefits-card.woocommerce-card{display:inline-block;max-width:100%;text-align:center}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-card__body{padding:48px}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-profile-wizard__card-actions{margin-top:16px;display:inline-flex}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-profile-wizard__card-actions .components-button{width:auto}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-profile-wizard__card-actions .components-button:first-child{margin-left:16px}.woocommerce-profile-wizard__benefits-card.woocommerce-card .woocommerce-profile-wizard__benefits-install-notice{margin-top:24px;margin-bottom:0;font-size:14px;color:#787c82}.woocommerce-profile-wizard__plugins-card .woocommerce-profile-wizard__plugins-actions{text-align:right;margin-right:44px}.woocommerce-profile-wizard__plugins-card .woocommerce-profile-wizard__plugins-actions button.is-button{height:40px;min-width:auto;display:initial;margin:16px 0 0 12px}.woocommerce-profile-wizard__header svg>g{transform:none}@media (max-width:782px){.woocommerce-profile-wizard__header{position:fixed;z-index:999;width:100%;bottom:0;border-top:1px solid #dcdcde;border-bottom:none}}.woocommerce-profile-wizard__header .woocommerce-stepper{margin:0 16px;width:100%}.woocommerce-profile-wizard__header .woocommerce-stepper__steps{margin:0}.woocommerce-profile-wizard__submit{margin-bottom:12px}.woocommerce-profile-wizard__tooltip-icon{color:#50575e;display:flex;align-items:center;margin-right:4px;cursor:help}.components-modal__frame.woocommerce-profile-wizard__usage-modal{width:600px;max-width:100%}.components-modal__frame.woocommerce-profile-wizard__usage-modal .components-modal__header{border-bottom:0;margin-bottom:0}.components-modal__frame.woocommerce-profile-wizard__usage-modal .woocommerce-profile-wizard__usage-wrapper{flex-grow:1;display:flex;flex-direction:column}.components-modal__frame.woocommerce-profile-wizard__usage-modal .woocommerce-profile-wizard__usage-wrapper a{color:#50575e}.components-modal__frame.woocommerce-profile-wizard__usage-modal .woocommerce-profile-wizard__usage-wrapper button.is-primary{align-self:flex-end}.woocommerce-business-extensions{margin-right:-16px;margin-left:-16px;padding:16px 24px;border-top:1px solid #f0f0f0;border-bottom:1px solid #f0f0f0;display:flex;align-items:center}.woocommerce-business-extensions label{display:flex;align-items:center}.woocommerce-business-extensions .components-checkbox-control__input-container{margin-left:16px}.woocommerce-business-extensions .woocommerce-business-extensions__label-subtext{display:block;color:#949494}.woocommerce-business-extensions .woocommerce-business-extensions__popover-wrapper{margin-right:auto}.woocommerce-business-extensions .woocommerce-business-extensions__benefits{padding:4px;display:-ms-grid;display:grid;-ms-grid-columns:1fr 1fr;grid-template-columns:1fr 1fr;max-width:100%;min-width:580px;font-size:14px}@media (max-width:782px){.woocommerce-business-extensions .woocommerce-business-extensions__benefits{-ms-grid-columns:1fr;grid-template-columns:1fr;min-width:300px}}.woocommerce-business-extensions .woocommerce-business-extensions__benefits .woocommerce-business-extensions__benefit{padding:10px;font-size:14px;display:inline-flex}.woocommerce-business-extensions .woocommerce-business-extensions__benefits .woocommerce-business-extensions__benefit i{color:#007cba;color:var(--wp-admin-theme-color);margin-left:16px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/48.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/48.style.css new file mode 100644 index 0000000..5a1ce7e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/48.style.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-store-alerts{position:relative;margin:0 0 40px;margin-right:var(--large-gap);padding:24px;border:0;box-shadow:0 0 8px -2px rgba(0,0,0,.3)}.woocommerce-store-alerts:before{content:"";position:absolute;top:0;left:0;width:4px;height:100%;background:transparent}.woocommerce-store-alerts .woocommerce-card__header{padding:0;border:0;margin-bottom:12px}.woocommerce-store-alerts .woocommerce-card__title{display:inline-flex}.woocommerce-store-alerts .woocommerce-card__title svg{margin-right:6px}.woocommerce-store-alerts .woocommerce-card__body{padding:0}.woocommerce-store-alerts a.components-button{min-height:36px;padding:4px 16px}@media (max-width:782px){.woocommerce-store-alerts a.components-button{min-height:36px;font-size:16px;line-height:1.625;padding:5px 16px}}.woocommerce-store-alerts a.components-button+.components-button{margin-left:10px}.woocommerce-store-alerts a.components-button.is-button{color:#757575}@media (max-width:782px){.woocommerce-store-alerts{margin-bottom:24px;padding:16px}.woocommerce-store-alerts .woocommerce-card__header{display:flex;flex-direction:column-reverse;align-items:flex-start}}.woocommerce-embed-page .woocommerce-store-alerts{margin:40px 20px 20px}@media (max-width:782px){.woocommerce-embed-page .woocommerce-store-alerts{margin-top:24px}}.is-alert-error:before{background-color:#dc3232}.is-alert-error .woocommerce-card__title svg{color:#dc3232}.is-alert-update:before{background-color:#11a0d2}.is-alert-update .woocommerce-card__title svg{color:#11a0d2}.woocommerce-store-alerts__message{margin-bottom:16px}.woocommerce-store-alerts__pagination{display:inline-flex;align-items:center;border:1px solid #b5bfc9;border-radius:4px;background:#f0f2f4;margin-left:16px;min-width:120px}.woocommerce-store-alerts__pagination .components-button{padding:4px/*!rtl:ignore*/}.rtl .woocommerce-store-alerts__pagination .components-button .dashicons-arrow-left-alt2,.rtl .woocommerce-store-alerts__pagination .components-button .dashicons-arrow-right-alt2{transform:scaleX(-1)}.woocommerce-store-alerts__pagination .woocommerce-store-alerts__pagination-label{padding:5px 12px;border-color:#b5bfc9;border-style:solid;border-width:0 1px;flex:1 1}@media (max-width:782px){.woocommerce-store-alerts__pagination{margin-left:0;margin-bottom:14px}.woocommerce-store-alerts__pagination .woocommerce-store-alerts__pagination-label{text-align:center}}.woocommerce-store-alerts__pagination button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.woocommerce-store-alerts__pagination button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.woocommerce-store-alerts.is-loading:before{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent}.woocommerce-store-alerts.is-loading:before:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-store-alerts.is-loading:before{animation:none}}.woocommerce-store-alerts.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-store-alerts.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-store-alerts.is-loading .is-placeholder{animation:none}}.woocommerce-store-alerts.is-loading .woocommerce-card__title .is-placeholder{width:340px;height:20px}.woocommerce-store-alerts.is-loading .woocommerce-card__action .is-placeholder{min-width:120px;height:30px}.woocommerce-store-alerts.is-loading .woocommerce-store-alerts__message .is-placeholder:first-child{width:75%}.woocommerce-store-alerts.is-loading .woocommerce-store-alerts__message .is-placeholder:nth-child(2){width:45%}.woocommerce-store-alerts.is-loading .woocommerce-store-alerts__actions .is-placeholder{width:110px;height:26px}@media (max-width:782px){.woocommerce-store-alerts.is-loading .woocommerce-card__title{width:100%}.woocommerce-store-alerts.is-loading .woocommerce-card__title .is-placeholder{width:50%}.woocommerce-store-alerts.is-loading .woocommerce-card__action{margin-bottom:14px}}.woocommerce-store-alerts__snooze{display:inline-flex;margin-left:10px}.woocommerce-store-alerts__snooze .components-select-control__input{vertical-align:initial;min-height:36px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/48.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/48.style.rtl.css new file mode 100644 index 0000000..a7b383d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/48.style.rtl.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-store-alerts{position:relative;margin:0 0 40px;margin-left:var(--large-gap);padding:24px;border:0;box-shadow:0 0 8px -2px rgba(0,0,0,.3)}.woocommerce-store-alerts:before{content:"";position:absolute;top:0;right:0;width:4px;height:100%;background:transparent}.woocommerce-store-alerts .woocommerce-card__header{padding:0;border:0;margin-bottom:12px}.woocommerce-store-alerts .woocommerce-card__title{display:inline-flex}.woocommerce-store-alerts .woocommerce-card__title svg{margin-left:6px}.woocommerce-store-alerts .woocommerce-card__body{padding:0}.woocommerce-store-alerts a.components-button{min-height:36px;padding:4px 16px}@media (max-width:782px){.woocommerce-store-alerts a.components-button{min-height:36px;font-size:16px;line-height:1.625;padding:5px 16px}}.woocommerce-store-alerts a.components-button+.components-button{margin-right:10px}.woocommerce-store-alerts a.components-button.is-button{color:#757575}@media (max-width:782px){.woocommerce-store-alerts{margin-bottom:24px;padding:16px}.woocommerce-store-alerts .woocommerce-card__header{display:flex;flex-direction:column-reverse;align-items:flex-start}}.woocommerce-embed-page .woocommerce-store-alerts{margin:40px 20px 20px}@media (max-width:782px){.woocommerce-embed-page .woocommerce-store-alerts{margin-top:24px}}.is-alert-error:before{background-color:#dc3232}.is-alert-error .woocommerce-card__title svg{color:#dc3232}.is-alert-update:before{background-color:#11a0d2}.is-alert-update .woocommerce-card__title svg{color:#11a0d2}.woocommerce-store-alerts__message{margin-bottom:16px}.woocommerce-store-alerts__pagination{display:inline-flex;align-items:center;border:1px solid #b5bfc9;border-radius:4px;background:#f0f2f4;margin-right:16px;min-width:120px}.woocommerce-store-alerts__pagination .components-button{padding:4px}.rtl .woocommerce-store-alerts__pagination .components-button .dashicons-arrow-left-alt2,.rtl .woocommerce-store-alerts__pagination .components-button .dashicons-arrow-right-alt2{transform:scaleX(-1)}.woocommerce-store-alerts__pagination .woocommerce-store-alerts__pagination-label{padding:5px 12px;border-color:#b5bfc9;border-style:solid;border-width:0 1px;flex:1 1}@media (max-width:782px){.woocommerce-store-alerts__pagination{margin-right:0;margin-bottom:14px}.woocommerce-store-alerts__pagination .woocommerce-store-alerts__pagination-label{text-align:center}}.woocommerce-store-alerts__pagination button:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.woocommerce-store-alerts__pagination button:last-child{border-top-right-radius:0;border-bottom-right-radius:0}.woocommerce-store-alerts.is-loading:before{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent}.woocommerce-store-alerts.is-loading:before:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-store-alerts.is-loading:before{animation:none}}.woocommerce-store-alerts.is-loading .is-placeholder{animation:loading-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent;display:inline-block;height:16px}.woocommerce-store-alerts.is-loading .is-placeholder:after{content:"\00a0"}@media screen and (prefers-reduced-motion:reduce){.woocommerce-store-alerts.is-loading .is-placeholder{animation:none}}.woocommerce-store-alerts.is-loading .woocommerce-card__title .is-placeholder{width:340px;height:20px}.woocommerce-store-alerts.is-loading .woocommerce-card__action .is-placeholder{min-width:120px;height:30px}.woocommerce-store-alerts.is-loading .woocommerce-store-alerts__message .is-placeholder:first-child{width:75%}.woocommerce-store-alerts.is-loading .woocommerce-store-alerts__message .is-placeholder:nth-child(2){width:45%}.woocommerce-store-alerts.is-loading .woocommerce-store-alerts__actions .is-placeholder{width:110px;height:26px}@media (max-width:782px){.woocommerce-store-alerts.is-loading .woocommerce-card__title{width:100%}.woocommerce-store-alerts.is-loading .woocommerce-card__title .is-placeholder{width:50%}.woocommerce-store-alerts.is-loading .woocommerce-card__action{margin-bottom:14px}}.woocommerce-store-alerts__snooze{display:inline-flex;margin-right:10px}.woocommerce-store-alerts__snooze .components-select-control__input{vertical-align:initial;min-height:36px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/49.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/49.style.css new file mode 100644 index 0000000..0c7135b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/49.style.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-dashboard__store-performance{margin-bottom:24px}@media (max-width:782px){.woocommerce-dashboard__store-performance{border-width:0}}.woocommerce-dashboard__store-performance .woocommerce-summary{background-color:#f0f0f0;margin:0}@media (max-width:782px){.woocommerce-dashboard__store-performance .woocommerce-summary.is-placeholder{border-top:0}.woocommerce-dashboard__store-performance .woocommerce-summary:not(.is-placeholder) .woocommerce-summary__item-container:first-child .woocommerce-summary__item{border-top:1px solid #ccc}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/49.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/49.style.rtl.css new file mode 100644 index 0000000..0c7135b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/49.style.rtl.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-dashboard__store-performance{margin-bottom:24px}@media (max-width:782px){.woocommerce-dashboard__store-performance{border-width:0}}.woocommerce-dashboard__store-performance .woocommerce-summary{background-color:#f0f0f0;margin:0}@media (max-width:782px){.woocommerce-dashboard__store-performance .woocommerce-summary.is-placeholder{border-top:0}.woocommerce-dashboard__store-performance .woocommerce-summary:not(.is-placeholder) .woocommerce-summary__item-container:first-child .woocommerce-summary__item{border-top:1px solid #ccc}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/5.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/5.js new file mode 100644 index 0000000..5a3c63d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/5.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[5],{153:function(t,e,n){"use strict";function r(t){return function(){return t}}var o=function(){};o.thatReturns=r,o.thatReturnsFalse=r(!1),o.thatReturnsTrue=r(!0),o.thatReturnsNull=r(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(t){return t},t.exports=o},192:function(t,e,n){"use strict";n.d(e,"a",(function(){return o})),n.d(e,"b",(function(){return i}));var r=n(0),o=Object(r.createContext)({}),i=function(){return Object(r.useContext)(o)}},193:function(t,e,n){"use strict";n.d(e,"b",(function(){return d})),n.d(e,"d",(function(){return f})),n.d(e,"a",(function(){return p})),n.d(e,"c",(function(){return b}));var r=n(41),o=(n(557),n(301)),i=n(31);function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return isNaN(t)?"".concat(8,"px"):"".concat(8*t,"px")}var c={borderColor:Object(i.a)("lightGray.500"),borderRadius:"3px",backgroundShady:Object(i.a)("lightGray.200")},s=c.borderColor,u=c.borderRadius,l=c.backgroundShady,d=Object(r.a)("div",{target:"e1q7k77g0",label:"CardUI"})("background:",Object(i.a)("white"),";box-sizing:border-box;border-radius:",u,";border:1px solid ",s,";",m,";&.is-elevated{box-shadow:0px 1px 3px 0px rgba( 0,0,0,0.2 ),0px 1px 1px 0px rgba( 0,0,0,0.14 ),0px 2px 1px -1px rgba( 0,0,0,0.12 );}"),f=Object(r.a)(o.a,{target:"e1q7k77g1",label:"HeaderUI"})("border-bottom:1px solid ",s,";border-top-left-radius:",u,";border-top-right-radius:",u,";box-sizing:border-box;&:last-child{border-bottom:none;}",v,";",m,";",g,";"),p=(Object(r.a)("div",{target:"e1q7k77g2",label:"MediaUI"})("box-sizing:border-box;overflow:hidden;& > img,& > iframe{display:block;height:auto;max-width:100%;width:100%;}&:first-of-type{border-top-left-radius:",u,";border-top-right-radius:",u,";}&:last-of-type{border-bottom-left-radius:",u,";border-bottom-right-radius:",u,";}"),Object(r.a)("div",{target:"e1q7k77g3",label:"BodyUI"})("box-sizing:border-box;",(function(){return"\n\t\t&.is-size {\n\t\t\t&-large {\n\t\t\t\tpadding: ".concat(a(3)," ").concat(a(4),";\n\t\t\t}\n\t\t\t&-medium {\n\t\t\t\tpadding: ").concat(a(2)," ").concat(a(3),";\n\t\t\t}\n\t\t\t&-small {\n\t\t\t\tpadding: ").concat(a(2),";\n\t\t\t}\n\t\t\t&-extraSmall {\n\t\t\t\tpadding: ").concat(a(1),";\n\t\t\t}\n\t\t}\n\t")}),";",g,";")),b=Object(r.a)(o.a,{target:"e1q7k77g4",label:"FooterUI"})("border-top:1px solid ",s,";border-bottom-left-radius:",u,";border-bottom-right-radius:",u,";box-sizing:border-box;&:first-of-type{border-top:none;}",v,";",m,";",g,";");function v(){return"\n\t\t&.is-size {\n\t\t\t&-large {\n\t\t\t\tpadding: ".concat(a(3)," ").concat(a(4),";\n\t\t\t}\n\t\t\t&-medium {\n\t\t\t\tpadding: ").concat(a(2)," ").concat(a(3),";\n\t\t\t}\n\t\t\t&-small {\n\t\t\t\tpadding: ").concat(a(2),";\n\t\t\t}\n\t\t\t&-extraSmall {\n\t\t\t\tpadding: ").concat(a(1),";\n\t\t\t}\n\t\t}\n\t")}function m(){return"\n\t\t&.is-borderless {\n\t\t\tborder: none;\n\t\t}\n\t"}function g(){return"\n\t\t&.is-shady {\n\t\t\tbackground: ".concat(l,";\n\t\t}\n\t")}},210:function(t,e,n){"use strict";var r=n(6),o="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,i=n(153),a=n(211),c=n(212),s="function"==typeof Symbol&&Symbol.iterator;function u(t,e){return t&&"object"==typeof t&&null!=t.key?(n=t.key,r={"=":"=0",":":"=2"},"$"+(""+n).replace(/[=:]/g,(function(t){return r[t]}))):e.toString(36);var n,r}function l(t,e,n,r){var i,c=typeof t;if("undefined"!==c&&"boolean"!==c||(t=null),null===t||"string"===c||"number"===c||"object"===c&&t.$$typeof===o)return n(r,t,""===e?"."+u(t,0):e),1;var d=0,f=""===e?".":e+":";if(Array.isArray(t))for(var p=0;p "+s);if("componentClose"===d.type)throw new Error("Missing opening component token: `"+d.value+"`");if("componentOpen"===d.type){n=e[d.value],c=f;break}v.push(e[d.value])}else v.push(d.value);return n&&(l=function(t,e){var n,r,o=e[t],i=0;for(r=t+1;r *{",i,":",r,"px;&:last-child{",i,":0;}}")}),";",(function(t){return t.isReversed?i:""}),";"),c=Object(r.a)("div",{target:"eboqfv51",label:"Item"})({name:"13luw5d",styles:"box-sizing:border-box;min-width:0;max-width:100%;"})},557:function(t,e,n){"use strict";n.d(e,"a",(function(){return r}));var r="hr"},724:function(t,e,n){"use strict";var r=n(7),o=n(12),i=n(0),a=n(4),c=n.n(a),s=n(192),u=n(193);function l(t){var e=t.className,n=t.isBorderless,a=t.isElevated,l=t.size,d=Object(o.a)(t,["className","isBorderless","isElevated","size"]),f=s.a.Provider,p={isBorderless:n,isElevated:a,size:l},b=c()("components-card",n&&"is-borderless",a&&"is-elevated",l&&"is-size-".concat(l),e);return Object(i.createElement)(f,{value:p},Object(i.createElement)(u.b,Object(r.a)({},d,{className:b})))}l.defaultProps={isBorderless:!1,isElevated:!1,size:"medium"},e.a=l},725:function(t,e,n){"use strict";var r=n(7),o=n(8),i=n(12),a=n(0),c=n(4),s=n.n(c),u=n(193),l=n(192);function d(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function f(t){for(var e=1;e "+l);if("componentClose"===f.type)throw new Error("Missing opening component token: `"+f.value+"`");if("componentOpen"===f.type){n=t[f.value],i=p;break}m.push(t[f.value])}else m.push(f.value);return n&&(u=function(e,t){var n,r,o=t[e],c=0;for(r=e+1;r0?c[0].name:null))}),[c]),Object(i.createElement)("div",{className:n},Object(i.createElement)(p.a,{role:"tablist",orientation:h,onNavigate:function(e,t){t.click()},className:"components-tab-panel__tabs"},c.map((function(e){return Object(i.createElement)(m,{className:l()("components-tab-panel__tabs-item",e.className,Object(o.a)({},O,e.name===_)),tabId:"".concat(D,"-").concat(e.name),"aria-controls":"".concat(D,"-").concat(e.name,"-view"),selected:e.name===_,key:e.name,onClick:Object(u.partial)(N,e.name)},e.title)}))),C&&Object(i.createElement)("div",{"aria-labelledby":w,role:"tabpanel",id:"".concat(w,"-view"),className:"components-tab-panel__tab-content"},r(C)))}},807:function(e,t,n){"use strict";var o=n(7),a=n(8),r=n(12),c=n(0),i=n(4),s=n.n(i),l=n(193),u=n(192);function d(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function p(e){for(var t=1;t=c.left&&a<=c.right&&r>=c.top&&r<=c.bottom);var n,a,r,c})),r=Object(d.find)(a,(function(e){var t=e.isRelative?e.element.current.parentElement:e.element.current;return!Object(d.some)(a,(function(n){return n!==e&&t.contains(n.element.current)}))})),c=this.dropZones.indexOf(r),i=null;r&&r.withPosition&&(i={x:o.clientX,y:o.clientY});var s=[];this.state.isDraggingOverDocument?c!==this.state.hoveredDropZone?(-1!==this.state.hoveredDropZone&&s.push(this.dropZones[this.state.hoveredDropZone]),r&&s.push(r)):r&&c===this.state.hoveredDropZone&&!Object(d.isEqual)(i,this.state.position)&&s.push(r):s=this.dropZones,s.forEach((function(e){var o=n.dropZones.indexOf(e)===c;e.setState({isDraggingOverDocument:j(t,e),isDraggingOverElement:o,position:o?i:null,type:o?t:null})}));var l={isDraggingOverDocument:!0,hoveredDropZone:c,position:i};b()(l,this.state)||this.setState(l)}},{key:"onDragOver",value:function(e){this.toggleDraggingOverDocument(e,O(e)),e.preventDefault()}},{key:"onDrop",value:function(e){e.dataTransfer&&e.dataTransfer.files.length;var t=this.state,n=t.position,a=t.hoveredDropZone,r=O(e),c=this.dropZones[a];if(this.resetDragState(),c)switch(r){case"file":c.onFilesDrop(Object(o.a)(e.dataTransfer.files),n);break;case"html":c.onHTMLDrop(e.dataTransfer.getData("text/html"),n);break;case"default":c.onDrop(e,n)}e.stopPropagation(),e.preventDefault()}},{key:"render",value:function(){return Object(u.createElement)("div",{ref:this.ref,onDrop:this.onDrop,className:"components-drop-zone__provider"},Object(u.createElement)(h,{value:this.dropZoneCallbacks},this.props.children))}}]),n}(u.Component);t.c=g},842:function(e,t,n){"use strict";var o=n(7),a=n(12),r=n(0),c=n(72);t.a=function(e){var t=e.accept,n=e.children,i=e.multiple,s=void 0!==i&&i,l=e.onChange,u=e.render,d=Object(a.a)(e,["accept","children","multiple","onChange","render"]),p=Object(r.useRef)(),b=function(){p.current.click()},m=u?u({openFileDialog:b}):Object(r.createElement)(c.a,Object(o.a)({onClick:b},d),n);return Object(r.createElement)("div",{className:"components-form-file-upload"},m,Object(r.createElement)("input",{type:"file",ref:p,multiple:s,style:{display:"none"},accept:t,onChange:l}))}},855:function(e,t,n){"use strict";var o=n(8),a=n(7),r=n(26),c=n(0),i=n(4),s=n.n(i),l=n(3),u=n(575),d=n(88),p=Object(c.createElement)(d.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(c.createElement)(d.b,{d:"M18.5 15v3.5H13V6.7l4.5 4.1 1-1.1-6.2-5.8-5.8 5.8 1 1.1 4-4v11.7h-6V15H4v5h16v-5z"})),b=n(825);function m(e){var t,n=e.className,a=e.label,i=e.onFilesDrop,d=e.onHTMLDrop,m=e.onDrop,f=Object(c.useRef)(),h=function(e){var t=e.element,n=e.onFilesDrop,o=e.onHTMLDrop,a=e.onDrop,i=e.isDisabled,s=e.withPosition,l=e.__unstableIsRelative,u=void 0!==l&&l,d=Object(c.useContext)(b.a),p=d.addDropZone,m=d.removeDropZone,f=Object(c.useState)({isDraggingOverDocument:!1,isDraggingOverElement:!1,type:null}),h=Object(r.a)(f,2),v=h[0],O=h[1];return Object(c.useEffect)((function(){if(!i){var e={element:t,onDrop:a,onFilesDrop:n,onHTMLDrop:o,setState:O,withPosition:s,isRelative:u};return p(e),function(){m(e)}}}),[i,a,n,o,s]),v}({element:f,onFilesDrop:i,onHTMLDrop:d,onDrop:m,__unstableIsRelative:!0}),v=h.isDraggingOverDocument,O=h.isDraggingOverElement,j=h.type;O&&(t=Object(c.createElement)("div",{className:"components-drop-zone__content"},Object(c.createElement)(u.a,{icon:p,className:"components-drop-zone__content-icon"}),Object(c.createElement)("span",{className:"components-drop-zone__content-text"},a||Object(l.__)("Drop files to upload"))));var g=s()("components-drop-zone",n,Object(o.a)({"is-active":(v||O)&&("file"===j&&i||"html"===j&&d||"default"===j&&m),"is-dragging-over-document":v,"is-dragging-over-element":O},"is-dragging-".concat(j),!!j));return Object(c.createElement)("div",{ref:f,className:g},t)}t.a=function(e){return Object(c.createElement)(b.b,null,(function(t){var n=t.addDropZone,o=t.removeDropZone;return Object(c.createElement)(m,Object(a.a)({addDropZone:n,removeDropZone:o},e))}))}},98:function(e,t){function n(e,t,n,o,a,r,c){try{var i=e[r](c),s=i.value}catch(e){return void n(e)}i.done?t(s):Promise.resolve(s).then(o,a)}e.exports=function(e){return function(){var t=this,o=arguments;return new Promise((function(a,r){var c=e.apply(t,o);function i(e){n(c,a,r,i,s,"next",e)}function s(e){n(c,a,r,i,s,"throw",e)}i(void 0)}))}}}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/54.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/54.js new file mode 100644 index 0000000..0965850 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/54.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[54],{153:function(e,t,n){"use strict";function o(e){return function(){return e}}var r=function(){};r.thatReturns=o,r.thatReturnsFalse=o(!1),r.thatReturnsTrue=o(!0),r.thatReturnsNull=o(null),r.thatReturnsThis=function(){return this},r.thatReturnsArgument=function(e){return e},e.exports=r},210:function(e,t,n){"use strict";var o=n(6),r="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,i=n(153),a=n(211),c=n(212),l="function"==typeof Symbol&&Symbol.iterator;function s(e,t){return e&&"object"==typeof e&&null!=e.key?(n=e.key,o={"=":"=0",":":"=2"},"$"+(""+n).replace(/[=:]/g,(function(e){return o[e]}))):t.toString(36);var n,o}function u(e,t,n,o){var i,c=typeof e;if("undefined"!==c&&"boolean"!==c||(e=null),null===e||"string"===c||"number"===c||"object"===c&&e.$$typeof===r)return n(o,e,""===t?"."+s(e,0):t),1;var f=0,p=""===t?".":t+":";if(Array.isArray(e))for(var d=0;d "+l);if("componentClose"===f.type)throw new Error("Missing opening component token: `"+f.value+"`");if("componentOpen"===f.type){n=t[f.value],c=p;break}b.push(t[f.value])}else b.push(f.value);return n&&(u=function(e,t){var n,o,r=t[e],i=0;for(o=e+1;ot.bottom&&n.leftt.right;case"left":return n.left+rt.bottom&&n.topt.right;case"bottom":return n.bottom-r>t.bottom&&n.leftt.right&&n.topt.right&&n.leftt.bottom}}},function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return y}));var o=n(1),r=n.n(o),i=n(2),a=n.n(i),c=n(0),l=n.n(c),s=n(3),u=n.n(s);function f(e){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function p(e,t){for(var n=0;n-1?function(){i||(i=setTimeout(a,r||0))}:function(){clearTimeout(i),i=setTimeout(a,o||0)},getLastTimeout:function(){return i}};e.addEventListener(t,c.fn),n.debounceCheck[t]=c})),m(h(n),"startWatching",(function(){n.debounceCheck||n.interval||(n.props.intervalCheck&&(n.interval=setInterval(n.check,n.props.intervalDelay)),n.props.scrollCheck&&n.addEventListener(n.getContainer(),"scroll",n.props.scrollDelay,n.props.scrollThrottle),n.props.resizeCheck&&n.addEventListener(window,"resize",n.props.resizeDelay,n.props.resizeThrottle),!n.props.delayedCall&&n.check())})),m(h(n),"stopWatching",(function(){if(n.debounceCheck)for(var e in n.debounceCheck)if(n.debounceCheck.hasOwnProperty(e)){var t=n.debounceCheck[e];clearTimeout(t.getLastTimeout()),t.target.removeEventListener(e,t.fn),n.debounceCheck[e]=null}n.debounceCheck=null,n.interval&&(n.interval=clearInterval(n.interval))})),m(h(n),"check",(function(){var e,t,o=n.node;if(!o)return n.state;if(e=function(e){return void 0===e.width&&(e.width=e.right-e.left),void 0===e.height&&(e.height=e.bottom-e.top),e}(n.roundRectDown(o.getBoundingClientRect())),n.props.containment){var r=n.props.containment.getBoundingClientRect();t={top:r.top,left:r.left,bottom:r.bottom,right:r.right}}else t={top:0,left:0,bottom:window.innerHeight||document.documentElement.clientHeight,right:window.innerWidth||document.documentElement.clientWidth};var i=n.props.offset||{};"object"===f(i)&&(t.top+=i.top||0,t.left+=i.left||0,t.bottom-=i.bottom||0,t.right-=i.right||0);var a={top:e.top>=t.top,left:e.left>=t.left,bottom:e.bottom<=t.bottom,right:e.right<=t.right},c=e.height>0&&e.width>0,l=c&&a.top&&a.left&&a.bottom&&a.right;if(c&&n.props.partialVisibility){var s=e.top<=t.bottom&&e.bottom>=t.top&&e.left<=t.right&&e.right>=t.left;"string"==typeof n.props.partialVisibility&&(s=a[n.props.partialVisibility]),l=n.props.minTopValue?s&&e.top<=t.bottom-n.props.minTopValue:s}"string"==typeof i.direction&&"number"==typeof i.value&&(console.warn("[notice] offset.direction and offset.value have been deprecated. They still work for now, but will be removed in next major version. Please upgrade to the new syntax: { %s: %d }",i.direction,i.value),l=u()(i,e,t));var p=n.state;return n.state.isVisible!==l&&(p={isVisible:l,visibilityRect:a},n.setState(p),n.props.onChange&&n.props.onChange(l)),p})),n.state={isVisible:null,visibilityRect:{}},n}var n,o,i;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&b(e,t)}(t,e),n=t,(o=[{key:"componentDidMount",value:function(){this.node=a.a.findDOMNode(this),this.props.active&&this.startWatching()}},{key:"componentWillUnmount",value:function(){this.stopWatching()}},{key:"componentDidUpdate",value:function(e){this.node=a.a.findDOMNode(this),this.props.active&&!e.active?(this.setState({isVisible:null,visibilityRect:{}}),this.startWatching()):this.props.active||this.stopWatching()}},{key:"roundRectDown",value:function(e){return{top:Math.floor(e.top),left:Math.floor(e.left),bottom:Math.floor(e.bottom),right:Math.floor(e.right)}}},{key:"render",value:function(){return this.props.children instanceof Function?this.props.children({isVisible:this.state.isVisible,visibilityRect:this.state.visibilityRect}):r.a.Children.only(this.props.children)}}])&&p(n.prototype,o),i&&p(n,i),t}(r.a.Component);m(y,"defaultProps",{active:!0,partialVisibility:!1,minTopValue:0,scrollCheck:!1,scrollDelay:250,scrollThrottle:-1,resizeCheck:!1,resizeDelay:250,resizeThrottle:-1,intervalCheck:!0,intervalDelay:100,delayedCall:!1,offset:{},containment:null,children:r.a.createElement("span",null)}),m(y,"propTypes",{onChange:l.a.func,active:l.a.bool,partialVisibility:l.a.oneOfType([l.a.bool,l.a.oneOf(["top","right","bottom","left"])]),delayedCall:l.a.bool,offset:l.a.oneOfType([l.a.shape({top:l.a.number,left:l.a.number,bottom:l.a.number,right:l.a.number}),l.a.shape({direction:l.a.oneOf(["top","right","bottom","left"]),value:l.a.number})]),scrollCheck:l.a.bool,scrollDelay:l.a.number,scrollThrottle:l.a.number,resizeCheck:l.a.bool,resizeDelay:l.a.number,resizeThrottle:l.a.number,intervalCheck:l.a.bool,intervalDelay:l.a.number,containment:"undefined"!=typeof window?l.a.instanceOf(window.Element):l.a.any,children:l.a.oneOfType([l.a.element,l.a.func]),minTopValue:l.a.number})},function(e,t,n){"use strict";var o=n(6);function r(){}function i(){}i.resetWarningCache=r,e.exports=function(){function e(e,t,n,r,i,a){if(a!==o){var c=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw c.name="Invariant Violation",c}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:r};return n.PropTypes=n,n}},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"}])},e.exports=o(n(6),n(100))}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/6.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/6.js new file mode 100644 index 0000000..422621e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/6.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[6],{559:function(e,t,n){"use strict";var i=n(7),a=n(58),s=n(56);n(1);function r(e,t){return e.replace(new RegExp("(^|\\s)"+t+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,"")}var o=n(6),l=n.n(o),c=n(100),u=n.n(c),p=!1,d=n(97),f=function(e){function t(t,n){var i;i=e.call(this,t,n)||this;var a,s=n&&!n.isMounting?t.enter:t.appear;return i.appearStatus=null,t.in?s?(a="exited",i.appearStatus="entering"):a="entered":a=t.unmountOnExit||t.mountOnEnter?"unmounted":"exited",i.state={status:a},i.nextCallback=null,i}Object(s.a)(t,e),t.getDerivedStateFromProps=function(e,t){return e.in&&"unmounted"===t.status?{status:"exited"}:null};var n=t.prototype;return n.componentDidMount=function(){this.updateStatus(!0,this.appearStatus)},n.componentDidUpdate=function(e){var t=null;if(e!==this.props){var n=this.state.status;this.props.in?"entering"!==n&&"entered"!==n&&(t="entering"):"entering"!==n&&"entered"!==n||(t="exiting")}this.updateStatus(!1,t)},n.componentWillUnmount=function(){this.cancelNextCallback()},n.getTimeouts=function(){var e,t,n,i=this.props.timeout;return e=t=n=i,null!=i&&"number"!=typeof i&&(e=i.exit,t=i.enter,n=void 0!==i.appear?i.appear:t),{exit:e,enter:t,appear:n}},n.updateStatus=function(e,t){if(void 0===e&&(e=!1),null!==t){this.cancelNextCallback();var n=u.a.findDOMNode(this);"entering"===t?this.performEnter(n,e):this.performExit(n)}else this.props.unmountOnExit&&"exited"===this.state.status&&this.setState({status:"unmounted"})},n.performEnter=function(e,t){var n=this,i=this.props.enter,a=this.context?this.context.isMounting:t,s=this.getTimeouts(),r=a?s.appear:s.enter;!t&&!i||p?this.safeSetState({status:"entered"},(function(){n.props.onEntered(e)})):(this.props.onEnter(e,a),this.safeSetState({status:"entering"},(function(){n.props.onEntering(e,a),n.onTransitionEnd(e,r,(function(){n.safeSetState({status:"entered"},(function(){n.props.onEntered(e,a)}))}))})))},n.performExit=function(e){var t=this,n=this.props.exit,i=this.getTimeouts();n&&!p?(this.props.onExit(e),this.safeSetState({status:"exiting"},(function(){t.props.onExiting(e),t.onTransitionEnd(e,i.exit,(function(){t.safeSetState({status:"exited"},(function(){t.props.onExited(e)}))}))}))):this.safeSetState({status:"exited"},(function(){t.props.onExited(e)}))},n.cancelNextCallback=function(){null!==this.nextCallback&&(this.nextCallback.cancel(),this.nextCallback=null)},n.safeSetState=function(e,t){t=this.setNextCallback(t),this.setState(e,t)},n.setNextCallback=function(e){var t=this,n=!0;return this.nextCallback=function(i){n&&(n=!1,t.nextCallback=null,e(i))},this.nextCallback.cancel=function(){n=!1},this.nextCallback},n.onTransitionEnd=function(e,t,n){this.setNextCallback(n);var i=null==t&&!this.props.addEndListener;e&&!i?(this.props.addEndListener&&this.props.addEndListener(e,this.nextCallback),null!=t&&setTimeout(this.nextCallback,t)):setTimeout(this.nextCallback,0)},n.render=function(){var e=this.state.status;if("unmounted"===e)return null;var t=this.props,n=t.children,i=Object(a.a)(t,["children"]);if(delete i.in,delete i.mountOnEnter,delete i.unmountOnExit,delete i.appear,delete i.enter,delete i.exit,delete i.timeout,delete i.addEndListener,delete i.onEnter,delete i.onEntering,delete i.onEntered,delete i.onExit,delete i.onExiting,delete i.onExited,"function"==typeof n)return l.a.createElement(d.a.Provider,{value:null},n(e,i));var s=l.a.Children.only(n);return l.a.createElement(d.a.Provider,{value:null},l.a.cloneElement(s,i))},t}(l.a.Component);function E(){}f.contextType=d.a,f.propTypes={},f.defaultProps={in:!1,mountOnEnter:!1,unmountOnExit:!1,appear:!1,enter:!0,exit:!0,onEnter:E,onEntering:E,onEntered:E,onExit:E,onExiting:E,onExited:E},f.UNMOUNTED=0,f.EXITED=1,f.ENTERING=2,f.ENTERED=3,f.EXITING=4;var h=f,x=function(e,t){return e&&t&&t.split(" ").forEach((function(t){return i=t,void((n=e).classList?n.classList.remove(i):"string"==typeof n.className?n.className=r(n.className,i):n.setAttribute("class",r(n.className&&n.className.baseVal||"",i)));var n,i}))},m=function(e){function t(){for(var t,n=arguments.length,i=new Array(n),a=0;a1&&void 0!==arguments[1]?arguments[1]:i.identity;return function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1?arguments[1]:void 0,i="function"==typeof e?e(n):e,s=Object(c.getIdsFromQuery)(r);if(s.length<1)return Promise.resolve([]);var u={include:s.join(","),per_page:s.length};return o()({path:Object(a.addQueryArgs)(i,u)}).then((function(e){return e.map(t)}))}}var d=m(s.NAMESPACE+"/products/categories",(function(e){return{key:e.id,label:e.name}})),f=m(s.NAMESPACE+"/coupons",(function(e){return{key:e.id,label:e.code}})),p=m(s.NAMESPACE+"/customers",(function(e){return{key:e.id,label:e.name}})),y=m(s.NAMESPACE+"/products",(function(e){return{key:e.id,label:e.name}})),b=m(s.NAMESPACE+"/taxes",(function(e){return{key:e.id,label:Object(l.a)(e)}}));function g(e){var t=e.attributes,r=e.name,a=Object(u.g)("variationTitleAttributesSeparator"," - ");if(r.indexOf(a)>-1)return r;var n=t.map((function(e){return e.option})).join(", ");return n?r+a+n:r}var v=m((function(e){var t=e.products;return t?s.NAMESPACE+"/products/".concat(t,"/variations"):s.NAMESPACE+"/variations"}),(function(e){return{key:e.id,label:g(e)}}))},765:function(e,t,r){"use strict";r.d(t,"a",(function(){return n}));var a=r(3);function n(e){return[e.country,e.state,e.name||Object(a.__)("TAX",'woocommerce'),e.priority].map((function(e){return e.toString().toUpperCase().trim()})).filter(Boolean).join("-")}},766:function(e,t,r){"use strict";var a=r(5),n=r.n(a),o=r(17),i=r.n(o),c=r(15),s=r.n(c),u=r(18),l=r.n(u),m=r(19),d=r.n(m),f=r(9),p=r.n(f),y=r(0),b=r(3),g=r(277),v=r(154),h=r(20),O=r(2),j=r(1),_=r.n(j),R=r(77),w=r(35),k=r(40),C=r(762),S=r(763),D=r(32);function q(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function E(e){for(var t=1;t2&&void 0!==arguments[2]?arguments[2]:{};if(!t||0===t.length)return null;var n=t.slice(0),o=n.pop();if(o.showFilters(r,a)){var i=Object(D.flattenFilters)(o.filters),c=r[o.param]||o.defaultValue||"all";return Object(O.find)(i,{value:c})}return e(n,r,a)}(n,c),m=Object(O.get)(l,["settings","param"]),d=t.mode||function(e,t){if(e&&t){var r=Object(O.get)(e,["settings","param"]);if(!r||Object.keys(t).includes(r))return Object(O.get)(e,["chartMode"])}return null}(l,c)||"time-comparison",f=e(w.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,p={mode:d,filterParam:m,defaultDateRange:f};if(o)return p;var y=u.some((function(e){return c[e]&&c[e].length}));if(c.search&&!y)return E(E({},p),{},{emptySearchResults:!0});var b=r&&r.map((function(e){return e.key})),g=Object(w.getReportChartData)({endpoint:a,dataType:"primary",query:c,select:e,limitBy:u,filters:n,advancedFilters:s,defaultDateRange:f,fields:b});if("item-comparison"===d)return E(E({},p),{},{primaryData:g});var v=Object(w.getReportChartData)({endpoint:a,dataType:"secondary",query:c,select:e,limitBy:u,filters:n,advancedFilters:s,defaultDateRange:f,fields:b});return E(E({},p),{},{primaryData:g,secondaryData:v})})))(T)},768:function(e,t,r){"use strict";r.d(t,"a",(function(){return n}));var a=r(2);function n(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=Object(a.find)(t,{key:e});return r||t[0]}},769:function(e,t,r){"use strict";var a=r(17),n=r.n(a),o=r(15),i=r.n(o),c=r(18),s=r.n(c),u=r(19),l=r.n(u),m=r(9),d=r.n(m),f=r(0),p=r(3),y=r(277),b=r(20),g=r(1),v=r.n(g),h=r(32),O=r(77),j=r(298),_=r(35),R=r(40),w=r(64),k=r(763),C=r(762);function S(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=d()(e);if(t){var n=d()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return l()(this,r)}}var D=function(e){s()(r,e);var t=S(r);function r(){return n()(this,r),t.apply(this,arguments)}return i()(r,[{key:"formatVal",value:function(e,t){var r=this.context,a=r.formatAmount,n=r.getCurrencyConfig;return"currency"===t?a(e):Object(j.formatValue)(n(),t,e)}},{key:"getValues",value:function(e,t){var r=this.props,a=r.emptySearchResults,n=r.summaryData.totals,o=n.primary?n.primary[e]:0,i=n.secondary?n.secondary[e]:0,c=a?0:o,s=a?0:i;return{delta:Object(j.calculateDelta)(c,s),prevValue:this.formatVal(s,t),value:this.formatVal(c,t)}}},{key:"render",value:function(){var e=this,t=this.props,r=t.charts,a=t.query,n=t.selectedChart,o=t.summaryData,i=t.endpoint,c=t.report,s=t.defaultDateRange,u=o.isError,l=o.isRequesting;if(u)return Object(f.createElement)(k.a,{isError:!0});if(l)return Object(f.createElement)(O.SummaryListPlaceholder,{numberOfItems:r.length});var m=Object(R.getDateParamsFromQuery)(a,s).compare;return Object(f.createElement)(O.SummaryList,null,(function(t){var a=t.onToggle;return r.map((function(t){var r=t.key,o=t.order,s=t.orderby,u=t.label,l=t.type,d={chart:r};s&&(d.orderby=s),o&&(d.order=o);var y=Object(h.getNewPath)(d),b=n.key===r,g=e.getValues(r,l),v=g.delta,j=g.prevValue,_=g.value;return Object(f.createElement)(O.SummaryNumber,{key:r,delta:v,href:y,label:u,prevLabel:"previous_period"===m?Object(p.__)("Previous Period:",'woocommerce'):Object(p.__)("Previous Year:",'woocommerce'),prevValue:j,selected:b,value:_,onLinkClickCallback:function(){a&&a(),Object(w.recordEvent)("analytics_chart_tab_click",{report:c||i,key:r})}})}))}))}}]),r}(f.Component);D.propTypes={charts:v.a.array.isRequired,endpoint:v.a.string.isRequired,limitProperties:v.a.array,query:v.a.object.isRequired,selectedChart:v.a.shape({key:v.a.string.isRequired,label:v.a.string.isRequired,order:v.a.oneOf(["asc","desc"]),orderby:v.a.string,type:v.a.oneOf(["average","number","currency"]).isRequired}).isRequired,summaryData:v.a.object,report:v.a.string},D.defaultProps={summaryData:{totals:{primary:{},secondary:{}},isError:!1}},D.contextType=C.a,t.a=Object(y.a)(Object(b.withSelect)((function(e,t){var r=t.charts,a=t.endpoint,n=t.limitProperties,o=t.query,i=t.filters,c=t.advancedFilters,s=n||[a],u=s.some((function(e){return o[e]&&o[e].length}));if(o.search&&!u)return{emptySearchResults:!0};var l=r&&r.map((function(e){return e.key})),m=e(_.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range;return{summaryData:Object(_.getSummaryNumbers)({endpoint:a,query:o,select:e,limitBy:s,filters:i,advancedFilters:c,defaultDateRange:m,fields:l}),defaultDateRange:m}})))(D)},781:function(e,t,r){"use strict";function a(e,t,r){return!!t&&(e&&t<=r==="instock")}r.d(t,"a",(function(){return a}))},795:function(e,t,r){"use strict";var a=r(17),n=r.n(a),o=r(15),i=r.n(o),c=r(11),s=r.n(c),u=r(18),l=r.n(u),m=r(19),d=r.n(m),f=r(9),p=r.n(f),y=r(0),b=r(3),g=r(277),v=r(81),h=r(20),O=r(2),j=r(32),_=r(77),R=r(298),w=r(36),k=r(35),C=r(796),S=r(781),D=r(771),q=r(762);r(828);function E(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=p()(e);if(t){var n=p()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return d()(this,r)}}var P=Object(w.g)("manageStock","no"),T=Object(w.g)("stockStatuses",{}),A=function(e){l()(r,e);var t=E(r);function r(){var e;return n()(this,r),(e=t.call(this)).getHeadersContent=e.getHeadersContent.bind(s()(e)),e.getRowsContent=e.getRowsContent.bind(s()(e)),e.getSummary=e.getSummary.bind(s()(e)),e}return i()(r,[{key:"getHeadersContent",value:function(){return[{label:Object(b.__)("Product Title",'woocommerce'),key:"product_name",required:!0,isLeftAligned:!0,isSortable:!0},{label:Object(b.__)("SKU",'woocommerce'),key:"sku",hiddenByDefault:!0,isSortable:!0},{label:Object(b.__)("Items Sold",'woocommerce'),key:"items_sold",required:!0,defaultSort:!0,isSortable:!0,isNumeric:!0},{label:Object(b.__)("Net Sales",'woocommerce'),screenReaderLabel:Object(b.__)("Net Sales",'woocommerce'),key:"net_revenue",required:!0,isSortable:!0,isNumeric:!0},{label:Object(b.__)("Orders",'woocommerce'),key:"orders_count",isSortable:!0,isNumeric:!0},{label:Object(b.__)("Category",'woocommerce'),key:"product_cat"},{label:Object(b.__)("Variations",'woocommerce'),key:"variations",isSortable:!0},"yes"===P?{label:Object(b.__)("Status",'woocommerce'),key:"stock_status"}:null,"yes"===P?{label:Object(b.__)("Stock",'woocommerce'),key:"stock",isNumeric:!0}:null].filter(Boolean)}},{key:"getRowsContent",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],r=this.props.query,a=Object(j.getPersistedQuery)(r),n=this.context,o=n.render,i=n.formatDecimal,c=n.getCurrencyConfig,s=c();return Object(O.map)(t,(function(t){var n=t.product_id,c=t.items_sold,u=t.net_revenue,l=t.orders_count,m=t.extended_info||{},d=m.category_ids,f=m.low_stock_amount,p=m.manage_stock,g=m.sku,h=m.stock_status,O=m.stock_quantity,k=m.variations,D=void 0===k?[]:k,q=Object(v.decodeEntities)(m.name),E=Object(j.getNewPath)(a,"/analytics/orders",{filter:"advanced",product_includes:n}),A=Object(j.getNewPath)(a,"/analytics/products",{filter:"single_product",products:n}),N=e.props.categories,F=d&&d.map((function(e){return N.get(e)})).filter(Boolean)||[],x=Object(S.a)(h,O,f)?Object(y.createElement)(_.Link,{href:Object(w.f)("post.php?action=edit&post="+n),type:"wp-admin"},Object(b._x)("Low","Indication of a low quantity",'woocommerce')):T[h];return[{display:Object(y.createElement)(_.Link,{href:A,type:"wc-admin"},q),value:q},{display:g,value:g},{display:Object(R.formatValue)(s,"number",c),value:c},{display:o(u),value:i(u)},{display:Object(y.createElement)(_.Link,{href:E,type:"wc-admin"},l),value:l},{display:Object(y.createElement)("div",{className:"woocommerce-table__product-categories"},F[0]&&Object(y.createElement)(C.a,{category:F[0],categories:N}),F.length>1&&Object(y.createElement)(_.Tag,{label:Object(b.sprintf)(Object(b._x)("+%d more","categories",'woocommerce'),F.length-1),popoverContents:F.map((function(e){return Object(y.createElement)(C.a,{category:e,categories:N,key:e.id,query:r})}))})),value:F.map((function(e){return e.name})).join(", ")},{display:Object(R.formatValue)(s,"number",D.length),value:D.length},"yes"===P?{display:p?x:Object(b.__)("N/A",'woocommerce'),value:p?T[h]:null}:null,"yes"===P?{display:p?Object(R.formatValue)(s,"number",O):Object(b.__)("N/A",'woocommerce'),value:O}:null].filter(Boolean)}))}},{key:"getSummary",value:function(e){var t=e.products_count,r=void 0===t?0:t,a=e.items_sold,n=void 0===a?0:a,o=e.net_revenue,i=void 0===o?0:o,c=e.orders_count,s=void 0===c?0:c,u=this.context,l=u.formatAmount,m=(0,u.getCurrencyConfig)();return[{label:Object(b._n)("product","products",r,'woocommerce'),value:Object(R.formatValue)(m,"number",r)},{label:Object(b._n)("item sold","items sold",n,'woocommerce'),value:Object(R.formatValue)(m,"number",n)},{label:Object(b.__)("net sales",'woocommerce'),value:l(i)},{label:Object(b._n)("orders","orders",s,'woocommerce'),value:Object(R.formatValue)(m,"number",s)}]}},{key:"render",value:function(){var e=this.props,t=e.advancedFilters,r=e.baseSearchQuery,a=e.filters,n=e.hideCompare,o=e.isRequesting,i=e.query,c={helpText:Object(b.__)("Check at least two products below to compare",'woocommerce'),placeholder:Object(b.__)("Search by product name or SKU",'woocommerce')};return Object(y.createElement)(D.a,{compareBy:n?void 0:"products",endpoint:"products",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,getSummary:this.getSummary,summaryFields:["products_count","items_sold","net_revenue","orders_count"],itemIdField:"product_id",isRequesting:o,labels:c,query:i,searchBy:"products",baseSearchQuery:r,tableQuery:{orderby:i.orderby||"items_sold",order:i.order||"desc",extended_info:!0,segmentby:i.segmentby},title:Object(b.__)("Products",'woocommerce'),columnPrefsKey:"products_report_columns",filters:a,advancedFilters:t})}}]),r}(y.Component);A.contextType=q.a,t.a=Object(g.a)(Object(h.withSelect)((function(e,t){var r=t.query;if(t.isRequesting||r.search&&(!r.products||!r.products.length))return{};var a=e(k.ITEMS_STORE_NAME),n=a.getItems,o=a.getItemsError,i=a.isResolving,c={per_page:-1};return{categories:n("categories",c),isError:Boolean(o("categories",c)),isRequesting:i("getItems",["categories",c])}})))(A)},796:function(e,t,r){"use strict";r.d(t,"a",(function(){return h}));var a=r(17),n=r.n(a),o=r(15),i=r.n(o),c=r(18),s=r.n(c),u=r(19),l=r.n(u),m=r(9),d=r.n(m),f=r(0),p=r(2),y=r(738),b=r(77),g=r(32);function v(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=d()(e);if(t){var n=d()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return l()(this,r)}}var h=function(e){s()(r,e);var t=v(r);function r(){return n()(this,r),t.apply(this,arguments)}return i()(r,[{key:"getCategoryAncestorIds",value:function(e,t){for(var r=[],a=e.parent;a;)r.unshift(a),a=t.get(a).parent;return r}},{key:"getCategoryAncestors",value:function(e,t){var r=this.getCategoryAncestorIds(e,t);if(r.length)return 1===r.length?t.get(Object(p.first)(r)).name+" › ":2===r.length?t.get(Object(p.first)(r)).name+" › "+t.get(Object(p.last)(r)).name+" › ":t.get(Object(p.first)(r)).name+" … "+t.get(Object(p.last)(r)).name+" › "}},{key:"render",value:function(){var e=this.props,t=e.categories,r=e.category,a=e.query,n=Object(g.getPersistedQuery)(a);return r?Object(f.createElement)("div",{className:"woocommerce-table__breadcrumbs"},this.getCategoryAncestors(r,t),Object(f.createElement)(b.Link,{href:Object(g.getNewPath)(n,"/analytics/categories",{filter:"single_category",categories:r.id}),type:"wc-admin"},r.name)):Object(f.createElement)(y.a,null)}}]),r}(f.Component)},828:function(e,t,r){}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/7.style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/7.style.css new file mode 100644 index 0000000..45294f2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/7.style.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-table__product-categories>.woocommerce-table__breadcrumbs{display:inline-block;margin-right:12px}.woocommerce-table__product-categories .components-popover__content{padding:0 16px;text-align:left}.woocommerce-table__product-categories .components-popover__content .woocommerce-table__breadcrumbs{margin-top:12px;margin-bottom:12px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/7.style.rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/7.style.rtl.css new file mode 100644 index 0000000..51a21c1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/7.style.rtl.css @@ -0,0 +1 @@ +:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-20:#005a87}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-20:#006187}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-20:#183ad6}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-20:#064054}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-20:#2b2724}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-20:#3a2c4d}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-20:#d02c21}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-20:#4c6066}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-20:#c36922}.woocommerce-table__product-categories>.woocommerce-table__breadcrumbs{display:inline-block;margin-left:12px}.woocommerce-table__product-categories .components-popover__content{padding:0 16px;text-align:right}.woocommerce-table__product-categories .components-popover__content .woocommerce-table__breadcrumbs{margin-top:12px;margin-bottom:12px} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/8.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/8.js new file mode 100644 index 0000000..b9651b1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/8.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[8],{764:function(e,t,r){"use strict";r.d(t,"e",(function(){return u})),r.d(t,"a",(function(){return d})),r.d(t,"b",(function(){return b})),r.d(t,"c",(function(){return p})),r.d(t,"d",(function(){return _})),r.d(t,"f",(function(){return f})),r.d(t,"h",(function(){return O})),r.d(t,"g",(function(){return v}));var a=r(37),o=r(43),c=r.n(o),n=r(2),i=r(32),l=r(35),m=r(36),s=r(765);function u(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n.identity;return function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",o=arguments.length>1?arguments[1]:void 0,n="function"==typeof e?e(o):e,l=Object(i.getIdsFromQuery)(r);if(l.length<1)return Promise.resolve([]);var m={include:l.join(","),per_page:l.length};return c()({path:Object(a.addQueryArgs)(n,m)}).then((function(e){return e.map(t)}))}}var d=u(l.NAMESPACE+"/products/categories",(function(e){return{key:e.id,label:e.name}})),b=u(l.NAMESPACE+"/coupons",(function(e){return{key:e.id,label:e.code}})),p=u(l.NAMESPACE+"/customers",(function(e){return{key:e.id,label:e.name}})),_=u(l.NAMESPACE+"/products",(function(e){return{key:e.id,label:e.name}})),f=u(l.NAMESPACE+"/taxes",(function(e){return{key:e.id,label:Object(s.a)(e)}}));function O(e){var t=e.attributes,r=e.name,a=Object(m.g)("variationTitleAttributesSeparator"," - ");if(r.indexOf(a)>-1)return r;var o=t.map((function(e){return e.option})).join(", ");return o?r+a+o:r}var v=u((function(e){var t=e.products;return t?l.NAMESPACE+"/products/".concat(t,"/variations"):l.NAMESPACE+"/variations"}),(function(e){return{key:e.id,label:O(e)}}))},765:function(e,t,r){"use strict";r.d(t,"a",(function(){return o}));var a=r(3);function o(e){return[e.country,e.state,e.name||Object(a.__)("TAX",'woocommerce'),e.priority].map((function(e){return e.toString().toUpperCase().trim()})).filter(Boolean).join("-")}},766:function(e,t,r){"use strict";var a=r(5),o=r.n(a),c=r(17),n=r.n(c),i=r(15),l=r.n(i),m=r(18),s=r.n(m),u=r(19),d=r.n(u),b=r(9),p=r.n(b),_=r(0),f=r(3),O=r(277),v=r(154),y=r(20),j=r(2),g=r(1),h=r.n(g),w=r(77),S=r(35),R=r(40),C=r(762),D=r(763),x=r(32);function E(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function q(e){for(var t=1;t2&&void 0!==arguments[2]?arguments[2]:{};if(!t||0===t.length)return null;var o=t.slice(0),c=o.pop();if(c.showFilters(r,a)){var n=Object(x.flattenFilters)(c.filters),i=r[c.param]||c.defaultValue||"all";return Object(j.find)(n,{value:i})}return e(o,r,a)}(o,i),u=Object(j.get)(s,["settings","param"]),d=t.mode||function(e,t){if(e&&t){var r=Object(j.get)(e,["settings","param"]);if(!r||Object.keys(t).includes(r))return Object(j.get)(e,["chartMode"])}return null}(s,i)||"time-comparison",b=e(S.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,p={mode:d,filterParam:u,defaultDateRange:b};if(c)return p;var _=m.some((function(e){return i[e]&&i[e].length}));if(i.search&&!_)return q(q({},p),{},{emptySearchResults:!0});var f=r&&r.map((function(e){return e.key})),O=Object(S.getReportChartData)({endpoint:a,dataType:"primary",query:i,select:e,limitBy:m,filters:o,advancedFilters:l,defaultDateRange:b,fields:f});if("item-comparison"===d)return q(q({},p),{},{primaryData:O});var v=Object(S.getReportChartData)({endpoint:a,dataType:"secondary",query:i,select:e,limitBy:m,filters:o,advancedFilters:l,defaultDateRange:b,fields:f});return q(q({},p),{},{primaryData:O,secondaryData:v})})))(A)},797:function(e,t,r){"use strict";r.d(t,"b",(function(){return i})),r.d(t,"c",(function(){return l})),r.d(t,"a",(function(){return m}));var a=r(3),o=r(55),c=r(36),n=r(764),i=Object(o.applyFilters)("woocommerce_admin_orders_report_charts",[{key:"orders_count",label:Object(a.__)("Orders",'woocommerce'),type:"number"},{key:"net_revenue",label:Object(a.__)("Net Sales",'woocommerce'),order:"desc",orderby:"net_total",type:"currency"},{key:"avg_order_value",label:Object(a.__)("Average Order Value",'woocommerce'),type:"currency"},{key:"avg_items_per_order",label:Object(a.__)("Average Items Per Order",'woocommerce'),order:"desc",orderby:"num_items_sold",type:"average"}]),l=Object(o.applyFilters)("woocommerce_admin_orders_report_filters",[{label:Object(a.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(a.__)("All Orders",'woocommerce'),value:"all"},{label:Object(a.__)("Advanced Filters",'woocommerce'),value:"advanced"}]}]),m=Object(o.applyFilters)("woocommerce_admin_orders_report_advanced_filters",{title:Object(a._x)("Orders Match {{select /}} Filters","A sentence describing filters for Orders. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ",'woocommerce'),filters:{status:{labels:{add:Object(a.__)("Order Status",'woocommerce'),remove:Object(a.__)("Remove order status filter",'woocommerce'),rule:Object(a.__)("Select an order status filter match",'woocommerce'),title:Object(a.__)("{{title}}Order Status{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(a.__)("Select an order status",'woocommerce')},rules:[{value:"is",label:Object(a._x)("Is","order status",'woocommerce')},{value:"is_not",label:Object(a._x)("Is Not","order status",'woocommerce')}],input:{component:"SelectControl",options:Object.keys(c.d).map((function(e){return{value:e,label:c.d[e]}}))}},product:{labels:{add:Object(a.__)("Products",'woocommerce'),placeholder:Object(a.__)("Search products",'woocommerce'),remove:Object(a.__)("Remove products filter",'woocommerce'),rule:Object(a.__)("Select a product filter match",'woocommerce'),title:Object(a.__)("{{title}}Product{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(a.__)("Select products",'woocommerce')},rules:[{value:"includes",label:Object(a._x)("Includes","products",'woocommerce')},{value:"excludes",label:Object(a._x)("Excludes","products",'woocommerce')}],input:{component:"Search",type:"products",getLabels:n.d}},variation:{labels:{add:Object(a.__)("Variations",'woocommerce'),placeholder:Object(a.__)("Search variations",'woocommerce'),remove:Object(a.__)("Remove variations filter",'woocommerce'),rule:Object(a.__)("Select a variation filter match",'woocommerce'),title:Object(a.__)("{{title}}Variation{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(a.__)("Select variation",'woocommerce')},rules:[{value:"includes",label:Object(a._x)("Includes","variations",'woocommerce')},{value:"excludes",label:Object(a._x)("Excludes","variations",'woocommerce')}],input:{component:"Search",type:"variations",getLabels:n.g}},coupon:{labels:{add:Object(a.__)("Coupon Codes",'woocommerce'),placeholder:Object(a.__)("Search coupons",'woocommerce'),remove:Object(a.__)("Remove coupon filter",'woocommerce'),rule:Object(a.__)("Select a coupon filter match",'woocommerce'),title:Object(a.__)("{{title}}Coupon Code{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(a.__)("Select coupon codes",'woocommerce')},rules:[{value:"includes",label:Object(a._x)("Includes","coupon code",'woocommerce')},{value:"excludes",label:Object(a._x)("Excludes","coupon code",'woocommerce')}],input:{component:"Search",type:"coupons",getLabels:n.b}},customer_type:{labels:{add:Object(a.__)("Customer Type",'woocommerce'),remove:Object(a.__)("Remove customer filter",'woocommerce'),rule:Object(a.__)("Select a customer filter match",'woocommerce'),title:Object(a.__)("{{title}}Customer is{{/title}} {{filter /}}",'woocommerce'),filter:Object(a.__)("Select a customer type",'woocommerce')},input:{component:"SelectControl",options:[{value:"new",label:Object(a.__)("New",'woocommerce')},{value:"returning",label:Object(a.__)("Returning",'woocommerce')}],defaultOption:"new"}},refunds:{labels:{add:Object(a.__)("Refunds",'woocommerce'),remove:Object(a.__)("Remove refunds filter",'woocommerce'),rule:Object(a.__)("Select a refund filter match",'woocommerce'),title:Object(a.__)("{{title}}Refunds{{/title}} {{filter /}}",'woocommerce'),filter:Object(a.__)("Select a refund type",'woocommerce')},input:{component:"SelectControl",options:[{value:"all",label:Object(a.__)("All",'woocommerce')},{value:"partial",label:Object(a.__)("Partially refunded",'woocommerce')},{value:"full",label:Object(a.__)("Fully refunded",'woocommerce')},{value:"none",label:Object(a.__)("None",'woocommerce')}],defaultOption:"all"}},tax_rate:{labels:{add:Object(a.__)("Tax Rates",'woocommerce'),placeholder:Object(a.__)("Search tax rates",'woocommerce'),remove:Object(a.__)("Remove tax rate filter",'woocommerce'),rule:Object(a.__)("Select a tax rate filter match",'woocommerce'),title:Object(a.__)("{{title}}Tax Rate{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(a.__)("Select tax rates",'woocommerce')},rules:[{value:"includes",label:Object(a._x)("Includes","tax rate",'woocommerce')},{value:"excludes",label:Object(a._x)("Excludes","tax rate",'woocommerce')}],input:{component:"Search",type:"taxes",getLabels:n.f}},attribute:{allowMultiple:!0,labels:{add:Object(a.__)("Attribute",'woocommerce'),placeholder:Object(a.__)("Search attributes",'woocommerce'),remove:Object(a.__)("Remove attribute filter",'woocommerce'),rule:Object(a.__)("Select a product attribute filter match",'woocommerce'),title:Object(a.__)("{{title}}Attribute{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(a.__)("Select attributes",'woocommerce')},rules:[{value:"is",label:Object(a._x)("Is","product attribute",'woocommerce')},{value:"is_not",label:Object(a._x)("Is Not","product attribute",'woocommerce')}],input:{component:"ProductAttribute"}}}})}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/9.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/9.js new file mode 100644 index 0000000..4a3432d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/9.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[9],{776:function(e,t,n){"use strict";n.d(t,"a",(function(){return r}));var c=n(20);function r(e){var t=Object(c.dispatch)("core/notices").createNotice;e.error_data&&e.errors&&Object.keys(e.errors).length?Object.keys(e.errors).forEach((function(n){t("error",e.errors[n].join(" "))})):e.message&&t(e.code?"error":"success",e.message)}},792:function(e,t,n){"use strict";n.d(t,"b",(function(){return ye})),n.d(t,"a",(function(){return Oe}));var c=n(0),r=n(3),o=n(43),a=n.n(o),i=n(2),s=n(42),l=n.n(s),u=n(36),m=n(77),p=n(35),d=n(38),_=n.n(d),b=n(14),h=n.n(b),f=n(98),y=n.n(f),O=n(17),g=n.n(O),w=n(15),j=n.n(w),k=n(11),C=n.n(k),v=n(18),E=n.n(v),S=n(19),P=n.n(S),x=n(9),A=n.n(x),R=n(5),N=n.n(R),L=n(72),T=n(277),M=n(20);function q(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=A()(e);if(t){var r=A()(this).constructor;n=Reflect.construct(c,arguments,r)}else n=c.apply(this,arguments);return P()(this,n)}}var U=function(e){E()(n,e);var t=q(n);function n(){var e;g()(this,n);for(var c=arguments.length,o=new Array(c),a=0;a0&&Object(d.createElement)("span",{className:"woocommerce-layout__inbox-badge"},r))),Object(d.createElement)("div",{className:"woocommerce-layout__inbox-subtitle"},c&&Object(d.createElement)(b.a,{variant:"body.small"},c)),o&&Object(d.createElement)("div",{className:"woocommerce-layout__activity-panel-header-menu"},o))}}]),o}(d.Component);y.propTypes={className:g.a.string,unreadMessages:g.a.number,title:g.a.string.isRequired,subtitle:g.a.string,menu:g.a.shape({type:g.a.oneOf([f.EllipsisMenu])})},t.a=y},775:function(e,t,o){},843:function(e,t,o){"use strict";o.r(t),o.d(t,"SETUP_TASK_HELP_ITEMS_FILTER",(function(){return k})),o.d(t,"HelpPanel",(function(){return j}));var c=o(0),n=o(3),r=o(190),m=o(20),a=o(55),i=o(570),s=o(844),u=o(800),l=o(2),p=o(36),d=o(77),_=o(35),h=o(830),w=o(64),g=o(774),b=o(191),f=o(792),k="woocommerce_admin_setup_task_help_items";function y(e){var t,o,c;switch(e.taskName){case"products":return[{title:Object(n.__)("Adding and Managing Products",'woocommerce'),link:"https://docs.woocommerce.com/document/managing-products/?utm_source=help_panel"},{title:Object(n.__)("Import products using the CSV Importer and Exporter",'woocommerce'),link:"https://docs.woocommerce.com/document/product-csv-importer-exporter/?utm_source=help_panel"},{title:Object(n.__)("Migrate products using Cart2Cart",'woocommerce'),link:"https://woocommerce.com/products/cart2cart/?utm_source=help_panel"},{title:Object(n.__)("Learn more about setting up products",'woocommerce'),link:"https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/setup-products/?utm_source=help_panel"}];case"appearance":return[{title:Object(n.__)("Showcase your products and tailor your shopping experience using Blocks",'woocommerce'),link:"https://docs.woocommerce.com/document/woocommerce-blocks/?utm_source=help_panel"},{title:Object(n.__)("Manage Store Notice, Catalog View and Product Images",'woocommerce'),link:"https://docs.woocommerce.com/document/woocommerce-customizer/?utm_source=help_panel"},{title:Object(n.__)("How to choose and change a theme",'woocommerce'),link:"https://docs.woocommerce.com/document/choose-change-theme/?utm_source=help_panel"}];case"shipping":return o=(t=e).activePlugins,c="US"===t.countryCode&&!o.includes("woocommerce-services"),[{title:Object(n.__)("Setting up Shipping Zones",'woocommerce'),link:"https://docs.woocommerce.com/document/setting-up-shipping-zones/?utm_source=help_panel"},{title:Object(n.__)("Core Shipping Options",'woocommerce'),link:"https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/shipping/core-shipping-options/?utm_source=help_panel"},{title:Object(n.__)("Product Shipping Classes",'woocommerce'),link:"https://docs.woocommerce.com/document/product-shipping-classes/?utm_source=help_panel"},c&&{title:Object(n.__)("WooCommerce Shipping setup and configuration",'woocommerce'),link:"https://docs.woocommerce.com/document/woocommerce-services/#section-3/?utm_source=help_panel"},{title:Object(n.__)("Learn more about configuring your shipping settings",'woocommerce'),link:"https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/shipping/?utm_source=help_panel"}].filter(Boolean);case"tax":return function(e){var t=e.countryCode,o=e.getSetting("onboarding",{}),c=o.automatedTaxSupportedCountries,r=void 0===c?[]:c,m=!o.taxJarActivated&&r.includes(t);return[{title:Object(n.__)("Setting up Taxes in WooCommerce",'woocommerce'),link:"https://docs.woocommerce.com/document/setting-up-taxes-in-woocommerce/?utm_source=help_panel"},m&&{title:Object(n.__)("Automated Tax calculation using WooCommerce Tax",'woocommerce'),link:"https://docs.woocommerce.com/document/woocommerce-services/?utm_source=help_panel#section-10"}].filter(Boolean)}(e);case"payments":return function(e){var t=e.countryCode,o=e.onboardingStatus,c=e.profileItems,r=e.getPaymentMethods({activePlugins:[],countryCode:t,onboardingStatus:o,options:{},profileItems:c}),m=function(e){return Boolean(r.find((function(t){return t.key===e})))},a=m("wcpay"),i=m("stripe"),s=m("klarna_checkout"),u=m("klarna_payments"),l=m("paypal"),p=m("square"),d=m("payfast"),_=m("eway");return[{title:Object(n.__)("Which Payment Option is Right for Me?",'woocommerce'),link:"https://docs.woocommerce.com/document/premium-payment-gateway-extensions/?utm_source=help_panel"},a&&{title:Object(n.__)("WooCommerce Payments Start Up Guide",'woocommerce'),link:"https://docs.woocommerce.com/document/payments//?utm_source=help_panel"},a&&{title:Object(n.__)("WooCommerce Payments FAQs",'woocommerce'),link:"https://docs.woocommerce.com/documentation/woocommerce-payments/woocommerce-payments-faqs/?utm_source=help_panel"},i&&{title:Object(n.__)("Stripe Setup and Configuration",'woocommerce'),link:"https://docs.woocommerce.com/document/stripe/?utm_source=help_panel"},l&&{title:Object(n.__)("PayPal Checkout Setup and Configuration",'woocommerce'),link:"https://docs.woocommerce.com/document/paypal-express-checkout/?utm_source=help_panel"},p&&{title:Object(n.__)("Square - Get started",'woocommerce'),link:"https://docs.woocommerce.com/document/woocommerce-square/?utm_source=help_panel"},s&&{title:Object(n.__)("Klarna - Introduction",'woocommerce'),link:"https://docs.woocommerce.com/document/klarna-checkout/?utm_source=help_panel"},u&&{title:Object(n.__)("Klarna - Introduction",'woocommerce'),link:"https://docs.woocommerce.com/document/klarna-payments/?utm_source=help_panel"},d&&{title:Object(n.__)("PayFast Setup and Configuration",'woocommerce'),link:"https://docs.woocommerce.com/document/payfast-payment-gateway/?utm_source=help_panel"},_&&{title:Object(n.__)("eWAY Setup and Configuration",'woocommerce'),link:"https://docs.woocommerce.com/document/eway/?utm_source=help_panel"},{title:Object(n.__)("Direct Bank Transfer (BACS)",'woocommerce'),link:"https://docs.woocommerce.com/document/bacs/?utm_source=help_panel"},{title:Object(n.__)("Cash on Delivery",'woocommerce'),link:"https://docs.woocommerce.com/document/cash-on-delivery/?utm_source=help_panel"}].filter(Boolean)}(e);default:return[]}}function O(e,t){var o=e.taskName;t&&e.recordEvent("help_panel_click",{task_name:o,link:t.currentTarget.href})}var j=function(e){var t=e.taskName;Object(c.useEffect)((function(){e.recordEvent("help_panel_open",{task_name:t})}),[t]);var o=function(e){var t=y(e),o={title:Object(n.__)("WooCommerce Docs",'woocommerce'),link:"https://docs.woocommerce.com/?utm_source=help_panel"};t.push(o);var m=Object(a.applyFilters)(k,t,e.taskName,e),p=Array.isArray(m)?m.filter((function(e){return e instanceof Object&&e.title&&e.link})):[];p.length||(p=[o]);var d=Object(l.partial)(O,e);return p.map((function(e){return{title:Object(c.createElement)(r.a,{as:"div",variant:"button"},e.title),before:Object(c.createElement)(i.a,{icon:s.a}),after:Object(c.createElement)(i.a,{icon:u.a}),linkType:"external",target:"_blank",href:e.link,onClick:d}}))}(e);return Object(c.createElement)(c.Fragment,null,Object(c.createElement)(g.a,{title:Object(n.__)("Documentation",'woocommerce')}),Object(c.createElement)(d.Section,null,Object(c.createElement)(d.List,{items:o,className:"woocommerce-quick-links__list"})))};j.defaultProps={getPaymentMethods:f.a,getSetting:p.g,recordEvent:w.recordEvent},t.default=Object(h.a)(Object(m.withSelect)((function(e){var t=e(_.ONBOARDING_STORE_NAME),o=t.getProfileItems,c=t.getTasksStatus,n=e(_.SETTINGS_STORE_NAME).getSettings,r=e(_.PLUGINS_STORE_NAME).getActivePlugins,m=n("general").general,a=void 0===m?{}:m,i=r(),s=c(),u=o();return{activePlugins:i,countryCode:Object(b.b)(a.woocommerce_default_country),onboardingStatus:s,profileItems:u}})))(j)}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/activity-panels-inbox.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/activity-panels-inbox.js new file mode 100644 index 0000000..d7a0d25 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/activity-panels-inbox.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[11],{772:function(e,t,n){"use strict";var c=n(778),a=["a","b","em","i","strong","p","br"],r=["target","href","rel","name","download"];t.a=function(e){return{__html:Object(c.sanitize)(e,{ALLOWED_TAGS:a,ALLOWED_ATTR:r})}}},773:function(e,t,n){"use strict";n.d(t,"a",(function(){return C})),n.d(t,"b",(function(){return k}));var c=n(17),a=n.n(c),r=n(15),o=n.n(r),i=n(18),s=n.n(i),l=n(19),m=n.n(l),u=n(9),d=n.n(u),b=n(0),f=n(4),p=n.n(f),v=n(104),_=n.n(v),h=n(16),y=n.n(h),O=n(1),w=n.n(O),g=n(77),j=n(72),E=(n(777),n(2));function N(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=d()(e);if(t){var a=d()(this).constructor;n=Reflect.construct(c,arguments,a)}else n=c.apply(this,arguments);return m()(this,n)}}var R=function(e){s()(n,e);var t=N(n);function n(){return a()(this,n),t.apply(this,arguments)}return o()(n,[{key:"render",value:function(){var e=this.props,t=e.className,n=e.hasAction,c=e.hasDate,a=e.hasSubtitle,r=e.lines,o=p()("woocommerce-activity-card is-loading",t);return Object(b.createElement)("div",{className:o,"aria-hidden":!0},Object(b.createElement)("span",{className:"woocommerce-activity-card__icon"},Object(b.createElement)("span",{className:"is-placeholder"})),Object(b.createElement)("div",{className:"woocommerce-activity-card__header"},Object(b.createElement)("div",{className:"woocommerce-activity-card__title is-placeholder"}),a&&Object(b.createElement)("div",{className:"woocommerce-activity-card__subtitle is-placeholder"}),c&&Object(b.createElement)("div",{className:"woocommerce-activity-card__date"},Object(b.createElement)("span",{className:"is-placeholder"}))),Object(b.createElement)("div",{className:"woocommerce-activity-card__body"},Object(E.range)(r).map((function(e){return Object(b.createElement)("span",{className:"is-placeholder",key:e})}))),n&&Object(b.createElement)("div",{className:"woocommerce-activity-card__actions"},Object(b.createElement)("span",{className:"is-placeholder"})))}}]),n}(b.Component);R.propTypes={className:w.a.string,hasAction:w.a.bool,hasDate:w.a.bool,hasSubtitle:w.a.bool,lines:w.a.number},R.defaultProps={hasAction:!1,hasDate:!1,hasSubtitle:!1,lines:1};var k=R;function D(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=d()(e);if(t){var a=d()(this).constructor;n=Reflect.construct(c,arguments,a)}else n=c.apply(this,arguments);return m()(this,n)}}var C=function(e){s()(n,e);var t=D(n);function n(){return a()(this,n),t.apply(this,arguments)}return o()(n,[{key:"getCard",value:function(){var e=this.props,t=e.actions,n=e.className,c=e.children,a=e.date,r=e.icon,o=e.subtitle,i=e.title,s=e.unread,l=p()("woocommerce-activity-card",n),m=Array.isArray(t)?t:[t];return Object(b.createElement)("section",{className:l},s&&Object(b.createElement)("span",{className:"woocommerce-activity-card__unread"}),r&&Object(b.createElement)("span",{className:"woocommerce-activity-card__icon","aria-hidden":!0},r),i&&Object(b.createElement)("header",{className:"woocommerce-activity-card__header"},Object(b.createElement)(g.H,{className:"woocommerce-activity-card__title"},i),o&&Object(b.createElement)("div",{className:"woocommerce-activity-card__subtitle"},o),a&&Object(b.createElement)("span",{className:"woocommerce-activity-card__date"},y.a.utc(a).fromNow())),c&&Object(b.createElement)(g.Section,{className:"woocommerce-activity-card__body"},c),t&&Object(b.createElement)("footer",{className:"woocommerce-activity-card__actions"},m.map((function(e,t){return Object(b.cloneElement)(e,{key:t})}))))}},{key:"render",value:function(){var e=this.props.onClick;return e?Object(b.createElement)(j.a,{className:"woocommerce-activity-card__button",onClick:e},this.getCard()):this.getCard()}}]),n}(b.Component);C.propTypes={actions:w.a.oneOfType([w.a.arrayOf(w.a.element),w.a.element]),onClick:w.a.func,className:w.a.string,children:w.a.node,date:w.a.string,icon:w.a.node,subtitle:w.a.node,title:w.a.oneOfType([w.a.string,w.a.node]),unread:w.a.bool},C.defaultProps={icon:Object(b.createElement)(_.a,{icon:"notice-outline",size:48}),unread:!1}},774:function(e,t,n){"use strict";var c=n(17),a=n.n(c),r=n(15),o=n.n(r),i=n(18),s=n.n(i),l=n(19),m=n.n(l),u=n(9),d=n.n(u),b=n(0),f=n(4),p=n.n(f),v=n(1),_=n.n(v),h=n(190),y=n(77);n(775);function O(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=d()(e);if(t){var a=d()(this).constructor;n=Reflect.construct(c,arguments,a)}else n=c.apply(this,arguments);return m()(this,n)}}var w=function(e){s()(n,e);var t=O(n);function n(){return a()(this,n),t.apply(this,arguments)}return o()(n,[{key:"render",value:function(){var e=this.props,t=e.className,n=e.menu,c=e.subtitle,a=e.title,r=e.unreadMessages,o=p()({"woocommerce-layout__inbox-panel-header":c,"woocommerce-layout__activity-panel-header":!c},t),i=r||0;return Object(b.createElement)("div",{className:o},Object(b.createElement)("div",{className:"woocommerce-layout__inbox-title"},Object(b.createElement)(h.a,{variant:"title.small"},a),Object(b.createElement)(h.a,{variant:"button"},i>0&&Object(b.createElement)("span",{className:"woocommerce-layout__inbox-badge"},r))),Object(b.createElement)("div",{className:"woocommerce-layout__inbox-subtitle"},c&&Object(b.createElement)(h.a,{variant:"body.small"},c)),n&&Object(b.createElement)("div",{className:"woocommerce-layout__activity-panel-header-menu"},n))}}]),n}(b.Component);w.propTypes={className:_.a.string,unreadMessages:_.a.number,title:_.a.string.isRequired,subtitle:_.a.string,menu:_.a.shape({type:_.a.oneOf([y.EllipsisMenu])})},t.a=w},775:function(e,t,n){},777:function(e,t,n){},784:function(e,t,n){},798:function(e,t,n){"use strict";n.r(t);var c=n(62),a=n.n(c),r=n(0),o=n(3),i=n(277),s=n(77),l=n(35),m=n(20),u=n(560),d=n(559),b=n(773),f=n(17),p=n.n(f),v=n(15),_=n.n(v),h=n(18),y=n.n(h),O=n(19),w=n.n(O),g=n(9),j=n.n(g),E=n(1),N=n.n(E);function R(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=j()(e);if(t){var a=j()(this).constructor;n=Reflect.construct(c,arguments,a)}else n=c.apply(this,arguments);return w()(this,n)}}var k=function(e){y()(n,e);var t=R(n);function n(){return p()(this,n),t.apply(this,arguments)}return _()(n,[{key:"render",value:function(){var e=this.props.className;return Object(r.createElement)("div",{className:"woocommerce-inbox-message is-placeholder ".concat(e),"aria-hidden":!0},Object(r.createElement)("div",{className:"woocommerce-inbox-message__image"},Object(r.createElement)("div",{className:"banner-block"})),Object(r.createElement)("div",{className:"woocommerce-inbox-message__wrapper"},Object(r.createElement)("div",{className:"woocommerce-inbox-message__content"},Object(r.createElement)("div",{className:"woocommerce-inbox-message__date"},Object(r.createElement)("div",{className:"sixth-line"})),Object(r.createElement)("div",{className:"woocommerce-inbox-message__title"},Object(r.createElement)("div",{className:"line"}),Object(r.createElement)("div",{className:"line"})),Object(r.createElement)("div",{className:"woocommerce-inbox-message__text"},Object(r.createElement)("div",{className:"line"}),Object(r.createElement)("div",{className:"third-line"}))),Object(r.createElement)("div",{className:"woocommerce-inbox-message__actions"},Object(r.createElement)("div",{className:"fifth-line"}),Object(r.createElement)("div",{className:"fifth-line"}))))}}]),n}(r.Component);k.propTypes={className:N.a.string};var D=k,C=n(11),x=n.n(C),T=n(5),A=n.n(T),S=n(535),M=n(72),L=n(736),U=n(783),B=n.n(U),P=n(16),q=n.n(P),F=n(4),I=n.n(F),Y=n(64),z=n(36);function V(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=j()(e);if(t){var a=j()(this).constructor;n=Reflect.construct(c,arguments,a)}else n=c.apply(this,arguments);return w()(this,n)}}var W=function(e){y()(n,e);var t=V(n);function n(e){var c;return p()(this,n),(c=t.call(this,e)).state={inAction:!1},c.handleActionClick=c.handleActionClick.bind(x()(c)),c}return _()(n,[{key:"handleActionClick",value:function(e){var t=this.props,n=t.action,c=t.actionCallback,a=t.batchUpdateNotes,r=t.createNotice,i=t.noteId,s=t.triggerNoteAction,l=t.removeAllNotes,m=t.removeNote,u=t.onClick,d=t.updateNote,b=e.target.href||"",f=!0;b.length&&!b.startsWith(z.a)&&(e.preventDefault(),f=!1,window.open(b,"_blank")),n?this.setState({inAction:f},(function(){s(i,n.id),u&&u()})):(i?m(i).then((function(){r("success",Object(o.__)("Message dismissed.",'woocommerce'),{actions:[{label:Object(o.__)("Undo",'woocommerce'),onClick:function(){d(i,{is_deleted:0})}}]})})).catch((function(){r("error",Object(o.__)("Message could not be dismissed.",'woocommerce'))})):l().then((function(e){r("success",Object(o.__)("All messages dismissed.",'woocommerce'),{actions:[{label:Object(o.__)("Undo",'woocommerce'),onClick:function(){a(e.map((function(e){return e.id})),{is_deleted:0})}}]})})).catch((function(){r("error",Object(o.__)("Message could not be dismissed.",'woocommerce'))})),c(!0))}},{key:"render",value:function(){var e=this.props,t=e.action,n=e.dismiss,c=e.label;return Object(r.createElement)(M.a,{isSecondary:!0,isBusy:this.state.inAction,disabled:this.state.inAction,href:t&&t.url&&t.url.length?t.url:void 0,onClick:this.handleActionClick},n?c:t.label)}}]),n}(r.Component);W.propTypes={noteId:N.a.number,label:N.a.string,dismiss:N.a.bool,actionCallback:N.a.func,action:N.a.shape({id:N.a.number.isRequired,url:N.a.string,label:N.a.string.isRequired,primary:N.a.bool.isRequired}),onClick:N.a.func};var H=Object(i.a)(Object(m.withDispatch)((function(e){var t=e("core/notices").createNotice,n=e(l.NOTES_STORE_NAME),c=n.batchUpdateNotes,a=n.removeAllNotes,r=n.removeNote,o=n.updateNote;return{batchUpdateNotes:c,createNotice:t,removeAllNotes:a,removeNote:r,triggerNoteAction:n.triggerNoteAction,updateNote:o}})))(W),Q=n(772);n(784);function G(){var e,t="",n=(e=window.location.search)?e.substr(1).split("&").reduce((function(e,t){var n=t.split("="),c=n[0],a=decodeURIComponent(n[1]);return a=isNaN(Number(a))?a:Number(a),e[c]=a,e}),{}):{},c=n.page,a=n.path,r=n.post_type;if(c){var o="wc-admin"===c?"home_screen":c;t=a?a.replace(/\//g,"_").substring(1):o}else r&&(t=r);return t}function J(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=j()(e);if(t){var a=j()(this).constructor;n=Reflect.construct(c,arguments,a)}else n=c.apply(this,arguments);return w()(this,n)}}var Z=function(e){y()(n,e);var t=J(n);function n(e){var c;return p()(this,n),c=t.call(this,e),A()(x()(c),"onActionClicked",(function(e){e.actioned_text&&c.setState({clickedActionText:e.actioned_text})})),c.onVisible=c.onVisible.bind(x()(c)),c.hasBeenSeen=!1,c.state={isDismissModalOpen:!1,dismissType:null,clickedActionText:null},c.openDismissModal=c.openDismissModal.bind(x()(c)),c.closeDismissModal=c.closeDismissModal.bind(x()(c)),c.bodyNotificationRef=Object(r.createRef)(),c.screen=G(),c}return _()(n,[{key:"componentDidMount",value:function(){var e=this;this.bodyNotificationRef.current&&this.bodyNotificationRef.current.addEventListener("click",(function(t){return e.handleBodyClick(t,e.props)}))}},{key:"componentWillUnmount",value:function(){var e=this;this.bodyNotificationRef.current&&this.bodyNotificationRef.current.removeEventListener("click",(function(t){return e.handleBodyClick(t,e.props)}))}},{key:"handleBodyClick",value:function(e,t){var n=e.target.href;if(n){var c=t.note;Object(Y.recordEvent)("wcadmin_inbox_action_click",{note_name:c.name,note_title:c.title,note_content_inner_link:n})}}},{key:"onVisible",value:function(e){if(e&&!this.hasBeenSeen){var t=this.props.note;Object(Y.recordEvent)("inbox_note_view",{note_content:t.content,note_name:t.name,note_title:t.title,note_type:t.type,screen:this.screen}),this.hasBeenSeen=!0}}},{key:"openDismissModal",value:function(e,t){this.setState({isDismissModalOpen:!0,dismissType:e}),t()}},{key:"closeDismissModal",value:function(e){var t=this.state.dismissType,n=this.props.note,c="all"===t;Object(Y.recordEvent)("inbox_action_dismiss",{note_name:n.name,note_title:n.title,note_name_dismiss_all:c,note_name_dismiss_confirmation:e||!1,screen:this.screen}),this.setState({isDismissModalOpen:!1})}},{key:"handleBlur",value:function(e,t){var n=e.relatedTarget?e.relatedTarget:document.activeElement;!!n&&["woocommerce-admin-dismiss-notification","components-popover__content"].some((function(e){return n.className.includes(e)}))?e.preventDefault():t()}},{key:"renderDismissButton",value:function(){var e=this;return this.state.clickedActionText?null:Object(r.createElement)(S.a,{contentClassName:"woocommerce-admin-dismiss-dropdown",position:"bottom right",renderToggle:function(t){var n=t.onClose,c=t.onToggle;return Object(r.createElement)(M.a,{isTertiary:!0,onClick:c,onBlur:function(t){return e.handleBlur(t,n)}},Object(o.__)("Dismiss",'woocommerce'))},focusOnMount:!1,popoverProps:{noArrow:!0},renderContent:function(t){var n=t.onToggle;return Object(r.createElement)("ul",null,Object(r.createElement)("li",null,Object(r.createElement)(M.a,{className:"woocommerce-admin-dismiss-notification",onClick:function(){return e.openDismissModal("this",n)}},Object(o.__)("Dismiss this message",'woocommerce'))),Object(r.createElement)("li",null,Object(r.createElement)(M.a,{className:"woocommerce-admin-dismiss-notification",onClick:function(){return e.openDismissModal("all",n)}},Object(o.__)("Dismiss all messages",'woocommerce'))))}})}},{key:"getDismissConfirmationButton",value:function(){var e=this.props.note,t=this.state.dismissType;return Object(r.createElement)(H,{key:e.id,noteId:"all"===t?null:e.id,label:Object(o.__)("Yes, I'm sure",'woocommerce'),actionCallback:this.closeDismissModal,dismiss:!0,screen:this.screen})}},{key:"renderDismissConfirmationModal",value:function(){var e=this;return Object(r.createElement)(L.a,{title:Object(r.createElement)(r.Fragment,null,Object(o.__)("Are you sure?",'woocommerce')),onRequestClose:function(){return e.closeDismissModal()},className:"woocommerce-inbox-dismiss-confirmation_modal"},Object(r.createElement)("div",{className:"woocommerce-inbox-dismiss-confirmation_wrapper"},Object(r.createElement)("p",null,Object(o.__)("Dismissed messages cannot be viewed again",'woocommerce')),Object(r.createElement)("div",{className:"woocommerce-inbox-dismiss-confirmation_buttons"},Object(r.createElement)(M.a,{isSecondary:!0,onClick:function(){return e.closeDismissModal()}},Object(o.__)("Cancel",'woocommerce')),this.getDismissConfirmationButton())))}},{key:"renderActions",value:function(e){var t=this,n=e.actions,c=e.id,a=this.state.clickedActionText;return a||(n?Object(r.createElement)(r.Fragment,null,n.map((function(e,n){return Object(r.createElement)(H,{key:n,noteId:c,action:e,onClick:function(){return t.onActionClicked(e)}})}))):void 0)}},{key:"render",value:function(){var e=this.props,t=e.lastRead,n=e.note,c=this.state.isDismissModalOpen,a=n.content,o=n.date_created,i=n.date_created_gmt,l=n.image,m=n.is_deleted,u=n.layout,d=n.status,b=n.title;if(m)return null;var f=!t||!i||new Date(i+"Z").getTime()>t,p=o,v="plain"!==u&&""!==u,_=I()("woocommerce-inbox-message",u,{"message-is-unread":f&&"unactioned"===d});return Object(r.createElement)(B.a,{onChange:this.onVisible},Object(r.createElement)("section",{className:_},v&&Object(r.createElement)("div",{className:"woocommerce-inbox-message__image"},Object(r.createElement)("img",{src:l,alt:""})),Object(r.createElement)("div",{className:"woocommerce-inbox-message__wrapper"},Object(r.createElement)("div",{className:"woocommerce-inbox-message__content"},p&&Object(r.createElement)("span",{className:"woocommerce-inbox-message__date"},q.a.utc(p).fromNow()),Object(r.createElement)(s.H,{className:"woocommerce-inbox-message__title"},b),Object(r.createElement)(s.Section,{className:"woocommerce-inbox-message__text"},Object(r.createElement)("span",{dangerouslySetInnerHTML:Object(Q.a)(a),ref:this.bodyNotificationRef}))),Object(r.createElement)("div",{className:"woocommerce-inbox-message__actions"},this.renderActions(n),this.renderDismissButton())),c&&this.renderDismissConfirmationModal()))}}]),n}(r.Component);Z.propTypes={note:N.a.shape({id:N.a.number,status:N.a.string,title:N.a.string,content:N.a.string,date_created:N.a.string,date_created_gmt:N.a.string,actions:N.a.arrayOf(N.a.shape({id:N.a.number.isRequired,url:N.a.string,label:N.a.string.isRequired,primary:N.a.bool.isRequired})),layout:N.a.string,image:N.a.string,is_deleted:N.a.bool}),lastRead:N.a.number};var K=Z,X=n(446),$=function(e){var t=e.hasNotes,n=e.isBatchUpdating,c=e.lastRead,a=e.notes;if(!n){if(!t)return Object(r.createElement)(b.a,{className:"woocommerce-empty-activity-card",title:Object(o.__)("Your inbox is empty",'woocommerce'),icon:!1},Object(o.__)("As things begin to happen in your store your inbox will start to fill up. You'll see things like achievements, new feature announcements, extension recommendations and more!",'woocommerce'));var i=Object.keys(a).map((function(e){return a[e]}));return Object(r.createElement)(u.a,{role:"menu"},i.map((function(e){var t=e.id;return e.is_deleted?null:Object(r.createElement)(d.a,{key:t,timeout:500,classNames:"woocommerce-inbox-message"},Object(r.createElement)(K,{key:t,note:e,lastRead:c}))})))}};t.default=Object(i.a)(Object(m.withSelect)((function(e){var t=e(l.NOTES_STORE_NAME),n=t.getNotes,c=t.getNotesError,a=t.isResolving,r=t.isNotesRequesting,o={page:1,per_page:l.QUERY_DEFAULTS.pageSize,status:"unactioned",type:l.QUERY_DEFAULTS.noteTypes,orderby:"date",order:"desc",_fields:["id","name","title","content","type","status","actions","date_created","date_created_gmt","layout","image","is_deleted"]};return{notes:n(o),isError:Boolean(c("getNotes",[o])),isResolving:a("getNotes",[o]),isBatchUpdating:r("batchUpdateNotes")}})))((function(e){var t=e.isError,n=e.isResolving,c=e.isBatchUpdating,i=e.notes,m=Object(l.useUserPreferences)(),u=m.updateUserPreferences,d=a()(m,["updateUserPreferences"]).activity_panel_inbox_last_read;if(Object(r.useEffect)((function(){var e=Date.now();return function(){u({activity_panel_inbox_last_read:e})}}),[]),t){var b=Object(o.__)("There was an error getting your inbox. Please try again.",'woocommerce'),f=Object(o.__)("Reload",'woocommerce');return Object(r.createElement)(s.EmptyContent,{title:b,actionLabel:f,actionURL:null,actionCallback:function(){window.location.reload()}})}var p=Object(X.b)(i);return Object(r.createElement)(r.Fragment,null,Object(r.createElement)("div",{className:"woocommerce-homepage-notes-wrapper"},(n||c)&&Object(r.createElement)(s.Section,null,Object(r.createElement)(D,{className:"banner message-is-unread"})),Object(r.createElement)(s.Section,null,!n&&!c&&$({hasNotes:p,isBatchUpdating:c,lastRead:d,notes:i}))))}))},845:function(e,t,n){"use strict";n.r(t);var c=n(17),a=n.n(c),r=n(15),o=n.n(r),i=n(18),s=n.n(i),l=n(19),m=n.n(l),u=n(9),d=n.n(u),b=n(0),f=n(3),p=n(4),v=n.n(p),_=n(20),h=n(72),y=n(104),O=n.n(y),w=n(42),g=n.n(w),j=n(2),E=n(1),N=n.n(E),R=n(77),k=n(36),D=n(35),C=n(64),x=n(773),T=n(774),A=n(772);function S(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=d()(e);if(t){var a=d()(this).constructor;n=Reflect.construct(c,arguments,a)}else n=c.apply(this,arguments);return m()(this,n)}}var M=function(e){s()(n,e);var t=S(n);function n(){var e;return a()(this,n),(e=t.call(this)).mountTime=(new Date).getTime(),e}return o()(n,[{key:"recordReviewEvent",value:function(e){Object(C.recordEvent)("activity_panel_reviews_".concat(e),{})}},{key:"renderReview",value:function(e,t){var n=this,c=t.lastRead,a=e&&e._embedded&&e._embedded.up&&e._embedded.up[0]||null;if(Object(j.isNull)(a))return null;var r=g()({mixedString:Object(f.sprintf)(Object(f.__)("{{productLink}}%s{{/productLink}} reviewed by {{authorLink}}%s{{/authorLink}}",'woocommerce'),a.name,e.reviewer),components:{productLink:Object(b.createElement)(R.Link,{href:a.permalink,onClick:function(){return n.recordReviewEvent("product")},type:"external"}),authorLink:Object(b.createElement)(R.Link,{href:"mailto:"+e.reviewer_email,onClick:function(){return n.recordReviewEvent("customer")},type:"external"})}}),o=Object(b.createElement)(b.Fragment,null,Object(b.createElement)(R.ReviewRating,{review:e}),e.verified&&Object(b.createElement)("span",{className:"woocommerce-review-activity-card__verified"},Object(b.createElement)(O.a,{icon:"checkmark",size:18}),Object(f.__)("Verified customer",'woocommerce'))),i=Object(j.get)(a,["images",0])||Object(j.get)(a,["image"]),s=v()("woocommerce-review-activity-card__image-overlay__product",{"is-placeholder":!i||!i.src}),l=Object(b.createElement)("div",{className:"woocommerce-review-activity-card__image-overlay"},Object(b.createElement)(R.Gravatar,{user:e.reviewer_email,size:24}),Object(b.createElement)("div",{className:s},Object(b.createElement)(R.ProductImage,{product:a}))),m={date:e.date_created_gmt,status:e.status},u=Object(b.createElement)(h.a,{isSecondary:!0,onClick:function(){return Object(C.recordEvent)("review_manage_click",m)},href:Object(k.f)("comment.php?action=editcomment&c="+e.id)},Object(f.__)("Manage",'woocommerce'));return Object(b.createElement)(x.a,{className:"woocommerce-review-activity-card",key:e.id,title:r,subtitle:o,date:e.date_created_gmt,icon:l,actions:u,unread:"hold"===e.status||!c||!e.date_created_gmt||new Date(e.date_created_gmt+"Z").getTime()>c},Object(b.createElement)("span",{dangerouslySetInnerHTML:Object(A.a)(e.review)}))}},{key:"renderEmptyMessage",value:function(){var e=this,t=this.props.lastApprovedReviewTime,n=Object(f.__)("You have no reviews to moderate",'woocommerce'),c="",a="",r="",o="",i="learn_more";if(t){((new Date).getTime()-t)/864e5>30?(c="https://woocommerce.com/posts/reviews-woocommerce-best-practices/",a="_blank",r=Object(f.__)("Learn more",'woocommerce'),o=Object(b.createElement)(b.Fragment,null,Object(b.createElement)("p",null,Object(f.__)("We noticed that it's been a while since your products had any reviews.",'woocommerce')),Object(b.createElement)("p",null,Object(f.__)("Take some time to learn about best practices for collecting and using your reviews.",'woocommerce')))):(c=Object(k.f)("edit-comments.php?comment_type=review"),r=Object(f.__)("View all Reviews",'woocommerce'),o=Object(b.createElement)("p",null,Object(f.__)("Awesome, you've moderated all of your product reviews. How about responding to some of those negative reviews?",'woocommerce')),i="view_reviews")}else c="https://woocommerce.com/posts/reviews-woocommerce-best-practices/",a="_blank",r=Object(f.__)("Learn more",'woocommerce'),o=Object(b.createElement)(b.Fragment,null,Object(b.createElement)("p",null,Object(f.__)("Your customers haven't started reviewing your products.",'woocommerce')),Object(b.createElement)("p",null,Object(f.__)("Take some time to learn about best practices for collecting and using your reviews.",'woocommerce')));return Object(b.createElement)(x.a,{className:"woocommerce-empty-activity-card",title:n,icon:Object(b.createElement)(O.a,{icon:"time",size:48}),actions:Object(b.createElement)(h.a,{href:c,target:a,isSecondary:!0,onClick:function(){return e.recordReviewEvent(i)}},r)},o)}},{key:"render",value:function(){var e=this,t=this.props,n=t.isError,c=t.isRequesting,a=t.reviews;if(n){var r=Object(f.__)("There was an error getting your reviews. Please try again.",'woocommerce'),o=Object(f.__)("Reload",'woocommerce');return Object(b.createElement)(b.Fragment,null,Object(b.createElement)(R.EmptyContent,{title:r,actionLabel:o,actionURL:null,actionCallback:function(){window.location.reload()}}))}var i=c||a.length?Object(f.__)("Reviews",'woocommerce'):Object(f.__)("No reviews to moderate",'woocommerce');return Object(b.createElement)(b.Fragment,null,Object(b.createElement)(T.a,{title:i}),Object(b.createElement)(R.Section,null,c?Object(b.createElement)(x.b,{className:"woocommerce-review-activity-card",hasAction:!0,hasDate:!0,lines:2}):Object(b.createElement)(b.Fragment,null,a.length?a.map((function(t){return e.renderReview(t,e.props)})):this.renderEmptyMessage())))}}]),n}(b.Component);M.propTypes={reviews:N.a.array.isRequired,isError:N.a.bool,isRequesting:N.a.bool},M.defaultProps={reviews:[],isError:!1,isRequesting:!1},t.default=Object(_.withSelect)((function(e,t){var n=t.hasUnapprovedReviews,c=e(D.REVIEWS_STORE_NAME),a=c.getReviews,r=c.getReviewsError,o=c.isResolving,i=[],s=!1,l=!1,m=null;if(n){var u={page:1,per_page:D.QUERY_DEFAULTS.pageSize,status:"hold",_embed:1};i=a(u),s=Boolean(r(u)),l=o("getReviews",[u])}else{var d={page:1,per_page:1,status:"approved",_embed:1},b=a(d);if(b.length){var f=b[0];if(f.date_created_gmt)m=new Date(f.date_created_gmt).getTime()}s=Boolean(r(d)),l=o("getReviews",[d])}return{reviews:i,isError:s,isRequesting:l,lastApprovedReviewTime:m}}))(M)}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/activity-panels-stock.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/activity-panels-stock.js new file mode 100644 index 0000000..9a21320 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/activity-panels-stock.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[12],{439:function(e,t,n){"use strict";var c=n(8),r=n(12),a=n(4),o=n.n(a),i=n(0);function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);t&&(c=c.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,c)}return n}t.a=function(e){var t=e.as,n=void 0===t?"div":t,a=e.className,u=Object(r.a)(e,["as","className"]);return function(e){var t=e.as,n=void 0===t?"div":t,c=Object(r.a)(e,["as"]);return"function"==typeof c.children?c.children(c):Object(i.createElement)(n,c)}(function(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:window,t=e.navigator.platform;return-1!==t.indexOf("Mac")||Object(a.includes)(["iPad","iPhone"],t)}var s=8,u=9,l=13,m=27,d=32,f=37,p=38,b=39,y=40,v="alt",h="ctrl",O="shift",j={primary:function(e){return e()?["meta"]:[h]},primaryShift:function(e){return e()?[O,"meta"]:[h,O]},primaryAlt:function(e){return e()?[v,"meta"]:[h,v]},secondary:function(e){return e()?[O,v,"meta"]:[h,O,v]},access:function(e){return e()?[h,v]:[O,v]},ctrl:function(){return[h]},alt:function(){return[v]},ctrlShift:function(){return[h,O]},shift:function(){return[O]},shiftAlt:function(){return[O,v]}},_=(Object(a.mapValues)(j,(function(e){return function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:i;return[].concat(Object(r.a)(e(n)),[t.toLowerCase()]).join("+")}})),Object(a.mapValues)(j,(function(e){return function(t){var n,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:i,s=o(),u=(n={},Object(c.a)(n,v,s?"⌥":"Alt"),Object(c.a)(n,h,s?"^":"Ctrl"),Object(c.a)(n,"meta","⌘"),Object(c.a)(n,O,s?"⇧":"Shift"),n),l=e(o).reduce((function(e,t){var n=Object(a.get)(u,t,t);return[].concat(Object(r.a)(e),s?[n]:[n,"+"])}),[]),m=Object(a.capitalize)(t);return[].concat(Object(r.a)(l),[m])}})));Object(a.mapValues)(_,(function(e){return function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:i;return e(t,n).join("")}})),Object(a.mapValues)(j,(function(e){return function(t){var n,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:i,u=s(),l=(n={},Object(c.a)(n,O,"Shift"),Object(c.a)(n,"meta",u?"Command":"Control"),Object(c.a)(n,h,"Control"),Object(c.a)(n,v,u?"Option":"Alt"),Object(c.a)(n,",",Object(o.__)("Comma")),Object(c.a)(n,".",Object(o.__)("Period")),Object(c.a)(n,"`",Object(o.__)("Backtick")),n);return[].concat(Object(r.a)(e(s)),[t]).map((function(e){return Object(a.capitalize)(Object(a.get)(l,e,e))})).join(u?" ":" + ")}})),Object(a.mapValues)(j,(function(e){return function(t,n){var c=arguments.length>2&&void 0!==arguments[2]?arguments[2]:i,r=e(c);return!!r.every((function(e){return t["".concat(e,"Key")]}))&&(n?t.key===n:Object(a.includes)(r,t.key.toLowerCase()))}}))},767:function(e,t,n){"use strict";var c=n(0),r=n(4),a=n.n(r),o=n(439);function i(e){var t=e.id,n=e.label,r=e.hideLabelFromVision,s=e.help,u=e.className,l=e.children;return Object(c.createElement)("div",{className:a()("components-base-control",u)},Object(c.createElement)("div",{className:"components-base-control__field"},n&&t&&(r?Object(c.createElement)(o.a,{as:"label",htmlFor:t},n):Object(c.createElement)("label",{className:"components-base-control__label",htmlFor:t},n)),n&&!t&&(r?Object(c.createElement)(o.a,{as:"label"},n):Object(c.createElement)(i.VisualLabel,null,n)),l),!!s&&Object(c.createElement)("p",{id:t+"__help",className:"components-base-control__help"},s))}i.VisualLabel=function(e){var t=e.className,n=e.children;return t=a()("components-base-control__label",t),Object(c.createElement)("span",{className:t},n)},t.a=i},773:function(e,t,n){"use strict";n.d(t,"a",(function(){return C})),n.d(t,"b",(function(){return S}));var c=n(17),r=n.n(c),a=n(15),o=n.n(a),i=n(18),s=n.n(i),u=n(19),l=n.n(u),m=n(9),d=n.n(m),f=n(0),p=n(4),b=n.n(p),y=n(104),v=n.n(y),h=n(16),O=n.n(h),j=n(1),_=n.n(j),E=n(77),g=n(72),w=(n(777),n(2));function k(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=d()(e);if(t){var r=d()(this).constructor;n=Reflect.construct(c,arguments,r)}else n=c.apply(this,arguments);return l()(this,n)}}var N=function(e){s()(n,e);var t=k(n);function n(){return r()(this,n),t.apply(this,arguments)}return o()(n,[{key:"render",value:function(){var e=this.props,t=e.className,n=e.hasAction,c=e.hasDate,r=e.hasSubtitle,a=e.lines,o=b()("woocommerce-activity-card is-loading",t);return Object(f.createElement)("div",{className:o,"aria-hidden":!0},Object(f.createElement)("span",{className:"woocommerce-activity-card__icon"},Object(f.createElement)("span",{className:"is-placeholder"})),Object(f.createElement)("div",{className:"woocommerce-activity-card__header"},Object(f.createElement)("div",{className:"woocommerce-activity-card__title is-placeholder"}),r&&Object(f.createElement)("div",{className:"woocommerce-activity-card__subtitle is-placeholder"}),c&&Object(f.createElement)("div",{className:"woocommerce-activity-card__date"},Object(f.createElement)("span",{className:"is-placeholder"}))),Object(f.createElement)("div",{className:"woocommerce-activity-card__body"},Object(w.range)(a).map((function(e){return Object(f.createElement)("span",{className:"is-placeholder",key:e})}))),n&&Object(f.createElement)("div",{className:"woocommerce-activity-card__actions"},Object(f.createElement)("span",{className:"is-placeholder"})))}}]),n}(f.Component);N.propTypes={className:_.a.string,hasAction:_.a.bool,hasDate:_.a.bool,hasSubtitle:_.a.bool,lines:_.a.number},N.defaultProps={hasAction:!1,hasDate:!1,hasSubtitle:!1,lines:1};var S=N;function R(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=d()(e);if(t){var r=d()(this).constructor;n=Reflect.construct(c,arguments,r)}else n=c.apply(this,arguments);return l()(this,n)}}var C=function(e){s()(n,e);var t=R(n);function n(){return r()(this,n),t.apply(this,arguments)}return o()(n,[{key:"getCard",value:function(){var e=this.props,t=e.actions,n=e.className,c=e.children,r=e.date,a=e.icon,o=e.subtitle,i=e.title,s=e.unread,u=b()("woocommerce-activity-card",n),l=Array.isArray(t)?t:[t];return Object(f.createElement)("section",{className:u},s&&Object(f.createElement)("span",{className:"woocommerce-activity-card__unread"}),a&&Object(f.createElement)("span",{className:"woocommerce-activity-card__icon","aria-hidden":!0},a),i&&Object(f.createElement)("header",{className:"woocommerce-activity-card__header"},Object(f.createElement)(E.H,{className:"woocommerce-activity-card__title"},i),o&&Object(f.createElement)("div",{className:"woocommerce-activity-card__subtitle"},o),r&&Object(f.createElement)("span",{className:"woocommerce-activity-card__date"},O.a.utc(r).fromNow())),c&&Object(f.createElement)(E.Section,{className:"woocommerce-activity-card__body"},c),t&&Object(f.createElement)("footer",{className:"woocommerce-activity-card__actions"},l.map((function(e,t){return Object(f.cloneElement)(e,{key:t})}))))}},{key:"render",value:function(){var e=this.props.onClick;return e?Object(f.createElement)(g.a,{className:"woocommerce-activity-card__button",onClick:e},this.getCard()):this.getCard()}}]),n}(f.Component);C.propTypes={actions:_.a.oneOfType([_.a.arrayOf(_.a.element),_.a.element]),onClick:_.a.func,className:_.a.string,children:_.a.node,date:_.a.string,icon:_.a.node,subtitle:_.a.node,title:_.a.oneOfType([_.a.string,_.a.node]),unread:_.a.bool},C.defaultProps={icon:Object(f.createElement)(v.a,{icon:"notice-outline",size:48}),unread:!1}},774:function(e,t,n){"use strict";var c=n(17),r=n.n(c),a=n(15),o=n.n(a),i=n(18),s=n.n(i),u=n(19),l=n.n(u),m=n(9),d=n.n(m),f=n(0),p=n(4),b=n.n(p),y=n(1),v=n.n(y),h=n(190),O=n(77);n(775);function j(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=d()(e);if(t){var r=d()(this).constructor;n=Reflect.construct(c,arguments,r)}else n=c.apply(this,arguments);return l()(this,n)}}var _=function(e){s()(n,e);var t=j(n);function n(){return r()(this,n),t.apply(this,arguments)}return o()(n,[{key:"render",value:function(){var e=this.props,t=e.className,n=e.menu,c=e.subtitle,r=e.title,a=e.unreadMessages,o=b()({"woocommerce-layout__inbox-panel-header":c,"woocommerce-layout__activity-panel-header":!c},t),i=a||0;return Object(f.createElement)("div",{className:o},Object(f.createElement)("div",{className:"woocommerce-layout__inbox-title"},Object(f.createElement)(h.a,{variant:"title.small"},r),Object(f.createElement)(h.a,{variant:"button"},i>0&&Object(f.createElement)("span",{className:"woocommerce-layout__inbox-badge"},a))),Object(f.createElement)("div",{className:"woocommerce-layout__inbox-subtitle"},c&&Object(f.createElement)(h.a,{variant:"body.small"},c)),n&&Object(f.createElement)("div",{className:"woocommerce-layout__activity-panel-header-menu"},n))}}]),n}(f.Component);_.propTypes={className:v.a.string,unreadMessages:v.a.number,title:v.a.string.isRequired,subtitle:v.a.string,menu:v.a.shape({type:v.a.oneOf([O.EllipsisMenu])})},t.a=_},775:function(e,t,n){},777:function(e,t,n){},856:function(e,t,n){"use strict";n.r(t);var c=n(17),r=n.n(c),a=n(15),o=n.n(a),i=n(18),s=n.n(i),u=n(19),l=n.n(u),m=n(9),d=n.n(m),f=n(0),p=n(3),b=n(277),y=n(20),v=n(1),h=n.n(v),O=n(104),j=n.n(O),_=n(77),E=n(35),g=n(773),w=n(774),k=n(14),N=n.n(k),S=n(98),R=n.n(S),C=n(11),P=n.n(C),D=n(72),q=n(767),A=n(4),x=n.n(A),T=n(71),L=n(2),I=n(36),F=n(64);function M(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=d()(e);if(t){var r=d()(this).constructor;n=Reflect.construct(c,arguments,r)}else n=c.apply(this,arguments);return l()(this,n)}}var V=function(e){s()(c,e);var t,n=M(c);function c(e){var t;return r()(this,c),(t=n.call(this,e)).state={quantity:e.product.stock_quantity,editing:!1,edited:!1},t.beginEdit=t.beginEdit.bind(P()(t)),t.cancelEdit=t.cancelEdit.bind(P()(t)),t.onQuantityChange=t.onQuantityChange.bind(P()(t)),t.handleKeyDown=t.handleKeyDown.bind(P()(t)),t.onSubmit=t.onSubmit.bind(P()(t)),t}return o()(c,[{key:"recordStockEvent",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};Object(F.recordEvent)("activity_panel_stock_".concat(e),t)}},{key:"beginEdit",value:function(){var e=this,t=this.props.product;this.setState({editing:!0,quantity:t.stock_quantity},(function(){e.quantityInput&&e.quantityInput.focus()})),this.recordStockEvent("update_stock")}},{key:"cancelEdit",value:function(){var e=this.props.product;this.setState({editing:!1,quantity:e.stock_quantity}),this.recordStockEvent("cancel")}},{key:"handleKeyDown",value:function(e){e.keyCode===T.d&&this.cancelEdit()}},{key:"onQuantityChange",value:function(e){this.setState({quantity:e.target.value})}},{key:"onSubmit",value:(t=R()(N.a.mark((function e(){var t,n,c,r,a;return N.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t=this.props,n=t.product,c=t.updateProductStock,r=t.createNotice,a=this.state.quantity,this.setState({editing:!1,edited:!0}),e.next=5,c(n,a);case 5:e.sent.success?r("success",Object(p.sprintf)(Object(p.__)("%s stock updated.",'woocommerce'),n.name)):r("error",Object(p.sprintf)(Object(p.__)("%s stock could not be updated.",'woocommerce'),n.name)),this.recordStockEvent("save",{quantity:a});case 8:case"end":return e.stop()}}),e,this)}))),function(){return t.apply(this,arguments)})},{key:"getActions",value:function(){return this.state.editing?[Object(f.createElement)(D.a,{key:"save",type:"submit",isPrimary:!0},Object(p.__)("Save",'woocommerce')),Object(f.createElement)(D.a,{key:"cancel",type:"reset"},Object(p.__)("Cancel",'woocommerce'))]:[Object(f.createElement)(D.a,{key:"update",isSecondary:!0,onClick:this.beginEdit},Object(p.__)("Update stock",'woocommerce'))]}},{key:"getBody",value:function(){var e=this,t=this.props.product,n=this.state,c=n.editing,r=n.quantity;return c?Object(f.createElement)(f.Fragment,null,Object(f.createElement)(q.a,{className:"woocommerce-stock-activity-card__edit-quantity"},Object(f.createElement)("input",{className:"components-text-control__input",type:"number",value:r,onKeyDown:this.handleKeyDown,onChange:this.onQuantityChange,ref:function(t){e.quantityInput=t}})),Object(f.createElement)("span",null,Object(p.__)("in stock",'woocommerce'))):Object(f.createElement)("span",{className:"woocommerce-stock-activity-card__stock-quantity"},Object(p.sprintf)(Object(p.__)("%d in stock",'woocommerce'),t.stock_quantity))}},{key:"render",value:function(){var e=this,t=this.props.product,n=this.state,c=n.edited,r=n.editing,a=Object(I.g)("notifyLowStockAmount",0),o=Number.isFinite(t.low_stock_amount)?t.low_stock_amount:a,i=t.stock_quantity<=o;if(!i&&!c)return null;var s=Object(f.createElement)(_.Link,{href:"post.php?action=edit&post="+(t.parent_id||t.id),onClick:function(){return e.recordStockEvent("product_name")},type:"wp-admin"},t.name),u=null;"variation"===t.type&&(u=Object.values(t.attributes).map((function(e){return e.option})).join(", "));var l=Object(L.get)(t,["images",0])||Object(L.get)(t,["image"]),m=x()("woocommerce-stock-activity-card__image-overlay__product",{"is-placeholder":!l||!l.src}),d=Object(f.createElement)("div",{className:"woocommerce-stock-activity-card__image-overlay"},Object(f.createElement)("div",{className:m},Object(f.createElement)(_.ProductImage,{product:t}))),p=x()("woocommerce-stock-activity-card",{"is-dimmed":!r&&!i}),b=Object(f.createElement)(g.a,{className:p,title:s,subtitle:u,icon:d,actions:this.getActions()},this.getBody());return r?Object(f.createElement)("form",{onReset:this.cancelEdit,onSubmit:this.onSubmit},b):b}}]),c}(f.Component),K=Object(b.a)(Object(y.withDispatch)((function(e){var t=e("core/notices").createNotice;return{updateProductStock:e(E.ITEMS_STORE_NAME).updateProductStock,createNotice:t}})))(V);function z(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,c=d()(e);if(t){var r=d()(this).constructor;n=Reflect.construct(c,arguments,r)}else n=c.apply(this,arguments);return l()(this,n)}}var Q=function(e){s()(n,e);var t=z(n);function n(){return r()(this,n),t.apply(this,arguments)}return o()(n,[{key:"renderEmptyCard",value:function(){return Object(f.createElement)(g.a,{className:"woocommerce-empty-activity-card",title:Object(p.__)("Your stock is in good shape.",'woocommerce'),icon:Object(f.createElement)(j.a,{icon:"checkmark",size:48})},Object(p.__)("You currently have no products running low on stock.",'woocommerce'))}},{key:"renderProducts",value:function(){var e=this.props.products;return 0===e.length?this.renderEmptyCard():e.map((function(e){return Object(f.createElement)(K,{key:e.id,product:e})}))}},{key:"render",value:function(){var e=this.props,t=e.isError,n=e.isRequesting,c=e.products;if(t){var r=Object(p.__)("There was an error getting your low stock products. Please try again.",'woocommerce'),a=Object(p.__)("Reload",'woocommerce');return Object(f.createElement)(f.Fragment,null,Object(f.createElement)(_.EmptyContent,{title:r,actionLabel:a,actionURL:null,actionCallback:function(){window.location.reload()}}))}var o=n||c.length>0?Object(p.__)("Stock",'woocommerce'):Object(p.__)("No products with low stock",'woocommerce');return Object(f.createElement)(f.Fragment,null,Object(f.createElement)(w.a,{title:o}),Object(f.createElement)(_.Section,null,n?Object(f.createElement)(g.b,{className:"woocommerce-stock-activity-card",hasAction:!0,lines:1}):this.renderProducts()))}}]),n}(f.Component);Q.propTypes={products:h.a.array.isRequired,isError:h.a.bool,isRequesting:h.a.bool},Q.defaultProps={products:[],isError:!1,isRequesting:!1};t.default=Object(b.a)(Object(y.withSelect)((function(e){var t=e(E.ITEMS_STORE_NAME),n=t.getItems,c=t.getItemsError,r=t.isResolving,a={page:1,per_page:E.QUERY_DEFAULTS.pageSize,low_in_stock:!0,status:"publish"};return{products:Array.from(n("products",a).values()),isError:Boolean(c("products",a)),isRequesting:r("getItems",["products",a])}})))(Q)},98:function(e,t){function n(e,t,n,c,r,a,o){try{var i=e[a](o),s=i.value}catch(e){return void n(e)}i.done?t(s):Promise.resolve(s).then(c,r)}e.exports=function(e){return function(){var t=this,c=arguments;return new Promise((function(r,a){var o=e.apply(t,c);function i(e){n(o,r,a,i,s,"next",e)}function s(e){n(o,r,a,i,s,"throw",e)}i(void 0)}))}}}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-categories.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-categories.js new file mode 100644 index 0000000..6969d26 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-categories.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[14],{743:function(e,t,r){"use strict";r.r(t),r.d(t,"default",(function(){return z}));var o=r(5),c=r.n(o),a=r(17),n=r.n(a),i=r(15),s=r.n(i),l=r(18),m=r.n(l),u=r(19),d=r.n(u),g=r(9),p=r.n(g),b=r(0),y=r(1),_=r.n(y),f=r(3),O=r(55),h=r(764),j=Object(O.applyFilters)("woocommerce_admin_categories_report_charts",[{key:"items_sold",label:Object(f.__)("Items Sold",'woocommerce'),order:"desc",orderby:"items_sold",type:"number"},{key:"net_revenue",label:Object(f.__)("Net Sales",'woocommerce'),order:"desc",orderby:"net_revenue",type:"currency"},{key:"orders_count",label:Object(f.__)("Orders",'woocommerce'),order:"desc",orderby:"orders_count",type:"number"}]),v=Object(O.applyFilters)("woocommerce_admin_categories_report_filters",[{label:Object(f.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(f.__)("All Categories",'woocommerce'),value:"all"},{label:Object(f.__)("Single Category",'woocommerce'),value:"select_category",chartMode:"item-comparison",subFilters:[{component:"Search",value:"single_category",chartMode:"item-comparison",path:["select_category"],settings:{type:"categories",param:"categories",getLabels:h.a,labels:{placeholder:Object(f.__)("Type to search for a category",'woocommerce'),button:Object(f.__)("Single Category",'woocommerce')}}}]},{label:Object(f.__)("Comparison",'woocommerce'),value:"compare-categories",chartMode:"item-comparison",settings:{type:"categories",param:"categories",getLabels:h.a,labels:{helpText:Object(f.__)("Check at least two categories below to compare",'woocommerce'),placeholder:Object(f.__)("Search for categories to compare",'woocommerce'),title:Object(f.__)("Compare Categories",'woocommerce'),update:Object(f.__)("Compare",'woocommerce')}}}]}]),w=Object(O.applyFilters)("woocommerce_admin_category_report_advanced_filters",{}),C=r(11),S=r.n(C),R=r(277),q=r(20),k=r(2),P=r(32),E=r(77),F=r(298),D=r(35),x=r(796),N=r(771),T=r(762);function V(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,o=p()(e);if(t){var c=p()(this).constructor;r=Reflect.construct(o,arguments,c)}else r=o.apply(this,arguments);return d()(this,r)}}var I=function(e){m()(r,e);var t=V(r);function r(e){var o;return n()(this,r),(o=t.call(this,e)).getRowsContent=o.getRowsContent.bind(S()(o)),o.getSummary=o.getSummary.bind(S()(o)),o}return s()(r,[{key:"getHeadersContent",value:function(){return[{label:Object(f.__)("Category",'woocommerce'),key:"category",required:!0,isSortable:!0,isLeftAligned:!0},{label:Object(f.__)("Items Sold",'woocommerce'),key:"items_sold",required:!0,defaultSort:!0,isSortable:!0,isNumeric:!0},{label:Object(f.__)("Net Sales",'woocommerce'),key:"net_revenue",isSortable:!0,isNumeric:!0},{label:Object(f.__)("Products",'woocommerce'),key:"products_count",isSortable:!0,isNumeric:!0},{label:Object(f.__)("Orders",'woocommerce'),key:"orders_count",isSortable:!0,isNumeric:!0}]}},{key:"getRowsContent",value:function(e){var t=this,r=this.context,o=r.render,c=r.formatDecimal,a=(0,r.getCurrencyConfig)();return Object(k.map)(e,(function(e){var r=e.category_id,n=e.items_sold,i=e.net_revenue,s=e.products_count,l=e.orders_count,m=t.props,u=m.categories,d=m.query,g=u.get(r),p=Object(P.getPersistedQuery)(d);return[{display:Object(b.createElement)(x.a,{query:d,category:g,categories:u}),value:g&&g.name},{display:Object(F.formatValue)(a,"number",n),value:n},{display:o(i),value:c(i)},{display:g&&Object(b.createElement)(E.Link,{href:Object(P.getNewPath)(p,"/analytics/categories",{filter:"single_category",categories:g.id}),type:"wc-admin"},Object(F.formatValue)(a,"number",s)),value:s},{display:Object(F.formatValue)(a,"number",l),value:l}]}))}},{key:"getSummary",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=e.items_sold,o=void 0===r?0:r,c=e.net_revenue,a=void 0===c?0:c,n=e.orders_count,i=void 0===n?0:n,s=this.context,l=s.formatAmount,m=s.getCurrencyConfig,u=m();return[{label:Object(f._n)("category","categories",t,'woocommerce'),value:Object(F.formatValue)(u,"number",t)},{label:Object(f._n)("item sold","items sold",o,'woocommerce'),value:Object(F.formatValue)(u,"number",o)},{label:Object(f.__)("net sales",'woocommerce'),value:l(a)},{label:Object(f._n)("order","orders",i,'woocommerce'),value:Object(F.formatValue)(u,"number",i)}]}},{key:"render",value:function(){var e=this.props,t=e.advancedFilters,r=e.filters,o=e.isRequesting,c=e.query,a={helpText:Object(f.__)("Check at least two categories below to compare",'woocommerce'),placeholder:Object(f.__)("Search by category name",'woocommerce')};return Object(b.createElement)(N.a,{compareBy:"categories",endpoint:"categories",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,getSummary:this.getSummary,summaryFields:["items_sold","net_revenue","orders_count"],isRequesting:o,itemIdField:"category_id",query:c,searchBy:"categories",labels:a,tableQuery:{orderby:c.orderby||"items_sold",order:c.order||"desc",extended_info:!0},title:Object(f.__)("Categories",'woocommerce'),columnPrefsKey:"categories_report_columns",filters:r,advancedFilters:t})}}]),r}(b.Component);I.contextType=T.a;var L=Object(R.a)(Object(q.withSelect)((function(e,t){var r=t.isRequesting,o=t.query;if(r||o.search&&(!o.categories||!o.categories.length))return{};var c=e(D.ITEMS_STORE_NAME),a=c.getItems,n=c.getItemsError,i=c.isResolving,s={per_page:-1};return{categories:a("categories",s),isError:Boolean(n("categories",s)),isRequesting:i("getItems",["categories",s])}})))(I),M=r(768),A=r(766),B=r(769),H=r(795),Q=r(770);function J(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function K(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,o=p()(e);if(t){var c=p()(this).constructor;r=Reflect.construct(o,arguments,c)}else r=o.apply(this,arguments);return d()(this,r)}}var z=function(e){m()(r,e);var t=K(r);function r(){return n()(this,r),t.apply(this,arguments)}return s()(r,[{key:"getChartMeta",value:function(){var e=this.props.query,t="compare-categories"===e.filter&&e.categories&&e.categories.split(",").length>1,r="single_category"===e.filter&&!!e.categories,o=t||r?"item-comparison":"time-comparison";return{isSingleCategoryView:r,itemsLabel:r?Object(f.__)("%d products",'woocommerce'):Object(f.__)("%d categories",'woocommerce'),mode:o}}},{key:"render",value:function(){var e=this.props,t=e.isRequesting,r=e.query,o=e.path,a=this.getChartMeta(),n=a.mode,i=a.itemsLabel,s=a.isSingleCategoryView,l=function(e){for(var t=1;t0?Object(R.getNewPath)(n,"/analytics/coupons",{filter:"single_coupon",coupons:o}):null,g=null===b?m:Object(y.createElement)(w.Link,{href:b,type:"wc-admin"},m),h=o>0?Object(R.getNewPath)(n,"/analytics/orders",{filter:"advanced",coupon_includes:o}):null;return[{display:g,value:m},{display:null===h?s:Object(y.createElement)(w.Link,{href:h,type:"wc-admin"},Object(C.formatValue)(u(),"number",s)),value:s},{display:c(r),value:i(r)},{display:d?Object(y.createElement)(w.Date,{date:d,visibleFormat:a}):Object(v.__)("N/A",'woocommerce'),value:d},{display:p?Object(y.createElement)(w.Date,{date:p,visibleFormat:a}):Object(v.__)("N/A",'woocommerce'),value:p},{display:t.getCouponType(f),value:f}]}))}},{key:"getSummary",value:function(e){var t=e.coupons_count,r=void 0===t?0:t,n=e.orders_count,a=void 0===n?0:n,o=e.amount,c=void 0===o?0:o,i=this.context,u=i.formatAmount,s=(0,i.getCurrencyConfig)();return[{label:Object(v._n)("coupon","coupons",r,'woocommerce'),value:Object(C.formatValue)(s,"number",r)},{label:Object(v._n)("order","orders",a,'woocommerce'),value:Object(C.formatValue)(s,"number",a)},{label:Object(v.__)("amount discounted",'woocommerce'),value:u(c)}]}},{key:"getCouponType",value:function(e){return{percent:Object(v.__)("Percentage",'woocommerce'),fixed_cart:Object(v.__)("Fixed cart",'woocommerce'),fixed_product:Object(v.__)("Fixed product",'woocommerce')}[e]||Object(v.__)("N/A",'woocommerce')}},{key:"render",value:function(){var e=this.props,t=e.advancedFilters,r=e.filters,n=e.isRequesting,a=e.query;return Object(y.createElement)(k.a,{compareBy:"coupons",endpoint:"coupons",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,getSummary:this.getSummary,summaryFields:["coupons_count","orders_count","amount"],isRequesting:n,itemIdField:"coupon_id",query:a,searchBy:"coupons",tableQuery:{orderby:a.orderby||"orders_count",order:a.order||"desc",extended_info:!0},title:Object(v.__)("Coupons",'woocommerce'),columnPrefsKey:"coupons_report_columns",filters:r,advancedFilters:t})}}]),r}(y.Component);S.contextType=E.a;var F=S,T=r(768),A=r(766),x=r(769),N=r(770);function L(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function M(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,n=f()(e);if(t){var a=f()(this).constructor;r=Reflect.construct(n,arguments,a)}else r=n.apply(this,arguments);return d()(this,r)}}var V=function(e){l()(r,e);var t=M(r);function r(){return c()(this,r),t.apply(this,arguments)}return u()(r,[{key:"getChartMeta",value:function(){var e=this.props.query,t="compare-coupons"===e.filter&&e.coupons&&e.coupons.split(",").length>1?"item-comparison":"time-comparison";return{itemsLabel:Object(v.__)("%d coupons",'woocommerce'),mode:t}}},{key:"render",value:function(){var e=this.props,t=e.isRequesting,r=e.query,n=e.path,o=this.getChartMeta(),c=o.mode,i=o.itemsLabel,u=function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:c.identity;return function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",a=arguments.length>1?arguments[1]:void 0,c="function"==typeof e?e(a):e,u=Object(i.getIdsFromQuery)(r);if(u.length<1)return Promise.resolve([]);var s={include:u.join(","),per_page:u.length};return o()({path:Object(n.addQueryArgs)(c,s)}).then((function(e){return e.map(t)}))}}var d=m(u.NAMESPACE+"/products/categories",(function(e){return{key:e.id,label:e.name}})),p=m(u.NAMESPACE+"/coupons",(function(e){return{key:e.id,label:e.code}})),f=m(u.NAMESPACE+"/customers",(function(e){return{key:e.id,label:e.name}})),y=m(u.NAMESPACE+"/products",(function(e){return{key:e.id,label:e.name}})),b=m(u.NAMESPACE+"/taxes",(function(e){return{key:e.id,label:Object(l.a)(e)}}));function g(e){var t=e.attributes,r=e.name,n=Object(s.g)("variationTitleAttributesSeparator"," - ");if(r.indexOf(n)>-1)return r;var a=t.map((function(e){return e.option})).join(", ");return a?r+n+a:r}var v=m((function(e){var t=e.products;return t?u.NAMESPACE+"/products/".concat(t,"/variations"):u.NAMESPACE+"/variations"}),(function(e){return{key:e.id,label:g(e)}}))},765:function(e,t,r){"use strict";r.d(t,"a",(function(){return a}));var n=r(3);function a(e){return[e.country,e.state,e.name||Object(n.__)("TAX",'woocommerce'),e.priority].map((function(e){return e.toString().toUpperCase().trim()})).filter(Boolean).join("-")}},766:function(e,t,r){"use strict";var n=r(5),a=r.n(n),o=r(17),c=r.n(o),i=r(15),u=r.n(i),s=r(18),l=r.n(s),m=r(19),d=r.n(m),p=r(9),f=r.n(p),y=r(0),b=r(3),g=r(277),v=r(154),h=r(20),O=r(2),_=r(1),j=r.n(_),w=r(77),R=r(35),C=r(40),D=r(762),q=r(763),k=r(32);function E(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function P(e){for(var t=1;t2&&void 0!==arguments[2]?arguments[2]:{};if(!t||0===t.length)return null;var a=t.slice(0),o=a.pop();if(o.showFilters(r,n)){var c=Object(k.flattenFilters)(o.filters),i=r[o.param]||o.defaultValue||"all";return Object(O.find)(c,{value:i})}return e(a,r,n)}(a,i),m=Object(O.get)(l,["settings","param"]),d=t.mode||function(e,t){if(e&&t){var r=Object(O.get)(e,["settings","param"]);if(!r||Object.keys(t).includes(r))return Object(O.get)(e,["chartMode"])}return null}(l,i)||"time-comparison",p=e(R.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,f={mode:d,filterParam:m,defaultDateRange:p};if(o)return f;var y=s.some((function(e){return i[e]&&i[e].length}));if(i.search&&!y)return P(P({},f),{},{emptySearchResults:!0});var b=r&&r.map((function(e){return e.key})),g=Object(R.getReportChartData)({endpoint:n,dataType:"primary",query:i,select:e,limitBy:s,filters:a,advancedFilters:u,defaultDateRange:p,fields:b});if("item-comparison"===d)return P(P({},f),{},{primaryData:g});var v=Object(R.getReportChartData)({endpoint:n,dataType:"secondary",query:i,select:e,limitBy:s,filters:a,advancedFilters:u,defaultDateRange:p,fields:b});return P(P({},f),{},{primaryData:g,secondaryData:v})})))(F)},768:function(e,t,r){"use strict";r.d(t,"a",(function(){return a}));var n=r(2);function a(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=Object(n.find)(t,{key:e});return r||t[0]}},769:function(e,t,r){"use strict";var n=r(17),a=r.n(n),o=r(15),c=r.n(o),i=r(18),u=r.n(i),s=r(19),l=r.n(s),m=r(9),d=r.n(m),p=r(0),f=r(3),y=r(277),b=r(20),g=r(1),v=r.n(g),h=r(32),O=r(77),_=r(298),j=r(35),w=r(40),R=r(64),C=r(763),D=r(762);function q(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,n=d()(e);if(t){var a=d()(this).constructor;r=Reflect.construct(n,arguments,a)}else r=n.apply(this,arguments);return l()(this,r)}}var k=function(e){u()(r,e);var t=q(r);function r(){return a()(this,r),t.apply(this,arguments)}return c()(r,[{key:"formatVal",value:function(e,t){var r=this.context,n=r.formatAmount,a=r.getCurrencyConfig;return"currency"===t?n(e):Object(_.formatValue)(a(),t,e)}},{key:"getValues",value:function(e,t){var r=this.props,n=r.emptySearchResults,a=r.summaryData.totals,o=a.primary?a.primary[e]:0,c=a.secondary?a.secondary[e]:0,i=n?0:o,u=n?0:c;return{delta:Object(_.calculateDelta)(i,u),prevValue:this.formatVal(u,t),value:this.formatVal(i,t)}}},{key:"render",value:function(){var e=this,t=this.props,r=t.charts,n=t.query,a=t.selectedChart,o=t.summaryData,c=t.endpoint,i=t.report,u=t.defaultDateRange,s=o.isError,l=o.isRequesting;if(s)return Object(p.createElement)(C.a,{isError:!0});if(l)return Object(p.createElement)(O.SummaryListPlaceholder,{numberOfItems:r.length});var m=Object(w.getDateParamsFromQuery)(n,u).compare;return Object(p.createElement)(O.SummaryList,null,(function(t){var n=t.onToggle;return r.map((function(t){var r=t.key,o=t.order,u=t.orderby,s=t.label,l=t.type,d={chart:r};u&&(d.orderby=u),o&&(d.order=o);var y=Object(h.getNewPath)(d),b=a.key===r,g=e.getValues(r,l),v=g.delta,_=g.prevValue,j=g.value;return Object(p.createElement)(O.SummaryNumber,{key:r,delta:v,href:y,label:s,prevLabel:"previous_period"===m?Object(f.__)("Previous Period:",'woocommerce'):Object(f.__)("Previous Year:",'woocommerce'),prevValue:_,selected:b,value:j,onLinkClickCallback:function(){n&&n(),Object(R.recordEvent)("analytics_chart_tab_click",{report:i||c,key:r})}})}))}))}}]),r}(p.Component);k.propTypes={charts:v.a.array.isRequired,endpoint:v.a.string.isRequired,limitProperties:v.a.array,query:v.a.object.isRequired,selectedChart:v.a.shape({key:v.a.string.isRequired,label:v.a.string.isRequired,order:v.a.oneOf(["asc","desc"]),orderby:v.a.string,type:v.a.oneOf(["average","number","currency"]).isRequired}).isRequired,summaryData:v.a.object,report:v.a.string},k.defaultProps={summaryData:{totals:{primary:{},secondary:{}},isError:!1}},k.contextType=D.a,t.a=Object(y.a)(Object(b.withSelect)((function(e,t){var r=t.charts,n=t.endpoint,a=t.limitProperties,o=t.query,c=t.filters,i=t.advancedFilters,u=a||[n],s=u.some((function(e){return o[e]&&o[e].length}));if(o.search&&!s)return{emptySearchResults:!0};var l=r&&r.map((function(e){return e.key})),m=e(j.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range;return{summaryData:Object(j.getSummaryNumbers)({endpoint:n,query:o,select:e,limitBy:u,filters:c,advancedFilters:i,defaultDateRange:m,fields:l}),defaultDateRange:m}})))(k)},789:function(e,t,r){"use strict";r.d(t,"b",(function(){return c})),r.d(t,"c",(function(){return i})),r.d(t,"a",(function(){return u}));var n=r(3),a=r(55),o=r(764),c=Object(a.applyFilters)("woocommerce_admin_coupons_report_charts",[{key:"orders_count",label:Object(n.__)("Discounted Orders",'woocommerce'),order:"desc",orderby:"orders_count",type:"number"},{key:"amount",label:Object(n.__)("Amount",'woocommerce'),order:"desc",orderby:"amount",type:"currency"}]),i=Object(a.applyFilters)("woocommerce_admin_coupons_report_filters",[{label:Object(n.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(n.__)("All Coupons",'woocommerce'),value:"all"},{label:Object(n.__)("Single Coupon",'woocommerce'),value:"select_coupon",chartMode:"item-comparison",subFilters:[{component:"Search",value:"single_coupon",chartMode:"item-comparison",path:["select_coupon"],settings:{type:"coupons",param:"coupons",getLabels:o.b,labels:{placeholder:Object(n.__)("Type to search for a coupon",'woocommerce'),button:Object(n.__)("Single Coupon",'woocommerce')}}}]},{label:Object(n.__)("Comparison",'woocommerce'),value:"compare-coupons",settings:{type:"coupons",param:"coupons",getLabels:o.b,labels:{title:Object(n.__)("Compare Coupon Codes",'woocommerce'),update:Object(n.__)("Compare",'woocommerce'),helpText:Object(n.__)("Check at least two coupon codes below to compare",'woocommerce')}}}]}]),u=Object(a.applyFilters)("woocommerce_admin_coupon_report_advanced_filters",{})}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-customers.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-customers.js new file mode 100644 index 0000000..690209d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-customers.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[16],{744:function(e,t,r){"use strict";r.r(t),r.d(t,"default",(function(){return G}));var o,c=r(5),a=r.n(c),n=r(17),m=r.n(n),i=r(15),l=r.n(i),u=r(18),s=r.n(u),d=r(19),b=r.n(d),_=r(9),f=r.n(_),v=r(0),p=r(1),O=r.n(p),j=r(14),w=r.n(j),y=r(98),g=r.n(y),h=r(3),S=r(81),x=r(55),E=r(36),C=r(35),R=r(764),A=Object(E.g)("dataEndpoints",{countries:{}}).countries,k=Object(x.applyFilters)("woocommerce_admin_customers_report_filters",[{label:Object(h.__)("Show",'woocommerce'),staticParams:["paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(h.__)("All Customers",'woocommerce'),value:"all"},{label:Object(h.__)("Single Customer",'woocommerce'),value:"select_customer",chartMode:"item-comparison",subFilters:[{component:"Search",value:"single_customer",chartMode:"item-comparison",path:["select_customer"],settings:{type:"customers",param:"customers",getLabels:R.c,labels:{placeholder:Object(h.__)("Type to search for a customer",'woocommerce'),button:Object(h.__)("Single Customer",'woocommerce')}}}]},{label:Object(h.__)("Advanced Filters",'woocommerce'),value:"advanced"}]}]),P=Object(x.applyFilters)("woocommerce_admin_customers_report_advanced_filters",{title:Object(h._x)("Customers Match {{select /}} Filters","A sentence describing filters for Customers. See screen shot for context: https://cloudup.com/cCsm3GeXJbE",'woocommerce'),filters:{name:{labels:{add:Object(h.__)("Name",'woocommerce'),placeholder:Object(h.__)("Search",'woocommerce'),remove:Object(h.__)("Remove customer name filter",'woocommerce'),rule:Object(h.__)("Select a customer name filter match",'woocommerce'),title:Object(h.__)("{{title}}Name{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(h.__)("Select customer name",'woocommerce')},rules:[{value:"includes",label:Object(h._x)("Includes","customer names",'woocommerce')},{value:"excludes",label:Object(h._x)("Excludes","customer names",'woocommerce')}],input:{component:"Search",type:"customers",getLabels:Object(R.e)(C.NAMESPACE+"/customers",(function(e){return{id:e.id,label:e.name}}))}},country:{labels:{add:Object(h.__)("Country / Region",'woocommerce'),placeholder:Object(h.__)("Search",'woocommerce'),remove:Object(h.__)("Remove country / region filter",'woocommerce'),rule:Object(h.__)("Select a country / region filter match",'woocommerce'),title:Object(h.__)("{{title}}Country / Region{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(h.__)("Select country / region",'woocommerce')},rules:[{value:"includes",label:Object(h._x)("Includes","countries",'woocommerce')},{value:"excludes",label:Object(h._x)("Excludes","countries",'woocommerce')}],input:{component:"Search",type:"countries",getLabels:(o=g()(w.a.mark((function e(t){var r,o;return w.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=A.map((function(e){return{key:e.code,label:Object(S.decodeEntities)(e.name)}})),o=t.split(","),e.next=4,r.filter((function(e){return o.includes(e.key)}));case 4:return e.abrupt("return",e.sent);case 5:case"end":return e.stop()}}),e)}))),function(e){return o.apply(this,arguments)})}},username:{labels:{add:Object(h.__)("Username",'woocommerce'),placeholder:Object(h.__)("Search customer username",'woocommerce'),remove:Object(h.__)("Remove customer username filter",'woocommerce'),rule:Object(h.__)("Select a customer username filter match",'woocommerce'),title:Object(h.__)("{{title}}Username{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(h.__)("Select customer username",'woocommerce')},rules:[{value:"includes",label:Object(h._x)("Includes","customer usernames",'woocommerce')},{value:"excludes",label:Object(h._x)("Excludes","customer usernames",'woocommerce')}],input:{component:"Search",type:"usernames",getLabels:R.c}},email:{labels:{add:Object(h.__)("Email",'woocommerce'),placeholder:Object(h.__)("Search customer email",'woocommerce'),remove:Object(h.__)("Remove customer email filter",'woocommerce'),rule:Object(h.__)("Select a customer email filter match",'woocommerce'),title:Object(h.__)("{{title}}Email{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(h.__)("Select customer email",'woocommerce')},rules:[{value:"includes",label:Object(h._x)("Includes","customer emails",'woocommerce')},{value:"excludes",label:Object(h._x)("Excludes","customer emails",'woocommerce')}],input:{component:"Search",type:"emails",getLabels:Object(R.e)(C.NAMESPACE+"/customers",(function(e){return{id:e.id,label:e.email}}))}},orders_count:{labels:{add:Object(h.__)("No. of Orders",'woocommerce'),remove:Object(h.__)("Remove order filter",'woocommerce'),rule:Object(h.__)("Select an order count filter match",'woocommerce'),title:Object(h.__)("{{title}}No. of Orders{{/title}} {{rule /}} {{filter /}}",'woocommerce')},rules:[{value:"max",label:Object(h._x)("Less Than","number of orders",'woocommerce')},{value:"min",label:Object(h._x)("More Than","number of orders",'woocommerce')},{value:"between",label:Object(h._x)("Between","number of orders",'woocommerce')}],input:{component:"Number"}},total_spend:{labels:{add:Object(h.__)("Total Spend",'woocommerce'),remove:Object(h.__)("Remove total spend filter",'woocommerce'),rule:Object(h.__)("Select a total spend filter match",'woocommerce'),title:Object(h.__)("{{title}}Total Spend{{/title}} {{rule /}} {{filter /}}",'woocommerce')},rules:[{value:"max",label:Object(h._x)("Less Than","total spend by customer",'woocommerce')},{value:"min",label:Object(h._x)("More Than","total spend by customer",'woocommerce')},{value:"between",label:Object(h._x)("Between","total spend by customer",'woocommerce')}],input:{component:"Currency"}},avg_order_value:{labels:{add:Object(h.__)("AOV",'woocommerce'),remove:Object(h.__)("Remove average order value filter",'woocommerce'),rule:Object(h.__)("Select an average order value filter match",'woocommerce'),title:Object(h.__)("{{title}}AOV{{/title}} {{rule /}} {{filter /}}",'woocommerce')},rules:[{value:"max",label:Object(h._x)("Less Than","average order value of customer",'woocommerce')},{value:"min",label:Object(h._x)("More Than","average order value of customer",'woocommerce')},{value:"between",label:Object(h._x)("Between","average order value of customer",'woocommerce')}],input:{component:"Currency"}},registered:{labels:{add:Object(h.__)("Registered",'woocommerce'),remove:Object(h.__)("Remove registered filter",'woocommerce'),rule:Object(h.__)("Select a registered filter match",'woocommerce'),title:Object(h.__)("{{title}}Registered{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(h.__)("Select registered date",'woocommerce')},rules:[{value:"before",label:Object(h._x)("Before","date",'woocommerce')},{value:"after",label:Object(h._x)("After","date",'woocommerce')},{value:"between",label:Object(h._x)("Between","date",'woocommerce')}],input:{component:"Date"}},last_active:{labels:{add:Object(h.__)("Last active",'woocommerce'),remove:Object(h.__)("Remove last active filter",'woocommerce'),rule:Object(h.__)("Select a last active filter match",'woocommerce'),title:Object(h.__)("{{title}}Last active{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(h.__)("Select registered date",'woocommerce')},rules:[{value:"before",label:Object(h._x)("Before","date",'woocommerce')},{value:"after",label:Object(h._x)("After","date",'woocommerce')},{value:"between",label:Object(h._x)("Between","date",'woocommerce')}],input:{component:"Date"}}}}),N=r(11),D=r.n(N),F=r(159),M=r(77),T=r(298),L=r(40),B=r(771),q=r(762);function V(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,o=f()(e);if(t){var c=f()(this).constructor;r=Reflect.construct(o,arguments,c)}else r=o.apply(this,arguments);return b()(this,r)}}var I=Object(E.g)("dataEndpoints",{countries:{}}).countries,H=function(e){s()(r,e);var t=V(r);function r(){var e;return m()(this,r),(e=t.call(this)).getHeadersContent=e.getHeadersContent.bind(D()(e)),e.getRowsContent=e.getRowsContent.bind(D()(e)),e.getSummary=e.getSummary.bind(D()(e)),e}return l()(r,[{key:"getHeadersContent",value:function(){return[{label:Object(h.__)("Name",'woocommerce'),key:"name",required:!0,isLeftAligned:!0,isSortable:!0},{label:Object(h.__)("Username",'woocommerce'),key:"username",hiddenByDefault:!0},{label:Object(h.__)("Last Active",'woocommerce'),key:"date_last_active",defaultSort:!0,isSortable:!0},{label:Object(h.__)("Date Registered",'woocommerce'),key:"date_registered",isSortable:!0},{label:Object(h.__)("Email",'woocommerce'),key:"email"},{label:Object(h.__)("Orders",'woocommerce'),key:"orders_count",isSortable:!0,isNumeric:!0},{label:Object(h.__)("Total Spend",'woocommerce'),key:"total_spend",isSortable:!0,isNumeric:!0},{label:Object(h.__)("AOV",'woocommerce'),screenReaderLabel:Object(h.__)("Average Order Value",'woocommerce'),key:"avg_order_value",isNumeric:!0},{label:Object(h.__)("Country / Region",'woocommerce'),key:"country",isSortable:!0},{label:Object(h.__)("City",'woocommerce'),key:"city",hiddenByDefault:!0,isSortable:!0},{label:Object(h.__)("Region",'woocommerce'),key:"state",hiddenByDefault:!0,isSortable:!0},{label:Object(h.__)("Postal Code",'woocommerce'),key:"postcode",hiddenByDefault:!0,isSortable:!0}]}},{key:"getCountryName",value:function(e){return void 0!==I[e]?I[e]:null}},{key:"getRowsContent",value:function(e){var t=this,r=Object(E.g)("dateFormat",L.defaultTableDateFormat),o=this.context,c=o.formatAmount,a=o.formatDecimal,n=o.getCurrencyConfig;return null==e?void 0:e.map((function(e){var o=e.avg_order_value,m=e.date_last_active,i=e.date_registered,l=e.email,u=e.name,s=e.user_id,d=e.orders_count,b=e.username,_=e.total_spend,f=e.postcode,p=e.city,O=e.state,j=e.country,w=t.getCountryName(j),y=s?Object(v.createElement)(M.Link,{href:Object(E.f)("user-edit.php?user_id="+s),type:"wp-admin"},u):u,g=m?Object(v.createElement)(M.Date,{date:m,visibleFormat:r}):"—",h=i?Object(v.createElement)(M.Date,{date:i,visibleFormat:r}):"—",S=Object(v.createElement)(v.Fragment,null,Object(v.createElement)(F.a,{text:w},Object(v.createElement)("span",{"aria-hidden":"true"},j)),Object(v.createElement)("span",{className:"screen-reader-text"},w));return[{display:y,value:u},{display:b,value:b},{display:g,value:m},{display:h,value:i},{display:Object(v.createElement)("a",{href:"mailto:"+l},l),value:l},{display:Object(T.formatValue)(n(),"number",d),value:d},{display:c(_),value:a(_)},{display:c(o),value:a(o)},{display:S,value:j},{display:p,value:p},{display:O,value:O},{display:f,value:f}]}))}},{key:"getSummary",value:function(e){var t=e.customers_count,r=void 0===t?0:t,o=e.avg_orders_count,c=void 0===o?0:o,a=e.avg_total_spend,n=void 0===a?0:a,m=e.avg_avg_order_value,i=void 0===m?0:m,l=this.context,u=l.formatAmount,s=(0,l.getCurrencyConfig)();return[{label:Object(h._n)("customer","customers",r,'woocommerce'),value:Object(T.formatValue)(s,"number",r)},{label:Object(h._n)("average order","average orders",c,'woocommerce'),value:Object(T.formatValue)(s,"number",c)},{label:Object(h.__)("average lifetime spend",'woocommerce'),value:u(n)},{label:Object(h.__)("average order value",'woocommerce'),value:u(i)}]}},{key:"render",value:function(){var e=this.props,t=e.isRequesting,r=e.query,o=e.filters,c=e.advancedFilters;return Object(v.createElement)(B.a,{endpoint:"customers",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,getSummary:this.getSummary,summaryFields:["customers_count","avg_orders_count","avg_total_spend","avg_avg_order_value"],isRequesting:t,itemIdField:"id",query:r,labels:{placeholder:Object(h.__)("Search by customer name",'woocommerce')},searchBy:"customers",title:Object(h.__)("Customers",'woocommerce'),columnPrefsKey:"customers_report_columns",filters:o,advancedFilters:c})}}]),r}(v.Component);H.contextType=q.a;var U=H,J=r(770);function Q(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function X(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,o=f()(e);if(t){var c=f()(this).constructor;r=Reflect.construct(o,arguments,c)}else r=o.apply(this,arguments);return b()(this,r)}}var G=function(e){s()(r,e);var t=X(r);function r(){return m()(this,r),t.apply(this,arguments)}return l()(r,[{key:"render",value:function(){var e=this.props,t=e.isRequesting,r=e.query,o=e.path,c=function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:n.identity;return function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",c=arguments.length>1?arguments[1]:void 0,n="function"==typeof e?e(c):e,i=Object(m.getIdsFromQuery)(r);if(i.length<1)return Promise.resolve([]);var l={include:i.join(","),per_page:i.length};return a()({path:Object(o.addQueryArgs)(n,l)}).then((function(e){return e.map(t)}))}}var d=s(i.NAMESPACE+"/products/categories",(function(e){return{key:e.id,label:e.name}})),b=s(i.NAMESPACE+"/coupons",(function(e){return{key:e.id,label:e.code}})),_=s(i.NAMESPACE+"/customers",(function(e){return{key:e.id,label:e.name}})),f=s(i.NAMESPACE+"/products",(function(e){return{key:e.id,label:e.name}})),v=s(i.NAMESPACE+"/taxes",(function(e){return{key:e.id,label:Object(u.a)(e)}}));function p(e){var t=e.attributes,r=e.name,o=Object(l.g)("variationTitleAttributesSeparator"," - ");if(r.indexOf(o)>-1)return r;var c=t.map((function(e){return e.option})).join(", ");return c?r+o+c:r}var O=s((function(e){var t=e.products;return t?i.NAMESPACE+"/products/".concat(t,"/variations"):i.NAMESPACE+"/variations"}),(function(e){return{key:e.id,label:p(e)}}))},765:function(e,t,r){"use strict";r.d(t,"a",(function(){return c}));var o=r(3);function c(e){return[e.country,e.state,e.name||Object(o.__)("TAX",'woocommerce'),e.priority].map((function(e){return e.toString().toUpperCase().trim()})).filter(Boolean).join("-")}},98:function(e,t){function r(e,t,r,o,c,a,n){try{var m=e[a](n),i=m.value}catch(e){return void r(e)}m.done?t(i):Promise.resolve(i).then(o,c)}e.exports=function(e){return function(){var t=this,o=arguments;return new Promise((function(c,a){var n=e.apply(t,o);function m(e){r(n,c,a,m,i,"next",e)}function i(e){r(n,c,a,m,i,"throw",e)}m(void 0)}))}}}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-downloads.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-downloads.js new file mode 100644 index 0000000..c52fd6e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-downloads.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[17],{750:function(e,t,r){"use strict";r.r(t),r.d(t,"default",(function(){return V}));var a=r(17),n=r.n(a),o=r(15),c=r.n(o),i=r(18),s=r.n(i),u=r(19),l=r.n(u),d=r(9),m=r.n(d),p=r(0),f=r(1),b=r.n(f),y=r(791),v=r(11),h=r.n(v),_=r(3),g=r(20),O=r(2),j=r(16),w=r.n(j),R=r(77),D=r(32),S=r(298),C=r(36),E=r(35),q=r(40),P=r(771),k=r(762);function F(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=m()(e);if(t){var n=m()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return l()(this,r)}}var x=function(e){s()(r,e);var t=F(r);function r(){var e;return n()(this,r),(e=t.call(this)).getHeadersContent=e.getHeadersContent.bind(h()(e)),e.getRowsContent=e.getRowsContent.bind(h()(e)),e.getSummary=e.getSummary.bind(h()(e)),e}return c()(r,[{key:"getHeadersContent",value:function(){return[{label:Object(_.__)("Date",'woocommerce'),key:"date",defaultSort:!0,required:!0,isLeftAligned:!0,isSortable:!0},{label:Object(_.__)("Product Title",'woocommerce'),key:"product",isSortable:!0,required:!0},{label:Object(_.__)("File Name",'woocommerce'),key:"file_name"},{label:Object(_.__)("Order #",'woocommerce'),screenReaderLabel:Object(_.__)("Order Number",'woocommerce'),key:"order_number"},{label:Object(_.__)("Username",'woocommerce'),key:"user_id"},{label:Object(_.__)("IP",'woocommerce'),key:"ip_address"}]}},{key:"getRowsContent",value:function(e){var t=this.props.query,r=Object(D.getPersistedQuery)(t),a=Object(C.g)("dateFormat",q.defaultTableDateFormat);return Object(O.map)(e,(function(e){var t,n,o=e._embedded,c=e.date,i=e.file_name,s=e.file_path,u=e.ip_address,l=e.order_id,d=e.order_number,m=e.product_id,f=e.username,b=o.product[0],y=b.code,v=b.name;if("woocommerce_rest_product_invalid_id"===y)t=Object(_.__)("(Deleted)",'woocommerce'),n=Object(_.__)("(Deleted)",'woocommerce');else{var h=Object(D.getNewPath)(r,"/analytics/products",{filter:"single_product",products:m});t=Object(p.createElement)(R.Link,{href:h,type:"wc-admin"},v),n=v}return[{display:Object(p.createElement)(R.Date,{date:c,visibleFormat:a}),value:c},{display:t,value:n},{display:Object(p.createElement)(R.Link,{href:s,type:"external"},i),value:i},{display:Object(p.createElement)(R.Link,{href:Object(C.f)("post.php?post=".concat(l,"&action=edit")),type:"wp-admin"},d),value:d},{display:f,value:f},{display:u,value:u}]}))}},{key:"getSummary",value:function(e){var t=e.download_count,r=void 0===t?0:t,a=this.props,n=a.query,o=a.defaultDateRange,c=Object(q.getCurrentDates)(n,o),i=w()(c.primary.after),s=w()(c.primary.before).diff(i,"days")+1,u=this.context.getCurrencyConfig();return[{label:Object(_._n)("day","days",s,'woocommerce'),value:Object(S.formatValue)(u,"number",s)},{label:Object(_._n)("download","downloads",r,'woocommerce'),value:Object(S.formatValue)(u,"number",r)}]}},{key:"render",value:function(){var e=this.props,t=e.query,r=e.filters,a=e.advancedFilters;return Object(p.createElement)(P.a,{endpoint:"downloads",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,getSummary:this.getSummary,summaryFields:["download_count"],query:t,tableQuery:{_embed:!0},title:Object(_.__)("Downloads",'woocommerce'),columnPrefsKey:"downloads_report_columns",filters:r,advancedFilters:a})}}]),r}(p.Component);x.contextType=k.a;var T=Object(g.withSelect)((function(e){return{defaultDateRange:e(E.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range}}))(x),A=r(768),I=r(766),N=r(769),L=r(770);function M(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=m()(e);if(t){var n=m()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return l()(this,r)}}var V=function(e){s()(r,e);var t=M(r);function r(){return n()(this,r),t.apply(this,arguments)}return c()(r,[{key:"render",value:function(){var e=this.props,t=e.query,r=e.path;return Object(p.createElement)(p.Fragment,null,Object(p.createElement)(L.a,{query:t,path:r,filters:y.c,advancedFilters:y.a,report:"downloads"}),Object(p.createElement)(N.a,{charts:y.b,endpoint:"downloads",query:t,selectedChart:Object(A.a)(t.chart,y.b),filters:y.c,advancedFilters:y.a}),Object(p.createElement)(I.a,{charts:y.b,endpoint:"downloads",path:r,query:t,selectedChart:Object(A.a)(t.chart,y.b),filters:y.c,advancedFilters:y.a}),Object(p.createElement)(T,{query:t,filters:y.c,advancedFilters:y.a}))}}]),r}(p.Component);V.propTypes={query:b.a.object.isRequired}},764:function(e,t,r){"use strict";r.d(t,"e",(function(){return d})),r.d(t,"a",(function(){return m})),r.d(t,"b",(function(){return p})),r.d(t,"c",(function(){return f})),r.d(t,"d",(function(){return b})),r.d(t,"f",(function(){return y})),r.d(t,"h",(function(){return v})),r.d(t,"g",(function(){return h}));var a=r(37),n=r(43),o=r.n(n),c=r(2),i=r(32),s=r(35),u=r(36),l=r(765);function d(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:c.identity;return function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1?arguments[1]:void 0,c="function"==typeof e?e(n):e,s=Object(i.getIdsFromQuery)(r);if(s.length<1)return Promise.resolve([]);var u={include:s.join(","),per_page:s.length};return o()({path:Object(a.addQueryArgs)(c,u)}).then((function(e){return e.map(t)}))}}var m=d(s.NAMESPACE+"/products/categories",(function(e){return{key:e.id,label:e.name}})),p=d(s.NAMESPACE+"/coupons",(function(e){return{key:e.id,label:e.code}})),f=d(s.NAMESPACE+"/customers",(function(e){return{key:e.id,label:e.name}})),b=d(s.NAMESPACE+"/products",(function(e){return{key:e.id,label:e.name}})),y=d(s.NAMESPACE+"/taxes",(function(e){return{key:e.id,label:Object(l.a)(e)}}));function v(e){var t=e.attributes,r=e.name,a=Object(u.g)("variationTitleAttributesSeparator"," - ");if(r.indexOf(a)>-1)return r;var n=t.map((function(e){return e.option})).join(", ");return n?r+a+n:r}var h=d((function(e){var t=e.products;return t?s.NAMESPACE+"/products/".concat(t,"/variations"):s.NAMESPACE+"/variations"}),(function(e){return{key:e.id,label:v(e)}}))},765:function(e,t,r){"use strict";r.d(t,"a",(function(){return n}));var a=r(3);function n(e){return[e.country,e.state,e.name||Object(a.__)("TAX",'woocommerce'),e.priority].map((function(e){return e.toString().toUpperCase().trim()})).filter(Boolean).join("-")}},766:function(e,t,r){"use strict";var a=r(5),n=r.n(a),o=r(17),c=r.n(o),i=r(15),s=r.n(i),u=r(18),l=r.n(u),d=r(19),m=r.n(d),p=r(9),f=r.n(p),b=r(0),y=r(3),v=r(277),h=r(154),_=r(20),g=r(2),O=r(1),j=r.n(O),w=r(77),R=r(35),D=r(40),S=r(762),C=r(763),E=r(32);function q(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function P(e){for(var t=1;t2&&void 0!==arguments[2]?arguments[2]:{};if(!t||0===t.length)return null;var n=t.slice(0),o=n.pop();if(o.showFilters(r,a)){var c=Object(E.flattenFilters)(o.filters),i=r[o.param]||o.defaultValue||"all";return Object(g.find)(c,{value:i})}return e(n,r,a)}(n,i),d=Object(g.get)(l,["settings","param"]),m=t.mode||function(e,t){if(e&&t){var r=Object(g.get)(e,["settings","param"]);if(!r||Object.keys(t).includes(r))return Object(g.get)(e,["chartMode"])}return null}(l,i)||"time-comparison",p=e(R.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,f={mode:m,filterParam:d,defaultDateRange:p};if(o)return f;var b=u.some((function(e){return i[e]&&i[e].length}));if(i.search&&!b)return P(P({},f),{},{emptySearchResults:!0});var y=r&&r.map((function(e){return e.key})),v=Object(R.getReportChartData)({endpoint:a,dataType:"primary",query:i,select:e,limitBy:u,filters:n,advancedFilters:s,defaultDateRange:p,fields:y});if("item-comparison"===m)return P(P({},f),{},{primaryData:v});var h=Object(R.getReportChartData)({endpoint:a,dataType:"secondary",query:i,select:e,limitBy:u,filters:n,advancedFilters:s,defaultDateRange:p,fields:y});return P(P({},f),{},{primaryData:v,secondaryData:h})})))(F)},768:function(e,t,r){"use strict";r.d(t,"a",(function(){return n}));var a=r(2);function n(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=Object(a.find)(t,{key:e});return r||t[0]}},769:function(e,t,r){"use strict";var a=r(17),n=r.n(a),o=r(15),c=r.n(o),i=r(18),s=r.n(i),u=r(19),l=r.n(u),d=r(9),m=r.n(d),p=r(0),f=r(3),b=r(277),y=r(20),v=r(1),h=r.n(v),_=r(32),g=r(77),O=r(298),j=r(35),w=r(40),R=r(64),D=r(763),S=r(762);function C(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=m()(e);if(t){var n=m()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return l()(this,r)}}var E=function(e){s()(r,e);var t=C(r);function r(){return n()(this,r),t.apply(this,arguments)}return c()(r,[{key:"formatVal",value:function(e,t){var r=this.context,a=r.formatAmount,n=r.getCurrencyConfig;return"currency"===t?a(e):Object(O.formatValue)(n(),t,e)}},{key:"getValues",value:function(e,t){var r=this.props,a=r.emptySearchResults,n=r.summaryData.totals,o=n.primary?n.primary[e]:0,c=n.secondary?n.secondary[e]:0,i=a?0:o,s=a?0:c;return{delta:Object(O.calculateDelta)(i,s),prevValue:this.formatVal(s,t),value:this.formatVal(i,t)}}},{key:"render",value:function(){var e=this,t=this.props,r=t.charts,a=t.query,n=t.selectedChart,o=t.summaryData,c=t.endpoint,i=t.report,s=t.defaultDateRange,u=o.isError,l=o.isRequesting;if(u)return Object(p.createElement)(D.a,{isError:!0});if(l)return Object(p.createElement)(g.SummaryListPlaceholder,{numberOfItems:r.length});var d=Object(w.getDateParamsFromQuery)(a,s).compare;return Object(p.createElement)(g.SummaryList,null,(function(t){var a=t.onToggle;return r.map((function(t){var r=t.key,o=t.order,s=t.orderby,u=t.label,l=t.type,m={chart:r};s&&(m.orderby=s),o&&(m.order=o);var b=Object(_.getNewPath)(m),y=n.key===r,v=e.getValues(r,l),h=v.delta,O=v.prevValue,j=v.value;return Object(p.createElement)(g.SummaryNumber,{key:r,delta:h,href:b,label:u,prevLabel:"previous_period"===d?Object(f.__)("Previous Period:",'woocommerce'):Object(f.__)("Previous Year:",'woocommerce'),prevValue:O,selected:y,value:j,onLinkClickCallback:function(){a&&a(),Object(R.recordEvent)("analytics_chart_tab_click",{report:i||c,key:r})}})}))}))}}]),r}(p.Component);E.propTypes={charts:h.a.array.isRequired,endpoint:h.a.string.isRequired,limitProperties:h.a.array,query:h.a.object.isRequired,selectedChart:h.a.shape({key:h.a.string.isRequired,label:h.a.string.isRequired,order:h.a.oneOf(["asc","desc"]),orderby:h.a.string,type:h.a.oneOf(["average","number","currency"]).isRequired}).isRequired,summaryData:h.a.object,report:h.a.string},E.defaultProps={summaryData:{totals:{primary:{},secondary:{}},isError:!1}},E.contextType=S.a,t.a=Object(b.a)(Object(y.withSelect)((function(e,t){var r=t.charts,a=t.endpoint,n=t.limitProperties,o=t.query,c=t.filters,i=t.advancedFilters,s=n||[a],u=s.some((function(e){return o[e]&&o[e].length}));if(o.search&&!u)return{emptySearchResults:!0};var l=r&&r.map((function(e){return e.key})),d=e(j.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range;return{summaryData:Object(j.getSummaryNumbers)({endpoint:a,query:o,select:e,limitBy:s,filters:c,advancedFilters:i,defaultDateRange:d,fields:l}),defaultDateRange:d}})))(E)},791:function(e,t,r){"use strict";r.d(t,"b",(function(){return m})),r.d(t,"c",(function(){return p})),r.d(t,"a",(function(){return f}));var a,n,o=r(14),c=r.n(o),i=r(98),s=r.n(i),u=r(3),l=r(55),d=r(764),m=Object(l.applyFilters)("woocommerce_admin_downloads_report_charts",[{key:"download_count",label:Object(u.__)("Downloads",'woocommerce'),type:"number"}]),p=Object(l.applyFilters)("woocommerce_admin_downloads_report_filters",[{label:Object(u.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(u.__)("All Downloads",'woocommerce'),value:"all"},{label:Object(u.__)("Advanced Filters",'woocommerce'),value:"advanced"}]}]),f=Object(l.applyFilters)("woocommerce_admin_downloads_report_advanced_filters",{title:Object(u._x)("Downloads Match {{select /}} Filters","A sentence describing filters for Downloads. See screen shot for context: https://cloudup.com/ccxhyH2mEDg",'woocommerce'),filters:{product:{labels:{add:Object(u.__)("Product",'woocommerce'),placeholder:Object(u.__)("Search",'woocommerce'),remove:Object(u.__)("Remove product filter",'woocommerce'),rule:Object(u.__)("Select a product filter match",'woocommerce'),title:Object(u.__)("{{title}}Product{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(u.__)("Select product",'woocommerce')},rules:[{value:"includes",label:Object(u._x)("Includes","products",'woocommerce')},{value:"excludes",label:Object(u._x)("Excludes","products",'woocommerce')}],input:{component:"Search",type:"products",getLabels:d.d}},customer:{labels:{add:Object(u.__)("Username",'woocommerce'),placeholder:Object(u.__)("Search customer username",'woocommerce'),remove:Object(u.__)("Remove customer username filter",'woocommerce'),rule:Object(u.__)("Select a customer username filter match",'woocommerce'),title:Object(u.__)("{{title}}Username{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(u.__)("Select customer username",'woocommerce')},rules:[{value:"includes",label:Object(u._x)("Includes","customer usernames",'woocommerce')},{value:"excludes",label:Object(u._x)("Excludes","customer usernames",'woocommerce')}],input:{component:"Search",type:"usernames",getLabels:d.c}},order:{labels:{add:Object(u.__)("Order #",'woocommerce'),placeholder:Object(u.__)("Search order number",'woocommerce'),remove:Object(u.__)("Remove order number filter",'woocommerce'),rule:Object(u.__)("Select a order number filter match",'woocommerce'),title:Object(u.__)("{{title}}Order #{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(u.__)("Select order number",'woocommerce')},rules:[{value:"includes",label:Object(u._x)("Includes","order numbers",'woocommerce')},{value:"excludes",label:Object(u._x)("Excludes","order numbers",'woocommerce')}],input:{component:"Search",type:"orders",getLabels:(n=s()(c.a.mark((function e(t){var r;return c.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=t.split(","),e.next=3,r.map((function(e){return{id:e,label:"#"+e}}));case 3:return e.abrupt("return",e.sent);case 4:case"end":return e.stop()}}),e)}))),function(e){return n.apply(this,arguments)})}},ip_address:{labels:{add:Object(u.__)("IP Address",'woocommerce'),placeholder:Object(u.__)("Search IP address",'woocommerce'),remove:Object(u.__)("Remove IP address filter",'woocommerce'),rule:Object(u.__)("Select an IP address filter match",'woocommerce'),title:Object(u.__)("{{title}}IP Address{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(u.__)("Select IP address",'woocommerce')},rules:[{value:"includes",label:Object(u._x)("Includes","IP addresses",'woocommerce')},{value:"excludes",label:Object(u._x)("Excludes","IP addresses",'woocommerce')}],input:{component:"Search",type:"downloadIps",getLabels:(a=s()(c.a.mark((function e(t){var r;return c.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=t.split(","),e.next=3,r.map((function(e){return{id:e,label:e}}));case 3:return e.abrupt("return",e.sent);case 4:case"end":return e.stop()}}),e)}))),function(e){return a.apply(this,arguments)})}}}})},98:function(e,t){function r(e,t,r,a,n,o,c){try{var i=e[o](c),s=i.value}catch(e){return void r(e)}i.done?t(s):Promise.resolve(s).then(a,n)}e.exports=function(e){return function(){var t=this,a=arguments;return new Promise((function(n,o){var c=e.apply(t,a);function i(e){r(c,n,o,i,s,"next",e)}function s(e){r(c,n,o,i,s,"throw",e)}i(void 0)}))}}}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-orders.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-orders.js new file mode 100644 index 0000000..151e872 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-orders.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[18],{747:function(e,t,r){"use strict";r.r(t),r.d(t,"default",(function(){return x}));var n=r(17),a=r.n(n),o=r(15),c=r.n(o),u=r(18),i=r.n(u),s=r(19),l=r.n(s),m=r(9),d=r.n(m),f=r(0),b=r(1),p=r.n(b),y=r(797),v=r(768),_=r(11),h=r.n(_),O=r(3),j=r(2),g=r(77),w=r(298),R=r(36),k=r(32),q=r(40),S=r(771),C=r(762);r(829);function E(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,n=d()(e);if(t){var a=d()(this).constructor;r=Reflect.construct(n,arguments,a)}else r=n.apply(this,arguments);return l()(this,r)}}var D=function(e){i()(r,e);var t=E(r);function r(){var e;return a()(this,r),(e=t.call(this)).getHeadersContent=e.getHeadersContent.bind(h()(e)),e.getRowsContent=e.getRowsContent.bind(h()(e)),e.getSummary=e.getSummary.bind(h()(e)),e}return c()(r,[{key:"getHeadersContent",value:function(){return[{label:Object(O.__)("Date",'woocommerce'),key:"date",required:!0,defaultSort:!0,isLeftAligned:!0,isSortable:!0},{label:Object(O.__)("Order #",'woocommerce'),screenReaderLabel:Object(O.__)("Order Number",'woocommerce'),key:"order_number",required:!0},{label:Object(O.__)("Status",'woocommerce'),key:"status",required:!1,isSortable:!1},{label:Object(O.__)("Customer",'woocommerce'),key:"customer_id",required:!1,isSortable:!1},{label:Object(O.__)("Product(s)",'woocommerce'),screenReaderLabel:Object(O.__)("Products",'woocommerce'),key:"products",required:!1,isSortable:!1},{label:Object(O.__)("Items Sold",'woocommerce'),key:"num_items_sold",required:!1,isSortable:!0,isNumeric:!0},{label:Object(O.__)("Coupon(s)",'woocommerce'),screenReaderLabel:Object(O.__)("Coupons",'woocommerce'),key:"coupons",required:!1,isSortable:!1},{label:Object(O.__)("Net Sales",'woocommerce'),screenReaderLabel:Object(O.__)("Net Sales",'woocommerce'),key:"net_total",required:!0,isSortable:!0,isNumeric:!0}]}},{key:"getCustomerName",value:function(e){var t=e||{},r=t.first_name,n=t.last_name;return r||n?[r,n].join(" "):""}},{key:"getRowsContent",value:function(e){var t=this,r=this.props.query,n=Object(k.getPersistedQuery)(r),a=Object(R.g)("dateFormat",q.defaultTableDateFormat),o=this.context,c=o.render,u=o.getCurrencyConfig;return Object(j.map)(e,(function(e){var r=e.currency,o=e.date_created,i=e.net_total,s=e.num_items_sold,l=e.order_id,m=e.order_number,d=e.parent_id,b=e.status,p=e.extended_info||{},y=p.coupons,v=p.customer,_=p.products.sort((function(e,t){return t.quantity-e.quantity})).map((function(e){return{label:e.name,quantity:e.quantity,href:Object(k.getNewPath)(n,"/analytics/products",{filter:"single_product",products:e.id})}})),h=y.map((function(e){return{label:e.code,href:Object(k.getNewPath)(n,"/analytics/coupons",{filter:"single_coupon",coupons:e.id})}}));return[{display:Object(f.createElement)(g.Date,{date:o,visibleFormat:a}),value:o},{display:Object(f.createElement)(g.Link,{href:"post.php?post="+(d||l)+"&action=edit"+(d?"#order_refunds":""),type:"wp-admin"},m),value:m},{display:Object(f.createElement)(g.OrderStatus,{className:"woocommerce-orders-table__status",order:{status:b},orderStatusMap:Object(R.g)("orderStatuses",{})}),value:b},{display:t.getCustomerName(v),value:t.getCustomerName(v)},{display:t.renderList(_.length?[_[0]]:[],_.map((function(e){return{label:Object(O.sprintf)(Object(O.__)("%s× %s",'woocommerce'),e.quantity,e.label),href:e.href}}))),value:_.map((function(e){var t=e.quantity,r=e.label;return Object(O.sprintf)(Object(O.__)("%s× %s",'woocommerce'),t,r)})).join(", ")},{display:Object(w.formatValue)(u(),"number",s),value:s},{display:t.renderList(h.length?[h[0]]:[],h),value:h.map((function(e){return e.label})).join(", ")},{display:c(i,r),value:i}]}))}},{key:"getSummary",value:function(e){var t=e.orders_count,r=void 0===t?0:t,n=e.total_customers,a=void 0===n?0:n,o=e.products,c=void 0===o?0:o,u=e.num_items_sold,i=void 0===u?0:u,s=e.coupons_count,l=void 0===s?0:s,m=e.net_revenue,d=void 0===m?0:m,f=this.context,b=f.formatAmount,p=(0,f.getCurrencyConfig)();return[{label:Object(O._n)("order","orders",r,'woocommerce'),value:Object(w.formatValue)(p,"number",r)},{label:Object(O._n)(" customer"," customers",a,'woocommerce'),value:Object(w.formatValue)(p,"number",a)},{label:Object(O._n)("product","products",c,'woocommerce'),value:Object(w.formatValue)(p,"number",c)},{label:Object(O._n)("item sold","items sold",i,'woocommerce'),value:Object(w.formatValue)(p,"number",i)},{label:Object(O._n)("coupon","coupons",l,'woocommerce'),value:Object(w.formatValue)(p,"number",l)},{label:Object(O.__)("net sales",'woocommerce'),value:b(d)}]}},{key:"renderLinks",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return e.map((function(e,t){return Object(f.createElement)(g.Link,{href:e.href,key:t,type:"wc-admin"},e.label)}))}},{key:"renderList",value:function(e,t){return Object(f.createElement)(f.Fragment,null,this.renderLinks(e),t.length>1&&Object(f.createElement)(g.ViewMoreList,{items:this.renderLinks(t)}))}},{key:"render",value:function(){var e=this.props,t=e.query,r=e.filters,n=e.advancedFilters;return Object(f.createElement)(S.a,{endpoint:"orders",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,getSummary:this.getSummary,summaryFields:["orders_count","total_customers","products","num_items_sold","coupons_count","net_revenue"],query:t,tableQuery:{extended_info:!0},title:Object(O.__)("Orders",'woocommerce'),columnPrefsKey:"orders_report_columns",filters:r,advancedFilters:n})}}]),r}(f.Component);D.contextType=C.a;var L=D,P=r(766),N=r(769),V=r(770);function F(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,n=d()(e);if(t){var a=d()(this).constructor;r=Reflect.construct(n,arguments,a)}else r=n.apply(this,arguments);return l()(this,r)}}var x=function(e){i()(r,e);var t=F(r);function r(){return a()(this,r),t.apply(this,arguments)}return c()(r,[{key:"render",value:function(){var e=this.props,t=e.path,r=e.query;return Object(f.createElement)(f.Fragment,null,Object(f.createElement)(V.a,{query:r,path:t,filters:y.c,advancedFilters:y.a,report:"orders"}),Object(f.createElement)(N.a,{charts:y.b,endpoint:"orders",query:r,selectedChart:Object(v.a)(r.chart,y.b),filters:y.c,advancedFilters:y.a}),Object(f.createElement)(P.a,{charts:y.b,endpoint:"orders",path:t,query:r,selectedChart:Object(v.a)(r.chart,y.b),filters:y.c,advancedFilters:y.a}),Object(f.createElement)(L,{query:r,filters:y.c,advancedFilters:y.a}))}}]),r}(f.Component);x.propTypes={path:p.a.string.isRequired,query:p.a.object.isRequired}},768:function(e,t,r){"use strict";r.d(t,"a",(function(){return a}));var n=r(2);function a(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=Object(n.find)(t,{key:e});return r||t[0]}},769:function(e,t,r){"use strict";var n=r(17),a=r.n(n),o=r(15),c=r.n(o),u=r(18),i=r.n(u),s=r(19),l=r.n(s),m=r(9),d=r.n(m),f=r(0),b=r(3),p=r(277),y=r(20),v=r(1),_=r.n(v),h=r(32),O=r(77),j=r(298),g=r(35),w=r(40),R=r(64),k=r(763),q=r(762);function S(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,n=d()(e);if(t){var a=d()(this).constructor;r=Reflect.construct(n,arguments,a)}else r=n.apply(this,arguments);return l()(this,r)}}var C=function(e){i()(r,e);var t=S(r);function r(){return a()(this,r),t.apply(this,arguments)}return c()(r,[{key:"formatVal",value:function(e,t){var r=this.context,n=r.formatAmount,a=r.getCurrencyConfig;return"currency"===t?n(e):Object(j.formatValue)(a(),t,e)}},{key:"getValues",value:function(e,t){var r=this.props,n=r.emptySearchResults,a=r.summaryData.totals,o=a.primary?a.primary[e]:0,c=a.secondary?a.secondary[e]:0,u=n?0:o,i=n?0:c;return{delta:Object(j.calculateDelta)(u,i),prevValue:this.formatVal(i,t),value:this.formatVal(u,t)}}},{key:"render",value:function(){var e=this,t=this.props,r=t.charts,n=t.query,a=t.selectedChart,o=t.summaryData,c=t.endpoint,u=t.report,i=t.defaultDateRange,s=o.isError,l=o.isRequesting;if(s)return Object(f.createElement)(k.a,{isError:!0});if(l)return Object(f.createElement)(O.SummaryListPlaceholder,{numberOfItems:r.length});var m=Object(w.getDateParamsFromQuery)(n,i).compare;return Object(f.createElement)(O.SummaryList,null,(function(t){var n=t.onToggle;return r.map((function(t){var r=t.key,o=t.order,i=t.orderby,s=t.label,l=t.type,d={chart:r};i&&(d.orderby=i),o&&(d.order=o);var p=Object(h.getNewPath)(d),y=a.key===r,v=e.getValues(r,l),_=v.delta,j=v.prevValue,g=v.value;return Object(f.createElement)(O.SummaryNumber,{key:r,delta:_,href:p,label:s,prevLabel:"previous_period"===m?Object(b.__)("Previous Period:",'woocommerce'):Object(b.__)("Previous Year:",'woocommerce'),prevValue:j,selected:y,value:g,onLinkClickCallback:function(){n&&n(),Object(R.recordEvent)("analytics_chart_tab_click",{report:u||c,key:r})}})}))}))}}]),r}(f.Component);C.propTypes={charts:_.a.array.isRequired,endpoint:_.a.string.isRequired,limitProperties:_.a.array,query:_.a.object.isRequired,selectedChart:_.a.shape({key:_.a.string.isRequired,label:_.a.string.isRequired,order:_.a.oneOf(["asc","desc"]),orderby:_.a.string,type:_.a.oneOf(["average","number","currency"]).isRequired}).isRequired,summaryData:_.a.object,report:_.a.string},C.defaultProps={summaryData:{totals:{primary:{},secondary:{}},isError:!1}},C.contextType=q.a,t.a=Object(p.a)(Object(y.withSelect)((function(e,t){var r=t.charts,n=t.endpoint,a=t.limitProperties,o=t.query,c=t.filters,u=t.advancedFilters,i=a||[n],s=i.some((function(e){return o[e]&&o[e].length}));if(o.search&&!s)return{emptySearchResults:!0};var l=r&&r.map((function(e){return e.key})),m=e(g.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range;return{summaryData:Object(g.getSummaryNumbers)({endpoint:n,query:o,select:e,limitBy:i,filters:c,advancedFilters:u,defaultDateRange:m,fields:l}),defaultDateRange:m}})))(C)},829:function(e,t,r){}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-products.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-products.js new file mode 100644 index 0000000..d2df99a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-products.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[19],{741:function(e,t,r){"use strict";r.r(t);var o=r(5),a=r.n(o),c=r(17),n=r.n(c),i=r(15),s=r.n(i),l=r(18),u=r.n(l),m=r(19),d=r.n(m),p=r(9),b=r.n(p),_=r(0),f=r(3),y=r(277),v=r(1),O=r.n(v),g=r(35),h=r(20),j=r(787),w=r(768),S=r(795),k=r(766),q=r(763),R=r(769),C=r(788),P=r(770);function E(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function F(e){for(var t=1;t1||r&&o?"item-comparison":"time-comparison";return{compareObject:r&&o?"variations":"products",itemsLabel:r&&o?Object(f.__)("%d variations",'woocommerce'):Object(f.__)("%d products",'woocommerce'),mode:a}}},{key:"render",value:function(){var e=this.getChartMeta(),t=e.compareObject,r=e.itemsLabel,o=e.mode,a=this.props,c=a.path,n=a.query,i=a.isError,s=a.isRequesting,l=a.isSingleProductVariable;if(i)return Object(_.createElement)(q.a,{isError:!0});var u=F({},n);return"item-comparison"===o&&(u.segmentby="products"===t?"product":"variation"),Object(_.createElement)(_.Fragment,null,Object(_.createElement)(P.a,{query:n,path:c,filters:j.c,advancedFilters:j.a,report:"products"}),Object(_.createElement)(R.a,{mode:o,charts:j.b,endpoint:"products",isRequesting:s,query:u,selectedChart:Object(w.a)(n.chart,j.b),filters:j.c,advancedFilters:j.a}),Object(_.createElement)(k.a,{charts:j.b,mode:o,filters:j.c,advancedFilters:j.a,endpoint:"products",isRequesting:s,itemsLabel:r,path:c,query:u,selectedChart:Object(w.a)(u.chart,j.b)}),l?Object(_.createElement)(C.a,{baseSearchQuery:{filter:"single_product"},isRequesting:s,query:n,filters:j.c,advancedFilters:j.a}):Object(_.createElement)(S.a,{isRequesting:s,query:n,filters:j.c,advancedFilters:j.a}))}}]),r}(_.Component);L.propTypes={path:O.a.string.isRequired,query:O.a.object.isRequired},t.default=Object(y.a)(Object(h.withSelect)((function(e,t){var r=t.query,o=t.isRequesting,a=!r.search&&r.products&&1===r.products.split(",").length;if(o)return{query:F({},r),isSingleProductView:a,isRequesting:o};var c=e(g.ITEMS_STORE_NAME),n=c.getItems,i=c.isResolving,s=c.getItemsError;if(a){var l=parseInt(r.products,10),u={include:l},m=n("products",u),d=m&&m.get(l)&&"variable"===m.get(l).type,p=i("getItems",["products",u]),b=Boolean(s("products",u));return{query:F(F({},r),{},{"is-variable":d}),isSingleProductView:a,isSingleProductVariable:d,isRequesting:p,isError:b}}return{query:r,isSingleProductView:a}})))(L)},787:function(e,t,r){"use strict";r.d(t,"b",(function(){return n})),r.d(t,"c",(function(){return l})),r.d(t,"a",(function(){return u}));var o=r(3),a=r(55),c=r(764),n=Object(a.applyFilters)("woocommerce_admin_products_report_charts",[{key:"items_sold",label:Object(o.__)("Items Sold",'woocommerce'),order:"desc",orderby:"items_sold",type:"number"},{key:"net_revenue",label:Object(o.__)("Net Sales",'woocommerce'),order:"desc",orderby:"net_revenue",type:"currency"},{key:"orders_count",label:Object(o.__)("Orders",'woocommerce'),order:"desc",orderby:"orders_count",type:"number"}]),i={label:Object(o.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(o.__)("All Products",'woocommerce'),value:"all"},{label:Object(o.__)("Single Product",'woocommerce'),value:"select_product",chartMode:"item-comparison",subFilters:[{component:"Search",value:"single_product",chartMode:"item-comparison",path:["select_product"],settings:{type:"products",param:"products",getLabels:c.d,labels:{placeholder:Object(o.__)("Type to search for a product",'woocommerce'),button:Object(o.__)("Single Product",'woocommerce')}}}]},{label:Object(o.__)("Comparison",'woocommerce'),value:"compare-products",chartMode:"item-comparison",settings:{type:"products",param:"products",getLabels:c.d,labels:{helpText:Object(o.__)("Check at least two products below to compare",'woocommerce'),placeholder:Object(o.__)("Search for products to compare",'woocommerce'),title:Object(o.__)("Compare Products",'woocommerce'),update:Object(o.__)("Compare",'woocommerce')}}}]},s={showFilters:function(e){return"single_product"===e.filter&&!!e.products&&e["is-variable"]},staticParams:["filter","products","chartType","paged","per_page"],param:"filter-variations",filters:[{label:Object(o.__)("All Variations",'woocommerce'),chartMode:"item-comparison",value:"all"},{label:Object(o.__)("Single Variation",'woocommerce'),value:"select_variation",subFilters:[{component:"Search",value:"single_variation",path:["select_variation"],settings:{type:"variations",param:"variations",getLabels:c.g,labels:{placeholder:Object(o.__)("Type to search for a variation",'woocommerce'),button:Object(o.__)("Single Variation",'woocommerce')}}}]},{label:Object(o.__)("Comparison",'woocommerce'),chartMode:"item-comparison",value:"compare-variations",settings:{type:"variations",param:"variations",getLabels:c.g,labels:{helpText:Object(o.__)("Check at least two variations below to compare",'woocommerce'),placeholder:Object(o.__)("Search for variations to compare",'woocommerce'),title:Object(o.__)("Compare Variations",'woocommerce'),update:Object(o.__)("Compare",'woocommerce')}}}]},l=Object(a.applyFilters)("woocommerce_admin_products_report_filters",[i,s]),u=Object(a.applyFilters)("woocommerce_admin_products_report_advanced_filters",{})},788:function(e,t,r){"use strict";var o=r(17),a=r.n(o),c=r(15),n=r.n(c),i=r(11),s=r.n(i),l=r(18),u=r.n(l),m=r(19),d=r.n(m),p=r(9),b=r.n(p),_=r(0),f=r(3),y=r(2),v=r(77),O=r(32),g=r(298),h=r(36),j=r(771),w=r(781),S=r(762),k=r(764);function q(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,o=b()(e);if(t){var a=b()(this).constructor;r=Reflect.construct(o,arguments,a)}else r=o.apply(this,arguments);return d()(this,r)}}var R=Object(h.g)("manageStock","no"),C=Object(h.g)("stockStatuses",{}),P=function(e){return Object(k.h)(e.extended_info||{})},E=function(e){u()(r,e);var t=q(r);function r(){var e;return a()(this,r),(e=t.call(this)).getHeadersContent=e.getHeadersContent.bind(s()(e)),e.getRowsContent=e.getRowsContent.bind(s()(e)),e.getSummary=e.getSummary.bind(s()(e)),e}return n()(r,[{key:"getHeadersContent",value:function(){return[{label:Object(f.__)("Product / Variation Title",'woocommerce'),key:"name",required:!0,isLeftAligned:!0},{label:Object(f.__)("SKU",'woocommerce'),key:"sku",hiddenByDefault:!0,isSortable:!0},{label:Object(f.__)("Items Sold",'woocommerce'),key:"items_sold",required:!0,defaultSort:!0,isSortable:!0,isNumeric:!0},{label:Object(f.__)("Net Sales",'woocommerce'),screenReaderLabel:Object(f.__)("Net Sales",'woocommerce'),key:"net_revenue",required:!0,isSortable:!0,isNumeric:!0},{label:Object(f.__)("Orders",'woocommerce'),key:"orders_count",isSortable:!0,isNumeric:!0},"yes"===R?{label:Object(f.__)("Status",'woocommerce'),key:"stock_status"}:null,"yes"===R?{label:Object(f.__)("Stock",'woocommerce'),key:"stock",isNumeric:!0}:null].filter(Boolean)}},{key:"getRowsContent",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=this.props.query,r=Object(O.getPersistedQuery)(t),o=this.context,a=o.formatAmount,c=o.formatDecimal,n=o.getCurrencyConfig;return Object(y.map)(e,(function(e){var t=e.items_sold,o=e.net_revenue,i=e.orders_count,s=e.product_id,l=e.variation_id,u=e.extended_info||{},m=u.stock_status,d=u.stock_quantity,p=u.low_stock_amount,b=u.sku,y=P(e),j=Object(O.getNewPath)(r,"/analytics/orders",{filter:"advanced",variation_includes:l}),S=Object(h.f)("post.php?post=".concat(s,"&action=edit"));return[{display:Object(_.createElement)(v.Link,{href:S,type:"wp-admin"},y),value:y},{display:b,value:b},{display:Object(g.formatValue)(n(),"number",t),value:t},{display:a(o),value:c(o)},{display:Object(_.createElement)(v.Link,{href:j,type:"wc-admin"},i),value:i},"yes"===R?{display:Object(w.a)(m,d,p)?Object(_.createElement)(v.Link,{href:S,type:"wp-admin"},Object(f._x)("Low","Indication of a low quantity",'woocommerce')):C[m],value:C[m]}:null,"yes"===R?{display:d,value:d}:null].filter(Boolean)}))}},{key:"getSummary",value:function(e){var t=e.variations_count,r=void 0===t?0:t,o=e.items_sold,a=void 0===o?0:o,c=e.net_revenue,n=void 0===c?0:c,i=e.orders_count,s=void 0===i?0:i,l=this.context,u=l.formatAmount,m=(0,l.getCurrencyConfig)();return[{label:Object(f._n)("variation sold","variations sold",r,'woocommerce'),value:Object(g.formatValue)(m,"number",r)},{label:Object(f._n)("item sold","items sold",a,'woocommerce'),value:Object(g.formatValue)(m,"number",a)},{label:Object(f.__)("net sales",'woocommerce'),value:u(n)},{label:Object(f._n)("orders","orders",s,'woocommerce'),value:Object(g.formatValue)(m,"number",s)}]}},{key:"render",value:function(){var e=this.props,t=e.advancedFilters,r=e.baseSearchQuery,o=e.filters,a=e.isRequesting,c=e.query,n={helpText:Object(f.__)("Check at least two variations below to compare",'woocommerce'),placeholder:Object(f.__)("Search by variation name or SKU",'woocommerce')};return Object(_.createElement)(j.a,{baseSearchQuery:r,compareBy:"variations",compareParam:"filter-variations",endpoint:"variations",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,isRequesting:a,itemIdField:"variation_id",labels:n,query:c,getSummary:this.getSummary,summaryFields:["variations_count","items_sold","net_revenue","orders_count"],tableQuery:{orderby:c.orderby||"items_sold",order:c.order||"desc",extended_info:!0,products:c.products,variations:c.variations},title:Object(f.__)("Variations",'woocommerce'),columnPrefsKey:"variations_report_columns",filters:o,advancedFilters:t})}}]),r}(_.Component);E.contextType=S.a,t.a=E}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-revenue.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-revenue.js new file mode 100644 index 0000000..97e2830 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-revenue.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[20],{745:function(e,t,r){"use strict";r.r(t),r.d(t,"default",(function(){return I}));var a=r(17),n=r.n(a),o=r(15),i=r.n(o),s=r(18),c=r.n(s),u=r(19),l=r.n(u),d=r(9),m=r.n(d),p=r(0),y=r(1),f=r.n(y),b=r(786),v=r(768),g=r(766),h=r(769),_=r(11),O=r.n(_),j=r(3),R=r(154),w=r(20),q=r(277),D=r(2),S=r(77),C=r(298),k=r(36),E=r(35),T=r(40),F=r(771),P=r(762);function x(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=m()(e);if(t){var n=m()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return l()(this,r)}}var N=function(e){c()(r,e);var t=x(r);function r(){var e;return n()(this,r),(e=t.call(this)).getHeadersContent=e.getHeadersContent.bind(O()(e)),e.getRowsContent=e.getRowsContent.bind(O()(e)),e.getSummary=e.getSummary.bind(O()(e)),e}return i()(r,[{key:"getHeadersContent",value:function(){return[{label:Object(j.__)("Date",'woocommerce'),key:"date",required:!0,defaultSort:!0,isLeftAligned:!0,isSortable:!0},{label:Object(j.__)("Orders",'woocommerce'),key:"orders_count",required:!1,isSortable:!0,isNumeric:!0},{label:Object(j.__)("Gross Sales",'woocommerce'),key:"gross_sales",required:!1,isSortable:!0,isNumeric:!0},{label:Object(j.__)("Returns",'woocommerce'),key:"refunds",required:!1,isSortable:!0,isNumeric:!0},{label:Object(j.__)("Coupons",'woocommerce'),key:"coupons",required:!1,isSortable:!0,isNumeric:!0},{label:Object(j.__)("Net Sales",'woocommerce'),key:"net_revenue",required:!1,isSortable:!0,isNumeric:!0},{label:Object(j.__)("Taxes",'woocommerce'),key:"taxes",required:!1,isSortable:!0,isNumeric:!0},{label:Object(j.__)("Shipping",'woocommerce'),key:"shipping",required:!1,isSortable:!0,isNumeric:!0},{label:Object(j.__)("Total Sales",'woocommerce'),key:"total_sales",required:!1,isSortable:!0,isNumeric:!0}]}},{key:"getRowsContent",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=Object(k.g)("dateFormat",T.defaultTableDateFormat),r=this.context,a=r.formatAmount,n=r.render,o=r.formatDecimal,i=r.getCurrencyConfig;return e.map((function(e){var r=e.subtotals,s=r.coupons,c=r.gross_sales,u=r.total_sales,l=r.net_revenue,d=r.orders_count,m=r.refunds,y=r.shipping,f=r.taxes,b=Object(p.createElement)(S.Link,{href:"edit.php?post_type=shop_order&m="+Object(R.a)("Ymd",e.date_start),type:"wp-admin"},Object(C.formatValue)(i(),"number",d));return[{display:Object(p.createElement)(S.Date,{date:e.date_start,visibleFormat:t}),value:e.date_start},{display:b,value:Number(d)},{display:n(c),value:o(c)},{display:a(m),value:o(m)},{display:a(s),value:o(s)},{display:n(l),value:o(l)},{display:n(f),value:o(f)},{display:n(y),value:o(y)},{display:n(u),value:o(u)}]}))}},{key:"getSummary",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=e.orders_count,a=void 0===r?0:r,n=e.gross_sales,o=void 0===n?0:n,i=e.total_sales,s=void 0===i?0:i,c=e.refunds,u=void 0===c?0:c,l=e.coupons,d=void 0===l?0:l,m=e.taxes,p=void 0===m?0:m,y=e.shipping,f=void 0===y?0:y,b=e.net_revenue,v=void 0===b?0:b,g=this.context,h=g.formatAmount,_=g.getCurrencyConfig,O=_();return[{label:Object(j._n)("day","days",t,'woocommerce'),value:Object(C.formatValue)(O,"number",t)},{label:Object(j._n)("order","orders",a,'woocommerce'),value:Object(C.formatValue)(O,"number",a)},{label:Object(j.__)("gross sales",'woocommerce'),value:h(o)},{label:Object(j.__)("returns",'woocommerce'),value:h(u)},{label:Object(j.__)("coupons",'woocommerce'),value:h(d)},{label:Object(j.__)("net sales",'woocommerce'),value:h(v)},{label:Object(j.__)("taxes",'woocommerce'),value:h(p)},{label:Object(j.__)("shipping",'woocommerce'),value:h(f)},{label:Object(j.__)("total sales",'woocommerce'),value:h(s)}]}},{key:"render",value:function(){var e=this.props,t=e.advancedFilters,r=e.filters,a=e.tableData,n=e.query;return Object(p.createElement)(F.a,{endpoint:"revenue",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,getSummary:this.getSummary,summaryFields:["orders_count","gross_sales","total_sales","refunds","coupons","taxes","shipping","net_revenue"],query:n,tableData:a,title:Object(j.__)("Revenue",'woocommerce'),columnPrefsKey:"revenue_report_columns",filters:r,advancedFilters:t})}}]),r}(p.Component);N.contextType=P.a;var A=Object(q.a)(Object(w.withSelect)((function(e,t){var r=t.query,a=t.filters,n=t.advancedFilters,o=e(E.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,i=Object(T.getCurrentDates)(r,o),s=e(E.REPORTS_STORE_NAME),c=s.getReportStats,u=s.getReportStatsError,l=s.isResolving,d={interval:"day",orderby:r.orderby||"date",order:r.order||"desc",page:r.paged||1,per_page:r.per_page||E.QUERY_DEFAULTS.pageSize,after:Object(T.appendTimestamp)(i.primary.after,"start"),before:Object(T.appendTimestamp)(i.primary.before,"end")},m=Object(E.getReportTableQuery)({endpoint:"revenue",query:r,select:e,tableQuery:d,filters:a,advancedFilters:n}),p=c("revenue",m),y=Boolean(u("revenue",m)),f=l("getReportStats",["revenue",m]);return{tableData:{items:{data:Object(D.get)(p,["data","intervals"],[]),totalResults:Object(D.get)(p,["totalResults"],0)},isError:y,isRequesting:f,query:d}}})))(N),V=r(770);function L(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=m()(e);if(t){var n=m()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return l()(this,r)}}var I=function(e){c()(r,e);var t=L(r);function r(){return n()(this,r),t.apply(this,arguments)}return i()(r,[{key:"render",value:function(){var e=this.props,t=e.path,r=e.query;return Object(p.createElement)(p.Fragment,null,Object(p.createElement)(V.a,{query:r,path:t,report:"revenue",filters:b.c,advancedFilters:b.a}),Object(p.createElement)(h.a,{charts:b.b,endpoint:"revenue",query:r,selectedChart:Object(v.a)(r.chart,b.b),filters:b.c,advancedFilters:b.a}),Object(p.createElement)(g.a,{charts:b.b,endpoint:"revenue",path:t,query:r,selectedChart:Object(v.a)(r.chart,b.b),filters:b.c,advancedFilters:b.a}),Object(p.createElement)(A,{query:r,filters:b.c,advancedFilters:b.a}))}}]),r}(p.Component);I.propTypes={path:f.a.string.isRequired,query:f.a.object.isRequired}},766:function(e,t,r){"use strict";var a=r(5),n=r.n(a),o=r(17),i=r.n(o),s=r(15),c=r.n(s),u=r(18),l=r.n(u),d=r(19),m=r.n(d),p=r(9),y=r.n(p),f=r(0),b=r(3),v=r(277),g=r(154),h=r(20),_=r(2),O=r(1),j=r.n(O),R=r(77),w=r(35),q=r(40),D=r(762),S=r(763),C=r(32);function k(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function E(e){for(var t=1;t2&&void 0!==arguments[2]?arguments[2]:{};if(!t||0===t.length)return null;var n=t.slice(0),o=n.pop();if(o.showFilters(r,a)){var i=Object(C.flattenFilters)(o.filters),s=r[o.param]||o.defaultValue||"all";return Object(_.find)(i,{value:s})}return e(n,r,a)}(n,s),d=Object(_.get)(l,["settings","param"]),m=t.mode||function(e,t){if(e&&t){var r=Object(_.get)(e,["settings","param"]);if(!r||Object.keys(t).includes(r))return Object(_.get)(e,["chartMode"])}return null}(l,s)||"time-comparison",p=e(w.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,y={mode:m,filterParam:d,defaultDateRange:p};if(o)return y;var f=u.some((function(e){return s[e]&&s[e].length}));if(s.search&&!f)return E(E({},y),{},{emptySearchResults:!0});var b=r&&r.map((function(e){return e.key})),v=Object(w.getReportChartData)({endpoint:a,dataType:"primary",query:s,select:e,limitBy:u,filters:n,advancedFilters:c,defaultDateRange:p,fields:b});if("item-comparison"===m)return E(E({},y),{},{primaryData:v});var g=Object(w.getReportChartData)({endpoint:a,dataType:"secondary",query:s,select:e,limitBy:u,filters:n,advancedFilters:c,defaultDateRange:p,fields:b});return E(E({},y),{},{primaryData:v,secondaryData:g})})))(F)},768:function(e,t,r){"use strict";r.d(t,"a",(function(){return n}));var a=r(2);function n(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=Object(a.find)(t,{key:e});return r||t[0]}},769:function(e,t,r){"use strict";var a=r(17),n=r.n(a),o=r(15),i=r.n(o),s=r(18),c=r.n(s),u=r(19),l=r.n(u),d=r(9),m=r.n(d),p=r(0),y=r(3),f=r(277),b=r(20),v=r(1),g=r.n(v),h=r(32),_=r(77),O=r(298),j=r(35),R=r(40),w=r(64),q=r(763),D=r(762);function S(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=m()(e);if(t){var n=m()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return l()(this,r)}}var C=function(e){c()(r,e);var t=S(r);function r(){return n()(this,r),t.apply(this,arguments)}return i()(r,[{key:"formatVal",value:function(e,t){var r=this.context,a=r.formatAmount,n=r.getCurrencyConfig;return"currency"===t?a(e):Object(O.formatValue)(n(),t,e)}},{key:"getValues",value:function(e,t){var r=this.props,a=r.emptySearchResults,n=r.summaryData.totals,o=n.primary?n.primary[e]:0,i=n.secondary?n.secondary[e]:0,s=a?0:o,c=a?0:i;return{delta:Object(O.calculateDelta)(s,c),prevValue:this.formatVal(c,t),value:this.formatVal(s,t)}}},{key:"render",value:function(){var e=this,t=this.props,r=t.charts,a=t.query,n=t.selectedChart,o=t.summaryData,i=t.endpoint,s=t.report,c=t.defaultDateRange,u=o.isError,l=o.isRequesting;if(u)return Object(p.createElement)(q.a,{isError:!0});if(l)return Object(p.createElement)(_.SummaryListPlaceholder,{numberOfItems:r.length});var d=Object(R.getDateParamsFromQuery)(a,c).compare;return Object(p.createElement)(_.SummaryList,null,(function(t){var a=t.onToggle;return r.map((function(t){var r=t.key,o=t.order,c=t.orderby,u=t.label,l=t.type,m={chart:r};c&&(m.orderby=c),o&&(m.order=o);var f=Object(h.getNewPath)(m),b=n.key===r,v=e.getValues(r,l),g=v.delta,O=v.prevValue,j=v.value;return Object(p.createElement)(_.SummaryNumber,{key:r,delta:g,href:f,label:u,prevLabel:"previous_period"===d?Object(y.__)("Previous Period:",'woocommerce'):Object(y.__)("Previous Year:",'woocommerce'),prevValue:O,selected:b,value:j,onLinkClickCallback:function(){a&&a(),Object(w.recordEvent)("analytics_chart_tab_click",{report:s||i,key:r})}})}))}))}}]),r}(p.Component);C.propTypes={charts:g.a.array.isRequired,endpoint:g.a.string.isRequired,limitProperties:g.a.array,query:g.a.object.isRequired,selectedChart:g.a.shape({key:g.a.string.isRequired,label:g.a.string.isRequired,order:g.a.oneOf(["asc","desc"]),orderby:g.a.string,type:g.a.oneOf(["average","number","currency"]).isRequired}).isRequired,summaryData:g.a.object,report:g.a.string},C.defaultProps={summaryData:{totals:{primary:{},secondary:{}},isError:!1}},C.contextType=D.a,t.a=Object(f.a)(Object(b.withSelect)((function(e,t){var r=t.charts,a=t.endpoint,n=t.limitProperties,o=t.query,i=t.filters,s=t.advancedFilters,c=n||[a],u=c.some((function(e){return o[e]&&o[e].length}));if(o.search&&!u)return{emptySearchResults:!0};var l=r&&r.map((function(e){return e.key})),d=e(j.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range;return{summaryData:Object(j.getSummaryNumbers)({endpoint:a,query:o,select:e,limitBy:c,filters:i,advancedFilters:s,defaultDateRange:d,fields:l}),defaultDateRange:d}})))(C)},786:function(e,t,r){"use strict";r.d(t,"b",(function(){return o})),r.d(t,"c",(function(){return i})),r.d(t,"a",(function(){return s}));var a=r(3),n=r(55),o=Object(n.applyFilters)("woocommerce_admin_revenue_report_charts",[{key:"gross_sales",label:Object(a.__)("Gross Sales",'woocommerce'),order:"desc",orderby:"gross_sales",type:"currency"},{key:"refunds",label:Object(a.__)("Returns",'woocommerce'),order:"desc",orderby:"refunds",type:"currency"},{key:"coupons",label:Object(a.__)("Coupons",'woocommerce'),order:"desc",orderby:"coupons",type:"currency"},{key:"net_revenue",label:Object(a.__)("Net Sales",'woocommerce'),orderby:"net_revenue",type:"currency"},{key:"taxes",label:Object(a.__)("Taxes",'woocommerce'),order:"desc",orderby:"taxes",type:"currency"},{key:"shipping",label:Object(a.__)("Shipping",'woocommerce'),orderby:"shipping",type:"currency"},{key:"total_sales",label:Object(a.__)("Total Sales",'woocommerce'),order:"desc",orderby:"total_sales",type:"currency"}]),i=Object(n.applyFilters)("woocommerce_admin_revenue_report_filters",[]),s=Object(n.applyFilters)("woocommerce_admin_revenue_report_advanced_filters",{})}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-stock.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-stock.js new file mode 100644 index 0000000..0d3c840 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-stock.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[21],{742:function(e,t,o){"use strict";o.r(t),o.d(t,"default",(function(){return D}));var r=o(17),n=o.n(r),c=o(15),a=o.n(c),i=o(18),u=o.n(i),l=o(19),s=o.n(l),m=o(9),d=o.n(m),f=o(0),b=o(1),p=o.n(b),_=o(3),y=o(55),k=Object(y.applyFilters)("woocommerce_admin_stock_report_filters",[{label:Object(_.__)("Show",'woocommerce'),staticParams:["paged","per_page"],param:"type",showFilters:function(){return!0},filters:[{label:Object(_.__)("All Products",'woocommerce'),value:"all"},{label:Object(_.__)("Out of Stock",'woocommerce'),value:"outofstock"},{label:Object(_.__)("Low Stock",'woocommerce'),value:"lowstock"},{label:Object(_.__)("In Stock",'woocommerce'),value:"instock"},{label:Object(_.__)("On Backorder",'woocommerce'),value:"onbackorder"}]}]),v=Object(y.applyFilters)("woocommerce_admin_stock_report_advanced_filters",{}),w=o(11),O=o.n(w),j=o(81),h=o(77),g=o(32),S=o(298),C=o(36),R=o(771);function q(e,t,o){return!!t&&(e&&t<=o==="instock")}var F=o(762);function E(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var o,r=d()(e);if(t){var n=d()(this).constructor;o=Reflect.construct(r,arguments,n)}else o=r.apply(this,arguments);return s()(this,o)}}var P=Object(C.g)("stockStatuses",{}),V=function(e){u()(o,e);var t=E(o);function o(){var e;return n()(this,o),(e=t.call(this)).getHeadersContent=e.getHeadersContent.bind(O()(e)),e.getRowsContent=e.getRowsContent.bind(O()(e)),e.getSummary=e.getSummary.bind(O()(e)),e}return a()(o,[{key:"getHeadersContent",value:function(){return[{label:Object(_.__)("Product / Variation",'woocommerce'),key:"title",required:!0,isLeftAligned:!0,isSortable:!0},{label:Object(_.__)("SKU",'woocommerce'),key:"sku",isSortable:!0},{label:Object(_.__)("Status",'woocommerce'),key:"stock_status",isSortable:!0,defaultSort:!0},{label:Object(_.__)("Stock",'woocommerce'),key:"stock_quantity",isSortable:!0}]}},{key:"getRowsContent",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],o=this.props.query,r=Object(g.getPersistedQuery)(o);return t.map((function(t){var o=t.id,n=t.manage_stock,c=t.parent_id,a=t.sku,i=t.stock_quantity,u=t.stock_status,l=t.low_stock_amount,s=Object(j.decodeEntities)(t.name),m=Object(g.getNewPath)(r,"/analytics/products",{filter:"single_product",products:c||o}),d=Object(f.createElement)(h.Link,{href:m,type:"wc-admin"},s),b=Object(C.f)("post.php?action=edit&post="+(c||o));return[{display:d,value:s},{display:a,value:a},{display:q(u,i,l)?Object(f.createElement)(h.Link,{href:b,type:"wp-admin"},Object(_._x)("Low","Indication of a low quantity",'woocommerce')):Object(f.createElement)(h.Link,{href:b,type:"wp-admin"},P[u]),value:u},{display:n?Object(S.formatValue)(e.context.getCurrencyConfig(),"number",i):Object(_.__)("N/A",'woocommerce'),value:i}]}))}},{key:"getSummary",value:function(e){var t=e.products,o=void 0===t?0:t,r=e.outofstock,n=void 0===r?0:r,c=e.lowstock,a=void 0===c?0:c,i=e.instock,u=void 0===i?0:i,l=e.onbackorder,s=void 0===l?0:l,m=this.context.getCurrencyConfig();return[{label:Object(_._n)("product","products",o,'woocommerce'),value:Object(S.formatValue)(m,"number",o)},{label:Object(_.__)("out of stock",'woocommerce'),value:Object(S.formatValue)(m,"number",n)},{label:Object(_.__)("low stock",'woocommerce'),value:Object(S.formatValue)(m,"number",a)},{label:Object(_.__)("on backorder",'woocommerce'),value:Object(S.formatValue)(m,"number",s)},{label:Object(_.__)("in stock",'woocommerce'),value:Object(S.formatValue)(m,"number",u)}]}},{key:"render",value:function(){var e=this.props,t=e.advancedFilters,o=e.filters,r=e.query;return Object(f.createElement)(R.a,{endpoint:"stock",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,getSummary:this.getSummary,summaryFields:["products","outofstock","lowstock","instock","onbackorder"],query:r,tableQuery:{orderby:r.orderby||"stock_status",order:r.order||"asc",type:r.type||"all"},title:Object(_.__)("Stock",'woocommerce'),filters:o,advancedFilters:t})}}]),o}(f.Component);V.contextType=F.a;var x=V,L=o(770);function A(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var o,r=d()(e);if(t){var n=d()(this).constructor;o=Reflect.construct(r,arguments,n)}else o=r.apply(this,arguments);return s()(this,o)}}var D=function(e){u()(o,e);var t=A(o);function o(){return n()(this,o),t.apply(this,arguments)}return a()(o,[{key:"render",value:function(){var e=this.props,t=e.query,o=e.path;return Object(f.createElement)(f.Fragment,null,Object(f.createElement)(L.a,{query:t,path:o,showDatePicker:!1,filters:k,advancedFilters:v,report:"stock"}),Object(f.createElement)(x,{query:t,filters:k,advancedFilters:v}))}}]),o}(f.Component);D.propTypes={query:p.a.object.isRequired}}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-taxes.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-taxes.js new file mode 100644 index 0000000..101174e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-taxes.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[22],{749:function(e,t,r){"use strict";r.r(t),r.d(t,"default",(function(){return L}));var a=r(5),n=r.n(a),o=r(17),i=r.n(o),c=r(15),s=r.n(c),u=r(18),l=r.n(u),d=r(19),m=r.n(d),p=r(9),f=r.n(p),y=r(0),b=r(1),g=r.n(b),h=r(3),v=r(790),_=r(768),O=r(766),j=r(769),R=r(11),x=r.n(R),w=r(2),C=r(77),q=r(32),D=r(298),k=r(765),S=r(771),E=r(762);function P(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=f()(e);if(t){var n=f()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return m()(this,r)}}var T=function(e){l()(r,e);var t=P(r);function r(){var e;return i()(this,r),(e=t.call(this)).getHeadersContent=e.getHeadersContent.bind(x()(e)),e.getRowsContent=e.getRowsContent.bind(x()(e)),e.getSummary=e.getSummary.bind(x()(e)),e}return s()(r,[{key:"getHeadersContent",value:function(){return[{label:Object(h.__)("Tax Code",'woocommerce'),key:"tax_code",required:!0,isLeftAligned:!0,isSortable:!0},{label:Object(h.__)("Rate",'woocommerce'),key:"rate",isSortable:!0,isNumeric:!0},{label:Object(h.__)("Total Tax",'woocommerce'),key:"total_tax",isSortable:!0},{label:Object(h.__)("Order Tax",'woocommerce'),key:"order_tax",isSortable:!0},{label:Object(h.__)("Shipping Tax",'woocommerce'),key:"shipping_tax",isSortable:!0},{label:Object(h.__)("Orders",'woocommerce'),key:"orders_count",required:!0,defaultSort:!0,isSortable:!0,isNumeric:!0}]}},{key:"getRowsContent",value:function(e){var t=this,r=this.context,a=r.render,n=r.formatDecimal,o=r.getCurrencyConfig;return Object(w.map)(e,(function(e){var r=t.props.query,i=e.order_tax,c=e.orders_count,s=e.tax_rate,u=e.tax_rate_id,l=e.total_tax,d=e.shipping_tax,m=Object(k.a)(e),p=Object(q.getPersistedQuery)(r),f=Object(q.getNewPath)(p,"/analytics/orders",{filter:"advanced",tax_rate_includes:u});return[{display:Object(y.createElement)(C.Link,{href:f,type:"wc-admin"},m),value:m},{display:s.toFixed(2)+"%",value:s},{display:a(l),value:n(l)},{display:a(i),value:n(i)},{display:a(d),value:n(d)},{display:Object(D.formatValue)(o(),"number",c),value:c}]}))}},{key:"getSummary",value:function(e){var t=e.tax_codes,r=void 0===t?0:t,a=e.total_tax,n=void 0===a?0:a,o=e.order_tax,i=void 0===o?0:o,c=e.shipping_tax,s=void 0===c?0:c,u=e.orders_count,l=void 0===u?0:u,d=this.context,m=d.formatAmount,p=(0,d.getCurrencyConfig)();return[{label:Object(h._n)("tax code","tax codes",r,'woocommerce'),value:Object(D.formatValue)(p,"number",r)},{label:Object(h.__)("total tax",'woocommerce'),value:m(n)},{label:Object(h.__)("order tax",'woocommerce'),value:m(i)},{label:Object(h.__)("shipping tax",'woocommerce'),value:m(s)},{label:Object(h._n)("order","orders",l,'woocommerce'),value:Object(D.formatValue)(p,"number",l)}]}},{key:"render",value:function(){var e=this.props,t=e.advancedFilters,r=e.filters,a=e.isRequesting,n=e.query;return Object(y.createElement)(S.a,{compareBy:"taxes",endpoint:"taxes",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,getSummary:this.getSummary,summaryFields:["tax_codes","total_tax","order_tax","shipping_tax","orders_count"],isRequesting:a,itemIdField:"tax_rate_id",query:n,searchBy:"taxes",tableQuery:{orderby:n.orderby||"tax_rate_id"},title:Object(h.__)("Taxes",'woocommerce'),columnPrefsKey:"taxes_report_columns",filters:r,advancedFilters:t})}}]),r}(y.Component);T.contextType=E.a;var F=T,A=r(770);function N(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function M(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=f()(e);if(t){var n=f()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return m()(this,r)}}var L=function(e){l()(r,e);var t=M(r);function r(){return i()(this,r),t.apply(this,arguments)}return s()(r,[{key:"getChartMeta",value:function(){var e="compare-taxes"===this.props.query.filter?"item-comparison":"time-comparison";return{itemsLabel:Object(h.__)("%d taxes",'woocommerce'),mode:e}}},{key:"render",value:function(){var e=this.props,t=e.isRequesting,r=e.query,a=e.path,o=this.getChartMeta(),i=o.mode,c=o.itemsLabel,s=function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:i.identity;return function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1?arguments[1]:void 0,i="function"==typeof e?e(n):e,s=Object(c.getIdsFromQuery)(r);if(s.length<1)return Promise.resolve([]);var u={include:s.join(","),per_page:s.length};return o()({path:Object(a.addQueryArgs)(i,u)}).then((function(e){return e.map(t)}))}}var m=d(s.NAMESPACE+"/products/categories",(function(e){return{key:e.id,label:e.name}})),p=d(s.NAMESPACE+"/coupons",(function(e){return{key:e.id,label:e.code}})),f=d(s.NAMESPACE+"/customers",(function(e){return{key:e.id,label:e.name}})),y=d(s.NAMESPACE+"/products",(function(e){return{key:e.id,label:e.name}})),b=d(s.NAMESPACE+"/taxes",(function(e){return{key:e.id,label:Object(l.a)(e)}}));function g(e){var t=e.attributes,r=e.name,a=Object(u.g)("variationTitleAttributesSeparator"," - ");if(r.indexOf(a)>-1)return r;var n=t.map((function(e){return e.option})).join(", ");return n?r+a+n:r}var h=d((function(e){var t=e.products;return t?s.NAMESPACE+"/products/".concat(t,"/variations"):s.NAMESPACE+"/variations"}),(function(e){return{key:e.id,label:g(e)}}))},765:function(e,t,r){"use strict";r.d(t,"a",(function(){return n}));var a=r(3);function n(e){return[e.country,e.state,e.name||Object(a.__)("TAX",'woocommerce'),e.priority].map((function(e){return e.toString().toUpperCase().trim()})).filter(Boolean).join("-")}},766:function(e,t,r){"use strict";var a=r(5),n=r.n(a),o=r(17),i=r.n(o),c=r(15),s=r.n(c),u=r(18),l=r.n(u),d=r(19),m=r.n(d),p=r(9),f=r.n(p),y=r(0),b=r(3),g=r(277),h=r(154),v=r(20),_=r(2),O=r(1),j=r.n(O),R=r(77),x=r(35),w=r(40),C=r(762),q=r(763),D=r(32);function k(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function S(e){for(var t=1;t2&&void 0!==arguments[2]?arguments[2]:{};if(!t||0===t.length)return null;var n=t.slice(0),o=n.pop();if(o.showFilters(r,a)){var i=Object(D.flattenFilters)(o.filters),c=r[o.param]||o.defaultValue||"all";return Object(_.find)(i,{value:c})}return e(n,r,a)}(n,c),d=Object(_.get)(l,["settings","param"]),m=t.mode||function(e,t){if(e&&t){var r=Object(_.get)(e,["settings","param"]);if(!r||Object.keys(t).includes(r))return Object(_.get)(e,["chartMode"])}return null}(l,c)||"time-comparison",p=e(x.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,f={mode:m,filterParam:d,defaultDateRange:p};if(o)return f;var y=u.some((function(e){return c[e]&&c[e].length}));if(c.search&&!y)return S(S({},f),{},{emptySearchResults:!0});var b=r&&r.map((function(e){return e.key})),g=Object(x.getReportChartData)({endpoint:a,dataType:"primary",query:c,select:e,limitBy:u,filters:n,advancedFilters:s,defaultDateRange:p,fields:b});if("item-comparison"===m)return S(S({},f),{},{primaryData:g});var h=Object(x.getReportChartData)({endpoint:a,dataType:"secondary",query:c,select:e,limitBy:u,filters:n,advancedFilters:s,defaultDateRange:p,fields:b});return S(S({},f),{},{primaryData:g,secondaryData:h})})))(P)},768:function(e,t,r){"use strict";r.d(t,"a",(function(){return n}));var a=r(2);function n(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=Object(a.find)(t,{key:e});return r||t[0]}},769:function(e,t,r){"use strict";var a=r(17),n=r.n(a),o=r(15),i=r.n(o),c=r(18),s=r.n(c),u=r(19),l=r.n(u),d=r(9),m=r.n(d),p=r(0),f=r(3),y=r(277),b=r(20),g=r(1),h=r.n(g),v=r(32),_=r(77),O=r(298),j=r(35),R=r(40),x=r(64),w=r(763),C=r(762);function q(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=m()(e);if(t){var n=m()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return l()(this,r)}}var D=function(e){s()(r,e);var t=q(r);function r(){return n()(this,r),t.apply(this,arguments)}return i()(r,[{key:"formatVal",value:function(e,t){var r=this.context,a=r.formatAmount,n=r.getCurrencyConfig;return"currency"===t?a(e):Object(O.formatValue)(n(),t,e)}},{key:"getValues",value:function(e,t){var r=this.props,a=r.emptySearchResults,n=r.summaryData.totals,o=n.primary?n.primary[e]:0,i=n.secondary?n.secondary[e]:0,c=a?0:o,s=a?0:i;return{delta:Object(O.calculateDelta)(c,s),prevValue:this.formatVal(s,t),value:this.formatVal(c,t)}}},{key:"render",value:function(){var e=this,t=this.props,r=t.charts,a=t.query,n=t.selectedChart,o=t.summaryData,i=t.endpoint,c=t.report,s=t.defaultDateRange,u=o.isError,l=o.isRequesting;if(u)return Object(p.createElement)(w.a,{isError:!0});if(l)return Object(p.createElement)(_.SummaryListPlaceholder,{numberOfItems:r.length});var d=Object(R.getDateParamsFromQuery)(a,s).compare;return Object(p.createElement)(_.SummaryList,null,(function(t){var a=t.onToggle;return r.map((function(t){var r=t.key,o=t.order,s=t.orderby,u=t.label,l=t.type,m={chart:r};s&&(m.orderby=s),o&&(m.order=o);var y=Object(v.getNewPath)(m),b=n.key===r,g=e.getValues(r,l),h=g.delta,O=g.prevValue,j=g.value;return Object(p.createElement)(_.SummaryNumber,{key:r,delta:h,href:y,label:u,prevLabel:"previous_period"===d?Object(f.__)("Previous Period:",'woocommerce'):Object(f.__)("Previous Year:",'woocommerce'),prevValue:O,selected:b,value:j,onLinkClickCallback:function(){a&&a(),Object(x.recordEvent)("analytics_chart_tab_click",{report:c||i,key:r})}})}))}))}}]),r}(p.Component);D.propTypes={charts:h.a.array.isRequired,endpoint:h.a.string.isRequired,limitProperties:h.a.array,query:h.a.object.isRequired,selectedChart:h.a.shape({key:h.a.string.isRequired,label:h.a.string.isRequired,order:h.a.oneOf(["asc","desc"]),orderby:h.a.string,type:h.a.oneOf(["average","number","currency"]).isRequired}).isRequired,summaryData:h.a.object,report:h.a.string},D.defaultProps={summaryData:{totals:{primary:{},secondary:{}},isError:!1}},D.contextType=C.a,t.a=Object(y.a)(Object(b.withSelect)((function(e,t){var r=t.charts,a=t.endpoint,n=t.limitProperties,o=t.query,i=t.filters,c=t.advancedFilters,s=n||[a],u=s.some((function(e){return o[e]&&o[e].length}));if(o.search&&!u)return{emptySearchResults:!0};var l=r&&r.map((function(e){return e.key})),d=e(j.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range;return{summaryData:Object(j.getSummaryNumbers)({endpoint:a,query:o,select:e,limitBy:s,filters:i,advancedFilters:c,defaultDateRange:d,fields:l}),defaultDateRange:d}})))(D)},790:function(e,t,r){"use strict";r.d(t,"b",(function(){return s})),r.d(t,"c",(function(){return u})),r.d(t,"a",(function(){return l}));var a=r(3),n=r(55),o=r(35),i=r(764),c=r(765),s=Object(n.applyFilters)("woocommerce_admin_taxes_report_charts",[{key:"total_tax",label:Object(a.__)("Total Tax",'woocommerce'),order:"desc",orderby:"total_tax",type:"currency"},{key:"order_tax",label:Object(a.__)("Order Tax",'woocommerce'),order:"desc",orderby:"order_tax",type:"currency"},{key:"shipping_tax",label:Object(a.__)("Shipping Tax",'woocommerce'),order:"desc",orderby:"shipping_tax",type:"currency"},{key:"orders_count",label:Object(a.__)("Orders",'woocommerce'),order:"desc",orderby:"orders_count",type:"number"}]),u=Object(n.applyFilters)("woocommerce_admin_taxes_report_filters",[{label:Object(a.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(a.__)("All Taxes",'woocommerce'),value:"all"},{label:Object(a.__)("Comparison",'woocommerce'),value:"compare-taxes",chartMode:"item-comparison",settings:{type:"taxes",param:"taxes",getLabels:Object(i.e)(o.NAMESPACE+"/taxes",(function(e){return{id:e.id,key:e.id,label:Object(c.a)(e)}})),labels:{helpText:Object(a.__)("Check at least two tax codes below to compare",'woocommerce'),placeholder:Object(a.__)("Search for tax codes to compare",'woocommerce'),title:Object(a.__)("Compare Tax Codes",'woocommerce'),update:Object(a.__)("Compare",'woocommerce')}}}]}]),l=Object(n.applyFilters)("woocommerce_admin_taxes_report_advanced_filters",{})}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-variations.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-variations.js new file mode 100644 index 0000000..afc13b8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report-variations.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[23],{746:function(e,t,r){"use strict";r.r(t);var a=r(5),n=r.n(a),o=r(0),i=r(3),c=r(1),s=r.n(c),l=r(55),u=r(764),m=Object(l.applyFilters)("woocommerce_admin_variations_report_charts",[{key:"items_sold",label:Object(i.__)("Items Sold",'woocommerce'),order:"desc",orderby:"items_sold",type:"number"},{key:"net_revenue",label:Object(i.__)("Net Sales",'woocommerce'),order:"desc",orderby:"net_revenue",type:"currency"},{key:"orders_count",label:Object(i.__)("Orders",'woocommerce'),order:"desc",orderby:"orders_count",type:"number"}]),d=Object(l.applyFilters)("woocommerce_admin_variations_report_filters",[{label:Object(i.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter-variations",showFilters:function(){return!0},filters:[{label:Object(i.__)("All Variations",'woocommerce'),chartMode:"item-comparison",value:"all"},{label:Object(i.__)("Single Variation",'woocommerce'),value:"select_variation",subFilters:[{component:"Search",value:"single_variation",path:["select_variation"],settings:{type:"variations",param:"variations",getLabels:u.g,labels:{placeholder:Object(i.__)("Type to search for a variation",'woocommerce'),button:Object(i.__)("Single Variation",'woocommerce')}}}]},{label:Object(i.__)("Comparison",'woocommerce'),chartMode:"item-comparison",value:"compare-variations",settings:{type:"variations",param:"variations",getLabels:u.g,labels:{helpText:Object(i.__)("Check at least two variations below to compare",'woocommerce'),placeholder:Object(i.__)("Search for variations to compare",'woocommerce'),title:Object(i.__)("Compare Variations",'woocommerce'),update:Object(i.__)("Compare",'woocommerce')}}},{label:Object(i.__)("Advanced Filters",'woocommerce'),value:"advanced"}]}]),p=Object(l.applyFilters)("woocommerce_admin_variations_report_advanced_filters",{title:Object(i._x)("Variations Match {{select /}} Filters","A sentence describing filters for Variations. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ",'woocommerce'),filters:{attribute:{allowMultiple:!0,labels:{add:Object(i.__)("Attribute",'woocommerce'),placeholder:Object(i.__)("Search attributes",'woocommerce'),remove:Object(i.__)("Remove attribute filter",'woocommerce'),rule:Object(i.__)("Select a product attribute filter match",'woocommerce'),title:Object(i.__)("{{title}}Attribute{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(i.__)("Select attributes",'woocommerce')},rules:[{value:"is",label:Object(i._x)("Is","product attribute",'woocommerce')},{value:"is_not",label:Object(i._x)("Is Not","product attribute",'woocommerce')}],input:{component:"ProductAttribute"}},category:{labels:{add:Object(i.__)("Categories",'woocommerce'),placeholder:Object(i.__)("Search categories",'woocommerce'),remove:Object(i.__)("Remove categories filter",'woocommerce'),rule:Object(i.__)("Select a category filter match",'woocommerce'),title:Object(i.__)("{{title}}Category{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(i.__)("Select categories",'woocommerce')},rules:[{value:"includes",label:Object(i._x)("Includes","categories",'woocommerce')},{value:"excludes",label:Object(i._x)("Excludes","categories",'woocommerce')}],input:{component:"Search",type:"categories",getLabels:u.a}},product:{labels:{add:Object(i.__)("Products",'woocommerce'),placeholder:Object(i.__)("Search products",'woocommerce'),remove:Object(i.__)("Remove products filter",'woocommerce'),rule:Object(i.__)("Select a product filter match",'woocommerce'),title:Object(i.__)("{{title}}Product{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(i.__)("Select products",'woocommerce')},rules:[{value:"includes",label:Object(i._x)("Includes","products",'woocommerce')},{value:"excludes",label:Object(i._x)("Excludes","products",'woocommerce')}],input:{component:"Search",type:"variableProducts",getLabels:u.d}}}}),b=r(768),f=r(766),y=r(763),v=r(769),_=r(788),g=r(770);function h(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}var O=function(e){var t=function(e){var t=e.query,r="compare-variations"===t["filter-variations"]&&t.variations&&t.variations.split(",").length>1;return{compareObject:"variations",itemsLabel:Object(i.__)("%d variations",'woocommerce'),mode:r?"item-comparison":"time-comparison"}}(e),r=t.itemsLabel,a=t.mode,c=e.path,s=e.query,l=e.isError,u=e.isRequesting;if(l)return Object(o.createElement)(y.a,{isError:!0});var O=function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:i.identity;return function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1?arguments[1]:void 0,i="function"==typeof e?e(n):e,s=Object(c.getIdsFromQuery)(r);if(s.length<1)return Promise.resolve([]);var l={include:s.join(","),per_page:s.length};return o()({path:Object(a.addQueryArgs)(i,l)}).then((function(e){return e.map(t)}))}}var d=m(s.NAMESPACE+"/products/categories",(function(e){return{key:e.id,label:e.name}})),p=m(s.NAMESPACE+"/coupons",(function(e){return{key:e.id,label:e.code}})),b=m(s.NAMESPACE+"/customers",(function(e){return{key:e.id,label:e.name}})),f=m(s.NAMESPACE+"/products",(function(e){return{key:e.id,label:e.name}})),y=m(s.NAMESPACE+"/taxes",(function(e){return{key:e.id,label:Object(u.a)(e)}}));function v(e){var t=e.attributes,r=e.name,a=Object(l.g)("variationTitleAttributesSeparator"," - ");if(r.indexOf(a)>-1)return r;var n=t.map((function(e){return e.option})).join(", ");return n?r+a+n:r}var _=m((function(e){var t=e.products;return t?s.NAMESPACE+"/products/".concat(t,"/variations"):s.NAMESPACE+"/variations"}),(function(e){return{key:e.id,label:v(e)}}))},765:function(e,t,r){"use strict";r.d(t,"a",(function(){return n}));var a=r(3);function n(e){return[e.country,e.state,e.name||Object(a.__)("TAX",'woocommerce'),e.priority].map((function(e){return e.toString().toUpperCase().trim()})).filter(Boolean).join("-")}},766:function(e,t,r){"use strict";var a=r(5),n=r.n(a),o=r(17),i=r.n(o),c=r(15),s=r.n(c),l=r(18),u=r.n(l),m=r(19),d=r.n(m),p=r(9),b=r.n(p),f=r(0),y=r(3),v=r(277),_=r(154),g=r(20),h=r(2),O=r(1),j=r.n(O),w=r(77),R=r(35),S=r(40),k=r(762),C=r(763),q=r(32);function D(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function E(e){for(var t=1;t2&&void 0!==arguments[2]?arguments[2]:{};if(!t||0===t.length)return null;var n=t.slice(0),o=n.pop();if(o.showFilters(r,a)){var i=Object(q.flattenFilters)(o.filters),c=r[o.param]||o.defaultValue||"all";return Object(h.find)(i,{value:c})}return e(n,r,a)}(n,c),m=Object(h.get)(u,["settings","param"]),d=t.mode||function(e,t){if(e&&t){var r=Object(h.get)(e,["settings","param"]);if(!r||Object.keys(t).includes(r))return Object(h.get)(e,["chartMode"])}return null}(u,c)||"time-comparison",p=e(R.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,b={mode:d,filterParam:m,defaultDateRange:p};if(o)return b;var f=l.some((function(e){return c[e]&&c[e].length}));if(c.search&&!f)return E(E({},b),{},{emptySearchResults:!0});var y=r&&r.map((function(e){return e.key})),v=Object(R.getReportChartData)({endpoint:a,dataType:"primary",query:c,select:e,limitBy:l,filters:n,advancedFilters:s,defaultDateRange:p,fields:y});if("item-comparison"===d)return E(E({},b),{},{primaryData:v});var _=Object(R.getReportChartData)({endpoint:a,dataType:"secondary",query:c,select:e,limitBy:l,filters:n,advancedFilters:s,defaultDateRange:p,fields:y});return E(E({},b),{},{primaryData:v,secondaryData:_})})))(F)},768:function(e,t,r){"use strict";r.d(t,"a",(function(){return n}));var a=r(2);function n(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=Object(a.find)(t,{key:e});return r||t[0]}},769:function(e,t,r){"use strict";var a=r(17),n=r.n(a),o=r(15),i=r.n(o),c=r(18),s=r.n(c),l=r(19),u=r.n(l),m=r(9),d=r.n(m),p=r(0),b=r(3),f=r(277),y=r(20),v=r(1),_=r.n(v),g=r(32),h=r(77),O=r(298),j=r(35),w=r(40),R=r(64),S=r(763),k=r(762);function C(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=d()(e);if(t){var n=d()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return u()(this,r)}}var q=function(e){s()(r,e);var t=C(r);function r(){return n()(this,r),t.apply(this,arguments)}return i()(r,[{key:"formatVal",value:function(e,t){var r=this.context,a=r.formatAmount,n=r.getCurrencyConfig;return"currency"===t?a(e):Object(O.formatValue)(n(),t,e)}},{key:"getValues",value:function(e,t){var r=this.props,a=r.emptySearchResults,n=r.summaryData.totals,o=n.primary?n.primary[e]:0,i=n.secondary?n.secondary[e]:0,c=a?0:o,s=a?0:i;return{delta:Object(O.calculateDelta)(c,s),prevValue:this.formatVal(s,t),value:this.formatVal(c,t)}}},{key:"render",value:function(){var e=this,t=this.props,r=t.charts,a=t.query,n=t.selectedChart,o=t.summaryData,i=t.endpoint,c=t.report,s=t.defaultDateRange,l=o.isError,u=o.isRequesting;if(l)return Object(p.createElement)(S.a,{isError:!0});if(u)return Object(p.createElement)(h.SummaryListPlaceholder,{numberOfItems:r.length});var m=Object(w.getDateParamsFromQuery)(a,s).compare;return Object(p.createElement)(h.SummaryList,null,(function(t){var a=t.onToggle;return r.map((function(t){var r=t.key,o=t.order,s=t.orderby,l=t.label,u=t.type,d={chart:r};s&&(d.orderby=s),o&&(d.order=o);var f=Object(g.getNewPath)(d),y=n.key===r,v=e.getValues(r,u),_=v.delta,O=v.prevValue,j=v.value;return Object(p.createElement)(h.SummaryNumber,{key:r,delta:_,href:f,label:l,prevLabel:"previous_period"===m?Object(b.__)("Previous Period:",'woocommerce'):Object(b.__)("Previous Year:",'woocommerce'),prevValue:O,selected:y,value:j,onLinkClickCallback:function(){a&&a(),Object(R.recordEvent)("analytics_chart_tab_click",{report:c||i,key:r})}})}))}))}}]),r}(p.Component);q.propTypes={charts:_.a.array.isRequired,endpoint:_.a.string.isRequired,limitProperties:_.a.array,query:_.a.object.isRequired,selectedChart:_.a.shape({key:_.a.string.isRequired,label:_.a.string.isRequired,order:_.a.oneOf(["asc","desc"]),orderby:_.a.string,type:_.a.oneOf(["average","number","currency"]).isRequired}).isRequired,summaryData:_.a.object,report:_.a.string},q.defaultProps={summaryData:{totals:{primary:{},secondary:{}},isError:!1}},q.contextType=k.a,t.a=Object(f.a)(Object(y.withSelect)((function(e,t){var r=t.charts,a=t.endpoint,n=t.limitProperties,o=t.query,i=t.filters,c=t.advancedFilters,s=n||[a],l=s.some((function(e){return o[e]&&o[e].length}));if(o.search&&!l)return{emptySearchResults:!0};var u=r&&r.map((function(e){return e.key})),m=e(j.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range;return{summaryData:Object(j.getSummaryNumbers)({endpoint:a,query:o,select:e,limitBy:s,filters:i,advancedFilters:c,defaultDateRange:m,fields:u}),defaultDateRange:m}})))(q)},781:function(e,t,r){"use strict";function a(e,t,r){return!!t&&(e&&t<=r==="instock")}r.d(t,"a",(function(){return a}))},788:function(e,t,r){"use strict";var a=r(17),n=r.n(a),o=r(15),i=r.n(o),c=r(11),s=r.n(c),l=r(18),u=r.n(l),m=r(19),d=r.n(m),p=r(9),b=r.n(p),f=r(0),y=r(3),v=r(2),_=r(77),g=r(32),h=r(298),O=r(36),j=r(771),w=r(781),R=r(762),S=r(764);function k(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=b()(e);if(t){var n=b()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return d()(this,r)}}var C=Object(O.g)("manageStock","no"),q=Object(O.g)("stockStatuses",{}),D=function(e){return Object(S.h)(e.extended_info||{})},E=function(e){u()(r,e);var t=k(r);function r(){var e;return n()(this,r),(e=t.call(this)).getHeadersContent=e.getHeadersContent.bind(s()(e)),e.getRowsContent=e.getRowsContent.bind(s()(e)),e.getSummary=e.getSummary.bind(s()(e)),e}return i()(r,[{key:"getHeadersContent",value:function(){return[{label:Object(y.__)("Product / Variation Title",'woocommerce'),key:"name",required:!0,isLeftAligned:!0},{label:Object(y.__)("SKU",'woocommerce'),key:"sku",hiddenByDefault:!0,isSortable:!0},{label:Object(y.__)("Items Sold",'woocommerce'),key:"items_sold",required:!0,defaultSort:!0,isSortable:!0,isNumeric:!0},{label:Object(y.__)("Net Sales",'woocommerce'),screenReaderLabel:Object(y.__)("Net Sales",'woocommerce'),key:"net_revenue",required:!0,isSortable:!0,isNumeric:!0},{label:Object(y.__)("Orders",'woocommerce'),key:"orders_count",isSortable:!0,isNumeric:!0},"yes"===C?{label:Object(y.__)("Status",'woocommerce'),key:"stock_status"}:null,"yes"===C?{label:Object(y.__)("Stock",'woocommerce'),key:"stock",isNumeric:!0}:null].filter(Boolean)}},{key:"getRowsContent",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=this.props.query,r=Object(g.getPersistedQuery)(t),a=this.context,n=a.formatAmount,o=a.formatDecimal,i=a.getCurrencyConfig;return Object(v.map)(e,(function(e){var t=e.items_sold,a=e.net_revenue,c=e.orders_count,s=e.product_id,l=e.variation_id,u=e.extended_info||{},m=u.stock_status,d=u.stock_quantity,p=u.low_stock_amount,b=u.sku,v=D(e),j=Object(g.getNewPath)(r,"/analytics/orders",{filter:"advanced",variation_includes:l}),R=Object(O.f)("post.php?post=".concat(s,"&action=edit"));return[{display:Object(f.createElement)(_.Link,{href:R,type:"wp-admin"},v),value:v},{display:b,value:b},{display:Object(h.formatValue)(i(),"number",t),value:t},{display:n(a),value:o(a)},{display:Object(f.createElement)(_.Link,{href:j,type:"wc-admin"},c),value:c},"yes"===C?{display:Object(w.a)(m,d,p)?Object(f.createElement)(_.Link,{href:R,type:"wp-admin"},Object(y._x)("Low","Indication of a low quantity",'woocommerce')):q[m],value:q[m]}:null,"yes"===C?{display:d,value:d}:null].filter(Boolean)}))}},{key:"getSummary",value:function(e){var t=e.variations_count,r=void 0===t?0:t,a=e.items_sold,n=void 0===a?0:a,o=e.net_revenue,i=void 0===o?0:o,c=e.orders_count,s=void 0===c?0:c,l=this.context,u=l.formatAmount,m=(0,l.getCurrencyConfig)();return[{label:Object(y._n)("variation sold","variations sold",r,'woocommerce'),value:Object(h.formatValue)(m,"number",r)},{label:Object(y._n)("item sold","items sold",n,'woocommerce'),value:Object(h.formatValue)(m,"number",n)},{label:Object(y.__)("net sales",'woocommerce'),value:u(i)},{label:Object(y._n)("orders","orders",s,'woocommerce'),value:Object(h.formatValue)(m,"number",s)}]}},{key:"render",value:function(){var e=this.props,t=e.advancedFilters,r=e.baseSearchQuery,a=e.filters,n=e.isRequesting,o=e.query,i={helpText:Object(y.__)("Check at least two variations below to compare",'woocommerce'),placeholder:Object(y.__)("Search by variation name or SKU",'woocommerce')};return Object(f.createElement)(j.a,{baseSearchQuery:r,compareBy:"variations",compareParam:"filter-variations",endpoint:"variations",getHeadersContent:this.getHeadersContent,getRowsContent:this.getRowsContent,isRequesting:n,itemIdField:"variation_id",labels:i,query:o,getSummary:this.getSummary,summaryFields:["variations_count","items_sold","net_revenue","orders_count"],tableQuery:{orderby:o.orderby||"items_sold",order:o.order||"desc",extended_info:!0,products:o.products,variations:o.variations},title:Object(y.__)("Variations",'woocommerce'),columnPrefsKey:"variations_report_columns",filters:a,advancedFilters:t})}}]),r}(f.Component);E.contextType=R.a,t.a=E}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report.js new file mode 100644 index 0000000..dd70a4a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/analytics-report.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[13],{762:function(t,e,r){"use strict";r.d(e,"b",(function(){return u})),r.d(e,"a",(function(){return f}));var n=r(0),c=r(55),o=r(214),i=r.n(o),a=r(36),s=i()(a.b),u=function(t){var e=s.getCurrencyConfig(),r=Object(c.applyFilters)("woocommerce_admin_report_currency",e,t);return i()(r)},f=Object(n.createContext)(s)},763:function(t,e,r){"use strict";var n=r(17),c=r.n(n),o=r(15),i=r.n(o),a=r(18),s=r.n(a),u=r(19),f=r.n(u),p=r(9),l=r.n(p),b=r(0),y=r(3),m=r(1),h=r.n(m),O=r(77),d=r(36);function j(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}();return function(){var r,n=l()(t);if(e){var c=l()(this).constructor;r=Reflect.construct(n,arguments,c)}else r=n.apply(this,arguments);return f()(this,r)}}var v=function(t){s()(r,t);var e=j(r);function r(){return c()(this,r),e.apply(this,arguments)}return i()(r,[{key:"render",value:function(){var t,e,r,n,c=this.props,o=c.className,i=c.isError,a=c.isEmpty;return i?(t=Object(y.__)("There was an error getting your stats. Please try again.",'woocommerce'),e=Object(y.__)("Reload",'woocommerce'),n=function(){window.location.reload()}):a&&(t=Object(y.__)("No results could be found for this date range.",'woocommerce'),e=Object(y.__)("View Orders",'woocommerce'),r=Object(d.f)("edit.php?post_type=shop_order")),Object(b.createElement)(O.EmptyContent,{className:o,title:t,actionLabel:e,actionURL:r,actionCallback:n})}}]),r}(b.Component);v.propTypes={className:h.a.string,isError:h.a.bool,isEmpty:h.a.bool},v.defaultProps={className:""},e.a=v},801:function(t,e,r){},840:function(t,e,r){"use strict";r.r(e);var n=r(5),c=r.n(n),o=r(17),i=r.n(o),a=r(15),s=r.n(a),u=r(18),f=r.n(u),p=r(19),l=r.n(p),b=r(9),y=r.n(b),m=r(0),h=r(277),O=r(20),d=r(1),j=r.n(d),v=r(2),g=r(32),w=r(35),_=(r(801),r(763)),E=r(762),R=r(292);function P(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function D(t){for(var e=1;e "+s);if("componentClose"===m.type)throw new Error("Missing opening component token: `"+m.value+"`");if("componentOpen"===m.type){r=t[m.value],i=p;break}f.push(t[m.value])}else f.push(m.value);return r&&(u=function(e,t){var r,n,o=t[e],a=0;for(n=e+1;n0&&Object(l.createElement)("div",{className:"woocommerce-setting__options-group",key:e.key,"aria-labelledby":r+"-label"},e.label&&Object(l.createElement)("span",{className:"woocommerce-setting__options-group-label"},e.label),n.renderCheckboxOptions(e.options))}));case"checkbox":return n.renderCheckboxOptions(i);case"button":return Object(l.createElement)(m.a,{isSecondary:!0,onClick:n.handleInputCallback,disabled:p},a);case"component":var d=u;return Object(l.createElement)(d,o()({value:s,onChange:t},n.props));case"text":default:var b=Object(D.uniqueId)(r);return Object(l.createElement)("input",{id:b,type:"text",name:r,onChange:t,value:s,placeholder:a,disabled:p})}})),s()(w()(n),"handleInputCallback",(function(){var e=n.props,t=e.createNotice,r=e.callback;if("function"==typeof r)return new Promise((function(e,o){n.setState({disabled:!0}),r(e,o,t)})).then((function(){n.setState({disabled:!1})})).catch((function(){n.setState({disabled:!1})}))})),n.state={disabled:!1},n}return y()(r,[{key:"renderCheckboxOptions",value:function(e){var t=this.props,r=t.handleChange,n=t.name,o=t.value,a=this.state.disabled;return e.map((function(e){return Object(l.createElement)(C.a,{key:n+"-"+e.value,label:e.label,name:n,checked:o&&o.includes(e.value),onChange:function(t){return r({target:{checked:t,name:n,type:"checkbox",value:e.value}})},disabled:a})}))}},{key:"render",value:function(){var e=this.props,t=e.helpText,r=e.label,n=e.name;return Object(l.createElement)("div",{className:"woocommerce-setting"},Object(l.createElement)("div",{className:"woocommerce-setting__label",id:n+"-label"},r),Object(l.createElement)("div",{className:"woocommerce-setting__input"},this.renderInput(),t&&Object(l.createElement)("span",{className:"woocommerce-setting__help"},t)))}}]),r}(l.Component);A.propTypes={callback:R.a.func,handleChange:R.a.func.isRequired,helpText:R.a.oneOfType([R.a.string,R.a.array]),inputText:R.a.string,inputType:R.a.oneOf(["button","checkbox","checkboxGroup","text","component"]),label:R.a.string.isRequired,name:R.a.string.isRequired,options:R.a.arrayOf(R.a.shape({value:R.a.string,label:R.a.string,description:R.a.string,key:R.a.string,options:R.a.array})),value:R.a.oneOfType([R.a.string,R.a.array])};var F=Object(p.a)(Object(d.withDispatch)((function(e){return{createNotice:e("core/notices").createNotice}})))(A),M=r(7),V=r(21),z=r(22),L=r(13),Y=r(23),q=r(24),U=r(10),H=r(189),W=r(96);function B(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,n=Object(U.a)(e);if(t){var o=Object(U.a)(this).constructor;r=Reflect.construct(n,arguments,o)}else r=n.apply(this,arguments);return Object(q.a)(this,r)}}var G=Object(W.a)((function(e){return function(t){Object(Y.a)(n,t);var r=B(n);function n(){var e;return Object(V.a)(this,n),(e=r.apply(this,arguments)).debouncedSpeak=Object(D.debounce)(e.speak.bind(Object(L.a)(e)),500),e}return Object(z.a)(n,[{key:"speak",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"polite";Object(H.a)(e,t)}},{key:"componentWillUnmount",value:function(){this.debouncedSpeak.cancel()}},{key:"render",value:function(){return Object(l.createElement)(e,Object(M.a)({},this.props,{speak:this.speak,debouncedSpeak:this.debouncedSpeak}))}}]),n}(l.Component)}),"withSpokenMessages"),$=r(16),Q=r.n($),J=function(e,t,r){var n={};if(r&&(n.skip_existing=!0),"all"!==t.label)if("custom"===t.label){var o=Q()().diff(Q()(t.date,e),"days",!0);n.days=Math.floor(o)}else n.days=parseInt(t.label,10);return n},K=r(37);var X=Object(p.a)([Object(d.withSelect)((function(e){var t=(0,e(f.IMPORT_STORE_NAME).getFormSettings)();return{selectedPeriod:t.period,skipChecked:t.skipPrevious}})),Object(d.withDispatch)((function(e){var t=e(f.IMPORT_STORE_NAME),r=t.updateImportation,n=t.setImportStarted;return{createNotice:e("core/notices").createNotice,setImportStarted:n,updateImportation:r}}))])((function(e){var t,r=e.clearStatusAndTotalsCache,n=e.createNotice,o=e.dateFormat,a=e.importDate,c=e.onImportStarted,i=e.selectedPeriod,s=e.stopImport,p=e.skipChecked,d=e.status,b=e.setImportStarted,f=e.updateImportation,v=function(){var e=Object(K.addQueryArgs)("/wc-analytics/reports/import",J(o,i,p)),t=Object(u.__)("There was a problem rebuilding your report data.",'woocommerce');g(e,t,!0),c()},O=function(){s();var e=Object(u.__)("There was a problem stopping your current import.",'woocommerce');g("/wc-analytics/reports/import/cancel",e)},g=function(e,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];f(e,r).then((function(e){"success"===e.status?n("success",e.message):(n("error",t),b(!1),s())})).catch((function(e){e&&e.message&&(n("error",e.message),b(!1),s())}))},j=function(){var e=Object(u.__)("There was a problem deleting your previous data.",'woocommerce');g("/wc-analytics/reports/import/delete",e),Object(h.recordEvent)("analytics_import_delete_previous"),b(!1)},y=function(){b(!1),r()};return Object(l.createElement)("div",{className:"woocommerce-settings__actions woocommerce-settings-historical-data__actions"},(t="ready"!==d,["initializing","customers","orders","finalizing"].includes(d)?Object(l.createElement)(l.Fragment,null,Object(l.createElement)(m.a,{className:"woocommerce-settings-historical-data__action-button",isPrimary:!0,onClick:O},Object(u.__)("Stop Import",'woocommerce')),Object(l.createElement)("div",{className:"woocommerce-setting__help woocommerce-settings-historical-data__action-help"},Object(u.__)("Imported data will not be lost if the import is stopped.",'woocommerce'),Object(l.createElement)("br",null),Object(u.__)("Navigating away from this page will not affect the import.",'woocommerce'))):["ready","nothing"].includes(d)?a?Object(l.createElement)(l.Fragment,null,Object(l.createElement)(m.a,{isPrimary:!0,onClick:v,disabled:t},Object(u.__)("Start",'woocommerce')),Object(l.createElement)(m.a,{isSecondary:!0,onClick:j},Object(u.__)("Delete Previously Imported Data",'woocommerce'))):Object(l.createElement)(l.Fragment,null,Object(l.createElement)(m.a,{isPrimary:!0,onClick:v,disabled:t},Object(u.__)("Start",'woocommerce'))):("error"===d&&n("error",Object(u.__)("Something went wrong with the importation process.",'woocommerce')),Object(l.createElement)(l.Fragment,null,Object(l.createElement)(m.a,{isSecondary:!0,onClick:y},Object(u.__)("Re-import Data",'woocommerce')),Object(l.createElement)(m.a,{isSecondary:!0,onClick:j},Object(u.__)("Delete Previously Imported Data",'woocommerce'))))))})),Z=r(851),ee=r(40);var te=Object(d.withDispatch)((function(e){return{setImportPeriod:e(f.IMPORT_STORE_NAME).setImportPeriod}}))((function(e){var t,r=e.dateFormat,n=e.disabled,o=e.setImportPeriod,a=e.value,c=function(e){e.date&&e.date.isValid?o(e.date.format(r),!0):o(e.text,!0)},i=function(e){return e.isValid()&&a.date.length===r.length?e.isAfter(new Date,"day")?ee.dateValidationMessages.future:null:ee.dateValidationMessages.invalid};return Object(l.createElement)("div",{className:"woocommerce-settings-historical-data__columns"},Object(l.createElement)("div",{className:"woocommerce-settings-historical-data__column"},Object(l.createElement)(Z.a,{label:Object(u.__)("Import Historical Data",'woocommerce'),value:a.label,disabled:n,onChange:function(e){o(e)},options:[{label:"All",value:"all"},{label:"Last 365 days",value:"365"},{label:"Last 90 days",value:"90"},{label:"Last 30 days",value:"30"},{label:"Last 7 days",value:"7"},{label:"Last 24 hours",value:"1"},{label:"Custom",value:"custom"}]})),"custom"===a.label&&(t=Q()(a.date,r),Object(l.createElement)("div",{className:"woocommerce-settings-historical-data__column"},Object(l.createElement)("div",{className:"woocommerce-settings-historical-data__column-label"},Object(u.__)("Beginning on",'woocommerce')),Object(l.createElement)(b.DatePicker,{date:t.isValid()?t.toDate():null,dateFormat:r,disabled:n,error:i(t),isInvalidDate:function(e){return Q()(e).isAfter(new Date,"day")},onUpdate:c,text:a.date}))))}));var re=function(e){var t=e.label,r=e.progress,n=e.total,o=Object(u.sprintf)(Object(u.__)("Imported %(label)s",'woocommerce'),{label:t}),a=Object(D.isNil)(n)?null:Object(u.sprintf)(Object(u.__)("%(progress)s of %(total)s",'woocommerce'),{progress:r||0,total:n});return Object(l.createElement)("div",{className:"woocommerce-settings-historical-data__progress"},Object(l.createElement)("span",{className:"woocommerce-settings-historical-data__progress-label"},o),a&&Object(l.createElement)("span",{className:"woocommerce-settings-historical-data__progress-label"},a),Object(l.createElement)("progress",{className:"woocommerce-settings-historical-data__progress-bar",max:n,value:r||0}))},ne=r(55),oe=r(738);var ae=function(e){var t=e.importDate,r=e.status,n=Object(ne.applyFilters)("woocommerce_admin_import_status",{nothing:Object(u.__)("Nothing To Import",'woocommerce'),ready:Object(u.__)("Ready To Import",'woocommerce'),initializing:[Object(u.__)("Initializing",'woocommerce'),Object(l.createElement)(oe.a,{key:"spinner"})],customers:[Object(u.__)("Importing Customers",'woocommerce'),Object(l.createElement)(oe.a,{key:"spinner"})],orders:[Object(u.__)("Importing Orders",'woocommerce'),Object(l.createElement)(oe.a,{key:"spinner"})],finalizing:[Object(u.__)("Finalizing",'woocommerce'),Object(l.createElement)(oe.a,{key:"spinner"})],finished:-1===t?Object(u.__)("All historical data imported",'woocommerce'):Object(u.sprintf)(Object(u.__)("Historical data from %s onward imported",'woocommerce'),Q()(t).format("YYYY-MM-DD"))});return Object(l.createElement)("span",{className:"woocommerce-settings-historical-data__status"},Object(u.__)("Status:",'woocommerce')+" ",n[r])};var ce=Object(d.withDispatch)((function(e){return{setSkipPrevious:e(f.IMPORT_STORE_NAME).setSkipPrevious}}))((function(e){var t=e.checked,r=e.disabled,n=e.setSkipPrevious;return Object(l.createElement)(C.a,{className:"woocommerce-settings-historical-data__skip-checkbox",checked:t,disabled:r,label:Object(u.__)("Skip previously imported customers and orders",'woocommerce'),onChange:function(e){n(e)}})}));r(804);function ie(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function se(e){for(var t=1;t0||T>0)&&I===N&&C===T),A={customersTotal:O,isError:R,ordersTotal:g};c&&(A={cacheNeedsClearing:i,customersProgress:I,customersTotal:Object(D.isNil)(N)?O:N,inProgress:l,isError:R,ordersProgress:C,ordersTotal:Object(D.isNil)(T)?g:T});var F=function(e){var t=e.cacheNeedsClearing,r=e.customersProgress,n=e.customersTotal,o=e.isError,a=e.inProgress,c=e.ordersProgress,i=e.ordersTotal;return o?"error":a?Object(D.isNil)(r)||Object(D.isNil)(c)||Object(D.isNil)(n)||Object(D.isNil)(i)||t?"initializing":r0||i>0?r===n&&c===i?"finished":"ready":"nothing"}(A);return"initializing"===F&&d(),x&&m(),se(se({},A),{},{importDate:w,status:F})}))(ue);function pe(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,n=P()(e);if(t){var o=P()(this).constructor;r=Reflect.construct(n,arguments,o)}else r=n.apply(this,arguments);return I()(this,r)}}var de=function(e){E()(r,e);var t=pe(r);function r(){var e;return g()(this,r),(e=t.apply(this,arguments)).dateFormat=Object(u.__)("MM/DD/YYYY",'woocommerce'),e.intervalId=-1,e.lastImportStopTimestamp=0,e.cacheNeedsClearing=!0,e.onImportFinished=e.onImportFinished.bind(w()(e)),e.onImportStarted=e.onImportStarted.bind(w()(e)),e.clearStatusAndTotalsCache=e.clearStatusAndTotalsCache.bind(w()(e)),e.stopImport=e.stopImport.bind(w()(e)),e.startStatusCheckInterval=e.startStatusCheckInterval.bind(w()(e)),e.cancelStatusCheckInterval=e.cancelStatusCheckInterval.bind(w()(e)),e}return y()(r,[{key:"startStatusCheckInterval",value:function(){var e=this;this.intervalId<0&&(this.cacheNeedsClearing=!0,this.intervalId=setInterval((function(){e.clearCache("getImportStatus")}),3*f.SECOND))}},{key:"cancelStatusCheckInterval",value:function(){clearInterval(this.intervalId),this.intervalId=-1}},{key:"clearCache",value:function(e,t){var r=this,n=this.props,o=n.invalidateResolution,a=n.lastImportStartTimestamp;o(e,["getImportStatus"===e?a:t]).then((function(){r.cacheNeedsClearing=!1}))}},{key:"stopImport",value:function(){this.cancelStatusCheckInterval(),this.lastImportStopTimestamp=Date.now()}},{key:"onImportFinished",value:function(){var e=this.props.debouncedSpeak;this.cacheNeedsClearing||(e("Import complete"),this.stopImport())}},{key:"onImportStarted",value:function(){var e=this.props,t=e.notes,r=e.setImportStarted,n=e.updateNote,o=t.find((function(e){return"wc-admin-historical-data"===e.name}));o&&n(o.id,{status:"actioned"}),r(!0)}},{key:"clearStatusAndTotalsCache",value:function(){var e=this.props,t=e.selectedPeriod,r=e.skipChecked,n=J(this.dateFormat,t,r);this.clearCache("getImportTotals",n),this.clearCache("getImportStatus")}},{key:"isImportationInProgress",value:function(){var e=this.props.lastImportStartTimestamp;return void 0!==e&&void 0===this.lastImportStopTimestamp||e>this.lastImportStopTimestamp}},{key:"render",value:function(){var e=this.props,t=e.activeImport,r=e.createNotice,n=e.lastImportStartTimestamp,o=e.selectedPeriod,a=e.skipChecked;return Object(l.createElement)(me,{activeImport:t,cacheNeedsClearing:this.cacheNeedsClearing,createNotice:r,dateFormat:this.dateFormat,inProgress:this.isImportationInProgress(),onImportFinished:this.onImportFinished,onImportStarted:this.onImportStarted,lastImportStartTimestamp:n,clearStatusAndTotalsCache:this.clearStatusAndTotalsCache,period:o,skipChecked:a,startStatusCheckInterval:this.startStatusCheckInterval,stopImport:this.stopImport})}}]),r}(l.Component),be=Object(p.a)([Object(d.withSelect)((function(e){var t=e(f.NOTES_STORE_NAME).getNotes,r=e(f.IMPORT_STORE_NAME),n=r.getImportStarted,o=r.getFormSettings,a=t({page:1,per_page:f.QUERY_DEFAULTS.pageSize,type:"update",status:"unactioned"}),c=n(),i=c.activeImport,s=c.lastImportStartTimestamp,l=o();return{activeImport:i,lastImportStartTimestamp:s,notes:a,selectedPeriod:l.period,skipChecked:l.skipPrevious}})),Object(d.withDispatch)((function(e){var t=e(f.NOTES_STORE_NAME).updateNote,r=e(f.IMPORT_STORE_NAME);return{invalidateResolution:r.invalidateResolution,setImportStarted:r.setImportStarted,updateNote:t}})),G])(de);function fe(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}t.default=Object(p.a)(Object(d.withDispatch)((function(e){return{createNotice:e("core/notices").createNotice}})))((function(e){var t=e.createNotice,r=e.query,n=Object(f.useSettings)("wc_admin",["wcAdminSettings"]),a=n.settingsError,i=n.isRequesting,p=n.isDirty,d=n.persistSettings,O=n.updateAndPersistSettings,g=n.updateSettings,j=n.wcAdminSettings,y=Object(l.useRef)(!1);Object(l.useEffect)((function(){function e(e){if(p)return e.returnValue=Object(u.__)("You have unsaved changes. If you proceed, they will be lost.",'woocommerce'),e.returnValue}return window.addEventListener("beforeunload",e),function(){return window.removeEventListener("beforeunload",e)}}),[p]),Object(l.useEffect)((function(){i?y.current=!0:!i&&y.current&&(a?t("error",Object(u.__)("There was an error saving your settings. Please try again.",'woocommerce')):t("success",Object(u.__)("Your settings have been successfully saved.",'woocommerce')),y.current=!1)}),[i,a,t]);var _=function(e){var t=e.target,r=t.checked,n=t.name,o=t.type,a=t.value,i=function(e){for(var t=1;t0?"down":"up"};Object(E.recordEvent)("dash_section_order_change",o)}else e(t,n+n)};return Object(s.createElement)(ee.a.Provider,{value:Object(ee.b)(Object(k.getQuery)())},(n=Object(w.getDateParamsFromQuery)(S,j),r=n.period,o=n.compare,a=n.before,i=n.after,d=Object(w.getCurrentDates)(S,j),v={period:r,compare:o,before:a,after:i,primaryDate:d.primary,secondaryDate:d.secondary},h=T.filter((function(e){return e.isVisible})).map((function(e){return e.key})),Object(s.createElement)(s.Fragment,null,Object(s.createElement)($.a,{report:"dashboard",query:S,path:D,dateQuery:v,isoDateFormat:w.isoDateFormat,filters:re}),T.map((function(e,t){return e.isVisible?Object(s.createElement)(Y,{component:e.component,hiddenBlocks:e.hiddenBlocks,key:e.key,onChangeHiddenBlocks:(n=e.key,function(e){x(n,{hiddenBlocks:e})}),onTitleUpdate:N(e.key),path:D,query:S,title:e.title,onMove:Object(b.partial)(M,t),onRemove:B(e.key),isFirst:e.key===h[0],isLast:e.key===h[h.length-1],filters:re}):null;var n})),0===(t=T.filter((function(e){return!1===e.isVisible}))).length?null:Object(s.createElement)(p.a,{position:"top center",className:"woocommerce-dashboard-section__add-more",renderToggle:function(e){var t=e.onToggle,n=e.isOpen;return Object(s.createElement)(m.a,{onClick:t,title:Object(u.__)("Add more sections",'woocommerce'),"aria-expanded":n},Object(s.createElement)(O.a,{icon:y}))},renderContent:function(e){var n=e.onToggle;return Object(s.createElement)(s.Fragment,null,Object(s.createElement)(_.H,null,Object(u.__)("Dashboard Sections",'woocommerce')),Object(s.createElement)("div",{className:"woocommerce-dashboard-section__add-more-choices"},t.map((function(e){return Object(s.createElement)(m.a,{key:e.key,onClick:B(e.key,n),className:"woocommerce-dashboard-section__add-more-btn",title:Object(u.sprintf)(Object(u.__)("Add %s section",'woocommerce'),e.title)},Object(s.createElement)(f.a,{icon:e.icon,size:30}),Object(s.createElement)("span",{className:"woocommerce-dashboard-section__add-more-btn-title"},e.title))}))))}}))))}))}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/dashboard-charts.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/dashboard-charts.js new file mode 100644 index 0000000..69b7c65 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/dashboard-charts.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[32],{763:function(e,t,r){"use strict";var o=r(17),c=r.n(o),a=r(15),n=r.n(a),l=r(18),i=r.n(l),m=r(19),s=r.n(m),d=r(9),u=r.n(d),p=r(0),_=r(3),b=r(1),h=r.n(b),y=r(77),w=r(36);function O(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,o=u()(e);if(t){var c=u()(this).constructor;r=Reflect.construct(o,arguments,c)}else r=o.apply(this,arguments);return s()(this,r)}}var f=function(e){i()(r,e);var t=O(r);function r(){return c()(this,r),t.apply(this,arguments)}return n()(r,[{key:"render",value:function(){var e,t,r,o,c=this.props,a=c.className,n=c.isError,l=c.isEmpty;return n?(e=Object(_.__)("There was an error getting your stats. Please try again.",'woocommerce'),t=Object(_.__)("Reload",'woocommerce'),o=function(){window.location.reload()}):l&&(e=Object(_.__)("No results could be found for this date range.",'woocommerce'),t=Object(_.__)("View Orders",'woocommerce'),r=Object(w.f)("edit.php?post_type=shop_order")),Object(p.createElement)(y.EmptyContent,{className:a,title:e,actionLabel:t,actionURL:r,actionCallback:o})}}]),r}(p.Component);f.propTypes={className:h.a.string,isError:h.a.bool,isEmpty:h.a.bool},f.defaultProps={className:""},t.a=f},786:function(e,t,r){"use strict";r.d(t,"b",(function(){return a})),r.d(t,"c",(function(){return n})),r.d(t,"a",(function(){return l}));var o=r(3),c=r(55),a=Object(c.applyFilters)("woocommerce_admin_revenue_report_charts",[{key:"gross_sales",label:Object(o.__)("Gross Sales",'woocommerce'),order:"desc",orderby:"gross_sales",type:"currency"},{key:"refunds",label:Object(o.__)("Returns",'woocommerce'),order:"desc",orderby:"refunds",type:"currency"},{key:"coupons",label:Object(o.__)("Coupons",'woocommerce'),order:"desc",orderby:"coupons",type:"currency"},{key:"net_revenue",label:Object(o.__)("Net Sales",'woocommerce'),orderby:"net_revenue",type:"currency"},{key:"taxes",label:Object(o.__)("Taxes",'woocommerce'),order:"desc",orderby:"taxes",type:"currency"},{key:"shipping",label:Object(o.__)("Shipping",'woocommerce'),orderby:"shipping",type:"currency"},{key:"total_sales",label:Object(o.__)("Total Sales",'woocommerce'),order:"desc",orderby:"total_sales",type:"currency"}]),n=Object(c.applyFilters)("woocommerce_admin_revenue_report_filters",[]),l=Object(c.applyFilters)("woocommerce_admin_revenue_report_advanced_filters",{})},787:function(e,t,r){"use strict";r.d(t,"b",(function(){return n})),r.d(t,"c",(function(){return m})),r.d(t,"a",(function(){return s}));var o=r(3),c=r(55),a=r(764),n=Object(c.applyFilters)("woocommerce_admin_products_report_charts",[{key:"items_sold",label:Object(o.__)("Items Sold",'woocommerce'),order:"desc",orderby:"items_sold",type:"number"},{key:"net_revenue",label:Object(o.__)("Net Sales",'woocommerce'),order:"desc",orderby:"net_revenue",type:"currency"},{key:"orders_count",label:Object(o.__)("Orders",'woocommerce'),order:"desc",orderby:"orders_count",type:"number"}]),l={label:Object(o.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(o.__)("All Products",'woocommerce'),value:"all"},{label:Object(o.__)("Single Product",'woocommerce'),value:"select_product",chartMode:"item-comparison",subFilters:[{component:"Search",value:"single_product",chartMode:"item-comparison",path:["select_product"],settings:{type:"products",param:"products",getLabels:a.d,labels:{placeholder:Object(o.__)("Type to search for a product",'woocommerce'),button:Object(o.__)("Single Product",'woocommerce')}}}]},{label:Object(o.__)("Comparison",'woocommerce'),value:"compare-products",chartMode:"item-comparison",settings:{type:"products",param:"products",getLabels:a.d,labels:{helpText:Object(o.__)("Check at least two products below to compare",'woocommerce'),placeholder:Object(o.__)("Search for products to compare",'woocommerce'),title:Object(o.__)("Compare Products",'woocommerce'),update:Object(o.__)("Compare",'woocommerce')}}}]},i={showFilters:function(e){return"single_product"===e.filter&&!!e.products&&e["is-variable"]},staticParams:["filter","products","chartType","paged","per_page"],param:"filter-variations",filters:[{label:Object(o.__)("All Variations",'woocommerce'),chartMode:"item-comparison",value:"all"},{label:Object(o.__)("Single Variation",'woocommerce'),value:"select_variation",subFilters:[{component:"Search",value:"single_variation",path:["select_variation"],settings:{type:"variations",param:"variations",getLabels:a.g,labels:{placeholder:Object(o.__)("Type to search for a variation",'woocommerce'),button:Object(o.__)("Single Variation",'woocommerce')}}}]},{label:Object(o.__)("Comparison",'woocommerce'),chartMode:"item-comparison",value:"compare-variations",settings:{type:"variations",param:"variations",getLabels:a.g,labels:{helpText:Object(o.__)("Check at least two variations below to compare",'woocommerce'),placeholder:Object(o.__)("Search for variations to compare",'woocommerce'),title:Object(o.__)("Compare Variations",'woocommerce'),update:Object(o.__)("Compare",'woocommerce')}}}]},m=Object(c.applyFilters)("woocommerce_admin_products_report_filters",[l,i]),s=Object(c.applyFilters)("woocommerce_admin_products_report_advanced_filters",{})},789:function(e,t,r){"use strict";r.d(t,"b",(function(){return n})),r.d(t,"c",(function(){return l})),r.d(t,"a",(function(){return i}));var o=r(3),c=r(55),a=r(764),n=Object(c.applyFilters)("woocommerce_admin_coupons_report_charts",[{key:"orders_count",label:Object(o.__)("Discounted Orders",'woocommerce'),order:"desc",orderby:"orders_count",type:"number"},{key:"amount",label:Object(o.__)("Amount",'woocommerce'),order:"desc",orderby:"amount",type:"currency"}]),l=Object(c.applyFilters)("woocommerce_admin_coupons_report_filters",[{label:Object(o.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(o.__)("All Coupons",'woocommerce'),value:"all"},{label:Object(o.__)("Single Coupon",'woocommerce'),value:"select_coupon",chartMode:"item-comparison",subFilters:[{component:"Search",value:"single_coupon",chartMode:"item-comparison",path:["select_coupon"],settings:{type:"coupons",param:"coupons",getLabels:a.b,labels:{placeholder:Object(o.__)("Type to search for a coupon",'woocommerce'),button:Object(o.__)("Single Coupon",'woocommerce')}}}]},{label:Object(o.__)("Comparison",'woocommerce'),value:"compare-coupons",settings:{type:"coupons",param:"coupons",getLabels:a.b,labels:{title:Object(o.__)("Compare Coupon Codes",'woocommerce'),update:Object(o.__)("Compare",'woocommerce'),helpText:Object(o.__)("Check at least two coupon codes below to compare",'woocommerce')}}}]}]),i=Object(c.applyFilters)("woocommerce_admin_coupon_report_advanced_filters",{})},790:function(e,t,r){"use strict";r.d(t,"b",(function(){return i})),r.d(t,"c",(function(){return m})),r.d(t,"a",(function(){return s}));var o=r(3),c=r(55),a=r(35),n=r(764),l=r(765),i=Object(c.applyFilters)("woocommerce_admin_taxes_report_charts",[{key:"total_tax",label:Object(o.__)("Total Tax",'woocommerce'),order:"desc",orderby:"total_tax",type:"currency"},{key:"order_tax",label:Object(o.__)("Order Tax",'woocommerce'),order:"desc",orderby:"order_tax",type:"currency"},{key:"shipping_tax",label:Object(o.__)("Shipping Tax",'woocommerce'),order:"desc",orderby:"shipping_tax",type:"currency"},{key:"orders_count",label:Object(o.__)("Orders",'woocommerce'),order:"desc",orderby:"orders_count",type:"number"}]),m=Object(c.applyFilters)("woocommerce_admin_taxes_report_filters",[{label:Object(o.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(o.__)("All Taxes",'woocommerce'),value:"all"},{label:Object(o.__)("Comparison",'woocommerce'),value:"compare-taxes",chartMode:"item-comparison",settings:{type:"taxes",param:"taxes",getLabels:Object(n.e)(a.NAMESPACE+"/taxes",(function(e){return{id:e.id,key:e.id,label:Object(l.a)(e)}})),labels:{helpText:Object(o.__)("Check at least two tax codes below to compare",'woocommerce'),placeholder:Object(o.__)("Search for tax codes to compare",'woocommerce'),title:Object(o.__)("Compare Tax Codes",'woocommerce'),update:Object(o.__)("Compare",'woocommerce')}}}]}]),s=Object(c.applyFilters)("woocommerce_admin_taxes_report_advanced_filters",{})},791:function(e,t,r){"use strict";r.d(t,"b",(function(){return u})),r.d(t,"c",(function(){return p})),r.d(t,"a",(function(){return _}));var o,c,a=r(14),n=r.n(a),l=r(98),i=r.n(l),m=r(3),s=r(55),d=r(764),u=Object(s.applyFilters)("woocommerce_admin_downloads_report_charts",[{key:"download_count",label:Object(m.__)("Downloads",'woocommerce'),type:"number"}]),p=Object(s.applyFilters)("woocommerce_admin_downloads_report_filters",[{label:Object(m.__)("Show",'woocommerce'),staticParams:["chartType","paged","per_page"],param:"filter",showFilters:function(){return!0},filters:[{label:Object(m.__)("All Downloads",'woocommerce'),value:"all"},{label:Object(m.__)("Advanced Filters",'woocommerce'),value:"advanced"}]}]),_=Object(s.applyFilters)("woocommerce_admin_downloads_report_advanced_filters",{title:Object(m._x)("Downloads Match {{select /}} Filters","A sentence describing filters for Downloads. See screen shot for context: https://cloudup.com/ccxhyH2mEDg",'woocommerce'),filters:{product:{labels:{add:Object(m.__)("Product",'woocommerce'),placeholder:Object(m.__)("Search",'woocommerce'),remove:Object(m.__)("Remove product filter",'woocommerce'),rule:Object(m.__)("Select a product filter match",'woocommerce'),title:Object(m.__)("{{title}}Product{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(m.__)("Select product",'woocommerce')},rules:[{value:"includes",label:Object(m._x)("Includes","products",'woocommerce')},{value:"excludes",label:Object(m._x)("Excludes","products",'woocommerce')}],input:{component:"Search",type:"products",getLabels:d.d}},customer:{labels:{add:Object(m.__)("Username",'woocommerce'),placeholder:Object(m.__)("Search customer username",'woocommerce'),remove:Object(m.__)("Remove customer username filter",'woocommerce'),rule:Object(m.__)("Select a customer username filter match",'woocommerce'),title:Object(m.__)("{{title}}Username{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(m.__)("Select customer username",'woocommerce')},rules:[{value:"includes",label:Object(m._x)("Includes","customer usernames",'woocommerce')},{value:"excludes",label:Object(m._x)("Excludes","customer usernames",'woocommerce')}],input:{component:"Search",type:"usernames",getLabels:d.c}},order:{labels:{add:Object(m.__)("Order #",'woocommerce'),placeholder:Object(m.__)("Search order number",'woocommerce'),remove:Object(m.__)("Remove order number filter",'woocommerce'),rule:Object(m.__)("Select a order number filter match",'woocommerce'),title:Object(m.__)("{{title}}Order #{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(m.__)("Select order number",'woocommerce')},rules:[{value:"includes",label:Object(m._x)("Includes","order numbers",'woocommerce')},{value:"excludes",label:Object(m._x)("Excludes","order numbers",'woocommerce')}],input:{component:"Search",type:"orders",getLabels:(c=i()(n.a.mark((function e(t){var r;return n.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=t.split(","),e.next=3,r.map((function(e){return{id:e,label:"#"+e}}));case 3:return e.abrupt("return",e.sent);case 4:case"end":return e.stop()}}),e)}))),function(e){return c.apply(this,arguments)})}},ip_address:{labels:{add:Object(m.__)("IP Address",'woocommerce'),placeholder:Object(m.__)("Search IP address",'woocommerce'),remove:Object(m.__)("Remove IP address filter",'woocommerce'),rule:Object(m.__)("Select an IP address filter match",'woocommerce'),title:Object(m.__)("{{title}}IP Address{{/title}} {{rule /}} {{filter /}}",'woocommerce'),filter:Object(m.__)("Select IP address",'woocommerce')},rules:[{value:"includes",label:Object(m._x)("Includes","IP addresses",'woocommerce')},{value:"excludes",label:Object(m._x)("Excludes","IP addresses",'woocommerce')}],input:{component:"Search",type:"downloadIps",getLabels:(o=i()(n.a.mark((function e(t){var r;return n.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=t.split(","),e.next=3,r.map((function(e){return{id:e,label:e}}));case 3:return e.abrupt("return",e.sent);case 4:case"end":return e.stop()}}),e)}))),function(e){return o.apply(this,arguments)})}}}})},834:function(e,t,r){},835:function(e,t,r){},854:function(e,t,r){"use strict";r.r(t);var o=r(5),c=r.n(o),a=r(34),n=r.n(a),l=r(62),i=r.n(l),m=r(0),s=r(3),d=r(4),u=r.n(d),p=r(104),_=r.n(p),b=r(1),h=r.n(b),y=r(851),w=r(761),O=r(72),f=r(77),j=r(35),v=r(40),g=r(64),k=r(17),x=r.n(k),S=r(15),C=r.n(S),P=r(11),T=r.n(P),E=r(18),F=r.n(E),R=r(19),I=r.n(R),D=r(9),N=r.n(D),q=r(32),A=r(36),B=r(766);r(834);function L(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,o=N()(e);if(t){var c=N()(this).constructor;r=Reflect.construct(o,arguments,c)}else r=o.apply(this,arguments);return I()(this,r)}}var M=function(e){F()(r,e);var t=L(r);function r(){var e;x()(this,r);for(var o=arguments.length,a=new Array(o),n=0;n0&&Object(p.createElement)("span",{className:"woocommerce-layout__inbox-badge"},r))),Object(p.createElement)("div",{className:"woocommerce-layout__inbox-subtitle"},a&&Object(p.createElement)(O.a,{variant:"body.small"},a)),n&&Object(p.createElement)("div",{className:"woocommerce-layout__activity-panel-header-menu"},n))}}]),n}(p.Component);j.propTypes={className:v.a.string,unreadMessages:v.a.number,title:v.a.string.isRequired,subtitle:v.a.string,menu:v.a.shape({type:v.a.oneOf([_.EllipsisMenu])})},t.a=j},775:function(e,t,n){},777:function(e,t,n){},780:function(e,t,n){},782:function(e,t,n){"use strict";n.d(t,"b",(function(){return b})),n.d(t,"a",(function(){return h}));var a=n(5),c=n.n(a),r=n(16),o=n.n(r),i=n(2),l=n(40),s=n(35),m=n(32),u=n(298),d=n(36);function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function f(e){for(var t=1;tt.bottom&&n.leftt.right;case"left":return n.left+ct.bottom&&n.topt.right;case"bottom":return n.bottom-c>t.bottom&&n.leftt.right&&n.topt.right&&n.leftt.bottom}}},function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return v}));var a=n(1),c=n.n(a),r=n(2),o=n.n(r),i=n(0),l=n.n(i),s=n(3),m=n.n(s);function u(e){return(u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function d(e,t){for(var n=0;n-1?function(){r||(r=setTimeout(o,c||0))}:function(){clearTimeout(r),r=setTimeout(o,a||0)},getLastTimeout:function(){return r}};e.addEventListener(t,i.fn),n.debounceCheck[t]=i})),h(f(n),"startWatching",(function(){n.debounceCheck||n.interval||(n.props.intervalCheck&&(n.interval=setInterval(n.check,n.props.intervalDelay)),n.props.scrollCheck&&n.addEventListener(n.getContainer(),"scroll",n.props.scrollDelay,n.props.scrollThrottle),n.props.resizeCheck&&n.addEventListener(window,"resize",n.props.resizeDelay,n.props.resizeThrottle),!n.props.delayedCall&&n.check())})),h(f(n),"stopWatching",(function(){if(n.debounceCheck)for(var e in n.debounceCheck)if(n.debounceCheck.hasOwnProperty(e)){var t=n.debounceCheck[e];clearTimeout(t.getLastTimeout()),t.target.removeEventListener(e,t.fn),n.debounceCheck[e]=null}n.debounceCheck=null,n.interval&&(n.interval=clearInterval(n.interval))})),h(f(n),"check",(function(){var e,t,a=n.node;if(!a)return n.state;if(e=function(e){return void 0===e.width&&(e.width=e.right-e.left),void 0===e.height&&(e.height=e.bottom-e.top),e}(n.roundRectDown(a.getBoundingClientRect())),n.props.containment){var c=n.props.containment.getBoundingClientRect();t={top:c.top,left:c.left,bottom:c.bottom,right:c.right}}else t={top:0,left:0,bottom:window.innerHeight||document.documentElement.clientHeight,right:window.innerWidth||document.documentElement.clientWidth};var r=n.props.offset||{};"object"===u(r)&&(t.top+=r.top||0,t.left+=r.left||0,t.bottom-=r.bottom||0,t.right-=r.right||0);var o={top:e.top>=t.top,left:e.left>=t.left,bottom:e.bottom<=t.bottom,right:e.right<=t.right},i=e.height>0&&e.width>0,l=i&&o.top&&o.left&&o.bottom&&o.right;if(i&&n.props.partialVisibility){var s=e.top<=t.bottom&&e.bottom>=t.top&&e.left<=t.right&&e.right>=t.left;"string"==typeof n.props.partialVisibility&&(s=o[n.props.partialVisibility]),l=n.props.minTopValue?s&&e.top<=t.bottom-n.props.minTopValue:s}"string"==typeof r.direction&&"number"==typeof r.value&&(console.warn("[notice] offset.direction and offset.value have been deprecated. They still work for now, but will be removed in next major version. Please upgrade to the new syntax: { %s: %d }",r.direction,r.value),l=m()(r,e,t));var d=n.state;return n.state.isVisible!==l&&(d={isVisible:l,visibilityRect:o},n.setState(d),n.props.onChange&&n.props.onChange(l)),d})),n.state={isVisible:null,visibilityRect:{}},n}var n,a,r;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&b(e,t)}(t,e),n=t,(a=[{key:"componentDidMount",value:function(){this.node=o.a.findDOMNode(this),this.props.active&&this.startWatching()}},{key:"componentWillUnmount",value:function(){this.stopWatching()}},{key:"componentDidUpdate",value:function(e){this.node=o.a.findDOMNode(this),this.props.active&&!e.active?(this.setState({isVisible:null,visibilityRect:{}}),this.startWatching()):this.props.active||this.stopWatching()}},{key:"roundRectDown",value:function(e){return{top:Math.floor(e.top),left:Math.floor(e.left),bottom:Math.floor(e.bottom),right:Math.floor(e.right)}}},{key:"render",value:function(){return this.props.children instanceof Function?this.props.children({isVisible:this.state.isVisible,visibilityRect:this.state.visibilityRect}):c.a.Children.only(this.props.children)}}])&&d(n.prototype,a),r&&d(n,r),t}(c.a.Component);h(v,"defaultProps",{active:!0,partialVisibility:!1,minTopValue:0,scrollCheck:!1,scrollDelay:250,scrollThrottle:-1,resizeCheck:!1,resizeDelay:250,resizeThrottle:-1,intervalCheck:!0,intervalDelay:100,delayedCall:!1,offset:{},containment:null,children:c.a.createElement("span",null)}),h(v,"propTypes",{onChange:l.a.func,active:l.a.bool,partialVisibility:l.a.oneOfType([l.a.bool,l.a.oneOf(["top","right","bottom","left"])]),delayedCall:l.a.bool,offset:l.a.oneOfType([l.a.shape({top:l.a.number,left:l.a.number,bottom:l.a.number,right:l.a.number}),l.a.shape({direction:l.a.oneOf(["top","right","bottom","left"]),value:l.a.number})]),scrollCheck:l.a.bool,scrollDelay:l.a.number,scrollThrottle:l.a.number,resizeCheck:l.a.bool,resizeDelay:l.a.number,resizeThrottle:l.a.number,intervalCheck:l.a.bool,intervalDelay:l.a.number,containment:"undefined"!=typeof window?l.a.instanceOf(window.Element):l.a.any,children:l.a.oneOfType([l.a.element,l.a.func]),minTopValue:l.a.number})},function(e,t,n){"use strict";var a=n(6);function c(){}function r(){}r.resetWarningCache=c,e.exports=function(){function e(e,t,n,c,r,o){if(o!==a){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:r,resetWarningCache:c};return n.PropTypes=n,n}},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"}])},e.exports=a(n(6),n(100))},784:function(e,t,n){},793:function(e,t,n){"use strict";n.d(t,"a",(function(){return f})),n.d(t,"b",(function(){return _}));var a=n(0),c=n(3),r=n(55),o=n(42),i=n.n(o),l=n(36),s=n(87),m=n(77),u=n(35),d=n(40),p=function(e){var t=e.value,n=e.onChange,c=Object(u.useSettings)("wc_admin",["wcAdminSettings"]).wcAdminSettings.woocommerce_default_date_range,r=Object(s.parse)(t.replace(/&/g,"&")),o=Object(d.getDateParamsFromQuery)(r,c),i=o.period,l=o.compare,p=o.before,f=o.after,b=Object(d.getCurrentDates)(r,c),h={period:i,compare:l,before:p,after:f,primaryDate:b.primary,secondaryDate:b.secondary};return Object(a.createElement)(m.DateRangeFilterPicker,{query:r,onRangeSelect:function(e){n({target:{name:"woocommerce_default_date_range",value:Object(s.stringify)(e)}})},dateQuery:h,isoDateFormat:d.isoDateFormat})},f=["processing","on-hold"],b=["completed","processing","refunded","cancelled","failed","pending","on-hold"],h=Object.keys(l.d).filter((function(e){return"refunded"!==e})).map((function(e){return{value:e,label:l.d[e],description:Object(c.sprintf)(Object(c.__)("Exclude the %s status from reports",'woocommerce'),l.d[e])}})),v=Object(l.g)("unregisteredOrderStatuses",{}),O=[{key:"defaultStatuses",options:h.filter((function(e){return b.includes(e.value)}))},{key:"customStatuses",label:Object(c.__)("Custom Statuses",'woocommerce'),options:h.filter((function(e){return!b.includes(e.value)}))},{key:"unregisteredStatuses",label:Object(c.__)("Unregistered Statuses",'woocommerce'),options:Object.keys(v).map((function(e){return{value:e,label:e,description:Object(c.sprintf)(Object(c.__)("Exclude the %s status from reports",'woocommerce'),e)}}))}],_=Object(r.applyFilters)("woocommerce_admin_analytics_settings",{woocommerce_excluded_report_order_statuses:{label:Object(c.__)("Excluded Statuses:",'woocommerce'),inputType:"checkboxGroup",options:O,helpText:i()({mixedString:Object(c.__)("Orders with these statuses are excluded from the totals in your reports. The {{strong}}Refunded{{/strong}} status can not be excluded.",'woocommerce'),components:{strong:Object(a.createElement)("strong",null)}}),defaultValue:["pending","cancelled","failed"]},woocommerce_actionable_order_statuses:{label:Object(c.__)("Actionable Statuses:",'woocommerce'),inputType:"checkboxGroup",options:O,helpText:Object(c.__)("Orders with these statuses require action on behalf of the store admin. These orders will show up in the Home Screen - Orders task.",'woocommerce'),defaultValue:f},woocommerce_default_date_range:{name:"woocommerce_default_date_range",label:Object(c.__)("Default Date Range:",'woocommerce'),inputType:"component",component:p,helpText:Object(c.__)("Select a default date range. When no range is selected, reports will be viewed by the default date range.",'woocommerce'),defaultValue:"period=month&compare=previous_year"}})},794:function(e,t,n){},798:function(e,t,n){"use strict";n.r(t);var a=n(62),c=n.n(a),r=n(0),o=n(3),i=n(277),l=n(77),s=n(35),m=n(20),u=n(560),d=n(559),p=n(773),f=n(17),b=n.n(f),h=n(15),v=n.n(h),O=n(18),_=n.n(O),y=n(19),j=n.n(y),g=n(9),w=n.n(g),E=n(1),k=n.n(E);function N(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,a=w()(e);if(t){var c=w()(this).constructor;n=Reflect.construct(a,arguments,c)}else n=a.apply(this,arguments);return j()(this,n)}}var C=function(e){_()(n,e);var t=N(n);function n(){return b()(this,n),t.apply(this,arguments)}return v()(n,[{key:"render",value:function(){var e=this.props.className;return Object(r.createElement)("div",{className:"woocommerce-inbox-message is-placeholder ".concat(e),"aria-hidden":!0},Object(r.createElement)("div",{className:"woocommerce-inbox-message__image"},Object(r.createElement)("div",{className:"banner-block"})),Object(r.createElement)("div",{className:"woocommerce-inbox-message__wrapper"},Object(r.createElement)("div",{className:"woocommerce-inbox-message__content"},Object(r.createElement)("div",{className:"woocommerce-inbox-message__date"},Object(r.createElement)("div",{className:"sixth-line"})),Object(r.createElement)("div",{className:"woocommerce-inbox-message__title"},Object(r.createElement)("div",{className:"line"}),Object(r.createElement)("div",{className:"line"})),Object(r.createElement)("div",{className:"woocommerce-inbox-message__text"},Object(r.createElement)("div",{className:"line"}),Object(r.createElement)("div",{className:"third-line"}))),Object(r.createElement)("div",{className:"woocommerce-inbox-message__actions"},Object(r.createElement)("div",{className:"fifth-line"}),Object(r.createElement)("div",{className:"fifth-line"}))))}}]),n}(r.Component);C.propTypes={className:k.a.string};var z=C,M=n(11),S=n.n(M),R=n(5),T=n.n(R),D=n(535),x=n(72),P=n(736),A=n(783),L=n.n(A),I=n(16),V=n.n(I),q=n(4),B=n.n(q),H=n(64),U=n(36);function F(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,a=w()(e);if(t){var c=w()(this).constructor;n=Reflect.construct(a,arguments,c)}else n=a.apply(this,arguments);return j()(this,n)}}var W=function(e){_()(n,e);var t=F(n);function n(e){var a;return b()(this,n),(a=t.call(this,e)).state={inAction:!1},a.handleActionClick=a.handleActionClick.bind(S()(a)),a}return v()(n,[{key:"handleActionClick",value:function(e){var t=this.props,n=t.action,a=t.actionCallback,c=t.batchUpdateNotes,r=t.createNotice,i=t.noteId,l=t.triggerNoteAction,s=t.removeAllNotes,m=t.removeNote,u=t.onClick,d=t.updateNote,p=e.target.href||"",f=!0;p.length&&!p.startsWith(U.a)&&(e.preventDefault(),f=!1,window.open(p,"_blank")),n?this.setState({inAction:f},(function(){l(i,n.id),u&&u()})):(i?m(i).then((function(){r("success",Object(o.__)("Message dismissed.",'woocommerce'),{actions:[{label:Object(o.__)("Undo",'woocommerce'),onClick:function(){d(i,{is_deleted:0})}}]})})).catch((function(){r("error",Object(o.__)("Message could not be dismissed.",'woocommerce'))})):s().then((function(e){r("success",Object(o.__)("All messages dismissed.",'woocommerce'),{actions:[{label:Object(o.__)("Undo",'woocommerce'),onClick:function(){c(e.map((function(e){return e.id})),{is_deleted:0})}}]})})).catch((function(){r("error",Object(o.__)("Message could not be dismissed.",'woocommerce'))})),a(!0))}},{key:"render",value:function(){var e=this.props,t=e.action,n=e.dismiss,a=e.label;return Object(r.createElement)(x.a,{isSecondary:!0,isBusy:this.state.inAction,disabled:this.state.inAction,href:t&&t.url&&t.url.length?t.url:void 0,onClick:this.handleActionClick},n?a:t.label)}}]),n}(r.Component);W.propTypes={noteId:k.a.number,label:k.a.string,dismiss:k.a.bool,actionCallback:k.a.func,action:k.a.shape({id:k.a.number.isRequired,url:k.a.string,label:k.a.string.isRequired,primary:k.a.bool.isRequired}),onClick:k.a.func};var G=Object(i.a)(Object(m.withDispatch)((function(e){var t=e("core/notices").createNotice,n=e(s.NOTES_STORE_NAME),a=n.batchUpdateNotes,c=n.removeAllNotes,r=n.removeNote,o=n.updateNote;return{batchUpdateNotes:a,createNotice:t,removeAllNotes:c,removeNote:r,triggerNoteAction:n.triggerNoteAction,updateNote:o}})))(W),K=n(772);n(784);function J(){var e,t="",n=(e=window.location.search)?e.substr(1).split("&").reduce((function(e,t){var n=t.split("="),a=n[0],c=decodeURIComponent(n[1]);return c=isNaN(Number(c))?c:Number(c),e[a]=c,e}),{}):{},a=n.page,c=n.path,r=n.post_type;if(a){var o="wc-admin"===a?"home_screen":a;t=c?c.replace(/\//g,"_").substring(1):o}else r&&(t=r);return t}function Q(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,a=w()(e);if(t){var c=w()(this).constructor;n=Reflect.construct(a,arguments,c)}else n=a.apply(this,arguments);return j()(this,n)}}var Y=function(e){_()(n,e);var t=Q(n);function n(e){var a;return b()(this,n),a=t.call(this,e),T()(S()(a),"onActionClicked",(function(e){e.actioned_text&&a.setState({clickedActionText:e.actioned_text})})),a.onVisible=a.onVisible.bind(S()(a)),a.hasBeenSeen=!1,a.state={isDismissModalOpen:!1,dismissType:null,clickedActionText:null},a.openDismissModal=a.openDismissModal.bind(S()(a)),a.closeDismissModal=a.closeDismissModal.bind(S()(a)),a.bodyNotificationRef=Object(r.createRef)(),a.screen=J(),a}return v()(n,[{key:"componentDidMount",value:function(){var e=this;this.bodyNotificationRef.current&&this.bodyNotificationRef.current.addEventListener("click",(function(t){return e.handleBodyClick(t,e.props)}))}},{key:"componentWillUnmount",value:function(){var e=this;this.bodyNotificationRef.current&&this.bodyNotificationRef.current.removeEventListener("click",(function(t){return e.handleBodyClick(t,e.props)}))}},{key:"handleBodyClick",value:function(e,t){var n=e.target.href;if(n){var a=t.note;Object(H.recordEvent)("wcadmin_inbox_action_click",{note_name:a.name,note_title:a.title,note_content_inner_link:n})}}},{key:"onVisible",value:function(e){if(e&&!this.hasBeenSeen){var t=this.props.note;Object(H.recordEvent)("inbox_note_view",{note_content:t.content,note_name:t.name,note_title:t.title,note_type:t.type,screen:this.screen}),this.hasBeenSeen=!0}}},{key:"openDismissModal",value:function(e,t){this.setState({isDismissModalOpen:!0,dismissType:e}),t()}},{key:"closeDismissModal",value:function(e){var t=this.state.dismissType,n=this.props.note,a="all"===t;Object(H.recordEvent)("inbox_action_dismiss",{note_name:n.name,note_title:n.title,note_name_dismiss_all:a,note_name_dismiss_confirmation:e||!1,screen:this.screen}),this.setState({isDismissModalOpen:!1})}},{key:"handleBlur",value:function(e,t){var n=e.relatedTarget?e.relatedTarget:document.activeElement;!!n&&["woocommerce-admin-dismiss-notification","components-popover__content"].some((function(e){return n.className.includes(e)}))?e.preventDefault():t()}},{key:"renderDismissButton",value:function(){var e=this;return this.state.clickedActionText?null:Object(r.createElement)(D.a,{contentClassName:"woocommerce-admin-dismiss-dropdown",position:"bottom right",renderToggle:function(t){var n=t.onClose,a=t.onToggle;return Object(r.createElement)(x.a,{isTertiary:!0,onClick:a,onBlur:function(t){return e.handleBlur(t,n)}},Object(o.__)("Dismiss",'woocommerce'))},focusOnMount:!1,popoverProps:{noArrow:!0},renderContent:function(t){var n=t.onToggle;return Object(r.createElement)("ul",null,Object(r.createElement)("li",null,Object(r.createElement)(x.a,{className:"woocommerce-admin-dismiss-notification",onClick:function(){return e.openDismissModal("this",n)}},Object(o.__)("Dismiss this message",'woocommerce'))),Object(r.createElement)("li",null,Object(r.createElement)(x.a,{className:"woocommerce-admin-dismiss-notification",onClick:function(){return e.openDismissModal("all",n)}},Object(o.__)("Dismiss all messages",'woocommerce'))))}})}},{key:"getDismissConfirmationButton",value:function(){var e=this.props.note,t=this.state.dismissType;return Object(r.createElement)(G,{key:e.id,noteId:"all"===t?null:e.id,label:Object(o.__)("Yes, I'm sure",'woocommerce'),actionCallback:this.closeDismissModal,dismiss:!0,screen:this.screen})}},{key:"renderDismissConfirmationModal",value:function(){var e=this;return Object(r.createElement)(P.a,{title:Object(r.createElement)(r.Fragment,null,Object(o.__)("Are you sure?",'woocommerce')),onRequestClose:function(){return e.closeDismissModal()},className:"woocommerce-inbox-dismiss-confirmation_modal"},Object(r.createElement)("div",{className:"woocommerce-inbox-dismiss-confirmation_wrapper"},Object(r.createElement)("p",null,Object(o.__)("Dismissed messages cannot be viewed again",'woocommerce')),Object(r.createElement)("div",{className:"woocommerce-inbox-dismiss-confirmation_buttons"},Object(r.createElement)(x.a,{isSecondary:!0,onClick:function(){return e.closeDismissModal()}},Object(o.__)("Cancel",'woocommerce')),this.getDismissConfirmationButton())))}},{key:"renderActions",value:function(e){var t=this,n=e.actions,a=e.id,c=this.state.clickedActionText;return c||(n?Object(r.createElement)(r.Fragment,null,n.map((function(e,n){return Object(r.createElement)(G,{key:n,noteId:a,action:e,onClick:function(){return t.onActionClicked(e)}})}))):void 0)}},{key:"render",value:function(){var e=this.props,t=e.lastRead,n=e.note,a=this.state.isDismissModalOpen,c=n.content,o=n.date_created,i=n.date_created_gmt,s=n.image,m=n.is_deleted,u=n.layout,d=n.status,p=n.title;if(m)return null;var f=!t||!i||new Date(i+"Z").getTime()>t,b=o,h="plain"!==u&&""!==u,v=B()("woocommerce-inbox-message",u,{"message-is-unread":f&&"unactioned"===d});return Object(r.createElement)(L.a,{onChange:this.onVisible},Object(r.createElement)("section",{className:v},h&&Object(r.createElement)("div",{className:"woocommerce-inbox-message__image"},Object(r.createElement)("img",{src:s,alt:""})),Object(r.createElement)("div",{className:"woocommerce-inbox-message__wrapper"},Object(r.createElement)("div",{className:"woocommerce-inbox-message__content"},b&&Object(r.createElement)("span",{className:"woocommerce-inbox-message__date"},V.a.utc(b).fromNow()),Object(r.createElement)(l.H,{className:"woocommerce-inbox-message__title"},p),Object(r.createElement)(l.Section,{className:"woocommerce-inbox-message__text"},Object(r.createElement)("span",{dangerouslySetInnerHTML:Object(K.a)(c),ref:this.bodyNotificationRef}))),Object(r.createElement)("div",{className:"woocommerce-inbox-message__actions"},this.renderActions(n),this.renderDismissButton())),a&&this.renderDismissConfirmationModal()))}}]),n}(r.Component);Y.propTypes={note:k.a.shape({id:k.a.number,status:k.a.string,title:k.a.string,content:k.a.string,date_created:k.a.string,date_created_gmt:k.a.string,actions:k.a.arrayOf(k.a.shape({id:k.a.number.isRequired,url:k.a.string,label:k.a.string.isRequired,primary:k.a.bool.isRequired})),layout:k.a.string,image:k.a.string,is_deleted:k.a.bool}),lastRead:k.a.number};var $=Y,X=n(446),Z=function(e){var t=e.hasNotes,n=e.isBatchUpdating,a=e.lastRead,c=e.notes;if(!n){if(!t)return Object(r.createElement)(p.a,{className:"woocommerce-empty-activity-card",title:Object(o.__)("Your inbox is empty",'woocommerce'),icon:!1},Object(o.__)("As things begin to happen in your store your inbox will start to fill up. You'll see things like achievements, new feature announcements, extension recommendations and more!",'woocommerce'));var i=Object.keys(c).map((function(e){return c[e]}));return Object(r.createElement)(u.a,{role:"menu"},i.map((function(e){var t=e.id;return e.is_deleted?null:Object(r.createElement)(d.a,{key:t,timeout:500,classNames:"woocommerce-inbox-message"},Object(r.createElement)($,{key:t,note:e,lastRead:a}))})))}};t.default=Object(i.a)(Object(m.withSelect)((function(e){var t=e(s.NOTES_STORE_NAME),n=t.getNotes,a=t.getNotesError,c=t.isResolving,r=t.isNotesRequesting,o={page:1,per_page:s.QUERY_DEFAULTS.pageSize,status:"unactioned",type:s.QUERY_DEFAULTS.noteTypes,orderby:"date",order:"desc",_fields:["id","name","title","content","type","status","actions","date_created","date_created_gmt","layout","image","is_deleted"]};return{notes:n(o),isError:Boolean(a("getNotes",[o])),isResolving:c("getNotes",[o]),isBatchUpdating:r("batchUpdateNotes")}})))((function(e){var t=e.isError,n=e.isResolving,a=e.isBatchUpdating,i=e.notes,m=Object(s.useUserPreferences)(),u=m.updateUserPreferences,d=c()(m,["updateUserPreferences"]).activity_panel_inbox_last_read;if(Object(r.useEffect)((function(){var e=Date.now();return function(){u({activity_panel_inbox_last_read:e})}}),[]),t){var p=Object(o.__)("There was an error getting your inbox. Please try again.",'woocommerce'),f=Object(o.__)("Reload",'woocommerce');return Object(r.createElement)(l.EmptyContent,{title:p,actionLabel:f,actionURL:null,actionCallback:function(){window.location.reload()}})}var b=Object(X.b)(i);return Object(r.createElement)(r.Fragment,null,Object(r.createElement)("div",{className:"woocommerce-homepage-notes-wrapper"},(n||a)&&Object(r.createElement)(l.Section,null,Object(r.createElement)(z,{className:"banner message-is-unread"})),Object(r.createElement)(l.Section,null,!n&&!a&&Z({hasNotes:b,isBatchUpdating:a,lastRead:d,notes:i}))))}))},805:function(e,t,n){},806:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var a=n(8),c=n(26),r=n(7),o=n(12),i=n(0),l=n(4),s=n.n(l),m=n(2),u=n(300),d=n(761),p=n(72),f=function(e){var t=e.tabId,n=e.onClick,a=e.children,c=e.selected,l=Object(o.a)(e,["tabId","onClick","children","selected"]);return Object(i.createElement)(p.a,Object(r.a)({role:"tab",tabIndex:c?null:-1,"aria-selected":c,id:t,onClick:n},l),a)};function b(e){var t,n=e.className,r=e.children,o=e.tabs,l=e.initialTabName,p=e.orientation,h=void 0===p?"horizontal":p,v=e.activeClass,O=void 0===v?"is-active":v,_=e.onSelect,y=void 0===_?m.noop:_,j=Object(u.a)(b,"tab-panel"),g=Object(i.useState)(null),w=Object(c.a)(g,2),E=w[0],k=w[1],N=function(e){k(e),y(e)},C=Object(m.find)(o,{name:E}),z="".concat(j,"-").concat(null!==(t=null==C?void 0:C.name)&&void 0!==t?t:"none");return Object(i.useEffect)((function(){Object(m.find)(o,{name:E})||k(l||(o.length>0?o[0].name:null))}),[o]),Object(i.createElement)("div",{className:n},Object(i.createElement)(d.a,{role:"tablist",orientation:h,onNavigate:function(e,t){t.click()},className:"components-tab-panel__tabs"},o.map((function(e){return Object(i.createElement)(f,{className:s()("components-tab-panel__tabs-item",e.className,Object(a.a)({},O,e.name===E)),tabId:"".concat(j,"-").concat(e.name),"aria-controls":"".concat(j,"-").concat(e.name,"-view"),selected:e.name===E,key:e.name,onClick:Object(m.partial)(N,e.name)},e.title)}))),C&&Object(i.createElement)("div",{"aria-labelledby":z,role:"tabpanel",id:"".concat(z,"-view"),className:"components-tab-panel__tab-content"},r(C)))}},807:function(e,t,n){"use strict";var a=n(7),c=n(8),r=n(12),o=n(0),i=n(4),l=n.n(i),s=n(193),m=n(192);function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function d(e){for(var t=1;t":".","?":"/","|":"\\"},l={option:"alt",command:"meta",return:"enter",escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},s=1;s<20;++s)r[111+s]="f"+s;for(s=0;s<=9;++s)r[s+96]=s.toString();b.prototype.bind=function(e,t,n){return e=e instanceof Array?e:[e],this._bindMultiple.call(this,e,t,n),this},b.prototype.unbind=function(e,t){return this.bind.call(this,e,(function(){}),t)},b.prototype.trigger=function(e,t){return this._directMap[e+":"+t]&&this._directMap[e+":"+t]({},e),this},b.prototype.reset=function(){return this._callbacks={},this._directMap={},this},b.prototype.stopCallback=function(e,t){if((" "+t.className+" ").indexOf(" mousetrap ")>-1)return!1;if(function e(t,a){return null!==t&&t!==n&&(t===a||e(t.parentNode,a))}(t,this.target))return!1;if("composedPath"in e&&"function"==typeof e.composedPath){var a=e.composedPath()[0];a!==e.target&&(t=a)}return"INPUT"==t.tagName||"SELECT"==t.tagName||"TEXTAREA"==t.tagName||t.isContentEditable},b.prototype.handleKey=function(){var e=this;return e._handleKey.apply(e,arguments)},b.addKeycodes=function(e){for(var t in e)e.hasOwnProperty(t)&&(r[t]=e[t]);c=null},b.init=function(){var e=b(n);for(var t in e)"_"!==t.charAt(0)&&(b[t]=function(t){return function(){return e[t].apply(e,arguments)}}(t))},b.init(),t.Mousetrap=b,e.exports&&(e.exports=b),"function"==typeof define&&define.amd&&define((function(){return b}))}function m(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent("on"+t,n)}function u(e){if("keypress"==e.type){var t=String.fromCharCode(e.which);return e.shiftKey||(t=t.toLowerCase()),t}return r[e.which]?r[e.which]:o[e.which]?o[e.which]:String.fromCharCode(e.which).toLowerCase()}function d(e){return"shift"==e||"ctrl"==e||"alt"==e||"meta"==e}function p(e,t,n){return n||(n=function(){if(!c)for(var e in c={},r)e>95&&e<112||r.hasOwnProperty(e)&&(c[r[e]]=e);return c}()[e]?"keydown":"keypress"),"keypress"==n&&t.length&&(n="keydown"),n}function f(e,t){var n,a,c,r=[];for(n=function(e){return"+"===e?["+"]:(e=e.replace(/\+{2}/g,"+plus")).split("+")}(e),c=0;c1?v(e,i,n,a):(o=f(e,a),t._callbacks[o.key]=t._callbacks[o.key]||[],s(o.key,o.modifiers,{type:o.action},c,e,r),t._callbacks[o.key][c?"unshift":"push"]({callback:n,modifiers:o.modifiers,action:o.action,seq:c,level:r,combo:e}))}t._handleKey=function(e,t,n){var a,c=s(e,t,n),r={},m=0,u=!1;for(a=0;a0&&void 0!==arguments[0]?arguments[0]:window,t=e.navigator.platform;return-1!==t.indexOf("Mac")||Object(o.includes)(["iPad","iPhone"],t)}var J=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},c=n.bindGlobal,r=void 0!==c&&c,i=n.eventName,l=void 0===i?"keydown":i,s=n.isDisabled,m=void 0!==s&&s,u=n.target,d=Object(a.useRef)(t);Object(a.useEffect)((function(){d.current=t}),[t]),Object(a.useEffect)((function(){if(!m){var t=new G.a(u?u.current:document);return Object(o.castArray)(e).forEach((function(e){var n=e.split("+"),a=new Set(n.filter((function(e){return e.length>1}))),c=a.has("alt"),o=a.has("shift");if(K()&&(1===a.size&&c||2===a.size&&c&&o))throw new Error("Cannot bind ".concat(e,". Alt and Shift+Alt modifiers are reserved for character input."));t[r?"bindGlobal":"bind"](e,(function(){return d.current.apply(d,arguments)}),l)})),function(){t.reset()}}}),[e,r,l,u,m])};function Q(e){var t=e.target,n=e.callback,a=e.shortcut,c=e.bindGlobal,r=e.eventName;return J(a,n,{bindGlobal:c,target:t,eventName:r}),null}var Y=function(e){var t=e.children,n=e.shortcuts,c=e.bindGlobal,r=e.eventName,i=Object(a.useRef)(),l=Object(o.map)(n,(function(e,t){return Object(a.createElement)(Q,{key:t,shortcut:t,callback:e,bindGlobal:c,eventName:r,target:i})}));return a.Children.count(t)?Object(a.createElement)("div",{ref:i},l,t):l},$=n(88),X=function(e){var t=e.isSelected;return Object(a.createElement)($.c,{width:"8",height:"8",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(a.createElement)($.a,{cx:"4",cy:"4",r:"4",fill:t?"#419ECD":"#E1E3E6"}))};function Z(e){var t=e.currentPage,n=e.numberOfPages,c=e.setCurrentPage;return Object(a.createElement)("ul",{className:"components-guide__page-control","aria-label":Object(h.__)("Guide controls")},Object(o.times)(n,(function(e){return Object(a.createElement)("li",{key:e,"aria-current":e===t?"step":void 0},Object(a.createElement)(D.a,{key:e,icon:Object(a.createElement)(X,{isSelected:e===t}),"aria-label":Object(h.sprintf)(Object(h.__)("Page %1$d of %2$d"),e+1,n),onClick:function(){return c(e)}}))})))}function ee(e){var t=e.className,n=e.onClick,c=e.children,r=Object(a.useRef)(null);return Object(a.useLayoutEffect)((function(){document.activeElement&&document.activeElement!==document.body||r.current.focus()}),[r]),Object(a.createElement)(D.a,{ref:r,className:t,isPrimary:!0,onClick:n},c)}function te(e){var t=e.children,n=e.className,c=e.contentLabel,r=e.finishButtonText,o=e.onFinish,i=e.pages,l=void 0===i?[]:i,s=Object(a.useState)(0),m=Object(H.a)(s,2),u=m[0],d=m[1];Object(a.useEffect)((function(){a.Children.count(t)&&Object(U.a)("Passing children to ",{alternative:"the `pages` prop"})}),[t]),a.Children.count(t)&&(l=a.Children.map(t,(function(e){return{content:e}})));var f=u>0,b=u0&&{className:"woocommerce-homescreen-card",count:t,id:"orders-panel",initialOpen:!0,panel:Object(a.createElement)(ge,{countUnreadOrders:t,orderStatuses:n}),title:Object(h.__)("Orders",'woocommerce')}].filter(Boolean)}({countUnreadOrders:function(e,t){var n=e(l.ITEMS_STORE_NAME),a=n.getItemsTotalCount,c=n.getItemsError,r=n.isResolving;if(!t.length)return 0;var o={page:1,per_page:1,status:t,_fields:["id"]},i=a("orders",o,null),s=Boolean(c("orders",o)),m=r("getItemsTotalCount",["orders",o,null]);return s||m?null:i}(e,n),orderStatuses:n,totalOrderCount:t})}));return Object(a.createElement)(k.Accordion,null,Object(a.createElement)(a.Fragment,null,e.map((function(e){var t=e.className,n=e.count,c=e.id,r=e.initialOpen,o=e.panel,i=e.title;return Object(a.createElement)(k.AccordionPanel,{key:c,className:t,count:n,initialOpen:r,title:i},o)}))))},Ee=(n(813),n(780),n(30)),ke=n.n(Ee),Ne=Object(a.createElement)($.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(a.createElement)($.b,{fillRule:"evenodd",d:"M6.863 13.644L5 13.25h-.5a.5.5 0 01-.5-.5v-3a.5.5 0 01.5-.5H5L18 6.5h2V16h-2l-3.854-.815.026.008a3.75 3.75 0 01-7.31-1.549zm1.477.313a2.251 2.251 0 004.356.921l-4.356-.921zm-2.84-3.28L18.157 8h.343v6.5h-.343L5.5 11.823v-1.146z",clipRule:"evenodd"})),Ce=Object(a.createElement)($.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(a.createElement)($.b,{fillRule:"evenodd",d:"M5 5.5h14a.5.5 0 01.5.5v1.5a.5.5 0 01-.5.5H5a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM4 9.232A2 2 0 013 7.5V6a2 2 0 012-2h14a2 2 0 012 2v1.5a2 2 0 01-1 1.732V18a2 2 0 01-2 2H6a2 2 0 01-2-2V9.232zm1.5.268V18a.5.5 0 00.5.5h12a.5.5 0 00.5-.5V9.5h-13z",clipRule:"evenodd"})),ze=Object(a.createElement)($.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},Object(a.createElement)($.b,{d:"M18.33 3.57s.27-.8-.31-1.36c-.53-.52-1.22-.24-1.22-.24-.61.3-5.76 3.47-7.67 5.57-.86.96-2.06 3.79-1.09 4.82.92.98 3.96-.17 4.79-1 2.06-2.06 5.21-7.17 5.5-7.79zM1.4 17.65c2.37-1.56 1.46-3.41 3.23-4.64.93-.65 2.22-.62 3.08.29.63.67.8 2.57-.16 3.46-1.57 1.45-4 1.55-6.15.89z"})),Me=Object(a.createElement)($.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(a.createElement)($.b,{d:"M12 4L4 7.9V20h16V7.9L12 4zm6.5 14.5H14V13h-4v5.5H5.5V8.8L12 5.7l6.5 3.1v9.7z"})),Se=Object(a.createElement)($.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"-2 -2 24 24"},Object(a.createElement)($.b,{d:"M13.89 3.39l2.71 2.72c.46.46.42 1.24.03 1.64l-8.01 8.02-5.56 1.16 1.16-5.58s7.6-7.63 7.99-8.03c.39-.39 1.22-.39 1.68.07zm-2.73 2.79l-5.59 5.61 1.11 1.11 5.54-5.65zm-2.97 8.23l5.58-5.6-1.07-1.08-5.59 5.6zM13.89 3.39l2.71 2.72c.46.46.42 1.24.03 1.64l-8.01 8.02-5.56 1.16 1.16-5.58s7.6-7.63 7.99-8.03c.39-.39 1.22-.39 1.68.07zm-2.73 2.79l-5.59 5.61 1.11 1.11 5.54-5.65zm-2.97 8.23l5.58-5.6-1.07-1.08-5.59 5.6z"})),Re=Object(a.createElement)($.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(a.createElement)($.b,{fillRule:"evenodd",d:"M5.5 9.5v-2h13v2h-13zm0 3v4h13v-4h-13zM4 7a1 1 0 011-1h14a1 1 0 011 1v10a1 1 0 01-1 1H5a1 1 0 01-1-1V7z",clipRule:"evenodd"})),Te=Object(a.createElement)($.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(a.createElement)($.b,{fillRule:"evenodd",d:"M6.5 8a1.5 1.5 0 103 0 1.5 1.5 0 00-3 0zM8 5a3 3 0 100 6 3 3 0 000-6zm6.5 11a1.5 1.5 0 103 0 1.5 1.5 0 00-3 0zm1.5-3a3 3 0 100 6 3 3 0 000-6zM5.47 17.41a.75.75 0 001.06 1.06L18.47 6.53a.75.75 0 10-1.06-1.06L5.47 17.41z",clipRule:"evenodd"})),De=Object(a.createElement)($.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(a.createElement)($.b,{d:"M3 6.75C3 5.784 3.784 5 4.75 5H15V7.313l.05.027 5.056 2.73.394.212v3.468a1.75 1.75 0 01-1.75 1.75h-.012a2.5 2.5 0 11-4.975 0H9.737a2.5 2.5 0 11-4.975 0H3V6.75zM13.5 14V6.5H4.75a.25.25 0 00-.25.25V14h.965a2.493 2.493 0 011.785-.75c.7 0 1.332.287 1.785.75H13.5zm4.535 0h.715a.25.25 0 00.25-.25v-2.573l-4-2.16v4.568a2.487 2.487 0 011.25-.335c.7 0 1.332.287 1.785.75zM6.282 15.5a1.002 1.002 0 00.968 1.25 1 1 0 10-.968-1.25zm9 0a1 1 0 101.937.498 1 1 0 00-1.938-.498z"})),xe=(n(814),n(815),function(e){var t=e.title,n=e.children;return Object(a.createElement)("div",{className:"woocommerce-quick-links__category"},Object(a.createElement)("h3",{className:"woocommerce-quick-links__category-header"},t),n)}),Pe=n(570),Ae=Object(a.createElement)($.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(a.createElement)($.b,{d:"M18.2 17c0 .7-.6 1.2-1.2 1.2H7c-.7 0-1.2-.6-1.2-1.2V7c0-.7.6-1.2 1.2-1.2h3.2V4.2H7C5.5 4.2 4.2 5.5 4.2 7v10c0 1.5 1.2 2.8 2.8 2.8h10c1.5 0 2.8-1.2 2.8-2.8v-3.6h-1.5V17zM14.9 3v1.5h3.7l-6.4 6.4 1.1 1.1 6.4-6.4v3.7h1.5V3h-6.3z"})),Le=(n(816),function(e){var t=e.icon,n=e.title,c=e.href,r=e.linkType,o=e.onClick,i="external"===r;return Object(a.createElement)("div",{className:"woocommerce-quick-links__item"},Object(a.createElement)(k.Link,{onClick:o,href:c,type:r,className:"woocommerce-quick-links__item-link"},Object(a.createElement)(Pe.a,{className:"woocommerce-quick-links__item-link__icon",icon:t}),Object(a.createElement)(j.a,{className:"woocommerce-quick-links__item-link__text",as:"div",variant:"button"},n),i&&Object(a.createElement)(Pe.a,{icon:Ae})))});function Ie(e){var t=e.path,n=e.tab,a=void 0===n?null:n,c=e.type,r=e.href,o=void 0===r?null:r;return{"wc-admin":{href:"admin.php?page=wc-admin&path=%2F".concat(t),linkType:"wc-admin"},"wp-admin":{href:t,linkType:"wp-admin"},"wc-settings":{href:"admin.php?page=wc-settings&tab=".concat(a),linkType:"wp-admin"}}[c]||{href:o,linkType:"external"}}var Ve=function(){var e=Object(i.g)("siteUrl"),t=Object(C.applyFilters)("woocommerce_admin_homescreen_quicklinks",[]).reduce((function(e,t){var n=t.icon,a=t.href,c=t.title;return new URL(a,window.location.href).origin===window.location.origin&&e.push({icon:n,link:{href:a,linkType:"wp-admin"},title:c,listItemTag:"quick-links-extension-link"}),e}),[]),n=function(e){return[{title:Object(h.__)("Marketing & Merchandising",'woocommerce'),items:[{title:Object(h.__)("Marketing",'woocommerce'),link:Ie({type:"wc-admin",path:"marketing"}),icon:Ne,listItemTag:"marketing"},{title:Object(h.__)("Add products",'woocommerce'),link:Ie({type:"wp-admin",path:"post-new.php?post_type=product"}),icon:Ce,listItemTag:"add-products"},{title:Object(h.__)("Personalize my store",'woocommerce'),link:Ie({type:"wp-admin",path:"customize.php"}),icon:ze,listItemTag:"personalize-store"},{title:Object(h.__)("View my store",'woocommerce'),link:Ie({type:"external",href:e}),icon:Me,listItemTag:"view-store"}]},{title:Object(h.__)("Settings",'woocommerce'),items:[{title:Object(h.__)("Store details",'woocommerce'),link:Ie({type:"wc-settings",tab:"general"}),icon:Se,listItemTag:"edit-store-details"},{title:Object(h.__)("Payments",'woocommerce'),link:Ie({type:"wc-settings",tab:"checkout"}),icon:Re,listItemTag:"payment-settings"},{title:Object(h.__)("Tax",'woocommerce'),link:Ie({type:"wc-settings",tab:"tax"}),icon:Te,listItemTag:"tax-settings"},{title:Object(h.__)("Shipping",'woocommerce'),link:Ie({type:"wc-settings",tab:"shipping"}),icon:De,listItemTag:"shipping-settings"}]}]}(e),c={title:Object(h.__)("Extensions",'woocommerce'),items:t},r=t.length?[].concat(ke()(n),[c]):n;return Object(a.createElement)(_.a,{size:"medium"},Object(a.createElement)(y.a,{size:"medium"},Object(a.createElement)(j.a,{variant:"title.small"},Object(h.__)("Store management",'woocommerce'))),Object(a.createElement)(g.a,{size:"custom",className:"woocommerce-store-management-links__card-body"},r.map((function(e){return Object(a.createElement)(xe,{key:e.title,title:e.title},e.items.map((function(e){var t=e.icon,n=e.listItemTag,c=e.title,r=e.link,o=r.href,i=r.linkType;return Object(a.createElement)(Le,{icon:t,key:"".concat(c,"_").concat(n,"_").concat(o),title:c,linkType:i,href:o,onClick:function(){Object(N.recordEvent)("home_quick_links_click",{task_name:n})}})})))}))))},qe=function(e){var t=e.children,n=e.shouldStick,c=void 0!==n&&n,r=Object(a.useState)(!1),o=u()(r,2),i=o[0],l=o[1],s=Object(a.useRef)(null),m=Object(a.useRef)(null),d=Object(a.useCallback)((function(){if(s.current){var e=s.current.getBoundingClientRect(),t=e.bottom,n=e.top;null===m.current&&(m.current=n);var a=t=782}),[]);Object(a.useLayoutEffect)((function(){return g(),window.addEventListener("resize",g),function(){window.removeEventListener("resize",g)}}),[g]);var w=j.current&&d,E=function(){return r?Object(a.createElement)(q,null):Object(a.createElement)(a.Suspense,{fallback:Object(a.createElement)(q,null)},Object(a.createElement)(Be,{query:c}))};return Object(a.createElement)("div",{className:p()("woocommerce-homescreen",{"two-columns":d})},y?Object(a.createElement)(a.Fragment,null,Object(a.createElement)(qe,{shouldStick:w},Object(a.createElement)(re.a,{className:"your-store-today",title:Object(h.__)("Your store today",'woocommerce'),subtitle:Object(h.__)("To do's, tips, and insights for your business",'woocommerce')}),Object(a.createElement)(we,null),_&&E(),!_&&w&&Object(a.createElement)(Ve,null)),Object(a.createElement)(qe,{shouldStick:w},Object(a.createElement)(V,null),Object(a.createElement)(B.default,null),!_&&!w&&Object(a.createElement)(Ve,null))):_&&E(),s&&Object(a.createElement)(ce,{onClose:function(){m({woocommerce_task_list_welcome_modal_dismissed:"yes"})}}))};He.propTypes={requestingTaskList:b.a.bool.isRequired,taskListComplete:b.a.bool,taskListHidden:b.a.bool,query:b.a.object.isRequired,shouldShowWelcomeModal:b.a.bool,updateOptions:b.a.func.isRequired};var Ue=Object(c.a)(Object(r.withSelect)((function(e){var t=e(l.NOTES_STORE_NAME).isNotesRequesting,n=e(l.OPTIONS_STORE_NAME),a=n.getOption,c=n.isResolving,r=n.hasFinishedResolution,o="yes"===a("woocommerce_task_list_welcome_modal_dismissed"),i=r("getOption",["woocommerce_task_list_welcome_modal_dismissed"])&&!o;return{defaultHomescreenLayout:a("woocommerce_default_homepage_layout")||"single_column",isBatchUpdating:t("batchUpdateNotes"),shouldShowWelcomeModal:i,taskListComplete:"yes"===a("woocommerce_task_list_complete"),taskListHidden:"yes"===a("woocommerce_task_list_hidden"),requestingTaskList:c("getOption",["woocommerce_task_list_complete"])||c("getOption",["woocommerce_task_list_hidden"])}})),Object(r.withDispatch)((function(e){return{updateOptions:e(l.OPTIONS_STORE_NAME).updateOptions}})))(He),Fe=Object(i.g)("onboarding",{});t.default=Object(c.a)(Fe.profile||Fe.tasksStatus?Object(l.withOnboardingHydration)({profileItems:Fe.profile,tasksStatus:Fe.tasksStatus}):o.identity,Object(r.withSelect)((function(e){return{profileItems:(0,e(l.ONBOARDING_STORE_NAME).getProfileItems)()}})))((function(e){var t=e.profileItems,n=e.query,c=t||{},r=c.completed,o=c.skipped;return r||o||Object(s.getHistory)().push(Object(s.getNewPath)({},"/setup-wizard",{})),Object(a.createElement)(Ue,{query:n})}))}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/leaderboards.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/leaderboards.js new file mode 100644 index 0000000..1f901e6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/leaderboards.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[37],{763:function(e,t,r){"use strict";var a=r(17),n=r.n(a),o=r(15),s=r.n(o),c=r(18),i=r.n(c),l=r(19),d=r.n(l),u=r(9),m=r.n(u),b=r(0),f=r(3),p=r(1),h=r.n(p),g=r(77),y=r(36);function _(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=m()(e);if(t){var n=m()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return d()(this,r)}}var w=function(e){i()(r,e);var t=_(r);function r(){return n()(this,r),t.apply(this,arguments)}return s()(r,[{key:"render",value:function(){var e,t,r,a,n=this.props,o=n.className,s=n.isError,c=n.isEmpty;return s?(e=Object(f.__)("There was an error getting your stats. Please try again.",'woocommerce'),t=Object(f.__)("Reload",'woocommerce'),a=function(){window.location.reload()}):c&&(e=Object(f.__)("No results could be found for this date range.",'woocommerce'),t=Object(f.__)("View Orders",'woocommerce'),r=Object(y.f)("edit.php?post_type=shop_order")),Object(b.createElement)(g.EmptyContent,{className:o,title:e,actionLabel:t,actionURL:r,actionCallback:a})}}]),r}(b.Component);w.propTypes={className:h.a.string,isError:h.a.bool,isEmpty:h.a.bool},w.defaultProps={className:""},t.a=w},772:function(e,t,r){"use strict";var a=r(778),n=["a","b","em","i","strong","p","br"],o=["target","href","rel","name","download"];t.a=function(e){return{__html:Object(a.sanitize)(e,{ALLOWED_TAGS:n,ALLOWED_ATTR:o})}}},836:function(e,t,r){},837:function(e,t,r){},857:function(e,t,r){"use strict";r.r(t);var a=r(34),n=r.n(a),o=r(62),s=r.n(o),c=r(0),i=r(3),l=r(277),d=r(1),u=r.n(d),m=r(851),b=r(20),f=r(77),p=r(35),h=r(36),g=r(64),y=r(17),_=r.n(y),w=r(15),O=r.n(w),v=r(18),j=r.n(v),E=r(19),R=r.n(E),T=r(9),k=r.n(T),L=r(32),q=r(763),S=r(772);r(836);function N(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,a=k()(e);if(t){var n=k()(this).constructor;r=Reflect.construct(a,arguments,n)}else r=a.apply(this,arguments);return R()(this,r)}}var I=function(e){j()(r,e);var t=N(r);function r(){return _()(this,r),t.apply(this,arguments)}return O()(r,[{key:"getFormattedHeaders",value:function(){return this.props.headers.map((function(e,t){return{isLeftAligned:0===t,hiddenByDefault:!1,isSortable:!1,key:e.label,label:e.label}}))}},{key:"getFormattedRows",value:function(){return this.props.rows.map((function(e){return e.map((function(e){return{display:Object(c.createElement)("div",{dangerouslySetInnerHTML:Object(S.a)(e.display)}),value:e.value}}))}))}},{key:"render",value:function(){var e=this.props,t=e.isRequesting,r=e.isError,a=e.totalRows,n=e.title,o="woocommerce-leaderboard";if(r)return Object(c.createElement)(q.a,{className:o,isError:!0});var s=this.getFormattedRows();return t||0!==s.length?Object(c.createElement)(f.TableCard,{className:o,headers:this.getFormattedHeaders(),isLoading:t,rows:s,rowsPerPage:a,showMenu:!1,title:n,totalRows:a}):Object(c.createElement)(f.Card,{title:n,className:o},Object(c.createElement)(f.EmptyTable,null,Object(i.__)("No data recorded for the selected time period.",'woocommerce')))}}]),r}(c.Component);I.propTypes={headers:u.a.arrayOf(u.a.shape({label:u.a.string})),id:u.a.string.isRequired,query:u.a.object,rows:u.a.arrayOf(u.a.arrayOf(u.a.shape({display:u.a.node,value:u.a.oneOfType([u.a.string,u.a.number,u.a.bool])}))).isRequired,title:u.a.string.isRequired,totalRows:u.a.number.isRequired},I.defaultProps={rows:[],isError:!1,isRequesting:!1};var P=Object(l.a)(Object(b.withSelect)((function(e,t){var r=t.id,a=t.query,n=t.totalRows,o=t.filters,s=e(p.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,c=Object(p.getFilterQuery)({filters:o,query:a}),i={id:r,per_page:n,persisted_query:Object(L.getPersistedQuery)(a),query:a,select:e,defaultDateRange:s,filterQuery:c};return Object(p.getLeaderboard)(i)})))(I),C=(r(837),function(e){var t=e.allLeaderboards,r=e.controls,a=e.isFirst,o=e.isLast,l=e.hiddenBlocks,d=e.onMove,u=e.onRemove,b=e.onTitleBlur,h=e.onTitleChange,y=e.onToggleHiddenBlock,_=e.query,w=e.title,O=e.titleInput,v=e.filters,j=Object(p.useUserPreferences)(),E=j.updateUserPreferences,R=s()(j,["updateUserPreferences"]),T=Object(c.useState)(parseInt(R.dashboard_leaderboard_rows||5,10)),k=n()(T,2),L=k[0],q=k[1],S=function(e){q(parseInt(e,10));var t={dashboard_leaderboard_rows:parseInt(e,10)};E(t)};return Object(c.createElement)(c.Fragment,null,Object(c.createElement)("div",{className:"woocommerce-dashboard__dashboard-leaderboards"},Object(c.createElement)(f.SectionHeader,{title:w||Object(i.__)("Leaderboards",'woocommerce'),menu:Object(c.createElement)(f.EllipsisMenu,{label:Object(i.__)("Choose which leaderboards to display and other settings",'woocommerce'),renderContent:function(e){var n=e.onToggle;return Object(c.createElement)(c.Fragment,null,Object(c.createElement)(f.MenuTitle,null,Object(i.__)("Leaderboards",'woocommerce')),function(e){var t=e.allLeaderboards,r=e.hiddenBlocks,a=e.onToggleHiddenBlock;return t.map((function(e){var t=!r.includes(e.id);return Object(c.createElement)(f.MenuItem,{checked:t,isCheckbox:!0,isClickable:!0,key:e.id,onInvoke:function(){a(e.id)(),Object(g.recordEvent)("dash_leaderboards_toggle",{status:t?"off":"on",key:e.id})}},e.label)}))}({allLeaderboards:t,hiddenBlocks:l,onToggleHiddenBlock:y}),Object(c.createElement)(m.a,{className:"woocommerce-dashboard__dashboard-leaderboards__select",label:Object(i.__)("Rows Per Table",'woocommerce'),value:L,options:Array.from({length:20},(function(e,t){return{v:t+1,label:t+1}})),onChange:S}),window.wcAdminFeatures["analytics-dashboard/customizable"]&&Object(c.createElement)(r,{onToggle:n,onMove:d,onRemove:u,isFirst:a,isLast:o,onTitleBlur:b,onTitleChange:h,titleInput:O}))}})}),Object(c.createElement)("div",{className:"woocommerce-dashboard__columns"},function(e){var t=e.allLeaderboards,r=e.hiddenBlocks,a=e.query,n=e.rowsPerTable,o=e.filters;return t.map((function(e){if(!r.includes(e.id))return Object(c.createElement)(P,{headers:e.headers,id:e.id,key:e.id,query:a,title:e.label,totalRows:n,filters:o})}))}({allLeaderboards:t,hiddenBlocks:l,query:_,rowsPerTable:L,filters:v}))))});C.propTypes={query:u.a.object.isRequired};t.default=Object(l.a)(Object(b.withSelect)((function(e){var t=e(p.ITEMS_STORE_NAME),r=t.getItems,a=t.getItemsError;return{allLeaderboards:Object(h.g)("dataEndpoints",{leaderboards:[]}).leaderboards,getItems:r,getItemsError:a}})))(C)}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/marketing-overview.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/marketing-overview.js new file mode 100644 index 0000000..efd7d67 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/marketing-overview.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[39],{113:function(M,t,e){"use strict";e.d(t,"b",(function(){return j})),e.d(t,"a",(function(){return u}));var j="wc/marketing",u="/wc-admin/marketing"},194:function(M,t,e){"use strict";var j=e(0),u=e(724),L=e(558),N=e(190),c=e(725),i=e(1),n=e.n(i),r=e(4),g=e.n(r),D=(e(552),function(M){var t=M.title,e=M.description,i=M.children,n=M.className;return Object(j.createElement)(u.a,{className:g()(n,"woocommerce-admin-marketing-card")},Object(j.createElement)(L.a,null,Object(j.createElement)("div",null,Object(j.createElement)(N.a,{variant:"title.small"},t),Object(j.createElement)(N.a,{variant:"subtitle.small",className:"woocommerce-admin-marketing-card-subtitle"},e))),Object(j.createElement)(c.a,null,i))});D.propTypes={title:n.a.string,description:n.a.string,className:n.a.string,children:n.a.node},t.a=D},279:function(M,t,e){"use strict";e.d(t,"a",(function(){return r})),e.d(t,"b",(function(){return _})),e.d(t,"c",(function(){return W}));var j={};e.r(j),e.d(j,"blank",(function(){return w})),e.d(j,"amazonEbayIntegration",(function(){return x})),e.d(j,"woocommerceAmazonEbayIntegration",(function(){return x})),e.d(j,"automatewoo",(function(){return m})),e.d(j,"automatewooAlt",(function(){return d})),e.d(j,"facebook",(function(){return k})),e.d(j,"facebookForWoocommerce",(function(){return k})),e.d(j,"googleAds",(function(){return Y})),e.d(j,"klikenMarketingForGoogle",(function(){return Y})),e.d(j,"hubspotForWoocommerce",(function(){return Q})),e.d(j,"mailchimpForWoocommerce",(function(){return U})),e.d(j,"woocommerceStoreCredit",(function(){return b})),e.d(j,"woocommerceFreeGiftCoupons",(function(){return h})),e.d(j,"woocommerceUrlCoupons",(function(){return f})),e.d(j,"woocommerceGroupCoupons",(function(){return p})),e.d(j,"woocommerceSmartCoupons",(function(){return v}));var u=e(38),L=e.n(u),N=e(0),c=e(72),i=e(4),n=e.n(i),r=(e(551),function(M){return Object(N.createElement)(c.a,L()({},M,{className:n()(M.className,"woocommerce-admin-marketing-button")}))}),g=(e(194),e(17)),D=e.n(g),I=e(15),a=e.n(I),y=e(18),z=e.n(y),A=e(19),T=e.n(A),o=e(9),O=e.n(o),S=e(1),E=e.n(S),l=e(570),s=e(2),C=(e(553),e(88)),w=Object(N.createElement)(C.c,{width:"36",height:"36",fill:"none",xmlns:"http://www.w3.org/2000/svg"}),x=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg",width:"100",height:"100",viewBox:"0 0 100 100"},Object(N.createElement)("defs",null,Object(N.createElement)("clipPath",{id:"b"},Object(N.createElement)("rect",{width:"100",height:"100"}))),Object(N.createElement)("g",{id:"a",clipPath:"url(#b)"},Object(N.createElement)("rect",{width:"100",height:"100",fill:"#fff"}),Object(N.createElement)("rect",{width:"100",height:"100",fill:"#eee"}),Object(N.createElement)("g",{transform:"translate(9 25.655)"},Object(N.createElement)(C.b,{d:"M179.753,195.8c-4.732,3.488-11.591,5.349-17.5,5.349a31.66,31.66,0,0,1-21.374-8.156c-.443-.4-.046-.946.486-.634a43.018,43.018,0,0,0,21.384,5.671,42.523,42.523,0,0,0,16.312-3.335c.8-.34,1.471.525.688,1.106",transform:"translate(-129.235 -176.611)",fill:"#f90",fillRule:"evenodd"}),Object(N.createElement)(C.b,{d:"M577.807,183.949c-.6-.773-4-.365-5.522-.184-.464.057-.535-.347-.117-.638,2.7-1.9,7.142-1.354,7.66-.716s-.135,5.09-2.676,7.213c-.39.326-.762.152-.588-.28.571-1.425,1.85-4.619,1.244-5.395",transform:"translate(-525.323 -167.01)",fill:"#f90",fillRule:"evenodd"}),Object(N.createElement)(C.b,{d:"M572.708,6.758V4.908a.457.457,0,0,1,.468-.468h8.284a.461.461,0,0,1,.479.468V6.493a2.605,2.605,0,0,1-.624,1.163l-4.292,6.129a9.146,9.146,0,0,1,4.725,1.014.843.843,0,0,1,.44.72v1.974c0,.269-.3.585-.61.422a9.542,9.542,0,0,0-8.752.014c-.287.156-.588-.156-.588-.425V15.627a2.238,2.238,0,0,1,.3-1.272l4.973-7.132h-4.328a.458.458,0,0,1-.479-.464",transform:"translate(-525.64 -4.078)",fillRule:"evenodd"}),Object(N.createElement)(C.b,{d:"M173.431,15.624h-2.52a.476.476,0,0,1-.45-.429V2.261a.473.473,0,0,1,.486-.464h2.35a.475.475,0,0,1,.457.432V3.92h.046a3.463,3.463,0,0,1,6.589,0,3.722,3.722,0,0,1,6.4-.982c.8,1.088.634,2.669.634,4.055l0,8.163a.476.476,0,0,1-.486.468h-2.517a.479.479,0,0,1-.454-.468V8.3a16.192,16.192,0,0,0-.071-2.424,1.312,1.312,0,0,0-1.482-1.113,1.674,1.674,0,0,0-1.506,1.06,7.831,7.831,0,0,0-.234,2.478v6.855a.476.476,0,0,1-.486.468h-2.517a.476.476,0,0,1-.454-.468l0-6.855c0-1.443.238-3.566-1.553-3.566-1.811,0-1.74,2.07-1.74,3.566v6.855a.476.476,0,0,1-.486.468",transform:"translate(-156.58 -1.399)",fillRule:"evenodd"}),Object(N.createElement)(C.b,{d:"M714.982,1.524c3.739,0,5.763,3.211,5.763,7.295,0,3.945-2.237,7.075-5.763,7.075-3.672,0-5.671-3.211-5.671-7.213,0-4.027,2.024-7.156,5.671-7.156M715,4.164c-1.857,0-1.974,2.531-1.974,4.108s-.025,4.955,1.953,4.955c1.953,0,2.045-2.722,2.045-4.381a11.959,11.959,0,0,0-.376-3.431A1.577,1.577,0,0,0,715,4.164",transform:"translate(-651.552 -1.399)",fillRule:"evenodd"}),Object(N.createElement)(C.b,{d:"M875.817,15.624h-2.51a.479.479,0,0,1-.454-.468l0-12.938a.477.477,0,0,1,.486-.422h2.336a.482.482,0,0,1,.45.362V4.136h.046c.705-1.769,1.694-2.612,3.435-2.612a3.307,3.307,0,0,1,2.942,1.524c.659,1.035.659,2.775.659,4.027v8.142a.484.484,0,0,1-.486.408h-2.527a.477.477,0,0,1-.447-.408V8.191c0-1.414.163-3.484-1.577-3.484a1.647,1.647,0,0,0-1.457,1.035,5.724,5.724,0,0,0-.4,2.449v6.965a.485.485,0,0,1-.493.468",transform:"translate(-801.775 -1.399)",fillRule:"evenodd"}),Object(N.createElement)(C.b,{d:"M413.163,8.046a4.93,4.93,0,0,1-.471,2.673,2.048,2.048,0,0,1-1.744,1.145c-.968,0-1.535-.737-1.535-1.825,0-2.148,1.925-2.538,3.75-2.538v.546m2.541,6.143a.526.526,0,0,1-.6.06,6.143,6.143,0,0,1-1.446-1.68,4.991,4.991,0,0,1-4.154,1.833,3.575,3.575,0,0,1-3.771-3.927,4.277,4.277,0,0,1,2.687-4.119,17.463,17.463,0,0,1,4.739-.876V5.154a3.214,3.214,0,0,0-.308-1.825,1.677,1.677,0,0,0-1.414-.656,1.917,1.917,0,0,0-2.024,1.514.527.527,0,0,1-.439.461l-2.442-.262a.444.444,0,0,1-.376-.528C406.719.893,409.4,0,411.795,0a5.714,5.714,0,0,1,3.8,1.255C416.818,2.4,416.7,3.928,416.7,5.59V9.517a3.447,3.447,0,0,0,.95,2.336.477.477,0,0,1-.011.67c-.514.429-1.428,1.226-1.932,1.673l0-.007",transform:"translate(-372.698 0)",fillRule:"evenodd"}),Object(N.createElement)(C.b,{d:"M7.426,8.046a4.93,4.93,0,0,1-.471,2.673,2.043,2.043,0,0,1-1.744,1.145c-.968,0-1.531-.737-1.531-1.825C3.679,7.89,5.6,7.5,7.426,7.5v.546m2.541,6.143a.526.526,0,0,1-.6.06,6.2,6.2,0,0,1-1.446-1.68A4.986,4.986,0,0,1,3.771,14.4,3.576,3.576,0,0,1,0,10.474,4.282,4.282,0,0,1,2.687,6.356,17.462,17.462,0,0,1,7.426,5.48V5.154a3.243,3.243,0,0,0-.3-1.825,1.686,1.686,0,0,0-1.414-.656A1.921,1.921,0,0,0,3.679,4.186a.527.527,0,0,1-.436.461L.8,4.385a.446.446,0,0,1-.376-.528C.985.893,3.662,0,6.058,0a5.714,5.714,0,0,1,3.8,1.255C11.08,2.4,10.963,3.928,10.963,5.59V9.517a3.447,3.447,0,0,0,.95,2.336.473.473,0,0,1-.007.67c-.514.429-1.428,1.226-1.932,1.673l-.007-.007",transform:"translate(0 0)",fillRule:"evenodd"})),Object(N.createElement)("g",{transform:"translate(18.9 54.637)"},Object(N.createElement)(C.b,{d:"M8.055,26.308C3.716,26.308.1,28.149.1,33.7c0,4.4,2.431,7.171,8.067,7.171,6.633,0,7.059-4.37,7.059-4.37H12.011s-.689,2.353-4.04,2.353a4.4,4.4,0,0,1-4.693-4.428H15.562V32.807c0-2.557-1.623-6.5-7.507-6.5Zm-.112,2.073c2.6,0,4.37,1.592,4.37,3.977H3.349C3.349,29.826,5.661,28.381,7.943,28.381Z",transform:"translate(0 -20.83)",fill:"#e53238"}),Object(N.createElement)(C.b,{d:"M75.169.1V17.254c0,.974-.069,2.341-.069,2.341h3.066s.11-.982.11-1.879c0,0,1.515,2.37,5.633,2.37a6.961,6.961,0,0,0,7.283-7.325A6.922,6.922,0,0,0,83.915,5.52c-4.279,0-5.609,2.311-5.609,2.311V.1Zm7.955,7.542c2.945,0,4.818,2.186,4.818,5.119a4.857,4.857,0,0,1-4.8,5.2c-3.143,0-4.839-2.454-4.839-5.175C78.306,10.254,79.827,7.642,83.123,7.642Z",transform:"translate(-59.609)",fill:"#0064d2"}),Object(N.createElement)(C.b,{d:"M159.834,26.308c-6.528,0-6.947,3.574-6.947,4.146h3.249s.17-2.087,3.473-2.087c2.146,0,3.809.982,3.809,2.871v.672h-3.809c-5.057,0-7.731,1.479-7.731,4.482,0,2.955,2.47,4.562,5.809,4.562,4.55,0,6.015-2.514,6.015-2.514,0,1,.077,1.985.077,1.985h2.888s-.112-1.221-.112-2V31.669c0-4.428-3.572-5.36-6.722-5.36Zm3.585,7.619v.9c0,1.169-.721,4.075-4.968,4.075-2.326,0-3.323-1.161-3.323-2.507C155.128,33.943,158.486,33.927,163.419,33.927Z",transform:"translate(-120.634 -20.83)",fill:"#f5af02"}),Object(N.createElement)(C.b,{d:"M214.879,29.041h3.655l5.246,10.51,5.234-10.51h3.311l-9.533,18.711h-3.473l2.751-5.216Z",transform:"translate(-170.706 -23.002)",fill:"#86b817"})))),m=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg",width:"100",height:"100",viewBox:"0 0 100 100"},Object(N.createElement)("defs",null,Object(N.createElement)("clipPath",{id:"b"},Object(N.createElement)("rect",{width:"100",height:"100"}))),Object(N.createElement)("g",{id:"a",clipPath:"url(#b)"},Object(N.createElement)("rect",{width:"100",height:"100",fill:"#fff"}),Object(N.createElement)("rect",{width:"100",height:"100",fill:"#7532e4"}),Object(N.createElement)("g",{transform:"translate(-43.503 -133.512)"},Object(N.createElement)(C.b,{d:"M78.217,193.13H64.405l-2.823,7.764H54.6L67.648,166.9h7.669l12.934,33.995H81.059Zm-11.6-6.047h9.4L71.33,174.245Z",transform:"translate(0 0)",fill:"#1ff2e6"}),Object(N.createElement)(C.b,{d:"M246.639,166.9h6.753l-9.4,33.995h-6.81l-7.764-24.208-7.764,24.208h-6.906L205.3,166.9h7l6.238,23.388,7.535-23.388h6.849l7.592,23.483Z",transform:"translate(-121.952)",fill:"#1ff2e6"})))),d=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg"},Object(N.createElement)(C.b,{fillRule:"evenodd",clipRule:"evenodd",d:"M4.67708 14.1615h3.77084l.77604 2.1198h1.96354L7.65625 7H5.5625L2 16.2813h1.90625l.77083-2.1198zm3.17188-1.6511H5.28125l1.28646-3.50519 1.28125 3.50519zM22.9791 7h-1.8437l-1.6719 6.4115L17.3906 7h-1.8698l-2.0573 6.3854L11.7604 7H9.8489l2.5781 9.2813h1.8854l2.1198-6.60942 2.1198 6.60942h1.8594L22.9791 7z"})),k=Object(N.createElement)(C.c,{width:"36",height:"36",viewBox:"0 0 36 36",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(N.createElement)(C.b,{fillRule:"evenodd",clipRule:"evenodd",d:"M34 0H2C0.8 0 0 0.8 0 2V34C0 35 0.8 36 2 36H19.2V22H14.6V16.6H19.2V12.6C19.2 8 22 5.4 26.2 5.4C28.2 5.4 29.8 5.6 30.4 5.6V10.4H27.6C25.4 10.4 25 11.4 25 13V16.4H30.4L29.6 22H25V36H34C35 36 36 35.2 36 34V2C36 0.8 35.2 0 34 0Z",fill:"#3B5997"})),Y=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg",width:"100",height:"100",viewBox:"0 0 100 100"},Object(N.createElement)("defs",null,Object(N.createElement)("clipPath",{id:"b"},Object(N.createElement)("rect",{width:"100",height:"100"}))),Object(N.createElement)("g",{id:"a",clipPath:"url(#b)"},Object(N.createElement)("rect",{width:"100",height:"100",fill:"#fff"}),Object(N.createElement)("rect",{width:"100",height:"100",fill:"#eee"}),Object(N.createElement)("g",{transform:"translate(17 7.967)"},Object(N.createElement)(C.b,{d:"M83.982,7.646a11.959,11.959,0,0,1,2.825-4.477,11.065,11.065,0,0,1,17.4,2.585c2.665,4.851,5.49,9.594,8.235,14.392,4.584,7.969,9.221,15.937,13.752,23.933a11.017,11.017,0,1,1-19.269,10.687q-6.037-10.514-12.1-21a2.415,2.415,0,0,0-.293-.426,4.336,4.336,0,0,1-.88-1.306c-1.786-3.145-3.625-6.263-5.41-9.381C87.1,20.626,85.9,18.627,84.755,16.6a11.036,11.036,0,0,1-1.466-5.863,8.171,8.171,0,0,1,.693-3.092",transform:"translate(-61.088 0)",fill:"#3c8bd9"}),Object(N.createElement)(C.b,{d:"M31.255,28.6a15.329,15.329,0,0,0-.506,2.932,11.513,11.513,0,0,0,1.6,6.263q4.4,7.556,8.768,15.165c.267.453.48.906.746,1.333-1.6,2.772-3.2,5.517-4.824,8.289C34.8,66.445,32.561,70.336,30.3,74.2c-.107,0-.133-.053-.16-.133a1.652,1.652,0,0,1,.107-.613,10.727,10.727,0,0,0-2.559-10.581,10.157,10.157,0,0,0-6.263-3.225,10.816,10.816,0,0,0-8.555,2.372c-.453.346-.746.853-1.279,1.119a.178.178,0,0,1-.187-.133c1.279-2.212,2.532-4.424,3.811-6.636q7.915-13.752,15.858-27.478c.053-.107.133-.187.187-.293",transform:"translate(-8.362 -20.954)",fill:"#fabc04"}),Object(N.createElement)(C.b,{d:"M4.173,147.8c.506-.453.986-.933,1.519-1.359a11.016,11.016,0,0,1,17.617,6.689,11.714,11.714,0,0,1-.426,5.677,2.788,2.788,0,0,1-.107.453c-.24.426-.453.88-.72,1.306a10.715,10.715,0,0,1-10.447,5.57,10.94,10.94,0,0,1-10.1-9.541A10.663,10.663,0,0,1,2.974,149.5c.267-.48.586-.906.879-1.386.133-.107.08-.32.32-.32",transform:"translate(-1.029 -105.664)",fill:"#34a852"}),Object(N.createElement)(C.b,{d:"M10.982,157.707c-.107.107-.107.293-.293.32-.027-.187.08-.293.187-.426l.107.107",transform:"translate(-7.837 -115.573)",fill:"#fabc04"}),Object(N.createElement)(C.b,{d:"M81.478,199.753c-.107-.187,0-.32.107-.453l.107.107-.213.346",transform:"translate(-59.731 -146.16)",fill:"#e1c025"}),Object(N.createElement)(C.b,{d:"M5.517,260.4a5.4,5.4,0,1,0,0,10.794A4.974,4.974,0,0,0,9.3,269.675a5.3,5.3,0,0,0,1.2-4.371H5.517v1.466H9.061a3.1,3.1,0,0,1-.8,1.866,3.672,3.672,0,0,1-2.745,1.093,3.918,3.918,0,0,1,0-7.836,3.661,3.661,0,0,1,2.665,1.066l1.039-1.039A5.116,5.116,0,0,0,5.517,260.4Zm9.035,3.864a3.518,3.518,0,1,0,3.465,3.518,3.437,3.437,0,0,0-3.465-3.518m0,5.65a2.141,2.141,0,1,1,1.946-2.132,2.021,2.021,0,0,1-1.946,2.132m7.516-5.65a3.518,3.518,0,1,0,3.465,3.518,3.421,3.421,0,0,0-3.465-3.518m0,5.65a2.141,2.141,0,1,1,1.946-2.132,2.021,2.021,0,0,1-1.946,2.132m7.489-5.65a3.483,3.483,0,0,0,0,6.956,2.329,2.329,0,0,0,1.812-.8h.053v.506c0,1.333-.693,2.052-1.839,2.052a1.9,1.9,0,0,1-1.732-1.226l-1.333.56a3.268,3.268,0,0,0,3.065,2.052c1.786,0,3.278-1.066,3.278-3.625V264.5H31.422v.56h-.053a2.329,2.329,0,0,0-1.812-.8m.133,5.6a1.992,1.992,0,0,1-1.919-2.105,2.017,2.017,0,0,1,1.919-2.132,1.957,1.957,0,0,1,1.839,2.132,1.932,1.932,0,0,1-1.839,2.105m4.291-9.035H35.5v10.287H33.98Zm5.6,3.438a3.346,3.346,0,0,0-3.331,3.518,3.443,3.443,0,0,0,3.491,3.518,3.485,3.485,0,0,0,2.932-1.546l-1.2-.8a2.014,2.014,0,0,1-1.732.959,1.745,1.745,0,0,1-1.706-1.066l4.717-1.946-.16-.4a3.3,3.3,0,0,0-3.012-2.239m-1.812,3.411a1.93,1.93,0,0,1,1.839-2.052,1.329,1.329,0,0,1,1.306.746Z",transform:"translate(0 -190.976)",fill:"#757575"}),Object(N.createElement)(C.b,{d:"M170.4,274.255l3.518-9.355h1.359l3.518,9.355h-1.333l-.906-2.532h-3.918l-.906,2.532Zm2.638-3.651h3.118l-1.519-4.211h-.053Z",transform:"translate(-124.986 -194.277)",fill:"#757575"}),Object(N.createElement)(C.b,{d:"M204.079,273.482a3.528,3.528,0,0,1-.879-2.425,3.623,3.623,0,0,1,.879-2.425,2.792,2.792,0,0,1,2.159-.986,2.827,2.827,0,0,1,1.279.293,2.219,2.219,0,0,1,.906.8h.053l-.053-.879V264.9h1.2v9.355h-1.146v-.879h-.053a2.427,2.427,0,0,1-.906.8,2.654,2.654,0,0,1-1.279.293,2.754,2.754,0,0,1-2.159-.986m3.785-.746a2.659,2.659,0,0,0,0-3.331,1.939,1.939,0,0,0-2.878,0,2.621,2.621,0,0,0,0,3.3,1.9,1.9,0,0,0,1.439.64,1.724,1.724,0,0,0,1.439-.613",transform:"translate(-149.044 -194.277)",fill:"#757575"}),Object(N.createElement)(C.b,{d:"M235.484,281.436a3.152,3.152,0,0,1-3.545.08,2.854,2.854,0,0,1-1.039-1.333l1.066-.453a1.976,1.976,0,0,0,.693.906,1.675,1.675,0,0,0,.986.32,1.831,1.831,0,0,0,.959-.24.677.677,0,0,0,.373-.586c0-.4-.32-.72-.933-.906l-1.093-.267c-1.253-.32-1.866-.906-1.866-1.812a1.7,1.7,0,0,1,.72-1.413,3.041,3.041,0,0,1,1.812-.533,3.108,3.108,0,0,1,1.546.4,2.24,2.24,0,0,1,.959,1.093l-1.066.453a1.506,1.506,0,0,0-.586-.64,1.8,1.8,0,0,0-.933-.24,1.585,1.585,0,0,0-.853.24.7.7,0,0,0-.373.586c0,.373.346.64,1.039.773l.959.24c1.279.32,1.892.959,1.892,1.919a1.662,1.662,0,0,1-.72,1.413",transform:"translate(-169.362 -201.831)",fill:"#757575"})))),Q=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg",width:"100",height:"100",viewBox:"0 0 100 100"},Object(N.createElement)("defs",null,Object(N.createElement)("clipPath",{id:"b"},Object(N.createElement)("rect",{width:"100",height:"100"}))),Object(N.createElement)("g",{id:"a",clipPath:"url(#b)"},Object(N.createElement)("rect",{width:"100",height:"100",fill:"#fff"}),Object(N.createElement)(C.b,{d:"M100,100H0V0H100V100ZM40.665,75.539a6.446,6.446,0,1,0,6.447,6.447,6.376,6.376,0,0,0-.3-1.843L54.158,72.8A19.808,19.808,0,1,0,69.206,37.48h.015V28.455a6.959,6.959,0,0,0,4.013-6.273v-.211a6.971,6.971,0,0,0-6.952-6.953H66.07a6.97,6.97,0,0,0-6.952,6.953v.211a6.957,6.957,0,0,0,4.013,6.273V37.5a19.745,19.745,0,0,0-9.376,4.126L28.935,22.295a7.919,7.919,0,0,0-4.148-9.145,7.845,7.845,0,0,0-3.5-.817,7.919,7.919,0,1,0,3.938,14.786l24.4,19a19.775,19.775,0,0,0,.3,22.3l-7.426,7.427A6.362,6.362,0,0,0,40.665,75.539Zm25.522-8.321h0l-.023,0a10.164,10.164,0,0,1,.023-20.328H66.2a10.166,10.166,0,0,1-.012,20.333Z",fill:"#ff7a59"}))),U=Object(N.createElement)(C.c,{width:"36",height:"36",viewBox:"0 0 36 36",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(N.createElement)("rect",{width:"36",height:"36",rx:"3",fill:"#FFE071"}),Object(N.createElement)(C.b,{d:"M24.0534 17.2863C24.2392 17.2638 24.4176 17.2625 24.5813 17.2863C24.6764 17.0647 24.6923 16.6823 24.6071 16.2661C24.4808 15.6471 24.3091 15.2728 23.9546 15.331C23.6002 15.3892 23.5873 15.8374 23.7143 16.4564C23.7848 16.8043 23.9117 17.1023 24.0534 17.2863Z",fill:"black"}),Object(N.createElement)(C.b,{d:"M21.0119 17.7757C21.2652 17.8889 21.4209 17.9647 21.4823 17.899C21.5215 17.8576 21.5099 17.7794 21.4491 17.6786C21.3241 17.4702 21.0665 17.2587 20.7937 17.1404C20.2357 16.895 19.5697 16.9764 19.0559 17.3532C18.886 17.4802 18.7254 17.6555 18.7487 17.7625C18.756 17.7969 18.7812 17.8232 18.8413 17.8314C18.9811 17.8476 19.4698 17.5954 20.0321 17.5603C20.4294 17.5353 20.7587 17.6624 21.0119 17.7757Z",fill:"black"}),Object(N.createElement)(C.b,{d:"M20.5024 18.073C20.1725 18.1262 19.9904 18.237 19.8733 18.3409C19.7733 18.4298 19.712 18.5281 19.7126 18.5975C19.7126 18.6307 19.7267 18.6495 19.7378 18.6589C19.7531 18.6726 19.7709 18.6802 19.7923 18.6802C19.8671 18.6802 20.0339 18.6119 20.0339 18.6119C20.4932 18.4442 20.7961 18.4642 21.0966 18.4993C21.2627 18.518 21.3406 18.5287 21.3774 18.4705C21.3884 18.4536 21.4013 18.4179 21.3682 18.3628C21.2903 18.2339 20.9568 18.0179 20.5024 18.073Z",fill:"black"}),Object(N.createElement)(C.b,{d:"M23.0263 19.1626C23.2501 19.2753 23.4972 19.2309 23.5775 19.0644C23.6578 18.8973 23.5413 18.6713 23.3169 18.5587C23.0925 18.446 22.846 18.4904 22.7657 18.6569C22.6859 18.824 22.8025 19.0506 23.0263 19.1626Z",fill:"black"}),Object(N.createElement)(C.b,{d:"M24.4673 17.8777C24.2851 17.8746 24.1343 18.0786 24.13 18.3334C24.1257 18.5881 24.2698 18.7971 24.4519 18.8003C24.634 18.8034 24.7849 18.5994 24.7892 18.3446C24.7935 18.0899 24.6494 17.8809 24.4673 17.8777Z",fill:"black"}),Object(N.createElement)(C.b,{d:"M12.2373 22.4735C12.1919 22.4153 12.1177 22.4335 12.0454 22.4504C11.9951 22.4623 11.9381 22.476 11.8755 22.4748C11.7419 22.4723 11.6284 22.4134 11.5646 22.3139C11.4819 22.1837 11.4868 21.9903 11.5781 21.7682C11.5904 21.7381 11.6051 21.7049 11.6211 21.6686C11.767 21.3344 12.0117 20.7743 11.7369 20.241C11.5303 19.8398 11.1937 19.5895 10.7884 19.5369C10.3996 19.4868 9.99919 19.6339 9.7441 19.9212C9.34124 20.3749 9.27808 20.9921 9.35595 21.2099C9.38477 21.29 9.42892 21.3119 9.46142 21.3163C9.5301 21.3257 9.63127 21.275 9.69505 21.1003C9.69934 21.0878 9.70547 21.0684 9.71344 21.0434C9.74165 20.9514 9.79438 20.7799 9.88084 20.6422C9.98508 20.4763 10.147 20.3618 10.3371 20.3205C10.5308 20.2779 10.7289 20.3161 10.8944 20.4269C11.1765 20.6153 11.285 20.9683 11.1648 21.305C11.1023 21.479 11.0011 21.812 11.0238 22.0855C11.0692 22.6394 11.4028 22.8616 11.7026 22.8854C11.9939 22.8966 12.1981 22.7295 12.2496 22.6075C12.279 22.5361 12.2539 22.4923 12.2373 22.4735Z",fill:"black"}),Object(N.createElement)(C.b,{d:"M29.0624 21.4609C29.0513 21.4209 28.979 21.1511 28.8796 20.8263C28.7803 20.5015 28.6773 20.2724 28.6773 20.2724C29.0759 19.6634 29.0826 19.1189 29.0299 18.8109C28.9735 18.4285 28.8177 18.1031 28.5031 17.7663C28.1892 17.4296 27.5466 17.0847 26.6434 16.8262C26.5403 16.7968 26.1994 16.7011 26.1694 16.6917C26.1669 16.6717 26.1442 15.5513 26.124 15.0706C26.1093 14.7233 26.0798 14.18 25.9149 13.6455C25.7181 12.922 25.3759 12.2886 24.9479 11.8836C26.1283 10.635 26.8647 9.25926 26.8629 8.07947C26.8592 5.81 24.1293 5.1234 20.7642 6.54542C20.7605 6.54667 20.0565 6.85147 20.051 6.8546C20.048 6.85147 18.7621 5.56402 18.7431 5.5465C14.907 2.13103 2.91255 15.7391 6.7474 19.0444L7.58562 19.7692C7.36794 20.3437 7.28271 21.0028 7.35261 21.7107C7.44213 22.6201 7.90202 23.4926 8.64704 24.166C9.35404 24.8057 10.2842 25.2106 11.1868 25.21C12.6793 28.72 16.0886 30.8737 20.0872 30.9951C24.3758 31.1253 27.9758 29.0711 29.4842 25.3815C29.583 25.1224 30.0018 23.9557 30.0018 22.9255C30.0005 21.8903 29.4272 21.4609 29.0624 21.4609ZM11.5161 24.2236C11.3861 24.2461 11.2531 24.2555 11.1188 24.2518C9.82374 24.2161 8.42445 23.0263 8.28526 21.6143C8.13135 20.054 8.91255 18.8535 10.2953 18.5687C10.4608 18.5349 10.6601 18.5149 10.876 18.5268C11.651 18.57 12.7928 19.1777 13.0534 20.9002C13.2845 22.4261 12.9172 23.9801 11.5161 24.2236ZM10.0696 17.6361C9.20872 17.807 8.45021 18.3052 7.98603 18.9931C7.70887 18.7571 7.19195 18.3002 7.10059 18.1218C6.35986 16.686 7.90877 13.8946 8.99104 12.318C11.6657 8.42245 15.8544 5.4739 17.7939 6.00903C18.1091 6.10041 19.1533 7.33591 19.1533 7.33591C19.1533 7.33591 17.2151 8.43372 15.4172 9.96402C12.9951 11.8667 11.1654 14.6338 10.0696 17.6361ZM23.6657 23.6403C23.694 23.6284 23.7136 23.5952 23.7099 23.5627C23.7056 23.5226 23.6706 23.4932 23.6314 23.4976C23.6314 23.4976 21.6024 23.8043 19.6856 23.0876C19.8941 22.3948 20.4496 22.6451 21.2884 22.714C22.8012 22.806 24.1563 22.5807 25.1582 22.2871C26.0265 22.033 27.1664 21.5317 28.0525 20.8182C28.3511 21.4879 28.4565 22.2252 28.4565 22.2252C28.4565 22.2252 28.6877 22.1832 28.8809 22.304C29.0636 22.4186 29.1973 22.657 29.1059 23.2735C28.9195 24.4252 28.44 25.3596 27.6343 26.2196C27.1437 26.7585 26.5477 27.2273 25.8665 27.5684C25.5047 27.7624 25.119 27.9301 24.7118 28.0659C21.6735 29.0786 18.5628 27.9652 17.5603 25.5737C17.4799 25.394 17.4125 25.2056 17.3592 25.0091C16.9318 23.4331 17.2948 21.5423 18.4285 20.3525V20.3519C18.4984 20.2761 18.5696 20.1866 18.5696 20.0746C18.5696 19.9807 18.5113 19.8818 18.4604 19.8111C18.0637 19.224 16.6896 18.2232 16.9655 16.2861C17.1635 14.8948 18.3556 13.9146 19.4673 13.9728C19.5611 13.9778 19.6549 13.9835 19.7487 13.9891C20.2307 14.0179 20.6507 14.0811 21.0468 14.098C21.7103 14.1274 22.3069 14.0285 23.0139 13.4277C23.2525 13.2249 23.4438 13.049 23.7669 12.9933C23.8006 12.9877 23.8853 12.9564 24.0545 12.9645C24.2268 12.9739 24.3911 13.0221 24.5389 13.1222C25.1055 13.5072 25.1858 14.4391 25.2153 15.1213C25.2318 15.5106 25.2778 16.4526 25.2937 16.7224C25.3299 17.3407 25.4887 17.4277 25.8113 17.536C25.9922 17.5967 26.1608 17.6424 26.4085 17.7131C27.1584 17.9278 27.603 18.1462 27.8838 18.426C28.0512 18.6013 28.1285 18.7872 28.153 18.9643C28.2413 19.6227 27.6521 20.4364 26.0921 21.1755C24.3868 21.9836 22.3174 22.1882 20.888 22.0255C20.7783 22.013 20.3883 21.9679 20.3871 21.9679C19.2435 21.8108 18.591 23.3192 19.2778 24.3525C19.7199 25.0185 20.9248 25.4522 22.1303 25.4522C24.8939 25.4529 27.0186 24.248 27.8084 23.2078C27.8323 23.1765 27.8342 23.1734 27.8716 23.1158C27.9102 23.0557 27.8783 23.0232 27.8299 23.057C27.1842 23.5076 24.3169 25.2976 21.2492 24.7594C21.2492 24.7594 20.8764 24.6968 20.5361 24.5616C20.2656 24.4546 19.6997 24.1886 19.631 23.5958C22.107 24.3788 23.6657 23.6403 23.6657 23.6403ZM19.7444 23.1677C19.7444 23.1684 19.7444 23.1684 19.7444 23.1677C19.745 23.169 19.745 23.169 19.745 23.1696C19.745 23.169 19.7444 23.1684 19.7444 23.1677ZM15.0088 12.3023C15.9599 11.1807 17.1304 10.2056 18.1784 9.65858C18.2145 9.6398 18.2532 9.67986 18.2336 9.71616C18.1502 9.87013 17.9901 10.1993 17.9392 10.4497C17.9313 10.4885 17.9729 10.5179 18.0048 10.4954C18.6573 10.0416 19.7916 9.55531 20.7875 9.49272C20.8304 9.49022 20.8506 9.54592 20.8169 9.57283C20.6654 9.69113 20.4999 9.85511 20.3791 10.021C20.3582 10.0491 20.3779 10.0898 20.4122 10.0898C21.1112 10.0948 22.0966 10.3446 22.7386 10.712C22.7821 10.737 22.7509 10.8227 22.7024 10.8115C21.7305 10.5843 20.1406 10.4115 18.488 10.8227C17.0133 11.1901 15.8875 11.7572 15.0665 12.3668C15.0254 12.3981 14.9757 12.3418 15.0088 12.3023Z",fill:"black"})),b=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(N.createElement)(C.b,{d:"M3.25 12a8.75 8.75 0 1117.5 0 8.75 8.75 0 01-17.5 0zM12 4.75a7.25 7.25 0 100 14.5 7.25 7.25 0 000-14.5zm-1.338 4.877c-.314.22-.412.452-.412.623 0 .171.098.403.412.623.312.218.783.377 1.338.377.825 0 1.605.233 2.198.648.59.414 1.052 1.057 1.052 1.852 0 .795-.461 1.438-1.052 1.852-.41.286-.907.486-1.448.582v.316a.75.75 0 01-1.5 0v-.316a3.64 3.64 0 01-1.448-.582c-.59-.414-1.052-1.057-1.052-1.852a.75.75 0 011.5 0c0 .171.098.403.412.623.312.218.783.377 1.338.377s1.026-.159 1.338-.377c.314-.22.412-.452.412-.623 0-.171-.098-.403-.412-.623-.312-.218-.783-.377-1.338-.377-.825 0-1.605-.233-2.198-.648-.59-.414-1.052-1.057-1.052-1.852 0-.795.461-1.438 1.052-1.852a3.64 3.64 0 011.448-.582V7.5a.75.75 0 011.5 0v.316c.54.096 1.039.296 1.448.582.59.414 1.052 1.057 1.052 1.852a.75.75 0 01-1.5 0c0-.171-.098-.403-.412-.623-.312-.218-.783-.377-1.338-.377s-1.026.159-1.338.377z"})),h=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg"},Object(N.createElement)(C.b,{fillRule:"evenodd",clipRule:"evenodd",d:"M14.75 9C16.1307 9 17.25 7.88071 17.25 6.5C17.25 5.11929 16.1307 4 14.75 4C13.3693 4 12.25 5.11929 12.25 6.5C12.25 5.11929 11.1307 4 9.75 4C8.36929 4 7.25 5.11929 7.25 6.5C7.25 7.88071 8.36929 9 9.75 9H4V20L20 20V9L14.75 9ZM14.75 7.5C15.3023 7.5 15.75 7.05228 15.75 6.5C15.75 5.94772 15.3023 5.5 14.75 5.5C14.1977 5.5 13.75 5.94772 13.75 6.5V7.5H14.75ZM18.5 18.5V10.5H13V18.5H18.5ZM11.5 18.5H5.5L5.5 10.5H11.5L11.5 18.5ZM8.75 6.5C8.75 7.05228 9.19772 7.5 9.75 7.5H10.75V6.5C10.75 5.94772 10.3023 5.5 9.75 5.5C9.19772 5.5 8.75 5.94772 8.75 6.5Z"})),f=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(N.createElement)(C.b,{d:"M15.6 7.2H14v1.5h1.6c2 0 3.7 1.7 3.7 3.7s-1.7 3.7-3.7 3.7H14v1.5h1.6c2.8 0 5.2-2.3 5.2-5.2 0-2.9-2.3-5.2-5.2-5.2zM4.7 12.4c0-2 1.7-3.7 3.7-3.7H10V7.2H8.4c-2.9 0-5.2 2.3-5.2 5.2 0 2.9 2.3 5.2 5.2 5.2H10v-1.5H8.4c-2 0-3.7-1.7-3.7-3.7zm4.6.9h5.3v-1.5H9.3v1.5z"})),p=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(N.createElement)(C.b,{d:"M17.5 9a2 2 0 11-4 0 2 2 0 014 0zm-4.25 8v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM8.5 11a2 2 0 100-4 2 2 0 000 4z"})),v=Object(N.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg"},Object(N.createElement)(C.b,{fillRule:"evenodd",clipRule:"evenodd",d:"M15 16.5H9V15h6v1.5zM15.0052 5.99481c-1.6597-1.65973-4.3507-1.65973-6.0104 0-1.65973 1.65973-1.65973 4.35069 0 6.01039.29289.2929.29289.7678 0 1.0607-.2929.2929-.76777.2929-1.06066 0-2.24552-2.2455-2.24552-5.88624 0-8.13175 2.24556-2.24551 5.88616-2.24551 8.13176 0 2.2455 2.24551 2.2455 5.88625 0 8.13175-.2929.2929-.7678.2929-1.0607 0-.2929-.2929-.2929-.7678 0-1.0607 1.6597-1.6597 1.6597-4.35066 0-6.01039zM14 19.5h-4V18h4v1.5z"}));function P(M){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(M){return!1}}();return function(){var e,j=O()(M);if(t){var u=O()(this).constructor;e=Reflect.construct(j,arguments,u)}else e=j.apply(this,arguments);return T()(this,e)}}var G=function(M){z()(e,M);var t=P(e);function e(){return D()(this,e),t.apply(this,arguments)}return a()(e,[{key:"render",value:function(){var M=Object(s.camelCase)(this.props.product),t=w;return M in j&&(t=j[M]),Object(N.createElement)("div",{className:n()(this.props.className,"woocommerce-admin-marketing-product-icon")},Object(N.createElement)(l.a,{icon:t}))}}]),e}(N.Component);G.propTypes={product:E.a.string.isRequired,className:E.a.string};var _=G,R=e(34),Z=e.n(R),B=e(560),H=e(559),V=(e(554),function(M){var t=M.children,e=M.animationKey,j=M.animate,u=Object(N.useState)(null),L=Z()(u,2),c=L[0],i=L[1],r=Object(N.useRef)(),g=n()("woocommerce-marketing-slider",j&&"animate-".concat(j)),D={};c&&(D.height=c);var I=Object(s.debounce)((function(){var M=r.current.querySelector(".woocommerce-marketing-slider__slide");i(M.clientHeight)}),50);Object(N.useEffect)((function(){return window.addEventListener("resize",I),function(){window.removeEventListener("resize",I)}}),[]);return Object(N.createElement)("div",{className:g,ref:r,style:D},Object(N.createElement)(B.a,null,Object(N.createElement)(H.a,{timeout:320,classNames:"slide",key:e,onEnter:function(){var M=r.current.querySelector(".slide-enter");i(M.clientHeight)}},Object(N.createElement)("div",{className:"woocommerce-marketing-slider__slide"},t))))});V.propTypes={animationKey:E.a.any.isRequired,animate:E.a.oneOf([null,"left","right"])};var W=V},444:function(M,t,e){},445:function(M,t,e){"use strict";e.d(t,"a",(function(){return n}));var j=e(5),u=e.n(j),L=e(37),N=e(36);function c(M,t){var e=Object.keys(M);if(Object.getOwnPropertySymbols){var j=Object.getOwnPropertySymbols(M);t&&(j=j.filter((function(t){return Object.getOwnPropertyDescriptor(M,t).enumerable}))),e.push.apply(e,j)}return e}function i(M){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{},e=window.location,j=e.pathname,u=e.search,c=Object(N.g)("connectNonce","");return t=i({"wccom-site":Object(N.g)("siteUrl"),"wccom-back":j+u,"wccom-woo-version":Object(N.g)("wcVersion"),"wccom-connect-nonce":c},t),Object(L.addQueryArgs)(M,t)}},448:function(M,t,e){"use strict";var j=e(38),u=e.n(j),L=e(0),N=e(3),c=e(277),i=e(738),n=e(4),r=e.n(n),g=e(20),D=e(1),I=e.n(D),a=(e(444),e(64)),y=e(279),z=e(445),A=function(M){var t=M.title,e=M.description,j=M.url,u=M.product,N=M.category,c="woocommerce-marketing-recommended-extensions-item",i=Object(z.a)(j);return"coupons"===N&&"automatewoo"===u&&(u="automatewoo-alt"),Object(L.createElement)("a",{href:i,className:c,onClick:function(){Object(a.recordEvent)("marketing_recommended_extension",{name:t})}},Object(L.createElement)(y.b,{product:u}),Object(L.createElement)("div",{className:"".concat(c,"__text")},Object(L.createElement)("h4",null,t),Object(L.createElement)("p",null,e)))};A.propTypes={title:I.a.string.isRequired,description:I.a.string.isRequired,url:I.a.string.isRequired,product:I.a.string.isRequired,category:I.a.string.isRequired};var T=A,o=e(113),O=e(194),S=function(M){var t=M.extensions,e=M.isLoading,j=M.title,N=M.description,c=M.category;if(0===t.length&&!e)return null;var n=c?"woocommerce-marketing-recommended-extensions-card__category-".concat(c):"";return Object(L.createElement)(O.a,{title:j,description:N,className:r()("woocommerce-marketing-recommended-extensions-card",n)},e?Object(L.createElement)(i.a,null):Object(L.createElement)("div",{className:r()("woocommerce-marketing-recommended-extensions-card__items","woocommerce-marketing-recommended-extensions-card__items--count-".concat(t.length))},t.map((function(M){return Object(L.createElement)(T,u()({key:M.product,category:c},M))}))))};S.propTypes={extensions:I.a.arrayOf(I.a.object).isRequired,isLoading:I.a.bool.isRequired,title:I.a.string,description:I.a.string,category:I.a.string},S.defaultProps={title:Object(N.__)("Recommended extensions",'woocommerce'),description:Object(N.__)("Great marketing requires the right tools. Take your marketing to the next level with our recommended marketing extensions.",'woocommerce')};t.a=Object(c.a)(Object(g.withSelect)((function(M,t){var e=M(o.b),j=e.getRecommendedPlugins,u=e.isResolving;return{extensions:j(t.category),isLoading:u("getRecommendedPlugins",[t.category])}})),Object(g.withDispatch)((function(M){return{createNotice:M("core/notices").createNotice}})))(S)},449:function(M,t,e){"use strict";var j=e(34),u=e.n(j),L=e(0),N=e(277),c=e(3),i=e(4),n=e.n(i),r=e(738),g=e(20),D=e(1),I=e.n(D),a=e(77),y=e(64),z=(e(555),e(279)),A=e(113),T=e(194),o=e(42),O=e.n(o),S=function(){return O()({mixedString:Object(c.__)("Read {{link}}the WooCommerce blog{{/link}} for more tips on marketing your store",'woocommerce'),components:{link:Object(L.createElement)(a.Link,{type:"external",href:"https://woocommerce.com/blog/marketing/coupons/",target:"_blank"})}})},E=function(M){var t,e,j=M.posts,N=M.isLoading,i=M.error,g=M.title,D=M.description,I=M.category,A=Object(L.useState)(1),o=u()(A,2),O=o[0],E=o[1],l=Object(L.useState)(null),s=u()(l,2),C=s[0],w=s[1],x=function(M){var t;M>O?(t="left",Object(y.recordEvent)("marketing_knowledge_carousel",{direction:"forward",page:M})):(t="right",Object(y.recordEvent)("marketing_knowledge_carousel",{direction:"back",page:M})),E(M),w(t)},m=function(){var M=j.slice(2*(O-1),2*(O-1)+2),t=n()("woocommerce-marketing-knowledgebase-card__page",{"page-with-single-post":1===M.length}),e=M.map((function(M,t){return Object(L.createElement)("a",{className:"woocommerce-marketing-knowledgebase-card__post",href:M.link,key:t,onClick:function(){!function(M){Object(y.recordEvent)("marketing_knowledge_article",{title:M.title})}(M)},target:"_blank",rel:"noopener noreferrer"},M.image&&Object(L.createElement)("div",{className:"woocommerce-marketing-knowledgebase-card__post-img"},Object(L.createElement)("img",{src:M.image,alt:""})),Object(L.createElement)("div",{className:"woocommerce-marketing-knowledgebase-card__post-text"},Object(L.createElement)("h3",null,M.title),Object(L.createElement)("p",{className:"woocommerce-marketing-knowledgebase-card__post-meta"},"By ",M.author_name,M.author_avatar&&Object(L.createElement)("img",{src:M.author_avatar.replace("s=96","s=32"),className:"woocommerce-gravatar",alt:"",width:"16",height:"16"}))))}));return Object(L.createElement)("div",{className:t},e)},d=I?"woocommerce-marketing-knowledgebase-card__category-".concat(I):"";return Object(L.createElement)(T.a,{title:g,description:D,className:n()("woocommerce-marketing-knowledgebase-card",d)},N?Object(L.createElement)(r.a,null):i?(t=Object(c.__)("Oops, our posts aren't loading right now",'woocommerce'),Object(L.createElement)(a.EmptyContent,{title:t,message:Object(L.createElement)(S,null),illustration:"",actionLabel:""})):0===j.length?(e=Object(c.__)("No posts yet",'woocommerce'),Object(L.createElement)(a.EmptyContent,{title:e,message:Object(L.createElement)(S,null),illustration:"",actionLabel:""})):Object(L.createElement)("div",{className:"woocommerce-marketing-knowledgebase-card__posts"},Object(L.createElement)(z.c,{animationKey:O,animate:C},m()),Object(L.createElement)(a.Pagination,{page:O,perPage:2,total:j.length,onPageChange:x,showPagePicker:!1,showPerPagePicker:!1,showPageArrowsLabel:!1})))};E.propTypes={posts:I.a.arrayOf(I.a.object).isRequired,isLoading:I.a.bool.isRequired,title:I.a.string,description:I.a.string,category:I.a.string},E.defaultProps={title:Object(c.__)("WooCommerce knowledge base",'woocommerce'),description:Object(c.__)("Learn the ins and outs of successful marketing from the experts at WooCommerce.",'woocommerce')};t.a=Object(N.a)(Object(g.withSelect)((function(M,t){var e=M(A.b),j=e.getBlogPosts,u=e.getBlogPostsError,L=e.isResolving;return{posts:j(t.category),isLoading:L("getBlogPosts",[t.category]),error:u(t.category)}})),Object(g.withDispatch)((function(M){return{createNotice:M("core/notices").createNotice}})))(E)},551:function(M,t,e){},552:function(M,t,e){},553:function(M,t,e){},554:function(M,t,e){},555:function(M,t,e){},556:function(M,t,e){"use strict";var j={};e.r(j),e.d(j,"receiveInstalledPlugins",(function(){return y})),e.d(j,"receiveActivatingPlugin",(function(){return z})),e.d(j,"removeActivatingPlugin",(function(){return A})),e.d(j,"receiveRecommendedPlugins",(function(){return T})),e.d(j,"receiveBlogPosts",(function(){return o})),e.d(j,"handleFetchError",(function(){return O})),e.d(j,"setError",(function(){return S})),e.d(j,"activateInstalledPlugin",(function(){return E})),e.d(j,"loadInstalledPluginsAfterActivation",(function(){return l}));var u={};e.r(u),e.d(u,"getInstalledPlugins",(function(){return s})),e.d(u,"getActivatingPlugins",(function(){return C})),e.d(u,"getRecommendedPlugins",(function(){return w})),e.d(u,"getBlogPosts",(function(){return x})),e.d(u,"getBlogPostsError",(function(){return m}));var L={};e.r(L),e.d(L,"getRecommendedPlugins",(function(){return Y})),e.d(L,"getBlogPosts",(function(){return Q}));var N=e(29),c=e(20),i=e(113),n=e(14),r=e.n(n),g=e(3),D={SET_INSTALLED_PLUGINS:"SET_INSTALLED_PLUGINS",SET_ACTIVATING_PLUGIN:"SET_ACTIVATING_PLUGIN",REMOVE_ACTIVATING_PLUGIN:"REMOVE_ACTIVATING_PLUGIN",SET_RECOMMENDED_PLUGINS:"SET_RECOMMENDED_PLUGINS",SET_BLOG_POSTS:"SET_BLOG_POSTS",SET_ERROR:"SET_ERROR"},I=r.a.mark(E),a=r.a.mark(l);function y(M){return{type:D.SET_INSTALLED_PLUGINS,plugins:M}}function z(M){return{type:D.SET_ACTIVATING_PLUGIN,pluginSlug:M}}function A(M){return{type:D.REMOVE_ACTIVATING_PLUGIN,pluginSlug:M}}function T(M,t){return{type:D.SET_RECOMMENDED_PLUGINS,data:{plugins:M,category:t}}}function o(M,t){return{type:D.SET_BLOG_POSTS,data:{posts:M,category:t}}}function O(M,t){(0,Object(c.dispatch)("core/notices").createNotice)("error",t),console.log(M)}function S(M,t){return{type:D.SET_ERROR,category:M,error:t}}function E(M){var t,e;return r.a.wrap((function(j){for(;;)switch(j.prev=j.next){case 0:return t=Object(c.dispatch)("core/notices"),e=t.createNotice,j.next=3,z(M);case 3:return j.prev=3,j.next=6,Object(N.apiFetch)({path:i.a+"/overview/activate-plugin",method:"POST",data:{plugin:M}});case 6:if(!j.sent){j.next=14;break}return j.next=10,e("success",Object(g.__)("The extension has been successfully activated.",'woocommerce'));case 10:return j.next=12,l(M);case 12:j.next=15;break;case 14:throw new Error;case 15:j.next=23;break;case 17:return j.prev=17,j.t0=j.catch(3),j.next=21,O(j.t0,Object(g.__)("There was an error trying to activate the extension.",'woocommerce'));case 21:return j.next=23,A(M);case 23:return j.abrupt("return",!0);case 24:case"end":return j.stop()}}),I,null,[[3,17]])}function l(M){var t;return r.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,Object(N.apiFetch)({path:"".concat(i.a,"/overview/installed-plugins")});case 3:if(!(t=e.sent)){e.next=11;break}return e.next=7,y(t);case 7:return e.next=9,A(M);case 9:e.next=12;break;case 11:throw new Error;case 12:e.next=18;break;case 14:return e.prev=14,e.t0=e.catch(0),e.next=18,O(e.t0,Object(g.__)("There was an error loading installed extensions.",'woocommerce'));case 18:case"end":return e.stop()}}),a,null,[[0,14]])}function s(M){return M.installedPlugins}function C(M){return M.activatingPlugins}function w(M,t){return M.recommendedPlugins[t]||[]}function x(M,t){return M.blogPosts[t]||[]}function m(M,t){return M.errors.blogPosts&&M.errors.blogPosts[t]}var d=r.a.mark(Y),k=r.a.mark(Q);function Y(M){var t,e;return r.a.wrap((function(j){for(;;)switch(j.prev=j.next){case 0:return j.prev=0,j.next=3,M?"&category=".concat(M):"";case 3:return t=j.sent,j.next=6,Object(N.apiFetch)({path:"".concat(i.a,"/recommended?per_page=6").concat(t)});case 6:if(!(e=j.sent)){j.next=12;break}return j.next=10,T(e,M);case 10:j.next=13;break;case 12:throw new Error;case 13:j.next=19;break;case 15:return j.prev=15,j.t0=j.catch(0),j.next=19,O(j.t0,Object(g.__)("There was an error loading recommended extensions.",'woocommerce'));case 19:case"end":return j.stop()}}),d,null,[[0,15]])}function Q(M){var t,e;return r.a.wrap((function(j){for(;;)switch(j.prev=j.next){case 0:return j.prev=0,j.next=3,M?"?category=".concat(M):"";case 3:return t=j.sent,j.next=6,Object(N.apiFetch)({path:"".concat(i.a,"/knowledge-base").concat(t),method:"GET"});case 6:if(!(e=j.sent)){j.next=12;break}return j.next=10,o(e,M);case 10:j.next=13;break;case 12:throw new Error;case 13:j.next=19;break;case 15:return j.prev=15,j.t0=j.catch(0),j.next=19,S(M,j.t0);case 19:case"end":return j.stop()}}),k,null,[[0,15]])}var U=e(30),b=e.n(U),h=e(5),f=e.n(h),p=e(36),v=e(2);function P(M,t){var e=Object.keys(M);if(Object.getOwnPropertySymbols){var j=Object.getOwnPropertySymbols(M);t&&(j=j.filter((function(t){return Object.getOwnPropertyDescriptor(M,t).enumerable}))),e.push.apply(e,j)}return e}function G(M){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:_,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case D.SET_INSTALLED_PLUGINS:return G(G({},M),{},{installedPlugins:t.plugins});case D.SET_ACTIVATING_PLUGIN:return G(G({},M),{},{activatingPlugins:[].concat(b()(M.activatingPlugins),[t.pluginSlug])});case D.REMOVE_ACTIVATING_PLUGIN:return G(G({},M),{},{activatingPlugins:Object(v.without)(M.activatingPlugins,t.pluginSlug)});case D.SET_RECOMMENDED_PLUGINS:return G(G({},M),{},{recommendedPlugins:G(G({},M.recommendedPlugins),{},f()({},t.data.category,t.data.plugins))});case D.SET_BLOG_POSTS:return G(G({},M),{},{blogPosts:G(G({},M.blogPosts),{},f()({},t.data.category,t.data.posts))});case D.SET_ERROR:return G(G({},M),{},{errors:G(G({},M.errors),{},{blogPosts:G(G({},M.errors.blogPosts),{},f()({},t.category,t.error))})});default:return M}};Object(c.registerStore)(i.b,{actions:j,selectors:u,resolvers:L,controls:N.controls,reducer:R})},558:function(M,t,e){"use strict";var j=e(7),u=e(8),L=e(12),N=e(0),c=e(4),i=e.n(c),n=e(193),r=e(192);function g(M,t){var e=Object.keys(M);if(Object.getOwnPropertySymbols){var j=Object.getOwnPropertySymbols(M);t&&(j=j.filter((function(t){return Object.getOwnPropertyDescriptor(M,t).enumerable}))),e.push.apply(e,j)}return e}function D(M){for(var t=1;t1){var i;(i=r.filter((function(e){return n.test(e.key)}))).length>0&&(r=i)}if(r.length>1){var l;1===(l=r.filter((function(e){return a.test(e.key)}))).length&&(r=l)}}1===r.length&&t!==r[0].key&&c("countryState",r[0].key)}),[o,C,t,e,c]),Object(s.createElement)(s.Fragment,null,Object(s.createElement)("input",{onChange:function(e){return i(e.target.value)},value:o,name:"country",type:"text",className:"woocommerce-select-control__autofill-input",tabIndex:"-1",autoComplete:"country"}),Object(s.createElement)("input",{onChange:function(e){return p(e.target.value)},value:C,name:"state",type:"text",className:"woocommerce-select-control__autofill-input",tabIndex:"-1",autoComplete:"address-level1"}))}(r,t("countryState").value,c);return Object(s.createElement)("div",{className:"woocommerce-store-address-fields"},Object(s.createElement)(d.TextControl,n()({label:Object(m.__)("Address line 1",'woocommerce'),required:!0,autoComplete:"address-line1"},t("addressLine1"))),Object(s.createElement)(d.TextControl,n()({label:Object(m.__)("Address line 2 (optional)",'woocommerce'),required:!0,autoComplete:"address-line2"},t("addressLine2"))),Object(s.createElement)(d.SelectControl,n()({label:Object(m.__)("Country / Region",'woocommerce'),required:!0,options:r,excludeSelectedOptions:!1,showAllOnFocus:!0,isSearchable:!0},t("countryState"),{controlClassName:t("countryState").className}),o),Object(s.createElement)(d.TextControl,n()({label:Object(m.__)("City",'woocommerce'),required:!0},t("city"),{autoComplete:"address-level2"})),Object(s.createElement)(d.TextControl,n()({label:Object(m.__)("Post code",'woocommerce'),required:!0,autoComplete:"postal-code"},t("postCode"))))}},822:function(e,t,c){},823:function(e,t,c){},824:function(e,t,c){},826:function(e,t,c){},848:function(e,t,c){"use strict";c.r(t);var r=c(5),n=c.n(r),o=c(14),a=c.n(o),i=c(98),l=c.n(i),s=c(17),m=c.n(s),C=c(15),u=c.n(C),p=c(11),d=c.n(p),b=c(18),f=c.n(b),h=c(19),O=c.n(h),_=c(9),j=c.n(_),g=c(3),E=c(0),v=c(277),y=c(2),w=c(20),k=c(32),L=c(35),S=c(64),M=c(36),N=c(190),P=c(72),Z=c(42),V=c.n(Z),T=c(77),x=c(776);function H(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var c,r=j()(e);if(t){var n=j()(this).constructor;c=Reflect.construct(r,arguments,n)}else c=r.apply(this,arguments);return O()(this,c)}}var I=function(e){f()(c,e);var t=H(c);function c(){return m()(this,c),t.apply(this,arguments)}return u()(c,[{key:"render",value:function(){return Object(E.createElement)("svg",{width:"161",height:"46",viewBox:"0 0 161 46",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-label":Object(g.__)("WooCommerce + Jetpack",'woocommerce'),className:"woocommerce-profile-wizard__benefits-logo"},Object(E.createElement)("path",{d:"M139.071 45.4503C150.906 45.4503 160.5 35.7679 160.5 23.824C160.5 11.8802 150.906 2.19775 139.071 2.19775C127.236 2.19775 117.642 11.8802 117.642 23.824C117.642 35.7679 127.236 45.4503 139.071 45.4503Z",fill:"#008710"}),Object(E.createElement)("path",{d:"M140.134 20.1919V41.1578L150.849 20.1919H140.134Z",fill:"#F6F7F7"}),Object(E.createElement)("path",{d:"M137.967 27.4144V6.48975L127.293 27.4144H137.967Z",fill:"#F6F7F7"}),Object(E.createElement)("path",{d:"M95.7021 24.668H100.542V21.6445H95.7021V16.8633H92.7138V21.6445H87.8857V24.668H92.7138V29.4609H95.7021V24.668Z",fill:"#2C3338"}),Object(E.createElement)("g",{clipPath:"url(#clip0)"},Object(E.createElement)("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M7.52123 2.25732H66.5046C70.2374 2.25732 73.2591 5.27907 73.2591 9.01182V31.5268C73.2591 35.2596 70.2374 38.2813 66.5046 38.2813H45.3524L48.2556 45.3913L35.4872 38.2813H7.55086C3.81811 38.2813 0.796359 35.2596 0.796359 31.5268V9.01182C0.766734 5.3087 3.78848 2.25732 7.52123 2.25732Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M4.41042 8.38982C4.82517 7.82695 5.4473 7.5307 6.2768 7.47145C7.78767 7.35295 8.6468 8.06395 8.85417 9.60445C9.77255 15.7961 10.7798 21.0397 11.8463 25.3353L18.3342 12.9817C18.9267 11.8559 19.6673 11.2634 20.5561 11.2042C21.8596 11.1153 22.6594 11.9448 22.9853 13.6927C23.7259 17.6328 24.6739 20.9805 25.7997 23.8245C26.5699 16.2997 27.8734 10.8783 29.7102 7.5307C30.1546 6.7012 30.8063 6.28645 31.6654 6.2272C32.3468 6.16795 32.9689 6.37533 33.5318 6.8197C34.0947 7.26408 34.3909 7.82695 34.4502 8.50832C34.4798 9.04157 34.3909 9.48595 34.1539 9.93033C32.9986 12.0633 32.0506 15.648 31.2803 20.625C30.5397 25.4538 30.2731 29.2162 30.4508 31.9121C30.5101 32.6527 30.3916 33.3045 30.0953 33.8673C29.7398 34.5191 29.2066 34.8746 28.5252 34.9338C27.7549 34.9931 26.955 34.6376 26.1848 33.8377C23.4297 31.0233 21.2374 26.8166 19.6377 21.2175C17.7121 25.0095 16.29 27.8535 15.3717 29.7495C13.6238 33.0971 12.1426 34.8153 10.8983 34.9042C10.0984 34.9635 9.41705 34.2821 8.82455 32.8601C7.31368 28.9792 5.6843 21.4841 3.93643 10.3747C3.84755 9.60445 3.99567 8.92307 4.41042 8.38982Z",fill:"#F6F7F7"}),Object(E.createElement)("path",{d:"M68.1043 13.041C67.0378 11.1746 65.4677 10.0489 63.3643 9.60451C62.8015 9.48601 62.2682 9.42676 61.7646 9.42676C58.9206 9.42676 56.6098 10.908 54.8027 13.8705C53.2622 16.3886 52.4919 19.1734 52.4919 22.2248C52.4919 24.5059 52.9659 26.4611 53.9139 28.0905C54.9804 29.9569 56.5506 31.0826 58.6539 31.527C59.2168 31.6455 59.7501 31.7048 60.2537 31.7048C63.1273 31.7048 65.4381 30.2235 67.2156 27.261C68.7561 24.7133 69.5263 21.9285 69.5263 18.8771C69.5263 16.5664 69.0523 14.6408 68.1043 13.041ZM64.3716 21.2471C63.9568 23.2024 63.2162 24.654 62.1201 25.6316C61.2609 26.4019 60.4611 26.7278 59.7204 26.5796C59.0094 26.4315 58.4169 25.8094 57.9726 24.654C57.6171 23.7356 57.4393 22.8173 57.4393 21.9581C57.4393 21.2175 57.4986 20.4769 57.6467 19.7955C57.9133 18.5809 58.417 17.3959 59.2168 16.2701C60.1945 14.8185 61.2313 14.226 62.2978 14.4334C63.0088 14.5815 63.6013 15.2036 64.0457 16.359C64.4012 17.2774 64.5789 18.1958 64.5789 19.0549C64.5789 19.8251 64.4901 20.5658 64.3716 21.2471Z",fill:"#F6F7F7"}),Object(E.createElement)("path",{d:"M49.5294 13.041C48.4629 11.1746 46.8631 10.0489 44.7894 9.60451C44.2265 9.48601 43.6932 9.42676 43.1896 9.42676C40.3456 9.42676 38.0349 10.908 36.2277 13.8705C34.6872 16.3886 33.917 19.1734 33.917 22.2248C33.917 24.5059 34.391 26.4611 35.339 28.0905C36.4055 29.9569 37.9756 31.0826 40.079 31.527C40.6419 31.6455 41.1751 31.7048 41.6787 31.7048C44.5524 31.7048 46.8631 30.2235 48.6406 27.261C50.1811 24.7133 50.9514 21.9285 50.9514 18.8771C50.9514 16.5664 50.4774 14.6408 49.5294 13.041ZM45.7966 21.2471C45.3819 23.2024 44.6412 24.654 43.5451 25.6316C42.686 26.4019 41.8861 26.7278 41.1455 26.5796C40.4345 26.4315 39.842 25.8094 39.3976 24.654C39.0421 23.7356 38.8644 22.8173 38.8644 21.9581C38.8644 21.2175 38.9236 20.4769 39.0717 19.7955C39.3384 18.5809 39.842 17.3959 40.6419 16.2701C41.6195 14.8185 42.6564 14.226 43.7229 14.4334C44.4339 14.5815 45.0264 15.2036 45.4707 16.359C45.8262 17.2774 46.004 18.1958 46.004 19.0549C46.004 19.8251 45.9447 20.5658 45.7966 21.2471Z",fill:"#F6F7F7"})),Object(E.createElement)("defs",null,Object(E.createElement)("clipPath",{id:"clip0"},Object(E.createElement)("rect",{x:"0.5",y:"2.19775",width:"72.8775",height:"43.2525",fill:"white"}))))}}]),c}(E.Component),R=function(){return Object(E.createElement)("svg",{width:"295",height:"160",viewBox:"0 0 295 160",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(E.createElement)("g",{clipPath:"url(#management-svg)"},Object(E.createElement)("path",{d:"M0 6C0 2.6863 2.68629 0 6 0H289C292.314 0 295 2.68629 295 6V160H0V6Z",fill:"#F7EDF7"}),Object(E.createElement)("path",{opacity:"0.05",d:"M268 125.429L188.122 25.6443C184.495 28.9602 180.026 31.2158 175.204 32.165C160.166 35.1256 145.48 24.8598 142.402 9.23575C140.226 -1.80872 144.438 -12.5683 152.403 -18.9762L125.167 -53L-30 79.5708L112.833 258L268 125.429Z",fill:"#7F54B3"}),Object(E.createElement)("path",{opacity:"0.05",d:"M169 27C181.703 27 192 16.9264 192 4.5C192 -7.9264 181.703 -18 169 -18C156.297 -18 146 -7.9264 146 4.5C146 16.9264 156.297 27 169 27Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M84.0826 16.6412H147.092C150.132 16.6411 153.082 17.6756 155.457 19.5743C157.832 21.4731 159.489 24.1232 160.158 27.0891L191.995 168.296C192.343 169.836 192.349 171.434 192.013 172.977C191.678 174.52 191.009 175.97 190.054 177.227C189.098 178.484 187.879 179.517 186.482 180.253C185.086 180.989 183.545 181.411 181.968 181.489L117.194 184.68C113.725 184.851 110.313 183.754 107.594 181.594C104.875 179.434 103.035 176.359 102.417 172.942L84.3566 73.107L83.013 73.4908L79.5574 54.5684L80.9405 54.2226L75.8993 26.3551C75.6834 25.1615 75.7334 23.9349 76.0459 22.7629C76.3584 21.5908 76.9257 20.5021 77.7072 19.5744C78.4887 18.6467 79.4653 17.9029 80.5673 17.3958C81.6693 16.8888 82.8696 16.6311 84.0826 16.6412Z",fill:"white"}),Object(E.createElement)("path",{d:"M138.797 19.6853H146.152C148.264 19.6853 150.313 20.4076 151.958 21.7324C153.603 23.0572 154.745 24.9047 155.195 26.9683L185.755 167.023C185.931 167.83 185.931 168.665 185.754 169.471C185.578 170.277 185.23 171.036 184.733 171.695C184.237 172.355 183.604 172.899 182.878 173.292C182.152 173.684 181.35 173.915 180.526 173.969L115.962 178.2C114.14 178.32 112.339 177.764 110.901 176.64C109.463 175.516 108.489 173.901 108.165 172.105L82.0889 27.3445C81.9201 26.4075 81.959 25.4449 82.2029 24.5247C82.4468 23.6044 82.8897 22.7489 83.5003 22.0185C84.111 21.288 84.8745 20.7005 85.737 20.2974C86.5995 19.8942 87.54 19.6853 88.4921 19.6853H95.4695C96.1448 19.6853 96.8013 19.9079 97.3373 20.3187C97.8734 20.7294 98.259 21.3054 98.4346 21.9575C98.5895 22.5331 98.93 23.0416 99.4032 23.4043C99.8764 23.7669 100.456 23.9634 101.052 23.9634H134.176C135.344 23.9634 136.468 23.5228 137.325 22.7296C138.181 21.9365 138.707 20.8492 138.797 19.6853L138.797 19.6853Z",fill:"#F6F7F7"}),Object(E.createElement)("path",{d:"M159.366 55.8843H92.5569V56.2134H159.366V55.8843Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M161.999 66.5796H94.532V66.9087H161.999V66.5796Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M96.7759 55.3634L98.294 53.3396L98.0308 53.1421L96.7189 54.8913L91.6633 50.7551L91.4551 51.0102L96.7759 55.3634Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M105.498 103.081L107.016 101.057L106.752 100.86L105.44 102.609L100.385 98.4729L100.177 98.7277L105.498 103.081Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M169.4 103.109L99.4648 104.59L99.4718 104.919L169.407 103.438L169.4 103.109Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M171.539 112.816L100.287 114.462L100.295 114.791L171.547 113.146L171.539 112.816Z",fill:"#2F2E41"}),Object(E.createElement)("path",{opacity:"0.1",d:"M127.854 140.871C127.854 145.017 129.501 148.993 132.433 151.924C135.364 154.856 139.341 156.503 143.487 156.503C147.633 156.503 151.609 154.856 154.54 151.924C157.472 148.993 159.119 145.017 159.119 140.871C159.119 140.675 159.116 140.481 159.108 140.287C158.955 136.195 157.202 132.326 154.226 129.512C151.25 126.699 147.289 125.166 143.194 125.242C139.099 125.319 135.198 126.999 132.33 129.922C129.461 132.844 127.854 136.776 127.854 140.871H127.854Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M129.335 146.96C129.335 147.155 129.338 147.349 129.346 147.544C130.863 150.756 133.428 153.355 136.619 154.915C139.81 156.475 143.438 156.901 146.904 156.125C150.37 155.348 153.468 153.414 155.688 150.642C157.908 147.869 159.118 144.423 159.119 140.871C159.119 140.676 159.116 140.481 159.107 140.287C157.591 137.075 155.026 134.476 151.835 132.916C148.643 131.356 145.016 130.93 141.55 131.706C138.084 132.483 134.986 134.417 132.765 137.189C130.545 139.962 129.335 143.408 129.335 146.96H129.335Z",fill:"black"}),Object(E.createElement)("path",{d:"M224.461 59.1491C229.783 59.1491 234.098 54.8348 234.098 49.513C234.098 44.1912 229.783 39.877 224.461 39.877C219.139 39.877 214.824 44.1912 214.824 49.513C214.824 54.8348 219.139 59.1491 224.461 59.1491Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M236.166 86.9957C236.166 86.9957 235.643 98.2553 235.119 99.0408C234.595 99.8264 229.881 111.086 229.881 111.086L227.525 103.754C227.525 103.754 231.191 97.7316 230.667 94.3275C230.143 90.9235 230.473 86.7346 230.473 86.7346L236.166 86.9957Z",fill:"#9F616A"}),Object(E.createElement)("path",{d:"M221.24 59.7637C225.29 59.7637 228.572 56.4811 228.572 52.4319C228.572 48.3827 225.29 45.1001 221.24 45.1001C217.191 45.1001 213.908 48.3827 213.908 52.4319C213.908 56.4811 217.191 59.7637 221.24 59.7637Z",fill:"#9F616A"}),Object(E.createElement)("path",{d:"M227.263 53.217C227.263 53.217 227.001 63.691 228.834 65.2621C230.667 66.8332 218.359 65.524 218.359 65.524C218.359 65.524 220.978 58.1922 218.883 56.6211C216.788 55.05 227.263 53.217 227.263 53.217Z",fill:"#9F616A"}),Object(E.createElement)("path",{d:"M217.574 65.0008C217.574 65.0008 219.145 62.1205 221.24 62.3823C223.335 62.6442 230.144 63.1679 230.406 63.6916C230.667 64.2153 231.453 66.0482 231.977 66.5719C232.501 67.0956 236.429 67.8812 236.69 71.0234C236.952 74.1656 227.263 93.2806 227.263 93.2806C227.263 93.2806 228.573 97.732 228.311 98.7794C228.049 99.8268 229.62 102.969 229.358 104.278C229.096 105.588 233.286 113.443 231.191 123.655V140.152C231.191 140.152 238.262 168.693 236.167 170.788C234.072 172.883 227.001 171.574 225.692 170.788C224.383 170.003 218.884 130.463 218.884 130.463L216.265 117.109L216.003 146.436C216.003 146.436 216.527 171.05 214.694 171.836C212.861 172.621 205.79 172.883 205.266 171.312C204.858 170.087 202.857 137.484 201.996 123.193C201.697 118.26 202.085 113.309 203.149 108.483C204.238 103.54 205.821 97.7324 207.623 95.3754C211.028 90.9239 213.122 76.7841 213.122 76.7841L208.671 68.6667C208.671 68.6667 211.289 66.0482 212.861 66.0482C214.432 66.0482 217.574 65.0008 217.574 65.0008Z",fill:"#444053"}),Object(E.createElement)("path",{d:"M235.119 69.1902L236.5 70.1301C236.5 70.1301 237.476 86.996 236.69 88.0434C235.904 89.0908 230.443 88.5796 230.031 87.6569C229.62 86.7341 235.119 69.1902 235.119 69.1902Z",fill:"#444053"}),Object(E.createElement)("path",{d:"M211.767 84.5249C212.533 89.8422 213.205 94.5756 209.286 98.8578C205.347 103.192 200.904 107.039 196.053 110.319C195.572 111.593 188.515 120.943 188.156 117.213C187.797 113.484 190.235 110.56 193.7 107.406C197.165 104.252 202.012 97.4081 204.747 93.6531C207.482 89.898 206.356 87.5565 206.261 84.42C206.166 81.2835 210.691 84.5628 211.767 84.5249Z",fill:"#9F616A"}),Object(E.createElement)("path",{d:"M212.337 67.8806L208.671 68.6662C208.671 68.6662 208.671 74.4269 207.623 76.7835C206.576 79.1402 204.743 84.639 205.528 84.9008C206.314 85.1627 213.646 88.8286 214.17 86.7338C214.694 84.639 216.003 67.8806 212.337 67.8806Z",fill:"#444053"}),Object(E.createElement)("path",{d:"M234.901 46.4615C240.223 46.4615 244.537 42.1473 244.537 36.8255C244.537 31.5037 240.223 27.1895 234.901 27.1895C229.579 27.1895 225.264 31.5037 225.264 36.8255C225.264 42.1473 229.579 46.4615 234.901 46.4615Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M243.213 44.8046C241.966 45.706 240.521 46.2957 238.999 46.5242C237.477 46.7527 235.922 46.6134 234.465 46.118C233.008 45.6226 231.691 44.7855 230.624 43.6767C229.557 42.5679 228.771 41.2197 228.331 39.7449C228.498 41.0666 228.936 42.3395 229.619 43.4832C230.302 44.6269 231.215 45.6166 232.3 46.3898C233.384 47.163 234.618 47.7029 235.922 47.9754C237.226 48.2479 238.572 48.2471 239.876 47.973C241.18 47.699 242.412 47.1576 243.496 46.3831C244.58 45.6087 245.492 44.6179 246.173 43.4734C246.855 42.3288 247.292 41.0554 247.456 39.7335C247.621 38.4116 247.51 37.07 247.13 35.7932C247.346 37.5085 247.096 39.2503 246.407 40.8358C245.718 42.4214 244.614 43.7922 243.213 44.8046Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M227.031 58.1854C230.934 58.1854 234.098 55.0216 234.098 51.1189C234.098 47.2162 230.934 44.0525 227.031 44.0525C223.128 44.0525 219.964 47.2162 219.964 51.1189C219.964 55.0216 223.128 58.1854 227.031 58.1854Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M221.088 53.3669C224.548 53.3669 227.352 51.1739 227.352 48.4686C227.352 45.7634 224.548 43.5703 221.088 43.5703C217.629 43.5703 214.824 45.7634 214.824 48.4686C214.824 51.1739 217.629 53.3669 221.088 53.3669Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M219.417 55.5916C220.074 55.5916 220.606 54.65 220.606 53.4884C220.606 52.3269 220.074 51.3853 219.417 51.3853C218.761 51.3853 218.229 52.3269 218.229 53.4884C218.229 54.65 218.761 55.5916 219.417 55.5916Z",fill:"#A0616A"})),Object(E.createElement)("defs",null,Object(E.createElement)("clipPath",{id:"management-svg"},Object(E.createElement)("path",{d:"M0 6C0 2.6863 2.68629 0 6 0H289C292.314 0 295 2.68629 295 6V160H0V6Z",fill:"white"}))))},A=function(){return Object(E.createElement)("svg",{width:"295",height:"160",viewBox:"0 0 295 160",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(E.createElement)("g",{clipPath:"url(#sales-tax-svg)"},Object(E.createElement)("path",{d:"M0 6C0 2.6863 2.68629 0 6 0H289C292.314 0 295 2.68629 295 6V160H0V6Z",fill:"#F7EDF7"}),Object(E.createElement)("path",{opacity:"0.05",d:"M164.773 36.3068C148.909 35.7553 133.8 30.6347 119.37 25.0313C104.94 19.4279 90.6516 13.2214 75.1674 10.2506C65.2082 8.34111 53.82 8.07148 45.7947 13.4102C38.0735 18.5577 35.5782 27.4188 34.2349 35.6499C33.2275 41.8416 32.6343 48.3594 35.3992 54.1564C37.3185 58.1813 40.7281 61.564 43.0862 65.4172C51.2879 78.8302 45.4908 95.3807 36.6052 108.468C32.4382 114.613 27.5995 120.478 24.3811 127.013C21.1627 133.548 19.6748 141.046 22.4888 147.719C25.2807 154.337 31.9308 159.298 39.1348 162.791C53.7636 169.9 71.0004 171.917 87.8181 173.066C125.032 175.613 162.447 174.51 199.759 173.407C213.569 172.998 227.438 172.584 241.025 170.449C248.568 169.265 256.357 167.382 261.833 162.85C268.785 157.082 270.508 147.317 265.851 140.083C258.037 127.952 236.437 124.94 230.968 111.921C227.96 104.754 231.049 96.7729 235.417 90.1253C244.79 75.8691 260.5 63.3607 261.328 47.0651C261.897 35.873 254.345 24.6636 242.668 19.3666C230.426 13.8171 213.454 14.5157 204.429 23.7028C195.119 33.1521 178.775 36.7971 164.773 36.3068Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M98.0173 58.1228C98.0173 58.1228 104.812 49.2691 108.518 49.9554C108.518 49.9554 104.4 57.8483 98.0173 59.0248V58.1228Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M101.445 47.2146C101.445 47.2146 107.45 40.4248 110.693 40.4419C110.693 40.4419 105.952 49.5113 101.197 49.428L101.445 47.2146Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M103.474 39.9447L109.273 25.8037C109.273 25.8037 109.565 38.5867 102.736 42.5674L103.474 39.9447Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M101.922 48.1023C101.922 48.1023 101.9 39.0329 99.4566 36.9077C99.4566 36.9077 97.0225 46.8424 100.645 49.9285L101.922 48.1023Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M198.534 25.4629H97.6055C96.2789 25.4629 95.2034 26.5384 95.2034 27.8651V180.276C95.2034 181.602 96.2789 182.678 97.6055 182.678H198.534C199.86 182.678 200.936 181.602 200.936 180.276V27.8651C200.936 26.5384 199.86 25.4629 198.534 25.4629Z",fill:"white"}),Object(E.createElement)("path",{opacity:"0.1",d:"M185.408 38.9763H112.041C108.086 38.9763 104.881 42.1819 104.881 46.1363V62.7235C104.881 66.6778 108.086 69.8835 112.041 69.8835H185.408C189.362 69.8835 192.567 66.6778 192.567 62.7235V46.1363C192.567 42.1819 189.362 38.9763 185.408 38.9763Z",fill:"black"}),Object(E.createElement)("path",{d:"M189.303 39.5791H107.945C106.564 39.5791 105.445 40.6985 105.445 42.0793V66.9712C105.445 68.3521 106.564 69.4715 107.945 69.4715H189.303C190.683 69.4715 191.803 68.3521 191.803 66.9712V42.0793C191.803 40.6985 190.683 39.5791 189.303 39.5791Z",fill:"#E6E8EC"}),Object(E.createElement)("path",{opacity:"0.1",d:"M122.728 82.7573H110.58C109.119 82.7573 107.935 83.9415 107.935 85.4022V99.4867C107.935 100.947 109.119 102.132 110.58 102.132H122.728C124.189 102.132 125.373 100.947 125.373 99.4867V85.4022C125.373 83.9415 124.189 82.7573 122.728 82.7573Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M144.041 82.7573H131.893C130.432 82.7573 129.248 83.9415 129.248 85.4022V99.4867C129.248 100.947 130.432 102.132 131.893 102.132H144.041C145.502 102.132 146.686 100.947 146.686 99.4867V85.4022C146.686 83.9415 145.502 82.7573 144.041 82.7573Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M165.354 82.7573H153.206C151.745 82.7573 150.561 83.9415 150.561 85.4022V99.4867C150.561 100.947 151.745 102.132 153.206 102.132H165.354C166.815 102.132 167.999 100.947 167.999 99.4867V85.4022C167.999 83.9415 166.815 82.7573 165.354 82.7573Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M182.243 83.1694H178.944C175.04 83.1694 171.875 86.3344 171.875 90.2387V95.4745C171.875 99.3787 175.04 102.544 178.944 102.544H182.243C186.147 102.544 189.312 99.3787 189.312 95.4745V90.2387C189.312 86.3344 186.147 83.1694 182.243 83.1694Z",fill:"black"}),Object(E.createElement)("path",{d:"M186.667 82.7573H174.519C173.059 82.7573 171.875 83.9415 171.875 85.4022V99.4867C171.875 100.947 173.059 102.132 174.519 102.132H186.667C188.128 102.132 189.312 100.947 189.312 99.4867V85.4022C189.312 83.9415 188.128 82.7573 186.667 82.7573Z",fill:"#646970"}),Object(E.createElement)("path",{opacity:"0.1",d:"M122.728 104.07H110.58C109.119 104.07 107.935 105.254 107.935 106.715V120.8C107.935 122.26 109.119 123.445 110.58 123.445H122.728C124.189 123.445 125.373 122.26 125.373 120.8V106.715C125.373 105.254 124.189 104.07 122.728 104.07Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M144.041 104.07H131.893C130.432 104.07 129.248 105.254 129.248 106.715V120.8C129.248 122.26 130.432 123.445 131.893 123.445H144.041C145.502 123.445 146.686 122.26 146.686 120.8V106.715C146.686 105.254 145.502 104.07 144.041 104.07Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M165.354 104.07H153.206C151.745 104.07 150.561 105.254 150.561 106.715V120.8C150.561 122.26 151.745 123.445 153.206 123.445H165.354C166.815 123.445 167.999 122.26 167.999 120.8V106.715C167.999 105.254 166.815 104.07 165.354 104.07Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M122.728 127.597H110.58C109.119 127.597 107.935 128.781 107.935 130.242V144.327C107.935 145.787 109.119 146.971 110.58 146.971H122.728C124.189 146.971 125.373 145.787 125.373 144.327V130.242C125.373 128.781 124.189 127.597 122.728 127.597Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M144.041 127.597H131.893C130.432 127.597 129.248 128.781 129.248 130.242V144.327C129.248 145.787 130.432 146.971 131.893 146.971H144.041C145.502 146.971 146.686 145.787 146.686 144.327V130.242C146.686 128.781 145.502 127.597 144.041 127.597Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M165.354 127.597H153.206C151.745 127.597 150.561 128.781 150.561 130.242V144.327C150.561 145.787 151.745 146.971 153.206 146.971H165.354C166.815 146.971 167.999 145.787 167.999 144.327V130.242C167.999 128.781 166.815 127.597 165.354 127.597Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M165.354 151.123H153.206C151.745 151.123 150.561 152.307 150.561 153.768V167.853C150.561 169.313 151.745 170.498 153.206 170.498H165.354C166.815 170.498 167.999 169.313 167.999 167.853V153.768C167.999 152.307 166.815 151.123 165.354 151.123Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M186.542 104.07H174.644C173.115 104.07 171.875 105.31 171.875 106.84V120.675C171.875 122.205 173.115 123.445 174.644 123.445H186.542C188.072 123.445 189.312 122.205 189.312 120.675V106.84C189.312 105.31 188.072 104.07 186.542 104.07Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M144.225 151.123H110.396C109.037 151.123 107.935 152.225 107.935 153.584V168.037C107.935 169.396 109.037 170.498 110.396 170.498H144.225C145.584 170.498 146.686 169.396 146.686 168.037V153.584C146.686 152.225 145.584 151.123 144.225 151.123Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M186.452 127.597H173.071C171.492 127.597 170.213 128.877 170.213 130.455V167.642C170.213 169.221 171.492 170.5 173.071 170.5H186.452C188.031 170.5 189.31 169.221 189.31 167.642V130.455C189.31 128.877 188.031 127.597 186.452 127.597Z",fill:"black"}),Object(E.createElement)("path",{d:"M187.925 64.251H180.292V65.077H187.925V64.251Z",fill:"#646970"}),Object(E.createElement)("path",{d:"M176.75 64.251H169.117V65.077H176.75V64.251Z",fill:"#646970"}),Object(E.createElement)("path",{d:"M165.572 64.251H157.939V65.077H165.572V64.251Z",fill:"#646970"}),Object(E.createElement)("path",{d:"M154.398 64.251H146.765V65.077H154.398V64.251Z",fill:"#646970"}),Object(E.createElement)("path",{d:"M236.67 122.236C237.456 119.589 236.67 116.941 236.67 116.941V114.444C236.67 114.444 237.569 109.561 233.554 106.428L230.892 104.08C230.892 104.08 229.399 102.798 228.965 102.717C228.885 102.7 228.803 102.687 228.72 102.68L228.642 102.634C228.413 102.242 228.218 101.832 228.058 101.408C228.231 101.43 228.406 101.413 228.57 101.357C228.735 101.301 228.884 101.208 229.007 101.085C229.103 100.974 229.179 100.847 229.23 100.71C229.385 100.364 229.412 99.9448 229.541 99.5771C229.655 99.2789 229.821 99.0034 230.032 98.7633C230.005 98.8074 229.975 98.8491 229.951 98.8956C230.328 98.425 230.821 98.023 231.176 97.5279C231.247 97.4297 231.312 97.3273 231.37 97.2215C231.355 97.2435 231.336 97.2631 231.319 97.2852C231.809 96.4984 231.958 95.5449 232.101 94.6257C232.169 94.3128 232.174 93.9894 232.115 93.6746C232.046 93.4657 231.958 93.2637 231.85 93.0716C231.272 91.8779 231.282 90.3753 230.358 89.4218C229.662 88.7085 228.608 88.4903 227.615 88.3678C226.622 88.2452 225.578 88.1741 224.725 87.6545C224.487 87.4739 224.223 87.3294 223.943 87.2255C223.802 87.1763 223.648 87.1778 223.508 87.2297C223.368 87.2816 223.251 87.3806 223.176 87.5098C223.158 87.5863 223.123 87.6577 223.073 87.7182C223.028 87.7434 222.979 87.7581 222.928 87.761C222.877 87.764 222.826 87.7552 222.779 87.7353L221.457 87.3824L221.472 87.4486H221.438L221.487 87.6569C221.513 87.6523 221.539 87.657 221.562 87.6699C221.585 87.6829 221.603 87.7034 221.612 87.728L221.399 88.0565C220.99 88.049 220.586 87.9659 220.207 87.8113C220.205 87.8325 220.205 87.8539 220.207 87.8751H220.188C220.163 88.2476 220.587 88.4903 220.717 88.8408C220.769 88.9942 220.769 89.1605 220.717 89.3139C220.664 89.4562 220.58 89.585 220.472 89.6914C220.004 90.1547 219.403 90.064 218.864 90.3557C218.817 90.3756 218.776 90.4054 218.742 90.4431C218.708 90.4808 218.683 90.5254 218.668 90.5738C218.647 90.61 218.64 90.6532 218.651 90.6939C218.672 90.7502 218.711 90.7983 218.761 90.8312C218.918 90.9581 219.09 91.0651 219.273 91.1499C219.219 91.1989 219.168 91.2479 219.119 91.2994C218.435 91.9949 217.933 92.8492 217.659 93.7859C217.386 94.7225 217.348 95.7124 217.551 96.667C217.753 97.6216 218.188 98.5113 218.818 99.2565C219.448 100.002 220.253 100.579 221.161 100.938C221.18 101.04 221.195 101.146 221.21 101.256C221.21 101.268 221.21 101.276 221.21 101.288L221.225 101.43L219.445 102.188C219.177 102.186 218.914 102.107 218.689 101.962C218.463 101.817 218.283 101.61 218.17 101.366C217.756 100.511 216.293 101.366 216.293 101.366C216.293 101.366 211.829 101.033 210.165 101.857C210.165 101.857 207.5 100.739 207.125 100.663C206.75 100.587 206.189 100.29 205.927 100.366C205.664 100.442 205.326 99.8761 205.137 99.9178C204.949 99.9595 204.875 99.5452 204.275 99.3957C203.674 99.2462 203.448 99.4349 202.774 98.7633C202.1 98.0917 196.619 95.4444 196.619 95.4444L194.158 93.4197L191.533 91.3313L191.487 91.417C191.469 91.3558 191.452 91.292 191.435 91.2234C191.174 90.183 190.846 89.1604 190.455 88.1619C190.286 87.7574 190.21 87.2476 189.982 87.5172C189.842 87.679 189.604 87.3235 189.246 87.0833C189.17 87.0309 189.084 86.9961 188.993 86.9813C188.902 86.9666 188.809 86.9724 188.72 86.9982C188.631 87.024 188.55 87.0693 188.481 87.1307C188.412 87.192 188.358 87.268 188.322 87.353C186.278 90.5591 185.545 90.7846 186.729 91.9637C187.785 93.0103 188.486 93.9246 189.347 94.2139L189.45 94.2457C189.431 94.2506 189.412 94.2506 189.393 94.2457L194.384 100.212C194.384 100.212 197.985 103.345 200.463 104.35C202.941 105.355 202.75 105.656 202.75 105.656C202.75 105.656 210.255 109.458 211.417 109.384C212.579 109.311 212.356 117.177 211.868 118.454C211.381 119.731 210.594 128.893 210.594 128.893C210.594 128.893 209.841 130.832 210.63 132.173C210.63 132.173 210.805 134.742 210.648 135.36C209.964 136.414 208.988 138.203 208.829 140.044C208.829 140.142 208.809 140.233 208.799 140.328C208.749 140.386 208.69 140.435 208.623 140.473L208.79 140.424C208.719 141.191 208.554 141.947 208.299 142.674C207.903 143.695 207.693 144.78 207.679 145.875V151.797L207.189 155.474C207.189 155.474 206.588 158.256 207.189 158.906C207.442 159.23 207.56 159.639 207.517 160.048C207.492 160.523 207.627 160.992 207.9 161.382C208.004 161.495 208.081 161.632 208.123 161.78C208.166 161.929 208.173 162.085 208.145 162.237C207.946 162.882 208.439 169.743 208.439 169.743C208.439 169.743 208.294 171.632 208.096 171.733C207.897 171.833 208.439 173.919 208.439 173.919C208.439 173.919 206.412 175.611 206.929 176.505L207.446 177.3L207.309 177.434L207.226 177.52C207.069 177.43 206.887 177.396 206.709 177.422C206.071 178.074 205.39 178.681 204.669 179.239C203.755 179.898 201.267 180.854 201.267 180.854L199.306 181.013H199.269C199.269 181.013 198.33 180.925 198.857 182.379C199.384 183.832 204.096 183.386 204.096 183.386L206.846 182.952C206.846 182.952 211.748 182.977 213.153 182.665C213.739 182.535 213.888 182.222 213.839 181.905L213.824 181.891C213.757 181.589 213.619 181.308 213.422 181.07C213.412 181.054 213.401 181.039 213.388 181.025L213.476 180.02C215.557 178.822 212.888 176.464 212.888 176.464C212.888 176.464 213.802 174.476 214.271 173.831C214.739 173.187 214.739 163.688 214.739 163.688C214.739 163.688 214.984 160.256 214.339 159.462C214.328 159.204 214.387 158.947 214.511 158.719C214.634 158.492 214.817 158.302 215.04 158.171C215.503 157.854 216.903 153.499 218.001 149.883L218.692 154.143C218.692 154.143 218.543 156.183 218.992 156.778C219.076 156.891 219.136 157.019 219.168 157.156C219.2 157.292 219.203 157.434 219.178 157.572C219.071 158.144 219.106 158.733 219.278 159.288C219.331 159.526 219.459 159.741 219.644 159.901C220.043 160.1 220.068 160.808 220.217 160.958C220.367 161.107 221.293 160.747 221.342 161.293C221.37 161.773 221.37 162.255 221.342 162.735L221.644 171.583C221.644 171.583 221.153 172.319 221.043 174.28C221.001 175.116 220.845 175.591 220.683 175.863C220.593 176.009 220.552 176.18 220.565 176.351C220.578 176.522 220.645 176.684 220.756 176.814L220.842 176.915L220.472 177.199C220.323 177.315 220.219 177.478 220.177 177.662C220.135 177.845 220.158 178.038 220.242 178.207C220.122 178.31 220.037 178.448 219.996 178.601C219.955 178.754 219.962 178.915 220.014 179.065C220.029 179.114 220.05 179.161 220.077 179.204C219.796 179.248 219.535 179.377 219.33 179.574C218.96 180.082 218.514 180.53 218.009 180.903C217.274 181.466 216.572 182.068 215.903 182.707C215.588 183.136 215.165 183.474 214.677 183.687C214.558 183.736 214.434 183.773 214.307 183.798C213.327 183.999 213.633 185.023 214.432 185.193C215.231 185.362 217.884 186.173 219.947 185.7C219.947 185.7 220.56 185.945 221.46 185.489C222.359 185.033 224.367 184.474 224.367 184.474C224.367 184.474 225.492 184.474 225.644 184.028C225.684 183.886 225.705 183.739 225.708 183.592L225.74 183.56L225.71 183.533C225.713 183.199 225.688 182.865 225.634 182.535C225.605 182.364 225.573 182.212 225.544 182.089C225.448 181.717 225.269 181.234 225.193 181.03C225.206 181.014 225.217 180.997 225.227 180.979C225.656 180.244 224.943 178.498 224.943 178.498C225.177 178.127 225.462 177.789 225.789 177.496C226.188 177.197 227.24 169.441 227.24 169.441C227.24 169.441 227.188 167.453 227.73 166.559C228.272 165.664 226.98 160.247 226.98 160.247C226.98 160.247 226.428 159.004 226.629 158.555C226.83 158.107 226.428 156.467 226.428 156.467V154.506C226.427 154.272 226.388 154.041 226.313 153.82C226.159 153.359 225.931 152.474 226.178 151.839C226.529 150.944 227.328 145.427 227.328 145.427C227.328 145.427 226.703 142.993 227.62 141.054C227.691 140.899 227.773 140.749 227.865 140.605C228.544 139.539 228.34 137.644 228.005 136.117C227.956 135.872 227.899 135.651 227.843 135.438C227.821 135.345 227.796 135.257 227.772 135.168L227.88 135.124C227.88 135.124 227.88 134.98 227.914 134.732C228.284 134.659 228.635 134.51 228.945 134.296C229.256 134.081 229.519 133.805 229.718 133.485C229.718 133.485 232.007 130.911 234.032 129.83C236.057 128.749 236.209 127.182 236.209 127.182C235.91 126.66 236.746 124.535 236.746 124.535L236.67 122.236ZM230.066 125.668L227.899 128.18V128.165C227.335 127.381 228.424 125.628 228.424 125.628L230.225 121.608C230.211 122.123 230.147 122.589 229.98 122.792C229.49 123.464 230.882 124.584 230.882 124.584C230.14 124.587 230.066 125.668 230.066 125.668Z",fill:"url(#paint0_linear)"}),Object(E.createElement)("path",{d:"M191.915 92.7263L190.732 95.023C190.357 94.991 189.987 94.9136 189.631 94.7926C189.066 94.624 188.544 94.3376 188.098 93.9522C187.652 93.5669 187.293 93.0914 187.045 92.5571C185.989 90.2236 187.736 88.7161 188.55 88.27C189.364 87.8238 190.121 87.3165 190.732 88.7798C191.115 89.7726 191.435 90.7886 191.69 91.8218C191.832 92.3586 191.915 92.7263 191.915 92.7263Z",fill:"#CC818C"}),Object(E.createElement)("path",{d:"M229.515 104.674L227.625 107.488C227.625 107.488 218.695 111.748 220.401 106.752C221.151 104.546 221.239 102.936 221.104 101.82C221.104 101.808 221.104 101.801 221.104 101.789C220.928 100.394 220.403 99.7884 220.403 99.7884C220.403 99.7884 229.108 95.3321 227.811 98.3789C227.546 99.0122 227.441 99.7007 227.505 100.384C227.611 101.368 227.931 102.318 228.441 103.166C228.747 103.703 229.107 104.208 229.515 104.674Z",fill:"#CC818C"}),Object(E.createElement)("path",{d:"M226.796 160.416C226.796 160.416 228.08 165.808 227.531 166.688C226.982 167.568 227.041 169.554 227.041 169.554C227.041 169.554 226.004 177.26 225.61 177.554C225.286 177.841 225.003 178.171 224.769 178.535C224.769 178.535 225.475 180.28 225.051 181.001C224.985 181.111 224.887 181.196 224.769 181.246C224.107 181.525 221.661 180.285 220.268 179.53C220.156 179.469 220.061 179.381 219.99 179.275C219.918 179.169 219.874 179.047 219.86 178.92C219.846 178.793 219.863 178.665 219.909 178.545C219.956 178.426 220.03 178.32 220.126 178.236C220.043 178.069 220.019 177.878 220.06 177.696C220.101 177.513 220.204 177.351 220.352 177.236L220.719 176.951L220.634 176.851C220.524 176.721 220.457 176.56 220.444 176.39C220.431 176.22 220.471 176.05 220.56 175.905C220.719 175.638 220.874 175.169 220.916 174.334C221.016 172.407 221.509 171.667 221.509 171.667L221.212 162.872C221.24 162.395 221.24 161.917 221.212 161.44C221.163 160.899 220.249 161.256 220.102 161.107C219.955 160.957 219.928 160.256 219.533 160.058C219.351 159.898 219.226 159.684 219.175 159.447C219.001 158.893 218.966 158.303 219.075 157.732C219.1 157.595 219.097 157.454 219.065 157.318C219.034 157.182 218.974 157.054 218.891 156.942C218.447 156.349 218.594 154.327 218.594 154.327L217.913 150.091C216.827 153.685 215.447 158.014 214.989 158.327C214.769 158.459 214.588 158.648 214.467 158.873C214.345 159.099 214.286 159.353 214.297 159.609C214.94 160.401 214.692 163.811 214.692 163.811C214.692 163.811 214.692 173.243 214.229 173.887C213.765 174.532 212.868 176.515 212.868 176.515C212.868 176.515 215.516 178.871 213.432 180.06H213.41C211.285 181.246 206.89 177.937 206.89 177.937L207.348 177.478L207.483 177.344L206.963 176.569C206.453 175.679 208.454 174 208.454 174C208.454 174 207.919 171.924 208.115 171.826C208.311 171.728 208.454 169.85 208.454 169.85C208.454 169.85 207.963 163.034 208.164 162.391C208.191 162.24 208.183 162.085 208.141 161.938C208.098 161.79 208.022 161.654 207.919 161.541C207.649 161.154 207.517 160.688 207.542 160.217C207.585 159.811 207.468 159.404 207.216 159.082C206.623 158.44 207.216 155.675 207.216 155.675L207.706 152.018V146.211C207.713 145.09 207.923 143.98 208.326 142.934C208.626 142.086 208.807 141.201 208.865 140.304C209.027 138.431 210.035 136.612 210.711 135.575C211.069 135.026 211.336 134.698 211.336 134.698L227.142 134.08C227.142 134.08 227.387 134.784 227.651 135.762C227.705 135.975 227.759 136.2 227.811 136.436C228.142 137.955 228.34 139.838 227.671 140.897C227.58 141.04 227.498 141.189 227.426 141.343C226.521 143.27 227.139 145.689 227.139 145.689C227.139 145.689 226.35 151.17 226.004 152.062C225.759 152.692 225.985 153.572 226.139 154.023C226.211 154.244 226.248 154.475 226.249 154.707V156.66C226.249 156.66 226.646 158.291 226.448 158.737C226.249 159.183 226.796 160.416 226.796 160.416Z",fill:"#444053"}),Object(E.createElement)("path",{opacity:"0.1",d:"M227.524 141.054C227.433 141.196 227.351 141.344 227.279 141.497L226.389 141.448C226.475 140.99 225.87 136.693 225.87 136.693L227.661 136.593C227.992 138.11 228.193 139.992 227.524 141.054Z",fill:"black"}),Object(E.createElement)("path",{d:"M227.671 140.904C227.58 141.048 227.499 141.197 227.426 141.35L226.536 141.299C226.622 140.843 226.017 136.543 226.017 136.543L227.808 136.443C228.142 137.963 228.34 139.845 227.671 140.904Z",fill:"#444053"}),Object(E.createElement)("path",{opacity:"0.05",d:"M227.671 140.904C227.58 141.048 227.499 141.197 227.426 141.35L226.536 141.299C226.622 140.843 226.017 136.543 226.017 136.543L227.808 136.443C228.142 137.963 228.34 139.845 227.671 140.904Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M220.869 160.774C220.869 160.774 221.894 159.303 223.649 159.303C225.404 159.303 226.154 159.104 226.154 159.104C226.154 159.104 225.031 159.771 224.254 159.857C223.477 159.943 220.869 160.774 220.869 160.774Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M208.662 140.728C208.736 140.74 209.983 139.431 210.069 138.914C210.137 138.587 210.332 138.299 210.611 138.115C210.611 138.115 211.415 138.436 210.699 139.421C209.983 140.407 208.662 140.728 208.662 140.728Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M227.799 98.3738C227.515 99.0454 227.265 99.1092 227.309 99.7489C226.978 100.099 226.597 100.399 226.179 100.639C225.296 101.163 224.335 102.19 223.237 102.19C222.501 102.191 221.772 102.053 221.088 101.783C220.911 100.389 220.386 99.7833 220.386 99.7833C220.386 99.7833 229.093 95.327 227.799 98.3738Z",fill:"black"}),Object(E.createElement)("path",{d:"M229.132 96.0035C229.132 97.167 228.787 98.3044 228.141 99.2718C227.494 100.239 226.575 100.993 225.5 101.439C224.425 101.884 223.243 102 222.101 101.773C220.96 101.546 219.912 100.986 219.089 100.163C218.267 99.3406 217.706 98.2923 217.479 97.1512C217.252 96.01 217.369 94.8272 217.814 93.7522C218.259 92.6772 219.013 91.7585 219.981 91.112C220.948 90.4656 222.086 90.1206 223.249 90.1206C224.809 90.1206 226.306 90.7404 227.409 91.8437C228.512 92.9469 229.132 94.4432 229.132 96.0035Z",fill:"#CC818C"}),Object(E.createElement)("path",{opacity:"0.1",d:"M229.515 104.673L227.625 107.487C227.625 107.487 218.695 111.747 220.401 106.752C221.151 104.546 221.239 102.935 221.104 101.82H221.119C221.225 102.19 221.285 102.571 221.298 102.955C221.325 103.725 221.345 104.698 223.259 105.019C226.446 105.553 228.147 103.563 228.446 103.173C228.751 103.708 229.109 104.21 229.515 104.673Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M191.915 92.7262L190.731 95.023C190.357 94.9909 189.987 94.9135 189.631 94.7926L189.528 94.67C190.018 94.8563 191.638 91.78 191.638 91.78L191.69 91.8217C191.832 92.3585 191.915 92.7262 191.915 92.7262Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M227.652 135.769C223.838 137.426 210.645 136.015 210.645 136.015C210.685 135.874 210.707 135.729 210.711 135.583C211.069 135.034 211.337 134.706 211.337 134.706L227.142 134.088C227.142 134.088 227.399 134.791 227.652 135.769Z",fill:"black"}),Object(E.createElement)("path",{d:"M221.109 101.958L219.349 102.71C219.084 102.708 218.825 102.63 218.602 102.485C218.379 102.341 218.202 102.135 218.092 101.894C217.683 101.043 216.239 101.894 216.239 101.894C216.239 101.894 211.827 101.56 210.199 102.384C210.199 102.384 207.569 101.271 207.199 101.198C206.829 101.124 206.272 100.828 206.013 100.901C205.753 100.975 205.422 100.411 205.235 100.457C205.049 100.504 204.976 100.087 204.382 99.9377C203.789 99.7882 203.569 99.9745 202.912 99.3078C202.255 98.641 196.835 96.0109 196.835 96.0109L194.384 94.0107L191.791 91.937C191.791 91.937 190.161 95.0108 189.678 94.8245L194.605 100.754C194.605 100.754 198.161 103.865 200.608 104.865C203.054 105.865 202.868 106.161 202.868 106.161C202.868 106.161 210.278 109.941 211.425 109.868C212.572 109.794 212.356 117.601 211.866 118.861C211.376 120.121 210.609 129.234 210.609 129.234C210.609 129.234 209.873 131.161 210.645 132.495C210.645 132.495 210.829 135.237 210.645 135.718C210.645 135.718 223.919 137.137 227.686 135.458C227.686 135.458 228.242 129.308 227.686 128.531C227.13 127.754 228.206 126.021 228.206 126.021L230.576 120.724L236.356 114.907C236.356 114.907 237.243 110.054 233.28 106.943L230.649 104.607C230.649 104.607 229.179 103.335 228.747 103.254C228.316 103.173 228.475 103.254 228.475 103.254C228.475 103.254 226.759 105.757 223.24 105.164C221.333 104.843 221.313 103.869 221.279 103.102C221.269 102.715 221.212 102.331 221.109 101.958Z",fill:"#67647E"}),Object(E.createElement)("path",{opacity:"0.1",d:"M228.353 121.901C228.353 121.901 220.2 122.234 218.572 124.795C218.572 124.795 220.685 123.793 222.573 124.09C224.46 124.386 228.353 121.901 228.353 121.901Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M219.349 130.827C219.349 130.827 223.203 131.087 224.019 130.271C224.835 129.455 224.838 128.974 224.838 128.974L219.349 130.827Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M229.132 114.044C229.132 114.044 225.87 117.898 229.836 119.564L229.132 114.044Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M209.829 106.6C209.829 106.6 211.015 109.019 211.608 109.179L209.829 106.6Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M205.828 105.561C205.828 105.561 208.792 108.23 209.348 108.487C209.348 108.487 206.272 105.561 205.828 105.561Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M217.646 103.006C217.646 103.006 214.792 107.267 216.645 109.87C216.645 109.86 215.609 106.784 217.646 103.006Z",fill:"black"}),Object(E.createElement)("path",{d:"M224.838 135.274L223.965 136.096L223.842 136.208L222.832 137.164C222.761 137.218 222.69 137.272 222.617 137.321C218.506 140.263 217.682 135.792 217.682 135.792C217.682 135.792 215.869 136.978 215.609 136.015C215.349 135.051 219.832 133.681 220.511 133.755C220.571 133.761 220.631 133.761 220.69 133.755C221.014 133.701 221.326 133.59 221.612 133.429L221.81 133.323C222.039 133.195 222.26 133.055 222.475 132.904L224.838 135.274Z",fill:"#CC818C"}),Object(E.createElement)("path",{opacity:"0.1",d:"M229.27 96.0032C229.272 97.0235 229.009 98.0269 228.506 98.9148C228.003 99.8026 227.278 100.544 226.402 101.067C226.32 100.93 226.247 100.786 226.186 100.638C225.975 100.148 225.845 99.6187 225.632 99.126C225.399 98.5882 225.066 98.0992 224.652 97.6847C224.581 97.6026 224.491 97.5401 224.389 97.5033C224.294 97.4902 224.197 97.4967 224.104 97.5224C224.011 97.5481 223.925 97.5925 223.85 97.6528C223.6 97.8219 223.322 97.944 223.029 98.0132C222.882 98.0468 222.729 98.042 222.585 97.999C222.44 97.9561 222.31 97.8765 222.205 97.768C221.975 97.4935 222.007 97.0915 222.073 96.741C222.217 95.9738 222.458 95.2188 222.46 94.4393C222.463 93.6598 222.164 92.8215 221.48 92.4342C220.882 92.0935 220.139 92.1891 219.475 91.9979C219.372 91.971 219.271 91.9366 219.173 91.895C219.99 91.0568 221.038 90.4812 222.183 90.2418C223.329 90.0024 224.52 90.1102 225.604 90.5513C226.688 90.9923 227.616 91.7467 228.269 92.7179C228.922 93.689 229.27 94.8329 229.27 96.0032Z",fill:"black"}),Object(E.createElement)("path",{d:"M218.771 90.954C218.665 91.0104 218.548 91.1134 218.58 91.231C218.6 91.2871 218.638 91.3352 218.687 91.3683C218.962 91.5898 219.279 91.7525 219.619 91.8463C220.283 92.0277 221.028 91.9419 221.626 92.2826C222.303 92.6674 222.607 93.5082 222.607 94.2877C222.607 95.0671 222.362 95.8221 222.222 96.5869C222.156 96.9399 222.122 97.3419 222.352 97.6164C222.457 97.7242 222.588 97.8034 222.732 97.8463C222.876 97.8892 223.029 97.8945 223.176 97.8615C223.469 97.7937 223.747 97.6724 223.997 97.5036C224.072 97.4429 224.159 97.3981 224.252 97.372C224.345 97.3459 224.443 97.3389 224.538 97.3517C224.639 97.39 224.729 97.4523 224.801 97.533C225.216 97.9482 225.548 98.4381 225.781 98.9768C225.997 99.467 226.124 99.9941 226.335 100.489C226.519 100.994 226.863 101.425 227.316 101.715C227.786 101.975 228.438 101.96 228.801 101.558C229.164 101.156 229.134 100.604 229.306 100.122C229.6 99.2808 230.421 98.7537 230.936 98.0282C231.512 97.2119 231.671 96.1873 231.828 95.1995C231.898 94.8885 231.903 94.5664 231.843 94.2533C231.776 94.0461 231.689 93.8458 231.583 93.6552C231.01 92.4689 231.022 90.9761 230.112 90.0299C229.426 89.3191 228.384 89.1034 227.404 88.9808C226.423 88.8583 225.394 88.7896 224.553 88.2724C224.317 88.0942 224.057 87.9506 223.781 87.8459C223.641 87.7967 223.488 87.7982 223.349 87.8502C223.211 87.9021 223.094 88.0013 223.021 88.1303C223.004 88.2057 222.969 88.2761 222.921 88.3362C222.877 88.3615 222.827 88.3763 222.777 88.3792C222.726 88.3822 222.676 88.3733 222.629 88.3533L221.325 88.0028L221.474 88.6597C221 88.6796 220.528 88.5959 220.089 88.4146C220.065 88.7872 220.484 89.0274 220.614 89.3755C220.661 89.5338 220.663 89.702 220.619 89.8613C220.576 90.0206 220.489 90.1647 220.369 90.2775C219.896 90.753 219.305 90.6623 218.771 90.954Z",fill:"#2F2E41"}),Object(E.createElement)("path",{opacity:"0.1",d:"M224.838 135.274L223.965 136.095L221.798 133.321C222.027 133.192 222.248 133.052 222.463 132.901L224.838 135.274Z",fill:"black"}),Object(E.createElement)("path",{d:"M234.662 112.54L236.378 114.91V117.393C236.378 117.393 237.155 120.023 236.378 122.653L236.461 124.95C236.461 124.95 235.635 127.06 235.932 127.58C235.932 127.58 235.785 129.137 233.784 130.21C231.784 131.284 229.514 133.828 229.514 133.828C229.514 133.828 228.661 135.458 226.365 135.088L224.178 136.015L221.661 132.791L225.068 130.938C225.068 130.938 226.254 129.347 226.958 129.421L229.848 126.048C229.848 126.048 229.921 124.974 230.662 124.974C230.662 124.974 229.291 123.864 229.772 123.197C230.252 122.531 229.848 119.565 229.848 119.565L234.662 112.54Z",fill:"#67647E"}),Object(E.createElement)("path",{opacity:"0.1",d:"M231.476 123.344C231.476 123.344 235.366 123.27 235.846 124.271C236.326 125.271 232.65 122.788 231.476 123.344Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M223.86 136.014C223.86 136.079 223.855 136.144 223.843 136.208C223.798 136.506 223.651 136.78 223.428 136.983C223.205 137.185 222.918 137.305 222.617 137.321H222.548C222.201 137.321 221.868 137.183 221.623 136.937C221.377 136.692 221.239 136.359 221.239 136.012C221.24 135.867 221.265 135.724 221.313 135.588C220.695 135.098 220.661 134.195 220.678 133.749C221.002 133.695 221.314 133.585 221.6 133.423C221.761 133.886 221.977 134.328 222.244 134.74C222.344 134.716 222.446 134.704 222.548 134.703C222.721 134.703 222.891 134.737 223.05 134.803C223.209 134.869 223.354 134.965 223.476 135.087C223.597 135.209 223.694 135.353 223.76 135.512C223.826 135.672 223.86 135.842 223.86 136.014Z",fill:"black"}),Object(E.createElement)("path",{d:"M221.717 133.129C221.717 133.129 220.84 133.328 220.84 133.487C220.84 133.646 220.641 135.093 221.604 135.693C222.568 136.294 222.47 134.865 222.47 134.865C222.47 134.865 221.641 133.595 221.717 133.129Z",fill:"#575988"}),Object(E.createElement)("path",{d:"M222.695 137.323C223.418 137.323 224.004 136.737 224.004 136.015C224.004 135.292 223.418 134.706 222.695 134.706C221.972 134.706 221.386 135.292 221.386 136.015C221.386 136.737 221.972 137.323 222.695 137.323Z",fill:"#E4AAB4"}),Object(E.createElement)("path",{d:"M222.695 137.137C223.315 137.137 223.818 136.635 223.818 136.015C223.818 135.394 223.315 134.892 222.695 134.892C222.075 134.892 221.573 135.394 221.573 136.015C221.573 136.635 222.075 137.137 222.695 137.137Z",fill:"#DCE6F2"}),Object(E.createElement)("path",{opacity:"0.1",d:"M217.597 136.522C217.597 136.522 220.364 138.816 223.918 137.36V138.473C223.918 138.473 221.548 140.103 219.401 139.115C217.254 138.127 217.597 136.522 217.597 136.522Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M217.597 136.225C217.597 136.225 220.364 138.522 223.918 137.063V138.176C223.918 138.176 221.548 139.806 219.401 138.818C217.254 137.831 217.597 136.225 217.597 136.225Z",fill:"black"}),Object(E.createElement)("path",{d:"M217.597 136.225C217.597 136.225 220.364 138.522 223.918 137.063V138.176C223.918 138.176 221.548 139.806 219.401 138.818C217.254 137.831 217.597 136.225 217.597 136.225Z",fill:"#444053"}),Object(E.createElement)("path",{opacity:"0.05",d:"M217.67 136.225C217.67 136.225 220.438 138.522 223.994 137.063V138.176C223.994 138.176 221.624 139.806 219.474 138.818C217.325 137.831 217.67 136.225 217.67 136.225Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.05",d:"M215.298 143.179L217.925 150.108C217.925 150.108 218.295 145.65 217.513 144.316C217.291 143.935 216.965 143.625 216.572 143.424C216.179 143.222 215.737 143.137 215.298 143.179Z",fill:"black"}),Object(E.createElement)("g",{opacity:"0.1"},Object(E.createElement)("path",{opacity:"0.1",d:"M221.754 88.2718L221.732 88.1713L221.311 88.0586L221.357 88.2645C221.489 88.2743 221.622 88.2767 221.754 88.2718Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M220.595 89.9436L220.639 89.9043C220.76 89.7917 220.847 89.6476 220.89 89.4882C220.933 89.3288 220.931 89.1606 220.884 89.0023C220.833 88.8794 220.762 88.7658 220.673 88.6665C220.465 88.6255 220.262 88.5656 220.065 88.4875C220.041 88.8577 220.457 89.0979 220.587 89.446C220.648 89.6059 220.65 89.7819 220.595 89.9436Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M227.603 101.334C227.146 101.046 226.797 100.616 226.61 100.109C226.402 99.6186 226.272 99.0892 226.058 98.5989C225.826 98.0602 225.493 97.5703 225.078 97.1552C225.007 97.0736 224.917 97.0112 224.816 96.9738C224.72 96.9612 224.624 96.968 224.531 96.9937C224.438 97.0194 224.352 97.0634 224.276 97.1233C224.027 97.2924 223.749 97.4145 223.455 97.4836C223.309 97.5168 223.156 97.5117 223.011 97.4688C222.867 97.4259 222.736 97.3466 222.632 97.2385C222.401 96.964 222.433 96.5595 222.499 96.209C222.644 95.4442 222.884 94.6868 222.887 93.9098C222.889 93.1328 222.59 92.2896 221.906 91.9047C221.308 91.564 220.565 91.6596 219.901 91.4684C219.56 91.3747 219.243 91.212 218.967 90.9904C218.95 90.9762 218.933 90.9606 218.918 90.9438C218.862 90.9652 218.808 90.9906 218.756 91.0198C218.649 91.0762 218.533 91.1792 218.563 91.2968C218.585 91.3526 218.623 91.4004 218.673 91.4341C218.947 91.6561 219.264 91.8188 219.605 91.9121C220.269 92.0935 221.012 92.0077 221.61 92.3484C222.286 92.7332 222.59 93.574 222.59 94.3535C222.59 95.1329 222.345 95.8879 222.203 96.6527C222.137 97.0057 222.105 97.4077 222.335 97.6822C222.44 97.7902 222.571 97.8695 222.715 97.9125C222.859 97.9554 223.012 97.9605 223.159 97.9273C223.452 97.8595 223.73 97.7381 223.98 97.5694C224.055 97.5088 224.141 97.464 224.234 97.4379C224.327 97.4117 224.424 97.4048 224.519 97.4175C224.62 97.4552 224.71 97.5175 224.781 97.5988C225.195 98.0148 225.528 98.5045 225.762 99.0426C225.978 99.5328 226.105 100.06 226.316 100.555C226.5 101.06 226.844 101.491 227.296 101.781C227.765 102.04 228.419 102.026 228.767 101.624C228.863 101.515 228.938 101.388 228.988 101.251C228.79 101.398 228.554 101.485 228.308 101.5C228.062 101.514 227.817 101.457 227.603 101.334Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M229.721 99.4493C230.091 98.9811 230.579 98.5815 230.927 98.0913C230.995 97.9933 231.059 97.8903 231.118 97.7874C230.669 98.3585 230.054 98.812 229.721 99.4493Z",fill:"black"}))),Object(E.createElement)("defs",null,Object(E.createElement)("linearGradient",{id:"paint0_linear",x1:"211.591",y1:"185.849",x2:"211.591",y2:"86.973",gradientUnits:"userSpaceOnUse"},Object(E.createElement)("stop",{stopColor:"#808080",stopOpacity:"0.25"}),Object(E.createElement)("stop",{offset:"0.54",stopColor:"#808080",stopOpacity:"0.12"}),Object(E.createElement)("stop",{offset:"1",stopColor:"#808080",stopOpacity:"0.1"})),Object(E.createElement)("clipPath",{id:"sales-tax-svg"},Object(E.createElement)("path",{d:"M0 6C0 2.6863 2.68629 0 6 0H289C292.314 0 295 2.68629 295 6V160H0V6Z",fill:"white"}))))},F=function(){return Object(E.createElement)("svg",{width:"295",height:"160",viewBox:"0 0 295 160",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(E.createElement)("g",{clipPath:"url(#shipping-labels-svg)"},Object(E.createElement)("path",{d:"M0 6C0 2.6863 2.68629 0 6 0H289C292.314 0 295 2.68629 295 6V160H0V6Z",fill:"#F7EDF7"}),Object(E.createElement)("path",{opacity:"0.05",d:"M297.839 152.033C290.282 167.747 274.937 178.255 259.035 185.184C237.627 194.516 214.051 198.218 190.8 196.652C186.725 196.379 182.663 195.942 178.613 195.342C164.546 193.274 150.833 189.248 137.864 183.381C134.121 181.682 130.454 179.827 126.862 177.816C120.864 174.465 115.117 170.676 109.666 166.48C108.295 165.425 106.943 164.343 105.61 163.235C104.686 162.466 103.77 161.681 102.84 160.918C100.878 159.31 98.8582 157.782 96.6056 156.638C95.9259 156.292 95.2292 155.982 94.518 155.709C87.3847 152.974 79.1593 154.006 71.7331 156.139C66.0845 157.762 60.5781 159.983 54.9352 161.569C52.4252 162.296 49.8677 162.844 47.2815 163.209C41.5074 163.946 35.6437 163.426 30.0854 161.686L29.6105 161.537C28.8141 161.285 28.0243 161.009 27.2412 160.709L26.7663 160.525C26.0078 160.231 25.2655 159.915 24.5392 159.576L24.0643 159.358C23.3058 159.003 22.5635 158.627 21.8373 158.232C21.5756 158.094 21.3168 157.945 21.0608 157.805C16.9289 155.478 13.1731 152.531 9.92289 149.063C9.82903 148.969 9.74086 148.871 9.63847 148.776C9.18624 148.283 8.74255 147.782 8.31307 147.268C8.1538 147.079 7.99452 146.89 7.83809 146.695C7.32803 146.068 6.83598 145.427 6.36195 144.771C6.29085 144.677 6.22259 144.579 6.15433 144.485C4.21218 141.776 2.60205 138.841 1.359 135.743C1.31918 135.648 1.28221 135.551 1.24808 135.456C0.868851 134.472 0.522806 133.471 0.209944 132.455C0.0819547 132.03 -0.0403466 131.595 -0.148426 131.17C-0.185401 131.044 -0.219532 130.915 -0.250818 130.789C-1.82082 124.559 -2 118.082 -2 111.643C-2 110.892 -2 110.142 -2 109.393C-1.95449 98.9768 -1.79522 88.3833 -0.270727 78.1109C-0.270727 78.0392 -0.250817 77.9675 -0.239441 77.8987C0.270798 74.4405 0.964835 71.0124 1.83967 67.6291C2.75527 64.0792 3.92542 60.601 5.34088 57.222C8.84778 48.9077 13.9474 41.3417 19.6102 34.3291C33.8739 16.6827 52.5802 1.86901 74.4749 -3.67574C98.0675 -9.64768 124.288 -3.92517 143.319 11.3473C149.121 16.0033 154.334 21.5165 160.85 25.0859C166.539 28.1937 173.197 29.481 179.289 27.0354C184.324 25.0142 187.6 24.0108 193.254 24.3175C204.96 24.985 216.5 27.4215 227.487 31.5452C227.931 31.7086 228.375 31.8778 228.815 32.0469C257.459 43.0934 282.082 65.0403 294.881 93.2428C295.22 93.9882 295.549 94.7394 295.868 95.4963C303.499 113.464 306.257 134.522 297.839 152.033Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M238.595 87.2081H167V163.188H238.595V87.2081Z",fill:"white"}),Object(E.createElement)("path",{d:"M170.312 125.071V90.0034H174.389L194.39 90.6387L193.498 95.848V125.071H170.312Z",fill:"#DCDCDE"}),Object(E.createElement)("path",{opacity:"0.5",d:"M190.44 93.561H172.86V94.5775H190.44V93.561Z",fill:"#7F54B3"}),Object(E.createElement)("path",{opacity:"0.5",d:"M190.44 98.1351H172.86V99.1516H190.44V98.1351Z",fill:"#7F54B3"}),Object(E.createElement)("path",{opacity:"0.5",d:"M190.44 102.709H180.504V103.726H190.44V102.709Z",fill:"#7F54B3"}),Object(E.createElement)("path",{opacity:"0.5",d:"M177.701 101.184H172.86V105.25H177.701V101.184Z",fill:"#7F54B3"}),Object(E.createElement)("path",{opacity:"0.5",d:"M190.441 117.702H179.994V121.768H190.441V117.702Z",fill:"#7F54B3"}),Object(E.createElement)("path",{opacity:"0.5",d:"M190.44 107.283H172.86V108.3H190.44V107.283Z",fill:"#7F54B3"}),Object(E.createElement)("path",{opacity:"0.5",d:"M190.44 111.857H172.86V112.874H190.44V111.857Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M209.04 140.572H196.555V162.934H209.04V140.572Z",fill:"#DCDCDE"}),Object(E.createElement)("path",{d:"M112.731 122.276H61.5195V163.442H112.731V122.276Z",fill:"white"}),Object(E.createElement)("path",{d:"M88.7813 151.499H80.1187V163.188H88.7813V151.499Z",fill:"#DCDCDE"}),Object(E.createElement)("path",{d:"M185.577 98.8864C183.646 102.254 170.048 96.6409 170.048 96.6409L144.067 86.2055L137.786 81.5686L133.785 78.6144L142.672 76.1334L142.921 76.2524L149.113 79.2016L172.864 93.3487C172.864 93.3487 190.613 90.1043 185.577 98.8864Z",fill:"#A0616A"}),Object(E.createElement)("path",{d:"M120.088 59.773C120.088 59.773 116.745 61.1143 116.358 64.8721C115.971 68.63 115.939 89.8314 115.939 89.8314C115.939 89.8314 124.674 84.8159 129.371 84.7133C134.068 84.6107 144.979 76.708 144.979 76.708C144.979 76.708 124.421 58.1896 120.088 59.773Z",fill:"#67647E"}),Object(E.createElement)("path",{opacity:"0.1",d:"M120.088 59.773C120.088 59.773 116.745 61.1143 116.358 64.8721C115.971 68.63 115.939 89.8314 115.939 89.8314C115.939 89.8314 124.674 84.8159 129.371 84.7133C134.068 84.6107 144.979 76.708 144.979 76.708C144.979 76.708 124.421 58.1896 120.088 59.773Z",fill:"black"}),Object(E.createElement)("path",{d:"M152.86 129.137L145.726 129.645C145.726 129.645 145.507 142.995 144.579 146.417L156.809 156.073L154.261 147.942L152.86 129.137Z",fill:"#A0616A"}),Object(E.createElement)("path",{d:"M157.501 156.35L157.501 156.35L157.501 156.35C156.994 156.171 157.064 156.073 157.064 156.073V155.565L144.599 145.588C144.478 146.035 144.344 146.329 144.197 146.417C143.74 146.69 143.086 147.585 142.435 148.621C141.678 149.834 141.193 151.196 141.013 152.614C140.833 154.032 140.964 155.472 141.394 156.835V156.835L140.885 165.475H142.923L143.433 157.598H145.98C145.98 157.598 150.312 163.188 151.586 165.221C152.86 167.254 158.465 167.762 164.07 163.951C168.807 160.73 160.263 157.328 157.501 156.35Z",fill:"#444053"}),Object(E.createElement)("path",{d:"M90.1827 99.0244C90.1827 99.0244 77.6983 114.017 89.6732 123.165C94.9424 127.191 99.5703 134.808 103.101 142.076C105.871 147.808 109.869 152.863 114.813 156.884C119.757 160.906 125.526 163.795 131.713 165.348C131.713 165.348 174.262 115.796 159.739 101.82C145.216 87.8434 105.779 99.1902 105.779 99.1902L90.1827 99.0244Z",fill:"#444053"}),Object(E.createElement)("path",{d:"M125.529 86.3823C125.585 89.729 124.943 93.4035 122.031 94.1963C116.425 95.721 115.916 94.9587 115.916 94.9587C115.916 94.9587 114.897 96.7375 115.152 98.7704C115.406 100.803 112.731 99.1516 112.731 99.1516C112.731 99.1516 85.5965 102.582 86.6157 98.7704C87.6348 94.9587 97.3166 81.7447 97.3166 81.7447C97.3166 81.7447 113.113 59.6368 116.425 60.3992C116.538 60.4246 116.652 60.4551 116.772 60.4881C120.145 61.469 125.87 65.7965 126.362 67.5144C126.872 69.2931 124.833 80.4742 124.833 80.4742C125.248 82.4178 125.481 84.3957 125.529 86.3823Z",fill:"#67647E"}),Object(E.createElement)("path",{d:"M165.599 117.575C162.287 119.608 160.249 105.123 160.249 105.123L136.299 90.6388L130.852 85.0508L127.381 81.4907L136.554 80.4742L136.78 80.6318L142.414 84.5401L163.561 102.328C163.561 102.328 168.911 115.542 165.599 117.575Z",fill:"#A0616A"}),Object(E.createElement)("path",{opacity:"0.1",d:"M124.833 80.4741C125.248 82.4178 125.481 84.3957 125.529 86.3823C123.748 86.705 122.14 86.8219 121.012 86.5729C116.425 85.5564 106.744 88.3517 106.744 88.3517C106.744 88.3517 111.839 67.7684 113.113 64.2108C113.417 63.3632 113.901 62.5914 114.533 61.9487C115.164 61.3059 115.928 60.8076 116.772 60.488C120.145 61.4689 125.87 65.7965 126.362 67.5143C126.872 69.2931 124.833 80.4741 124.833 80.4741Z",fill:"black"}),Object(E.createElement)("path",{d:"M124.717 57.2728C119.214 54.6655 116.866 48.0884 119.472 42.5824C122.077 37.0763 128.651 34.7264 134.154 37.3336C139.657 39.9409 142.006 46.518 139.4 52.024C136.794 57.5301 130.221 59.88 124.717 57.2728Z",fill:"#2F2E41"}),Object(E.createElement)("path",{opacity:"0.1",d:"M138.082 82.5072C138.082 82.5072 134.724 83.8743 130.852 85.0508L127.381 81.4907L136.554 80.4742L136.78 80.6318C137.601 81.7982 138.082 82.5072 138.082 82.5072Z",fill:"black"}),Object(E.createElement)("path",{d:"M132.131 54.7977L128.077 71.9742L118.3 62.9339C118.3 62.9339 123.308 56.0031 123.308 54.195C123.308 52.3869 132.131 54.7977 132.131 54.7977Z",fill:"#A0616A"}),Object(E.createElement)("path",{d:"M118.719 58.8744C118.719 58.8744 115.152 59.3827 113.878 62.9403C112.604 66.4979 107.508 87.0811 107.508 87.0811C107.508 87.0811 117.19 84.2859 121.776 85.3023C126.362 86.3188 138.847 81.2365 138.847 81.2365C138.847 81.2365 123.305 58.3662 118.719 58.8744Z",fill:"#67647E"}),Object(E.createElement)("path",{d:"M127.459 59.6811C123.207 57.6664 121.392 52.5841 123.406 48.3295C125.419 44.0748 130.499 42.2589 134.751 44.2736C139.003 46.2883 140.818 51.3706 138.805 55.6253C136.791 59.8799 131.712 61.6958 127.459 59.6811Z",fill:"#9F616A"}),Object(E.createElement)("path",{d:"M122.429 55.079C118.426 53.1828 116.718 48.3995 118.613 44.3951C120.508 40.3907 125.289 38.6816 129.291 40.5778C133.294 42.474 135.002 47.2573 133.107 51.2617C131.211 55.2661 126.431 56.9752 122.429 55.079Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M117.254 40.5669C113.557 38.8153 111.979 34.3967 113.729 30.6977C115.48 26.9987 119.896 25.4199 123.593 27.1715C127.29 28.9231 128.868 33.3417 127.117 37.0407C125.367 40.7397 120.951 42.3185 117.254 40.5669Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M112.267 36.8522C112.843 37.8846 113.659 38.7679 114.645 39.4279C115.632 40.088 116.762 40.5057 117.939 40.6462C119.116 40.7866 120.308 40.6457 121.413 40.2351C122.518 39.8246 123.506 39.1564 124.292 38.2865C123.746 39.1413 123.025 39.8724 122.177 40.4339C121.328 40.9954 120.369 41.375 119.361 41.5487C118.352 41.7224 117.317 41.6865 116.318 41.4432C115.32 41.1999 114.382 40.7546 113.562 40.1353C112.742 39.5159 112.059 38.7361 111.555 37.845C111.052 36.9538 110.739 35.9708 110.636 34.9579C110.534 33.945 110.644 32.9243 110.959 31.9601C111.275 30.996 111.79 30.1093 112.471 29.3562C111.761 30.4654 111.368 31.7467 111.332 33.0656C111.297 34.3845 111.619 35.6924 112.267 36.8522Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M130.914 53.5515C127.412 51.8923 125.63 48.3155 126.933 45.5625C128.236 42.8095 132.131 41.9227 135.633 43.5819C139.135 45.241 140.917 48.8178 139.614 51.5708C138.311 54.3239 134.416 55.2106 130.914 53.5515Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M131.416 56.008C130.665 55.6525 130.537 54.3498 131.129 53.0984C131.721 51.8471 132.81 51.1208 133.56 51.4764C134.311 51.8319 134.439 53.1346 133.847 54.3859C133.254 55.6373 132.166 56.3635 131.416 56.008Z",fill:"#A0616A"})),Object(E.createElement)("defs",null,Object(E.createElement)("clipPath",{id:"shipping-labels-svg"},Object(E.createElement)("path",{d:"M0 6C0 2.6863 2.68629 0 6 0H289C292.314 0 295 2.68629 295 6V160H0V6Z",fill:"white"}))))},D=function(){return Object(E.createElement)("svg",{width:"295",height:"160",viewBox:"0 0 295 160",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Object(E.createElement)("g",{clipPath:"url(#speed-svg)"},Object(E.createElement)("path",{d:"M0 6C0 2.6863 2.68629 0 6 0H289C292.314 0 295 2.68629 295 6V160H0V6Z",fill:"#F7EDF7"}),Object(E.createElement)("path",{opacity:"0.05",d:"M287.559 129.935C280.58 144.446 266.411 154.149 251.726 160.548C231.957 169.166 210.186 172.584 188.715 171.138C184.952 170.886 181.2 170.482 177.46 169.928C164.471 168.018 151.807 164.301 139.831 158.883C136.374 157.314 132.988 155.601 129.672 153.744C124.133 150.649 118.825 147.151 113.792 143.276C112.526 142.302 111.278 141.303 110.047 140.279C109.193 139.569 108.347 138.844 107.489 138.14C105.676 136.654 103.812 135.243 101.731 134.187C101.104 133.868 100.46 133.582 99.8036 133.329C93.2164 130.803 85.6207 131.757 78.763 133.726C73.5468 135.225 68.462 137.277 63.2511 138.741C60.9333 139.412 58.5715 139.918 56.1833 140.255C50.8512 140.935 45.4365 140.456 40.3037 138.849L39.8651 138.712C39.1297 138.479 38.4004 138.224 37.6772 137.946L37.2386 137.777C36.5382 137.505 35.8527 137.213 35.1821 136.901L34.7435 136.699C34.0431 136.371 33.3576 136.024 32.687 135.659C32.4453 135.532 32.2063 135.394 31.9699 135.264C28.1544 133.116 24.6861 130.394 21.6847 127.192C21.598 127.105 21.5166 127.015 21.422 126.927C21.0044 126.472 20.5947 126.009 20.1981 125.535C20.051 125.36 19.904 125.185 19.7595 125.005C19.2885 124.426 18.8341 123.834 18.3964 123.229C18.3307 123.142 18.2677 123.052 18.2046 122.964C16.4112 120.463 14.9243 117.753 13.7764 114.892C13.7396 114.805 13.7055 114.715 13.674 114.627C13.3238 113.718 13.0042 112.794 12.7153 111.855C12.5971 111.463 12.4842 111.061 12.3844 110.669C12.3502 110.553 12.3187 110.434 12.2898 110.317C10.84 104.564 10.6746 98.5833 10.6746 92.637C10.6746 91.9433 10.6746 91.2506 10.6746 90.5587C10.7166 80.9403 10.8637 71.1578 12.2714 61.6718C12.2714 61.6056 12.2898 61.5394 12.3003 61.4758C12.7715 58.2824 13.4124 55.1167 14.2203 51.9925C15.0658 48.7143 16.1464 45.5024 17.4535 42.382C20.6919 34.7042 25.4011 27.7175 30.6304 21.2417C43.8021 4.94627 61.0764 -8.7334 81.2949 -13.8537C103.081 -19.3684 127.295 -14.084 144.868 0.0192566C150.226 4.31881 155.041 9.40996 161.058 12.7061C166.311 15.576 172.459 16.7647 178.085 14.5064C182.734 12.6399 185.76 11.7133 190.981 11.9966C201.791 12.613 212.447 14.8629 222.593 18.6709C223.003 18.8218 223.413 18.9781 223.82 19.1343C250.271 29.3351 273.008 49.6018 284.827 75.6453C285.141 76.3336 285.445 77.0273 285.739 77.7262C292.786 94.3181 295.333 113.764 287.559 129.935Z",fill:"#7F54B3"}),Object(E.createElement)("path",{d:"M245.704 26.7351H50.4275C48.9672 26.7351 47.7834 27.9277 47.7834 29.3988V136.883C47.7834 138.354 48.9672 139.546 50.4275 139.546H245.704C247.165 139.546 248.349 138.354 248.349 136.883V29.3988C248.349 27.9277 247.165 26.7351 245.704 26.7351Z",fill:"white"}),Object(E.createElement)("path",{d:"M245.704 26.7351H50.4275C48.9672 26.7351 47.7834 27.9277 47.7834 29.3988V136.883C47.7834 138.354 48.9672 139.546 50.4275 139.546H245.704C247.165 139.546 248.349 138.354 248.349 136.883V29.3988C248.349 27.9277 247.165 26.7351 245.704 26.7351Z",fill:"white"}),Object(E.createElement)("path",{opacity:"0.04",d:"M245.704 26.7351H50.4275C48.9672 26.7351 47.7834 27.9277 47.7834 29.3988V136.883C47.7834 138.354 48.9672 139.546 50.4275 139.546H245.704C247.165 139.546 248.349 138.354 248.349 136.883V29.3988C248.349 27.9277 247.165 26.7351 245.704 26.7351Z",fill:"white"}),Object(E.createElement)("path",{d:"M247.33 25.4404H48.8017C48.5316 25.4404 48.2727 25.5485 48.0817 25.7409C47.8907 25.9333 47.7834 26.1942 47.7834 26.4662V30.8019H248.34V26.4662C248.34 26.1957 248.234 25.936 248.045 25.7439C247.856 25.5517 247.599 25.4427 247.33 25.4404Z",fill:"#5A5773"}),Object(E.createElement)("path",{d:"M51.7886 29.5076C52.5486 29.5076 53.1646 28.8869 53.1646 28.1213C53.1646 27.3557 52.5486 26.7351 51.7886 26.7351C51.0287 26.7351 50.4126 27.3557 50.4126 28.1213C50.4126 28.8869 51.0287 29.5076 51.7886 29.5076Z",fill:"white"}),Object(E.createElement)("path",{d:"M55.4935 29.5073C56.2534 29.5073 56.8695 28.8867 56.8695 28.1211C56.8695 27.3555 56.2534 26.7349 55.4935 26.7349C54.7335 26.7349 54.1174 27.3555 54.1174 28.1211C54.1174 28.8867 54.7335 29.5073 55.4935 29.5073Z",fill:"white"}),Object(E.createElement)("path",{d:"M59.198 29.5073C59.958 29.5073 60.5741 28.8867 60.5741 28.1211C60.5741 27.3555 59.958 26.7349 59.198 26.7349C58.4381 26.7349 57.822 27.3555 57.822 28.1211C57.822 28.8867 58.4381 29.5073 59.198 29.5073Z",fill:"white"}),Object(E.createElement)("path",{opacity:"0.2",d:"M118.126 40.8855H64.3022V45.4878H118.126V40.8855Z",fill:"#646970"}),Object(E.createElement)("path",{opacity:"0.1",d:"M231.83 59.3391H64.3022V130.135H231.83V59.3391Z",fill:"#5A5773"}),Object(E.createElement)("path",{opacity:"0.1",d:"M162.391 63.9563H159.523V58.3431C159.523 52.0091 154.51 46.7436 148.223 46.6476C146.706 46.6316 145.202 46.9179 143.796 47.4902C142.391 48.0625 141.111 48.9094 140.032 49.9821C138.953 51.0548 138.095 52.3321 137.507 53.7404C136.92 55.1486 136.616 56.66 136.611 58.1874V63.9563H133.749C132.484 63.9602 131.272 64.4682 130.378 65.3692C129.483 66.2702 128.979 67.4912 128.975 68.7654V91.8451C128.979 93.1194 129.483 94.3403 130.378 95.2413C131.272 96.1424 132.484 96.6503 133.749 96.6542H162.391C163.656 96.6503 164.868 96.1423 165.762 95.2412C166.656 94.3401 167.16 93.1192 167.163 91.8451V68.7654C167.16 67.4914 166.656 66.2704 165.762 65.3693C164.868 64.4682 163.656 63.9602 162.391 63.9563ZM149.742 78.9596V87.2257C149.745 87.6634 149.583 88.0858 149.288 88.4074C148.993 88.7289 148.588 88.9256 148.155 88.9575C147.929 88.9681 147.703 88.9325 147.49 88.8526C147.278 88.7728 147.084 88.6504 146.921 88.4929C146.757 88.3354 146.626 88.1461 146.537 87.9363C146.448 87.7266 146.402 87.5008 146.402 87.2727V78.9553C145.627 78.5748 145.004 77.9411 144.633 77.1577C144.262 76.3742 144.166 75.4873 144.359 74.6415C144.553 73.7957 145.026 73.0411 145.7 72.5007C146.374 71.9603 147.211 71.6662 148.072 71.6662C148.934 71.6662 149.77 71.9603 150.444 72.5007C151.119 73.0411 151.591 73.7957 151.785 74.6415C151.979 75.4873 151.882 76.3742 151.511 77.1577C151.141 77.9411 150.517 78.5748 149.742 78.9553V78.9596ZM156.187 63.9563H139.952V58.1874C139.952 56.0194 140.806 53.9402 142.328 52.4072C143.85 50.8742 145.914 50.013 148.066 50.013C150.218 50.013 152.282 50.8742 153.804 52.4072C155.325 53.9402 156.18 56.0194 156.18 58.1874L156.187 63.9563Z",fill:"black"}),Object(E.createElement)("path",{d:"M162.391 63.5298H159.523V57.9166C159.523 51.5826 154.51 46.3171 148.223 46.2211C146.706 46.2051 145.202 46.4914 143.796 47.0637C142.391 47.636 141.111 48.4829 140.032 49.5556C138.953 50.6283 138.095 51.9056 137.507 53.3138C136.92 54.7221 136.616 56.2335 136.611 57.7609V63.5298H133.749C132.484 63.5337 131.272 64.0416 130.378 64.9427C129.483 65.8437 128.979 67.0647 128.975 68.3389V91.4186C128.979 92.6928 129.483 93.9137 130.378 94.8148C131.272 95.7158 132.484 96.2238 133.749 96.2277H162.391C163.656 96.2238 164.868 95.7158 165.762 94.8147C166.656 93.9136 167.16 92.6926 167.163 91.4186V68.3389C167.16 67.0649 166.656 65.8439 165.762 64.9428C164.868 64.0417 163.656 63.5337 162.391 63.5298ZM149.742 78.533V86.7992C149.745 87.2369 149.583 87.6593 149.288 87.9808C148.993 88.3024 148.588 88.499 148.155 88.5309C147.929 88.5416 147.703 88.5059 147.49 88.4261C147.278 88.3462 147.084 88.2239 146.921 88.0664C146.757 87.9089 146.626 87.7195 146.537 87.5098C146.448 87.3001 146.402 87.0743 146.402 86.8461V78.5288C145.627 78.1483 145.004 77.5146 144.633 76.7312C144.262 75.9477 144.166 75.0607 144.359 74.2149C144.553 73.3692 145.026 72.6145 145.7 72.0742C146.374 71.5338 147.211 71.2396 148.072 71.2396C148.934 71.2396 149.77 71.5338 150.444 72.0742C151.119 72.6145 151.591 73.3692 151.785 74.2149C151.979 75.0607 151.882 75.9477 151.511 76.7312C151.141 77.5146 150.517 78.1483 149.742 78.5288V78.533ZM156.187 63.5298H139.952V57.7609C139.952 55.5929 140.806 53.5137 142.328 51.9807C143.85 50.4477 145.914 49.5864 148.066 49.5864C150.218 49.5864 152.282 50.4477 153.804 51.9807C155.325 53.5137 156.18 55.5929 156.18 57.7609L156.187 63.5298Z",fill:"#444053"}),Object(E.createElement)("path",{opacity:"0.1",d:"M231.83 52.5251H214.873V56.558H231.83V52.5251Z",fill:"#5A5773"}),Object(E.createElement)("path",{d:"M237.601 174.735C237.489 174.17 237.298 173.623 237.034 173.112L234.493 169.291H234.508C234.508 169.291 234.108 167.371 234.508 166.429C234.908 165.486 233.081 163.168 233.081 163.168C233.081 163.168 232.859 162.586 233.439 161.869C234.019 161.152 233.081 159.054 233.081 159.054C233.081 159.054 232.637 154.671 232.592 154.002C232.548 153.332 232.19 149.621 232.19 149.621L231.343 141.754L229.836 120.903L229.809 120.512C229.995 120.421 230.094 120.363 230.094 120.363L229.794 108.834L230.054 108.597C232.328 106.524 237.572 101.726 237.519 101.621C237.466 101.517 236.884 93.6089 236.816 91.6298C236.758 90.2233 236.452 88.8384 235.914 87.5393C235.783 87.277 235.404 85.5474 235.247 84.8159C235.205 84.6155 235.177 84.4896 235.177 84.4896C235.177 84.4896 233.64 81.538 233.774 80.1966C233.907 78.8552 234.174 77.8507 230.897 77.3815C230.897 77.3815 228.145 76.9677 226.506 75.8396C225.537 75.1638 224.478 74.6296 223.36 74.2529C223.36 74.2529 222.442 72.5467 221.802 73.1247C221.532 72.5159 221.329 71.8786 221.199 71.2245L221.18 71.1051C222.394 70.2526 223.267 68.9933 223.644 67.5521C223.665 67.471 223.682 67.3878 223.701 67.3068C223.765 67.3285 223.831 67.3407 223.898 67.3431C224.455 67.3431 224.798 66.7182 225.319 66.5198C225.53 66.4367 225.791 66.4239 225.954 66.2554C226.007 66.1904 226.047 66.1152 226.071 66.0342C226.095 65.9532 226.103 65.8681 226.093 65.7841C226.099 65.7259 226.099 65.6674 226.093 65.6092C226.094 65.5886 226.094 65.568 226.093 65.5474V65.5687C225.952 64.7924 225.355 64.1035 225.42 63.3145C225.484 62.5723 226.131 61.9197 226.079 61.1967C226.078 61.1396 226.073 61.0825 226.064 61.0261V61.0517C225.985 60.7694 225.84 60.5105 225.64 60.2967C225.412 59.984 225.113 59.7309 224.768 59.5588C224.474 59.4287 224.133 59.3989 223.858 59.2432C223.049 58.7996 223.051 57.6437 222.571 56.8546C222.365 56.5252 222.073 56.2595 221.726 56.0868C221.38 55.914 220.993 55.841 220.608 55.8757C220.007 55.9355 219.463 56.2575 218.868 56.362C218.055 56.507 217.228 56.2404 216.457 55.9355C215.686 55.6305 214.905 55.2957 214.078 55.2957C213.25 55.2957 212.354 55.7222 212.105 56.5091C211.971 56.9357 212.037 57.3942 211.935 57.8271C211.753 58.5906 211.088 59.1366 210.4 59.5162C209.977 59.7529 209.473 60.0238 209.342 60.4716C209.342 60.4588 209.342 60.4482 209.342 60.4375C209.332 60.4732 209.325 60.5096 209.321 60.5463C209.316 60.5938 209.316 60.6416 209.321 60.6892C209.321 60.9963 209.482 61.2884 209.59 61.5806C209.791 62.1365 209.786 62.7468 209.577 63.2995C209.42 63.7047 209.153 64.0609 209.001 64.464C208.929 64.6517 208.882 64.8482 208.861 65.0483V65.0142C208.856 65.1051 208.856 65.1963 208.861 65.2872C208.859 65.5986 208.931 65.906 209.073 66.1829C209.17 66.3741 209.304 66.5437 209.468 66.6818C209.631 66.8199 209.82 66.9236 210.024 66.9869C210.447 67.085 210.712 66.667 211.158 66.7736C211.238 66.793 211.317 66.818 211.393 66.8483C211.408 66.9442 211.423 67.0402 211.44 67.1341C211.71 68.5694 212.469 69.8645 213.586 70.7958C213.586 70.847 213.603 70.8982 213.61 70.9515C213.745 71.8018 213.804 72.6626 213.785 73.5235C213.785 73.5235 213.119 72.5403 212.204 74.4384C212.204 74.4384 209.818 75.8246 208.995 75.9825C208.171 76.1403 205.248 77.1661 205.248 77.1661C204.807 77.4873 204.276 77.6598 203.732 77.6587C202.82 77.6587 202.062 79.6698 202.172 80.7639C202.282 81.8579 202.106 82.6641 201.257 82.7089C200.408 82.7537 200.872 84.4875 200.878 84.5174L200.8 84.8906C200.635 85.6541 200.275 87.292 200.148 87.5479C199.61 88.847 199.304 90.2318 199.244 91.6383C199.178 93.6174 198.609 101.495 198.543 101.63C198.499 101.717 202.091 105.025 204.617 107.337L204.983 107.67L203.821 118.606C203.855 119.027 203.979 119.436 204.185 119.804C204.391 120.173 204.674 120.491 205.015 120.738C205.015 120.866 205.015 120.997 205.002 121.131C204.951 122.41 204.85 123.959 204.646 124.364C204.291 125.081 204.38 128.924 204.38 128.924C204.38 128.924 204.022 136.746 203.577 137.597C203.133 138.448 203.042 140.233 203.175 140.583C203.309 140.933 202.728 150.327 202.728 150.327L202.284 154.53C202.284 154.53 202.417 158.553 202.015 158.642C201.613 158.732 201.391 161.504 201.391 161.504C201.391 161.504 199.966 163.471 200.588 164.185C201.211 164.899 200.497 165.215 200.432 165.392C200.366 165.569 199.073 166.245 200.008 168.745C200.017 168.769 200.027 168.794 200.038 168.817C199.161 170.043 196.384 174 196.553 174.601C196.678 174.984 196.943 175.304 197.294 175.497C197.948 175.891 199.07 176.075 200.855 175.497C203.819 174.535 203.607 173.842 203.607 173.842C203.622 173.518 203.76 173.212 203.993 172.987C204.225 172.763 204.534 172.636 204.856 172.635C206.082 172.545 206.996 171.406 206.996 171.406L206.852 170.867L206.655 170.12C206.679 169.907 206.829 169.534 207.502 169.327C208.529 169.013 208.26 167.047 208.26 167.047C208.26 167.047 208.171 164.991 208.616 164.722C209.06 164.454 208.885 161.056 208.885 161.056C208.885 161.056 209.376 158.597 210.087 156.943C210.798 155.288 211.649 145.456 211.649 145.456C211.649 145.456 212.227 140.628 212.763 139.241C213.298 137.855 213.79 133.967 213.79 133.967C213.79 133.967 217.09 127.529 217.132 126.098C217.132 126.098 217.556 124.756 217.979 126.232C218.402 127.708 219.592 131.24 219.592 131.24L220.75 135.575L222.133 142.057L223.026 147.512C223.026 147.512 222.89 149.568 223.238 150.284C223.585 151.001 224.084 152.652 223.818 152.965C223.551 153.279 224.351 154.754 224.576 155.066C224.8 155.377 224.576 161.995 224.576 161.995C224.576 161.995 225.6 167.627 227.071 168.606C227.174 168.674 227.283 168.731 227.397 168.777C227.376 169.387 227.355 170.203 227.383 170.63C227.379 170.725 227.395 170.82 227.429 170.909C227.563 171.088 229.078 172.296 229.392 172.296C229.705 172.296 230.816 173.078 230.863 173.458C230.909 173.837 234.121 175.445 234.576 175.492C235.031 175.539 237.237 175.938 237.54 175.313C237.615 175.13 237.636 174.93 237.601 174.735ZM229.711 94.1805L229.94 94.3788C229.94 94.3788 230.175 96.2235 230.342 96.7759C230.509 97.3283 230.308 98.4031 230.308 98.4031C230.324 98.8043 230.403 99.2003 230.543 99.5761C230.742 99.9792 230.141 100.856 230.141 100.856H229.605L229.438 93.9501L229.711 94.1805ZM213.785 73.5619V73.5214C213.781 73.5342 213.779 73.5491 213.779 73.5619H213.785ZM205.561 100.146C205.479 99.9669 205.466 99.7634 205.527 99.5761C205.575 99.4748 205.612 99.3691 205.639 99.2605C205.705 98.9803 205.746 98.6948 205.762 98.4074C205.762 98.4038 205.762 98.4003 205.762 98.3967C205.743 98.2944 205.572 97.3048 205.73 96.7802C205.889 96.2555 206.13 94.3831 206.13 94.3831L206.283 94.253L206.636 93.9437C206.636 93.9437 206.636 93.8286 206.662 93.6388C206.736 95.2596 206.795 97.051 206.7 97.1406C206.522 97.3176 205.874 99.06 206.031 99.1282C206.082 99.1517 206.012 99.8491 205.893 100.787C205.76 100.586 205.649 100.371 205.561 100.146Z",fill:"url(#paint0_linear)"}),Object(E.createElement)("path",{d:"M222.623 75.2659V77.9189L217.221 80.6551C217.221 80.6551 211.857 77.3857 213.18 76.0848C214.026 75.2616 213.863 73.001 213.635 71.4463C213.501 70.542 213.347 69.8787 213.347 69.8787C213.347 69.8787 222.983 67.1063 221.527 69.2112C221.04 69.915 221.002 70.8256 221.165 71.7278C221.495 73.5171 222.623 75.2659 222.623 75.2659Z",fill:"#CC818C"}),Object(E.createElement)("path",{d:"M207.824 101.21L207.127 109.851C207.127 109.851 206.083 108.898 204.733 107.657C202.228 105.356 198.672 102.065 198.714 101.977C198.78 101.843 199.349 94.0034 199.411 92.0328C199.469 90.6341 199.771 89.2566 200.304 87.9637C200.431 87.7078 200.789 86.0785 200.939 85.3171C200.99 85.0804 201.022 84.9268 201.022 84.9268L202.19 84.4534C202.19 84.4534 207.059 89.9258 207.059 90.026C207.059 90.1262 206.727 94.3297 206.727 94.3297L206.382 94.6326L206.232 94.7626C206.232 94.7626 205.999 96.5989 205.834 97.1491C205.668 97.6993 205.846 98.6548 205.865 98.7571C205.85 99.0445 205.809 99.3299 205.745 99.6102C205.717 99.718 205.68 99.8229 205.632 99.9237C205.573 100.11 205.585 100.313 205.666 100.491C205.76 100.738 205.883 100.974 206.03 101.193L207.824 101.21Z",fill:"#444053"}),Object(E.createElement)("path",{d:"M237.332 101.977C237.383 102.082 232.19 106.857 229.94 108.919L228.919 109.851L228.229 101.209H230.018C230.018 101.209 230.615 100.341 230.416 99.9405C230.277 99.5666 230.199 99.1727 230.185 98.7739C230.185 98.7739 230.382 97.7076 230.217 97.1552C230.052 96.6028 229.819 94.7688 229.819 94.7688L229.593 94.5726L229.324 94.3358C229.324 94.3358 228.991 90.1324 228.991 90.0321C228.991 89.9319 233.86 84.4595 233.86 84.4595L235.02 84.9265C235.02 84.9265 235.046 85.0524 235.088 85.2528C235.245 85.9801 235.62 87.7011 235.749 87.9634C236.282 89.2563 236.584 90.6338 236.642 92.0326C236.697 94.0031 237.264 101.843 237.332 101.977Z",fill:"#444053"}),Object(E.createElement)("path",{d:"M234.349 166.476C233.951 167.41 234.349 169.323 234.349 169.323C234.349 169.323 228.422 169.634 226.974 168.655C225.526 167.676 224.501 162.069 224.501 162.069C224.501 162.069 224.713 155.486 224.501 155.175C224.29 154.863 223.485 153.396 223.75 153.085C224.014 152.773 223.538 151.127 223.176 150.414C222.814 149.702 222.964 147.657 222.964 147.657L222.08 142.227L220.712 135.778L219.55 131.461C219.55 131.461 218.358 127.947 217.954 126.48C217.549 125.012 217.122 126.345 217.122 126.345C217.079 127.77 213.811 134.176 213.811 134.176C213.811 134.176 213.324 138.047 212.795 139.425C212.265 140.803 211.689 145.61 211.689 145.61C211.689 145.61 210.843 155.396 210.144 157.043C209.445 158.689 208.965 161.135 208.965 161.135C208.965 161.135 209.143 164.518 208.7 164.784C208.258 165.051 208.33 167.098 208.33 167.098C208.33 167.098 208.594 169.054 207.578 169.367C206.562 169.681 206.732 170.346 206.732 170.346C206.732 170.346 201.079 171.28 200.152 168.787C199.225 166.294 200.506 165.631 200.575 165.452C200.645 165.273 201.35 164.963 200.732 164.249C200.114 163.535 201.526 161.581 201.526 161.581C201.526 161.581 201.748 158.824 202.144 158.734C202.54 158.644 202.411 154.641 202.411 154.641L202.851 150.459C202.851 150.459 203.427 141.116 203.294 140.76C203.16 140.404 203.249 138.627 203.692 137.774C204.134 136.921 204.485 129.141 204.485 129.141C204.485 129.141 204.397 125.317 204.75 124.605C204.962 124.202 205.051 122.651 205.101 121.387C205.14 120.421 205.148 119.621 205.148 119.621L210.093 117.753L216.444 115.708L221.787 118.288L229.605 119.8L229.703 121.159L231.195 141.912L232.042 149.741C232.042 149.741 232.395 153.432 232.44 154.1C232.484 154.767 232.925 159.129 232.925 159.129C232.925 159.129 233.852 161.219 233.278 161.931C232.705 162.643 232.925 163.21 232.925 163.21C232.925 163.21 234.747 165.541 234.349 166.476Z",fill:"#444053"}),Object(E.createElement)("path",{opacity:"0.1",d:"M221.531 69.2109C221.044 69.9147 221.006 70.8254 221.169 71.7275C220.057 72.5181 218.717 72.9186 217.356 72.8674C215.996 72.8161 214.69 72.316 213.639 71.4438C213.506 70.5396 213.351 69.8763 213.351 69.8763C213.351 69.8763 222.987 67.1081 221.531 69.2109Z",fill:"black"}),Object(E.createElement)("path",{d:"M223.783 66.4897C223.783 67.7256 223.42 68.9337 222.738 69.9613C222.056 70.9889 221.088 71.7898 219.954 72.2628C218.821 72.7357 217.574 72.8595 216.371 72.6184C215.167 72.3773 214.062 71.7821 213.195 70.9082C212.327 70.0343 211.736 68.9209 211.497 67.7088C211.258 66.4967 211.381 65.2403 211.85 64.0985C212.32 62.9567 213.115 61.9807 214.135 61.2941C215.155 60.6075 216.354 60.241 217.581 60.241C218.396 60.2371 219.205 60.396 219.959 60.7086C220.713 61.0213 221.399 61.4814 221.975 62.0624C222.552 62.6435 223.009 63.3339 223.319 64.0938C223.63 64.8537 223.787 65.668 223.783 66.4897Z",fill:"#CC818C"}),Object(E.createElement)("path",{opacity:"0.1",d:"M225.075 76.8738L223.043 113.332L212.003 110.996L209.816 96.3812L211.982 76.7607L213.612 76.9719L216.487 77.3408L219.334 77.5178L222.421 77.1723L225.075 76.8738Z",fill:"black"}),Object(E.createElement)("path",{d:"M225.075 77.1404L223.043 113.598L212.003 111.263L209.816 96.6479L211.982 77.0295L213.612 77.2385L216.487 77.6075L219.334 77.7845L222.421 77.439L225.075 77.1404Z",fill:"white"}),Object(E.createElement)("path",{d:"M216 78.1191L219.975 78.2535L218.858 79.8295C218.858 79.8295 218.936 83.0136 219.467 83.9264C219.999 84.8391 219.842 98.9403 219.842 98.9403L218.784 100.964L216.974 98.695L216.997 80.0769L216 78.1191Z",fill:"#7F54B3"}),Object(E.createElement)("path",{opacity:"0.1",d:"M216 78.1191L219.975 78.2535L218.858 79.8295C218.858 79.8295 218.936 83.0136 219.467 83.9264C219.999 84.8391 219.842 98.9403 219.842 98.9403L218.784 100.964L216.974 98.695L216.997 80.0769L216 78.1191Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M222.225 73.9817L218.517 78.1191L220.636 80.3434L224.148 76.8949L222.225 73.9817Z",fill:"black"}),Object(E.createElement)("path",{d:"M222.225 73.7151L218.517 77.8524L220.636 80.0768L224.148 76.6283L222.225 73.7151Z",fill:"white"}),Object(E.createElement)("path",{opacity:"0.1",d:"M216.95 77.9187L213.194 74.1375L212.841 76.1166L214.564 80.4544L216.95 77.9187Z",fill:"black"}),Object(E.createElement)("path",{d:"M217.082 77.652L213.328 73.8708L212.975 75.85L214.698 80.1878L217.082 77.652Z",fill:"white"}),Object(E.createElement)("path",{opacity:"0.1",d:"M229.722 121.165C227.919 122.03 225.988 122.592 224.006 122.83C220.363 123.297 217.979 118.627 217.979 118.627L216.588 120.45C216.146 122.387 209.412 122.875 206.674 122.141C206.106 122 205.572 121.746 205.104 121.393C205.142 120.427 205.15 119.627 205.15 119.627L210.095 117.759L216.446 115.714L221.789 118.294L229.607 119.806L229.722 121.165Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M225.075 77.1426L223.045 113.598L212.003 111.263L209.812 96.65L211.975 77.0295L213.605 77.2428C213.564 77.9575 213.484 78.6694 213.366 79.3755C213.102 80.6231 214.736 89.4757 214.736 89.4757C214.736 89.4757 217.841 99.4033 219.239 97.9723C220.636 96.5413 222.626 88.9852 222.626 88.9852C223.974 86.1829 222.649 78.3219 222.55 78.1641C222.48 77.9316 222.438 77.6919 222.423 77.4497L225.075 77.1426Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M229.845 105.353L229.938 108.925L228.917 109.857L228.229 101.209H229.753L229.845 105.353Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M205.868 98.7637C205.852 99.051 205.812 99.3364 205.747 99.6167C205.747 99.5378 205.747 99.493 205.73 99.4866C205.666 99.4695 205.743 99.1433 205.868 98.7637Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M207.824 101.21L207.127 109.851C207.127 109.851 206.084 108.898 204.733 107.657L204.894 106.125C204.894 106.125 205.464 102.363 205.671 100.508C205.765 100.755 205.887 100.991 206.035 101.21H207.824Z",fill:"black"}),Object(E.createElement)("path",{d:"M213.813 74.0032C213.813 74.0032 213.152 73.0243 212.246 74.9139C212.246 74.9139 209.884 76.2937 209.071 76.4494C208.258 76.6051 205.366 77.6288 205.366 77.6288C204.929 77.9468 204.404 78.1177 203.865 78.1171C202.959 78.1171 202.208 80.1197 202.318 81.2095C202.428 82.2993 202.252 83.1012 201.414 83.1459C200.575 83.1907 201.037 84.9459 201.037 84.9459L206.624 91.3972C206.624 91.3972 206.977 97.3367 206.801 97.5158C206.626 97.6949 205.984 99.4352 206.139 99.4949C206.293 99.5546 205.292 106.123 205.292 106.123L203.946 118.87C203.946 118.87 203.946 121.003 206.685 121.739C209.424 122.474 216.163 121.988 216.597 120.052L217.987 118.226C217.987 118.226 220.371 122.899 224.014 122.432C227.658 121.965 229.978 120.63 229.978 120.63L229.58 105.353L229.315 94.3424L235.004 84.9267C235.004 84.9267 233.479 81.99 233.613 80.6614C233.746 79.3327 234.009 78.3261 230.763 77.8591C230.763 77.8591 228.026 77.4475 226.413 76.3236C225.454 75.653 224.407 75.1217 223.301 74.7454C223.301 74.7454 222.391 73.0393 221.758 73.6236C221.758 73.6236 222.393 76.0357 222.34 76.3961C222.287 76.7565 222.439 78.3858 222.539 78.5543C222.638 78.7228 223.964 86.5731 222.615 89.3754C222.615 89.3754 220.636 96.9315 219.228 98.3625C217.82 99.7935 214.725 89.866 214.725 89.866C214.725 89.866 213.091 81.0112 213.355 79.7657C213.62 78.5202 213.813 74.0032 213.813 74.0032Z",fill:"#444053"}),Object(E.createElement)("path",{d:"M218.538 103.167C219.074 103.167 219.509 102.729 219.509 102.188C219.509 101.648 219.074 101.209 218.538 101.209C218.001 101.209 217.566 101.648 217.566 102.188C217.566 102.729 218.001 103.167 218.538 103.167Z",fill:"#50575E"}),Object(E.createElement)("path",{d:"M218.538 107.782C219.074 107.782 219.509 107.344 219.509 106.804C219.509 106.263 219.074 105.825 218.538 105.825C218.001 105.825 217.566 106.263 217.566 106.804C217.566 107.344 218.001 107.782 218.538 107.782Z",fill:"#50575E"}),Object(E.createElement)("path",{opacity:"0.1",d:"M223.783 66.4897C223.785 67.0229 223.718 67.554 223.584 68.07C223.454 68.01 223.345 67.9113 223.271 67.787C223.198 67.6628 223.164 67.519 223.174 67.3748C223.201 67.121 223.369 66.8885 223.333 66.6368C223.28 66.2487 222.814 66.0909 222.568 65.7838C222.266 65.4127 222.331 64.8731 222.357 64.3933C222.382 63.9134 222.261 63.3269 221.815 63.1627C221.681 63.1137 221.535 63.1094 221.406 63.054C221.055 62.9047 220.947 62.4653 220.712 62.1625C220.242 61.5526 219.308 61.5654 218.595 61.8554C218.284 62.0054 217.966 62.1392 217.642 62.2563C217.48 62.314 217.307 62.3372 217.136 62.3243C216.964 62.3115 216.797 62.2629 216.645 62.1817C216.505 62.0921 216.393 61.9684 216.249 61.8789C215.771 61.5888 215.144 61.8789 214.729 62.2521C214.314 62.6253 213.982 63.1265 213.459 63.3547C213.224 63.4613 212.934 63.5253 212.824 63.7556C212.769 63.881 212.746 64.0179 212.756 64.1544C212.756 64.984 212.854 65.8264 212.682 66.639C212.572 67.1615 212.208 67.7544 211.681 67.6904C211.615 67.6806 211.551 67.6642 211.488 67.6413C211.329 66.7872 211.349 65.9091 211.547 65.0631C211.744 64.2171 212.114 63.4219 212.634 62.7282C213.153 62.0346 213.811 61.4577 214.564 61.0344C215.317 60.6112 216.15 60.3509 217.009 60.2702C217.868 60.1895 218.734 60.2901 219.552 60.5657C220.37 60.8412 221.122 61.2857 221.76 61.8706C222.398 62.4555 222.908 63.168 223.257 63.9626C223.606 64.7572 223.787 65.6164 223.788 66.4854L223.783 66.4897Z",fill:"black"}),Object(E.createElement)("path",{d:"M211.211 67.2875C211.37 67.3237 211.52 67.4069 211.683 67.4282C212.21 67.4922 212.574 66.8993 212.684 66.3768C212.856 65.5643 212.767 64.7219 212.761 63.8923C212.749 63.7559 212.771 63.6187 212.826 63.4935C212.947 63.2632 213.237 63.1992 213.461 63.0925C213.974 62.8622 214.308 62.3717 214.731 61.99C215.155 61.6082 215.771 61.3267 216.249 61.6167C216.391 61.702 216.505 61.83 216.645 61.9196C216.798 61.9996 216.965 62.0475 217.137 62.0603C217.309 62.0732 217.481 62.0507 217.644 61.9942C217.972 61.8961 218.279 61.7234 218.595 61.5933C219.302 61.3032 220.238 61.2926 220.712 61.8982C220.947 62.2032 221.055 62.6404 221.406 62.7897C221.535 62.8452 221.681 62.8516 221.815 62.9006C222.261 63.0691 222.376 63.6513 222.357 64.1311C222.338 64.611 222.274 65.1506 222.568 65.5216C222.814 65.8245 223.28 65.9823 223.333 66.3747C223.366 66.6264 223.201 66.861 223.174 67.1126C223.168 67.2061 223.18 67.3 223.21 67.3887C223.24 67.4775 223.287 67.5594 223.349 67.6296C223.41 67.6998 223.485 67.757 223.569 67.7979C223.653 67.8387 223.744 67.8624 223.836 67.8676C224.387 67.8676 224.728 67.247 225.242 67.0486C225.454 66.9655 225.71 66.9527 225.877 66.7842C225.939 66.7032 225.983 66.6096 226.006 66.5098C226.029 66.41 226.029 66.3064 226.008 66.2062C225.905 65.3894 225.255 64.6792 225.325 63.8603C225.39 63.0755 226.112 62.3909 225.96 61.6189C225.882 61.3342 225.737 61.0729 225.536 60.8575C225.309 60.5477 225.014 60.2957 224.673 60.1217C224.378 59.9938 224.038 59.9639 223.769 59.8082C222.968 59.3668 222.971 58.2151 222.499 57.4303C222.296 57.106 222.009 56.8441 221.668 56.6733C221.328 56.5025 220.947 56.4294 220.568 56.4621C219.973 56.5218 219.433 56.8396 218.845 56.9462C218.038 57.0912 217.221 56.8247 216.457 56.5197C215.692 56.2147 214.92 55.8799 214.101 55.8799C213.281 55.8799 212.394 56.3064 212.144 57.087C212.013 57.5135 212.079 57.9699 211.977 58.3986C211.799 59.1599 211.13 59.7016 210.457 60.0791C209.994 60.3393 209.437 60.6379 209.382 61.1689C209.346 61.5058 209.53 61.8087 209.646 62.135C209.844 62.687 209.84 63.2922 209.634 63.8411C209.479 64.2442 209.221 64.5982 209.064 64.9991C208.953 65.2713 208.901 65.564 208.91 65.8582C208.92 66.1523 208.991 66.441 209.119 66.7053C209.218 66.8979 209.355 67.0683 209.521 67.2058C209.687 67.3433 209.88 67.4451 210.087 67.505C210.504 67.6052 210.766 67.1894 211.211 67.2875Z",fill:"#2F2E41"}),Object(E.createElement)("g",{opacity:"0.1"},Object(E.createElement)("path",{opacity:"0.1",d:"M212.685 65.9121C212.574 66.4346 212.208 67.0275 211.681 66.9635C211.518 66.9422 211.37 66.859 211.209 66.8227C210.767 66.7246 210.504 67.1426 210.087 67.036C209.88 66.9762 209.687 66.8744 209.52 66.7369C209.354 66.5993 209.217 66.429 209.117 66.2362C209.007 66.0192 208.94 65.7822 208.921 65.5389C208.878 65.9165 208.947 66.2983 209.117 66.6372C209.217 66.8299 209.354 67.0003 209.52 67.1378C209.687 67.2753 209.88 67.3771 210.087 67.4369C210.51 67.535 210.767 67.117 211.209 67.2237C211.364 67.278 211.522 67.3243 211.681 67.3623C212.208 67.4284 212.574 66.8355 212.685 66.313C212.771 65.8514 212.805 65.3813 212.786 64.9119C212.784 65.2478 212.75 65.5827 212.685 65.9121Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M209.784 62.7001C209.811 62.3506 209.764 61.9994 209.645 61.67C209.549 61.451 209.468 61.2259 209.401 60.9961C209.392 61.0319 209.385 61.0682 209.38 61.1049C209.344 61.4397 209.53 61.7447 209.645 62.071C209.719 62.2735 209.766 62.4851 209.784 62.7001Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M225.958 61.5762C225.858 62.1819 225.371 62.7513 225.323 63.3889C225.311 63.4981 225.311 63.6082 225.323 63.7174C225.429 62.9731 226.083 62.3141 225.958 61.5762Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M225.994 66.0762C225.976 66.1653 225.934 66.2479 225.873 66.315C225.717 66.4835 225.45 66.4963 225.238 66.5795C224.724 66.7778 224.392 67.4048 223.833 67.3984C223.69 67.3903 223.552 67.3386 223.439 67.2503C223.326 67.162 223.241 67.0411 223.198 66.9036C223.185 66.9499 223.175 66.9969 223.168 67.0444C223.162 67.1378 223.174 67.2314 223.204 67.3199C223.235 67.4084 223.282 67.49 223.343 67.56C223.405 67.63 223.48 67.687 223.563 67.7277C223.647 67.7684 223.738 67.7921 223.831 67.7972C224.383 67.7972 224.722 67.1766 225.236 66.9804C225.448 66.8972 225.706 66.8844 225.871 66.716C225.933 66.635 225.977 66.5413 226 66.4415C226.023 66.3418 226.024 66.2382 226.003 66.138C226 66.1124 225.996 66.0954 225.994 66.0762Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M223.339 65.8993C223.287 65.5111 222.821 65.3533 222.575 65.0462C222.425 64.8445 222.343 64.5991 222.342 64.3467C222.325 64.7434 222.332 65.1486 222.575 65.4471C222.819 65.7457 223.189 65.8737 223.308 66.1808C223.338 66.0902 223.348 65.9943 223.339 65.8993Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M222.355 63.6662C222.372 63.1863 222.257 62.5998 221.811 62.4356C221.679 62.3866 221.533 62.3802 221.404 62.3269C221.053 62.1776 220.943 61.7383 220.71 61.4354C220.238 60.8276 219.304 60.8383 218.593 61.1283C218.275 61.2584 217.973 61.4311 217.642 61.5293C217.48 61.5869 217.308 61.6101 217.136 61.5972C216.964 61.5844 216.797 61.5358 216.645 61.4546C216.506 61.365 216.391 61.2413 216.249 61.1518C215.769 60.8617 215.142 61.1518 214.729 61.525C214.317 61.8982 213.982 62.3972 213.459 62.6276C213.222 62.7342 212.934 62.7982 212.811 63.0285C212.758 63.1541 212.735 63.291 212.746 63.4273C212.746 63.5105 212.746 63.5937 212.746 63.6768C212.749 63.5909 212.77 63.5066 212.807 63.4295C212.93 63.1991 213.218 63.1351 213.455 63.0285C213.967 62.7982 214.302 62.3077 214.725 61.9259C215.149 61.5442 215.765 61.2627 216.245 61.5527C216.387 61.638 216.501 61.766 216.641 61.8534C216.793 61.9351 216.96 61.984 217.132 61.9968C217.303 62.0097 217.476 61.9862 217.638 61.9281C217.962 61.812 218.279 61.6789 218.589 61.5293C219.298 61.2392 220.231 61.2264 220.706 61.8342C220.938 62.1371 221.049 62.5764 221.4 62.7257C221.529 62.7811 221.675 62.7875 221.806 62.8366C222.168 62.9731 222.312 63.3825 222.344 63.7877L222.355 63.6662Z",fill:"black"})),Object(E.createElement)("g",{opacity:"0.1"},Object(E.createElement)("path",{opacity:"0.1",d:"M211.928 65.8994C211.94 65.5454 212.066 65.205 212.287 64.9292C212.508 64.6535 212.811 64.4573 213.152 64.3703C214.096 64.1378 215.086 64.183 216.006 64.5004C218.015 65.17 215.752 67.5799 215.752 67.5799C215.752 67.5799 214.246 69.0728 212.843 68.0299C212.428 67.7143 212.138 67.2609 212.024 66.7503C211.955 66.4721 211.923 66.186 211.928 65.8994Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M222.972 65.8991C222.96 65.5448 222.834 65.2042 222.613 64.9284C222.392 64.6526 222.088 64.4566 221.747 64.37C220.803 64.1379 219.814 64.1831 218.895 64.5001C216.886 65.1697 219.149 67.5796 219.149 67.5796C219.149 67.5796 220.652 69.0725 222.058 68.0296C222.472 67.714 222.763 67.2606 222.877 66.75C222.946 66.4718 222.978 66.1857 222.972 65.8991Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M215.627 64.3039V64.4041H219.295V64.2847L215.627 64.3039Z",fill:"black"}),Object(E.createElement)("path",{opacity:"0.1",d:"M216.797 65.3724H216.914V65.0333C216.914 65.0333 217.286 64.7412 217.905 65.0333V65.3362H218.116V65.1378H218.013C218.013 65.1378 218.055 64.7262 217.365 64.7923C217.365 64.7923 216.81 64.739 216.823 65.093H216.696L216.797 65.3724Z",fill:"black"})),Object(E.createElement)("path",{d:"M211.928 65.7608C211.941 65.4068 212.066 65.0664 212.287 64.7906C212.508 64.5149 212.811 64.3187 213.152 64.2317C214.096 64.0008 215.086 64.0459 216.006 64.3618C218.015 65.0336 215.752 67.4413 215.752 67.4413C215.752 67.4413 214.246 68.9342 212.843 67.8913C212.428 67.5765 212.137 67.1228 212.024 66.6117C211.955 66.3336 211.923 66.0474 211.928 65.7608Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M222.973 65.7608C222.961 65.4066 222.835 65.0659 222.613 64.7902C222.392 64.5144 222.088 64.3184 221.747 64.2317C220.804 64.0008 219.815 64.0459 218.896 64.3618C216.887 65.0336 219.15 67.4414 219.15 67.4414C219.15 67.4414 220.653 68.9342 222.058 67.8914C222.474 67.5765 222.764 67.1229 222.878 66.6118C222.947 66.3336 222.979 66.0475 222.973 65.7608Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M215.627 64.1696V64.2719H219.295V64.1504L215.627 64.1696Z",fill:"#2F2E41"}),Object(E.createElement)("path",{d:"M216.797 65.2382H216.914V64.8991C216.914 64.8991 217.286 64.6091 217.905 64.8991V65.2041H218.116V65.0036H218.013C218.013 65.0036 218.055 64.5942 217.365 64.6582C217.365 64.6582 216.81 64.607 216.823 64.9589H216.696L216.797 65.2382Z",fill:"#2F2E41"})),Object(E.createElement)("defs",null,Object(E.createElement)("linearGradient",{id:"paint0_linear",x1:"38982",y1:"103102",x2:"38982",y2:"34934.7",gradientUnits:"userSpaceOnUse"},Object(E.createElement)("stop",{stopColor:"#808080",stopOpacity:"0.25"}),Object(E.createElement)("stop",{offset:"0.54",stopColor:"#808080",stopOpacity:"0.12"}),Object(E.createElement)("stop",{offset:"1",stopColor:"#808080",stopOpacity:"0.1"})),Object(E.createElement)("clipPath",{id:"speed-svg"},Object(E.createElement)("path",{d:"M0 6C0 2.6863 2.68629 0 6 0H289C292.314 0 295 2.68629 295 6V160H0V6Z",fill:"white"}))))};function B(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var c,r=j()(e);if(t){var n=j()(this).constructor;c=Reflect.construct(r,arguments,n)}else c=r.apply(this,arguments);return O()(this,c)}}var z=function(e){f()(r,e);var t,c=B(r);function r(e){var t;return m()(this,r),(t=c.call(this,e)).isJetpackActive=e.activePlugins.includes("jetpack"),t.isWcsActive=e.activePlugins.includes("woocommerce-services"),t.pluginsToInstall=[],t.isJetpackActive||t.pluginsToInstall.push("jetpack"),t.isWcsActive||t.pluginsToInstall.push("woocommerce-services"),Object(S.recordEvent)("storeprofiler_plugins_to_install",{plugins:t.pluginsToInstall}),t.startPluginInstall=t.startPluginInstall.bind(d()(t)),t.skipPluginInstall=t.skipPluginInstall.bind(d()(t)),t}return u()(r,[{key:"skipPluginInstall",value:(t=l()(a.a.mark((function e(){var t,c,r,n,o,i;return a.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t=this.props,c=t.createNotice,r=t.goToNextStep,n=t.isProfileItemsError,o=t.updateProfileItems,i=this.isJetpackActive?"skipped-wcs":"skipped",e.next=4,o({plugins:i});case 4:n?c("error",Object(g.__)("There was a problem updating your preferences.",'woocommerce')):Object(S.recordEvent)("storeprofiler_install_plugins",{install:!1,plugins:i}),r();case 6:case"end":return e.stop()}}),e,this)}))),function(){return t.apply(this,arguments)})},{key:"startPluginInstall",value:function(){var e=this.props,t=e.createNotice,c=e.goToNextStep,r=e.installAndActivatePlugins,n=e.updateProfileItems,o=e.updateOptions,a=this.isJetpackActive?"installed-wcs":"installed";Object(S.recordEvent)("storeprofiler_install_plugins",{install:!0,plugins:a}),Promise.all([r(this.pluginsToInstall),n({plugins:a}),o({woocommerce_setup_jetpack_opted_in:!0})]).then(c).catch((function(e,r){e&&Object(x.a)(e),r&&t("error",Object(g.__)("There was a problem updating your preferences.",'woocommerce')),c()}))}},{key:"renderBenefit",value:function(e){var t=e.description,c=e.icon,r=e.title;return Object(E.createElement)("div",{className:"woocommerce-profile-wizard__benefit-card",key:r},c,Object(E.createElement)("div",{className:"woocommerce-profile-wizard__benefit-card-content"},Object(E.createElement)(T.H,{className:"woocommerce-profile-wizard__benefit-card-title"},r),Object(E.createElement)("p",null,t)))}},{key:"getBenefits",value:function(){return[{title:Object(g.__)("Store management on the go",'woocommerce'),icon:Object(E.createElement)(R,null),description:Object(g.__)("Your store in your pocket. Manage orders, receive sales notifications, and more. Only with a Jetpack connection.",'woocommerce'),visible:!this.isJetpackActive},{title:Object(g.__)("Automated sales taxes",'woocommerce'),icon:Object(E.createElement)(A,null),description:Object(g.__)("Ensure that the correct rate of tax is charged on all of your orders automatically, and print shipping labels at home.",'woocommerce'),visible:!this.isWcsActive||!this.isJetpackActive},{title:Object(g.__)("Improved speed & security",'woocommerce'),icon:Object(E.createElement)(D,null),description:Object(g.__)("Automatically block brute force attacks and speed up your store using our powerful, global server network to cache images.",'woocommerce'),visible:!this.isJetpackActive},{title:Object(g.__)("Print shipping labels at home",'woocommerce'),icon:Object(E.createElement)(F,null),description:Object(g.__)("Save time at the post office by printing shipping labels for your orders at home.",'woocommerce'),visible:this.isJetpackActive&&!this.isWcsActive}]}},{key:"renderBenefits",value:function(){var e=this;return Object(E.createElement)("div",{className:"woocommerce-profile-wizard__benefits"},Object(y.filter)(this.getBenefits(),(function(e){return e.visible})).map((function(t){return e.renderBenefit(t)})))}},{key:"render",value:function(){var e=this.props,t=e.activePlugins,c=e.isInstallingActivating,r=e.isRequesting,n=this.pluginsToInstall.map((function(e){return L.pluginNames[e]})).join(" "+Object(g.__)("and",'woocommerce')+" "),o=this.pluginsToInstall.filter((function(e){return!t.includes(e)})),a=c||!o.length,i=!this.isWcsActive,l=Object(g._n)("plugin","plugins",this.pluginsToInstall.length,'woocommerce');return Object(E.createElement)(T.Card,{className:"woocommerce-profile-wizard__benefits-card"},Object(E.createElement)(I,null),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__step-header"},Object(E.createElement)(N.a,{variant:"title.small",as:"h2"},Object(g.sprintf)(Object(g.__)("Enhance your store with %s",'woocommerce'),n))),this.renderBenefits(),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__card-actions"},Object(E.createElement)(P.a,{isPrimary:!0,isBusy:a,disabled:r||a,onClick:this.startPluginInstall},Object(g.__)("Yes please!",'woocommerce')),Object(E.createElement)(P.a,{isSecondary:!0,isBusy:r&&!a,disabled:r||a,className:"woocommerce-profile-wizard__skip",onClick:this.skipPluginInstall},Object(g.__)("No thanks",'woocommerce'))),Object(E.createElement)("p",{className:"woocommerce-profile-wizard__benefits-install-notice"},i?V()({mixedString:Object(g.sprintf)(Object(g.__)("%s %s will be installed & activated for free, and you agree to our {{link}}Terms of Service{{/link}}.",'woocommerce'),n,l),components:{link:Object(E.createElement)(T.Link,{href:"https://wordpress.com/tos/",target:"_blank",type:"external"})}}):Object(g.sprintf)(Object(g.__)("%s %s will be installed & activated for free.",'woocommerce'),n,l)))}}]),r}(E.Component),U=Object(v.a)(Object(w.withSelect)((function(e){var t=e(L.ONBOARDING_STORE_NAME),c=t.getOnboardingError,r=t.getProfileItems,n=t.isOnboardingRequesting,o=e(L.PLUGINS_STORE_NAME),a=o.getActivePlugins,i=o.isPluginsRequesting;return{activePlugins:a(),isProfileItemsError:Boolean(c("updateProfileItems")),profileItems:r(),isRequesting:n("updateProfileItems"),isInstallingActivating:i("installPlugins")||i("activatePlugins")||i("getJetpackConnectUrl")}})),Object(w.withDispatch)((function(e){var t=e(L.PLUGINS_STORE_NAME).installAndActivatePlugins,c=e(L.ONBOARDING_STORE_NAME).updateProfileItems,r=e(L.OPTIONS_STORE_NAME).updateOptions;return{createNotice:e("core/notices").createNotice,installAndActivatePlugins:t,updateProfileItems:c,updateOptions:r}})))(z),q=c(38),G=c.n(q),W=c(30),J=c.n(W),Y=c(821),$=c(779),Q=c(136),K=c(298),X=c(191),ee=c(762);function te(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var c,r=j()(e);if(t){var n=j()(this).constructor;c=Reflect.construct(r,arguments,n)}else c=r.apply(this,arguments);return O()(this,c)}}var ce=Object(M.g)("wcAdminAssetUrl",""),re=function(e){f()(r,e);var t,c=te(r);function r(e){var t;m()(this,r),t=c.call(this);var n=Object(y.get)(e,"settings",{}),o=Object(y.get)(e,"profileItems",{}),a=Object(y.get)(o,"industry",[]).map((function(e){return e.slug})),i=Object(y.get)(o,"business_extensions",!1);return t.state={isPopoverVisible:!1},t.initialValues={other_platform:o.other_platform||"",other_platform_name:o.other_platform_name||"",product_count:o.product_count||"",selling_venues:o.selling_venues||"",revenue:o.revenue||"","facebook-for-woocommerce":!i||i.includes("facebook-for-woocommerce"),"mailchimp-for-woocommerce":!i||i.includes("mailchimp-for-woocommerce"),"creative-mail-by-constant-contact":!i||i.includes("creative-mail-by-constant-contact"),"kliken-marketing-for-google":!i||i.includes("kliken-marketing-for-google"),install_extensions:!0},t.extensions=["facebook-for-woocommerce","mailchimp-for-woocommerce","kliken-marketing-for-google","creative-mail-by-constant-contact"],t.bundleInstall="US"===Object(X.b)(n.woocommerce_default_country)&&(a.includes("fashion-apparel-accessories")||a.includes("health-beauty"))&&!a.includes("cbd-other-hemp-derived-products"),t.onContinue=t.onContinue.bind(d()(t)),t.validate=t.validate.bind(d()(t)),t.getNumberRangeString=t.getNumberRangeString.bind(d()(t)),t.numberFormat=t.numberFormat.bind(d()(t)),t}return u()(r,[{key:"onContinue",value:(t=l()(a.a.mark((function e(t){var c,r,n,o,i,l,s,m,C,u,p,d,b,f,h,O;return a.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:c=this.props,r=c.createNotice,n=c.goToNextStep,o=c.installAndActivatePlugins,i=c.updateProfileItems,l=t.install_extensions,s=t.other_platform,m=t.other_platform_name,C=t.product_count,u=t.revenue,p=t.selling_venues,d=this.getBusinessExtensions(t),b=this.context.getCurrencyConfig,Object(S.recordEvent)("storeprofiler_store_business_details_continue",{product_number:C,already_selling:p,currency:b().code,revenue:u,used_platform:s,used_platform_name:m,install_woocommerce_services:d.includes("facebook-for-woocommerce"),install_jetpack:d.includes("jetpack"),install_facebook:d.includes("facebook-for-woocommerce"),install_mailchimp:d.includes("mailchimp-for-woocommerce"),install_creative_mail:d.includes("creative-mail-by-constant-contact"),install_google_ads:d.includes("kliken-marketing-for-google"),install_extensions:l,bundle_install:this.bundleInstall}),f={other_platform:s,other_platform_name:"other"===s?m:"",product_count:C,revenue:u,selling_venues:p,business_extensions:d},h={},Object.keys(f).forEach((function(e){""!==f[e]&&(h[e]=f[e])})),O=[i(h).catch((function(){throw new Error}))],d.length&&O.push(o(d).then((function(e){Object(x.a)(e)})).catch((function(e){throw Object(x.a)(e),new Error}))),Promise.all(O).then((function(){n()})).catch((function(){r("error",Object(g.__)("There was a problem updating your business details.",'woocommerce'))}));case 11:case"end":return e.stop()}}),e,this)}))),function(e){return t.apply(this,arguments)})},{key:"validate",value:function(e){var t={};return e.product_count.length||(t.product_count=Object(g.__)("This field is required",'woocommerce')),e.selling_venues.length||(t.selling_venues=Object(g.__)("This field is required",'woocommerce')),!e.other_platform.length&&["other","brick-mortar-other"].includes(e.selling_venues)&&(t.other_platform=Object(g.__)("This field is required",'woocommerce')),!e.other_platform_name&&"other"===e.other_platform&&["other","brick-mortar-other"].includes(e.selling_venues)&&(t.other_platform_name=Object(g.__)("This field is required",'woocommerce')),!e.revenue.length&&["other","brick-mortar","brick-mortar-other","other-woocommerce"].includes(e.selling_venues)&&(t.revenue=Object(g.__)("This field is required",'woocommerce')),t}},{key:"getBusinessExtensions",value:function(e){var t=this;return this.bundleInstall?e.install_extensions?["jetpack","woocommerce-services","woocommerce-payments"].concat(J()(this.extensions)):[]:""===e.selling_venues?[]:Object(y.keys)(Object(y.pickBy)(e)).filter((function(e){return t.extensions.includes(e)}))}},{key:"convertCurrency",value:function(e){var t=Object(X.c)(this.props.settings.woocommerce_default_country);if("US"===t)return e;var c={US:1,EU:.9,IN:71.24,GB:.76,BR:4.19,VN:23172.5,ID:14031,BD:84.87,PK:154.8,RU:63.74,TR:5.75,MX:19.37,CA:1.32},r=c[t]||c.US,n=r.toString().split(".")[0].length,o=Math.pow(10,2+n);return Math.round(e*r/o)*o}},{key:"numberFormat",value:function(e){var t=this.context.getCurrencyConfig;return Object(K.formatValue)(t(),"number",e)}},{key:"getNumberRangeString",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],c=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.numberFormat;return t?Object(g.sprintf)(Object(g._x)("%1$s - %2$s","store product count or revenue range",'woocommerce'),c(e),c(t)):Object(g.sprintf)(Object(g._x)("%s+","store product count or revenue",'woocommerce'),c(e))}},{key:"renderBusinessExtensionHelpText",value:function(e){var t=this.props.isInstallingActivating,c=this.getBusinessExtensions(e);if(0===c.length)return null;var r=c.map((function(e){return L.pluginNames[e]})).join(", ");if(t)return Object(E.createElement)(N.a,{variant:"caption",as:"p"},Object(g.sprintf)(Object(g._n)("Installing the following plugin: %s","Installing the following plugins: %s",c.length,'woocommerce'),r));var n=this.bundleInstall?Object(g.__)("User accounts are required to use these features.",'woocommerce'):"";return Object(E.createElement)("div",{className:"woocommerce-profile-wizard__footnote"},Object(E.createElement)(N.a,{variant:"caption",as:"p"},Object(g.sprintf)(Object(g._n)("The following plugin will be installed for free: %s. %s","The following plugins will be installed for free: %s. %s",c.length,'woocommerce'),r,n)),this.bundleInstall&&Object(E.createElement)(N.a,{variant:"caption",as:"p"},V()({mixedString:Object(g.__)("By installing Jetpack and WooCommerce Shipping plugins for free you agree to our {{link}}Terms of Service{{/link}}.",'woocommerce'),components:{link:Object(E.createElement)(T.Link,{href:"https://wordpress.com/tos/",target:"_blank",type:"external"})}})))}},{key:"renderBusinessExtensions",value:function(e,t){if(""===e.selling_venues)return null;var c=[{slug:"facebook-for-woocommerce",title:Object(g.__)("Market on Facebook",'woocommerce'),icon:"onboarding/fb-woocommerce.png",description:Object(g.__)("Grow your business by targeting the right people and driving sales with Facebook.",'woocommerce')},{slug:"mailchimp-for-woocommerce",title:Object(g.__)("Contact customers with Mailchimp",'woocommerce'),icon:"onboarding/mailchimp.png",description:Object(g.__)("Send targeted campaigns, recover abandoned carts and much more with Mailchimp.",'woocommerce')},{slug:"creative-mail-by-constant-contact",title:Object(g.__)("Email marketing for WooCommerce with Creative Mail",'woocommerce'),icon:"onboarding/creativemail.png",description:Object(g.__)("Create on-brand store campaigns, fast email promotions and customer retargeting with Creative Mail.",'woocommerce')},{slug:"kliken-marketing-for-google",title:Object(g.__)("Drive traffic to your store with Google Ads & Marketing by Kliken",'woocommerce'),icon:"onboarding/g-shopping.png",description:Object(g.__)("Get in front of shoppers and drive traffic so you can grow your business with Smart Shopping Campaigns and free listings.",'woocommerce')}];return Object(E.createElement)(E.Fragment,null,c.map((function(c){return Object(E.createElement)("div",{className:"woocommerce-profile-wizard__benefit",key:c.title},Object(E.createElement)("div",{className:"woocommerce-profile-wizard__business-extension"},Object(E.createElement)("img",{src:ce+c.icon,alt:""})),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__benefit-content"},Object(E.createElement)(T.H,{className:"woocommerce-profile-wizard__benefit-title"},c.title),Object(E.createElement)("p",null,c.description)),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__benefit-toggle"},Object(E.createElement)(Y.a,G()({checked:e[c.slug]},t(c.slug)))))})))}},{key:"renderBusinessExtensionsBundle",value:function(e,t){var c=this,r=this.state.isPopoverVisible;return Object(E.createElement)("div",{className:"woocommerce-business-extensions"},Object(E.createElement)("label",{htmlFor:"woocommerce-business-extensions__checkbox"},Object(E.createElement)($.a,G()({id:"woocommerce-business-extensions__checkbox"},t("install_extensions"))),Object(E.createElement)("span",{className:"woocommerce-business-extensions__label-text"},V()({mixedString:Object(g.__)("Install recommended {{strong}}free{{/strong}} business features",'woocommerce'),components:{strong:Object(E.createElement)("strong",null)}}),Object(E.createElement)("span",{className:"woocommerce-business-extensions__label-subtext"},Object(g.__)("Requires an account",'woocommerce')))),Object(E.createElement)("div",{className:"woocommerce-business-extensions__popover-wrapper"},Object(E.createElement)(P.a,{isTertiary:!0,label:Object(g.__)("Learn more about recommended free business features",'woocommerce'),onClick:function(){Object(S.recordEvent)("storeprofiler_store_business_details_popover"),c.setState({isPopoverVisible:!0})}},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"info")),r&&Object(E.createElement)(Q.a,{className:"woocommerce-business-extensions__popover",focusOnMount:"container",position:"top center",onClose:function(){return c.setState({isPopoverVisible:!1})}},Object(E.createElement)("div",{className:"woocommerce-business-extensions__benefits"},Object(E.createElement)("div",{className:"woocommerce-business-extensions__benefit"},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"check"),Object(g.__)("Manage your store on the go with the WooCommerce mobile app",'woocommerce')),Object(E.createElement)("div",{className:"woocommerce-business-extensions__benefit"},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"check"),Object(g.__)("Accept credit cards with WooCommerce Payments",'woocommerce')),Object(E.createElement)("div",{className:"woocommerce-business-extensions__benefit"},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"check"),Object(g.__)("Speed & security enhancements",'woocommerce')),Object(E.createElement)("div",{className:"woocommerce-business-extensions__benefit"},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"check"),Object(g.__)("Automatic sales taxes",'woocommerce')),Object(E.createElement)("div",{className:"woocommerce-business-extensions__benefit"},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"check"),Object(g.__)("Market on Facebook",'woocommerce')),Object(E.createElement)("div",{className:"woocommerce-business-extensions__benefit"},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"check"),Object(g.__)("Contact customers with Mailchimp",'woocommerce')),Object(E.createElement)("div",{className:"woocommerce-business-extensions__benefit"},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"check"),Object(g.__)("Drive sales with Google Ads",'woocommerce')),Object(E.createElement)("div",{className:"woocommerce-business-extensions__benefit"},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"check"),Object(g.__)("Print shipping labels at home",'woocommerce'))))))}},{key:"render",value:function(){var e=this,t=this.props,c=t.goToNextStep,r=t.isInstallingActivating,n=t.hasInstallActivateError,o=this.context.formatAmount,a=[{key:"0",label:Object(g.__)("I don't have any products yet.",'woocommerce')},{key:"1-10",label:this.getNumberRangeString(1,10)},{key:"11-100",label:this.getNumberRangeString(11,100)},{key:"101-1000",label:this.getNumberRangeString(101,1e3)},{key:"1000+",label:this.getNumberRangeString(1e3)}],i=[{key:"none",label:Object(g.sprintf)(Object(g.__)("%s (I'm just getting started)",'woocommerce'),o(0))},{key:"up-to-2500",label:Object(g.sprintf)(Object(g.__)("Up to %s",'woocommerce'),o(this.convertCurrency(2500)))},{key:"2500-10000",label:this.getNumberRangeString(this.convertCurrency(2500),this.convertCurrency(1e4),o)},{key:"10000-50000",label:this.getNumberRangeString(this.convertCurrency(1e4),this.convertCurrency(5e4),o)},{key:"50000-250000",label:this.getNumberRangeString(this.convertCurrency(5e4),this.convertCurrency(25e4),o)},{key:"more-than-250000",label:Object(g.sprintf)(Object(g.__)("More than %s",'woocommerce'),o(this.convertCurrency(25e4)))}],l=[{key:"no",label:Object(g.__)("No",'woocommerce')},{key:"other",label:Object(g.__)("Yes, on another platform",'woocommerce')},{key:"other-woocommerce",label:Object(g.__)("Yes, I own a different store powered by WooCommerce",'woocommerce')},{key:"brick-mortar",label:Object(g.__)("Yes, in person at physical stores and/or events",'woocommerce')},{key:"brick-mortar-other",label:Object(g.__)("Yes, on another platform and in person at physical stores and/or events",'woocommerce')}],s=[{key:"shopify",label:Object(g.__)("Shopify",'woocommerce')},{key:"bigcommerce",label:Object(g.__)("BigCommerce",'woocommerce')},{key:"magento",label:Object(g.__)("Magento",'woocommerce')},{key:"wix",label:Object(g.__)("Wix",'woocommerce')},{key:"amazon",label:Object(g.__)("Amazon",'woocommerce')},{key:"ebay",label:Object(g.__)("eBay",'woocommerce')},{key:"etsy",label:Object(g.__)("Etsy",'woocommerce')},{key:"squarespace",label:Object(g.__)("Squarespace",'woocommerce')},{key:"other",label:Object(g.__)("Other",'woocommerce')}];return Object(E.createElement)(T.Form,{initialValues:this.initialValues,onSubmitCallback:this.onContinue,validate:this.validate},(function(t){var o=t.getInputProps,m=t.handleSubmit,C=t.values,u=t.isValidForm;return Object(E.createElement)(E.Fragment,null,Object(E.createElement)("div",{className:"woocommerce-profile-wizard__step-header"},Object(E.createElement)(N.a,{variant:"title.small",as:"h2"},Object(g.__)("Tell us about your business",'woocommerce')),Object(E.createElement)(N.a,{variant:"body"},Object(g.__)("We'd love to know if you are just getting started or you already have a business in place.",'woocommerce'))),Object(E.createElement)(T.Card,null,Object(E.createElement)(E.Fragment,null,Object(E.createElement)(T.SelectControl,G()({label:Object(g.__)("How many products do you plan to display?",'woocommerce'),options:a,required:!0},o("product_count"))),Object(E.createElement)(T.SelectControl,G()({label:Object(g.__)("Currently selling elsewhere?",'woocommerce'),options:l,required:!0},o("selling_venues"))),["other","brick-mortar","brick-mortar-other","other-woocommerce"].includes(C.selling_venues)&&Object(E.createElement)(T.SelectControl,G()({label:Object(g.__)("What's your current annual revenue?",'woocommerce'),options:i,required:!0},o("revenue"))),["other","brick-mortar-other"].includes(C.selling_venues)&&Object(E.createElement)(E.Fragment,null,Object(E.createElement)("div",{className:"business-competitors"},Object(E.createElement)(T.SelectControl,G()({label:Object(g.__)("Which platform is the store using?",'woocommerce'),options:s,required:!0},o("other_platform"))),"other"===C.other_platform&&Object(E.createElement)(T.TextControl,G()({label:Object(g.__)("What is the platform name?",'woocommerce'),required:!0},o("other_platform_name"))))),e.bundleInstall?e.renderBusinessExtensionsBundle(C,o):e.renderBusinessExtensions(C,o),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__card-actions"},Object(E.createElement)(P.a,{isPrimary:!0,onClick:m,disabled:!u,isBusy:r},n?Object(g.__)("Retry",'woocommerce'):Object(g.__)("Continue",'woocommerce')),n&&Object(E.createElement)(P.a,{onClick:function(){return c()}},Object(g.__)("Continue without installing",'woocommerce'))))),e.renderBusinessExtensionHelpText(C))}))}}]),r}(E.Component);re.contextType=ee.a;var ne=Object(v.a)(Object(w.withSelect)((function(e){var t=e(L.SETTINGS_STORE_NAME),c=t.getSettings,r=t.getSettingsError,n=e(L.ONBOARDING_STORE_NAME),o=n.getProfileItems,a=n.getOnboardingError,i=e(L.PLUGINS_STORE_NAME),l=i.getPluginsError,s=i.isPluginsRequesting,m=c("general").general,C=void 0===m?{}:m;return{hasInstallActivateError:l("installPlugins")||l("activatePlugins"),isError:Boolean(a("updateProfileItems")),profileItems:o(),isSettingsError:Boolean(r("general")),settings:C,isInstallingActivating:s("installPlugins")||s("activatePlugins")||s("getJetpackConnectUrl")}})),Object(w.withDispatch)((function(e){var t=e(L.ONBOARDING_STORE_NAME).updateProfileItems,c=e(L.PLUGINS_STORE_NAME).installAndActivatePlugins;return{createNotice:e("core/notices").createNotice,installAndActivatePlugins:c,updateProfileItems:t}})))(re);function oe(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var c,r=j()(e);if(t){var n=j()(this).constructor;c=Reflect.construct(r,arguments,n)}else c=r.apply(this,arguments);return O()(this,c)}}var ae=Object(M.g)("onboarding",{}),ie=function(e){f()(n,e);var t,c,r=oe(n);function n(e){var t;m()(this,n);var c=Object(y.get)(e,"profileItems",{}).industry||[],o=e.locationSettings;if("US"!==Object(X.c)(o.woocommerce_default_country)){var a="cbd-other-hemp-derived-products";c=c.filter((function(e){return a!==e&&a!==e.slug}))}return(t=r.call(this)).state={error:null,selected:c,textInputListContent:{}},t.onContinue=t.onContinue.bind(d()(t)),t.onIndustryChange=t.onIndustryChange.bind(d()(t)),t.onDetailChange=t.onDetailChange.bind(d()(t)),t}return u()(n,[{key:"onContinue",value:(c=l()(a.a.mark((function e(){var t,c,r,n,o,i,l;return a.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.validateField();case 2:if(!this.state.error){e.next=4;break}return e.abrupt("return");case 4:return t=this.props,c=t.createNotice,r=t.goToNextStep,n=t.isError,o=t.updateProfileItems,i=this.state.selected.map((function(e){return e.slug})),l=this.state.selected.map((function(e){return e.detail})).filter((function(e){return e})).join(","),Object(S.recordEvent)("storeprofiler_store_industry_continue",{store_industry:i,industries_with_detail:l}),e.next=10,o({industry:this.state.selected});case 10:n?c("error",Object(g.__)("There was a problem updating your industries.",'woocommerce')):r();case 11:case"end":return e.stop()}}),e,this)}))),function(){return c.apply(this,arguments)})},{key:"validateField",value:(t=l()(a.a.mark((function e(){var t;return a.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:t=this.state.selected.length?null:Object(g.__)("Please select at least one industry",'woocommerce'),this.setState({error:t});case 2:case"end":return e.stop()}}),e,this)}))),function(){return t.apply(this,arguments)})},{key:"onIndustryChange",value:function(e){var t=this;this.setState((function(t){var c=t.selected,r=Object(y.find)(c,{slug:e});if(r){var n=t.textInputListContent;return n[e]=r.detail,{selected:Object(y.filter)(t.selected,(function(t){return t.slug!==e}))||[],textInputListContent:n}}return c.push({slug:e,detail:t.textInputListContent[e]}),{selected:c}}),(function(){return t.validateField()}))}},{key:"onDetailChange",value:function(e,t){this.setState((function(c){var r=c.selected,n=c.textInputListContent;return r[Object(y.findIndex)(r,{slug:t})].detail=e,n[t]=e,{selected:r,textInputListContent:n}}))}},{key:"render",value:function(){var e=this,t=ae.industries,c=this.state,r=c.error,n=c.selected,o=c.textInputListContent,a=this.props.locationSettings,i=Object(X.c)(a.woocommerce_default_country),l=Object.keys(t),s="US"===i?l:l.filter((function(e){return"cbd-other-hemp-derived-products"!==e}));return Object(E.createElement)(E.Fragment,null,Object(E.createElement)("div",{className:"woocommerce-profile-wizard__step-header"},Object(E.createElement)(N.a,{variant:"title.small",as:"h2"},Object(g.__)("In which industry does the store operate?",'woocommerce')),Object(E.createElement)(N.a,{variant:"body"},Object(g.__)("Choose any that apply"))),Object(E.createElement)(T.Card,null,Object(E.createElement)("div",{className:"woocommerce-profile-wizard__checkbox-group"},s.map((function(c){var r=Object(y.find)(n,{slug:c});return Object(E.createElement)("div",{key:"div-".concat(c)},Object(E.createElement)($.a,{key:"checkbox-control-".concat(c),label:t[c].label,onChange:function(){return e.onIndustryChange(c)},checked:r||!1,className:"woocommerce-profile-wizard__checkbox"}),t[c].use_description&&r&&Object(E.createElement)(T.TextControl,{key:"text-control-".concat(r.slug),label:t[r.slug].description_label,value:r.detail||o[c]||"",onChange:function(t){return e.onDetailChange(t,r.slug)},className:"woocommerce-profile-wizard__text"}))})),r&&Object(E.createElement)("span",{className:"woocommerce-profile-wizard__error"},r)),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__card-actions"},Object(E.createElement)(P.a,{isPrimary:!0,onClick:this.onContinue,disabled:!n.length},Object(g.__)("Continue",'woocommerce')))))}}]),n}(E.Component),le=Object(v.a)(Object(w.withSelect)((function(e){var t=e(L.ONBOARDING_STORE_NAME),c=t.getProfileItems,r=t.getOnboardingError,n=(0,e(L.SETTINGS_STORE_NAME).getSettings)("general").general,o=void 0===n?{}:n;return{isError:Boolean(r("updateProfileItems")),profileItems:c(),locationSettings:o}})),Object(w.withDispatch)((function(e){var t=e(L.ONBOARDING_STORE_NAME).updateProfileItems;return{createNotice:e("core/notices").createNotice,updateProfileItems:t}})))(ie),se=c(34),me=c.n(se),Ce=c(159);function ue(e){var t=e.annualPrice,c=e.description,r=e.isMonthlyPricing,n=e.label,o=e.moreUrl,a=e.slug,i=Object(E.useState)(""),l=me()(i,2),s=l[0],m=l[1];if(!t)return n;var C=Object(g.__)("This product type requires a paid extension.\nWe'll add this to a cart so that\nyou can purchase and install it later.",'woocommerce');return Object(E.createElement)(E.Fragment,null,Object(E.createElement)("span",{className:"woocommerce-product-wizard__product-types-label"},n),Object(E.createElement)(P.a,{isTertiary:!0,label:Object(g.__)("Learn more about recommended free business features",'woocommerce'),onClick:function(){m(!0)}},Object(E.createElement)("i",{className:"material-icons-outlined","aria-hidden":"true"},"info")),s&&Object(E.createElement)(Q.a,{focusOnMount:"container",position:"top center",onClose:function(){return m(!1)}},V()({mixedString:c+(o?" {{moreLink/}}":""),components:{moreLink:o?Object(E.createElement)(T.Link,{href:o,target:"_blank",type:"external",onClick:function(){return Object(S.recordEvent)("storeprofiler_store_product_type_learn_more",{product_type:a})}},Object(g.__)("Learn more",'woocommerce')):""}})),Object(E.createElement)(Ce.a,{text:C,position:"bottom center"},Object(E.createElement)(T.Pill,null,Object(E.createElement)("span",{className:"screen-reader-text"},C),r?Object(g.sprintf)(Object(g.__)("$%f per month",'woocommerce'),(t/12).toFixed(2)):Object(g.sprintf)(Object(g.__)("$%f per year",'woocommerce'),t))))}c(822);function pe(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var c,r=j()(e);if(t){var n=j()(this).constructor;c=Reflect.construct(r,arguments,n)}else c=r.apply(this,arguments);return O()(this,c)}}var de=function(e){f()(c,e);var t=pe(c);function c(e){var r;m()(this,c),r=t.call(this);var n=Object(y.get)(e,"profileItems",{}),o=Object(M.g)("onboarding",{}).productTypes,a=void 0===o?{}:o,i=Object.keys(a).filter((function(e){return!!a[e].default}));return r.state={error:null,isMonthlyPricing:!0,selected:n.product_types||i},r.onContinue=r.onContinue.bind(d()(r)),r.onChange=r.onChange.bind(d()(r)),r}return u()(c,[{key:"validateField",value:function(){var e=this.state.selected.length?null:Object(g.__)("Please select at least one product type",'woocommerce');return this.setState({error:e}),!e}},{key:"onContinue",value:function(){if(this.validateField()){var e=this.props,t=e.createNotice,c=e.goToNextStep,r=e.updateProfileItems;Object(S.recordEvent)("storeprofiler_store_product_type_continue",{product_type:this.state.selected}),r({product_types:this.state.selected}).then((function(){return c()})).catch((function(){return t("error",Object(g.__)("There was a problem updating your product types.",'woocommerce'))}))}}},{key:"onChange",value:function(e){var t=this;this.setState((function(t){if(Object(y.includes)(t.selected,e))return{selected:Object(y.filter)(t.selected,(function(t){return t!==e}))||[]};var c=t.selected;return c.push(e),{selected:c}}),(function(){return t.validateField()}))}},{key:"render",value:function(){var e=this,t=Object(M.g)("onboarding",{}).productTypes,c=void 0===t?{}:t,r=this.state,n=r.error,o=r.isMonthlyPricing,a=r.selected;return Object(E.createElement)("div",{className:"woocommerce-profile-wizard__product-types"},Object(E.createElement)("div",{className:"woocommerce-profile-wizard__step-header"},Object(E.createElement)(N.a,{variant:"title.small",as:"h2"},Object(g.__)("What type of products will be listed?",'woocommerce')),Object(E.createElement)(N.a,{variant:"body"},Object(g.__)("Choose any that apply"))),Object(E.createElement)(T.Card,null,Object(E.createElement)("div",{className:"woocommerce-profile-wizard__checkbox-group"},Object.keys(c).map((function(t){return Object(E.createElement)($.a,{key:t,label:Object(E.createElement)(ue,{description:c[t].description,label:c[t].label,annualPrice:c[t].yearly_price,isMonthlyPricing:o,moreUrl:c[t].more_url,slug:t}),onChange:function(){return e.onChange(t)},checked:a.includes(t),className:"woocommerce-profile-wizard__checkbox"})})),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__product-types-pricing-toggle woocommerce-profile-wizard__checkbox"},Object(E.createElement)("label",{htmlFor:"woocommerce-product-types__pricing-toggle"},Object(E.createElement)(N.a,{variant:"body"},Object(g.__)("Display monthly prices",'woocommerce')),Object(E.createElement)(Y.a,{id:"woocommerce-product-types__pricing-toggle",checked:o,onChange:function(){return e.setState({isMonthlyPricing:!o})}}))),n&&Object(E.createElement)("span",{className:"woocommerce-profile-wizard__error"},n),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__card-actions"},Object(E.createElement)(P.a,{isPrimary:!0,onClick:this.onContinue,disabled:!a.length},Object(g.__)("Continue",'woocommerce'))))),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__card-help-text"},Object(E.createElement)(N.a,{variant:"caption"},Object(g.__)("Billing is annual. All purchases are covered by our 30 day money back guarantee and include access to support and updates. Extensions will be added to a cart for you to purchase later.",'woocommerce'))))}}]),c}(E.Component),be=Object(v.a)(Object(w.withSelect)((function(e){var t=e(L.ONBOARDING_STORE_NAME),c=t.getProfileItems,r=t.getOnboardingError;return{isError:Boolean(r("updateProfileItems")),profileItems:c()}})),Object(w.withDispatch)((function(e){var t=e(L.ONBOARDING_STORE_NAME).updateProfileItems;return{createNotice:e("core/notices").createNotice,updateProfileItems:t}})))(de);function fe(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var c,r=j()(e);if(t){var n=j()(this).constructor;c=Reflect.construct(r,arguments,n)}else c=r.apply(this,arguments);return O()(this,c)}}var he=function(e){f()(c,e);var t=fe(c);function c(){return m()(this,c),t.apply(this,arguments)}return u()(c,[{key:"renderStepper",value:function(){var e=this.props,t=e.currentStep,c=e.steps,r=Object(y.filter)(c,(function(e){return!!e.label})),n=r.findIndex((function(e){return e.key===t}));return r.map((function(e,t){var c=r[t-1];return t1&&void 0!==arguments[1]?arguments[1]:"",c=this.props.updateProfileItems,r=e.is_installed,n=e.price,o=e.slug,a=Object(M.g)("onboarding",{}),i=a.activeTheme,l=void 0===i?"":i;this.setState({chosen:o}),Object(S.recordEvent)("storeprofiler_store_theme_choose",{theme:o,location:t}),o!==l&&Object(X.d)(n)<=0?r?this.activateTheme(o):this.installTheme(o):c({theme:o})}},{key:"installTheme",value:function(e){var t=this,c=this.props.createNotice;Te()({path:"/wc-admin/onboarding/themes/install?theme="+e,method:"POST"}).then((function(r){c("success",Object(g.sprintf)(Object(g.__)("%s was installed on your site.",'woocommerce'),r.name)),t.activateTheme(e)})).catch((function(e){t.setState({chosen:null}),c("error",e.message)}))}},{key:"activateTheme",value:function(e){var t=this,c=this.props,r=c.createNotice,n=c.updateProfileItems;Te()({path:"/wc-admin/onboarding/themes/activate?theme="+e,method:"POST"}).then((function(t){r("success",Object(g.sprintf)(Object(g.__)("%s was activated on your site.",'woocommerce'),t.name)),Object(M.h)("onboarding",Xe(Xe({},Object(M.g)("onboarding",{})),{},{activeTheme:t.slug})),n({theme:e})})).catch((function(e){t.setState({chosen:null}),r("error",e.message)}))}},{key:"onClosePreview",value:function(){var e=this.state.demo;Object(S.recordEvent)("storeprofiler_store_theme_demo_close",{theme:e.slug}),document.body.classList.remove("woocommerce-theme-preview-active"),this.setState({demo:null})}},{key:"openDemo",value:function(e){Object(S.recordEvent)("storeprofiler_store_theme_live_demo",{theme:e.slug}),document.body.classList.add("woocommerce-theme-preview-active"),this.setState({demo:e})}},{key:"skipStep",value:function(){var e=Object(M.g)("onboarding",{}).activeTheme,t=void 0===e?"":e;Object(S.recordEvent)("storeprofiler_store_theme_skip_step",{activeTheme:t}),this.props.goToNextStep()}},{key:"renderTheme",value:function(e){var t=this,c=e.demo_url,r=e.has_woocommerce_support,n=e.image,o=e.slug,a=e.title,i=this.state.chosen,l=Object(M.g)("onboarding",{}).activeTheme,s=void 0===l?"":l;return Object(E.createElement)(T.Card,{className:"woocommerce-profile-wizard__theme",key:o},n&&Object(E.createElement)("div",{className:"woocommerce-profile-wizard__theme-image",style:{backgroundImage:"url(".concat(n,")")},role:"img","aria-label":a}),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__theme-details"},Object(E.createElement)(T.H,{className:"woocommerce-profile-wizard__theme-name"},a,!r&&Object(E.createElement)(Ce.a,{text:Object(g.__)("This theme does not support WooCommerce.",'woocommerce')},Object(E.createElement)("span",null,Object(E.createElement)(Ie.a,{icon:"info",role:"img","aria-hidden":"true",focusable:"false"})))),Object(E.createElement)("p",{className:"woocommerce-profile-wizard__theme-status"},this.getThemeStatus(e)),Object(E.createElement)("div",{className:"woocommerce-profile-wizard__theme-actions"},o===s?Object(E.createElement)(P.a,{isPrimary:!0,onClick:function(){return t.onChoose(e,"card")},isBusy:i===o},Object(g.__)("Continue with my active theme",'woocommerce')):Object(E.createElement)(P.a,{isSecondary:!0,onClick:function(){return t.onChoose(e,"card")},isBusy:i===o},Object(g.__)("Choose",'woocommerce')),c&&Object(E.createElement)(P.a,{isTertiary:!0,onClick:function(){return t.openDemo(e)}},Object(g.__)("Live demo",'woocommerce')))))}},{key:"getThemeStatus",value:function(e){var t=e.is_installed,c=e.price,r=e.slug,n=Object(M.g)("onboarding",{}).activeTheme;return(void 0===n?"":n)===r?Object(g.__)("Currently active theme",'woocommerce'):t?Object(g.__)("Installed",'woocommerce'):Object(X.d)(c)<=0?Object(g.__)("Free",'woocommerce'):Object(g.sprintf)(Object(g.__)("%s per year",'woocommerce'),Object(xe.decodeEntities)(c))}},{key:"doesActiveThemeSupportWooCommerce",value:function(){var e=Object(M.g)("onboarding",{}).activeTheme,t=void 0===e?"":e,c=this.getThemes().find((function(e){return e.slug===t}));return c&&c.has_woocommerce_support}},{key:"onSelectTab",value:function(e){Object(S.recordEvent)("storeprofiler_store_theme_navigate",{navigation:e}),this.setState({activeTab:e})}},{key:"getPriceValue",value:function(e){return Number(Object(xe.decodeEntities)(e).replace(/[^0-9.-]+/g,""))}},{key:"getThemes",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"all",t=this.state.uploadedThemes,c=Object(M.g)("onboarding",{}),r=c.activeTheme,n=void 0===r?"":r,o=c.themes,a=void 0===o?[]:o,i=[].concat(J()(a.filter((function(e){return e&&(e.has_woocommerce_support||e.slug===n)}))),J()(t));switch(e){case"paid":return i.filter((function(e){return Object(X.d)(e.price)>0}));case"free":return i.filter((function(e){return Object(X.d)(e.price)<=0}));case"all":default:return i}}},{key:"handleUploadComplete",value:function(e){"success"===e.status&&e.theme_data&&(this.setState({uploadedThemes:[].concat(J()(this.state.uploadedThemes),[e.theme_data])}),Object(S.recordEvent)("storeprofiler_store_theme_upload",{theme:e.theme_data.slug}))}},{key:"render",value:function(){var e=this,t=this.state,c=t.activeTab,r=t.chosen,n=t.demo,o=this.getThemes(c),a=this.doesActiveThemeSupportWooCommerce();return Object(E.createElement)(E.Fragment,null,Object(E.createElement)("div",{className:"woocommerce-profile-wizard__step-header"},Object(E.createElement)(N.a,{variant:"title.small",as:"h2"},Object(g.__)("Choose a theme",'woocommerce')),Object(E.createElement)(N.a,{variant:"body"},Object(g.__)("Choose how your store appears to customers. And don't worry, you can always switch themes and edit them later.",'woocommerce'))),Object(E.createElement)(Re.a,{className:"woocommerce-profile-wizard__themes-tab-panel",activeClass:"is-active",onSelect:this.onSelectTab,tabs:[{name:"all",title:Object(g.__)("All themes",'woocommerce')},{name:"paid",title:Object(g.__)("Paid themes",'woocommerce')},{name:"free",title:Object(g.__)("Free themes",'woocommerce')}]},(function(){return Object(E.createElement)("div",{className:"woocommerce-profile-wizard__themes"},o&&o.map((function(t){return e.renderTheme(t)})),Object(E.createElement)(Je,{onUploadComplete:e.handleUploadComplete}))})),n&&Object(E.createElement)(Qe,{theme:n,onChoose:function(){return e.onChoose(n,"card")},onClose:this.onClosePreview,isBusy:r===n.slug}),a&&Object(E.createElement)("p",{className:"woocommerce-profile-wizard__themes-skip-this-step"},Object(E.createElement)(P.a,{isLink:!0,className:"woocommerce-profile-wizard__skip",onClick:function(){return e.skipStep()}},Object(g.__)("Skip this step",'woocommerce'))))}}]),c}(E.Component),ct=Object(v.a)(Object(w.withSelect)((function(e){var t=e(L.ONBOARDING_STORE_NAME),c=t.getProfileItems,r=t.getOnboardingError,n=t.isOnboardingRequesting;return{isError:Boolean(r("updateProfileItems")),isUpdatingProfileItems:n("updateProfileItems"),profileItems:c()}})),Object(w.withDispatch)((function(e){var t=e(L.ONBOARDING_STORE_NAME).updateProfileItems;return{createNotice:e("core/notices").createNotice,updateProfileItems:t}})))(tt);c(826);function rt(e,t){var c=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),c.push.apply(c,r)}return c}function nt(e){for(var t=1;t "+l);if("componentClose"===m.type)throw new Error("Missing opening component token: `"+m.value+"`");if("componentOpen"===m.type){n=t[m.value],i=p;break}b.push(t[m.value])}else b.push(m.value);return n&&(u=function(e,t){var n,r,o=t[e],a=0;for(r=e+1;r0&&this.setState({currentIndex:t-1})}},{key:"nextAlert",value:function(e){e.stopPropagation();var t=this.props.alerts,n=this.state.currentIndex;n0&&this.props.isLoading)return Object(b.createElement)(W,{hasMultipleAlerts:t>1});if(0===e.length)return null;var n=this.state.currentIndex,r=e.length,o=e[n],a=o.type,c=j()("woocommerce-store-alerts","woocommerce-analytics__card",{"is-alert-error":"error"===a,"is-alert-update":"update"===a});return Object(b.createElement)(M.Card,{title:[o.icon&&Object(b.createElement)(O.a,{key:"icon",icon:o.icon}),Object(b.createElement)(b.Fragment,{key:"title"},o.title)],className:c,action:r>1&&Object(b.createElement)("div",{className:"woocommerce-store-alerts__pagination"},Object(b.createElement)(v.a,{onClick:this.previousAlert,disabled:0===n,label:Object(h.__)("Previous Alert",'woocommerce')},Object(b.createElement)(S.a,{icon:R})),Object(b.createElement)("span",{className:"woocommerce-store-alerts__pagination-label",role:"status","aria-live":"polite"},w()({mixedString:Object(h.__)("{{current /}} of {{total /}}",'woocommerce'),components:{current:Object(b.createElement)(b.Fragment,null,n+1),total:Object(b.createElement)(b.Fragment,null,r)}})),Object(b.createElement)(v.a,{onClick:this.nextAlert,disabled:r-1===n,label:Object(h.__)("Next Alert",'woocommerce')},Object(b.createElement)(S.a,{icon:P.a})))},Object(b.createElement)("div",{className:"woocommerce-store-alerts__message",dangerouslySetInnerHTML:Object(D.a)(o.content)}),this.renderActions(o))}}]),n}(b.Component);t.default=Object(E.a)(Object(N.withSelect)((function(e){var t=e(L.NOTES_STORE_NAME),n=t.getNotes,r=t.isResolving,o={page:1,per_page:L.QUERY_DEFAULTS.pageSize,type:"error,update",status:"unactioned"};return{alerts:n(o).filter((function(e){return"unactioned"===e.status})),isLoading:r("getNotes",[o])}})),Object(N.withDispatch)((function(e){var t=e(L.NOTES_STORE_NAME);return{triggerNoteAction:t.triggerNoteAction,updateNote:t.updateNote}})))(B)}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/store-performance.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/store-performance.js new file mode 100644 index 0000000..75d42c0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/store-performance.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[49],{782:function(e,t,r){"use strict";r.d(t,"b",(function(){return b})),r.d(t,"a",(function(){return y}));var n=r(5),a=r.n(n),c=r(16),o=r.n(c),i=r(2),s=r(40),u=r(35),l=r(32),m=r(298),p=r(36);function d(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function f(e){for(var t=1;t0&&Object(b.createElement)("div",{className:"woocommerce-dashboard__store-performance"},this.renderList()))}}]),r}(b.Component);I.contextType=k.a,t.default=Object(O.a)(Object(v.withSelect)((function(e,t){var r=t.hiddenBlocks,n=t.query,a=t.filters,c=T.filter((function(e){return!r.includes(e.stat)})),o=e(h.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,i={hiddenBlocks:r,userIndicators:c,indicators:T,defaultDateRange:o};if(0===c.length)return i;var s=Object(P.a)(e,c,n,a);return D(D({},i),s)})))(I)}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/task-list.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/task-list.js new file mode 100644 index 0000000..44927c2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/chunks/task-list.js @@ -0,0 +1 @@ +(window.__wcAdmin_webpackJsonp=window.__wcAdmin_webpackJsonp||[]).push([[50],{439:function(e,t,n){"use strict";var o=n(8),c=n(12),r=n(4),a=n.n(r),i=n(0);function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}t.a=function(e){var t=e.as,n=void 0===t?"div":t,r=e.className,l=Object(c.a)(e,["as","className"]);return function(e){var t=e.as,n=void 0===t?"div":t,o=Object(c.a)(e,["as"]);return"function"==typeof o.children?o.children(o):Object(i.createElement)(n,o)}(function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{},n=window.location,o=n.pathname,c=n.search,i=Object(a.g)("connectNonce","");return t=s({"wccom-site":Object(a.g)("siteUrl"),"wccom-back":o+c,"wccom-woo-version":Object(a.g)("wcVersion"),"wccom-connect-nonce":i},t),Object(r.addQueryArgs)(e,t)}},767:function(e,t,n){"use strict";var o=n(0),c=n(4),r=n.n(c),a=n(439);function i(e){var t=e.id,n=e.label,c=e.hideLabelFromVision,s=e.help,l=e.className,u=e.children;return Object(o.createElement)("div",{className:r()("components-base-control",l)},Object(o.createElement)("div",{className:"components-base-control__field"},n&&t&&(c?Object(o.createElement)(a.a,{as:"label",htmlFor:t},n):Object(o.createElement)("label",{className:"components-base-control__label",htmlFor:t},n)),n&&!t&&(c?Object(o.createElement)(a.a,{as:"label"},n):Object(o.createElement)(i.VisualLabel,null,n)),u),!!s&&Object(o.createElement)("p",{id:t+"__help",className:"components-base-control__help"},s))}i.VisualLabel=function(e){var t=e.className,n=e.children;return t=r()("components-base-control__label",t),Object(o.createElement)("span",{className:t},n)},t.a=i},779:function(e,t,n){"use strict";n.d(t,"a",(function(){return u}));var o=n(7),c=n(12),r=n(0),a=n(300),i=n(575),s=n(759),l=n(767);function u(e){var t=e.label,n=e.className,m=e.heading,p=e.checked,d=e.help,h=e.onChange,b=Object(c.a)(e,["label","className","heading","checked","help","onChange"]),_=Object(a.a)(u),f="inspector-checkbox-control-".concat(_);return Object(r.createElement)(l.a,{label:m,id:f,help:d,className:n},Object(r.createElement)("span",{className:"components-checkbox-control__input-container"},Object(r.createElement)("input",Object(o.a)({id:f,className:"components-checkbox-control__input",type:"checkbox",value:"1",onChange:function(e){return h(e.target.checked)},checked:p,"aria-describedby":d?f+"__help":void 0},b)),p?Object(r.createElement)(i.a,{icon:s.a,className:"components-checkbox-control__checked",role:"presentation"}):null),Object(r.createElement)("label",{className:"components-checkbox-control__label",htmlFor:f},t))}},785:function(e,t,n){"use strict";n.d(t,"b",(function(){return _})),n.d(t,"a",(function(){return f}));var o=n(38),c=n.n(o),r=n(34),a=n.n(r),i=n(30),s=n.n(i),l=n(0),u=n(3),m=n(81),p=n(2),d=n(36),h=n(77),b=Object(d.g)("dataEndpoints",{countries:{}}).countries;function _(e){var t={};return e.addressLine1.length||(t.addressLine1=Object(u.__)("Please add an address",'woocommerce')),e.countryState.length||(t.countryState=Object(u.__)("Please select a country / region",'woocommerce')),e.city.length||(t.city=Object(u.__)("Please add a city",'woocommerce')),e.postCode.length||(t.postCode=Object(u.__)("Please add a post code",'woocommerce')),t}function f(e){var t=e.getInputProps,n=e.setValue,o=Object(l.useMemo)((function(){return b.reduce((function(e,t){if(!t.states.length)return e.push({key:t.code,label:Object(m.decodeEntities)(t.name)}),e;var n=t.states.map((function(e){return{key:t.code+":"+e.code,label:Object(m.decodeEntities)(t.name)+" — "+Object(m.decodeEntities)(e.name)}}));return e.push.apply(e,s()(n)),e}),[])}),[]),r=function(e,t,n){var o=Object(l.useState)(""),c=a()(o,2),r=c[0],i=c[1],s=Object(l.useState)(""),u=a()(s,2),m=u[0],d=u[1];return Object(l.useEffect)((function(){var o=[],c=new RegExp(Object(p.escapeRegExp)(r),"i");if((m.length||r.length)&&(o=e.filter((function(e){return c.test(e.label)}))),r.length&&m.length){var a=new RegExp(Object(p.escapeRegExp)(m.replace(/\s/g,"")),"i");if((o=o.filter((function(e){return a.test(e.label.replace("-","").replace(/\s/g,""))}))).length>1){var i;(i=o.filter((function(e){return c.test(e.key)}))).length>0&&(o=i)}if(o.length>1){var s;1===(s=o.filter((function(e){return a.test(e.key)}))).length&&(o=s)}}1===o.length&&t!==o[0].key&&n("countryState",o[0].key)}),[r,m,t,e,n]),Object(l.createElement)(l.Fragment,null,Object(l.createElement)("input",{onChange:function(e){return i(e.target.value)},value:r,name:"country",type:"text",className:"woocommerce-select-control__autofill-input",tabIndex:"-1",autoComplete:"country"}),Object(l.createElement)("input",{onChange:function(e){return d(e.target.value)},value:m,name:"state",type:"text",className:"woocommerce-select-control__autofill-input",tabIndex:"-1",autoComplete:"address-level1"}))}(o,t("countryState").value,n);return Object(l.createElement)("div",{className:"woocommerce-store-address-fields"},Object(l.createElement)(h.TextControl,c()({label:Object(u.__)("Address line 1",'woocommerce'),required:!0,autoComplete:"address-line1"},t("addressLine1"))),Object(l.createElement)(h.TextControl,c()({label:Object(u.__)("Address line 2 (optional)",'woocommerce'),required:!0,autoComplete:"address-line2"},t("addressLine2"))),Object(l.createElement)(h.SelectControl,c()({label:Object(u.__)("Country / Region",'woocommerce'),required:!0,options:o,excludeSelectedOptions:!1,showAllOnFocus:!0,isSearchable:!0},t("countryState"),{controlClassName:t("countryState").className}),r),Object(l.createElement)(h.TextControl,c()({label:Object(u.__)("City",'woocommerce'),required:!0},t("city"),{autoComplete:"address-level2"})),Object(l.createElement)(h.TextControl,c()({label:Object(u.__)("Post code",'woocommerce'),required:!0,autoComplete:"postal-code"},t("postCode"))))}},821:function(e,t,n){"use strict";var o=n(7),c=n(12),r=n(0),a=n(4),i=n.n(a),s=n(2);t.a=function(e){var t=e.className,n=e.checked,a=e.id,l=e.onChange,u=void 0===l?s.noop:l,m=Object(c.a)(e,["className","checked","id","onChange"]),p=i()("components-form-toggle",t,{"is-checked":n});return Object(r.createElement)("span",{className:p},Object(r.createElement)("input",Object(o.a)({className:"components-form-toggle__input",id:a,type:"checkbox",checked:n,onChange:u},m)),Object(r.createElement)("span",{className:"components-form-toggle__track"}),Object(r.createElement)("span",{className:"components-form-toggle__thumb"}))}},849:function(e,t,n){"use strict";n.r(t),n.d(t,"TaskDashboard",(function(){return He}));var o=n(30),c=n.n(o),r=n(17),a=n.n(r),i=n(15),s=n.n(i),l=n(18),u=n.n(l),m=n(19),p=n.n(m),d=n(9),h=n.n(d),b=n(0),_=n(3),f=n(277),g=n(4),O=n.n(g),y=n(72),v=n(190),k=n(724),j=n(558),w=n(725),S=n(20),E=n(570),C=n(88),P=Object(b.createElement)(C.c,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Object(b.createElement)(C.b,{d:"M9 18.6L3.5 13l1-1L9 16.4l9.5-9.9 1 1z"})),N=n(2),x=n(77),T=n(32),R=n(35),A=n(64),I=(n(794),n(736)),M=n(81),D=n(36),L=n(191),F=n(772),U=n(445);function B(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,o=h()(e);if(t){var c=h()(this).constructor;n=Reflect.construct(o,arguments,c)}else n=o.apply(this,arguments);return p()(this,n)}}var q=function(e){u()(n,e);var t=B(n);function n(e){var o;return a()(this,n),(o=t.call(this,e)).state={purchaseNowButtonBusy:!1,purchaseLaterButtonBusy:!1},o}return s()(n,[{key:"onClickPurchaseNow",value:function(){var e=this.props,t=e.productIds,n=e.onClickPurchaseNow;if(this.setState({purchaseNowButtonBusy:!0}),t.length){Object(A.recordEvent)("tasklist_modal_proceed_checkout",{product_ids:t,purchase_install:!0});var o=Object(U.a)("https://woocommerce.com/cart",{"wccom-replace-with":t.join(",")});n?n(o):window.location=o}}},{key:"onClickPurchaseLater",value:function(){var e=this.props.productIds;Object(A.recordEvent)("tasklist_modal_proceed_checkout",{product_ids:e,purchase_install:!1}),this.setState({purchaseLaterButtonBusy:!0}),this.props.onClickPurchaseLater()}},{key:"onClose",value:function(){var e=this.props,t=e.onClose,n=e.productIds;Object(A.recordEvent)("tasklist_modal_proceed_checkout",{product_ids:n,purchase_install:!1}),t()}},{key:"renderProducts",value:function(){var e=this.props.productIds,t=Object(D.g)("onboarding",{}),n=t.productTypes,o=void 0===n?{}:n,c=t.themes,r=void 0===c?[]:c,a=[];return e.forEach((function(e){var t=Object(N.find)(o,(function(t){return t.product===e}));t&&a.push({title:t.label,content:t.description});var n=Object(N.find)(r,(function(t){return t.id===e}));n&&a.push({title:Object(_.sprintf)(Object(_.__)("%s — %s per year",'woocommerce'),n.title,Object(M.decodeEntities)(n.price)),content:Object(b.createElement)("span",{dangerouslySetInnerHTML:Object(F.a)(n.excerpt)})})})),Object(b.createElement)(x.List,{items:a})}},{key:"render",value:function(){var e=this,t=this.state,n=t.purchaseNowButtonBusy,o=t.purchaseLaterButtonBusy;return Object(b.createElement)(I.a,{title:Object(_.__)("Would you like to purchase and install the following features now?",'woocommerce'),onRequestClose:function(){return e.onClose()},className:"woocommerce-cart-modal"},this.renderProducts(),Object(b.createElement)("p",{className:"woocommerce-cart-modal__help-text"},Object(_.__)("You won't have access to this functionality until the extensions have been purchased and installed.",'woocommerce')),Object(b.createElement)("div",{className:"woocommerce-cart-modal__actions"},Object(b.createElement)(y.a,{isLink:!0,isBusy:o,onClick:function(){return e.onClickPurchaseLater()}},Object(_.__)("I'll do it later",'woocommerce')),Object(b.createElement)(y.a,{isPrimary:!0,isBusy:n,onClick:function(){return e.onClickPurchaseNow()}},Object(_.__)("Purchase & install now",'woocommerce'))))}}]),n}(b.Component),J=Object(f.a)(Object(S.withSelect)((function(e){var t=e(R.PLUGINS_STORE_NAME).getInstalledPlugins,n=(0,e(R.ONBOARDING_STORE_NAME).getProfileItems)(),o=t();return{profileItems:n,productIds:Object(L.e)(n,!1,o)}})))(q),G=n(14),V=n.n(G),z=n(98),H=n.n(z),Z=n(5),W=n.n(Z),Q=n(55),Y=n(11),K=n.n(Y),X=n(43),$=n.n(X);function ee(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function te(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:null;return e&&e.methods&&Array.isArray(e.methods)?t?e.methods?e.methods.filter((function(e){return e.method_id===t})):[]:e.methods:[]}},{key:"disableShippingMethods",value:function(e,t){t.length&&t.forEach((function(t){$()({method:"POST",path:"/wc/v3/shipping/zones/".concat(e.id,"/methods/").concat(t.instance_id),data:{enabled:!1}})}))}},{key:"updateShippingZones",value:(t=H()(V.a.mark((function e(t){var n,o,c,r,a,i,s=this;return V.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:n=this.props,o=n.clearTaskStatusCache,c=n.createNotice,r=n.shippingZones,a=!1,i=!1,r.forEach((function(e){0===e.id?a=e.toggleable&&t["".concat(e.id,"_enabled")]:i=""!==t["".concat(e.id,"_rate")]&&parseFloat(t["".concat(e.id,"_rate")])!==parseFloat(0);var n=s.getShippingMethods(e),o=parseFloat(t["".concat(e.id,"_rate")])===parseFloat(0)?"free_shipping":"flat_rate",c=s.getShippingMethods(e,o).length?s.getShippingMethods(e,o)[0]:null;if(!e.toggleable||t["".concat(e.id,"_enabled")]){if(c){var r=n.filter((function(e){return e.instance_id!==c.instance_id}));s.disableShippingMethods(e,r)}$()({method:"POST",path:c?"/wc/v3/shipping/zones/".concat(e.id,"/methods/").concat(c.instance_id):"/wc/v3/shipping/zones/".concat(e.id,"/methods"),data:{method_id:o,enabled:!0,settings:{cost:t["".concat(e.id,"_rate")]}}})}else s.disableShippingMethods(e,n)})),Object(A.recordEvent)("tasklist_shipping_set_costs",{shipping_cost:i,rest_world:a}),o(),c("success",Object(_.__)("Your shipping rates have been updated.",'woocommerce')),this.props.onComplete();case 8:case"end":return e.stop()}}),e,this)}))),function(e){return t.apply(this,arguments)})},{key:"renderInputPrefix",value:function(){var e=this.context.getCurrencyConfig(),t=e.symbolPosition,n=e.symbol;return 0===t.indexOf("right")?null:Object(b.createElement)("span",{className:"woocommerce-shipping-rate__control-prefix"},n)}},{key:"renderInputSuffix",value:function(e){var t=this.context.getCurrencyConfig(),n=t.symbolPosition,o=t.symbol;return 0===n.indexOf("right")?Object(b.createElement)("span",{className:"woocommerce-shipping-rate__control-suffix"},o):parseFloat(e)===parseFloat(0)?Object(b.createElement)("span",{className:"woocommerce-shipping-rate__control-suffix"},Object(_.__)("Free shipping",'woocommerce')):null}},{key:"getFormattedRate",value:function(e){var t=this.context.formatDecimalString,n=t(e);return e.length&&n.length?t(e):t(0)}},{key:"getInitialValues",value:function(){var e=this,t=this.context.formatDecimalString,n={};return this.props.shippingZones.forEach((function(o){var c=e.getShippingMethods(o),r=c.length&&c[0].settings.cost?e.getFormattedRate(c[0].settings.cost.value):t(0);n["".concat(o.id,"_rate")]=r,c.length&&c[0].enabled?n["".concat(o.id,"_enabled")]=!0:n["".concat(o.id,"_enabled")]=!1})),n}},{key:"validate",value:function(e){var t={};return Object.keys(e).filter((function(e){return e.endsWith("_rate")})).forEach((function(n){e[n]<0&&(t[n]=Object(_.__)("Shipping rates can not be negative numbers.",'woocommerce'))})),t}},{key:"render",value:function(){var e=this,t=this.props,n=t.buttonText,o=t.shippingZones;return o.length?Object(b.createElement)(x.Form,{initialValues:this.getInitialValues(),onSubmitCallback:this.updateShippingZones,validate:this.validate},(function(t){var c=t.getInputProps,r=t.handleSubmit,a=t.setTouched,i=t.setValue,s=t.values;return Object(b.createElement)(b.Fragment,null,Object(b.createElement)("div",{className:"woocommerce-shipping-rates"},o.map((function(t){return Object(b.createElement)("div",{className:"woocommerce-shipping-rate",key:t.id},Object(b.createElement)("div",{className:"woocommerce-shipping-rate__icon"},t.locations?t.locations.map((function(e){return Object(b.createElement)(x.Flag,{size:24,code:e.code,key:e.code})})):Object(b.createElement)("i",{className:"material-icons-outlined"},"public")),Object(b.createElement)("div",{className:"woocommerce-shipping-rate__main"},t.toggleable?Object(b.createElement)("label",{htmlFor:"woocommerce-shipping-rate__toggle-".concat(t.id),className:"woocommerce-shipping-rate__name"},t.name,Object(b.createElement)(ke.a,le()({id:"woocommerce-shipping-rate__toggle-".concat(t.id)},c("".concat(t.id,"_enabled"))))):Object(b.createElement)("div",{className:"woocommerce-shipping-rate__name"},t.name),(!t.toggleable||s["".concat(t.id,"_enabled")])&&Object(b.createElement)(x.TextControlWithAffixes,le()({label:Object(_.__)("Shipping cost",'woocommerce'),required:!0},c("".concat(t.id,"_rate")),{onBlur:function(){a("".concat(t.id,"_rate")),i("".concat(t.id,"_rate"),e.getFormattedRate(s["".concat(t.id,"_rate")]))},prefix:e.renderInputPrefix(),suffix:e.renderInputSuffix(s["".concat(t.id,"_rate")]),className:"muriel-input-text woocommerce-shipping-rate__control-wrapper"}))))}))),Object(b.createElement)(y.a,{isPrimary:!0,onClick:r},n||Object(_.__)("Update",'woocommerce')))})):null}}]),o}(b.Component);Se.propTypes={buttonText:de.a.string,onComplete:de.a.func.isRequired,createNotice:de.a.func.isRequired,shippingZones:de.a.array},Se.defaultProps={shippingZones:[]},Se.contextType=je.a;var Ee=Object(f.a)(Object(S.withDispatch)((function(e){var t=e(R.ONBOARDING_STORE_NAME).invalidateResolutionForStoreSelector;return{clearTaskStatusCache:function(){return t("getTasksStatus")}}})))(Se),Ce=n(776);function Pe(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,o=h()(e);if(t){var c=h()(this).constructor;n=Reflect.construct(o,arguments,c)}else n=o.apply(this,arguments);return p()(this,n)}}var Ne=function(e){u()(o,e);var t,n=Pe(o);function o(e){var t;return a()(this,o),(t=n.call(this,e)).initialState={isPending:!1,step:"store_location",shippingZones:[]},t.activePlugins=e.activePlugins,t.state=t.initialState,t.completeStep=t.completeStep.bind(K()(t)),t}return s()(o,[{key:"componentDidMount",value:function(){this.reset()}},{key:"reset",value:function(){this.setState(this.initialState)}},{key:"fetchShippingZones",value:(t=H()(V.a.mark((function e(){var t,n,o,c,r,a,i;return V.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return this.setState({isPending:!0}),t=this.props,n=t.countryCode,o=t.countryName,c=[],e.next=5,$()({path:"/wc/v3/shipping/zones"});case 5:return r=e.sent,a=!1,e.next=9,Promise.all(r.map(function(){var e=H()(V.a.mark((function e(t){return V.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(0!==t.id){e.next=8;break}return e.next=3,$()({path:"/wc/v3/shipping/zones/".concat(t.id,"/methods")});case 3:return t.methods=e.sent,t.name=Object(_.__)("Rest of the world",'woocommerce'),t.toggleable=!0,c.push(t),e.abrupt("return");case 8:return e.next=10,$()({path:"/wc/v3/shipping/zones/".concat(t.id,"/locations")});case 10:if(t.locations=e.sent,!t.locations.find((function(e){return n===e.code}))){e.next=18;break}return e.next=15,$()({path:"/wc/v3/shipping/zones/".concat(t.id,"/methods")});case 15:t.methods=e.sent,c.push(t),a=!0;case 18:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()));case 9:if(a){e.next=17;break}return e.next=12,$()({method:"POST",path:"/wc/v3/shipping/zones",data:{name:o}});case 12:return i=e.sent,e.next=15,$()({method:"POST",path:"/wc/v3/shipping/zones/".concat(i.id,"/locations"),data:[{code:n,type:"country"}]});case 15:i.locations=e.sent,c.push(i);case 17:c.reverse(),this.setState({isPending:!1,shippingZones:c});case 19:case"end":return e.stop()}}),e,this)}))),function(){return t.apply(this,arguments)})},{key:"componentDidUpdate",value:function(e,t){var n=this.props,o=n.countryCode,c=n.settings,r=c.woocommerce_store_address,a=c.woocommerce_default_country,i=c.woocommerce_store_postcode,s=this.state.step;"rates"!==s||e.countryCode===o&&"rates"===t.step||this.fetchShippingZones();var l=Boolean(r&&a&&i);"store_location"===s&&l&&this.completeStep()}},{key:"completeStep",value:function(){var e=this.props.createNotice,t=this.state.step,n=this.getSteps(),o=n.findIndex((function(e){return e.key===t})),c=n[o+1];c?this.setState({step:c.key}):(e("success",Object(_.__)("📦 Shipping is done! Don't worry, you can always change it later.",'woocommerce')),Object(T.getHistory)().push(Object(T.getNewPath)({},"/",{})))}},{key:"getPluginsToActivate",value:function(){var e=this.props.countryCode,t=[];return["GB","CA","AU"].includes(e)?t.push("woocommerce-shipstation-integration"):"US"===e&&(t.push("woocommerce-services"),t.push("jetpack")),Object(N.difference)(t,this.activePlugins)}},{key:"getSteps",value:function(){var e=this,t=this.props,n=t.countryCode,o=t.isJetpackConnected,c=this.getPluginsToActivate(),r=!o&&"US"===n,a=[{key:"store_location",label:Object(_.__)("Set store location",'woocommerce'),description:Object(_.__)("The address from which your business operates",'woocommerce'),content:Object(b.createElement)(ve,le()({},this.props,{onComplete:function(t){var n=Object(L.b)(t.countryState);Object(A.recordEvent)("tasklist_shipping_set_location",{country:n}),e.completeStep()}})),visible:!0},{key:"rates",label:Object(_.__)("Set shipping costs",'woocommerce'),description:Object(_.__)("Define how much customers pay to ship to different destinations",'woocommerce'),content:Object(b.createElement)(Ee,le()({buttonText:c.length||r?Object(_.__)("Proceed",'woocommerce'):Object(_.__)("Complete task",'woocommerce'),shippingZones:this.state.shippingZones,onComplete:this.completeStep},this.props)),visible:!0},{key:"label_printing",label:Object(_.__)("Enable shipping label printing",'woocommerce'),description:c.includes("woocommerce-shipstation-integration")?me()({mixedString:Object(_.__)("We recommend using ShipStation to save time at the post office by printing your shipping labels at home. Try ShipStation free for 30 days. {{link}}Learn more{{/link}}.",'woocommerce'),components:{link:Object(b.createElement)(x.Link,{href:"https://woocommerce.com/products/shipstation-integration",target:"_blank",type:"external"})}}):Object(_.__)("With WooCommerce Shipping and Jetpack you can save time at the Post Office by printing your shipping labels at home",'woocommerce'),content:Object(b.createElement)(x.Plugins,le()({onComplete:function(t,n){Object(Ce.a)(n),Object(A.recordEvent)("tasklist_shipping_label_printing",{install:!0,plugins_to_activate:c}),e.completeStep()},onError:function(e,t){return Object(Ce.a)(t)},onSkip:function(){Object(A.recordEvent)("tasklist_shipping_label_printing",{install:!1,plugins_to_activate:c}),Object(T.getHistory)().push(Object(T.getNewPath)({},"/",{}))},pluginSlugs:c},this.props)),visible:c.length},{key:"connect",label:Object(_.__)("Connect your store",'woocommerce'),description:Object(_.__)("Connect your store to WordPress.com to enable label printing",'woocommerce'),content:Object(b.createElement)(_e,le()({redirectUrl:Object(D.f)("admin.php?page=wc-admin"),completeStep:this.completeStep},this.props,{onConnect:function(){Object(A.recordEvent)("tasklist_shipping_connect_store")}})),visible:r}];return Object(N.filter)(a,(function(e){return e.visible}))}},{key:"render",value:function(){var e=this.state,t=e.isPending,n=e.step,o=this.props.isUpdateSettingsRequesting;return Object(b.createElement)("div",{className:"woocommerce-task-shipping"},Object(b.createElement)(x.Card,{className:"is-narrow"},Object(b.createElement)(x.Stepper,{isPending:t||o,isVertical:!0,currentStep:n,steps:this.getSteps()})))}}]),o}(b.Component),xe=Object(f.a)(Object(S.withSelect)((function(e){var t=e(R.SETTINGS_STORE_NAME),n=t.getSettings,o=t.isUpdateSettingsRequesting,c=e(R.PLUGINS_STORE_NAME),r=c.getActivePlugins,a=c.isJetpackConnected,i=n("general").general,s=void 0===i?{}:i,l=Object(L.b)(s.woocommerce_default_country),u=Object(D.g)("dataEndpoints",{}).countries,m=l?(void 0===u?[]:u).find((function(e){return e.code===l})):null,p=m?m.name:null,d=r();return{countryCode:l,countryName:p,isUpdateSettingsRequesting:o("general"),settings:s,activePlugins:d,isJetpackConnected:a()}})),Object(S.withDispatch)((function(e){return{createNotice:e("core/notices").createNotice,updateAndPersistSettingsForGroup:e(R.SETTINGS_STORE_NAME).updateAndPersistSettingsForGroup}})))(Ne);function Te(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function Re(e){for(var t=1;tTerms of Service','woocommerce'),time:Object(_.__)("2 minutes",'woocommerce')},{key:"payments",title:Object(_.__)("Set up payments",'woocommerce'),container:Object(b.createElement)(qe,null),completed:p,onClick:function(){Object(A.recordEvent)("tasklist_click",{task_name:"payments"}),Object(T.updateQueryString)({task:"payments"})},visible:!S||"US"!==n,time:Object(_.__)("2 minutes",'woocommerce')},{key:"tax",title:Object(_.__)("Set up tax",'woocommerce'),container:Object(b.createElement)(Me,null),onClick:function(){Object(A.recordEvent)("tasklist_click",{task_name:"tax"}),Object(T.updateQueryString)({task:"tax"})},completed:g,visible:!0,time:Object(_.__)("1 minute",'woocommerce')},{key:"shipping",title:Object(_.__)("Set up shipping",'woocommerce'),container:Object(b.createElement)(xe,null),onClick:function(){Object(A.recordEvent)("tasklist_click",{task_name:"shipping"}),Object(T.updateQueryString)({task:"shipping"})},completed:O>0,visible:C&&C.includes("physical")||d,time:Object(_.__)("1 minute",'woocommerce')},{key:"appearance",title:Object(_.__)("Personalize my store",'woocommerce'),container:Object(b.createElement)(ce,null),onClick:function(){Object(A.recordEvent)("tasklist_click",{task_name:"appearance"}),Object(T.updateQueryString)({task:"appearance"})},completed:f,visible:!0,time:Object(_.__)("2 minutes",'woocommerce')}];return Object(Q.applyFilters)("woocommerce_admin_onboarding_task_list",M.sort((function(e,t){return e.completed===t.completed?0:e.completed?1:-1})),l)}function ze(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,o=h()(e);if(t){var c=h()(this).constructor;n=Reflect.construct(o,arguments,c)}else n=o.apply(this,arguments);return p()(this,n)}}var He=function(e){u()(n,e);var t=ze(n);function n(e){var o;return a()(this,n),(o=t.call(this,e)).state={isCartModalOpen:!1},o}return s()(n,[{key:"componentDidMount",value:function(){document.body.classList.add("woocommerce-onboarding"),document.body.classList.add("woocommerce-task-dashboard__body"),this.recordTaskView(),this.recordTaskListView(),this.possiblyCompleteTaskList(),this.possiblyTrackCompletedTasks()}},{key:"componentDidUpdate",value:function(e){var t=this.props.query;e.query.task!==t.task&&(window.document.documentElement.scrollTop=0,this.recordTaskView()),this.possiblyCompleteTaskList(),this.possiblyTrackCompletedTasks()}},{key:"possiblyCompleteTaskList",value:function(){var e=this.props,t=e.isTaskListComplete,n=e.updateOptions;this.getIncompleteTasks().length||t||n({woocommerce_task_list_complete:"yes",woocommerce_default_homepage_layout:"two_columns"})}},{key:"getCompletedTaskKeys",value:function(){return this.getVisibleTasks().filter((function(e){return e.completed})).map((function(e){return e.key}))}},{key:"getIncompleteTasks",value:function(){return this.getAllTasks().filter((function(e){return e.visible&&!e.completed}))}},{key:"possiblyTrackCompletedTasks",value:function(){var e=this.props,t=e.trackedCompletedTasks,n=e.updateOptions,o=this.getCompletedTaskKeys();0!==Object(N.xor)(t,o).length&&n({woocommerce_task_list_tracked_completed_tasks:o})}},{key:"dismissTask",value:function(e){var t=this,n=this.props,o=n.createNotice,r=n.dismissedTasks,a=n.updateOptions;o("success",Object(_.__)("Task dismissed"),{actions:[{label:Object(_.__)("Undo",'woocommerce'),onClick:function(){return t.undoDismissTask(e)}}]}),Object(A.recordEvent)("tasklist_dismiss_task",{task_name:e}),a({woocommerce_task_list_dismissed_tasks:[].concat(c()(r),[e])})}},{key:"undoDismissTask",value:function(e){var t=this.props,n=t.dismissedTasks;(0,t.updateOptions)({woocommerce_task_list_dismissed_tasks:n.filter((function(t){return t!==e}))})}},{key:"componentWillUnmount",value:function(){document.body.classList.remove("woocommerce-onboarding"),document.body.classList.remove("woocommerce-task-dashboard__body")}},{key:"getAllTasks",value:function(){var e=this.props;return Ve({activePlugins:e.activePlugins,countryCode:e.countryCode,createNotice:e.createNotice,installAndActivatePlugins:e.installAndActivatePlugins,installedPlugins:e.installedPlugins,isJetpackConnected:e.isJetpackConnected,onboardingStatus:e.onboardingStatus,profileItems:e.profileItems,query:e.query,toggleCartModal:this.toggleCartModal.bind(this)})}},{key:"getVisibleTasks",value:function(){var e=this.props.dismissedTasks;return this.getAllTasks().filter((function(t){return t.visible&&!e.includes(t.key)}))}},{key:"recordTaskView",value:function(){var e=this.props,t=e.isJetpackConnected,n=e.activePlugins,o=e.installedPlugins,c=e.query.task;c&&Ge(c,t,n,o)}},{key:"recordTaskListView",value:function(){if(!this.getCurrentTask()){var e=this.props.profileItems,t=this.getVisibleTasks();Object(A.recordEvent)("tasklist_view",{number_tasks:t.length,store_connected:e.wccom_connected})}}},{key:"hideTaskCard",value:function(e){Object(A.recordEvent)("tasklist_completed",{action:e,completed_task_count:this.getCompletedTaskKeys().length,incomplete_task_count:this.getIncompleteTasks().length}),this.props.updateOptions({woocommerce_task_list_hidden:"yes",woocommerce_task_list_prompt_shown:!0,woocommerce_default_homepage_layout:"two_columns"})}},{key:"getCurrentTask",value:function(){var e=this.props.query.task,t=this.getAllTasks().find((function(t){return t.key===e}));return t||null}},{key:"renderMenu",value:function(){var e=this;return Object(b.createElement)("div",{className:"woocommerce-card__menu woocommerce-card__header-item"},Object(b.createElement)(x.EllipsisMenu,{label:Object(_.__)("Task List Options",'woocommerce'),renderContent:function(){return Object(b.createElement)("div",{className:"woocommerce-task-card__section-controls"},Object(b.createElement)(y.a,{onClick:function(){return e.hideTaskCard("remove_card")}},Object(_.__)("Hide this",'woocommerce')))}}))}},{key:"toggleCartModal",value:function(){var e=this.state.isCartModalOpen;e||Object(A.recordEvent)("tasklist_purchase_extensions"),this.setState({isCartModalOpen:!e})}},{key:"render",value:function(){var e=this,t=this.props.query,n=this.state.isCartModalOpen,o=this.getCurrentTask(),c=this.getVisibleTasks().map((function(t){return t.className=O()(t.completed?"is-complete":null,t.className),t.before=Object(b.createElement)("div",{className:"woocommerce-task__icon"},t.completed&&Object(b.createElement)(E.a,{icon:P})),t.title=Object(b.createElement)(v.a,{as:"div",variant:t.completed?"body.small":"button"},t.title,t.additionalInfo&&Object(b.createElement)("div",{className:"woocommerce-task__additional-info",dangerouslySetInnerHTML:Object(F.a)(t.additionalInfo)}),t.time&&!t.completed&&Object(b.createElement)("div",{className:"woocommerce-task__estimated-time"},t.time)),!t.completed&&t.isDismissable&&(t.after=Object(b.createElement)(y.a,{"data-testid":"".concat(t.key,"-dismiss-button"),isTertiary:!0,onClick:function(n){n.stopPropagation(),e.dismissTask(t.key)}},Object(_.__)("Dismiss",'woocommerce'))),t.onClick||(t.onClick=function(e){if("A"===e.target.nodeName)return!1;Object(T.updateQueryString)({task:t.key})}),t}));return Object(b.createElement)(b.Fragment,null,Object(b.createElement)("div",{className:"woocommerce-task-dashboard__container"},o?Object(b.cloneElement)(o.container,{query:t}):Object(b.createElement)(b.Fragment,null,Object(b.createElement)(k.a,{size:"large",className:"woocommerce-task-card woocommerce-homescreen-card"},Object(b.createElement)(j.a,{size:"medium"},Object(b.createElement)("div",{className:"wooocommerce-task-card__header"},Object(b.createElement)(v.a,{variant:"title.small"},Object(_.__)("Finish setup",'woocommerce')),Object(b.createElement)(x.Badge,{count:this.getIncompleteTasks().length})),this.renderMenu()),Object(b.createElement)(w.a,null,Object(b.createElement)(x.List,{items:c}))))),n&&Object(b.createElement)(J,{onClose:function(){return e.toggleCartModal()},onClickPurchaseLater:function(){return e.toggleCartModal()}}))}}]),n}(b.Component);t.default=Object(f.a)(Object(S.withSelect)((function(e){var t=e(R.ONBOARDING_STORE_NAME),n=t.getProfileItems,o=t.getTasksStatus,c=e(R.OPTIONS_STORE_NAME).getOption,r=e(R.SETTINGS_STORE_NAME).getSettings,a=e(R.PLUGINS_STORE_NAME),i=a.getActivePlugins,s=a.getInstalledPlugins,l=a.isJetpackConnected,u=n(),m="yes"===c("woocommerce_task_list_complete"),p=c("woocommerce_task_list_tracked_completed_tasks")||[],d=c("woocommerce_task_list_dismissed_tasks")||[],h=r("general").general,b=void 0===h?{}:h,_=Object(L.b)(b.woocommerce_default_country),f=i(),g=s(),O=o();return{activePlugins:f,countryCode:_,dismissedTasks:d,isJetpackConnected:l(),installedPlugins:g,isTaskListComplete:m,onboardingStatus:O,profileItems:u,trackedCompletedTasks:p}})),Object(S.withDispatch)((function(e){var t=e("core/notices").createNotice,n=e(R.OPTIONS_STORE_NAME).updateOptions;return{createNotice:t,installAndActivatePlugins:e(R.PLUGINS_STORE_NAME).installAndActivatePlugins,updateOptions:n}})))(He)},98:function(e,t){function n(e,t,n,o,c,r,a){try{var i=e[r](a),s=i.value}catch(e){return void n(e)}i.done?t(s):Promise.resolve(s).then(o,c)}e.exports=function(e){return function(){var t=this,o=arguments;return new Promise((function(c,r){var a=e.apply(t,o);function i(e){n(a,c,r,i,s,"next",e)}function s(e){n(a,c,r,i,s,"throw",e)}i(void 0)}))}}}}]); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/components/ie-rtl.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/components/ie-rtl.css new file mode 100644 index 0000000..c6ab617 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/components/ie-rtl.css @@ -0,0 +1,1092 @@ +/** + * Colors + */ +/** + * Colors + */ +/** + * Colors + */ +/** + * Fonts & basic variables. + */ +/** + * Grid System. + * https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/ + */ +/** + * Dimensions. + */ +/** + * Shadows. + */ +/** + * Editor widths. + */ +/** + * Block UI. + */ +/** + * Border radii. + */ +/** + * Block paddings. + */ +/** + * Breakpoint mixins + */ +/** + * Long content fade mixin + * + * Creates a fading overlay to signify that the content is longer + * than the space allows. + */ +/** + * Focus styles. + */ +/** + * Applies editor left position to the selector passed as argument + */ +/** + * Styles that are reused verbatim in a few places + */ +/** + * Allows users to opt-out of animations via OS-level preferences. + */ +/** + * Reset default styles for JavaScript UI based pages. + * This is a WP-admin agnostic reset + */ +/** + * Reset the WP Admin page styles for Gutenberg-like pages. + */ +/** + * Breakpoints & Media Queries + */ +:root { + --wp-admin-theme-color: #007cba; + --wp-admin-theme-color-darker-10: #006ba1; + --wp-admin-theme-color-darker-20: #005a87; } + +body.admin-color-light { + --wp-admin-theme-color: #0085ba; + --wp-admin-theme-color-darker-10: #0073a1; + --wp-admin-theme-color-darker-20: #006187; } + +body.admin-color-modern { + --wp-admin-theme-color: #3858e9; + --wp-admin-theme-color-darker-10: #2145e6; + --wp-admin-theme-color-darker-20: #183ad6; } + +body.admin-color-blue { + --wp-admin-theme-color: #096484; + --wp-admin-theme-color-darker-10: #07526c; + --wp-admin-theme-color-darker-20: #064054; } + +body.admin-color-coffee { + --wp-admin-theme-color: #46403c; + --wp-admin-theme-color-darker-10: #383330; + --wp-admin-theme-color-darker-20: #2b2724; } + +body.admin-color-ectoplasm { + --wp-admin-theme-color: #523f6d; + --wp-admin-theme-color-darker-10: #46365d; + --wp-admin-theme-color-darker-20: #3a2c4d; } + +body.admin-color-midnight { + --wp-admin-theme-color: #e14d43; + --wp-admin-theme-color-darker-10: #dd382d; + --wp-admin-theme-color-darker-20: #d02c21; } + +body.admin-color-ocean { + --wp-admin-theme-color: #627c83; + --wp-admin-theme-color-darker-10: #576e74; + --wp-admin-theme-color-darker-20: #4c6066; } + +body.admin-color-sunrise { + --wp-admin-theme-color: #dd823b; + --wp-admin-theme-color-darker-10: #d97426; + --wp-admin-theme-color-darker-20: #c36922; } + +/* stylelint-disable block-closing-brace-newline-after */ +/* stylelint-enable */ +/** + * Breakpoint mixins + */ +/* stylelint-disable block-closing-brace-newline-after */ +/* stylelint-enable */ +/** + * Internal Dependencies + */ +.woocommerce-segmented-selection__item:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.woocommerce-segmented-selection__item:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.woocommerce-segmented-selection__item:nth-child(3) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.woocommerce-segmented-selection__item:nth-child(4) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.woocommerce-segmented-selection__item:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + +.woocommerce-segmented-selection__item:nth-child(6) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + +.woocommerce-segmented-selection__item:nth-child(7) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 4; + grid-row-start: 4; + -ms-grid-row-span: 1; + grid-row-end: 5; } + +.woocommerce-segmented-selection__item:nth-child(8) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 4; + grid-row-start: 4; + -ms-grid-row-span: 1; + grid-row-end: 5; } + +.woocommerce-segmented-selection__item:nth-child(9) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 5; + grid-row-start: 5; + -ms-grid-row-span: 1; + grid-row-end: 6; } + +.woocommerce-segmented-selection__item:nth-child(10) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 5; + grid-row-start: 5; + -ms-grid-row-span: 1; + grid-row-end: 6; } + +.has-1-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-2-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-2-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-3-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-3-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-3-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-4-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-4-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-4-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-4-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 6; + grid-column-start: 6; + -ms-grid-column-span: 1; + grid-column-end: 7; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +@media (max-width: 1440px) { + .has-6-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-6-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-6-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-6-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-6-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-6-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } } + +.has-7-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-7-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-7-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-7-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-7-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-7-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-7-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-8-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-8-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-8-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-8-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-8-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-8-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-8-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-8-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-9-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-9-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-9-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-9-items .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +@media (max-width: 1440px) { + .has-9-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-9-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-9-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-9-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-9-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-9-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-9-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + .has-9-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + .has-9-items .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } } + +.has-10-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-10-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-10-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-10-items .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-10-items .woocommerce-summary__item-container:nth-child(10) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +@media (max-width: 1440px) { + .has-10-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-10-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-10-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-10-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-10-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-10-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-10-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-10-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-10-items .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + .has-10-items .woocommerce-summary__item-container:nth-child(10) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } } + +@media (max-width: 960px) { + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 4; + grid-row-start: 4; + -ms-grid-row-span: 1; + grid-row-end: 5; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 5; + grid-row-start: 5; + -ms-grid-row-span: 1; + grid-row-end: 6; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 6; + grid-row-start: 6; + -ms-grid-row-span: 1; + grid-row-end: 7; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 7; + grid-row-start: 7; + -ms-grid-row-span: 1; + grid-row-end: 8; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 8; + grid-row-start: 8; + -ms-grid-row-span: 1; + grid-row-end: 9; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 9; + grid-row-start: 9; + -ms-grid-row-span: 1; + grid-row-end: 10; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(10) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 10; + grid-row-start: 10; + -ms-grid-row-span: 1; + grid-row-end: 11; } } diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/components/ie.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/components/ie.css new file mode 100644 index 0000000..c6ab617 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/components/ie.css @@ -0,0 +1,1092 @@ +/** + * Colors + */ +/** + * Colors + */ +/** + * Colors + */ +/** + * Fonts & basic variables. + */ +/** + * Grid System. + * https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/ + */ +/** + * Dimensions. + */ +/** + * Shadows. + */ +/** + * Editor widths. + */ +/** + * Block UI. + */ +/** + * Border radii. + */ +/** + * Block paddings. + */ +/** + * Breakpoint mixins + */ +/** + * Long content fade mixin + * + * Creates a fading overlay to signify that the content is longer + * than the space allows. + */ +/** + * Focus styles. + */ +/** + * Applies editor left position to the selector passed as argument + */ +/** + * Styles that are reused verbatim in a few places + */ +/** + * Allows users to opt-out of animations via OS-level preferences. + */ +/** + * Reset default styles for JavaScript UI based pages. + * This is a WP-admin agnostic reset + */ +/** + * Reset the WP Admin page styles for Gutenberg-like pages. + */ +/** + * Breakpoints & Media Queries + */ +:root { + --wp-admin-theme-color: #007cba; + --wp-admin-theme-color-darker-10: #006ba1; + --wp-admin-theme-color-darker-20: #005a87; } + +body.admin-color-light { + --wp-admin-theme-color: #0085ba; + --wp-admin-theme-color-darker-10: #0073a1; + --wp-admin-theme-color-darker-20: #006187; } + +body.admin-color-modern { + --wp-admin-theme-color: #3858e9; + --wp-admin-theme-color-darker-10: #2145e6; + --wp-admin-theme-color-darker-20: #183ad6; } + +body.admin-color-blue { + --wp-admin-theme-color: #096484; + --wp-admin-theme-color-darker-10: #07526c; + --wp-admin-theme-color-darker-20: #064054; } + +body.admin-color-coffee { + --wp-admin-theme-color: #46403c; + --wp-admin-theme-color-darker-10: #383330; + --wp-admin-theme-color-darker-20: #2b2724; } + +body.admin-color-ectoplasm { + --wp-admin-theme-color: #523f6d; + --wp-admin-theme-color-darker-10: #46365d; + --wp-admin-theme-color-darker-20: #3a2c4d; } + +body.admin-color-midnight { + --wp-admin-theme-color: #e14d43; + --wp-admin-theme-color-darker-10: #dd382d; + --wp-admin-theme-color-darker-20: #d02c21; } + +body.admin-color-ocean { + --wp-admin-theme-color: #627c83; + --wp-admin-theme-color-darker-10: #576e74; + --wp-admin-theme-color-darker-20: #4c6066; } + +body.admin-color-sunrise { + --wp-admin-theme-color: #dd823b; + --wp-admin-theme-color-darker-10: #d97426; + --wp-admin-theme-color-darker-20: #c36922; } + +/* stylelint-disable block-closing-brace-newline-after */ +/* stylelint-enable */ +/** + * Breakpoint mixins + */ +/* stylelint-disable block-closing-brace-newline-after */ +/* stylelint-enable */ +/** + * Internal Dependencies + */ +.woocommerce-segmented-selection__item:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.woocommerce-segmented-selection__item:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.woocommerce-segmented-selection__item:nth-child(3) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.woocommerce-segmented-selection__item:nth-child(4) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.woocommerce-segmented-selection__item:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + +.woocommerce-segmented-selection__item:nth-child(6) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + +.woocommerce-segmented-selection__item:nth-child(7) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 4; + grid-row-start: 4; + -ms-grid-row-span: 1; + grid-row-end: 5; } + +.woocommerce-segmented-selection__item:nth-child(8) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 4; + grid-row-start: 4; + -ms-grid-row-span: 1; + grid-row-end: 5; } + +.woocommerce-segmented-selection__item:nth-child(9) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 5; + grid-row-start: 5; + -ms-grid-row-span: 1; + grid-row-end: 6; } + +.woocommerce-segmented-selection__item:nth-child(10) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 5; + grid-row-start: 5; + -ms-grid-row-span: 1; + grid-row-end: 6; } + +.has-1-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-2-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-2-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-3-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-3-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-3-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-4-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-4-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-4-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-4-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-5-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-6-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 6; + grid-column-start: 6; + -ms-grid-column-span: 1; + grid-column-end: 7; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +@media (max-width: 1440px) { + .has-6-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-6-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-6-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-6-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-6-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-6-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } } + +.has-7-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-7-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-7-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-7-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-7-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-7-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-7-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-8-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-8-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-8-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-8-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-8-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-8-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-8-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-8-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-9-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-9-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-9-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-9-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-9-items .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +@media (max-width: 1440px) { + .has-9-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-9-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-9-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-9-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-9-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-9-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-9-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + .has-9-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + .has-9-items .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } } + +.has-10-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + +.has-10-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-10-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-10-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-10-items .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +.has-10-items .woocommerce-summary__item-container:nth-child(10) { + -ms-grid-column: 5; + grid-column-start: 5; + -ms-grid-column-span: 1; + grid-column-end: 6; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + +@media (max-width: 1440px) { + .has-10-items .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-10-items .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-10-items .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-10-items .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .has-10-items .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-10-items .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-10-items .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 3; + grid-column-start: 3; + -ms-grid-column-span: 1; + grid-column-end: 4; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-10-items .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 4; + grid-column-start: 4; + -ms-grid-column-span: 1; + grid-column-end: 5; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .has-10-items .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + .has-10-items .woocommerce-summary__item-container:nth-child(10) { + -ms-grid-column: 2; + grid-column-start: 2; + -ms-grid-column-span: 1; + grid-column-end: 3; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } } + +@media (max-width: 960px) { + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(1) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 1; + grid-row-start: 1; + -ms-grid-row-span: 1; + grid-row-end: 2; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(2) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 2; + grid-row-start: 2; + -ms-grid-row-span: 1; + grid-row-end: 3; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(3) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 3; + grid-row-start: 3; + -ms-grid-row-span: 1; + grid-row-end: 4; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(4) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 4; + grid-row-start: 4; + -ms-grid-row-span: 1; + grid-row-end: 5; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(5) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 5; + grid-row-start: 5; + -ms-grid-row-span: 1; + grid-row-end: 6; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(6) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 6; + grid-row-start: 6; + -ms-grid-row-span: 1; + grid-row-end: 7; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(7) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 7; + grid-row-start: 7; + -ms-grid-row-span: 1; + grid-row-end: 8; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(8) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 8; + grid-row-start: 8; + -ms-grid-row-span: 1; + grid-row-end: 9; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(9) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 9; + grid-row-start: 9; + -ms-grid-row-span: 1; + grid-row-end: 10; } + .woocommerce-summary > .woocommerce-summary__item-container:nth-child(10) { + -ms-grid-column: 1; + grid-column-start: 1; + -ms-grid-column-span: 1; + grid-column-end: 2; + -ms-grid-row: 10; + grid-row-start: 10; + -ms-grid-row-span: 1; + grid-row-end: 11; } } diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/components/index.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/components/index.js new file mode 100644 index 0000000..b49489e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-admin/dist/components/index.js @@ -0,0 +1,2 @@ +/*! For license information please see index.js.LICENSE.txt */ +this.wc=this.wc||{},this.wc.components=function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=730)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t,r){e.exports=r(138)()},function(e,t){!function(){e.exports=this.lodash}()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t,r){!function(){"use strict";var t={}.hasOwnProperty;function r(){for(var e=[],n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}},function(e,t,r){"use strict";function n(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}r.d(t,"a",(function(){return n}))},function(e,t,r){e.exports=r(137)},function(e,t){function r(e,t){for(var r=0;r1)for(var r=1;r96?f:d};function m(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function b(e){for(var t=1;t "+c);if("componentClose"===h.type)throw new Error("Missing opening component token: `"+h.value+"`");if("componentOpen"===h.type){r=t[h.value],s=f;break}m.push(t[h.value])}else m.push(h.value);return r&&(l=function(e,t){var r,n,i=t[e],o=0;for(n=e+1;n=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function p(e,t){if(c.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var r=e.length;if(0===r)return 0;for(var n=!1;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return B(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return H(e).length;default:if(n)return B(e).length;t=(""+t).toLowerCase(),n=!0}}function m(e,t,r){var n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return j(this,t,r);case"utf8":case"utf-8":return S(this,t,r);case"ascii":return A(this,t,r);case"latin1":case"binary":return C(this,t,r);case"base64":return E(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return z(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}function b(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}function v(e,t,r,n,i){if(0===e.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r=+r,isNaN(r)&&(r=i?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(i)return-1;r=e.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof t&&(t=c.from(t,n)),c.isBuffer(t))return 0===t.length?-1:g(e,t,r,n,i);if("number"==typeof t)return t&=255,c.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):g(e,[t],r,n,i);throw new TypeError("val must be string, number or Buffer")}function g(e,t,r,n,i){var o,a=1,s=e.length,c=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;a=2,s/=2,c/=2,r/=2}function u(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(i){var l=-1;for(o=r;os&&(r=s-c),o=r;o>=0;o--){for(var h=!0,f=0;fi&&(n=i):n=i;var o=t.length;if(o%2!=0)throw new TypeError("Invalid hex string");n>o/2&&(n=o/2);for(var a=0;a>8,i=r%256,o.push(i),o.push(n);return o}(t,e.length-r),e,r,n)}function E(e,t,r){return 0===t&&r===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,r))}function S(e,t,r){r=Math.min(e.length,r);for(var n=[],i=t;i239?4:u>223?3:u>191?2:1;if(i+h<=r)switch(h){case 1:u<128&&(l=u);break;case 2:128==(192&(o=e[i+1]))&&(c=(31&u)<<6|63&o)>127&&(l=c);break;case 3:o=e[i+1],a=e[i+2],128==(192&o)&&128==(192&a)&&(c=(15&u)<<12|(63&o)<<6|63&a)>2047&&(c<55296||c>57343)&&(l=c);break;case 4:o=e[i+1],a=e[i+2],s=e[i+3],128==(192&o)&&128==(192&a)&&128==(192&s)&&(c=(15&u)<<18|(63&o)<<12|(63&a)<<6|63&s)>65535&&c<1114112&&(l=c)}null===l?(l=65533,h=1):l>65535&&(l-=65536,n.push(l>>>10&1023|55296),l=56320|1023&l),n.push(l),i+=h}return function(e){var t=e.length;if(t<=4096)return String.fromCharCode.apply(String,e);var r="",n=0;for(;n0&&(e=this.toString("hex",0,r).match(/.{2}/g).join(" "),this.length>r&&(e+=" ... ")),""},c.prototype.compare=function(e,t,r,n,i){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),t<0||r>e.length||n<0||i>this.length)throw new RangeError("out of range index");if(n>=i&&t>=r)return 0;if(n>=i)return-1;if(t>=r)return 1;if(this===e)return 0;for(var o=(i>>>=0)-(n>>>=0),a=(r>>>=0)-(t>>>=0),s=Math.min(o,a),u=this.slice(n,i),l=e.slice(t,r),h=0;hi)&&(r=i),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var o=!1;;)switch(n){case"hex":return y(this,e,t,r);case"utf8":case"utf-8":return w(this,e,t,r);case"ascii":return M(this,e,t,r);case"latin1":case"binary":return _(this,e,t,r);case"base64":return O(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return k(this,e,t,r);default:if(o)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),o=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function A(e,t,r){var n="";r=Math.min(e.length,r);for(var i=t;in)&&(r=n);for(var i="",o=t;or)throw new RangeError("Trying to access beyond buffer length")}function D(e,t,r,n,i,o){if(!c.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError("Index out of range")}function P(e,t,r,n){t<0&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-r,2);i>>8*(n?i:1-i)}function R(e,t,r,n){t<0&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-r,4);i>>8*(n?i:3-i)&255}function T(e,t,r,n,i,o){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function F(e,t,r,n,o){return o||T(e,0,r,4),i.write(e,t,r,n,23,4),r+4}function N(e,t,r,n,o){return o||T(e,0,r,8),i.write(e,t,r,n,52,8),r+8}c.prototype.slice=function(e,t){var r,n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),(t=void 0===t?n:~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),t0&&(i*=256);)n+=this[e+--t]*i;return n},c.prototype.readUInt8=function(e,t){return t||x(e,1,this.length),this[e]},c.prototype.readUInt16LE=function(e,t){return t||x(e,2,this.length),this[e]|this[e+1]<<8},c.prototype.readUInt16BE=function(e,t){return t||x(e,2,this.length),this[e]<<8|this[e+1]},c.prototype.readUInt32LE=function(e,t){return t||x(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},c.prototype.readUInt32BE=function(e,t){return t||x(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},c.prototype.readIntLE=function(e,t,r){e|=0,t|=0,r||x(e,t,this.length);for(var n=this[e],i=1,o=0;++o=(i*=128)&&(n-=Math.pow(2,8*t)),n},c.prototype.readIntBE=function(e,t,r){e|=0,t|=0,r||x(e,t,this.length);for(var n=t,i=1,o=this[e+--n];n>0&&(i*=256);)o+=this[e+--n]*i;return o>=(i*=128)&&(o-=Math.pow(2,8*t)),o},c.prototype.readInt8=function(e,t){return t||x(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},c.prototype.readInt16LE=function(e,t){t||x(e,2,this.length);var r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},c.prototype.readInt16BE=function(e,t){t||x(e,2,this.length);var r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},c.prototype.readInt32LE=function(e,t){return t||x(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},c.prototype.readInt32BE=function(e,t){return t||x(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},c.prototype.readFloatLE=function(e,t){return t||x(e,4,this.length),i.read(this,e,!0,23,4)},c.prototype.readFloatBE=function(e,t){return t||x(e,4,this.length),i.read(this,e,!1,23,4)},c.prototype.readDoubleLE=function(e,t){return t||x(e,8,this.length),i.read(this,e,!0,52,8)},c.prototype.readDoubleBE=function(e,t){return t||x(e,8,this.length),i.read(this,e,!1,52,8)},c.prototype.writeUIntLE=function(e,t,r,n){(e=+e,t|=0,r|=0,n)||D(this,e,t,r,Math.pow(2,8*r)-1,0);var i=1,o=0;for(this[t]=255&e;++o=0&&(o*=256);)this[t+i]=e/o&255;return t+r},c.prototype.writeUInt8=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,1,255,0),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},c.prototype.writeUInt16LE=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},c.prototype.writeUInt16BE=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},c.prototype.writeUInt32LE=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):R(this,e,t,!0),t+4},c.prototype.writeUInt32BE=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):R(this,e,t,!1),t+4},c.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t|=0,!n){var i=Math.pow(2,8*r-1);D(this,e,t,r,i-1,-i)}var o=0,a=1,s=0;for(this[t]=255&e;++o>0)-s&255;return t+r},c.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t|=0,!n){var i=Math.pow(2,8*r-1);D(this,e,t,r,i-1,-i)}var o=r-1,a=1,s=0;for(this[t+o]=255&e;--o>=0&&(a*=256);)e<0&&0===s&&0!==this[t+o+1]&&(s=1),this[t+o]=(e/a>>0)-s&255;return t+r},c.prototype.writeInt8=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,1,127,-128),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},c.prototype.writeInt16LE=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},c.prototype.writeInt16BE=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},c.prototype.writeInt32LE=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,4,2147483647,-2147483648),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):R(this,e,t,!0),t+4},c.prototype.writeInt32BE=function(e,t,r){return e=+e,t|=0,r||D(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):R(this,e,t,!1),t+4},c.prototype.writeFloatLE=function(e,t,r){return F(this,e,t,!0,r)},c.prototype.writeFloatBE=function(e,t,r){return F(this,e,t,!1,r)},c.prototype.writeDoubleLE=function(e,t,r){return N(this,e,t,!0,r)},c.prototype.writeDoubleBE=function(e,t,r){return N(this,e,t,!1,r)},c.prototype.copy=function(e,t,r,n){if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t=0;--i)e[i+t]=this[i+r];else if(o<1e3||!c.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(o=t;o55295&&r<57344){if(!i){if(r>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(a+1===n){(t-=3)>-1&&o.push(239,191,189);continue}i=r;continue}if(r<56320){(t-=3)>-1&&o.push(239,191,189),i=r;continue}r=65536+(i-55296<<10|r-56320)}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,r<128){if((t-=1)<0)break;o.push(r)}else if(r<2048){if((t-=2)<0)break;o.push(r>>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return o}function H(e){return n.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(I,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,r,n){for(var i=0;i=t.length||i>=e.length);++i)t[i+r]=e[i];return i}}).call(this,r(46))},,function(e,t){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(e){"object"==typeof window&&(r=window)}e.exports=r},function(e,t,r){"use strict";function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}r.d(t,"a",(function(){return n}))},function(e,t){function r(t){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?e.exports=r=function(e){return typeof e}:e.exports=r=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(t)}e.exports=r},function(e,t,r){"use strict";r.d(t,"a",(function(){return m}));var n=function(e){for(var t,r=0,n=0,i=e.length;i>=4;++n,i-=4)t=1540483477*(65535&(t=255&e.charCodeAt(n)|(255&e.charCodeAt(++n))<<8|(255&e.charCodeAt(++n))<<16|(255&e.charCodeAt(++n))<<24))+(59797*(t>>>16)<<16),r=1540483477*(65535&(t^=t>>>24))+(59797*(t>>>16)<<16)^1540483477*(65535&r)+(59797*(r>>>16)<<16);switch(i){case 3:r^=(255&e.charCodeAt(n+2))<<16;case 2:r^=(255&e.charCodeAt(n+1))<<8;case 1:r=1540483477*(65535&(r^=255&e.charCodeAt(n)))+(59797*(r>>>16)<<16)}return(((r=1540483477*(65535&(r^=r>>>13))+(59797*(r>>>16)<<16))^r>>>15)>>>0).toString(36)},i={animationIterationCount:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},o=r(102),a=/[A-Z]|^ms/g,s=/_EMO_([^_]+?)_([^]*?)_EMO_/g,c=function(e){return 45===e.charCodeAt(1)},u=function(e){return null!=e&&"boolean"!=typeof e},l=Object(o.a)((function(e){return c(e)?e:e.replace(a,"-$&").toLowerCase()})),h=function(e,t){switch(e){case"animation":case"animationName":if("string"==typeof t)return t.replace(s,(function(e,t,r){return d={name:t,styles:r,next:d},t}))}return 1===i[e]||c(e)||"number"!=typeof t||0===t?t:t+"px"};function f(e,t,r,n){if(null==r)return"";if(void 0!==r.__emotion_styles)return r;switch(typeof r){case"boolean":return"";case"object":if(1===r.anim)return d={name:r.name,styles:r.styles,next:d},r.name;if(void 0!==r.styles){var i=r.next;if(void 0!==i)for(;void 0!==i;)d={name:i.name,styles:i.styles,next:d},i=i.next;return r.styles+";"}return function(e,t,r){var n="";if(Array.isArray(r))for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{},r=t.version,o=t.alternative,a=t.plugin,s=t.link,c=t.hint,u=a?" from ".concat(a):"",l=r?" and will be removed".concat(u," in version ").concat(r):"",h=o?" Please use ".concat(o," instead."):"",f=s?" See: ".concat(s):"",d=c?" Note: ".concat(c):"",p="".concat(e," is deprecated").concat(l,".").concat(h).concat(f).concat(d);p in i||(Object(n.doAction)("deprecated",e,t,p),console.warn(p),i[p]=!0)}},function(e,t,r){"use strict";function n(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n=0||(i[r]=e[r]);return i}r.d(t,"a",(function(){return n}))},function(e,t,r){"use strict";function n(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r1&&"boolean"!=typeof t)throw new TypeError('"allowMissing" argument must be a boolean');for(var r=m(e),o=b("%"+(r.length>0?r[0]:"")+"%",t),a=1;a=r.length){var s=i(o,r[a]);if(!t&&!(r[a]in o))throw new n("base intrinsic for "+e+" exists, but the property is not available.");o=s&&"get"in s&&!("originalValue"in s.get)?s.get:o[r[a]]}else o=o[r[a]];return o}},function(e,t,r){var n=r(280);e.exports=function(e,t){if(null==e)return{};var r,i,o=n(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}},,,function(e,t){function r(e,t){if(!e)throw new Error(t||"Assertion failed")}e.exports=r,r.equal=function(e,t,r){if(e!=t)throw new Error(r||"Assertion failed: "+e+" != "+t)}},function(e,t,r){"use strict";var n=t,i=r(75),o=r(65),a=r(261);n.assert=o,n.toArray=a.toArray,n.zero2=a.zero2,n.toHex=a.toHex,n.encode=a.encode,n.getNAF=function(e,t,r){var n=new Array(Math.max(e.bitLength(),r)+1);n.fill(0);for(var i=1<(i>>1)-1?(i>>1)-c:c,o.isubn(s)):s=0,n[a]=s,o.iushrn(1)}return n},n.getJSF=function(e,t){var r=[[],[]];e=e.clone(),t=t.clone();for(var n=0,i=0;e.cmpn(-n)>0||t.cmpn(-i)>0;){var o,a,s,c=e.andln(3)+n&3,u=t.andln(3)+i&3;if(3===c&&(c=-1),3===u&&(u=-1),0==(1&c))o=0;else o=3!==(s=e.andln(7)+n&7)&&5!==s||2!==u?c:-c;if(r[0].push(o),0==(1&u))a=0;else a=3!==(s=t.andln(7)+i&7)&&5!==s||2!==c?u:-u;r[1].push(a),2*n===o+1&&(n=1-n),2*i===a+1&&(i=1-i),e.iushrn(1),t.iushrn(1)}return r},n.cachedProperty=function(e,t,r){var n="_"+t;e.prototype[t]=function(){return void 0!==this[n]?this[n]:this[n]=r.call(this)}},n.parseBytes=function(e){return"string"==typeof e?n.toArray(e,"hex"):e},n.intFromLE=function(e){return new i(e,"hex","le")}},function(e,t,r){"use strict";r.d(t,"a",(function(){return p})),r.d(t,"c",(function(){return m})),r.d(t,"b",(function(){return b}));var n=r(56),i=r(6);var o=function(){function e(e){this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.before=null}var t=e.prototype;return t.insert=function(e){if(this.ctr%(this.isSpeedy?65e3:1)==0){var t,r=function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t}(this);t=0===this.tags.length?this.before:this.tags[this.tags.length-1].nextSibling,this.container.insertBefore(r,t),this.tags.push(r)}var n=this.tags[this.tags.length-1];if(this.isSpeedy){var i=function(e){if(e.sheet)return e.sheet;for(var t=0;tn&&(n=(t=t.trim()).charCodeAt(0)),n){case 38:return t.replace(m,"$1"+e.trim());case 58:return e.trim()+t.replace(m,"$1"+e.trim());default:if(0<1*r&&0c.charCodeAt(8))break;case 115:a=a.replace(c,"-webkit-"+c)+";"+a;break;case 207:case 102:a=a.replace(c,"-webkit-"+(102s.charCodeAt(0)&&(s=s.trim()),s=[s],0d)&&(L=(q=q.replace(" ",":")).length),0=e.length)&&56320==(64512&e.charCodeAt(t+1)))}function a(e){return(e>>>24|e>>>8&65280|e<<8&16711680|(255&e)<<24)>>>0}function s(e){return 1===e.length?"0"+e:e}function c(e){return 7===e.length?"0"+e:6===e.length?"00"+e:5===e.length?"000"+e:4===e.length?"0000"+e:3===e.length?"00000"+e:2===e.length?"000000"+e:1===e.length?"0000000"+e:e}t.inherits=i,t.toArray=function(e,t){if(Array.isArray(e))return e.slice();if(!e)return[];var r=[];if("string"==typeof e)if(t){if("hex"===t)for((e=e.replace(/[^a-z0-9]+/gi,"")).length%2!=0&&(e="0"+e),i=0;i>6|192,r[n++]=63&a|128):o(e,i)?(a=65536+((1023&a)<<10)+(1023&e.charCodeAt(++i)),r[n++]=a>>18|240,r[n++]=a>>12&63|128,r[n++]=a>>6&63|128,r[n++]=63&a|128):(r[n++]=a>>12|224,r[n++]=a>>6&63|128,r[n++]=63&a|128)}else for(i=0;i>>0}return a},t.split32=function(e,t){for(var r=new Array(4*e.length),n=0,i=0;n>>24,r[i+1]=o>>>16&255,r[i+2]=o>>>8&255,r[i+3]=255&o):(r[i+3]=o>>>24,r[i+2]=o>>>16&255,r[i+1]=o>>>8&255,r[i]=255&o)}return r},t.rotr32=function(e,t){return e>>>t|e<<32-t},t.rotl32=function(e,t){return e<>>32-t},t.sum32=function(e,t){return e+t>>>0},t.sum32_3=function(e,t,r){return e+t+r>>>0},t.sum32_4=function(e,t,r,n){return e+t+r+n>>>0},t.sum32_5=function(e,t,r,n,i){return e+t+r+n+i>>>0},t.sum64=function(e,t,r,n){var i=e[t],o=n+e[t+1]>>>0,a=(o>>0,e[t+1]=o},t.sum64_hi=function(e,t,r,n){return(t+n>>>0>>0},t.sum64_lo=function(e,t,r,n){return t+n>>>0},t.sum64_4_hi=function(e,t,r,n,i,o,a,s){var c=0,u=t;return c+=(u=u+n>>>0)>>0)>>0)>>0},t.sum64_4_lo=function(e,t,r,n,i,o,a,s){return t+n+o+s>>>0},t.sum64_5_hi=function(e,t,r,n,i,o,a,s,c,u){var l=0,h=t;return l+=(h=h+n>>>0)>>0)>>0)>>0)>>0},t.sum64_5_lo=function(e,t,r,n,i,o,a,s,c,u){return t+n+o+s+u>>>0},t.rotr64_hi=function(e,t,r){return(t<<32-r|e>>>r)>>>0},t.rotr64_lo=function(e,t,r){return(e<<32-r|t>>>r)>>>0},t.shr64_hi=function(e,t,r){return e>>>r},t.shr64_lo=function(e,t,r){return(e<<32-r|t>>>r)>>>0}},function(e,t,r){"use strict";r.d(t,"a",(function(){return c})),r.d(t,"h",(function(){return u})),r.d(t,"c",(function(){return l})),r.d(t,"d",(function(){return h})),r.d(t,"g",(function(){return f})),r.d(t,"e",(function(){return d})),r.d(t,"i",(function(){return p})),r.d(t,"f",(function(){return m})),r.d(t,"b",(function(){return b}));var n=r(8),i=r(27),o=r(2),a=r(3);function s(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:window,t=e.navigator.platform;return-1!==t.indexOf("Mac")||Object(o.includes)(["iPad","iPhone"],t)}var c=8,u=9,l=13,h=27,f=32,d=37,p=38,m=39,b=40,v="alt",g="ctrl",y="shift",w={primary:function(e){return e()?["meta"]:[g]},primaryShift:function(e){return e()?[y,"meta"]:[g,y]},primaryAlt:function(e){return e()?[v,"meta"]:[g,v]},secondary:function(e){return e()?[y,v,"meta"]:[g,y,v]},access:function(e){return e()?[g,v]:[y,v]},ctrl:function(){return[g]},alt:function(){return[v]},ctrlShift:function(){return[g,y]},shift:function(){return[y]},shiftAlt:function(){return[y,v]}},M=(Object(o.mapValues)(w,(function(e){return function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:s;return[].concat(Object(i.a)(e(r)),[t.toLowerCase()]).join("+")}})),Object(o.mapValues)(w,(function(e){return function(t){var r,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:s,c=a(),u=(r={},Object(n.a)(r,v,c?"⌥":"Alt"),Object(n.a)(r,g,c?"^":"Ctrl"),Object(n.a)(r,"meta","⌘"),Object(n.a)(r,y,c?"⇧":"Shift"),r),l=e(a).reduce((function(e,t){var r=Object(o.get)(u,t,t);return[].concat(Object(i.a)(e),c?[r]:[r,"+"])}),[]),h=Object(o.capitalize)(t);return[].concat(Object(i.a)(l),[h])}})));Object(o.mapValues)(M,(function(e){return function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:s;return e(t,r).join("")}})),Object(o.mapValues)(w,(function(e){return function(t){var r,c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:s,u=c(),l=(r={},Object(n.a)(r,y,"Shift"),Object(n.a)(r,"meta",u?"Command":"Control"),Object(n.a)(r,g,"Control"),Object(n.a)(r,v,u?"Option":"Alt"),Object(n.a)(r,",",Object(a.__)("Comma")),Object(n.a)(r,".",Object(a.__)("Period")),Object(n.a)(r,"`",Object(a.__)("Backtick")),r);return[].concat(Object(i.a)(e(c)),[t]).map((function(e){return Object(o.capitalize)(Object(o.get)(l,e,e))})).join(u?" ":" + ")}})),Object(o.mapValues)(w,(function(e){return function(t,r){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:s,i=e(n);return!!i.every((function(e){return t["".concat(e,"Key")]}))&&(r?t.key===r:Object(o.includes)(i,t.key.toLowerCase()))}}))},,,,function(e,t,r){(function(e){!function(e,t){"use strict";function n(e,t){if(!e)throw new Error(t||"Assertion failed")}function i(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e}function o(e,t,r){if(o.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(r=t,t=10),this._init(e||0,t||10,r||"be"))}var a;"object"==typeof e?e.exports=o:t.BN=o,o.BN=o,o.wordSize=26;try{a=r(398).Buffer}catch(e){}function s(e,t,r){for(var n=0,i=Math.min(e.length,r),o=t;o=49&&a<=54?a-49+10:a>=17&&a<=22?a-17+10:15&a}return n}function c(e,t,r,n){for(var i=0,o=Math.min(e.length,r),a=t;a=49?s-49+10:s>=17?s-17+10:s}return i}o.isBN=function(e){return e instanceof o||null!==e&&"object"==typeof e&&e.constructor.wordSize===o.wordSize&&Array.isArray(e.words)},o.max=function(e,t){return e.cmp(t)>0?e:t},o.min=function(e,t){return e.cmp(t)<0?e:t},o.prototype._init=function(e,t,r){if("number"==typeof e)return this._initNumber(e,t,r);if("object"==typeof e)return this._initArray(e,t,r);"hex"===t&&(t=16),n(t===(0|t)&&t>=2&&t<=36);var i=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&i++,16===t?this._parseHex(e,i):this._parseBase(e,t,i),"-"===e[0]&&(this.negative=1),this.strip(),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initNumber=function(e,t,r){e<0&&(this.negative=1,e=-e),e<67108864?(this.words=[67108863&e],this.length=1):e<4503599627370496?(this.words=[67108863&e,e/67108864&67108863],this.length=2):(n(e<9007199254740992),this.words=[67108863&e,e/67108864&67108863,1],this.length=3),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initArray=function(e,t,r){if(n("number"==typeof e.length),e.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(e.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)a=e[i]|e[i-1]<<8|e[i-2]<<16,this.words[o]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);else if("le"===r)for(i=0,o=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);return this.strip()},o.prototype._parseHex=function(e,t){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var r=0;r=t;r-=6)i=s(e,r,r+6),this.words[n]|=i<>>26-o&4194303,(o+=24)>=26&&(o-=26,n++);r+6!==t&&(i=s(e,t,r+6),this.words[n]|=i<>>26-o&4194303),this.strip()},o.prototype._parseBase=function(e,t,r){this.words=[0],this.length=1;for(var n=0,i=1;i<=67108863;i*=t)n++;n--,i=i/t|0;for(var o=e.length-r,a=o%n,s=Math.min(o,o-a)+r,u=0,l=r;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},o.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},o.prototype.inspect=function(){return(this.red?""};var u=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],l=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function f(e,t,r){r.negative=t.negative^e.negative;var n=e.length+t.length|0;r.length=n,n=n-1|0;var i=0|e.words[0],o=0|t.words[0],a=i*o,s=67108863&a,c=a/67108864|0;r.words[0]=s;for(var u=1;u>>26,h=67108863&c,f=Math.min(u,t.length-1),d=Math.max(0,u-e.length+1);d<=f;d++){var p=u-d|0;l+=(a=(i=0|e.words[p])*(o=0|t.words[d])+h)/67108864|0,h=67108863&a}r.words[u]=0|h,c=0|l}return 0!==c?r.words[u]=0|c:r.length--,r.strip()}o.prototype.toString=function(e,t){var r;if(t=0|t||1,16===(e=e||10)||"hex"===e){r="";for(var i=0,o=0,a=0;a>>24-i&16777215)||a!==this.length-1?u[6-c.length]+c+r:c+r,(i+=2)>=26&&(i-=26,a--)}for(0!==o&&(r=o.toString(16)+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}if(e===(0|e)&&e>=2&&e<=36){var f=l[e],d=h[e];r="";var p=this.clone();for(p.negative=0;!p.isZero();){var m=p.modn(d).toString(e);r=(p=p.idivn(d)).isZero()?m+r:u[f-m.length]+m+r}for(this.isZero()&&(r="0"+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}n(!1,"Base should be between 2 and 36")},o.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&n(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},o.prototype.toJSON=function(){return this.toString(16)},o.prototype.toBuffer=function(e,t){return n(void 0!==a),this.toArrayLike(a,e,t)},o.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},o.prototype.toArrayLike=function(e,t,r){var i=this.byteLength(),o=r||Math.max(1,i);n(i<=o,"byte array longer than desired length"),n(o>0,"Requested array length <= 0"),this.strip();var a,s,c="le"===t,u=new e(o),l=this.clone();if(c){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),u[s]=a;for(;s=4096&&(r+=13,t>>>=13),t>=64&&(r+=7,t>>>=7),t>=8&&(r+=4,t>>>=4),t>=2&&(r+=2,t>>>=2),r+t},o.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,r=0;return 0==(8191&t)&&(r+=13,t>>>=13),0==(127&t)&&(r+=7,t>>>=7),0==(15&t)&&(r+=4,t>>>=4),0==(3&t)&&(r+=2,t>>>=2),0==(1&t)&&r++,r},o.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},o.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},o.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},o.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var r=0;re.length?this.clone().iand(e):e.clone().iand(this)},o.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},o.prototype.iuxor=function(e){var t,r;this.length>e.length?(t=this,r=e):(t=e,r=this);for(var n=0;ne.length?this.clone().ixor(e):e.clone().ixor(this)},o.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},o.prototype.inotn=function(e){n("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),r=e%26;this._expand(t),r>0&&t--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-r),this.strip()},o.prototype.notn=function(e){return this.clone().inotn(e)},o.prototype.setn=function(e,t){n("number"==typeof e&&e>=0);var r=e/26|0,i=e%26;return this._expand(r+1),this.words[r]=t?this.words[r]|1<e.length?(r=this,n=e):(r=e,n=this);for(var i=0,o=0;o>>26;for(;0!==i&&o>>26;if(this.length=r.length,0!==i)this.words[this.length]=i,this.length++;else if(r!==this)for(;oe.length?this.clone().iadd(e):e.clone().iadd(this)},o.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var r,n,i=this.cmp(e);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(r=this,n=e):(r=e,n=this);for(var o=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==o&&a>26,this.words[a]=67108863&t;if(0===o&&a>>13,d=0|a[1],p=8191&d,m=d>>>13,b=0|a[2],v=8191&b,g=b>>>13,y=0|a[3],w=8191&y,M=y>>>13,_=0|a[4],O=8191&_,k=_>>>13,E=0|a[5],S=8191&E,A=E>>>13,C=0|a[6],j=8191&C,z=C>>>13,x=0|a[7],D=8191&x,P=x>>>13,R=0|a[8],T=8191&R,F=R>>>13,N=0|a[9],I=8191&N,L=N>>>13,B=0|s[0],H=8191&B,q=B>>>13,V=0|s[1],U=8191&V,W=V>>>13,K=0|s[2],G=8191&K,X=K>>>13,Y=0|s[3],Z=8191&Y,$=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],re=8191&te,ne=te>>>13,ie=0|s[6],oe=8191&ie,ae=ie>>>13,se=0|s[7],ce=8191&se,ue=se>>>13,le=0|s[8],he=8191&le,fe=le>>>13,de=0|s[9],pe=8191&de,me=de>>>13;r.negative=e.negative^t.negative,r.length=19;var be=(u+(n=Math.imul(h,H))|0)+((8191&(i=(i=Math.imul(h,q))+Math.imul(f,H)|0))<<13)|0;u=((o=Math.imul(f,q))+(i>>>13)|0)+(be>>>26)|0,be&=67108863,n=Math.imul(p,H),i=(i=Math.imul(p,q))+Math.imul(m,H)|0,o=Math.imul(m,q);var ve=(u+(n=n+Math.imul(h,U)|0)|0)+((8191&(i=(i=i+Math.imul(h,W)|0)+Math.imul(f,U)|0))<<13)|0;u=((o=o+Math.imul(f,W)|0)+(i>>>13)|0)+(ve>>>26)|0,ve&=67108863,n=Math.imul(v,H),i=(i=Math.imul(v,q))+Math.imul(g,H)|0,o=Math.imul(g,q),n=n+Math.imul(p,U)|0,i=(i=i+Math.imul(p,W)|0)+Math.imul(m,U)|0,o=o+Math.imul(m,W)|0;var ge=(u+(n=n+Math.imul(h,G)|0)|0)+((8191&(i=(i=i+Math.imul(h,X)|0)+Math.imul(f,G)|0))<<13)|0;u=((o=o+Math.imul(f,X)|0)+(i>>>13)|0)+(ge>>>26)|0,ge&=67108863,n=Math.imul(w,H),i=(i=Math.imul(w,q))+Math.imul(M,H)|0,o=Math.imul(M,q),n=n+Math.imul(v,U)|0,i=(i=i+Math.imul(v,W)|0)+Math.imul(g,U)|0,o=o+Math.imul(g,W)|0,n=n+Math.imul(p,G)|0,i=(i=i+Math.imul(p,X)|0)+Math.imul(m,G)|0,o=o+Math.imul(m,X)|0;var ye=(u+(n=n+Math.imul(h,Z)|0)|0)+((8191&(i=(i=i+Math.imul(h,$)|0)+Math.imul(f,Z)|0))<<13)|0;u=((o=o+Math.imul(f,$)|0)+(i>>>13)|0)+(ye>>>26)|0,ye&=67108863,n=Math.imul(O,H),i=(i=Math.imul(O,q))+Math.imul(k,H)|0,o=Math.imul(k,q),n=n+Math.imul(w,U)|0,i=(i=i+Math.imul(w,W)|0)+Math.imul(M,U)|0,o=o+Math.imul(M,W)|0,n=n+Math.imul(v,G)|0,i=(i=i+Math.imul(v,X)|0)+Math.imul(g,G)|0,o=o+Math.imul(g,X)|0,n=n+Math.imul(p,Z)|0,i=(i=i+Math.imul(p,$)|0)+Math.imul(m,Z)|0,o=o+Math.imul(m,$)|0;var we=(u+(n=n+Math.imul(h,Q)|0)|0)+((8191&(i=(i=i+Math.imul(h,ee)|0)+Math.imul(f,Q)|0))<<13)|0;u=((o=o+Math.imul(f,ee)|0)+(i>>>13)|0)+(we>>>26)|0,we&=67108863,n=Math.imul(S,H),i=(i=Math.imul(S,q))+Math.imul(A,H)|0,o=Math.imul(A,q),n=n+Math.imul(O,U)|0,i=(i=i+Math.imul(O,W)|0)+Math.imul(k,U)|0,o=o+Math.imul(k,W)|0,n=n+Math.imul(w,G)|0,i=(i=i+Math.imul(w,X)|0)+Math.imul(M,G)|0,o=o+Math.imul(M,X)|0,n=n+Math.imul(v,Z)|0,i=(i=i+Math.imul(v,$)|0)+Math.imul(g,Z)|0,o=o+Math.imul(g,$)|0,n=n+Math.imul(p,Q)|0,i=(i=i+Math.imul(p,ee)|0)+Math.imul(m,Q)|0,o=o+Math.imul(m,ee)|0;var Me=(u+(n=n+Math.imul(h,re)|0)|0)+((8191&(i=(i=i+Math.imul(h,ne)|0)+Math.imul(f,re)|0))<<13)|0;u=((o=o+Math.imul(f,ne)|0)+(i>>>13)|0)+(Me>>>26)|0,Me&=67108863,n=Math.imul(j,H),i=(i=Math.imul(j,q))+Math.imul(z,H)|0,o=Math.imul(z,q),n=n+Math.imul(S,U)|0,i=(i=i+Math.imul(S,W)|0)+Math.imul(A,U)|0,o=o+Math.imul(A,W)|0,n=n+Math.imul(O,G)|0,i=(i=i+Math.imul(O,X)|0)+Math.imul(k,G)|0,o=o+Math.imul(k,X)|0,n=n+Math.imul(w,Z)|0,i=(i=i+Math.imul(w,$)|0)+Math.imul(M,Z)|0,o=o+Math.imul(M,$)|0,n=n+Math.imul(v,Q)|0,i=(i=i+Math.imul(v,ee)|0)+Math.imul(g,Q)|0,o=o+Math.imul(g,ee)|0,n=n+Math.imul(p,re)|0,i=(i=i+Math.imul(p,ne)|0)+Math.imul(m,re)|0,o=o+Math.imul(m,ne)|0;var _e=(u+(n=n+Math.imul(h,oe)|0)|0)+((8191&(i=(i=i+Math.imul(h,ae)|0)+Math.imul(f,oe)|0))<<13)|0;u=((o=o+Math.imul(f,ae)|0)+(i>>>13)|0)+(_e>>>26)|0,_e&=67108863,n=Math.imul(D,H),i=(i=Math.imul(D,q))+Math.imul(P,H)|0,o=Math.imul(P,q),n=n+Math.imul(j,U)|0,i=(i=i+Math.imul(j,W)|0)+Math.imul(z,U)|0,o=o+Math.imul(z,W)|0,n=n+Math.imul(S,G)|0,i=(i=i+Math.imul(S,X)|0)+Math.imul(A,G)|0,o=o+Math.imul(A,X)|0,n=n+Math.imul(O,Z)|0,i=(i=i+Math.imul(O,$)|0)+Math.imul(k,Z)|0,o=o+Math.imul(k,$)|0,n=n+Math.imul(w,Q)|0,i=(i=i+Math.imul(w,ee)|0)+Math.imul(M,Q)|0,o=o+Math.imul(M,ee)|0,n=n+Math.imul(v,re)|0,i=(i=i+Math.imul(v,ne)|0)+Math.imul(g,re)|0,o=o+Math.imul(g,ne)|0,n=n+Math.imul(p,oe)|0,i=(i=i+Math.imul(p,ae)|0)+Math.imul(m,oe)|0,o=o+Math.imul(m,ae)|0;var Oe=(u+(n=n+Math.imul(h,ce)|0)|0)+((8191&(i=(i=i+Math.imul(h,ue)|0)+Math.imul(f,ce)|0))<<13)|0;u=((o=o+Math.imul(f,ue)|0)+(i>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,n=Math.imul(T,H),i=(i=Math.imul(T,q))+Math.imul(F,H)|0,o=Math.imul(F,q),n=n+Math.imul(D,U)|0,i=(i=i+Math.imul(D,W)|0)+Math.imul(P,U)|0,o=o+Math.imul(P,W)|0,n=n+Math.imul(j,G)|0,i=(i=i+Math.imul(j,X)|0)+Math.imul(z,G)|0,o=o+Math.imul(z,X)|0,n=n+Math.imul(S,Z)|0,i=(i=i+Math.imul(S,$)|0)+Math.imul(A,Z)|0,o=o+Math.imul(A,$)|0,n=n+Math.imul(O,Q)|0,i=(i=i+Math.imul(O,ee)|0)+Math.imul(k,Q)|0,o=o+Math.imul(k,ee)|0,n=n+Math.imul(w,re)|0,i=(i=i+Math.imul(w,ne)|0)+Math.imul(M,re)|0,o=o+Math.imul(M,ne)|0,n=n+Math.imul(v,oe)|0,i=(i=i+Math.imul(v,ae)|0)+Math.imul(g,oe)|0,o=o+Math.imul(g,ae)|0,n=n+Math.imul(p,ce)|0,i=(i=i+Math.imul(p,ue)|0)+Math.imul(m,ce)|0,o=o+Math.imul(m,ue)|0;var ke=(u+(n=n+Math.imul(h,he)|0)|0)+((8191&(i=(i=i+Math.imul(h,fe)|0)+Math.imul(f,he)|0))<<13)|0;u=((o=o+Math.imul(f,fe)|0)+(i>>>13)|0)+(ke>>>26)|0,ke&=67108863,n=Math.imul(I,H),i=(i=Math.imul(I,q))+Math.imul(L,H)|0,o=Math.imul(L,q),n=n+Math.imul(T,U)|0,i=(i=i+Math.imul(T,W)|0)+Math.imul(F,U)|0,o=o+Math.imul(F,W)|0,n=n+Math.imul(D,G)|0,i=(i=i+Math.imul(D,X)|0)+Math.imul(P,G)|0,o=o+Math.imul(P,X)|0,n=n+Math.imul(j,Z)|0,i=(i=i+Math.imul(j,$)|0)+Math.imul(z,Z)|0,o=o+Math.imul(z,$)|0,n=n+Math.imul(S,Q)|0,i=(i=i+Math.imul(S,ee)|0)+Math.imul(A,Q)|0,o=o+Math.imul(A,ee)|0,n=n+Math.imul(O,re)|0,i=(i=i+Math.imul(O,ne)|0)+Math.imul(k,re)|0,o=o+Math.imul(k,ne)|0,n=n+Math.imul(w,oe)|0,i=(i=i+Math.imul(w,ae)|0)+Math.imul(M,oe)|0,o=o+Math.imul(M,ae)|0,n=n+Math.imul(v,ce)|0,i=(i=i+Math.imul(v,ue)|0)+Math.imul(g,ce)|0,o=o+Math.imul(g,ue)|0,n=n+Math.imul(p,he)|0,i=(i=i+Math.imul(p,fe)|0)+Math.imul(m,he)|0,o=o+Math.imul(m,fe)|0;var Ee=(u+(n=n+Math.imul(h,pe)|0)|0)+((8191&(i=(i=i+Math.imul(h,me)|0)+Math.imul(f,pe)|0))<<13)|0;u=((o=o+Math.imul(f,me)|0)+(i>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,n=Math.imul(I,U),i=(i=Math.imul(I,W))+Math.imul(L,U)|0,o=Math.imul(L,W),n=n+Math.imul(T,G)|0,i=(i=i+Math.imul(T,X)|0)+Math.imul(F,G)|0,o=o+Math.imul(F,X)|0,n=n+Math.imul(D,Z)|0,i=(i=i+Math.imul(D,$)|0)+Math.imul(P,Z)|0,o=o+Math.imul(P,$)|0,n=n+Math.imul(j,Q)|0,i=(i=i+Math.imul(j,ee)|0)+Math.imul(z,Q)|0,o=o+Math.imul(z,ee)|0,n=n+Math.imul(S,re)|0,i=(i=i+Math.imul(S,ne)|0)+Math.imul(A,re)|0,o=o+Math.imul(A,ne)|0,n=n+Math.imul(O,oe)|0,i=(i=i+Math.imul(O,ae)|0)+Math.imul(k,oe)|0,o=o+Math.imul(k,ae)|0,n=n+Math.imul(w,ce)|0,i=(i=i+Math.imul(w,ue)|0)+Math.imul(M,ce)|0,o=o+Math.imul(M,ue)|0,n=n+Math.imul(v,he)|0,i=(i=i+Math.imul(v,fe)|0)+Math.imul(g,he)|0,o=o+Math.imul(g,fe)|0;var Se=(u+(n=n+Math.imul(p,pe)|0)|0)+((8191&(i=(i=i+Math.imul(p,me)|0)+Math.imul(m,pe)|0))<<13)|0;u=((o=o+Math.imul(m,me)|0)+(i>>>13)|0)+(Se>>>26)|0,Se&=67108863,n=Math.imul(I,G),i=(i=Math.imul(I,X))+Math.imul(L,G)|0,o=Math.imul(L,X),n=n+Math.imul(T,Z)|0,i=(i=i+Math.imul(T,$)|0)+Math.imul(F,Z)|0,o=o+Math.imul(F,$)|0,n=n+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,ee)|0)+Math.imul(P,Q)|0,o=o+Math.imul(P,ee)|0,n=n+Math.imul(j,re)|0,i=(i=i+Math.imul(j,ne)|0)+Math.imul(z,re)|0,o=o+Math.imul(z,ne)|0,n=n+Math.imul(S,oe)|0,i=(i=i+Math.imul(S,ae)|0)+Math.imul(A,oe)|0,o=o+Math.imul(A,ae)|0,n=n+Math.imul(O,ce)|0,i=(i=i+Math.imul(O,ue)|0)+Math.imul(k,ce)|0,o=o+Math.imul(k,ue)|0,n=n+Math.imul(w,he)|0,i=(i=i+Math.imul(w,fe)|0)+Math.imul(M,he)|0,o=o+Math.imul(M,fe)|0;var Ae=(u+(n=n+Math.imul(v,pe)|0)|0)+((8191&(i=(i=i+Math.imul(v,me)|0)+Math.imul(g,pe)|0))<<13)|0;u=((o=o+Math.imul(g,me)|0)+(i>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,n=Math.imul(I,Z),i=(i=Math.imul(I,$))+Math.imul(L,Z)|0,o=Math.imul(L,$),n=n+Math.imul(T,Q)|0,i=(i=i+Math.imul(T,ee)|0)+Math.imul(F,Q)|0,o=o+Math.imul(F,ee)|0,n=n+Math.imul(D,re)|0,i=(i=i+Math.imul(D,ne)|0)+Math.imul(P,re)|0,o=o+Math.imul(P,ne)|0,n=n+Math.imul(j,oe)|0,i=(i=i+Math.imul(j,ae)|0)+Math.imul(z,oe)|0,o=o+Math.imul(z,ae)|0,n=n+Math.imul(S,ce)|0,i=(i=i+Math.imul(S,ue)|0)+Math.imul(A,ce)|0,o=o+Math.imul(A,ue)|0,n=n+Math.imul(O,he)|0,i=(i=i+Math.imul(O,fe)|0)+Math.imul(k,he)|0,o=o+Math.imul(k,fe)|0;var Ce=(u+(n=n+Math.imul(w,pe)|0)|0)+((8191&(i=(i=i+Math.imul(w,me)|0)+Math.imul(M,pe)|0))<<13)|0;u=((o=o+Math.imul(M,me)|0)+(i>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,n=Math.imul(I,Q),i=(i=Math.imul(I,ee))+Math.imul(L,Q)|0,o=Math.imul(L,ee),n=n+Math.imul(T,re)|0,i=(i=i+Math.imul(T,ne)|0)+Math.imul(F,re)|0,o=o+Math.imul(F,ne)|0,n=n+Math.imul(D,oe)|0,i=(i=i+Math.imul(D,ae)|0)+Math.imul(P,oe)|0,o=o+Math.imul(P,ae)|0,n=n+Math.imul(j,ce)|0,i=(i=i+Math.imul(j,ue)|0)+Math.imul(z,ce)|0,o=o+Math.imul(z,ue)|0,n=n+Math.imul(S,he)|0,i=(i=i+Math.imul(S,fe)|0)+Math.imul(A,he)|0,o=o+Math.imul(A,fe)|0;var je=(u+(n=n+Math.imul(O,pe)|0)|0)+((8191&(i=(i=i+Math.imul(O,me)|0)+Math.imul(k,pe)|0))<<13)|0;u=((o=o+Math.imul(k,me)|0)+(i>>>13)|0)+(je>>>26)|0,je&=67108863,n=Math.imul(I,re),i=(i=Math.imul(I,ne))+Math.imul(L,re)|0,o=Math.imul(L,ne),n=n+Math.imul(T,oe)|0,i=(i=i+Math.imul(T,ae)|0)+Math.imul(F,oe)|0,o=o+Math.imul(F,ae)|0,n=n+Math.imul(D,ce)|0,i=(i=i+Math.imul(D,ue)|0)+Math.imul(P,ce)|0,o=o+Math.imul(P,ue)|0,n=n+Math.imul(j,he)|0,i=(i=i+Math.imul(j,fe)|0)+Math.imul(z,he)|0,o=o+Math.imul(z,fe)|0;var ze=(u+(n=n+Math.imul(S,pe)|0)|0)+((8191&(i=(i=i+Math.imul(S,me)|0)+Math.imul(A,pe)|0))<<13)|0;u=((o=o+Math.imul(A,me)|0)+(i>>>13)|0)+(ze>>>26)|0,ze&=67108863,n=Math.imul(I,oe),i=(i=Math.imul(I,ae))+Math.imul(L,oe)|0,o=Math.imul(L,ae),n=n+Math.imul(T,ce)|0,i=(i=i+Math.imul(T,ue)|0)+Math.imul(F,ce)|0,o=o+Math.imul(F,ue)|0,n=n+Math.imul(D,he)|0,i=(i=i+Math.imul(D,fe)|0)+Math.imul(P,he)|0,o=o+Math.imul(P,fe)|0;var xe=(u+(n=n+Math.imul(j,pe)|0)|0)+((8191&(i=(i=i+Math.imul(j,me)|0)+Math.imul(z,pe)|0))<<13)|0;u=((o=o+Math.imul(z,me)|0)+(i>>>13)|0)+(xe>>>26)|0,xe&=67108863,n=Math.imul(I,ce),i=(i=Math.imul(I,ue))+Math.imul(L,ce)|0,o=Math.imul(L,ue),n=n+Math.imul(T,he)|0,i=(i=i+Math.imul(T,fe)|0)+Math.imul(F,he)|0,o=o+Math.imul(F,fe)|0;var De=(u+(n=n+Math.imul(D,pe)|0)|0)+((8191&(i=(i=i+Math.imul(D,me)|0)+Math.imul(P,pe)|0))<<13)|0;u=((o=o+Math.imul(P,me)|0)+(i>>>13)|0)+(De>>>26)|0,De&=67108863,n=Math.imul(I,he),i=(i=Math.imul(I,fe))+Math.imul(L,he)|0,o=Math.imul(L,fe);var Pe=(u+(n=n+Math.imul(T,pe)|0)|0)+((8191&(i=(i=i+Math.imul(T,me)|0)+Math.imul(F,pe)|0))<<13)|0;u=((o=o+Math.imul(F,me)|0)+(i>>>13)|0)+(Pe>>>26)|0,Pe&=67108863;var Re=(u+(n=Math.imul(I,pe))|0)+((8191&(i=(i=Math.imul(I,me))+Math.imul(L,pe)|0))<<13)|0;return u=((o=Math.imul(L,me))+(i>>>13)|0)+(Re>>>26)|0,Re&=67108863,c[0]=be,c[1]=ve,c[2]=ge,c[3]=ye,c[4]=we,c[5]=Me,c[6]=_e,c[7]=Oe,c[8]=ke,c[9]=Ee,c[10]=Se,c[11]=Ae,c[12]=Ce,c[13]=je,c[14]=ze,c[15]=xe,c[16]=De,c[17]=Pe,c[18]=Re,0!==u&&(c[19]=u,r.length++),r};function p(e,t,r){return(new m).mulp(e,t,r)}function m(e,t){this.x=e,this.y=t}Math.imul||(d=f),o.prototype.mulTo=function(e,t){var r=this.length+e.length;return 10===this.length&&10===e.length?d(this,e,t):r<63?f(this,e,t):r<1024?function(e,t,r){r.negative=t.negative^e.negative,r.length=e.length+t.length;for(var n=0,i=0,o=0;o>>26)|0)>>>26,a&=67108863}r.words[o]=s,n=a,a=i}return 0!==n?r.words[o]=n:r.length--,r.strip()}(this,e,t):p(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),r=o.prototype._countBits(e)-1,n=0;n>=1;return n},m.prototype.permute=function(e,t,r,n,i,o){for(var a=0;a>>=1)i++;return 1<>>=13,r[2*a+1]=8191&o,o>>>=13;for(a=2*t;a>=26,t+=i/67108864|0,t+=o>>>26,this.words[r]=67108863&o}return 0!==t&&(this.words[r]=t,this.length++),this},o.prototype.muln=function(e){return this.clone().imuln(e)},o.prototype.sqr=function(){return this.mul(this)},o.prototype.isqr=function(){return this.imul(this.clone())},o.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),r=0;r>>i}return t}(e);if(0===t.length)return new o(1);for(var r=this,n=0;n=0);var t,r=e%26,i=(e-r)/26,o=67108863>>>26-r<<26-r;if(0!==r){var a=0;for(t=0;t>>26-r}a&&(this.words[t]=a,this.length++)}if(0!==i){for(t=this.length-1;t>=0;t--)this.words[t+i]=this.words[t];for(t=0;t=0),i=t?(t-t%26)/26:0;var o=e%26,a=Math.min((e-o)/26,this.length),s=67108863^67108863>>>o<a)for(this.length-=a,u=0;u=0&&(0!==l||u>=i);u--){var h=0|this.words[u];this.words[u]=l<<26-o|h>>>o,l=h&s}return c&&0!==l&&(c.words[c.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},o.prototype.ishrn=function(e,t,r){return n(0===this.negative),this.iushrn(e,t,r)},o.prototype.shln=function(e){return this.clone().ishln(e)},o.prototype.ushln=function(e){return this.clone().iushln(e)},o.prototype.shrn=function(e){return this.clone().ishrn(e)},o.prototype.ushrn=function(e){return this.clone().iushrn(e)},o.prototype.testn=function(e){n("number"==typeof e&&e>=0);var t=e%26,r=(e-t)/26,i=1<=0);var t=e%26,r=(e-t)/26;if(n(0===this.negative,"imaskn works only with positive numbers"),this.length<=r)return this;if(0!==t&&r++,this.length=Math.min(r,this.length),0!==t){var i=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},o.prototype.isubn=function(e){if(n("number"==typeof e),n(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(c/67108864|0),this.words[i+r]=67108863&o}for(;i>26,this.words[i+r]=67108863&o;if(0===s)return this.strip();for(n(-1===s),s=0,i=0;i>26,this.words[i]=67108863&o;return this.negative=1,this.strip()},o.prototype._wordDiv=function(e,t){var r=(this.length,e.length),n=this.clone(),i=e,a=0|i.words[i.length-1];0!==(r=26-this._countBits(a))&&(i=i.ushln(r),n.iushln(r),a=0|i.words[i.length-1]);var s,c=n.length-i.length;if("mod"!==t){(s=new o(null)).length=c+1,s.words=new Array(s.length);for(var u=0;u=0;h--){var f=67108864*(0|n.words[i.length+h])+(0|n.words[i.length+h-1]);for(f=Math.min(f/a|0,67108863),n._ishlnsubmul(i,f,h);0!==n.negative;)f--,n.negative=0,n._ishlnsubmul(i,1,h),n.isZero()||(n.negative^=1);s&&(s.words[h]=f)}return s&&s.strip(),n.strip(),"div"!==t&&0!==r&&n.iushrn(r),{div:s||null,mod:n}},o.prototype.divmod=function(e,t,r){return n(!e.isZero()),this.isZero()?{div:new o(0),mod:new o(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(i=s.div.neg()),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.iadd(e)),{div:i,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new o(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new o(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new o(this.modn(e.words[0]))}:this._wordDiv(e,t);var i,a,s},o.prototype.div=function(e){return this.divmod(e,"div",!1).div},o.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},o.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},o.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var r=0!==t.div.negative?t.mod.isub(e):t.mod,n=e.ushrn(1),i=e.andln(1),o=r.cmp(n);return o<0||1===i&&0===o?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},o.prototype.modn=function(e){n(e<=67108863);for(var t=(1<<26)%e,r=0,i=this.length-1;i>=0;i--)r=(t*r+(0|this.words[i]))%e;return r},o.prototype.idivn=function(e){n(e<=67108863);for(var t=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*t;this.words[r]=i/e|0,t=i%e}return this.strip()},o.prototype.divn=function(e){return this.clone().idivn(e)},o.prototype.egcd=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i=new o(1),a=new o(0),s=new o(0),c=new o(1),u=0;t.isEven()&&r.isEven();)t.iushrn(1),r.iushrn(1),++u;for(var l=r.clone(),h=t.clone();!t.isZero();){for(var f=0,d=1;0==(t.words[0]&d)&&f<26;++f,d<<=1);if(f>0)for(t.iushrn(f);f-- >0;)(i.isOdd()||a.isOdd())&&(i.iadd(l),a.isub(h)),i.iushrn(1),a.iushrn(1);for(var p=0,m=1;0==(r.words[0]&m)&&p<26;++p,m<<=1);if(p>0)for(r.iushrn(p);p-- >0;)(s.isOdd()||c.isOdd())&&(s.iadd(l),c.isub(h)),s.iushrn(1),c.iushrn(1);t.cmp(r)>=0?(t.isub(r),i.isub(s),a.isub(c)):(r.isub(t),s.isub(i),c.isub(a))}return{a:s,b:c,gcd:r.iushln(u)}},o.prototype._invmp=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i,a=new o(1),s=new o(0),c=r.clone();t.cmpn(1)>0&&r.cmpn(1)>0;){for(var u=0,l=1;0==(t.words[0]&l)&&u<26;++u,l<<=1);if(u>0)for(t.iushrn(u);u-- >0;)a.isOdd()&&a.iadd(c),a.iushrn(1);for(var h=0,f=1;0==(r.words[0]&f)&&h<26;++h,f<<=1);if(h>0)for(r.iushrn(h);h-- >0;)s.isOdd()&&s.iadd(c),s.iushrn(1);t.cmp(r)>=0?(t.isub(r),a.isub(s)):(r.isub(t),s.isub(a))}return(i=0===t.cmpn(1)?a:s).cmpn(0)<0&&i.iadd(e),i},o.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),r=e.clone();t.negative=0,r.negative=0;for(var n=0;t.isEven()&&r.isEven();n++)t.iushrn(1),r.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;r.isEven();)r.iushrn(1);var i=t.cmp(r);if(i<0){var o=t;t=r,r=o}else if(0===i||0===r.cmpn(1))break;t.isub(r)}return r.iushln(n)},o.prototype.invm=function(e){return this.egcd(e).a.umod(e)},o.prototype.isEven=function(){return 0==(1&this.words[0])},o.prototype.isOdd=function(){return 1==(1&this.words[0])},o.prototype.andln=function(e){return this.words[0]&e},o.prototype.bincn=function(e){n("number"==typeof e);var t=e%26,r=(e-t)/26,i=1<>>26,s&=67108863,this.words[a]=s}return 0!==o&&(this.words[a]=o,this.length++),this},o.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},o.prototype.cmpn=function(e){var t,r=e<0;if(0!==this.negative&&!r)return-1;if(0===this.negative&&r)return 1;if(this.strip(),this.length>1)t=1;else{r&&(e=-e),n(e<=67108863,"Number is too big");var i=0|this.words[0];t=i===e?0:ie.length)return 1;if(this.length=0;r--){var n=0|this.words[r],i=0|e.words[r];if(n!==i){ni&&(t=1);break}}return t},o.prototype.gtn=function(e){return 1===this.cmpn(e)},o.prototype.gt=function(e){return 1===this.cmp(e)},o.prototype.gten=function(e){return this.cmpn(e)>=0},o.prototype.gte=function(e){return this.cmp(e)>=0},o.prototype.ltn=function(e){return-1===this.cmpn(e)},o.prototype.lt=function(e){return-1===this.cmp(e)},o.prototype.lten=function(e){return this.cmpn(e)<=0},o.prototype.lte=function(e){return this.cmp(e)<=0},o.prototype.eqn=function(e){return 0===this.cmpn(e)},o.prototype.eq=function(e){return 0===this.cmp(e)},o.red=function(e){return new _(e)},o.prototype.toRed=function(e){return n(!this.red,"Already a number in reduction context"),n(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},o.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},o.prototype._forceRed=function(e){return this.red=e,this},o.prototype.forceRed=function(e){return n(!this.red,"Already a number in reduction context"),this._forceRed(e)},o.prototype.redAdd=function(e){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},o.prototype.redIAdd=function(e){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},o.prototype.redSub=function(e){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},o.prototype.redISub=function(e){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},o.prototype.redShl=function(e){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},o.prototype.redMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},o.prototype.redIMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},o.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},o.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},o.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},o.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},o.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},o.prototype.redPow=function(e){return n(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var b={k256:null,p224:null,p192:null,p25519:null};function v(e,t){this.name=e,this.p=new o(t,16),this.n=this.p.bitLength(),this.k=new o(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function g(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function y(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function w(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function M(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function _(e){if("string"==typeof e){var t=o._prime(e);this.m=t.p,this.prime=t}else n(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function O(e){_.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new o(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var e=new o(null);return e.words=new Array(Math.ceil(this.n/13)),e},v.prototype.ireduce=function(e){var t,r=e;do{this.split(r,this.tmp),t=(r=(r=this.imulK(r)).iadd(this.tmp)).bitLength()}while(t>this.n);var n=t0?r.isub(this.p):void 0!==r.strip?r.strip():r._strip(),r},v.prototype.split=function(e,t){e.iushrn(this.n,0,t)},v.prototype.imulK=function(e){return e.imul(this.k)},i(g,v),g.prototype.split=function(e,t){for(var r=Math.min(e.length,9),n=0;n>>22,i=o}i>>>=22,e.words[n-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},g.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,r=0;r>>=26,e.words[r]=i,t=n}return 0!==t&&(e.words[e.length++]=t),e},o._prime=function(e){if(b[e])return b[e];var t;if("k256"===e)t=new g;else if("p224"===e)t=new y;else if("p192"===e)t=new w;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new M}return b[e]=t,t},_.prototype._verify1=function(e){n(0===e.negative,"red works only with positives"),n(e.red,"red works only with red numbers")},_.prototype._verify2=function(e,t){n(0==(e.negative|t.negative),"red works only with positives"),n(e.red&&e.red===t.red,"red works only with red numbers")},_.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},_.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},_.prototype.add=function(e,t){this._verify2(e,t);var r=e.add(t);return r.cmp(this.m)>=0&&r.isub(this.m),r._forceRed(this)},_.prototype.iadd=function(e,t){this._verify2(e,t);var r=e.iadd(t);return r.cmp(this.m)>=0&&r.isub(this.m),r},_.prototype.sub=function(e,t){this._verify2(e,t);var r=e.sub(t);return r.cmpn(0)<0&&r.iadd(this.m),r._forceRed(this)},_.prototype.isub=function(e,t){this._verify2(e,t);var r=e.isub(t);return r.cmpn(0)<0&&r.iadd(this.m),r},_.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},_.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},_.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},_.prototype.isqr=function(e){return this.imul(e,e.clone())},_.prototype.sqr=function(e){return this.mul(e,e)},_.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(n(t%2==1),3===t){var r=this.m.add(new o(1)).iushrn(2);return this.pow(e,r)}for(var i=this.m.subn(1),a=0;!i.isZero()&&0===i.andln(1);)a++,i.iushrn(1);n(!i.isZero());var s=new o(1).toRed(this),c=s.redNeg(),u=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new o(2*l*l).toRed(this);0!==this.pow(l,u).cmp(c);)l.redIAdd(c);for(var h=this.pow(l,i),f=this.pow(e,i.addn(1).iushrn(1)),d=this.pow(e,i),p=a;0!==d.cmp(s);){for(var m=d,b=0;0!==m.cmp(s);b++)m=m.redSqr();n(b=0;n--){for(var u=t.words[n],l=c-1;l>=0;l--){var h=u>>l&1;i!==r[0]&&(i=this.sqr(i)),0!==h||0!==a?(a<<=1,a|=h,(4===++s||0===n&&0===l)&&(i=this.mul(i,r[a]),s=0,a=0)):s=0}c=26}return i},_.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},_.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},o.mont=function(e){return new O(e)},i(O,_),O.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},O.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},O.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var r=e.imul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},O.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new o(0)._forceRed(this);var r=e.mul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},O.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e,this)}).call(this,r(80)(e))},,,,function(e,t){e.exports=function(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r1;){var t=e.pop(),r=t.obj[t.prop];if(i(r)){for(var n=[],o=0;o=48&&s<=57||s>=65&&s<=90||s>=97&&s<=122?i+=n.charAt(a):s<128?i+=o[s]:s<2048?i+=o[192|s>>6]+o[128|63&s]:s<55296||s>=57344?i+=o[224|s>>12]+o[128|s>>6&63]+o[128|63&s]:(a+=1,s=65536+((1023&s)<<10|1023&n.charCodeAt(a)),i+=o[240|s>>18]+o[128|s>>12&63]+o[128|s>>6&63]+o[128|63&s])}return i},isBuffer:function(e){return!(!e||"object"!=typeof e)&&!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))},isRegExp:function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},maybeMap:function(e,t){if(i(e)){for(var r=[],n=0;n0&&a.length>i&&!a.warned){a.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=a.length,s=c,console&&console.warn&&console.warn(s)}return e}function f(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function d(e,t,r){var n={fired:!1,wrapFn:void 0,target:e,type:t,listener:r},i=f.bind(n);return i.listener=r,n.wrapFn=i,i}function p(e,t,r){var n=e._events;if(void 0===n)return[];var i=n[t];return void 0===i?[]:"function"==typeof i?r?[i.listener||i]:[i]:r?function(e){for(var t=new Array(e.length),r=0;r0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var c=i[e];if(void 0===c)return!1;if("function"==typeof c)o(c,this,t);else{var u=c.length,l=b(c,u);for(r=0;r=0;o--)if(r[o]===t||r[o].listener===t){a=r[o].listener,i=o;break}if(i<0)return this;0===i?r.shift():function(e,t){for(;t+1=0;n--)this.removeListener(e,t[n]);return this},s.prototype.listeners=function(e){return p(this,e,!0)},s.prototype.rawListeners=function(e){return p(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):m.call(e,t)},s.prototype.listenerCount=m,s.prototype.eventNames=function(){return this._eventsCount>0?n(this._events):[]}},function(e,t,r){"use strict";var n=r(28).Buffer,i=n.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function o(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(n.isEncoding===i||!i(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=c,this.end=u,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=h,t=3;break;default:return this.write=f,void(this.end=d)}this.lastNeed=0,this.lastTotal=0,this.lastChar=n.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,r=function(e,t,r){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==r?r:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function c(e,t){if((e.length-t)%2==0){var r=e.toString("utf16le",t);if(r){var n=r.charCodeAt(r.length-1);if(n>=55296&&n<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],r.slice(0,-1)}return r}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function u(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,r)}return t}function l(e,t){var r=(e.length-t)%3;return 0===r?e.toString("base64",t):(this.lastNeed=3-r,this.lastTotal=3,1===r?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-r))}function h(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function f(e){return e.toString(this.encoding)}function d(e){return e&&e.length?this.write(e):""}t.StringDecoder=o,o.prototype.write=function(e){if(0===e.length)return"";var t,r;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";r=this.lastNeed,this.lastNeed=0}else r=0;return r=0)return i>0&&(e.lastNeed=i-1),i;if(--n=0)return i>0&&(e.lastNeed=i-2),i;if(--n=0)return i>0&&(2===i?i=0:e.lastNeed=i-3),i;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=r;var n=e.length-(r-this.lastNeed);return e.copy(this.lastChar,0,n),e.toString("utf8",t,n)},o.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,r){"use strict";var n=r(148),i=Object.keys||function(e){var t=[];for(var r in e)t.push(r);return t};e.exports=h;var o=Object.create(r(121));o.inherits=r(25);var a=r(233),s=r(173);o.inherits(h,a);for(var c=i(s.prototype),u=0;u1&&void 0!==arguments[1]?arguments[1]:{},r=t.stylesPropName,s=void 0===r?"styles":r,l=t.themePropName,f=void 0===l?"theme":l,v=t.cssPropName,_=void 0===v?"css":v,O=t.flushBefore,k=void 0!==O&&O,E=t.pureComponent,S=void 0!==E&&E,A=void 0,C=void 0,j=void 0,z=void 0,x=y(S);function D(e){return e===u.DIRECTIONS.LTR?h.default.resolveLTR:h.default.resolveRTL}function P(e){return e===u.DIRECTIONS.LTR?j:z}function R(t,r){var n=P(t),i=t===u.DIRECTIONS.LTR?A:C,o=h.default.get();return i&&n===o||(t===u.DIRECTIONS.RTL?(C=e?h.default.createRTL(e):g,z=o,i=C):(A=e?h.default.createLTR(e):g,j=o,i=A)),i}function T(e,t){return{resolveMethod:D(e),styleDef:R(e)}}return function(e){var t=e.displayName||e.name||"Component",r=function(t){function r(e,t){d(this,r);var n=p(this,(r.__proto__||Object.getPrototypeOf(r)).call(this,e,t)),i=n.context[u.CHANNEL]?n.context[u.CHANNEL].getState():M;return n.state=T(i),n}return m(r,t),i(r,[{key:"componentDidMount",value:function(){var e=this;this.context[u.CHANNEL]&&(this.channelUnsubscribe=this.context[u.CHANNEL].subscribe((function(t){e.setState(T(t))})))}},{key:"componentWillUnmount",value:function(){this.channelUnsubscribe&&this.channelUnsubscribe()}},{key:"render",value:function(){var t;k&&h.default.flush();var r=this.state,i=r.resolveMethod,o=r.styleDef;return a.default.createElement(e,n({},this.props,(b(t={},f,h.default.get()),b(t,s,o()),b(t,_,i),t)))}}]),r}(x);return r.WrappedComponent=e,r.displayName="withStyles("+String(t)+")",r.contextTypes=w,e.propTypes&&(r.propTypes=(0,o.default)({},e.propTypes),delete r.propTypes[s],delete r.propTypes[f],delete r.propTypes[_]),e.defaultProps&&(r.defaultProps=(0,o.default)({},e.defaultProps)),(0,c.default)(r,e)}};var o=f(r(84)),a=f(r(6)),s=f(r(1)),c=f(r(293)),u=r(675),l=f(r(676)),h=f(r(471));function f(e){return e&&e.__esModule?e:{default:e}}function d(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function p(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function m(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function b(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}t.css=h.default.resolveLTR,t.withStylesPropTypes={styles:s.default.object.isRequired,theme:s.default.object.isRequired,css:s.default.func.isRequired};var v={},g=function(){return v};function y(e){if(e){if(!a.default.PureComponent)throw new ReferenceError("withStyles() pureComponent option requires React 15.3.0 or later");return a.default.PureComponent}return a.default.Component}var w=b({},u.CHANNEL,l.default),M=u.DIRECTIONS.LTR},function(e,t,r){"use strict";(function(t,n){var i=r(28).Buffer,o=t.crypto||t.msCrypto;o&&o.getRandomValues?e.exports=function(e,t){if(e>4294967295)throw new RangeError("requested too many random bytes");var r=i.allocUnsafe(e);if(e>0)if(e>65536)for(var a=0;a2?"one of ".concat(t," ").concat(e.slice(0,r-1).join(", "),", or ")+e[r-1]:2===r?"one of ".concat(t," ").concat(e[0]," or ").concat(e[1]):"of ".concat(t," ").concat(e[0])}return"of ".concat(t," ").concat(String(e))}i("ERR_INVALID_OPT_VALUE",(function(e,t){return'The value "'+t+'" is invalid for option "'+e+'"'}),TypeError),i("ERR_INVALID_ARG_TYPE",(function(e,t,r){var n,i,a,s;if("string"==typeof t&&(i="not ",t.substr(!a||a<0?0:+a,i.length)===i)?(n="must not be",t=t.replace(/^not /,"")):n="must be",function(e,t,r){return(void 0===r||r>e.length)&&(r=e.length),e.substring(r-t.length,r)===t}(e," argument"))s="The ".concat(e," ").concat(n," ").concat(o(t,"type"));else{var c=function(e,t,r){return"number"!=typeof r&&(r=0),!(r+t.length>e.length)&&-1!==e.indexOf(t,r)}(e,".")?"property":"argument";s='The "'.concat(e,'" ').concat(c," ").concat(n," ").concat(o(t,"type"))}return s+=". Received type ".concat(typeof r)}),TypeError),i("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),i("ERR_METHOD_NOT_IMPLEMENTED",(function(e){return"The "+e+" method is not implemented"})),i("ERR_STREAM_PREMATURE_CLOSE","Premature close"),i("ERR_STREAM_DESTROYED",(function(e){return"Cannot call "+e+" after a stream was destroyed"})),i("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),i("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),i("ERR_STREAM_WRITE_AFTER_END","write after end"),i("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),i("ERR_UNKNOWN_ENCODING",(function(e){return"Unknown encoding: "+e}),TypeError),i("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),e.exports.codes=n},function(e,t,r){"use strict";(function(t){var n=Object.keys||function(e){var t=[];for(var r in e)t.push(r);return t};e.exports=u;var i=r(225),o=r(229);r(25)(u,i);for(var a=n(o.prototype),s=0;s=this._finalSize&&(this._update(this._block),this._block.fill(0));var r=8*this._len;if(r<=4294967295)this._block.writeUInt32BE(r,this._blockSize-4);else{var n=(4294967295&r)>>>0,i=(r-n)/4294967296;this._block.writeUInt32BE(i,this._blockSize-8),this._block.writeUInt32BE(n,this._blockSize-4)}this._update(this._block);var o=this._hash();return e?o.toString(e):o},i.prototype._update=function(){throw new Error("_update must be implemented by subclass")},e.exports=i},function(e,t,r){"use strict";var n={};function i(e,t,r){r||(r=Error);var i=function(e){var r,n;function i(r,n,i){return e.call(this,function(e,r,n){return"string"==typeof t?t:t(e,r,n)}(r,n,i))||this}return n=e,(r=i).prototype=Object.create(n.prototype),r.prototype.constructor=r,r.__proto__=n,i}(r);i.prototype.name=r.name,i.prototype.code=e,n[e]=i}function o(e,t){if(Array.isArray(e)){var r=e.length;return e=e.map((function(e){return String(e)})),r>2?"one of ".concat(t," ").concat(e.slice(0,r-1).join(", "),", or ")+e[r-1]:2===r?"one of ".concat(t," ").concat(e[0]," or ").concat(e[1]):"of ".concat(t," ").concat(e[0])}return"of ".concat(t," ").concat(String(e))}i("ERR_INVALID_OPT_VALUE",(function(e,t){return'The value "'+t+'" is invalid for option "'+e+'"'}),TypeError),i("ERR_INVALID_ARG_TYPE",(function(e,t,r){var n,i,a,s;if("string"==typeof t&&(i="not ",t.substr(!a||a<0?0:+a,i.length)===i)?(n="must not be",t=t.replace(/^not /,"")):n="must be",function(e,t,r){return(void 0===r||r>e.length)&&(r=e.length),e.substring(r-t.length,r)===t}(e," argument"))s="The ".concat(e," ").concat(n," ").concat(o(t,"type"));else{var c=function(e,t,r){return"number"!=typeof r&&(r=0),!(r+t.length>e.length)&&-1!==e.indexOf(t,r)}(e,".")?"property":"argument";s='The "'.concat(e,'" ').concat(c," ").concat(n," ").concat(o(t,"type"))}return s+=". Received type ".concat(typeof r)}),TypeError),i("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),i("ERR_METHOD_NOT_IMPLEMENTED",(function(e){return"The "+e+" method is not implemented"})),i("ERR_STREAM_PREMATURE_CLOSE","Premature close"),i("ERR_STREAM_DESTROYED",(function(e){return"Cannot call "+e+" after a stream was destroyed"})),i("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),i("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),i("ERR_STREAM_WRITE_AFTER_END","write after end"),i("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),i("ERR_UNKNOWN_ENCODING",(function(e){return"Unknown encoding: "+e}),TypeError),i("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),e.exports.codes=n},function(e,t,r){"use strict";(function(t){var n=Object.keys||function(e){var t=[];for(var r in e)t.push(r);return t};e.exports=u;var i=r(255),o=r(259);r(25)(u,i);for(var a=n(o.prototype),s=0;s=this._delta8){var r=(e=this.pending).length%this._delta8;this.pending=e.slice(e.length-r,e.length),0===this.pending.length&&(this.pending=null),e=n.join32(e,0,e.length-r,this.endian);for(var i=0;i>>24&255,n[i++]=e>>>16&255,n[i++]=e>>>8&255,n[i++]=255&e}else for(n[i++]=255&e,n[i++]=e>>>8&255,n[i++]=e>>>16&255,n[i++]=e>>>24&255,n[i++]=0,n[i++]=0,n[i++]=0,n[i++]=0,o=8;o=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return n("end");if(o.tryLoc<=this.prev){var s=r.call(o,"catchLoc"),c=r.call(o,"finallyLoc");if(s&&c){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),_(r),l}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var i=n.arg;_(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,r){return this.delegate={iterator:k(e),resultName:t,nextLoc:r},"next"===this.method&&(this.arg=void 0),l}},e}(e.exports);try{regeneratorRuntime=n}catch(e){Function("r","regeneratorRuntime = r")(n)}},function(e,t,r){"use strict";var n=r(139);function i(){}function o(){}o.resetWarningCache=i,e.exports=function(){function e(e,t,r,i,o,a){if(a!==n){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var r={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:i};return r.PropTypes=r,r}},function(e,t,r){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(e,t,r){var n=r(79);e.exports=function(e){if(Array.isArray(e))return n(e)}},function(e,t){e.exports=function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}},function(e,t,r){"use strict";var n=Object.keys;e.exports=function(e,t){var r,i,o,a,s;if(e===t)return!0;if(r=n(e),i=n(t),r.length!==i.length)return!1;for(o=0;o2?arguments[2]:{},o=n(t);i&&(o=a.call(o,Object.getOwnPropertySymbols(t)));for(var s=0;s>>24]^l[p>>>16&255]^h[m>>>8&255]^f[255&b]^t[v++],a=u[p>>>24]^l[m>>>16&255]^h[b>>>8&255]^f[255&d]^t[v++],s=u[m>>>24]^l[b>>>16&255]^h[d>>>8&255]^f[255&p]^t[v++],c=u[b>>>24]^l[d>>>16&255]^h[p>>>8&255]^f[255&m]^t[v++],d=o,p=a,m=s,b=c;return o=(n[d>>>24]<<24|n[p>>>16&255]<<16|n[m>>>8&255]<<8|n[255&b])^t[v++],a=(n[p>>>24]<<24|n[m>>>16&255]<<16|n[b>>>8&255]<<8|n[255&d])^t[v++],s=(n[m>>>24]<<24|n[b>>>16&255]<<16|n[d>>>8&255]<<8|n[255&p])^t[v++],c=(n[b>>>24]<<24|n[d>>>16&255]<<16|n[p>>>8&255]<<8|n[255&m])^t[v++],[o>>>=0,a>>>=0,s>>>=0,c>>>=0]}var s=[0,1,2,4,8,16,32,64,128,27,54],c=function(){for(var e=new Array(256),t=0;t<256;t++)e[t]=t<128?t<<1:t<<1^283;for(var r=[],n=[],i=[[],[],[],[]],o=[[],[],[],[]],a=0,s=0,c=0;c<256;++c){var u=s^s<<1^s<<2^s<<3^s<<4;u=u>>>8^255&u^99,r[a]=u,n[u]=a;var l=e[a],h=e[l],f=e[h],d=257*e[u]^16843008*u;i[0][a]=d<<24|d>>>8,i[1][a]=d<<16|d>>>16,i[2][a]=d<<8|d>>>24,i[3][a]=d,d=16843009*f^65537*h^257*l^16843008*a,o[0][u]=d<<24|d>>>8,o[1][u]=d<<16|d>>>16,o[2][u]=d<<8|d>>>24,o[3][u]=d,0===a?a=s=1:(a=l^e[e[e[f^l]]],s^=e[e[s]])}return{SBOX:r,INV_SBOX:n,SUB_MIX:i,INV_SUB_MIX:o}}();function u(e){this._key=i(e),this._reset()}u.blockSize=16,u.keySize=32,u.prototype.blockSize=u.blockSize,u.prototype.keySize=u.keySize,u.prototype._reset=function(){for(var e=this._key,t=e.length,r=t+6,n=4*(r+1),i=[],o=0;o>>24,a=c.SBOX[a>>>24]<<24|c.SBOX[a>>>16&255]<<16|c.SBOX[a>>>8&255]<<8|c.SBOX[255&a],a^=s[o/t|0]<<24):t>6&&o%t==4&&(a=c.SBOX[a>>>24]<<24|c.SBOX[a>>>16&255]<<16|c.SBOX[a>>>8&255]<<8|c.SBOX[255&a]),i[o]=i[o-t]^a}for(var u=[],l=0;l>>24]]^c.INV_SUB_MIX[1][c.SBOX[f>>>16&255]]^c.INV_SUB_MIX[2][c.SBOX[f>>>8&255]]^c.INV_SUB_MIX[3][c.SBOX[255&f]]}this._nRounds=r,this._keySchedule=i,this._invKeySchedule=u},u.prototype.encryptBlockRaw=function(e){return a(e=i(e),this._keySchedule,c.SUB_MIX,c.SBOX,this._nRounds)},u.prototype.encryptBlock=function(e){var t=this.encryptBlockRaw(e),r=n.allocUnsafe(16);return r.writeUInt32BE(t[0],0),r.writeUInt32BE(t[1],4),r.writeUInt32BE(t[2],8),r.writeUInt32BE(t[3],12),r},u.prototype.decryptBlock=function(e){var t=(e=i(e))[1];e[1]=e[3],e[3]=t;var r=a(e,this._invKeySchedule,c.INV_SUB_MIX,c.INV_SBOX,this._nRounds),o=n.allocUnsafe(16);return o.writeUInt32BE(r[0],0),o.writeUInt32BE(r[3],4),o.writeUInt32BE(r[2],8),o.writeUInt32BE(r[1],12),o},u.prototype.scrub=function(){o(this._keySchedule),o(this._invKeySchedule),o(this._key)},e.exports.AES=u},function(e,t,r){var n=r(28).Buffer,i=r(167);e.exports=function(e,t,r,o){if(n.isBuffer(e)||(e=n.from(e,"binary")),t&&(n.isBuffer(t)||(t=n.from(t,"binary")),8!==t.length))throw new RangeError("salt should be Buffer with 8 byte length");for(var a=r/8,s=n.alloc(a),c=n.alloc(o||0),u=n.alloc(0);a>0||o>0;){var l=new i;l.update(u),l.update(e),t&&l.update(t),u=l.digest();var h=0;if(a>0){var f=s.length-a;h=Math.min(a,u.length),u.copy(s,f,0,h),a-=h}if(h0){var d=c.length-o,p=Math.min(o,u.length-h);u.copy(c,d,h,h+p),o-=p}}return u.fill(0),{key:s,iv:c}}},function(e,t,r){"use strict";var n=r(75),i=r(66),o=i.getNAF,a=i.getJSF,s=i.assert;function c(e,t){this.type=e,this.p=new n(t.p,16),this.red=t.prime?n.red(t.prime):n.mont(this.p),this.zero=new n(0).toRed(this.red),this.one=new n(1).toRed(this.red),this.two=new n(2).toRed(this.red),this.n=t.n&&new n(t.n,16),this.g=t.g&&this.pointFromJSON(t.g,t.gRed),this._wnafT1=new Array(4),this._wnafT2=new Array(4),this._wnafT3=new Array(4),this._wnafT4=new Array(4),this._bitLength=this.n?this.n.bitLength():0;var r=this.n&&this.p.div(this.n);!r||r.cmpn(100)>0?this.redN=null:(this._maxwellTrick=!0,this.redN=this.n.toRed(this.red))}function u(e,t){this.curve=e,this.type=t,this.precomputed=null}e.exports=c,c.prototype.point=function(){throw new Error("Not implemented")},c.prototype.validate=function(){throw new Error("Not implemented")},c.prototype._fixedNafMul=function(e,t){s(e.precomputed);var r=e._getDoubles(),n=o(t,1,this._bitLength),i=(1<=c;t--)u=(u<<1)+n[t];a.push(u)}for(var l=this.jpoint(null,null,null),h=this.jpoint(null,null,null),f=i;f>0;f--){for(c=0;c=0;u--){for(t=0;u>=0&&0===a[u];u--)t++;if(u>=0&&t++,c=c.dblp(t),u<0)break;var l=a[u];s(0!==l),c="affine"===e.type?l>0?c.mixedAdd(i[l-1>>1]):c.mixedAdd(i[-l-1>>1].neg()):l>0?c.add(i[l-1>>1]):c.add(i[-l-1>>1].neg())}return"affine"===e.type?c.toP():c},c.prototype._wnafMulAdd=function(e,t,r,n,i){for(var s=this._wnafT1,c=this._wnafT2,u=this._wnafT3,l=0,h=0;h=1;h-=2){var d=h-1,p=h;if(1===s[d]&&1===s[p]){var m=[t[d],null,null,t[p]];0===t[d].y.cmp(t[p].y)?(m[1]=t[d].add(t[p]),m[2]=t[d].toJ().mixedAdd(t[p].neg())):0===t[d].y.cmp(t[p].y.redNeg())?(m[1]=t[d].toJ().mixedAdd(t[p]),m[2]=t[d].add(t[p].neg())):(m[1]=t[d].toJ().mixedAdd(t[p]),m[2]=t[d].toJ().mixedAdd(t[p].neg()));var b=[-3,-1,-5,-7,0,7,5,1,3],v=a(r[d],r[p]);l=Math.max(v[0].length,l),u[d]=new Array(l),u[p]=new Array(l);for(var g=0;g=0;h--){for(var O=0;h>=0;){var k=!0;for(g=0;g=0&&O++,M=M.dblp(O),h<0)break;for(g=0;g0?E=c[g][S-1>>1]:S<0&&(E=c[g][-S-1>>1].neg()),M="affine"===E.type?M.mixedAdd(E):M.add(E))}}for(h=0;h=Math.ceil((e.bitLength()+1)/t.step)},u.prototype._getDoubles=function(e,t){if(this.precomputed&&this.precomputed.doubles)return this.precomputed.doubles;for(var r=[this],n=this,i=0;i1&&void 0!==arguments[1]?arguments[1]:new Date,o=[],a=i()(n);for(t=0;t1&&(r-=1),r<1/6?e+6*(t-e)*r:r<.5?t:r<2/3?e+(t-e)*(2/3-r)*6:e}if(e=z(e,360),t=z(t,100),r=z(r,100),0===t)n=i=o=r;else{var s=r<.5?r*(1+t):r+t-r*t,c=2*r-s;n=a(c,s,e+1/3),i=a(c,s,e),o=a(c,s,e-1/3)}return{r:255*n,g:255*i,b:255*o}}(e.h,c,l),h=!0,f="hsl"),e.hasOwnProperty("a")&&(o=e.a));var d,p,m;return o=j(o),{ok:h,format:e.format||f,r:a(255,s(i.r,0)),g:a(255,s(i.g,0)),b:a(255,s(i.b,0)),a:o}}(e);this._originalInput=e,this._r=l.r,this._g=l.g,this._b=l.b,this._a=l.a,this._roundA=o(100*this._a)/100,this._format=c.format||l.format,this._gradientType=c.gradientType,this._r<1&&(this._r=o(this._r)),this._g<1&&(this._g=o(this._g)),this._b<1&&(this._b=o(this._b)),this._ok=l.ok,this._tc_id=i++}function l(e,t,r){e=z(e,255),t=z(t,255),r=z(r,255);var n,i,o=s(e,t,r),c=a(e,t,r),u=(o+c)/2;if(o==c)n=i=0;else{var l=o-c;switch(i=u>.5?l/(2-o-c):l/(o+c),o){case e:n=(t-r)/l+(t>1)+720)%360;--t;)n.h=(n.h+i)%360,o.push(u(n));return o}function S(e,t){t=t||6;for(var r=u(e).toHsv(),n=r.h,i=r.s,o=r.v,a=[],s=1/t;t--;)a.push(u({h:n,s:i,v:o})),o=(o+s)%1;return a}u.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var e=this.toRgb();return(299*e.r+587*e.g+114*e.b)/1e3},getLuminance:function(){var e,r,n,i=this.toRgb();return e=i.r/255,r=i.g/255,n=i.b/255,.2126*(e<=.03928?e/12.92:t.pow((e+.055)/1.055,2.4))+.7152*(r<=.03928?r/12.92:t.pow((r+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:t.pow((n+.055)/1.055,2.4))},setAlpha:function(e){return this._a=j(e),this._roundA=o(100*this._a)/100,this},toHsv:function(){var e=h(this._r,this._g,this._b);return{h:360*e.h,s:e.s,v:e.v,a:this._a}},toHsvString:function(){var e=h(this._r,this._g,this._b),t=o(360*e.h),r=o(100*e.s),n=o(100*e.v);return 1==this._a?"hsv("+t+", "+r+"%, "+n+"%)":"hsva("+t+", "+r+"%, "+n+"%, "+this._roundA+")"},toHsl:function(){var e=l(this._r,this._g,this._b);return{h:360*e.h,s:e.s,l:e.l,a:this._a}},toHslString:function(){var e=l(this._r,this._g,this._b),t=o(360*e.h),r=o(100*e.s),n=o(100*e.l);return 1==this._a?"hsl("+t+", "+r+"%, "+n+"%)":"hsla("+t+", "+r+"%, "+n+"%, "+this._roundA+")"},toHex:function(e){return f(this._r,this._g,this._b,e)},toHexString:function(e){return"#"+this.toHex(e)},toHex8:function(e){return function(e,t,r,n,i){var a=[P(o(e).toString(16)),P(o(t).toString(16)),P(o(r).toString(16)),P(T(n))];if(i&&a[0].charAt(0)==a[0].charAt(1)&&a[1].charAt(0)==a[1].charAt(1)&&a[2].charAt(0)==a[2].charAt(1)&&a[3].charAt(0)==a[3].charAt(1))return a[0].charAt(0)+a[1].charAt(0)+a[2].charAt(0)+a[3].charAt(0);return a.join("")}(this._r,this._g,this._b,this._a,e)},toHex8String:function(e){return"#"+this.toHex8(e)},toRgb:function(){return{r:o(this._r),g:o(this._g),b:o(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+o(this._r)+", "+o(this._g)+", "+o(this._b)+")":"rgba("+o(this._r)+", "+o(this._g)+", "+o(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:o(100*z(this._r,255))+"%",g:o(100*z(this._g,255))+"%",b:o(100*z(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+o(100*z(this._r,255))+"%, "+o(100*z(this._g,255))+"%, "+o(100*z(this._b,255))+"%)":"rgba("+o(100*z(this._r,255))+"%, "+o(100*z(this._g,255))+"%, "+o(100*z(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(C[f(this._r,this._g,this._b,!0)]||!1)},toFilter:function(e){var t="#"+d(this._r,this._g,this._b,this._a),r=t,n=this._gradientType?"GradientType = 1, ":"";if(e){var i=u(e);r="#"+d(i._r,i._g,i._b,i._a)}return"progid:DXImageTransform.Microsoft.gradient("+n+"startColorstr="+t+",endColorstr="+r+")"},toString:function(e){var t=!!e;e=e||this._format;var r=!1,n=this._a<1&&this._a>=0;return t||!n||"hex"!==e&&"hex6"!==e&&"hex3"!==e&&"hex4"!==e&&"hex8"!==e&&"name"!==e?("rgb"===e&&(r=this.toRgbString()),"prgb"===e&&(r=this.toPercentageRgbString()),"hex"!==e&&"hex6"!==e||(r=this.toHexString()),"hex3"===e&&(r=this.toHexString(!0)),"hex4"===e&&(r=this.toHex8String(!0)),"hex8"===e&&(r=this.toHex8String()),"name"===e&&(r=this.toName()),"hsl"===e&&(r=this.toHslString()),"hsv"===e&&(r=this.toHsvString()),r||this.toHexString()):"name"===e&&0===this._a?this.toName():this.toRgbString()},clone:function(){return u(this.toString())},_applyModification:function(e,t){var r=e.apply(null,[this].concat([].slice.call(t)));return this._r=r._r,this._g=r._g,this._b=r._b,this.setAlpha(r._a),this},lighten:function(){return this._applyModification(v,arguments)},brighten:function(){return this._applyModification(g,arguments)},darken:function(){return this._applyModification(y,arguments)},desaturate:function(){return this._applyModification(p,arguments)},saturate:function(){return this._applyModification(m,arguments)},greyscale:function(){return this._applyModification(b,arguments)},spin:function(){return this._applyModification(w,arguments)},_applyCombination:function(e,t){return e.apply(null,[this].concat([].slice.call(t)))},analogous:function(){return this._applyCombination(E,arguments)},complement:function(){return this._applyCombination(M,arguments)},monochromatic:function(){return this._applyCombination(S,arguments)},splitcomplement:function(){return this._applyCombination(k,arguments)},triad:function(){return this._applyCombination(_,arguments)},tetrad:function(){return this._applyCombination(O,arguments)}},u.fromRatio=function(e,t){if("object"==typeof e){var r={};for(var n in e)e.hasOwnProperty(n)&&(r[n]="a"===n?e[n]:R(e[n]));e=r}return u(e,t)},u.equals=function(e,t){return!(!e||!t)&&u(e).toRgbString()==u(t).toRgbString()},u.random=function(){return u.fromRatio({r:c(),g:c(),b:c()})},u.mix=function(e,t,r){r=0===r?0:r||50;var n=u(e).toRgb(),i=u(t).toRgb(),o=r/100;return u({r:(i.r-n.r)*o+n.r,g:(i.g-n.g)*o+n.g,b:(i.b-n.b)*o+n.b,a:(i.a-n.a)*o+n.a})},u.readability=function(e,r){var n=u(e),i=u(r);return(t.max(n.getLuminance(),i.getLuminance())+.05)/(t.min(n.getLuminance(),i.getLuminance())+.05)},u.isReadable=function(e,t,r){var n,i,o=u.readability(e,t);switch(i=!1,(n=function(e){var t,r;t=((e=e||{level:"AA",size:"small"}).level||"AA").toUpperCase(),r=(e.size||"small").toLowerCase(),"AA"!==t&&"AAA"!==t&&(t="AA");"small"!==r&&"large"!==r&&(r="small");return{level:t,size:r}}(r)).level+n.size){case"AAsmall":case"AAAlarge":i=o>=4.5;break;case"AAlarge":i=o>=3;break;case"AAAsmall":i=o>=7}return i},u.mostReadable=function(e,t,r){var n,i,o,a,s=null,c=0;i=(r=r||{}).includeFallbackColors,o=r.level,a=r.size;for(var l=0;lc&&(c=n,s=u(t[l]));return u.isReadable(e,s,{level:o,size:a})||!i?s:(r.includeFallbackColors=!1,u.mostReadable(e,["#fff","#000"],r))};var A=u.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},C=u.hexNames=function(e){var t={};for(var r in e)e.hasOwnProperty(r)&&(t[e[r]]=r);return t}(A);function j(e){return e=parseFloat(e),(isNaN(e)||e<0||e>1)&&(e=1),e}function z(e,r){(function(e){return"string"==typeof e&&-1!=e.indexOf(".")&&1===parseFloat(e)})(e)&&(e="100%");var n=function(e){return"string"==typeof e&&-1!=e.indexOf("%")}(e);return e=a(r,s(0,parseFloat(e))),n&&(e=parseInt(e*r,10)/100),t.abs(e-r)<1e-6?1:e%r/parseFloat(r)}function x(e){return a(1,s(0,e))}function D(e){return parseInt(e,16)}function P(e){return 1==e.length?"0"+e:""+e}function R(e){return e<=1&&(e=100*e+"%"),e}function T(e){return t.round(255*parseFloat(e)).toString(16)}function F(e){return D(e)/255}var N,I,L,B=(I="[\\s|\\(]+("+(N="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+N+")[,|\\s]+("+N+")\\s*\\)?",L="[\\s|\\(]+("+N+")[,|\\s]+("+N+")[,|\\s]+("+N+")[,|\\s]+("+N+")\\s*\\)?",{CSS_UNIT:new RegExp(N),rgb:new RegExp("rgb"+I),rgba:new RegExp("rgba"+L),hsl:new RegExp("hsl"+I),hsla:new RegExp("hsla"+L),hsv:new RegExp("hsv"+I),hsva:new RegExp("hsva"+L),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});function H(e){return!!B.CSS_UNIT.exec(e)}e.exports?e.exports=u:"function"==typeof define&&define.amd?define((function(){return u})):window.tinycolor=u}(Math)},,function(e,t){function r(t,n){return e.exports=r=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},r(t,n)}e.exports=r},function(e,t,r){"use strict";var n=r(92),i=r(115),o=Object.prototype.hasOwnProperty,a={brackets:function(e){return e+"[]"},comma:"comma",indices:function(e,t){return e+"["+t+"]"},repeat:function(e){return e}},s=Array.isArray,c=Array.prototype.push,u=function(e,t){c.apply(e,s(t)?t:[t])},l=Date.prototype.toISOString,h=i.default,f={addQueryPrefix:!1,allowDots:!1,charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encoder:n.encode,encodeValuesOnly:!1,format:h,formatter:i.formatters[h],indices:!1,serializeDate:function(e){return l.call(e)},skipNulls:!1,strictNullHandling:!1},d=function e(t,r,i,o,a,c,l,h,d,p,m,b,v){var g,y=t;if("function"==typeof l?y=l(r,y):y instanceof Date?y=p(y):"comma"===i&&s(y)&&(y=n.maybeMap(y,(function(e){return e instanceof Date?p(e):e})).join(",")),null===y){if(o)return c&&!b?c(r,f.encoder,v,"key"):r;y=""}if("string"==typeof(g=y)||"number"==typeof g||"boolean"==typeof g||"symbol"==typeof g||"bigint"==typeof g||n.isBuffer(y))return c?[m(b?r:c(r,f.encoder,v,"key"))+"="+m(c(y,f.encoder,v,"value"))]:[m(r)+"="+m(String(y))];var w,M=[];if(void 0===y)return M;if(s(l))w=l;else{var _=Object.keys(y);w=h?_.sort(h):_}for(var O=0;O0?g+v:""}},function(e,t,r){"use strict";var n=r(92),i=Object.prototype.hasOwnProperty,o=Array.isArray,a={allowDots:!1,allowPrototypes:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decoder:n.decode,delimiter:"&",depth:5,ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictNullHandling:!1},s=function(e){return e.replace(/&#(\d+);/g,(function(e,t){return String.fromCharCode(parseInt(t,10))}))},c=function(e,t){return e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1?e.split(","):e},u=function(e,t,r,n){if(e){var o=r.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e,a=/(\[[^[\]]*])/g,s=r.depth>0&&/(\[[^[\]]*])/.exec(o),u=s?o.slice(0,s.index):o,l=[];if(u){if(!r.plainObjects&&i.call(Object.prototype,u)&&!r.allowPrototypes)return;l.push(u)}for(var h=0;r.depth>0&&null!==(s=a.exec(o))&&h=0;--o){var a,s=e[o];if("[]"===s&&r.parseArrays)a=[].concat(i);else{a=r.plainObjects?Object.create(null):{};var u="["===s.charAt(0)&&"]"===s.charAt(s.length-1)?s.slice(1,-1):s,l=parseInt(u,10);r.parseArrays||""!==u?!isNaN(l)&&s!==u&&String(l)===u&&l>=0&&r.parseArrays&&l<=r.arrayLimit?(a=[])[l]=i:a[u]=i:a={0:i}}i=a}return i}(l,t,r,n)}};e.exports=function(e,t){var r=function(e){if(!e)return a;if(null!==e.decoder&&void 0!==e.decoder&&"function"!=typeof e.decoder)throw new TypeError("Decoder has to be a function.");if(void 0!==e.charset&&"utf-8"!==e.charset&&"iso-8859-1"!==e.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var t=void 0===e.charset?a.charset:e.charset;return{allowDots:void 0===e.allowDots?a.allowDots:!!e.allowDots,allowPrototypes:"boolean"==typeof e.allowPrototypes?e.allowPrototypes:a.allowPrototypes,arrayLimit:"number"==typeof e.arrayLimit?e.arrayLimit:a.arrayLimit,charset:t,charsetSentinel:"boolean"==typeof e.charsetSentinel?e.charsetSentinel:a.charsetSentinel,comma:"boolean"==typeof e.comma?e.comma:a.comma,decoder:"function"==typeof e.decoder?e.decoder:a.decoder,delimiter:"string"==typeof e.delimiter||n.isRegExp(e.delimiter)?e.delimiter:a.delimiter,depth:"number"==typeof e.depth||!1===e.depth?+e.depth:a.depth,ignoreQueryPrefix:!0===e.ignoreQueryPrefix,interpretNumericEntities:"boolean"==typeof e.interpretNumericEntities?e.interpretNumericEntities:a.interpretNumericEntities,parameterLimit:"number"==typeof e.parameterLimit?e.parameterLimit:a.parameterLimit,parseArrays:!1!==e.parseArrays,plainObjects:"boolean"==typeof e.plainObjects?e.plainObjects:a.plainObjects,strictNullHandling:"boolean"==typeof e.strictNullHandling?e.strictNullHandling:a.strictNullHandling}}(t);if(""===e||null==e)return r.plainObjects?Object.create(null):{};for(var l="string"==typeof e?function(e,t){var r,u={},l=t.ignoreQueryPrefix?e.replace(/^\?/,""):e,h=t.parameterLimit===1/0?void 0:t.parameterLimit,f=l.split(t.delimiter,h),d=-1,p=t.charset;if(t.charsetSentinel)for(r=0;r-1&&(b=o(b)?[b]:b),i.call(u,m)?u[m]=n.combine(u[m],b):u[m]=b}return u}(e,r):e,h=r.plainObjects?Object.create(null):{},f=Object.keys(l),d=0;d>>32-t}function u(e,t,r,n,i,o,a){return c(e+(t&r|~t&n)+i+o|0,a)+t|0}function l(e,t,r,n,i,o,a){return c(e+(t&n|r&~n)+i+o|0,a)+t|0}function h(e,t,r,n,i,o,a){return c(e+(t^r^n)+i+o|0,a)+t|0}function f(e,t,r,n,i,o,a){return c(e+(r^(t|~n))+i+o|0,a)+t|0}n(s,i),s.prototype._update=function(){for(var e=a,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);var r=this._a,n=this._b,i=this._c,o=this._d;r=u(r,n,i,o,e[0],3614090360,7),o=u(o,r,n,i,e[1],3905402710,12),i=u(i,o,r,n,e[2],606105819,17),n=u(n,i,o,r,e[3],3250441966,22),r=u(r,n,i,o,e[4],4118548399,7),o=u(o,r,n,i,e[5],1200080426,12),i=u(i,o,r,n,e[6],2821735955,17),n=u(n,i,o,r,e[7],4249261313,22),r=u(r,n,i,o,e[8],1770035416,7),o=u(o,r,n,i,e[9],2336552879,12),i=u(i,o,r,n,e[10],4294925233,17),n=u(n,i,o,r,e[11],2304563134,22),r=u(r,n,i,o,e[12],1804603682,7),o=u(o,r,n,i,e[13],4254626195,12),i=u(i,o,r,n,e[14],2792965006,17),r=l(r,n=u(n,i,o,r,e[15],1236535329,22),i,o,e[1],4129170786,5),o=l(o,r,n,i,e[6],3225465664,9),i=l(i,o,r,n,e[11],643717713,14),n=l(n,i,o,r,e[0],3921069994,20),r=l(r,n,i,o,e[5],3593408605,5),o=l(o,r,n,i,e[10],38016083,9),i=l(i,o,r,n,e[15],3634488961,14),n=l(n,i,o,r,e[4],3889429448,20),r=l(r,n,i,o,e[9],568446438,5),o=l(o,r,n,i,e[14],3275163606,9),i=l(i,o,r,n,e[3],4107603335,14),n=l(n,i,o,r,e[8],1163531501,20),r=l(r,n,i,o,e[13],2850285829,5),o=l(o,r,n,i,e[2],4243563512,9),i=l(i,o,r,n,e[7],1735328473,14),r=h(r,n=l(n,i,o,r,e[12],2368359562,20),i,o,e[5],4294588738,4),o=h(o,r,n,i,e[8],2272392833,11),i=h(i,o,r,n,e[11],1839030562,16),n=h(n,i,o,r,e[14],4259657740,23),r=h(r,n,i,o,e[1],2763975236,4),o=h(o,r,n,i,e[4],1272893353,11),i=h(i,o,r,n,e[7],4139469664,16),n=h(n,i,o,r,e[10],3200236656,23),r=h(r,n,i,o,e[13],681279174,4),o=h(o,r,n,i,e[0],3936430074,11),i=h(i,o,r,n,e[3],3572445317,16),n=h(n,i,o,r,e[6],76029189,23),r=h(r,n,i,o,e[9],3654602809,4),o=h(o,r,n,i,e[12],3873151461,11),i=h(i,o,r,n,e[15],530742520,16),r=f(r,n=h(n,i,o,r,e[2],3299628645,23),i,o,e[0],4096336452,6),o=f(o,r,n,i,e[7],1126891415,10),i=f(i,o,r,n,e[14],2878612391,15),n=f(n,i,o,r,e[5],4237533241,21),r=f(r,n,i,o,e[12],1700485571,6),o=f(o,r,n,i,e[3],2399980690,10),i=f(i,o,r,n,e[10],4293915773,15),n=f(n,i,o,r,e[1],2240044497,21),r=f(r,n,i,o,e[8],1873313359,6),o=f(o,r,n,i,e[15],4264355552,10),i=f(i,o,r,n,e[6],2734768916,15),n=f(n,i,o,r,e[13],1309151649,21),r=f(r,n,i,o,e[4],4149444226,6),o=f(o,r,n,i,e[11],3174756917,10),i=f(i,o,r,n,e[2],718787259,15),n=f(n,i,o,r,e[9],3951481745,21),this._a=this._a+r|0,this._b=this._b+n|0,this._c=this._c+i|0,this._d=this._d+o|0},s.prototype._digest=function(){this._block[this._blockOffset++]=128,this._blockOffset>56&&(this._block.fill(0,this._blockOffset,64),this._update(),this._blockOffset=0),this._block.fill(0,this._blockOffset,56),this._block.writeUInt32LE(this._length[0],56),this._block.writeUInt32LE(this._length[1],60),this._update();var e=o.allocUnsafe(16);return e.writeInt32LE(this._a,0),e.writeInt32LE(this._b,4),e.writeInt32LE(this._c,8),e.writeInt32LE(this._d,12),e},e.exports=s},function(e,t,r){(function(t){function r(e){try{if(!t.localStorage)return!1}catch(e){return!1}var r=t.localStorage[e];return null!=r&&"true"===String(r).toLowerCase()}e.exports=function(e,t){if(r("noDeprecation"))return e;var n=!1;return function(){if(!n){if(r("throwDeprecation"))throw new Error(t);r("traceDeprecation")?console.trace(t):console.warn(t),n=!0}return e.apply(this,arguments)}}}).call(this,r(46))},function(e,t,r){"use strict";var n=r(107).codes.ERR_STREAM_PREMATURE_CLOSE;function i(){}e.exports=function e(t,r,o){if("function"==typeof r)return e(t,null,r);r||(r={}),o=function(e){var t=!1;return function(){if(!t){t=!0;for(var r=arguments.length,n=new Array(r),i=0;i>>32-t}function m(e,t,r,n,i,o,a,s){return p(e+(t^r^n)+o+a|0,s)+i|0}function b(e,t,r,n,i,o,a,s){return p(e+(t&r|~t&n)+o+a|0,s)+i|0}function v(e,t,r,n,i,o,a,s){return p(e+((t|~r)^n)+o+a|0,s)+i|0}function g(e,t,r,n,i,o,a,s){return p(e+(t&n|r&~n)+o+a|0,s)+i|0}function y(e,t,r,n,i,o,a,s){return p(e+(t^(r|~n))+o+a|0,s)+i|0}i(d,o),d.prototype._update=function(){for(var e=a,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);for(var r=0|this._a,n=0|this._b,i=0|this._c,o=0|this._d,d=0|this._e,w=0|this._a,M=0|this._b,_=0|this._c,O=0|this._d,k=0|this._e,E=0;E<80;E+=1){var S,A;E<16?(S=m(r,n,i,o,d,e[s[E]],h[0],u[E]),A=y(w,M,_,O,k,e[c[E]],f[0],l[E])):E<32?(S=b(r,n,i,o,d,e[s[E]],h[1],u[E]),A=g(w,M,_,O,k,e[c[E]],f[1],l[E])):E<48?(S=v(r,n,i,o,d,e[s[E]],h[2],u[E]),A=v(w,M,_,O,k,e[c[E]],f[2],l[E])):E<64?(S=g(r,n,i,o,d,e[s[E]],h[3],u[E]),A=b(w,M,_,O,k,e[c[E]],f[3],l[E])):(S=y(r,n,i,o,d,e[s[E]],h[4],u[E]),A=m(w,M,_,O,k,e[c[E]],f[4],l[E])),r=d,d=o,o=p(i,10),i=n,n=S,w=k,k=O,O=p(_,10),_=M,M=A}var C=this._b+i+O|0;this._b=this._c+o+k|0,this._c=this._d+d+w|0,this._d=this._e+r+M|0,this._e=this._a+n+_|0,this._a=C},d.prototype._digest=function(){this._block[this._blockOffset++]=128,this._blockOffset>56&&(this._block.fill(0,this._blockOffset,64),this._update(),this._blockOffset=0),this._block.fill(0,this._blockOffset,56),this._block.writeUInt32LE(this._length[0],56),this._block.writeUInt32LE(this._length[1],60),this._update();var e=n.alloc?n.alloc(20):new n(20);return e.writeInt32LE(this._a,0),e.writeInt32LE(this._b,4),e.writeInt32LE(this._c,8),e.writeInt32LE(this._d,12),e.writeInt32LE(this._e,16),e},e.exports=d},function(e,t,r){(t=e.exports=function(e){e=e.toLowerCase();var r=t[e];if(!r)throw new Error(e+" is not supported (we accept pull requests)");return new r}).sha=r(345),t.sha1=r(346),t.sha224=r(347),t.sha256=r(231),t.sha384=r(348),t.sha512=r(232)},function(e,t,r){(t=e.exports=r(233)).Stream=t,t.Readable=t,t.Writable=r(173),t.Duplex=r(95),t.Transform=r(236),t.PassThrough=r(355)},function(e,t,r){"use strict";(function(t,n,i){var o=r(148);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,r){var n=e.entry;e.entry=null;for(;n;){var i=n.callback;t.pendingcb--,i(r),n=n.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=g;var s,c=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?n:o.nextTick;g.WritableState=v;var u=Object.create(r(121));u.inherits=r(25);var l={deprecate:r(168)},h=r(234),f=r(28).Buffer,d=i.Uint8Array||function(){};var p,m=r(235);function b(){}function v(e,t){s=s||r(95),e=e||{};var n=t instanceof s;this.objectMode=!!e.objectMode,n&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var i=e.highWaterMark,u=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=i||0===i?i:n&&(u||0===u)?u:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var h=!1===e.decodeStrings;this.decodeStrings=!h,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var r=e._writableState,n=r.sync,i=r.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(r),t)!function(e,t,r,n,i){--t.pendingcb,r?(o.nextTick(i,n),o.nextTick(k,e,t),e._writableState.errorEmitted=!0,e.emit("error",n)):(i(n),e._writableState.errorEmitted=!0,e.emit("error",n),k(e,t))}(e,r,n,t,i);else{var a=_(r);a||r.corked||r.bufferProcessing||!r.bufferedRequest||M(e,r),n?c(w,e,r,a,i):w(e,r,a,i)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function g(e){if(s=s||r(95),!(p.call(g,this)||this instanceof s))return new g(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),h.call(this)}function y(e,t,r,n,i,o,a){t.writelen=n,t.writecb=a,t.writing=!0,t.sync=!0,r?e._writev(i,t.onwrite):e._write(i,o,t.onwrite),t.sync=!1}function w(e,t,r,n){r||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,n(),k(e,t)}function M(e,t){t.bufferProcessing=!0;var r=t.bufferedRequest;if(e._writev&&r&&r.next){var n=t.bufferedRequestCount,i=new Array(n),o=t.corkedRequestsFree;o.entry=r;for(var s=0,c=!0;r;)i[s]=r,r.isBuf||(c=!1),r=r.next,s+=1;i.allBuffers=c,y(e,t,!0,t.length,i,"",o.finish),t.pendingcb++,t.lastBufferedRequest=null,o.next?(t.corkedRequestsFree=o.next,o.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;r;){var u=r.chunk,l=r.encoding,h=r.callback;if(y(e,t,!1,t.objectMode?1:u.length,u,l,h),r=r.next,t.bufferedRequestCount--,t.writing)break}null===r&&(t.lastBufferedRequest=null)}t.bufferedRequest=r,t.bufferProcessing=!1}function _(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function O(e,t){e._final((function(r){t.pendingcb--,r&&e.emit("error",r),t.prefinished=!0,e.emit("prefinish"),k(e,t)}))}function k(e,t){var r=_(t);return r&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,o.nextTick(O,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),r}u.inherits(g,h),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(p=Function.prototype[Symbol.hasInstance],Object.defineProperty(g,Symbol.hasInstance,{value:function(e){return!!p.call(this,e)||this===g&&(e&&e._writableState instanceof v)}})):p=function(e){return e instanceof this},g.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},g.prototype.write=function(e,t,r){var n,i=this._writableState,a=!1,s=!i.objectMode&&(n=e,f.isBuffer(n)||n instanceof d);return s&&!f.isBuffer(e)&&(e=function(e){return f.from(e)}(e)),"function"==typeof t&&(r=t,t=null),s?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof r&&(r=b),i.ended?function(e,t){var r=new Error("write after end");e.emit("error",r),o.nextTick(t,r)}(this,r):(s||function(e,t,r,n){var i=!0,a=!1;return null===r?a=new TypeError("May not write null values to stream"):"string"==typeof r||void 0===r||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),o.nextTick(n,a),i=!1),i}(this,i,e,r))&&(i.pendingcb++,a=function(e,t,r,n,i,o){if(!r){var a=function(e,t,r){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=f.from(t,r));return t}(t,n,i);n!==a&&(r=!0,i="buffer",n=a)}var s=t.objectMode?1:n.length;t.length+=s;var c=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(g.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),g.prototype._write=function(e,t,r){r(new Error("_write() is not implemented"))},g.prototype._writev=null,g.prototype.end=function(e,t,r){var n=this._writableState;"function"==typeof e?(r=e,e=null,t=null):"function"==typeof t&&(r=t,t=null),null!=e&&this.write(e,t),n.corked&&(n.corked=1,this.uncork()),n.ending||n.finished||function(e,t,r){t.ending=!0,k(e,t),r&&(t.finished?o.nextTick(r):e.once("finish",r));t.ended=!0,e.writable=!1}(this,n,r)},Object.defineProperty(g.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),g.prototype.destroy=m.destroy,g.prototype._undestroy=m.undestroy,g.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,r(33),r(353).setImmediate,r(46))},function(e,t,r){"use strict";var n=r(65);function i(e){this.options=e,this.type=this.options.type,this.blockSize=8,this._init(),this.buffer=new Array(this.blockSize),this.bufferOff=0}e.exports=i,i.prototype._init=function(){},i.prototype.update=function(e){return 0===e.length?[]:"decrypt"===this.type?this._updateDecrypt(e):this._updateEncrypt(e)},i.prototype._buffer=function(e,t){for(var r=Math.min(this.buffer.length-this.bufferOff,e.length-t),n=0;n0;n--)t+=this._buffer(e,t),r+=this._flushBuffer(i,r);return t+=this._buffer(e,t),i},i.prototype.final=function(e){var t,r;return e&&(t=this.update(e)),r="encrypt"===this.type?this._finalEncrypt():this._finalDecrypt(),t?t.concat(r):r},i.prototype._pad=function(e,t){if(0===t)return!1;for(;t=0||!r.umod(e.prime1)||!r.umod(e.prime2);)r=new n(i(t));return r}e.exports=o,o.getr=a}).call(this,r(44).Buffer)},function(e,t,r){"use strict";var n=t;n.version=r(397).version,n.utils=r(66),n.rand=r(177),n.curve=r(262),n.curves=r(182),n.ec=r(409),n.eddsa=r(413)},function(e,t,r){"use strict";var n,i=t,o=r(183),a=r(262),s=r(66).assert;function c(e){"short"===e.type?this.curve=new a.short(e):"edwards"===e.type?this.curve=new a.edwards(e):this.curve=new a.mont(e),this.g=this.curve.g,this.n=this.curve.n,this.hash=e.hash,s(this.g.validate(),"Invalid curve"),s(this.g.mul(this.n).isInfinity(),"Invalid curve, G*N != O")}function u(e,t){Object.defineProperty(i,e,{configurable:!0,enumerable:!0,get:function(){var r=new c(t);return Object.defineProperty(i,e,{configurable:!0,enumerable:!0,value:r}),r}})}i.PresetCurve=c,u("p192",{type:"short",prime:"p192",p:"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff",a:"ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc",b:"64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1",n:"ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831",hash:o.sha256,gRed:!1,g:["188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012","07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811"]}),u("p224",{type:"short",prime:"p224",p:"ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001",a:"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe",b:"b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4",n:"ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d",hash:o.sha256,gRed:!1,g:["b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21","bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34"]}),u("p256",{type:"short",prime:null,p:"ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff",a:"ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc",b:"5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b",n:"ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551",hash:o.sha256,gRed:!1,g:["6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296","4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5"]}),u("p384",{type:"short",prime:null,p:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ffffffff 00000000 00000000 ffffffff",a:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ffffffff 00000000 00000000 fffffffc",b:"b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f 5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef",n:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 f4372ddf 581a0db2 48b0a77a ecec196a ccc52973",hash:o.sha384,gRed:!1,g:["aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 5502f25d bf55296c 3a545e38 72760ab7","3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 0a60b1ce 1d7e819d 7a431d7c 90ea0e5f"]}),u("p521",{type:"short",prime:null,p:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff",a:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffc",b:"00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b 99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd 3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00",n:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409",hash:o.sha512,gRed:!1,g:["000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66","00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 3fad0761 353c7086 a272c240 88be9476 9fd16650"]}),u("curve25519",{type:"mont",prime:"p25519",p:"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",a:"76d06",b:"1",n:"1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",hash:o.sha256,gRed:!1,g:["9"]}),u("ed25519",{type:"edwards",prime:"p25519",p:"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",a:"-1",c:"1",d:"52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3",n:"1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",hash:o.sha256,gRed:!1,g:["216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a","6666666666666666666666666666666666666666666666666666666666666658"]});try{n=r(408)}catch(e){n=void 0}u("secp256k1",{type:"short",prime:"k256",p:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f",a:"0",b:"7",n:"ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141",h:"1",hash:o.sha256,beta:"7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee",lambda:"5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72",basis:[{a:"3086d221a7d46bcde86c90e49284eb15",b:"-e4437ed6010e88286f547fa90abfe4c3"},{a:"114ca50f7a8e2f3f657c1108d9d44cfd8",b:"3086d221a7d46bcde86c90e49284eb15"}],gRed:!1,g:["79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",n]})},function(e,t,r){var n=t;n.utils=r(70),n.common=r(123),n.sha=r(402),n.ripemd=r(406),n.hmac=r(407),n.sha1=n.sha.sha1,n.sha256=n.sha.sha256,n.sha224=n.sha.sha224,n.sha384=n.sha.sha384,n.sha512=n.sha.sha512,n.ripemd160=n.ripemd.ripemd160},function(e,t,r){"use strict";(function(t){var n,i=r(44),o=i.Buffer,a={};for(n in i)i.hasOwnProperty(n)&&"SlowBuffer"!==n&&"Buffer"!==n&&(a[n]=i[n]);var s=a.Buffer={};for(n in o)o.hasOwnProperty(n)&&"allocUnsafe"!==n&&"allocUnsafeSlow"!==n&&(s[n]=o[n]);if(a.Buffer.prototype=o.prototype,s.from&&s.from!==Uint8Array.from||(s.from=function(e,t,r){if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type '+typeof e);if(e&&void 0===e.length)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);return o(e,t,r)}),s.alloc||(s.alloc=function(e,t,r){if("number"!=typeof e)throw new TypeError('The "size" argument must be of type number. Received type '+typeof e);if(e<0||e>=2*(1<<30))throw new RangeError('The value "'+e+'" is invalid for option "size"');var n=o(e);return t&&0!==t.length?"string"==typeof r?n.fill(t,r):n.fill(t):n.fill(0),n}),!a.kStringMaxLength)try{a.kStringMaxLength=t.binding("buffer").kStringMaxLength}catch(e){}a.constants||(a.constants={MAX_LENGTH:a.kMaxLength},a.kStringMaxLength&&(a.constants.MAX_STRING_LENGTH=a.kStringMaxLength)),e.exports=a}).call(this,r(33))},function(e,t,r){"use strict";const n=r(186).Reporter,i=r(124).EncoderBuffer,o=r(124).DecoderBuffer,a=r(65),s=["seq","seqof","set","setof","objid","bool","gentime","utctime","null_","enum","int","objDesc","bitstr","bmpstr","charstr","genstr","graphstr","ia5str","iso646str","numstr","octstr","printstr","t61str","unistr","utf8str","videostr"],c=["key","obj","use","optional","explicit","implicit","def","choice","any","contains"].concat(s);function u(e,t,r){const n={};this._baseState=n,n.name=r,n.enc=e,n.parent=t||null,n.children=null,n.tag=null,n.args=null,n.reverseArgs=null,n.choice=null,n.optional=!1,n.any=!1,n.obj=!1,n.use=null,n.useDecoder=null,n.key=null,n.default=null,n.explicit=null,n.implicit=null,n.contains=null,n.parent||(n.children=[],this._wrap())}e.exports=u;const l=["enc","parent","children","tag","args","reverseArgs","choice","optional","any","obj","use","alteredUse","key","default","explicit","implicit","contains"];u.prototype.clone=function(){const e=this._baseState,t={};l.forEach((function(r){t[r]=e[r]}));const r=new this.constructor(t.parent);return r._baseState=t,r},u.prototype._wrap=function(){const e=this._baseState;c.forEach((function(t){this[t]=function(){const r=new this.constructor(this);return e.children.push(r),r[t].apply(r,arguments)}}),this)},u.prototype._init=function(e){const t=this._baseState;a(null===t.parent),e.call(this),t.children=t.children.filter((function(e){return e._baseState.parent===this}),this),a.equal(t.children.length,1,"Root node can have only one child")},u.prototype._useArgs=function(e){const t=this._baseState,r=e.filter((function(e){return e instanceof this.constructor}),this);e=e.filter((function(e){return!(e instanceof this.constructor)}),this),0!==r.length&&(a(null===t.children),t.children=r,r.forEach((function(e){e._baseState.parent=this}),this)),0!==e.length&&(a(null===t.args),t.args=e,t.reverseArgs=e.map((function(e){if("object"!=typeof e||e.constructor!==Object)return e;const t={};return Object.keys(e).forEach((function(r){r==(0|r)&&(r|=0);const n=e[r];t[n]=r})),t})))},["_peekTag","_decodeTag","_use","_decodeStr","_decodeObjid","_decodeTime","_decodeNull","_decodeInt","_decodeBool","_decodeList","_encodeComposite","_encodeStr","_encodeObjid","_encodeTime","_encodeNull","_encodeInt","_encodeBool"].forEach((function(e){u.prototype[e]=function(){const t=this._baseState;throw new Error(e+" not implemented for encoding: "+t.enc)}})),s.forEach((function(e){u.prototype[e]=function(){const t=this._baseState,r=Array.prototype.slice.call(arguments);return a(null===t.tag),t.tag=e,this._useArgs(r),this}})),u.prototype.use=function(e){a(e);const t=this._baseState;return a(null===t.use),t.use=e,this},u.prototype.optional=function(){return this._baseState.optional=!0,this},u.prototype.def=function(e){const t=this._baseState;return a(null===t.default),t.default=e,t.optional=!0,this},u.prototype.explicit=function(e){const t=this._baseState;return a(null===t.explicit&&null===t.implicit),t.explicit=e,this},u.prototype.implicit=function(e){const t=this._baseState;return a(null===t.explicit&&null===t.implicit),t.implicit=e,this},u.prototype.obj=function(){const e=this._baseState,t=Array.prototype.slice.call(arguments);return e.obj=!0,0!==t.length&&this._useArgs(t),this},u.prototype.key=function(e){const t=this._baseState;return a(null===t.key),t.key=e,this},u.prototype.any=function(){return this._baseState.any=!0,this},u.prototype.choice=function(e){const t=this._baseState;return a(null===t.choice),t.choice=e,this._useArgs(Object.keys(e).map((function(t){return e[t]}))),this},u.prototype.contains=function(e){const t=this._baseState;return a(null===t.use),t.contains=e,this},u.prototype._decode=function(e,t){const r=this._baseState;if(null===r.parent)return e.wrapResult(r.children[0]._decode(e,t));let n,i=r.default,a=!0,s=null;if(null!==r.key&&(s=e.enterKey(r.key)),r.optional){let n=null;if(null!==r.explicit?n=r.explicit:null!==r.implicit?n=r.implicit:null!==r.tag&&(n=r.tag),null!==n||r.any){if(a=this._peekTag(e,n,r.any),e.isError(a))return a}else{const n=e.save();try{null===r.choice?this._decodeGeneric(r.tag,e,t):this._decodeChoice(e,t),a=!0}catch(e){a=!1}e.restore(n)}}if(r.obj&&a&&(n=e.enterObject()),a){if(null!==r.explicit){const t=this._decodeTag(e,r.explicit);if(e.isError(t))return t;e=t}const n=e.offset;if(null===r.use&&null===r.choice){let t;r.any&&(t=e.save());const n=this._decodeTag(e,null!==r.implicit?r.implicit:r.tag,r.any);if(e.isError(n))return n;r.any?i=e.raw(t):e=n}if(t&&t.track&&null!==r.tag&&t.track(e.path(),n,e.length,"tagged"),t&&t.track&&null!==r.tag&&t.track(e.path(),e.offset,e.length,"content"),r.any||(i=null===r.choice?this._decodeGeneric(r.tag,e,t):this._decodeChoice(e,t)),e.isError(i))return i;if(r.any||null!==r.choice||null===r.children||r.children.forEach((function(r){r._decode(e,t)})),r.contains&&("octstr"===r.tag||"bitstr"===r.tag)){const n=new o(i);i=this._getUse(r.contains,e._reporterState.obj)._decode(n,t)}}return r.obj&&a&&(i=e.leaveObject(n)),null===r.key||null===i&&!0!==a?null!==s&&e.exitKey(s):e.leaveKey(s,r.key,i),i},u.prototype._decodeGeneric=function(e,t,r){const n=this._baseState;return"seq"===e||"set"===e?null:"seqof"===e||"setof"===e?this._decodeList(t,e,n.args[0],r):/str$/.test(e)?this._decodeStr(t,e,r):"objid"===e&&n.args?this._decodeObjid(t,n.args[0],n.args[1],r):"objid"===e?this._decodeObjid(t,null,null,r):"gentime"===e||"utctime"===e?this._decodeTime(t,e,r):"null_"===e?this._decodeNull(t,r):"bool"===e?this._decodeBool(t,r):"objDesc"===e?this._decodeStr(t,e,r):"int"===e||"enum"===e?this._decodeInt(t,n.args&&n.args[0],r):null!==n.use?this._getUse(n.use,t._reporterState.obj)._decode(t,r):t.error("unknown tag: "+e)},u.prototype._getUse=function(e,t){const r=this._baseState;return r.useDecoder=this._use(e,t),a(null===r.useDecoder._baseState.parent),r.useDecoder=r.useDecoder._baseState.children[0],r.implicit!==r.useDecoder._baseState.implicit&&(r.useDecoder=r.useDecoder.clone(),r.useDecoder._baseState.implicit=r.implicit),r.useDecoder},u.prototype._decodeChoice=function(e,t){const r=this._baseState;let n=null,i=!1;return Object.keys(r.choice).some((function(o){const a=e.save(),s=r.choice[o];try{const r=s._decode(e,t);if(e.isError(r))return!1;n={type:o,value:r},i=!0}catch(t){return e.restore(a),!1}return!0}),this),i?n:e.error("Choice not matched")},u.prototype._createEncoderBuffer=function(e){return new i(e,this.reporter)},u.prototype._encode=function(e,t,r){const n=this._baseState;if(null!==n.default&&n.default===e)return;const i=this._encodeValue(e,t,r);return void 0===i||this._skipDefault(i,t,r)?void 0:i},u.prototype._encodeValue=function(e,t,r){const i=this._baseState;if(null===i.parent)return i.children[0]._encode(e,t||new n);let o=null;if(this.reporter=t,i.optional&&void 0===e){if(null===i.default)return;e=i.default}let a=null,s=!1;if(i.any)o=this._createEncoderBuffer(e);else if(i.choice)o=this._encodeChoice(e,t);else if(i.contains)a=this._getUse(i.contains,r)._encode(e,t),s=!0;else if(i.children)a=i.children.map((function(r){if("null_"===r._baseState.tag)return r._encode(null,t,e);if(null===r._baseState.key)return t.error("Child should have a key");const n=t.enterKey(r._baseState.key);if("object"!=typeof e)return t.error("Child expected, but input is not object");const i=r._encode(e[r._baseState.key],t,e);return t.leaveKey(n),i}),this).filter((function(e){return e})),a=this._createEncoderBuffer(a);else if("seqof"===i.tag||"setof"===i.tag){if(!i.args||1!==i.args.length)return t.error("Too many args for : "+i.tag);if(!Array.isArray(e))return t.error("seqof/setof, but data is not Array");const r=this.clone();r._baseState.implicit=null,a=this._createEncoderBuffer(e.map((function(r){const n=this._baseState;return this._getUse(n.args[0],e)._encode(r,t)}),r))}else null!==i.use?o=this._getUse(i.use,r)._encode(e,t):(a=this._encodePrimitive(i.tag,e),s=!0);if(!i.any&&null===i.choice){const e=null!==i.implicit?i.implicit:i.tag,r=null===i.implicit?"universal":"context";null===e?null===i.use&&t.error("Tag could be omitted only for .use()"):null===i.use&&(o=this._encodeComposite(e,s,r,a))}return null!==i.explicit&&(o=this._encodeComposite(i.explicit,!1,"context",o)),o},u.prototype._encodeChoice=function(e,t){const r=this._baseState,n=r.choice[e.type];return n||a(!1,e.type+" not found in "+JSON.stringify(Object.keys(r.choice))),n._encode(e.value,t)},u.prototype._encodePrimitive=function(e,t){const r=this._baseState;if(/str$/.test(e))return this._encodeStr(t,e);if("objid"===e&&r.args)return this._encodeObjid(t,r.reverseArgs[0],r.args[1]);if("objid"===e)return this._encodeObjid(t,null,null);if("gentime"===e||"utctime"===e)return this._encodeTime(t,e);if("null_"===e)return this._encodeNull();if("int"===e||"enum"===e)return this._encodeInt(t,r.args&&r.reverseArgs[0]);if("bool"===e)return this._encodeBool(t);if("objDesc"===e)return this._encodeStr(t,e);throw new Error("Unsupported tag: "+e)},u.prototype._isNumstr=function(e){return/^[0-9 ]*$/.test(e)},u.prototype._isPrintstr=function(e){return/^[A-Za-z0-9 '()+,-./:=?]*$/.test(e)}},function(e,t,r){"use strict";const n=r(25);function i(e){this._reporterState={obj:null,path:[],options:e||{},errors:[]}}function o(e,t){this.path=e,this.rethrow(t)}t.Reporter=i,i.prototype.isError=function(e){return e instanceof o},i.prototype.save=function(){const e=this._reporterState;return{obj:e.obj,pathLen:e.path.length}},i.prototype.restore=function(e){const t=this._reporterState;t.obj=e.obj,t.path=t.path.slice(0,e.pathLen)},i.prototype.enterKey=function(e){return this._reporterState.path.push(e)},i.prototype.exitKey=function(e){const t=this._reporterState;t.path=t.path.slice(0,e-1)},i.prototype.leaveKey=function(e,t,r){const n=this._reporterState;this.exitKey(e),null!==n.obj&&(n.obj[t]=r)},i.prototype.path=function(){return this._reporterState.path.join("/")},i.prototype.enterObject=function(){const e=this._reporterState,t=e.obj;return e.obj={},t},i.prototype.leaveObject=function(e){const t=this._reporterState,r=t.obj;return t.obj=e,r},i.prototype.error=function(e){let t;const r=this._reporterState,n=e instanceof o;if(t=n?e:new o(r.path.map((function(e){return"["+JSON.stringify(e)+"]"})).join(""),e.message||e,e.stack),!r.options.partial)throw t;return n||r.errors.push(t),t},i.prototype.wrapResult=function(e){const t=this._reporterState;return t.options.partial?{result:this.isError(e)?null:e,errors:t.errors}:e},n(o,Error),o.prototype.rethrow=function(e){if(this.message=e+" at: "+(this.path||"(shallow)"),Error.captureStackTrace&&Error.captureStackTrace(this,o),!this.stack)try{throw new Error(this.message)}catch(e){this.stack=e.stack}return this}},function(e,t,r){"use strict";function n(e){const t={};return Object.keys(e).forEach((function(r){(0|r)==r&&(r|=0);const n=e[r];t[n]=r})),t}t.tagClass={0:"universal",1:"application",2:"context",3:"private"},t.tagClassByName=n(t.tagClass),t.tag={0:"end",1:"bool",2:"int",3:"bitstr",4:"octstr",5:"null_",6:"objid",7:"objDesc",8:"external",9:"real",10:"enum",11:"embed",12:"utf8str",13:"relativeOid",16:"seq",17:"set",18:"numstr",19:"printstr",20:"t61str",21:"videostr",22:"ia5str",23:"utctime",24:"gentime",25:"graphstr",26:"iso646str",27:"genstr",28:"unistr",29:"charstr",30:"bmpstr"},t.tagByName=n(t.tag)},function(e,t,r){(function(e){!function(e,t){"use strict";function n(e,t){if(!e)throw new Error(t||"Assertion failed")}function i(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e}function o(e,t,r){if(o.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(r=t,t=10),this._init(e||0,t||10,r||"be"))}var a;"object"==typeof e?e.exports=o:t.BN=o,o.BN=o,o.wordSize=26;try{a=r(433).Buffer}catch(e){}function s(e,t,r){for(var n=0,i=Math.min(e.length,r),o=t;o=49&&a<=54?a-49+10:a>=17&&a<=22?a-17+10:15&a}return n}function c(e,t,r,n){for(var i=0,o=Math.min(e.length,r),a=t;a=49?s-49+10:s>=17?s-17+10:s}return i}o.isBN=function(e){return e instanceof o||null!==e&&"object"==typeof e&&e.constructor.wordSize===o.wordSize&&Array.isArray(e.words)},o.max=function(e,t){return e.cmp(t)>0?e:t},o.min=function(e,t){return e.cmp(t)<0?e:t},o.prototype._init=function(e,t,r){if("number"==typeof e)return this._initNumber(e,t,r);if("object"==typeof e)return this._initArray(e,t,r);"hex"===t&&(t=16),n(t===(0|t)&&t>=2&&t<=36);var i=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&i++,16===t?this._parseHex(e,i):this._parseBase(e,t,i),"-"===e[0]&&(this.negative=1),this.strip(),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initNumber=function(e,t,r){e<0&&(this.negative=1,e=-e),e<67108864?(this.words=[67108863&e],this.length=1):e<4503599627370496?(this.words=[67108863&e,e/67108864&67108863],this.length=2):(n(e<9007199254740992),this.words=[67108863&e,e/67108864&67108863,1],this.length=3),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initArray=function(e,t,r){if(n("number"==typeof e.length),e.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(e.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)a=e[i]|e[i-1]<<8|e[i-2]<<16,this.words[o]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);else if("le"===r)for(i=0,o=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);return this.strip()},o.prototype._parseHex=function(e,t){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var r=0;r=t;r-=6)i=s(e,r,r+6),this.words[n]|=i<>>26-o&4194303,(o+=24)>=26&&(o-=26,n++);r+6!==t&&(i=s(e,t,r+6),this.words[n]|=i<>>26-o&4194303),this.strip()},o.prototype._parseBase=function(e,t,r){this.words=[0],this.length=1;for(var n=0,i=1;i<=67108863;i*=t)n++;n--,i=i/t|0;for(var o=e.length-r,a=o%n,s=Math.min(o,o-a)+r,u=0,l=r;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},o.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},o.prototype.inspect=function(){return(this.red?""};var u=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],l=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function f(e,t,r){r.negative=t.negative^e.negative;var n=e.length+t.length|0;r.length=n,n=n-1|0;var i=0|e.words[0],o=0|t.words[0],a=i*o,s=67108863&a,c=a/67108864|0;r.words[0]=s;for(var u=1;u>>26,h=67108863&c,f=Math.min(u,t.length-1),d=Math.max(0,u-e.length+1);d<=f;d++){var p=u-d|0;l+=(a=(i=0|e.words[p])*(o=0|t.words[d])+h)/67108864|0,h=67108863&a}r.words[u]=0|h,c=0|l}return 0!==c?r.words[u]=0|c:r.length--,r.strip()}o.prototype.toString=function(e,t){var r;if(t=0|t||1,16===(e=e||10)||"hex"===e){r="";for(var i=0,o=0,a=0;a>>24-i&16777215)||a!==this.length-1?u[6-c.length]+c+r:c+r,(i+=2)>=26&&(i-=26,a--)}for(0!==o&&(r=o.toString(16)+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}if(e===(0|e)&&e>=2&&e<=36){var f=l[e],d=h[e];r="";var p=this.clone();for(p.negative=0;!p.isZero();){var m=p.modn(d).toString(e);r=(p=p.idivn(d)).isZero()?m+r:u[f-m.length]+m+r}for(this.isZero()&&(r="0"+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}n(!1,"Base should be between 2 and 36")},o.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&n(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},o.prototype.toJSON=function(){return this.toString(16)},o.prototype.toBuffer=function(e,t){return n(void 0!==a),this.toArrayLike(a,e,t)},o.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},o.prototype.toArrayLike=function(e,t,r){var i=this.byteLength(),o=r||Math.max(1,i);n(i<=o,"byte array longer than desired length"),n(o>0,"Requested array length <= 0"),this.strip();var a,s,c="le"===t,u=new e(o),l=this.clone();if(c){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),u[s]=a;for(;s=4096&&(r+=13,t>>>=13),t>=64&&(r+=7,t>>>=7),t>=8&&(r+=4,t>>>=4),t>=2&&(r+=2,t>>>=2),r+t},o.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,r=0;return 0==(8191&t)&&(r+=13,t>>>=13),0==(127&t)&&(r+=7,t>>>=7),0==(15&t)&&(r+=4,t>>>=4),0==(3&t)&&(r+=2,t>>>=2),0==(1&t)&&r++,r},o.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},o.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},o.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},o.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var r=0;re.length?this.clone().iand(e):e.clone().iand(this)},o.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},o.prototype.iuxor=function(e){var t,r;this.length>e.length?(t=this,r=e):(t=e,r=this);for(var n=0;ne.length?this.clone().ixor(e):e.clone().ixor(this)},o.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},o.prototype.inotn=function(e){n("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),r=e%26;this._expand(t),r>0&&t--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-r),this.strip()},o.prototype.notn=function(e){return this.clone().inotn(e)},o.prototype.setn=function(e,t){n("number"==typeof e&&e>=0);var r=e/26|0,i=e%26;return this._expand(r+1),this.words[r]=t?this.words[r]|1<e.length?(r=this,n=e):(r=e,n=this);for(var i=0,o=0;o>>26;for(;0!==i&&o>>26;if(this.length=r.length,0!==i)this.words[this.length]=i,this.length++;else if(r!==this)for(;oe.length?this.clone().iadd(e):e.clone().iadd(this)},o.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var r,n,i=this.cmp(e);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(r=this,n=e):(r=e,n=this);for(var o=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==o&&a>26,this.words[a]=67108863&t;if(0===o&&a>>13,d=0|a[1],p=8191&d,m=d>>>13,b=0|a[2],v=8191&b,g=b>>>13,y=0|a[3],w=8191&y,M=y>>>13,_=0|a[4],O=8191&_,k=_>>>13,E=0|a[5],S=8191&E,A=E>>>13,C=0|a[6],j=8191&C,z=C>>>13,x=0|a[7],D=8191&x,P=x>>>13,R=0|a[8],T=8191&R,F=R>>>13,N=0|a[9],I=8191&N,L=N>>>13,B=0|s[0],H=8191&B,q=B>>>13,V=0|s[1],U=8191&V,W=V>>>13,K=0|s[2],G=8191&K,X=K>>>13,Y=0|s[3],Z=8191&Y,$=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],re=8191&te,ne=te>>>13,ie=0|s[6],oe=8191&ie,ae=ie>>>13,se=0|s[7],ce=8191&se,ue=se>>>13,le=0|s[8],he=8191&le,fe=le>>>13,de=0|s[9],pe=8191&de,me=de>>>13;r.negative=e.negative^t.negative,r.length=19;var be=(u+(n=Math.imul(h,H))|0)+((8191&(i=(i=Math.imul(h,q))+Math.imul(f,H)|0))<<13)|0;u=((o=Math.imul(f,q))+(i>>>13)|0)+(be>>>26)|0,be&=67108863,n=Math.imul(p,H),i=(i=Math.imul(p,q))+Math.imul(m,H)|0,o=Math.imul(m,q);var ve=(u+(n=n+Math.imul(h,U)|0)|0)+((8191&(i=(i=i+Math.imul(h,W)|0)+Math.imul(f,U)|0))<<13)|0;u=((o=o+Math.imul(f,W)|0)+(i>>>13)|0)+(ve>>>26)|0,ve&=67108863,n=Math.imul(v,H),i=(i=Math.imul(v,q))+Math.imul(g,H)|0,o=Math.imul(g,q),n=n+Math.imul(p,U)|0,i=(i=i+Math.imul(p,W)|0)+Math.imul(m,U)|0,o=o+Math.imul(m,W)|0;var ge=(u+(n=n+Math.imul(h,G)|0)|0)+((8191&(i=(i=i+Math.imul(h,X)|0)+Math.imul(f,G)|0))<<13)|0;u=((o=o+Math.imul(f,X)|0)+(i>>>13)|0)+(ge>>>26)|0,ge&=67108863,n=Math.imul(w,H),i=(i=Math.imul(w,q))+Math.imul(M,H)|0,o=Math.imul(M,q),n=n+Math.imul(v,U)|0,i=(i=i+Math.imul(v,W)|0)+Math.imul(g,U)|0,o=o+Math.imul(g,W)|0,n=n+Math.imul(p,G)|0,i=(i=i+Math.imul(p,X)|0)+Math.imul(m,G)|0,o=o+Math.imul(m,X)|0;var ye=(u+(n=n+Math.imul(h,Z)|0)|0)+((8191&(i=(i=i+Math.imul(h,$)|0)+Math.imul(f,Z)|0))<<13)|0;u=((o=o+Math.imul(f,$)|0)+(i>>>13)|0)+(ye>>>26)|0,ye&=67108863,n=Math.imul(O,H),i=(i=Math.imul(O,q))+Math.imul(k,H)|0,o=Math.imul(k,q),n=n+Math.imul(w,U)|0,i=(i=i+Math.imul(w,W)|0)+Math.imul(M,U)|0,o=o+Math.imul(M,W)|0,n=n+Math.imul(v,G)|0,i=(i=i+Math.imul(v,X)|0)+Math.imul(g,G)|0,o=o+Math.imul(g,X)|0,n=n+Math.imul(p,Z)|0,i=(i=i+Math.imul(p,$)|0)+Math.imul(m,Z)|0,o=o+Math.imul(m,$)|0;var we=(u+(n=n+Math.imul(h,Q)|0)|0)+((8191&(i=(i=i+Math.imul(h,ee)|0)+Math.imul(f,Q)|0))<<13)|0;u=((o=o+Math.imul(f,ee)|0)+(i>>>13)|0)+(we>>>26)|0,we&=67108863,n=Math.imul(S,H),i=(i=Math.imul(S,q))+Math.imul(A,H)|0,o=Math.imul(A,q),n=n+Math.imul(O,U)|0,i=(i=i+Math.imul(O,W)|0)+Math.imul(k,U)|0,o=o+Math.imul(k,W)|0,n=n+Math.imul(w,G)|0,i=(i=i+Math.imul(w,X)|0)+Math.imul(M,G)|0,o=o+Math.imul(M,X)|0,n=n+Math.imul(v,Z)|0,i=(i=i+Math.imul(v,$)|0)+Math.imul(g,Z)|0,o=o+Math.imul(g,$)|0,n=n+Math.imul(p,Q)|0,i=(i=i+Math.imul(p,ee)|0)+Math.imul(m,Q)|0,o=o+Math.imul(m,ee)|0;var Me=(u+(n=n+Math.imul(h,re)|0)|0)+((8191&(i=(i=i+Math.imul(h,ne)|0)+Math.imul(f,re)|0))<<13)|0;u=((o=o+Math.imul(f,ne)|0)+(i>>>13)|0)+(Me>>>26)|0,Me&=67108863,n=Math.imul(j,H),i=(i=Math.imul(j,q))+Math.imul(z,H)|0,o=Math.imul(z,q),n=n+Math.imul(S,U)|0,i=(i=i+Math.imul(S,W)|0)+Math.imul(A,U)|0,o=o+Math.imul(A,W)|0,n=n+Math.imul(O,G)|0,i=(i=i+Math.imul(O,X)|0)+Math.imul(k,G)|0,o=o+Math.imul(k,X)|0,n=n+Math.imul(w,Z)|0,i=(i=i+Math.imul(w,$)|0)+Math.imul(M,Z)|0,o=o+Math.imul(M,$)|0,n=n+Math.imul(v,Q)|0,i=(i=i+Math.imul(v,ee)|0)+Math.imul(g,Q)|0,o=o+Math.imul(g,ee)|0,n=n+Math.imul(p,re)|0,i=(i=i+Math.imul(p,ne)|0)+Math.imul(m,re)|0,o=o+Math.imul(m,ne)|0;var _e=(u+(n=n+Math.imul(h,oe)|0)|0)+((8191&(i=(i=i+Math.imul(h,ae)|0)+Math.imul(f,oe)|0))<<13)|0;u=((o=o+Math.imul(f,ae)|0)+(i>>>13)|0)+(_e>>>26)|0,_e&=67108863,n=Math.imul(D,H),i=(i=Math.imul(D,q))+Math.imul(P,H)|0,o=Math.imul(P,q),n=n+Math.imul(j,U)|0,i=(i=i+Math.imul(j,W)|0)+Math.imul(z,U)|0,o=o+Math.imul(z,W)|0,n=n+Math.imul(S,G)|0,i=(i=i+Math.imul(S,X)|0)+Math.imul(A,G)|0,o=o+Math.imul(A,X)|0,n=n+Math.imul(O,Z)|0,i=(i=i+Math.imul(O,$)|0)+Math.imul(k,Z)|0,o=o+Math.imul(k,$)|0,n=n+Math.imul(w,Q)|0,i=(i=i+Math.imul(w,ee)|0)+Math.imul(M,Q)|0,o=o+Math.imul(M,ee)|0,n=n+Math.imul(v,re)|0,i=(i=i+Math.imul(v,ne)|0)+Math.imul(g,re)|0,o=o+Math.imul(g,ne)|0,n=n+Math.imul(p,oe)|0,i=(i=i+Math.imul(p,ae)|0)+Math.imul(m,oe)|0,o=o+Math.imul(m,ae)|0;var Oe=(u+(n=n+Math.imul(h,ce)|0)|0)+((8191&(i=(i=i+Math.imul(h,ue)|0)+Math.imul(f,ce)|0))<<13)|0;u=((o=o+Math.imul(f,ue)|0)+(i>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,n=Math.imul(T,H),i=(i=Math.imul(T,q))+Math.imul(F,H)|0,o=Math.imul(F,q),n=n+Math.imul(D,U)|0,i=(i=i+Math.imul(D,W)|0)+Math.imul(P,U)|0,o=o+Math.imul(P,W)|0,n=n+Math.imul(j,G)|0,i=(i=i+Math.imul(j,X)|0)+Math.imul(z,G)|0,o=o+Math.imul(z,X)|0,n=n+Math.imul(S,Z)|0,i=(i=i+Math.imul(S,$)|0)+Math.imul(A,Z)|0,o=o+Math.imul(A,$)|0,n=n+Math.imul(O,Q)|0,i=(i=i+Math.imul(O,ee)|0)+Math.imul(k,Q)|0,o=o+Math.imul(k,ee)|0,n=n+Math.imul(w,re)|0,i=(i=i+Math.imul(w,ne)|0)+Math.imul(M,re)|0,o=o+Math.imul(M,ne)|0,n=n+Math.imul(v,oe)|0,i=(i=i+Math.imul(v,ae)|0)+Math.imul(g,oe)|0,o=o+Math.imul(g,ae)|0,n=n+Math.imul(p,ce)|0,i=(i=i+Math.imul(p,ue)|0)+Math.imul(m,ce)|0,o=o+Math.imul(m,ue)|0;var ke=(u+(n=n+Math.imul(h,he)|0)|0)+((8191&(i=(i=i+Math.imul(h,fe)|0)+Math.imul(f,he)|0))<<13)|0;u=((o=o+Math.imul(f,fe)|0)+(i>>>13)|0)+(ke>>>26)|0,ke&=67108863,n=Math.imul(I,H),i=(i=Math.imul(I,q))+Math.imul(L,H)|0,o=Math.imul(L,q),n=n+Math.imul(T,U)|0,i=(i=i+Math.imul(T,W)|0)+Math.imul(F,U)|0,o=o+Math.imul(F,W)|0,n=n+Math.imul(D,G)|0,i=(i=i+Math.imul(D,X)|0)+Math.imul(P,G)|0,o=o+Math.imul(P,X)|0,n=n+Math.imul(j,Z)|0,i=(i=i+Math.imul(j,$)|0)+Math.imul(z,Z)|0,o=o+Math.imul(z,$)|0,n=n+Math.imul(S,Q)|0,i=(i=i+Math.imul(S,ee)|0)+Math.imul(A,Q)|0,o=o+Math.imul(A,ee)|0,n=n+Math.imul(O,re)|0,i=(i=i+Math.imul(O,ne)|0)+Math.imul(k,re)|0,o=o+Math.imul(k,ne)|0,n=n+Math.imul(w,oe)|0,i=(i=i+Math.imul(w,ae)|0)+Math.imul(M,oe)|0,o=o+Math.imul(M,ae)|0,n=n+Math.imul(v,ce)|0,i=(i=i+Math.imul(v,ue)|0)+Math.imul(g,ce)|0,o=o+Math.imul(g,ue)|0,n=n+Math.imul(p,he)|0,i=(i=i+Math.imul(p,fe)|0)+Math.imul(m,he)|0,o=o+Math.imul(m,fe)|0;var Ee=(u+(n=n+Math.imul(h,pe)|0)|0)+((8191&(i=(i=i+Math.imul(h,me)|0)+Math.imul(f,pe)|0))<<13)|0;u=((o=o+Math.imul(f,me)|0)+(i>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,n=Math.imul(I,U),i=(i=Math.imul(I,W))+Math.imul(L,U)|0,o=Math.imul(L,W),n=n+Math.imul(T,G)|0,i=(i=i+Math.imul(T,X)|0)+Math.imul(F,G)|0,o=o+Math.imul(F,X)|0,n=n+Math.imul(D,Z)|0,i=(i=i+Math.imul(D,$)|0)+Math.imul(P,Z)|0,o=o+Math.imul(P,$)|0,n=n+Math.imul(j,Q)|0,i=(i=i+Math.imul(j,ee)|0)+Math.imul(z,Q)|0,o=o+Math.imul(z,ee)|0,n=n+Math.imul(S,re)|0,i=(i=i+Math.imul(S,ne)|0)+Math.imul(A,re)|0,o=o+Math.imul(A,ne)|0,n=n+Math.imul(O,oe)|0,i=(i=i+Math.imul(O,ae)|0)+Math.imul(k,oe)|0,o=o+Math.imul(k,ae)|0,n=n+Math.imul(w,ce)|0,i=(i=i+Math.imul(w,ue)|0)+Math.imul(M,ce)|0,o=o+Math.imul(M,ue)|0,n=n+Math.imul(v,he)|0,i=(i=i+Math.imul(v,fe)|0)+Math.imul(g,he)|0,o=o+Math.imul(g,fe)|0;var Se=(u+(n=n+Math.imul(p,pe)|0)|0)+((8191&(i=(i=i+Math.imul(p,me)|0)+Math.imul(m,pe)|0))<<13)|0;u=((o=o+Math.imul(m,me)|0)+(i>>>13)|0)+(Se>>>26)|0,Se&=67108863,n=Math.imul(I,G),i=(i=Math.imul(I,X))+Math.imul(L,G)|0,o=Math.imul(L,X),n=n+Math.imul(T,Z)|0,i=(i=i+Math.imul(T,$)|0)+Math.imul(F,Z)|0,o=o+Math.imul(F,$)|0,n=n+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,ee)|0)+Math.imul(P,Q)|0,o=o+Math.imul(P,ee)|0,n=n+Math.imul(j,re)|0,i=(i=i+Math.imul(j,ne)|0)+Math.imul(z,re)|0,o=o+Math.imul(z,ne)|0,n=n+Math.imul(S,oe)|0,i=(i=i+Math.imul(S,ae)|0)+Math.imul(A,oe)|0,o=o+Math.imul(A,ae)|0,n=n+Math.imul(O,ce)|0,i=(i=i+Math.imul(O,ue)|0)+Math.imul(k,ce)|0,o=o+Math.imul(k,ue)|0,n=n+Math.imul(w,he)|0,i=(i=i+Math.imul(w,fe)|0)+Math.imul(M,he)|0,o=o+Math.imul(M,fe)|0;var Ae=(u+(n=n+Math.imul(v,pe)|0)|0)+((8191&(i=(i=i+Math.imul(v,me)|0)+Math.imul(g,pe)|0))<<13)|0;u=((o=o+Math.imul(g,me)|0)+(i>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,n=Math.imul(I,Z),i=(i=Math.imul(I,$))+Math.imul(L,Z)|0,o=Math.imul(L,$),n=n+Math.imul(T,Q)|0,i=(i=i+Math.imul(T,ee)|0)+Math.imul(F,Q)|0,o=o+Math.imul(F,ee)|0,n=n+Math.imul(D,re)|0,i=(i=i+Math.imul(D,ne)|0)+Math.imul(P,re)|0,o=o+Math.imul(P,ne)|0,n=n+Math.imul(j,oe)|0,i=(i=i+Math.imul(j,ae)|0)+Math.imul(z,oe)|0,o=o+Math.imul(z,ae)|0,n=n+Math.imul(S,ce)|0,i=(i=i+Math.imul(S,ue)|0)+Math.imul(A,ce)|0,o=o+Math.imul(A,ue)|0,n=n+Math.imul(O,he)|0,i=(i=i+Math.imul(O,fe)|0)+Math.imul(k,he)|0,o=o+Math.imul(k,fe)|0;var Ce=(u+(n=n+Math.imul(w,pe)|0)|0)+((8191&(i=(i=i+Math.imul(w,me)|0)+Math.imul(M,pe)|0))<<13)|0;u=((o=o+Math.imul(M,me)|0)+(i>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,n=Math.imul(I,Q),i=(i=Math.imul(I,ee))+Math.imul(L,Q)|0,o=Math.imul(L,ee),n=n+Math.imul(T,re)|0,i=(i=i+Math.imul(T,ne)|0)+Math.imul(F,re)|0,o=o+Math.imul(F,ne)|0,n=n+Math.imul(D,oe)|0,i=(i=i+Math.imul(D,ae)|0)+Math.imul(P,oe)|0,o=o+Math.imul(P,ae)|0,n=n+Math.imul(j,ce)|0,i=(i=i+Math.imul(j,ue)|0)+Math.imul(z,ce)|0,o=o+Math.imul(z,ue)|0,n=n+Math.imul(S,he)|0,i=(i=i+Math.imul(S,fe)|0)+Math.imul(A,he)|0,o=o+Math.imul(A,fe)|0;var je=(u+(n=n+Math.imul(O,pe)|0)|0)+((8191&(i=(i=i+Math.imul(O,me)|0)+Math.imul(k,pe)|0))<<13)|0;u=((o=o+Math.imul(k,me)|0)+(i>>>13)|0)+(je>>>26)|0,je&=67108863,n=Math.imul(I,re),i=(i=Math.imul(I,ne))+Math.imul(L,re)|0,o=Math.imul(L,ne),n=n+Math.imul(T,oe)|0,i=(i=i+Math.imul(T,ae)|0)+Math.imul(F,oe)|0,o=o+Math.imul(F,ae)|0,n=n+Math.imul(D,ce)|0,i=(i=i+Math.imul(D,ue)|0)+Math.imul(P,ce)|0,o=o+Math.imul(P,ue)|0,n=n+Math.imul(j,he)|0,i=(i=i+Math.imul(j,fe)|0)+Math.imul(z,he)|0,o=o+Math.imul(z,fe)|0;var ze=(u+(n=n+Math.imul(S,pe)|0)|0)+((8191&(i=(i=i+Math.imul(S,me)|0)+Math.imul(A,pe)|0))<<13)|0;u=((o=o+Math.imul(A,me)|0)+(i>>>13)|0)+(ze>>>26)|0,ze&=67108863,n=Math.imul(I,oe),i=(i=Math.imul(I,ae))+Math.imul(L,oe)|0,o=Math.imul(L,ae),n=n+Math.imul(T,ce)|0,i=(i=i+Math.imul(T,ue)|0)+Math.imul(F,ce)|0,o=o+Math.imul(F,ue)|0,n=n+Math.imul(D,he)|0,i=(i=i+Math.imul(D,fe)|0)+Math.imul(P,he)|0,o=o+Math.imul(P,fe)|0;var xe=(u+(n=n+Math.imul(j,pe)|0)|0)+((8191&(i=(i=i+Math.imul(j,me)|0)+Math.imul(z,pe)|0))<<13)|0;u=((o=o+Math.imul(z,me)|0)+(i>>>13)|0)+(xe>>>26)|0,xe&=67108863,n=Math.imul(I,ce),i=(i=Math.imul(I,ue))+Math.imul(L,ce)|0,o=Math.imul(L,ue),n=n+Math.imul(T,he)|0,i=(i=i+Math.imul(T,fe)|0)+Math.imul(F,he)|0,o=o+Math.imul(F,fe)|0;var De=(u+(n=n+Math.imul(D,pe)|0)|0)+((8191&(i=(i=i+Math.imul(D,me)|0)+Math.imul(P,pe)|0))<<13)|0;u=((o=o+Math.imul(P,me)|0)+(i>>>13)|0)+(De>>>26)|0,De&=67108863,n=Math.imul(I,he),i=(i=Math.imul(I,fe))+Math.imul(L,he)|0,o=Math.imul(L,fe);var Pe=(u+(n=n+Math.imul(T,pe)|0)|0)+((8191&(i=(i=i+Math.imul(T,me)|0)+Math.imul(F,pe)|0))<<13)|0;u=((o=o+Math.imul(F,me)|0)+(i>>>13)|0)+(Pe>>>26)|0,Pe&=67108863;var Re=(u+(n=Math.imul(I,pe))|0)+((8191&(i=(i=Math.imul(I,me))+Math.imul(L,pe)|0))<<13)|0;return u=((o=Math.imul(L,me))+(i>>>13)|0)+(Re>>>26)|0,Re&=67108863,c[0]=be,c[1]=ve,c[2]=ge,c[3]=ye,c[4]=we,c[5]=Me,c[6]=_e,c[7]=Oe,c[8]=ke,c[9]=Ee,c[10]=Se,c[11]=Ae,c[12]=Ce,c[13]=je,c[14]=ze,c[15]=xe,c[16]=De,c[17]=Pe,c[18]=Re,0!==u&&(c[19]=u,r.length++),r};function p(e,t,r){return(new m).mulp(e,t,r)}function m(e,t){this.x=e,this.y=t}Math.imul||(d=f),o.prototype.mulTo=function(e,t){var r=this.length+e.length;return 10===this.length&&10===e.length?d(this,e,t):r<63?f(this,e,t):r<1024?function(e,t,r){r.negative=t.negative^e.negative,r.length=e.length+t.length;for(var n=0,i=0,o=0;o>>26)|0)>>>26,a&=67108863}r.words[o]=s,n=a,a=i}return 0!==n?r.words[o]=n:r.length--,r.strip()}(this,e,t):p(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),r=o.prototype._countBits(e)-1,n=0;n>=1;return n},m.prototype.permute=function(e,t,r,n,i,o){for(var a=0;a>>=1)i++;return 1<>>=13,r[2*a+1]=8191&o,o>>>=13;for(a=2*t;a>=26,t+=i/67108864|0,t+=o>>>26,this.words[r]=67108863&o}return 0!==t&&(this.words[r]=t,this.length++),this},o.prototype.muln=function(e){return this.clone().imuln(e)},o.prototype.sqr=function(){return this.mul(this)},o.prototype.isqr=function(){return this.imul(this.clone())},o.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),r=0;r>>i}return t}(e);if(0===t.length)return new o(1);for(var r=this,n=0;n=0);var t,r=e%26,i=(e-r)/26,o=67108863>>>26-r<<26-r;if(0!==r){var a=0;for(t=0;t>>26-r}a&&(this.words[t]=a,this.length++)}if(0!==i){for(t=this.length-1;t>=0;t--)this.words[t+i]=this.words[t];for(t=0;t=0),i=t?(t-t%26)/26:0;var o=e%26,a=Math.min((e-o)/26,this.length),s=67108863^67108863>>>o<a)for(this.length-=a,u=0;u=0&&(0!==l||u>=i);u--){var h=0|this.words[u];this.words[u]=l<<26-o|h>>>o,l=h&s}return c&&0!==l&&(c.words[c.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},o.prototype.ishrn=function(e,t,r){return n(0===this.negative),this.iushrn(e,t,r)},o.prototype.shln=function(e){return this.clone().ishln(e)},o.prototype.ushln=function(e){return this.clone().iushln(e)},o.prototype.shrn=function(e){return this.clone().ishrn(e)},o.prototype.ushrn=function(e){return this.clone().iushrn(e)},o.prototype.testn=function(e){n("number"==typeof e&&e>=0);var t=e%26,r=(e-t)/26,i=1<=0);var t=e%26,r=(e-t)/26;if(n(0===this.negative,"imaskn works only with positive numbers"),this.length<=r)return this;if(0!==t&&r++,this.length=Math.min(r,this.length),0!==t){var i=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},o.prototype.isubn=function(e){if(n("number"==typeof e),n(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(c/67108864|0),this.words[i+r]=67108863&o}for(;i>26,this.words[i+r]=67108863&o;if(0===s)return this.strip();for(n(-1===s),s=0,i=0;i>26,this.words[i]=67108863&o;return this.negative=1,this.strip()},o.prototype._wordDiv=function(e,t){var r=(this.length,e.length),n=this.clone(),i=e,a=0|i.words[i.length-1];0!==(r=26-this._countBits(a))&&(i=i.ushln(r),n.iushln(r),a=0|i.words[i.length-1]);var s,c=n.length-i.length;if("mod"!==t){(s=new o(null)).length=c+1,s.words=new Array(s.length);for(var u=0;u=0;h--){var f=67108864*(0|n.words[i.length+h])+(0|n.words[i.length+h-1]);for(f=Math.min(f/a|0,67108863),n._ishlnsubmul(i,f,h);0!==n.negative;)f--,n.negative=0,n._ishlnsubmul(i,1,h),n.isZero()||(n.negative^=1);s&&(s.words[h]=f)}return s&&s.strip(),n.strip(),"div"!==t&&0!==r&&n.iushrn(r),{div:s||null,mod:n}},o.prototype.divmod=function(e,t,r){return n(!e.isZero()),this.isZero()?{div:new o(0),mod:new o(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(i=s.div.neg()),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.iadd(e)),{div:i,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new o(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new o(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new o(this.modn(e.words[0]))}:this._wordDiv(e,t);var i,a,s},o.prototype.div=function(e){return this.divmod(e,"div",!1).div},o.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},o.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},o.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var r=0!==t.div.negative?t.mod.isub(e):t.mod,n=e.ushrn(1),i=e.andln(1),o=r.cmp(n);return o<0||1===i&&0===o?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},o.prototype.modn=function(e){n(e<=67108863);for(var t=(1<<26)%e,r=0,i=this.length-1;i>=0;i--)r=(t*r+(0|this.words[i]))%e;return r},o.prototype.idivn=function(e){n(e<=67108863);for(var t=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*t;this.words[r]=i/e|0,t=i%e}return this.strip()},o.prototype.divn=function(e){return this.clone().idivn(e)},o.prototype.egcd=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i=new o(1),a=new o(0),s=new o(0),c=new o(1),u=0;t.isEven()&&r.isEven();)t.iushrn(1),r.iushrn(1),++u;for(var l=r.clone(),h=t.clone();!t.isZero();){for(var f=0,d=1;0==(t.words[0]&d)&&f<26;++f,d<<=1);if(f>0)for(t.iushrn(f);f-- >0;)(i.isOdd()||a.isOdd())&&(i.iadd(l),a.isub(h)),i.iushrn(1),a.iushrn(1);for(var p=0,m=1;0==(r.words[0]&m)&&p<26;++p,m<<=1);if(p>0)for(r.iushrn(p);p-- >0;)(s.isOdd()||c.isOdd())&&(s.iadd(l),c.isub(h)),s.iushrn(1),c.iushrn(1);t.cmp(r)>=0?(t.isub(r),i.isub(s),a.isub(c)):(r.isub(t),s.isub(i),c.isub(a))}return{a:s,b:c,gcd:r.iushln(u)}},o.prototype._invmp=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i,a=new o(1),s=new o(0),c=r.clone();t.cmpn(1)>0&&r.cmpn(1)>0;){for(var u=0,l=1;0==(t.words[0]&l)&&u<26;++u,l<<=1);if(u>0)for(t.iushrn(u);u-- >0;)a.isOdd()&&a.iadd(c),a.iushrn(1);for(var h=0,f=1;0==(r.words[0]&f)&&h<26;++h,f<<=1);if(h>0)for(r.iushrn(h);h-- >0;)s.isOdd()&&s.iadd(c),s.iushrn(1);t.cmp(r)>=0?(t.isub(r),a.isub(s)):(r.isub(t),s.isub(a))}return(i=0===t.cmpn(1)?a:s).cmpn(0)<0&&i.iadd(e),i},o.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),r=e.clone();t.negative=0,r.negative=0;for(var n=0;t.isEven()&&r.isEven();n++)t.iushrn(1),r.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;r.isEven();)r.iushrn(1);var i=t.cmp(r);if(i<0){var o=t;t=r,r=o}else if(0===i||0===r.cmpn(1))break;t.isub(r)}return r.iushln(n)},o.prototype.invm=function(e){return this.egcd(e).a.umod(e)},o.prototype.isEven=function(){return 0==(1&this.words[0])},o.prototype.isOdd=function(){return 1==(1&this.words[0])},o.prototype.andln=function(e){return this.words[0]&e},o.prototype.bincn=function(e){n("number"==typeof e);var t=e%26,r=(e-t)/26,i=1<>>26,s&=67108863,this.words[a]=s}return 0!==o&&(this.words[a]=o,this.length++),this},o.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},o.prototype.cmpn=function(e){var t,r=e<0;if(0!==this.negative&&!r)return-1;if(0===this.negative&&r)return 1;if(this.strip(),this.length>1)t=1;else{r&&(e=-e),n(e<=67108863,"Number is too big");var i=0|this.words[0];t=i===e?0:ie.length)return 1;if(this.length=0;r--){var n=0|this.words[r],i=0|e.words[r];if(n!==i){ni&&(t=1);break}}return t},o.prototype.gtn=function(e){return 1===this.cmpn(e)},o.prototype.gt=function(e){return 1===this.cmp(e)},o.prototype.gten=function(e){return this.cmpn(e)>=0},o.prototype.gte=function(e){return this.cmp(e)>=0},o.prototype.ltn=function(e){return-1===this.cmpn(e)},o.prototype.lt=function(e){return-1===this.cmp(e)},o.prototype.lten=function(e){return this.cmpn(e)<=0},o.prototype.lte=function(e){return this.cmp(e)<=0},o.prototype.eqn=function(e){return 0===this.cmpn(e)},o.prototype.eq=function(e){return 0===this.cmp(e)},o.red=function(e){return new _(e)},o.prototype.toRed=function(e){return n(!this.red,"Already a number in reduction context"),n(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},o.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},o.prototype._forceRed=function(e){return this.red=e,this},o.prototype.forceRed=function(e){return n(!this.red,"Already a number in reduction context"),this._forceRed(e)},o.prototype.redAdd=function(e){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},o.prototype.redIAdd=function(e){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},o.prototype.redSub=function(e){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},o.prototype.redISub=function(e){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},o.prototype.redShl=function(e){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},o.prototype.redMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},o.prototype.redIMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},o.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},o.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},o.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},o.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},o.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},o.prototype.redPow=function(e){return n(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var b={k256:null,p224:null,p192:null,p25519:null};function v(e,t){this.name=e,this.p=new o(t,16),this.n=this.p.bitLength(),this.k=new o(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function g(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function y(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function w(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function M(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function _(e){if("string"==typeof e){var t=o._prime(e);this.m=t.p,this.prime=t}else n(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function O(e){_.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new o(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var e=new o(null);return e.words=new Array(Math.ceil(this.n/13)),e},v.prototype.ireduce=function(e){var t,r=e;do{this.split(r,this.tmp),t=(r=(r=this.imulK(r)).iadd(this.tmp)).bitLength()}while(t>this.n);var n=t0?r.isub(this.p):void 0!==r.strip?r.strip():r._strip(),r},v.prototype.split=function(e,t){e.iushrn(this.n,0,t)},v.prototype.imulK=function(e){return e.imul(this.k)},i(g,v),g.prototype.split=function(e,t){for(var r=Math.min(e.length,9),n=0;n>>22,i=o}i>>>=22,e.words[n-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},g.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,r=0;r>>=26,e.words[r]=i,t=n}return 0!==t&&(e.words[e.length++]=t),e},o._prime=function(e){if(b[e])return b[e];var t;if("k256"===e)t=new g;else if("p224"===e)t=new y;else if("p192"===e)t=new w;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new M}return b[e]=t,t},_.prototype._verify1=function(e){n(0===e.negative,"red works only with positives"),n(e.red,"red works only with red numbers")},_.prototype._verify2=function(e,t){n(0==(e.negative|t.negative),"red works only with positives"),n(e.red&&e.red===t.red,"red works only with red numbers")},_.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},_.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},_.prototype.add=function(e,t){this._verify2(e,t);var r=e.add(t);return r.cmp(this.m)>=0&&r.isub(this.m),r._forceRed(this)},_.prototype.iadd=function(e,t){this._verify2(e,t);var r=e.iadd(t);return r.cmp(this.m)>=0&&r.isub(this.m),r},_.prototype.sub=function(e,t){this._verify2(e,t);var r=e.sub(t);return r.cmpn(0)<0&&r.iadd(this.m),r._forceRed(this)},_.prototype.isub=function(e,t){this._verify2(e,t);var r=e.isub(t);return r.cmpn(0)<0&&r.iadd(this.m),r},_.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},_.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},_.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},_.prototype.isqr=function(e){return this.imul(e,e.clone())},_.prototype.sqr=function(e){return this.mul(e,e)},_.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(n(t%2==1),3===t){var r=this.m.add(new o(1)).iushrn(2);return this.pow(e,r)}for(var i=this.m.subn(1),a=0;!i.isZero()&&0===i.andln(1);)a++,i.iushrn(1);n(!i.isZero());var s=new o(1).toRed(this),c=s.redNeg(),u=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new o(2*l*l).toRed(this);0!==this.pow(l,u).cmp(c);)l.redIAdd(c);for(var h=this.pow(l,i),f=this.pow(e,i.addn(1).iushrn(1)),d=this.pow(e,i),p=a;0!==d.cmp(s);){for(var m=d,b=0;0!==m.cmp(s);b++)m=m.redSqr();n(b=0;n--){for(var u=t.words[n],l=c-1;l>=0;l--){var h=u>>l&1;i!==r[0]&&(i=this.sqr(i)),0!==h||0!==a?(a<<=1,a|=h,(4===++s||0===n&&0===l)&&(i=this.mul(i,r[a]),s=0,a=0)):s=0}c=26}return i},_.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},_.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},o.mont=function(e){return new O(e)},i(O,_),O.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},O.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},O.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var r=e.imul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},O.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new o(0)._forceRed(this);var r=e.mul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},O.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e,this)}).call(this,r(80)(e))},function(e,t,r){"use strict";r.d(t,"a",(function(){return s}));var n=r(86),i=r(3);function o(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"polite",t=document.createElement("div");t.id="a11y-speak-".concat(e),t.className="a11y-speak-region",t.setAttribute("style","position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"),t.setAttribute("aria-live",e),t.setAttribute("aria-relevant","additions text"),t.setAttribute("aria-atomic","true");var r=document,n=r.body;return n&&n.appendChild(t),t}var a="";function s(e,t){!function(){for(var e=document.getElementsByClassName("a11y-speak-region"),t=document.getElementById("a11y-speak-intro-text"),r=0;r]+>/g," "),a===e&&(e+=" "),a=e,e}(e);var r=document.getElementById("a11y-speak-intro-text"),n=document.getElementById("a11y-speak-assertive"),i=document.getElementById("a11y-speak-polite");n&&"assertive"===t?n.textContent=e:i&&(i.textContent=e),r&&r.removeAttribute("hidden")}Object(n.a)((function(){var e=document.getElementById("a11y-speak-intro-text"),t=document.getElementById("a11y-speak-assertive"),r=document.getElementById("a11y-speak-polite");null===e&&function(){var e=document.createElement("p");e.id="a11y-speak-intro-text",e.className="a11y-speak-intro-text",e.textContent=Object(i.__)("Notifications"),e.setAttribute("style","position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"),e.setAttribute("hidden","hidden");var t=document.body;t&&t.appendChild(e)}(),null===t&&o("assertive"),null===r&&o("polite")}))},,,,,,,,function(e,t){e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}},function(e,t,r){"use strict";e.exports=function(e){return"string"==typeof e||"symbol"==typeof e}},function(e,t,r){"use strict";var n=r(61),i=r(308),o=i(n("String.prototype.indexOf"));e.exports=function(e,t){var r=n(e,!!t);return"function"==typeof r&&o(e,".prototype.")?i(r):r}},function(e,t,r){var n=r(165);e.exports=!n((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},function(e,t,r){var n=r(200),i=r(217),o=r(284);e.exports=n?function(e,t,r){return i.f(e,t,o(1,r))}:function(e,t,r){return e[t]=r,e}},function(e,t,r){var n=r(216);e.exports=function(e){if(!n(e))throw TypeError(String(e)+" is not an object");return e}},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(){return!("undefined"==typeof window||!("ontouchstart"in window||window.DocumentTouch&&"undefined"!=typeof document&&document instanceof window.DocumentTouch))||!("undefined"==typeof navigator||!navigator.maxTouchPoints&&!navigator.msMaxTouchPoints)},e.exports=t.default},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){return!(!o.default.isMoment(e)||!o.default.isMoment(t))&&(e.date()===t.date()&&e.month()===t.month()&&e.year()===t.year())};var n,i=r(16),o=(n=i)&&n.__esModule?n:{default:n}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var r=t?[t,a.DISPLAY_FORMAT,a.ISO_FORMAT]:[a.DISPLAY_FORMAT,a.ISO_FORMAT],n=(0,o.default)(e,r,!0);return n.isValid()?n.hour(12):null};var n,i=r(16),o=(n=i)&&n.__esModule?n:{default:n},a=r(52)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,i=r(1),o=(n=i)&&n.__esModule?n:{default:n},a=r(52);t.default=o.default.oneOf([a.HORIZONTAL_ORIENTATION,a.VERTICAL_ORIENTATION,a.VERTICAL_SCROLLABLE])},function(e,t,r){"use strict";var n=r(674);e.exports=function(e,t,r){return!n(e.props,t)||!n(e.state,r)}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,i=r(1),o=(n=i)&&n.__esModule?n:{default:n},a=r(52);t.default=o.default.oneOf([a.OPEN_DOWN,a.OPEN_UP])},function(e,t,r){"use strict";(function(e){var n=r(0),i=(r(90),Object(n.createContext)({slots:{},fills:{},registerSlot:function(){void 0!==e&&e.env},updateSlot:function(){},unregisterSlot:function(){},registerFill:function(){},unregisterFill:function(){}}));t.a=i}).call(this,r(33))},function(e,t,r){"use strict";var n=r(6),i="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,o=r(153),a=r(211),s=r(212),c="function"==typeof Symbol&&Symbol.iterator;function u(e,t){return e&&"object"==typeof e&&null!=e.key?(r=e.key,n={"=":"=0",":":"=2"},"$"+(""+r).replace(/[=:]/g,(function(e){return n[e]}))):t.toString(36);var r,n}function l(e,t,r,n){var o,s=typeof e;if("undefined"!==s&&"boolean"!==s||(e=null),null===e||"string"===s||"number"===s||"object"===s&&e.$$typeof===i)return r(n,e,""===t?"."+u(e,0):t),1;var h=0,f=""===t?".":t+":";if(Array.isArray(e))for(var d=0;d=this._blockSize;){for(var o=this._blockOffset;o0;++a)this._length[a]+=s,(s=this._length[a]/4294967296|0)>0&&(this._length[a]-=4294967296*s);return this},o.prototype._update=function(){throw new Error("_update is not implemented")},o.prototype.digest=function(e){if(this._finalized)throw new Error("Digest already called");this._finalized=!0;var t=this._digest();void 0!==e&&(t=t.toString(e)),this._block.fill(0),this._blockOffset=0;for(var r=0;r<4;++r)this._length[r]=0;return t},o.prototype._digest=function(){throw new Error("_digest is not implemented")},e.exports=o},function(e,t,r){"use strict";(function(t,n){var i;e.exports=E,E.ReadableState=k;r(93).EventEmitter;var o=function(e,t){return e.listeners(t).length},a=r(226),s=r(44).Buffer,c=t.Uint8Array||function(){};var u,l=r(338);u=l&&l.debuglog?l.debuglog("stream"):function(){};var h,f,d,p=r(339),m=r(227),b=r(228).getHighWaterMark,v=r(107).codes,g=v.ERR_INVALID_ARG_TYPE,y=v.ERR_STREAM_PUSH_AFTER_EOF,w=v.ERR_METHOD_NOT_IMPLEMENTED,M=v.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;r(25)(E,a);var _=m.errorOrDestroy,O=["error","close","destroy","pause","resume"];function k(e,t,n){i=i||r(108),e=e||{},"boolean"!=typeof n&&(n=t instanceof i),this.objectMode=!!e.objectMode,n&&(this.objectMode=this.objectMode||!!e.readableObjectMode),this.highWaterMark=b(this,e,"readableHighWaterMark",n),this.buffer=new p,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=!1!==e.emitClose,this.autoDestroy=!!e.autoDestroy,this.destroyed=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(h||(h=r(94).StringDecoder),this.decoder=new h(e.encoding),this.encoding=e.encoding)}function E(e){if(i=i||r(108),!(this instanceof E))return new E(e);var t=this instanceof i;this._readableState=new k(e,this,t),this.readable=!0,e&&("function"==typeof e.read&&(this._read=e.read),"function"==typeof e.destroy&&(this._destroy=e.destroy)),a.call(this)}function S(e,t,r,n,i){u("readableAddChunk",t);var o,a=e._readableState;if(null===t)a.reading=!1,function(e,t){if(u("onEofChunk"),t.ended)return;if(t.decoder){var r=t.decoder.end();r&&r.length&&(t.buffer.push(r),t.length+=t.objectMode?1:r.length)}t.ended=!0,t.sync?j(e):(t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,z(e)))}(e,a);else if(i||(o=function(e,t){var r;n=t,s.isBuffer(n)||n instanceof c||"string"==typeof t||void 0===t||e.objectMode||(r=new g("chunk",["string","Buffer","Uint8Array"],t));var n;return r}(a,t)),o)_(e,o);else if(a.objectMode||t&&t.length>0)if("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===s.prototype||(t=function(e){return s.from(e)}(t)),n)a.endEmitted?_(e,new M):A(e,a,t,!0);else if(a.ended)_(e,new y);else{if(a.destroyed)return!1;a.reading=!1,a.decoder&&!r?(t=a.decoder.write(t),a.objectMode||0!==t.length?A(e,a,t,!1):x(e,a)):A(e,a,t,!1)}else n||(a.reading=!1,x(e,a));return!a.ended&&(a.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=1073741824?e=1073741824:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function j(e){var t=e._readableState;u("emitReadable",t.needReadable,t.emittedReadable),t.needReadable=!1,t.emittedReadable||(u("emitReadable",t.flowing),t.emittedReadable=!0,n.nextTick(z,e))}function z(e){var t=e._readableState;u("emitReadable_",t.destroyed,t.length,t.ended),t.destroyed||!t.length&&!t.ended||(e.emit("readable"),t.emittedReadable=!1),t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark,F(e)}function x(e,t){t.readingMore||(t.readingMore=!0,n.nextTick(D,e,t))}function D(e,t){for(;!t.reading&&!t.ended&&(t.length0,t.resumeScheduled&&!t.paused?t.flowing=!0:e.listenerCount("data")>0&&e.resume()}function R(e){u("readable nexttick read 0"),e.read(0)}function T(e,t){u("resume",t.reading),t.reading||e.read(0),t.resumeScheduled=!1,e.emit("resume"),F(e),t.flowing&&!t.reading&&e.read(0)}function F(e){var t=e._readableState;for(u("flow",t.flowing);t.flowing&&null!==e.read(););}function N(e,t){return 0===t.length?null:(t.objectMode?r=t.buffer.shift():!e||e>=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.first():t.buffer.concat(t.length),t.buffer.clear()):r=t.buffer.consume(e,t.decoder),r);var r}function I(e){var t=e._readableState;u("endReadable",t.endEmitted),t.endEmitted||(t.ended=!0,n.nextTick(L,t,e))}function L(e,t){if(u("endReadableNT",e.endEmitted,e.length),!e.endEmitted&&0===e.length&&(e.endEmitted=!0,t.readable=!1,t.emit("end"),e.autoDestroy)){var r=t._writableState;(!r||r.autoDestroy&&r.finished)&&t.destroy()}}function B(e,t){for(var r=0,n=e.length;r=t.highWaterMark:t.length>0)||t.ended))return u("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?I(this):j(this),null;if(0===(e=C(e,t))&&t.ended)return 0===t.length&&I(this),null;var n,i=t.needReadable;return u("need readable",i),(0===t.length||t.length-e0?N(e,t):null)?(t.needReadable=t.length<=t.highWaterMark,e=0):(t.length-=e,t.awaitDrain=0),0===t.length&&(t.ended||(t.needReadable=!0),r!==e&&t.ended&&I(this)),null!==n&&this.emit("data",n),n},E.prototype._read=function(e){_(this,new w("_read()"))},E.prototype.pipe=function(e,t){var r=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,u("pipe count=%d opts=%j",i.pipesCount,t);var a=(!t||!1!==t.end)&&e!==n.stdout&&e!==n.stderr?c:b;function s(t,n){u("onunpipe"),t===r&&n&&!1===n.hasUnpiped&&(n.hasUnpiped=!0,u("cleanup"),e.removeListener("close",p),e.removeListener("finish",m),e.removeListener("drain",l),e.removeListener("error",d),e.removeListener("unpipe",s),r.removeListener("end",c),r.removeListener("end",b),r.removeListener("data",f),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||l())}function c(){u("onend"),e.end()}i.endEmitted?n.nextTick(a):r.once("end",a),e.on("unpipe",s);var l=function(e){return function(){var t=e._readableState;u("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&o(e,"data")&&(t.flowing=!0,F(e))}}(r);e.on("drain",l);var h=!1;function f(t){u("ondata");var n=e.write(t);u("dest.write",n),!1===n&&((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==B(i.pipes,e))&&!h&&(u("false write response, pause",i.awaitDrain),i.awaitDrain++),r.pause())}function d(t){u("onerror",t),b(),e.removeListener("error",d),0===o(e,"error")&&_(e,t)}function p(){e.removeListener("finish",m),b()}function m(){u("onfinish"),e.removeListener("close",p),b()}function b(){u("unpipe"),r.unpipe(e)}return r.on("data",f),function(e,t,r){if("function"==typeof e.prependListener)return e.prependListener(t,r);e._events&&e._events[t]?Array.isArray(e._events[t])?e._events[t].unshift(r):e._events[t]=[r,e._events[t]]:e.on(t,r)}(e,"error",d),e.once("close",p),e.once("finish",m),e.emit("pipe",r),i.flowing||(u("pipe resume"),r.resume()),e},E.prototype.unpipe=function(e){var t=this._readableState,r={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,r)),this;if(!e){var n=t.pipes,i=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var o=0;o0,!1!==i.flowing&&this.resume()):"readable"===e&&(i.endEmitted||i.readableListening||(i.readableListening=i.needReadable=!0,i.flowing=!1,i.emittedReadable=!1,u("on readable",i.length,i.reading),i.length?j(this):i.reading||n.nextTick(R,this))),r},E.prototype.addListener=E.prototype.on,E.prototype.removeListener=function(e,t){var r=a.prototype.removeListener.call(this,e,t);return"readable"===e&&n.nextTick(P,this),r},E.prototype.removeAllListeners=function(e){var t=a.prototype.removeAllListeners.apply(this,arguments);return"readable"!==e&&void 0!==e||n.nextTick(P,this),t},E.prototype.resume=function(){var e=this._readableState;return e.flowing||(u("resume"),e.flowing=!e.readableListening,function(e,t){t.resumeScheduled||(t.resumeScheduled=!0,n.nextTick(T,e,t))}(this,e)),e.paused=!1,this},E.prototype.pause=function(){return u("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(u("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this},E.prototype.wrap=function(e){var t=this,r=this._readableState,n=!1;for(var i in e.on("end",(function(){if(u("wrapped end"),r.decoder&&!r.ended){var e=r.decoder.end();e&&e.length&&t.push(e)}t.push(null)})),e.on("data",(function(i){(u("wrapped data"),r.decoder&&(i=r.decoder.write(i)),r.objectMode&&null==i)||(r.objectMode||i&&i.length)&&(t.push(i)||(n=!0,e.pause()))})),e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));for(var o=0;o-1))throw new M(e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(E.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(E.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),E.prototype._write=function(e,t,r){r(new m("_write()"))},E.prototype._writev=null,E.prototype.end=function(e,t,r){var i=this._writableState;return"function"==typeof e?(r=e,e=null,t=null):"function"==typeof t&&(r=t,t=null),null!=e&&this.write(e,t),i.corked&&(i.corked=1,this.uncork()),i.ending||function(e,t,r){t.ending=!0,x(e,t),r&&(t.finished?n.nextTick(r):e.once("finish",r));t.ended=!0,e.writable=!1}(this,i,r),this},Object.defineProperty(E.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}}),Object.defineProperty(E.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),E.prototype.destroy=h.destroy,E.prototype._undestroy=h.undestroy,E.prototype._destroy=function(e,t){t(e)}}).call(this,r(46),r(33))},function(e,t,r){"use strict";e.exports=l;var n=r(107).codes,i=n.ERR_METHOD_NOT_IMPLEMENTED,o=n.ERR_MULTIPLE_CALLBACK,a=n.ERR_TRANSFORM_ALREADY_TRANSFORMING,s=n.ERR_TRANSFORM_WITH_LENGTH_0,c=r(108);function u(e,t){var r=this._transformState;r.transforming=!1;var n=r.writecb;if(null===n)return this.emit("error",new o);r.writechunk=null,r.writecb=null,null!=t&&this.push(t),n(e);var i=this._readableState;i.reading=!1,(i.needReadable||i.length>>2|e<<30)^(e>>>13|e<<19)^(e>>>22|e<<10)}function f(e){return(e>>>6|e<<26)^(e>>>11|e<<21)^(e>>>25|e<<7)}function d(e){return(e>>>7|e<<25)^(e>>>18|e<<14)^e>>>3}n(c,i),c.prototype.init=function(){return this._a=1779033703,this._b=3144134277,this._c=1013904242,this._d=2773480762,this._e=1359893119,this._f=2600822924,this._g=528734635,this._h=1541459225,this},c.prototype._update=function(e){for(var t,r=this._w,n=0|this._a,i=0|this._b,o=0|this._c,s=0|this._d,c=0|this._e,p=0|this._f,m=0|this._g,b=0|this._h,v=0;v<16;++v)r[v]=e.readInt32BE(4*v);for(;v<64;++v)r[v]=0|(((t=r[v-2])>>>17|t<<15)^(t>>>19|t<<13)^t>>>10)+r[v-7]+d(r[v-15])+r[v-16];for(var g=0;g<64;++g){var y=b+f(c)+u(c,p,m)+a[g]+r[g]|0,w=h(n)+l(n,i,o)|0;b=m,m=p,p=c,c=s+y|0,s=o,o=i,i=n,n=y+w|0}this._a=n+this._a|0,this._b=i+this._b|0,this._c=o+this._c|0,this._d=s+this._d|0,this._e=c+this._e|0,this._f=p+this._f|0,this._g=m+this._g|0,this._h=b+this._h|0},c.prototype._hash=function(){var e=o.allocUnsafe(32);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e.writeInt32BE(this._h,28),e},e.exports=c},function(e,t,r){var n=r(25),i=r(109),o=r(28).Buffer,a=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591],s=new Array(160);function c(){this.init(),this._w=s,i.call(this,128,112)}function u(e,t,r){return r^e&(t^r)}function l(e,t,r){return e&t|r&(e|t)}function h(e,t){return(e>>>28|t<<4)^(t>>>2|e<<30)^(t>>>7|e<<25)}function f(e,t){return(e>>>14|t<<18)^(e>>>18|t<<14)^(t>>>9|e<<23)}function d(e,t){return(e>>>1|t<<31)^(e>>>8|t<<24)^e>>>7}function p(e,t){return(e>>>1|t<<31)^(e>>>8|t<<24)^(e>>>7|t<<25)}function m(e,t){return(e>>>19|t<<13)^(t>>>29|e<<3)^e>>>6}function b(e,t){return(e>>>19|t<<13)^(t>>>29|e<<3)^(e>>>6|t<<26)}function v(e,t){return e>>>0>>0?1:0}n(c,i),c.prototype.init=function(){return this._ah=1779033703,this._bh=3144134277,this._ch=1013904242,this._dh=2773480762,this._eh=1359893119,this._fh=2600822924,this._gh=528734635,this._hh=1541459225,this._al=4089235720,this._bl=2227873595,this._cl=4271175723,this._dl=1595750129,this._el=2917565137,this._fl=725511199,this._gl=4215389547,this._hl=327033209,this},c.prototype._update=function(e){for(var t=this._w,r=0|this._ah,n=0|this._bh,i=0|this._ch,o=0|this._dh,s=0|this._eh,c=0|this._fh,g=0|this._gh,y=0|this._hh,w=0|this._al,M=0|this._bl,_=0|this._cl,O=0|this._dl,k=0|this._el,E=0|this._fl,S=0|this._gl,A=0|this._hl,C=0;C<32;C+=2)t[C]=e.readInt32BE(4*C),t[C+1]=e.readInt32BE(4*C+4);for(;C<160;C+=2){var j=t[C-30],z=t[C-30+1],x=d(j,z),D=p(z,j),P=m(j=t[C-4],z=t[C-4+1]),R=b(z,j),T=t[C-14],F=t[C-14+1],N=t[C-32],I=t[C-32+1],L=D+F|0,B=x+T+v(L,D)|0;B=(B=B+P+v(L=L+R|0,R)|0)+N+v(L=L+I|0,I)|0,t[C]=B,t[C+1]=L}for(var H=0;H<160;H+=2){B=t[H],L=t[H+1];var q=l(r,n,i),V=l(w,M,_),U=h(r,w),W=h(w,r),K=f(s,k),G=f(k,s),X=a[H],Y=a[H+1],Z=u(s,c,g),$=u(k,E,S),J=A+G|0,Q=y+K+v(J,A)|0;Q=(Q=(Q=Q+Z+v(J=J+$|0,$)|0)+X+v(J=J+Y|0,Y)|0)+B+v(J=J+L|0,L)|0;var ee=W+V|0,te=U+q+v(ee,W)|0;y=g,A=S,g=c,S=E,c=s,E=k,s=o+Q+v(k=O+J|0,O)|0,o=i,O=_,i=n,_=M,n=r,M=w,r=Q+te+v(w=J+ee|0,J)|0}this._al=this._al+w|0,this._bl=this._bl+M|0,this._cl=this._cl+_|0,this._dl=this._dl+O|0,this._el=this._el+k|0,this._fl=this._fl+E|0,this._gl=this._gl+S|0,this._hl=this._hl+A|0,this._ah=this._ah+r+v(this._al,w)|0,this._bh=this._bh+n+v(this._bl,M)|0,this._ch=this._ch+i+v(this._cl,_)|0,this._dh=this._dh+o+v(this._dl,O)|0,this._eh=this._eh+s+v(this._el,k)|0,this._fh=this._fh+c+v(this._fl,E)|0,this._gh=this._gh+g+v(this._gl,S)|0,this._hh=this._hh+y+v(this._hl,A)|0},c.prototype._hash=function(){var e=o.allocUnsafe(64);function t(t,r,n){e.writeInt32BE(t,n),e.writeInt32BE(r,n+4)}return t(this._ah,this._al,0),t(this._bh,this._bl,8),t(this._ch,this._cl,16),t(this._dh,this._dl,24),t(this._eh,this._el,32),t(this._fh,this._fl,40),t(this._gh,this._gl,48),t(this._hh,this._hl,56),e},e.exports=c},function(e,t,r){"use strict";(function(t,n){var i=r(148);e.exports=y;var o,a=r(223);y.ReadableState=g;r(93).EventEmitter;var s=function(e,t){return e.listeners(t).length},c=r(234),u=r(28).Buffer,l=t.Uint8Array||function(){};var h=Object.create(r(121));h.inherits=r(25);var f=r(350),d=void 0;d=f&&f.debuglog?f.debuglog("stream"):function(){};var p,m=r(351),b=r(235);h.inherits(y,c);var v=["error","close","destroy","pause","resume"];function g(e,t){e=e||{};var n=t instanceof(o=o||r(95));this.objectMode=!!e.objectMode,n&&(this.objectMode=this.objectMode||!!e.readableObjectMode);var i=e.highWaterMark,a=e.readableHighWaterMark,s=this.objectMode?16:16384;this.highWaterMark=i||0===i?i:n&&(a||0===a)?a:s,this.highWaterMark=Math.floor(this.highWaterMark),this.buffer=new m,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.destroyed=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(p||(p=r(94).StringDecoder),this.decoder=new p(e.encoding),this.encoding=e.encoding)}function y(e){if(o=o||r(95),!(this instanceof y))return new y(e);this._readableState=new g(e,this),this.readable=!0,e&&("function"==typeof e.read&&(this._read=e.read),"function"==typeof e.destroy&&(this._destroy=e.destroy)),c.call(this)}function w(e,t,r,n,i){var o,a=e._readableState;null===t?(a.reading=!1,function(e,t){if(t.ended)return;if(t.decoder){var r=t.decoder.end();r&&r.length&&(t.buffer.push(r),t.length+=t.objectMode?1:r.length)}t.ended=!0,O(e)}(e,a)):(i||(o=function(e,t){var r;n=t,u.isBuffer(n)||n instanceof l||"string"==typeof t||void 0===t||e.objectMode||(r=new TypeError("Invalid non-string/buffer chunk"));var n;return r}(a,t)),o?e.emit("error",o):a.objectMode||t&&t.length>0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===u.prototype||(t=function(e){return u.from(e)}(t)),n?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):M(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!r?(t=a.decoder.write(t),a.objectMode||0!==t.length?M(e,a,t,!1):E(e,a)):M(e,a,t,!1))):n||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=8388608?e=8388608:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function O(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(d("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?i.nextTick(k,e):k(e))}function k(e){d("emit readable"),e.emit("readable"),j(e)}function E(e,t){t.readingMore||(t.readingMore=!0,i.nextTick(S,e,t))}function S(e,t){for(var r=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):r=function(e,t,r){var n;eo.length?o.length:e;if(a===o.length?i+=o:i+=o.slice(0,e),0===(e-=a)){a===o.length?(++n,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=o.slice(a));break}++n}return t.length-=n,i}(e,t):function(e,t){var r=u.allocUnsafe(e),n=t.head,i=1;n.data.copy(r),e-=n.data.length;for(;n=n.next;){var o=n.data,a=e>o.length?o.length:e;if(o.copy(r,r.length-e,0,a),0===(e-=a)){a===o.length?(++i,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=o.slice(a));break}++i}return t.length-=i,r}(e,t);return n}(e,t.buffer,t.decoder),r);var r}function x(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,i.nextTick(D,t,e))}function D(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function P(e,t){for(var r=0,n=e.length;r=t.highWaterMark||t.ended))return d("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?x(this):O(this),null;if(0===(e=_(e,t))&&t.ended)return 0===t.length&&x(this),null;var n,i=t.needReadable;return d("need readable",i),(0===t.length||t.length-e0?z(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),r!==e&&t.ended&&x(this)),null!==n&&this.emit("data",n),n},y.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},y.prototype.pipe=function(e,t){var r=this,o=this._readableState;switch(o.pipesCount){case 0:o.pipes=e;break;case 1:o.pipes=[o.pipes,e];break;default:o.pipes.push(e)}o.pipesCount+=1,d("pipe count=%d opts=%j",o.pipesCount,t);var c=(!t||!1!==t.end)&&e!==n.stdout&&e!==n.stderr?l:y;function u(t,n){d("onunpipe"),t===r&&n&&!1===n.hasUnpiped&&(n.hasUnpiped=!0,d("cleanup"),e.removeListener("close",v),e.removeListener("finish",g),e.removeListener("drain",h),e.removeListener("error",b),e.removeListener("unpipe",u),r.removeListener("end",l),r.removeListener("end",y),r.removeListener("data",m),f=!0,!o.awaitDrain||e._writableState&&!e._writableState.needDrain||h())}function l(){d("onend"),e.end()}o.endEmitted?i.nextTick(c):r.once("end",c),e.on("unpipe",u);var h=function(e){return function(){var t=e._readableState;d("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,j(e))}}(r);e.on("drain",h);var f=!1;var p=!1;function m(t){d("ondata"),p=!1,!1!==e.write(t)||p||((1===o.pipesCount&&o.pipes===e||o.pipesCount>1&&-1!==P(o.pipes,e))&&!f&&(d("false write response, pause",r._readableState.awaitDrain),r._readableState.awaitDrain++,p=!0),r.pause())}function b(t){d("onerror",t),y(),e.removeListener("error",b),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",g),y()}function g(){d("onfinish"),e.removeListener("close",v),y()}function y(){d("unpipe"),r.unpipe(e)}return r.on("data",m),function(e,t,r){if("function"==typeof e.prependListener)return e.prependListener(t,r);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(r):e._events[t]=[r,e._events[t]]:e.on(t,r)}(e,"error",b),e.once("close",v),e.once("finish",g),e.emit("pipe",r),o.flowing||(d("pipe resume"),r.resume()),e},y.prototype.unpipe=function(e){var t=this._readableState,r={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,r)),this;if(!e){var n=t.pipes,i=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var o=0;or)?t=("rmd160"===e?new c:u(e)).update(t).digest():t.lengthr||t!=t)throw new TypeError("Bad key length")}},function(e,t,r){(function(t){var r;if(t.browser)r="utf-8";else if(t.version){r=parseInt(t.version.split(".")[0].slice(1),10)>=6?"utf-8":"binary"}else r="utf-8";e.exports=r}).call(this,r(33))},function(e,t,r){var n=r(238),i=r(170),o=r(171),a=r(28).Buffer,s=r(241),c=r(242),u=r(244),l=a.alloc(128),h={md5:16,sha1:20,sha224:28,sha256:32,sha384:48,sha512:64,rmd160:20,ripemd160:20};function f(e,t,r){var s=function(e){function t(t){return o(e).update(t).digest()}return"rmd160"===e||"ripemd160"===e?function(e){return(new i).update(e).digest()}:"md5"===e?n:t}(e),c="sha512"===e||"sha384"===e?128:64;t.length>c?t=s(t):t.length>>0},t.writeUInt32BE=function(e,t,r){e[0+r]=t>>>24,e[1+r]=t>>>16&255,e[2+r]=t>>>8&255,e[3+r]=255&t},t.ip=function(e,t,r,n){for(var i=0,o=0,a=6;a>=0;a-=2){for(var s=0;s<=24;s+=8)i<<=1,i|=t>>>s+a&1;for(s=0;s<=24;s+=8)i<<=1,i|=e>>>s+a&1}for(a=6;a>=0;a-=2){for(s=1;s<=25;s+=8)o<<=1,o|=t>>>s+a&1;for(s=1;s<=25;s+=8)o<<=1,o|=e>>>s+a&1}r[n+0]=i>>>0,r[n+1]=o>>>0},t.rip=function(e,t,r,n){for(var i=0,o=0,a=0;a<4;a++)for(var s=24;s>=0;s-=8)i<<=1,i|=t>>>s+a&1,i<<=1,i|=e>>>s+a&1;for(a=4;a<8;a++)for(s=24;s>=0;s-=8)o<<=1,o|=t>>>s+a&1,o<<=1,o|=e>>>s+a&1;r[n+0]=i>>>0,r[n+1]=o>>>0},t.pc1=function(e,t,r,n){for(var i=0,o=0,a=7;a>=5;a--){for(var s=0;s<=24;s+=8)i<<=1,i|=t>>s+a&1;for(s=0;s<=24;s+=8)i<<=1,i|=e>>s+a&1}for(s=0;s<=24;s+=8)i<<=1,i|=t>>s+a&1;for(a=1;a<=3;a++){for(s=0;s<=24;s+=8)o<<=1,o|=t>>s+a&1;for(s=0;s<=24;s+=8)o<<=1,o|=e>>s+a&1}for(s=0;s<=24;s+=8)o<<=1,o|=e>>s+a&1;r[n+0]=i>>>0,r[n+1]=o>>>0},t.r28shl=function(e,t){return e<>>28-t};var n=[14,11,17,4,27,23,25,0,13,22,7,18,5,9,16,24,2,20,12,21,1,8,15,26,15,4,25,19,9,1,26,16,5,11,23,8,12,7,17,0,22,3,10,14,6,20,27,24];t.pc2=function(e,t,r,i){for(var o=0,a=0,s=n.length>>>1,c=0;c>>n[c]&1;for(c=s;c>>n[c]&1;r[i+0]=o>>>0,r[i+1]=a>>>0},t.expand=function(e,t,r){var n=0,i=0;n=(1&e)<<5|e>>>27;for(var o=23;o>=15;o-=4)n<<=6,n|=e>>>o&63;for(o=11;o>=3;o-=4)i|=e>>>o&63,i<<=6;i|=(31&e)<<1|e>>>31,t[r+0]=n>>>0,t[r+1]=i>>>0};var i=[14,0,4,15,13,7,1,4,2,14,15,2,11,13,8,1,3,10,10,6,6,12,12,11,5,9,9,5,0,3,7,8,4,15,1,12,14,8,8,2,13,4,6,9,2,1,11,7,15,5,12,11,9,3,7,14,3,10,10,0,5,6,0,13,15,3,1,13,8,4,14,7,6,15,11,2,3,8,4,14,9,12,7,0,2,1,13,10,12,6,0,9,5,11,10,5,0,13,14,8,7,10,11,1,10,3,4,15,13,4,1,2,5,11,8,6,12,7,6,12,9,0,3,5,2,14,15,9,10,13,0,7,9,0,14,9,6,3,3,4,15,6,5,10,1,2,13,8,12,5,7,14,11,12,4,11,2,15,8,1,13,1,6,10,4,13,9,0,8,6,15,9,3,8,0,7,11,4,1,15,2,14,12,3,5,11,10,5,14,2,7,12,7,13,13,8,14,11,3,5,0,6,6,15,9,0,10,3,1,4,2,7,8,2,5,12,11,1,12,10,4,14,15,9,10,3,6,15,9,0,0,6,12,10,11,1,7,13,13,8,15,9,1,4,3,5,14,11,5,12,2,7,8,2,4,14,2,14,12,11,4,2,1,12,7,4,10,7,11,13,6,1,8,5,5,0,3,15,15,10,13,3,0,9,14,8,9,6,4,11,2,8,1,12,11,7,10,1,13,14,7,2,8,13,15,6,9,15,12,0,5,9,6,10,3,4,0,5,14,3,12,10,1,15,10,4,15,2,9,7,2,12,6,9,8,5,0,6,13,1,3,13,4,14,14,0,7,11,5,3,11,8,9,4,14,3,15,2,5,12,2,9,8,5,12,15,3,10,7,11,0,14,4,1,10,7,1,6,13,0,11,8,6,13,4,13,11,0,2,11,14,7,15,4,0,9,8,1,13,10,3,14,12,3,9,5,7,12,5,2,10,15,6,8,1,6,1,6,4,11,11,13,13,8,12,1,3,4,7,10,14,7,10,9,15,5,6,0,8,15,0,14,5,2,9,3,2,12,13,1,2,15,8,13,4,8,6,10,15,3,11,7,1,4,10,12,9,5,3,6,14,11,5,0,0,14,12,9,7,2,7,2,11,1,4,14,1,7,9,4,12,10,14,8,2,13,0,15,6,12,10,9,13,0,15,3,3,5,5,6,8,11];t.substitute=function(e,t){for(var r=0,n=0;n<4;n++){r<<=4,r|=i[64*n+(e>>>18-6*n&63)]}for(n=0;n<4;n++){r<<=4,r|=i[256+64*n+(t>>>18-6*n&63)]}return r>>>0};var o=[16,25,12,11,3,20,4,15,31,17,9,6,27,14,1,22,30,24,8,18,0,5,29,23,13,19,2,26,10,21,28,7];t.permute=function(e){for(var t=0,r=0;r>>o[r]&1;return t>>>0},t.padSplit=function(e,t,r){for(var n=e.toString(2);n.length>>1];r=o.r28shl(r,s),i=o.r28shl(i,s),o.pc2(r,i,e.keys,a)}},c.prototype._update=function(e,t,r,n){var i=this._desState,a=o.readUInt32BE(e,t),s=o.readUInt32BE(e,t+4);o.ip(a,s,i.tmp,0),a=i.tmp[0],s=i.tmp[1],"encrypt"===this.type?this._encrypt(i,a,s,i.tmp,0):this._decrypt(i,a,s,i.tmp,0),a=i.tmp[0],s=i.tmp[1],o.writeUInt32BE(r,a,n),o.writeUInt32BE(r,s,n+4)},c.prototype._pad=function(e,t){for(var r=e.length-t,n=t;n>>0,a=f}o.rip(s,a,n,i)},c.prototype._decrypt=function(e,t,r,n,i){for(var a=r,s=t,c=e.keys.length-2;c>=0;c-=2){var u=e.keys[c],l=e.keys[c+1];o.expand(a,e.tmp,0),u^=e.tmp[0],l^=e.tmp[1];var h=o.substitute(u,l),f=a;a=(s^o.permute(h))>>>0,s=f}o.rip(a,s,n,i)}},function(e,t,r){var n=r(122),i=r(28).Buffer,o=r(248);function a(e){var t=e._cipher.encryptBlockRaw(e._prev);return o(e._prev),t}t.encrypt=function(e,t){var r=Math.ceil(t.length/16),o=e._cache.length;e._cache=i.concat([e._cache,i.allocUnsafe(16*r)]);for(var s=0;se;)r.ishrn(1);if(r.isEven()&&r.iadd(s),r.testn(1)||r.iadd(c),t.cmp(c)){if(!t.cmp(u))for(;r.mod(l).cmp(h);)r.iadd(d)}else for(;r.mod(o).cmp(f);)r.iadd(d);if(b(p=r.shrn(1))&&b(r)&&v(p)&&v(r)&&a.test(p)&&a.test(r))return r}}},function(e,t,r){(function(e){!function(e,t){"use strict";function n(e,t){if(!e)throw new Error(t||"Assertion failed")}function i(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e}function o(e,t,r){if(o.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(r=t,t=10),this._init(e||0,t||10,r||"be"))}var a;"object"==typeof e?e.exports=o:t.BN=o,o.BN=o,o.wordSize=26;try{a=r(379).Buffer}catch(e){}function s(e,t,r){for(var n=0,i=Math.min(e.length,r),o=t;o=49&&a<=54?a-49+10:a>=17&&a<=22?a-17+10:15&a}return n}function c(e,t,r,n){for(var i=0,o=Math.min(e.length,r),a=t;a=49?s-49+10:s>=17?s-17+10:s}return i}o.isBN=function(e){return e instanceof o||null!==e&&"object"==typeof e&&e.constructor.wordSize===o.wordSize&&Array.isArray(e.words)},o.max=function(e,t){return e.cmp(t)>0?e:t},o.min=function(e,t){return e.cmp(t)<0?e:t},o.prototype._init=function(e,t,r){if("number"==typeof e)return this._initNumber(e,t,r);if("object"==typeof e)return this._initArray(e,t,r);"hex"===t&&(t=16),n(t===(0|t)&&t>=2&&t<=36);var i=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&i++,16===t?this._parseHex(e,i):this._parseBase(e,t,i),"-"===e[0]&&(this.negative=1),this.strip(),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initNumber=function(e,t,r){e<0&&(this.negative=1,e=-e),e<67108864?(this.words=[67108863&e],this.length=1):e<4503599627370496?(this.words=[67108863&e,e/67108864&67108863],this.length=2):(n(e<9007199254740992),this.words=[67108863&e,e/67108864&67108863,1],this.length=3),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initArray=function(e,t,r){if(n("number"==typeof e.length),e.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(e.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)a=e[i]|e[i-1]<<8|e[i-2]<<16,this.words[o]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);else if("le"===r)for(i=0,o=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);return this.strip()},o.prototype._parseHex=function(e,t){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var r=0;r=t;r-=6)i=s(e,r,r+6),this.words[n]|=i<>>26-o&4194303,(o+=24)>=26&&(o-=26,n++);r+6!==t&&(i=s(e,t,r+6),this.words[n]|=i<>>26-o&4194303),this.strip()},o.prototype._parseBase=function(e,t,r){this.words=[0],this.length=1;for(var n=0,i=1;i<=67108863;i*=t)n++;n--,i=i/t|0;for(var o=e.length-r,a=o%n,s=Math.min(o,o-a)+r,u=0,l=r;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},o.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},o.prototype.inspect=function(){return(this.red?""};var u=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],l=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function f(e,t,r){r.negative=t.negative^e.negative;var n=e.length+t.length|0;r.length=n,n=n-1|0;var i=0|e.words[0],o=0|t.words[0],a=i*o,s=67108863&a,c=a/67108864|0;r.words[0]=s;for(var u=1;u>>26,h=67108863&c,f=Math.min(u,t.length-1),d=Math.max(0,u-e.length+1);d<=f;d++){var p=u-d|0;l+=(a=(i=0|e.words[p])*(o=0|t.words[d])+h)/67108864|0,h=67108863&a}r.words[u]=0|h,c=0|l}return 0!==c?r.words[u]=0|c:r.length--,r.strip()}o.prototype.toString=function(e,t){var r;if(t=0|t||1,16===(e=e||10)||"hex"===e){r="";for(var i=0,o=0,a=0;a>>24-i&16777215)||a!==this.length-1?u[6-c.length]+c+r:c+r,(i+=2)>=26&&(i-=26,a--)}for(0!==o&&(r=o.toString(16)+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}if(e===(0|e)&&e>=2&&e<=36){var f=l[e],d=h[e];r="";var p=this.clone();for(p.negative=0;!p.isZero();){var m=p.modn(d).toString(e);r=(p=p.idivn(d)).isZero()?m+r:u[f-m.length]+m+r}for(this.isZero()&&(r="0"+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}n(!1,"Base should be between 2 and 36")},o.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&n(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},o.prototype.toJSON=function(){return this.toString(16)},o.prototype.toBuffer=function(e,t){return n(void 0!==a),this.toArrayLike(a,e,t)},o.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},o.prototype.toArrayLike=function(e,t,r){var i=this.byteLength(),o=r||Math.max(1,i);n(i<=o,"byte array longer than desired length"),n(o>0,"Requested array length <= 0"),this.strip();var a,s,c="le"===t,u=new e(o),l=this.clone();if(c){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),u[s]=a;for(;s=4096&&(r+=13,t>>>=13),t>=64&&(r+=7,t>>>=7),t>=8&&(r+=4,t>>>=4),t>=2&&(r+=2,t>>>=2),r+t},o.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,r=0;return 0==(8191&t)&&(r+=13,t>>>=13),0==(127&t)&&(r+=7,t>>>=7),0==(15&t)&&(r+=4,t>>>=4),0==(3&t)&&(r+=2,t>>>=2),0==(1&t)&&r++,r},o.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},o.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},o.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},o.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var r=0;re.length?this.clone().iand(e):e.clone().iand(this)},o.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},o.prototype.iuxor=function(e){var t,r;this.length>e.length?(t=this,r=e):(t=e,r=this);for(var n=0;ne.length?this.clone().ixor(e):e.clone().ixor(this)},o.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},o.prototype.inotn=function(e){n("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),r=e%26;this._expand(t),r>0&&t--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-r),this.strip()},o.prototype.notn=function(e){return this.clone().inotn(e)},o.prototype.setn=function(e,t){n("number"==typeof e&&e>=0);var r=e/26|0,i=e%26;return this._expand(r+1),this.words[r]=t?this.words[r]|1<e.length?(r=this,n=e):(r=e,n=this);for(var i=0,o=0;o>>26;for(;0!==i&&o>>26;if(this.length=r.length,0!==i)this.words[this.length]=i,this.length++;else if(r!==this)for(;oe.length?this.clone().iadd(e):e.clone().iadd(this)},o.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var r,n,i=this.cmp(e);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(r=this,n=e):(r=e,n=this);for(var o=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==o&&a>26,this.words[a]=67108863&t;if(0===o&&a>>13,d=0|a[1],p=8191&d,m=d>>>13,b=0|a[2],v=8191&b,g=b>>>13,y=0|a[3],w=8191&y,M=y>>>13,_=0|a[4],O=8191&_,k=_>>>13,E=0|a[5],S=8191&E,A=E>>>13,C=0|a[6],j=8191&C,z=C>>>13,x=0|a[7],D=8191&x,P=x>>>13,R=0|a[8],T=8191&R,F=R>>>13,N=0|a[9],I=8191&N,L=N>>>13,B=0|s[0],H=8191&B,q=B>>>13,V=0|s[1],U=8191&V,W=V>>>13,K=0|s[2],G=8191&K,X=K>>>13,Y=0|s[3],Z=8191&Y,$=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],re=8191&te,ne=te>>>13,ie=0|s[6],oe=8191&ie,ae=ie>>>13,se=0|s[7],ce=8191&se,ue=se>>>13,le=0|s[8],he=8191&le,fe=le>>>13,de=0|s[9],pe=8191&de,me=de>>>13;r.negative=e.negative^t.negative,r.length=19;var be=(u+(n=Math.imul(h,H))|0)+((8191&(i=(i=Math.imul(h,q))+Math.imul(f,H)|0))<<13)|0;u=((o=Math.imul(f,q))+(i>>>13)|0)+(be>>>26)|0,be&=67108863,n=Math.imul(p,H),i=(i=Math.imul(p,q))+Math.imul(m,H)|0,o=Math.imul(m,q);var ve=(u+(n=n+Math.imul(h,U)|0)|0)+((8191&(i=(i=i+Math.imul(h,W)|0)+Math.imul(f,U)|0))<<13)|0;u=((o=o+Math.imul(f,W)|0)+(i>>>13)|0)+(ve>>>26)|0,ve&=67108863,n=Math.imul(v,H),i=(i=Math.imul(v,q))+Math.imul(g,H)|0,o=Math.imul(g,q),n=n+Math.imul(p,U)|0,i=(i=i+Math.imul(p,W)|0)+Math.imul(m,U)|0,o=o+Math.imul(m,W)|0;var ge=(u+(n=n+Math.imul(h,G)|0)|0)+((8191&(i=(i=i+Math.imul(h,X)|0)+Math.imul(f,G)|0))<<13)|0;u=((o=o+Math.imul(f,X)|0)+(i>>>13)|0)+(ge>>>26)|0,ge&=67108863,n=Math.imul(w,H),i=(i=Math.imul(w,q))+Math.imul(M,H)|0,o=Math.imul(M,q),n=n+Math.imul(v,U)|0,i=(i=i+Math.imul(v,W)|0)+Math.imul(g,U)|0,o=o+Math.imul(g,W)|0,n=n+Math.imul(p,G)|0,i=(i=i+Math.imul(p,X)|0)+Math.imul(m,G)|0,o=o+Math.imul(m,X)|0;var ye=(u+(n=n+Math.imul(h,Z)|0)|0)+((8191&(i=(i=i+Math.imul(h,$)|0)+Math.imul(f,Z)|0))<<13)|0;u=((o=o+Math.imul(f,$)|0)+(i>>>13)|0)+(ye>>>26)|0,ye&=67108863,n=Math.imul(O,H),i=(i=Math.imul(O,q))+Math.imul(k,H)|0,o=Math.imul(k,q),n=n+Math.imul(w,U)|0,i=(i=i+Math.imul(w,W)|0)+Math.imul(M,U)|0,o=o+Math.imul(M,W)|0,n=n+Math.imul(v,G)|0,i=(i=i+Math.imul(v,X)|0)+Math.imul(g,G)|0,o=o+Math.imul(g,X)|0,n=n+Math.imul(p,Z)|0,i=(i=i+Math.imul(p,$)|0)+Math.imul(m,Z)|0,o=o+Math.imul(m,$)|0;var we=(u+(n=n+Math.imul(h,Q)|0)|0)+((8191&(i=(i=i+Math.imul(h,ee)|0)+Math.imul(f,Q)|0))<<13)|0;u=((o=o+Math.imul(f,ee)|0)+(i>>>13)|0)+(we>>>26)|0,we&=67108863,n=Math.imul(S,H),i=(i=Math.imul(S,q))+Math.imul(A,H)|0,o=Math.imul(A,q),n=n+Math.imul(O,U)|0,i=(i=i+Math.imul(O,W)|0)+Math.imul(k,U)|0,o=o+Math.imul(k,W)|0,n=n+Math.imul(w,G)|0,i=(i=i+Math.imul(w,X)|0)+Math.imul(M,G)|0,o=o+Math.imul(M,X)|0,n=n+Math.imul(v,Z)|0,i=(i=i+Math.imul(v,$)|0)+Math.imul(g,Z)|0,o=o+Math.imul(g,$)|0,n=n+Math.imul(p,Q)|0,i=(i=i+Math.imul(p,ee)|0)+Math.imul(m,Q)|0,o=o+Math.imul(m,ee)|0;var Me=(u+(n=n+Math.imul(h,re)|0)|0)+((8191&(i=(i=i+Math.imul(h,ne)|0)+Math.imul(f,re)|0))<<13)|0;u=((o=o+Math.imul(f,ne)|0)+(i>>>13)|0)+(Me>>>26)|0,Me&=67108863,n=Math.imul(j,H),i=(i=Math.imul(j,q))+Math.imul(z,H)|0,o=Math.imul(z,q),n=n+Math.imul(S,U)|0,i=(i=i+Math.imul(S,W)|0)+Math.imul(A,U)|0,o=o+Math.imul(A,W)|0,n=n+Math.imul(O,G)|0,i=(i=i+Math.imul(O,X)|0)+Math.imul(k,G)|0,o=o+Math.imul(k,X)|0,n=n+Math.imul(w,Z)|0,i=(i=i+Math.imul(w,$)|0)+Math.imul(M,Z)|0,o=o+Math.imul(M,$)|0,n=n+Math.imul(v,Q)|0,i=(i=i+Math.imul(v,ee)|0)+Math.imul(g,Q)|0,o=o+Math.imul(g,ee)|0,n=n+Math.imul(p,re)|0,i=(i=i+Math.imul(p,ne)|0)+Math.imul(m,re)|0,o=o+Math.imul(m,ne)|0;var _e=(u+(n=n+Math.imul(h,oe)|0)|0)+((8191&(i=(i=i+Math.imul(h,ae)|0)+Math.imul(f,oe)|0))<<13)|0;u=((o=o+Math.imul(f,ae)|0)+(i>>>13)|0)+(_e>>>26)|0,_e&=67108863,n=Math.imul(D,H),i=(i=Math.imul(D,q))+Math.imul(P,H)|0,o=Math.imul(P,q),n=n+Math.imul(j,U)|0,i=(i=i+Math.imul(j,W)|0)+Math.imul(z,U)|0,o=o+Math.imul(z,W)|0,n=n+Math.imul(S,G)|0,i=(i=i+Math.imul(S,X)|0)+Math.imul(A,G)|0,o=o+Math.imul(A,X)|0,n=n+Math.imul(O,Z)|0,i=(i=i+Math.imul(O,$)|0)+Math.imul(k,Z)|0,o=o+Math.imul(k,$)|0,n=n+Math.imul(w,Q)|0,i=(i=i+Math.imul(w,ee)|0)+Math.imul(M,Q)|0,o=o+Math.imul(M,ee)|0,n=n+Math.imul(v,re)|0,i=(i=i+Math.imul(v,ne)|0)+Math.imul(g,re)|0,o=o+Math.imul(g,ne)|0,n=n+Math.imul(p,oe)|0,i=(i=i+Math.imul(p,ae)|0)+Math.imul(m,oe)|0,o=o+Math.imul(m,ae)|0;var Oe=(u+(n=n+Math.imul(h,ce)|0)|0)+((8191&(i=(i=i+Math.imul(h,ue)|0)+Math.imul(f,ce)|0))<<13)|0;u=((o=o+Math.imul(f,ue)|0)+(i>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,n=Math.imul(T,H),i=(i=Math.imul(T,q))+Math.imul(F,H)|0,o=Math.imul(F,q),n=n+Math.imul(D,U)|0,i=(i=i+Math.imul(D,W)|0)+Math.imul(P,U)|0,o=o+Math.imul(P,W)|0,n=n+Math.imul(j,G)|0,i=(i=i+Math.imul(j,X)|0)+Math.imul(z,G)|0,o=o+Math.imul(z,X)|0,n=n+Math.imul(S,Z)|0,i=(i=i+Math.imul(S,$)|0)+Math.imul(A,Z)|0,o=o+Math.imul(A,$)|0,n=n+Math.imul(O,Q)|0,i=(i=i+Math.imul(O,ee)|0)+Math.imul(k,Q)|0,o=o+Math.imul(k,ee)|0,n=n+Math.imul(w,re)|0,i=(i=i+Math.imul(w,ne)|0)+Math.imul(M,re)|0,o=o+Math.imul(M,ne)|0,n=n+Math.imul(v,oe)|0,i=(i=i+Math.imul(v,ae)|0)+Math.imul(g,oe)|0,o=o+Math.imul(g,ae)|0,n=n+Math.imul(p,ce)|0,i=(i=i+Math.imul(p,ue)|0)+Math.imul(m,ce)|0,o=o+Math.imul(m,ue)|0;var ke=(u+(n=n+Math.imul(h,he)|0)|0)+((8191&(i=(i=i+Math.imul(h,fe)|0)+Math.imul(f,he)|0))<<13)|0;u=((o=o+Math.imul(f,fe)|0)+(i>>>13)|0)+(ke>>>26)|0,ke&=67108863,n=Math.imul(I,H),i=(i=Math.imul(I,q))+Math.imul(L,H)|0,o=Math.imul(L,q),n=n+Math.imul(T,U)|0,i=(i=i+Math.imul(T,W)|0)+Math.imul(F,U)|0,o=o+Math.imul(F,W)|0,n=n+Math.imul(D,G)|0,i=(i=i+Math.imul(D,X)|0)+Math.imul(P,G)|0,o=o+Math.imul(P,X)|0,n=n+Math.imul(j,Z)|0,i=(i=i+Math.imul(j,$)|0)+Math.imul(z,Z)|0,o=o+Math.imul(z,$)|0,n=n+Math.imul(S,Q)|0,i=(i=i+Math.imul(S,ee)|0)+Math.imul(A,Q)|0,o=o+Math.imul(A,ee)|0,n=n+Math.imul(O,re)|0,i=(i=i+Math.imul(O,ne)|0)+Math.imul(k,re)|0,o=o+Math.imul(k,ne)|0,n=n+Math.imul(w,oe)|0,i=(i=i+Math.imul(w,ae)|0)+Math.imul(M,oe)|0,o=o+Math.imul(M,ae)|0,n=n+Math.imul(v,ce)|0,i=(i=i+Math.imul(v,ue)|0)+Math.imul(g,ce)|0,o=o+Math.imul(g,ue)|0,n=n+Math.imul(p,he)|0,i=(i=i+Math.imul(p,fe)|0)+Math.imul(m,he)|0,o=o+Math.imul(m,fe)|0;var Ee=(u+(n=n+Math.imul(h,pe)|0)|0)+((8191&(i=(i=i+Math.imul(h,me)|0)+Math.imul(f,pe)|0))<<13)|0;u=((o=o+Math.imul(f,me)|0)+(i>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,n=Math.imul(I,U),i=(i=Math.imul(I,W))+Math.imul(L,U)|0,o=Math.imul(L,W),n=n+Math.imul(T,G)|0,i=(i=i+Math.imul(T,X)|0)+Math.imul(F,G)|0,o=o+Math.imul(F,X)|0,n=n+Math.imul(D,Z)|0,i=(i=i+Math.imul(D,$)|0)+Math.imul(P,Z)|0,o=o+Math.imul(P,$)|0,n=n+Math.imul(j,Q)|0,i=(i=i+Math.imul(j,ee)|0)+Math.imul(z,Q)|0,o=o+Math.imul(z,ee)|0,n=n+Math.imul(S,re)|0,i=(i=i+Math.imul(S,ne)|0)+Math.imul(A,re)|0,o=o+Math.imul(A,ne)|0,n=n+Math.imul(O,oe)|0,i=(i=i+Math.imul(O,ae)|0)+Math.imul(k,oe)|0,o=o+Math.imul(k,ae)|0,n=n+Math.imul(w,ce)|0,i=(i=i+Math.imul(w,ue)|0)+Math.imul(M,ce)|0,o=o+Math.imul(M,ue)|0,n=n+Math.imul(v,he)|0,i=(i=i+Math.imul(v,fe)|0)+Math.imul(g,he)|0,o=o+Math.imul(g,fe)|0;var Se=(u+(n=n+Math.imul(p,pe)|0)|0)+((8191&(i=(i=i+Math.imul(p,me)|0)+Math.imul(m,pe)|0))<<13)|0;u=((o=o+Math.imul(m,me)|0)+(i>>>13)|0)+(Se>>>26)|0,Se&=67108863,n=Math.imul(I,G),i=(i=Math.imul(I,X))+Math.imul(L,G)|0,o=Math.imul(L,X),n=n+Math.imul(T,Z)|0,i=(i=i+Math.imul(T,$)|0)+Math.imul(F,Z)|0,o=o+Math.imul(F,$)|0,n=n+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,ee)|0)+Math.imul(P,Q)|0,o=o+Math.imul(P,ee)|0,n=n+Math.imul(j,re)|0,i=(i=i+Math.imul(j,ne)|0)+Math.imul(z,re)|0,o=o+Math.imul(z,ne)|0,n=n+Math.imul(S,oe)|0,i=(i=i+Math.imul(S,ae)|0)+Math.imul(A,oe)|0,o=o+Math.imul(A,ae)|0,n=n+Math.imul(O,ce)|0,i=(i=i+Math.imul(O,ue)|0)+Math.imul(k,ce)|0,o=o+Math.imul(k,ue)|0,n=n+Math.imul(w,he)|0,i=(i=i+Math.imul(w,fe)|0)+Math.imul(M,he)|0,o=o+Math.imul(M,fe)|0;var Ae=(u+(n=n+Math.imul(v,pe)|0)|0)+((8191&(i=(i=i+Math.imul(v,me)|0)+Math.imul(g,pe)|0))<<13)|0;u=((o=o+Math.imul(g,me)|0)+(i>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,n=Math.imul(I,Z),i=(i=Math.imul(I,$))+Math.imul(L,Z)|0,o=Math.imul(L,$),n=n+Math.imul(T,Q)|0,i=(i=i+Math.imul(T,ee)|0)+Math.imul(F,Q)|0,o=o+Math.imul(F,ee)|0,n=n+Math.imul(D,re)|0,i=(i=i+Math.imul(D,ne)|0)+Math.imul(P,re)|0,o=o+Math.imul(P,ne)|0,n=n+Math.imul(j,oe)|0,i=(i=i+Math.imul(j,ae)|0)+Math.imul(z,oe)|0,o=o+Math.imul(z,ae)|0,n=n+Math.imul(S,ce)|0,i=(i=i+Math.imul(S,ue)|0)+Math.imul(A,ce)|0,o=o+Math.imul(A,ue)|0,n=n+Math.imul(O,he)|0,i=(i=i+Math.imul(O,fe)|0)+Math.imul(k,he)|0,o=o+Math.imul(k,fe)|0;var Ce=(u+(n=n+Math.imul(w,pe)|0)|0)+((8191&(i=(i=i+Math.imul(w,me)|0)+Math.imul(M,pe)|0))<<13)|0;u=((o=o+Math.imul(M,me)|0)+(i>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,n=Math.imul(I,Q),i=(i=Math.imul(I,ee))+Math.imul(L,Q)|0,o=Math.imul(L,ee),n=n+Math.imul(T,re)|0,i=(i=i+Math.imul(T,ne)|0)+Math.imul(F,re)|0,o=o+Math.imul(F,ne)|0,n=n+Math.imul(D,oe)|0,i=(i=i+Math.imul(D,ae)|0)+Math.imul(P,oe)|0,o=o+Math.imul(P,ae)|0,n=n+Math.imul(j,ce)|0,i=(i=i+Math.imul(j,ue)|0)+Math.imul(z,ce)|0,o=o+Math.imul(z,ue)|0,n=n+Math.imul(S,he)|0,i=(i=i+Math.imul(S,fe)|0)+Math.imul(A,he)|0,o=o+Math.imul(A,fe)|0;var je=(u+(n=n+Math.imul(O,pe)|0)|0)+((8191&(i=(i=i+Math.imul(O,me)|0)+Math.imul(k,pe)|0))<<13)|0;u=((o=o+Math.imul(k,me)|0)+(i>>>13)|0)+(je>>>26)|0,je&=67108863,n=Math.imul(I,re),i=(i=Math.imul(I,ne))+Math.imul(L,re)|0,o=Math.imul(L,ne),n=n+Math.imul(T,oe)|0,i=(i=i+Math.imul(T,ae)|0)+Math.imul(F,oe)|0,o=o+Math.imul(F,ae)|0,n=n+Math.imul(D,ce)|0,i=(i=i+Math.imul(D,ue)|0)+Math.imul(P,ce)|0,o=o+Math.imul(P,ue)|0,n=n+Math.imul(j,he)|0,i=(i=i+Math.imul(j,fe)|0)+Math.imul(z,he)|0,o=o+Math.imul(z,fe)|0;var ze=(u+(n=n+Math.imul(S,pe)|0)|0)+((8191&(i=(i=i+Math.imul(S,me)|0)+Math.imul(A,pe)|0))<<13)|0;u=((o=o+Math.imul(A,me)|0)+(i>>>13)|0)+(ze>>>26)|0,ze&=67108863,n=Math.imul(I,oe),i=(i=Math.imul(I,ae))+Math.imul(L,oe)|0,o=Math.imul(L,ae),n=n+Math.imul(T,ce)|0,i=(i=i+Math.imul(T,ue)|0)+Math.imul(F,ce)|0,o=o+Math.imul(F,ue)|0,n=n+Math.imul(D,he)|0,i=(i=i+Math.imul(D,fe)|0)+Math.imul(P,he)|0,o=o+Math.imul(P,fe)|0;var xe=(u+(n=n+Math.imul(j,pe)|0)|0)+((8191&(i=(i=i+Math.imul(j,me)|0)+Math.imul(z,pe)|0))<<13)|0;u=((o=o+Math.imul(z,me)|0)+(i>>>13)|0)+(xe>>>26)|0,xe&=67108863,n=Math.imul(I,ce),i=(i=Math.imul(I,ue))+Math.imul(L,ce)|0,o=Math.imul(L,ue),n=n+Math.imul(T,he)|0,i=(i=i+Math.imul(T,fe)|0)+Math.imul(F,he)|0,o=o+Math.imul(F,fe)|0;var De=(u+(n=n+Math.imul(D,pe)|0)|0)+((8191&(i=(i=i+Math.imul(D,me)|0)+Math.imul(P,pe)|0))<<13)|0;u=((o=o+Math.imul(P,me)|0)+(i>>>13)|0)+(De>>>26)|0,De&=67108863,n=Math.imul(I,he),i=(i=Math.imul(I,fe))+Math.imul(L,he)|0,o=Math.imul(L,fe);var Pe=(u+(n=n+Math.imul(T,pe)|0)|0)+((8191&(i=(i=i+Math.imul(T,me)|0)+Math.imul(F,pe)|0))<<13)|0;u=((o=o+Math.imul(F,me)|0)+(i>>>13)|0)+(Pe>>>26)|0,Pe&=67108863;var Re=(u+(n=Math.imul(I,pe))|0)+((8191&(i=(i=Math.imul(I,me))+Math.imul(L,pe)|0))<<13)|0;return u=((o=Math.imul(L,me))+(i>>>13)|0)+(Re>>>26)|0,Re&=67108863,c[0]=be,c[1]=ve,c[2]=ge,c[3]=ye,c[4]=we,c[5]=Me,c[6]=_e,c[7]=Oe,c[8]=ke,c[9]=Ee,c[10]=Se,c[11]=Ae,c[12]=Ce,c[13]=je,c[14]=ze,c[15]=xe,c[16]=De,c[17]=Pe,c[18]=Re,0!==u&&(c[19]=u,r.length++),r};function p(e,t,r){return(new m).mulp(e,t,r)}function m(e,t){this.x=e,this.y=t}Math.imul||(d=f),o.prototype.mulTo=function(e,t){var r=this.length+e.length;return 10===this.length&&10===e.length?d(this,e,t):r<63?f(this,e,t):r<1024?function(e,t,r){r.negative=t.negative^e.negative,r.length=e.length+t.length;for(var n=0,i=0,o=0;o>>26)|0)>>>26,a&=67108863}r.words[o]=s,n=a,a=i}return 0!==n?r.words[o]=n:r.length--,r.strip()}(this,e,t):p(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),r=o.prototype._countBits(e)-1,n=0;n>=1;return n},m.prototype.permute=function(e,t,r,n,i,o){for(var a=0;a>>=1)i++;return 1<>>=13,r[2*a+1]=8191&o,o>>>=13;for(a=2*t;a>=26,t+=i/67108864|0,t+=o>>>26,this.words[r]=67108863&o}return 0!==t&&(this.words[r]=t,this.length++),this},o.prototype.muln=function(e){return this.clone().imuln(e)},o.prototype.sqr=function(){return this.mul(this)},o.prototype.isqr=function(){return this.imul(this.clone())},o.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),r=0;r>>i}return t}(e);if(0===t.length)return new o(1);for(var r=this,n=0;n=0);var t,r=e%26,i=(e-r)/26,o=67108863>>>26-r<<26-r;if(0!==r){var a=0;for(t=0;t>>26-r}a&&(this.words[t]=a,this.length++)}if(0!==i){for(t=this.length-1;t>=0;t--)this.words[t+i]=this.words[t];for(t=0;t=0),i=t?(t-t%26)/26:0;var o=e%26,a=Math.min((e-o)/26,this.length),s=67108863^67108863>>>o<a)for(this.length-=a,u=0;u=0&&(0!==l||u>=i);u--){var h=0|this.words[u];this.words[u]=l<<26-o|h>>>o,l=h&s}return c&&0!==l&&(c.words[c.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},o.prototype.ishrn=function(e,t,r){return n(0===this.negative),this.iushrn(e,t,r)},o.prototype.shln=function(e){return this.clone().ishln(e)},o.prototype.ushln=function(e){return this.clone().iushln(e)},o.prototype.shrn=function(e){return this.clone().ishrn(e)},o.prototype.ushrn=function(e){return this.clone().iushrn(e)},o.prototype.testn=function(e){n("number"==typeof e&&e>=0);var t=e%26,r=(e-t)/26,i=1<=0);var t=e%26,r=(e-t)/26;if(n(0===this.negative,"imaskn works only with positive numbers"),this.length<=r)return this;if(0!==t&&r++,this.length=Math.min(r,this.length),0!==t){var i=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},o.prototype.isubn=function(e){if(n("number"==typeof e),n(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(c/67108864|0),this.words[i+r]=67108863&o}for(;i>26,this.words[i+r]=67108863&o;if(0===s)return this.strip();for(n(-1===s),s=0,i=0;i>26,this.words[i]=67108863&o;return this.negative=1,this.strip()},o.prototype._wordDiv=function(e,t){var r=(this.length,e.length),n=this.clone(),i=e,a=0|i.words[i.length-1];0!==(r=26-this._countBits(a))&&(i=i.ushln(r),n.iushln(r),a=0|i.words[i.length-1]);var s,c=n.length-i.length;if("mod"!==t){(s=new o(null)).length=c+1,s.words=new Array(s.length);for(var u=0;u=0;h--){var f=67108864*(0|n.words[i.length+h])+(0|n.words[i.length+h-1]);for(f=Math.min(f/a|0,67108863),n._ishlnsubmul(i,f,h);0!==n.negative;)f--,n.negative=0,n._ishlnsubmul(i,1,h),n.isZero()||(n.negative^=1);s&&(s.words[h]=f)}return s&&s.strip(),n.strip(),"div"!==t&&0!==r&&n.iushrn(r),{div:s||null,mod:n}},o.prototype.divmod=function(e,t,r){return n(!e.isZero()),this.isZero()?{div:new o(0),mod:new o(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(i=s.div.neg()),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.iadd(e)),{div:i,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new o(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new o(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new o(this.modn(e.words[0]))}:this._wordDiv(e,t);var i,a,s},o.prototype.div=function(e){return this.divmod(e,"div",!1).div},o.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},o.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},o.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var r=0!==t.div.negative?t.mod.isub(e):t.mod,n=e.ushrn(1),i=e.andln(1),o=r.cmp(n);return o<0||1===i&&0===o?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},o.prototype.modn=function(e){n(e<=67108863);for(var t=(1<<26)%e,r=0,i=this.length-1;i>=0;i--)r=(t*r+(0|this.words[i]))%e;return r},o.prototype.idivn=function(e){n(e<=67108863);for(var t=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*t;this.words[r]=i/e|0,t=i%e}return this.strip()},o.prototype.divn=function(e){return this.clone().idivn(e)},o.prototype.egcd=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i=new o(1),a=new o(0),s=new o(0),c=new o(1),u=0;t.isEven()&&r.isEven();)t.iushrn(1),r.iushrn(1),++u;for(var l=r.clone(),h=t.clone();!t.isZero();){for(var f=0,d=1;0==(t.words[0]&d)&&f<26;++f,d<<=1);if(f>0)for(t.iushrn(f);f-- >0;)(i.isOdd()||a.isOdd())&&(i.iadd(l),a.isub(h)),i.iushrn(1),a.iushrn(1);for(var p=0,m=1;0==(r.words[0]&m)&&p<26;++p,m<<=1);if(p>0)for(r.iushrn(p);p-- >0;)(s.isOdd()||c.isOdd())&&(s.iadd(l),c.isub(h)),s.iushrn(1),c.iushrn(1);t.cmp(r)>=0?(t.isub(r),i.isub(s),a.isub(c)):(r.isub(t),s.isub(i),c.isub(a))}return{a:s,b:c,gcd:r.iushln(u)}},o.prototype._invmp=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i,a=new o(1),s=new o(0),c=r.clone();t.cmpn(1)>0&&r.cmpn(1)>0;){for(var u=0,l=1;0==(t.words[0]&l)&&u<26;++u,l<<=1);if(u>0)for(t.iushrn(u);u-- >0;)a.isOdd()&&a.iadd(c),a.iushrn(1);for(var h=0,f=1;0==(r.words[0]&f)&&h<26;++h,f<<=1);if(h>0)for(r.iushrn(h);h-- >0;)s.isOdd()&&s.iadd(c),s.iushrn(1);t.cmp(r)>=0?(t.isub(r),a.isub(s)):(r.isub(t),s.isub(a))}return(i=0===t.cmpn(1)?a:s).cmpn(0)<0&&i.iadd(e),i},o.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),r=e.clone();t.negative=0,r.negative=0;for(var n=0;t.isEven()&&r.isEven();n++)t.iushrn(1),r.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;r.isEven();)r.iushrn(1);var i=t.cmp(r);if(i<0){var o=t;t=r,r=o}else if(0===i||0===r.cmpn(1))break;t.isub(r)}return r.iushln(n)},o.prototype.invm=function(e){return this.egcd(e).a.umod(e)},o.prototype.isEven=function(){return 0==(1&this.words[0])},o.prototype.isOdd=function(){return 1==(1&this.words[0])},o.prototype.andln=function(e){return this.words[0]&e},o.prototype.bincn=function(e){n("number"==typeof e);var t=e%26,r=(e-t)/26,i=1<>>26,s&=67108863,this.words[a]=s}return 0!==o&&(this.words[a]=o,this.length++),this},o.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},o.prototype.cmpn=function(e){var t,r=e<0;if(0!==this.negative&&!r)return-1;if(0===this.negative&&r)return 1;if(this.strip(),this.length>1)t=1;else{r&&(e=-e),n(e<=67108863,"Number is too big");var i=0|this.words[0];t=i===e?0:ie.length)return 1;if(this.length=0;r--){var n=0|this.words[r],i=0|e.words[r];if(n!==i){ni&&(t=1);break}}return t},o.prototype.gtn=function(e){return 1===this.cmpn(e)},o.prototype.gt=function(e){return 1===this.cmp(e)},o.prototype.gten=function(e){return this.cmpn(e)>=0},o.prototype.gte=function(e){return this.cmp(e)>=0},o.prototype.ltn=function(e){return-1===this.cmpn(e)},o.prototype.lt=function(e){return-1===this.cmp(e)},o.prototype.lten=function(e){return this.cmpn(e)<=0},o.prototype.lte=function(e){return this.cmp(e)<=0},o.prototype.eqn=function(e){return 0===this.cmpn(e)},o.prototype.eq=function(e){return 0===this.cmp(e)},o.red=function(e){return new _(e)},o.prototype.toRed=function(e){return n(!this.red,"Already a number in reduction context"),n(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},o.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},o.prototype._forceRed=function(e){return this.red=e,this},o.prototype.forceRed=function(e){return n(!this.red,"Already a number in reduction context"),this._forceRed(e)},o.prototype.redAdd=function(e){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},o.prototype.redIAdd=function(e){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},o.prototype.redSub=function(e){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},o.prototype.redISub=function(e){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},o.prototype.redShl=function(e){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},o.prototype.redMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},o.prototype.redIMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},o.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},o.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},o.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},o.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},o.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},o.prototype.redPow=function(e){return n(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var b={k256:null,p224:null,p192:null,p25519:null};function v(e,t){this.name=e,this.p=new o(t,16),this.n=this.p.bitLength(),this.k=new o(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function g(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function y(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function w(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function M(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function _(e){if("string"==typeof e){var t=o._prime(e);this.m=t.p,this.prime=t}else n(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function O(e){_.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new o(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var e=new o(null);return e.words=new Array(Math.ceil(this.n/13)),e},v.prototype.ireduce=function(e){var t,r=e;do{this.split(r,this.tmp),t=(r=(r=this.imulK(r)).iadd(this.tmp)).bitLength()}while(t>this.n);var n=t0?r.isub(this.p):void 0!==r.strip?r.strip():r._strip(),r},v.prototype.split=function(e,t){e.iushrn(this.n,0,t)},v.prototype.imulK=function(e){return e.imul(this.k)},i(g,v),g.prototype.split=function(e,t){for(var r=Math.min(e.length,9),n=0;n>>22,i=o}i>>>=22,e.words[n-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},g.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,r=0;r>>=26,e.words[r]=i,t=n}return 0!==t&&(e.words[e.length++]=t),e},o._prime=function(e){if(b[e])return b[e];var t;if("k256"===e)t=new g;else if("p224"===e)t=new y;else if("p192"===e)t=new w;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new M}return b[e]=t,t},_.prototype._verify1=function(e){n(0===e.negative,"red works only with positives"),n(e.red,"red works only with red numbers")},_.prototype._verify2=function(e,t){n(0==(e.negative|t.negative),"red works only with positives"),n(e.red&&e.red===t.red,"red works only with red numbers")},_.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},_.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},_.prototype.add=function(e,t){this._verify2(e,t);var r=e.add(t);return r.cmp(this.m)>=0&&r.isub(this.m),r._forceRed(this)},_.prototype.iadd=function(e,t){this._verify2(e,t);var r=e.iadd(t);return r.cmp(this.m)>=0&&r.isub(this.m),r},_.prototype.sub=function(e,t){this._verify2(e,t);var r=e.sub(t);return r.cmpn(0)<0&&r.iadd(this.m),r._forceRed(this)},_.prototype.isub=function(e,t){this._verify2(e,t);var r=e.isub(t);return r.cmpn(0)<0&&r.iadd(this.m),r},_.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},_.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},_.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},_.prototype.isqr=function(e){return this.imul(e,e.clone())},_.prototype.sqr=function(e){return this.mul(e,e)},_.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(n(t%2==1),3===t){var r=this.m.add(new o(1)).iushrn(2);return this.pow(e,r)}for(var i=this.m.subn(1),a=0;!i.isZero()&&0===i.andln(1);)a++,i.iushrn(1);n(!i.isZero());var s=new o(1).toRed(this),c=s.redNeg(),u=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new o(2*l*l).toRed(this);0!==this.pow(l,u).cmp(c);)l.redIAdd(c);for(var h=this.pow(l,i),f=this.pow(e,i.addn(1).iushrn(1)),d=this.pow(e,i),p=a;0!==d.cmp(s);){for(var m=d,b=0;0!==m.cmp(s);b++)m=m.redSqr();n(b=0;n--){for(var u=t.words[n],l=c-1;l>=0;l--){var h=u>>l&1;i!==r[0]&&(i=this.sqr(i)),0!==h||0!==a?(a<<=1,a|=h,(4===++s||0===n&&0===l)&&(i=this.mul(i,r[a]),s=0,a=0)):s=0}c=26}return i},_.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},_.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},o.mont=function(e){return new O(e)},i(O,_),O.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},O.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},O.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var r=e.imul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},O.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new o(0)._forceRed(this);var r=e.mul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},O.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e,this)}).call(this,r(80)(e))},function(e,t,r){var n=r(380),i=r(177);function o(e){this.rand=e||new i.Rand}e.exports=o,o.create=function(e){return new o(e)},o.prototype._randbelow=function(e){var t=e.bitLength(),r=Math.ceil(t/8);do{var i=new n(this.rand.generate(r))}while(i.cmp(e)>=0);return i},o.prototype._randrange=function(e,t){var r=t.sub(e);return e.add(this._randbelow(r))},o.prototype.test=function(e,t,r){var i=e.bitLength(),o=n.mont(e),a=new n(1).toRed(o);t||(t=Math.max(1,i/48|0));for(var s=e.subn(1),c=0;!s.testn(c);c++);for(var u=e.shrn(c),l=s.toRed(o);t>0;t--){var h=this._randrange(new n(2),s);r&&r(h);var f=h.toRed(o).redPow(u);if(0!==f.cmp(a)&&0!==f.cmp(l)){for(var d=1;d0;t--){var l=this._randrange(new n(2),a),h=e.gcd(l);if(0!==h.cmpn(1))return h;var f=l.toRed(i).redPow(c);if(0!==f.cmp(o)&&0!==f.cmp(u)){for(var d=1;d0)if("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===s.prototype||(t=function(e){return s.from(e)}(t)),n)a.endEmitted?_(e,new M):A(e,a,t,!0);else if(a.ended)_(e,new y);else{if(a.destroyed)return!1;a.reading=!1,a.decoder&&!r?(t=a.decoder.write(t),a.objectMode||0!==t.length?A(e,a,t,!1):x(e,a)):A(e,a,t,!1)}else n||(a.reading=!1,x(e,a));return!a.ended&&(a.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=1073741824?e=1073741824:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function j(e){var t=e._readableState;u("emitReadable",t.needReadable,t.emittedReadable),t.needReadable=!1,t.emittedReadable||(u("emitReadable",t.flowing),t.emittedReadable=!0,n.nextTick(z,e))}function z(e){var t=e._readableState;u("emitReadable_",t.destroyed,t.length,t.ended),t.destroyed||!t.length&&!t.ended||(e.emit("readable"),t.emittedReadable=!1),t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark,F(e)}function x(e,t){t.readingMore||(t.readingMore=!0,n.nextTick(D,e,t))}function D(e,t){for(;!t.reading&&!t.ended&&(t.length0,t.resumeScheduled&&!t.paused?t.flowing=!0:e.listenerCount("data")>0&&e.resume()}function R(e){u("readable nexttick read 0"),e.read(0)}function T(e,t){u("resume",t.reading),t.reading||e.read(0),t.resumeScheduled=!1,e.emit("resume"),F(e),t.flowing&&!t.reading&&e.read(0)}function F(e){var t=e._readableState;for(u("flow",t.flowing);t.flowing&&null!==e.read(););}function N(e,t){return 0===t.length?null:(t.objectMode?r=t.buffer.shift():!e||e>=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.first():t.buffer.concat(t.length),t.buffer.clear()):r=t.buffer.consume(e,t.decoder),r);var r}function I(e){var t=e._readableState;u("endReadable",t.endEmitted),t.endEmitted||(t.ended=!0,n.nextTick(L,t,e))}function L(e,t){if(u("endReadableNT",e.endEmitted,e.length),!e.endEmitted&&0===e.length&&(e.endEmitted=!0,t.readable=!1,t.emit("end"),e.autoDestroy)){var r=t._writableState;(!r||r.autoDestroy&&r.finished)&&t.destroy()}}function B(e,t){for(var r=0,n=e.length;r=t.highWaterMark:t.length>0)||t.ended))return u("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?I(this):j(this),null;if(0===(e=C(e,t))&&t.ended)return 0===t.length&&I(this),null;var n,i=t.needReadable;return u("need readable",i),(0===t.length||t.length-e0?N(e,t):null)?(t.needReadable=t.length<=t.highWaterMark,e=0):(t.length-=e,t.awaitDrain=0),0===t.length&&(t.ended||(t.needReadable=!0),r!==e&&t.ended&&I(this)),null!==n&&this.emit("data",n),n},E.prototype._read=function(e){_(this,new w("_read()"))},E.prototype.pipe=function(e,t){var r=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,u("pipe count=%d opts=%j",i.pipesCount,t);var a=(!t||!1!==t.end)&&e!==n.stdout&&e!==n.stderr?c:b;function s(t,n){u("onunpipe"),t===r&&n&&!1===n.hasUnpiped&&(n.hasUnpiped=!0,u("cleanup"),e.removeListener("close",p),e.removeListener("finish",m),e.removeListener("drain",l),e.removeListener("error",d),e.removeListener("unpipe",s),r.removeListener("end",c),r.removeListener("end",b),r.removeListener("data",f),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||l())}function c(){u("onend"),e.end()}i.endEmitted?n.nextTick(a):r.once("end",a),e.on("unpipe",s);var l=function(e){return function(){var t=e._readableState;u("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&o(e,"data")&&(t.flowing=!0,F(e))}}(r);e.on("drain",l);var h=!1;function f(t){u("ondata");var n=e.write(t);u("dest.write",n),!1===n&&((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==B(i.pipes,e))&&!h&&(u("false write response, pause",i.awaitDrain),i.awaitDrain++),r.pause())}function d(t){u("onerror",t),b(),e.removeListener("error",d),0===o(e,"error")&&_(e,t)}function p(){e.removeListener("finish",m),b()}function m(){u("onfinish"),e.removeListener("close",p),b()}function b(){u("unpipe"),r.unpipe(e)}return r.on("data",f),function(e,t,r){if("function"==typeof e.prependListener)return e.prependListener(t,r);e._events&&e._events[t]?Array.isArray(e._events[t])?e._events[t].unshift(r):e._events[t]=[r,e._events[t]]:e.on(t,r)}(e,"error",d),e.once("close",p),e.once("finish",m),e.emit("pipe",r),i.flowing||(u("pipe resume"),r.resume()),e},E.prototype.unpipe=function(e){var t=this._readableState,r={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,r)),this;if(!e){var n=t.pipes,i=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var o=0;o0,!1!==i.flowing&&this.resume()):"readable"===e&&(i.endEmitted||i.readableListening||(i.readableListening=i.needReadable=!0,i.flowing=!1,i.emittedReadable=!1,u("on readable",i.length,i.reading),i.length?j(this):i.reading||n.nextTick(R,this))),r},E.prototype.addListener=E.prototype.on,E.prototype.removeListener=function(e,t){var r=a.prototype.removeListener.call(this,e,t);return"readable"===e&&n.nextTick(P,this),r},E.prototype.removeAllListeners=function(e){var t=a.prototype.removeAllListeners.apply(this,arguments);return"readable"!==e&&void 0!==e||n.nextTick(P,this),t},E.prototype.resume=function(){var e=this._readableState;return e.flowing||(u("resume"),e.flowing=!e.readableListening,function(e,t){t.resumeScheduled||(t.resumeScheduled=!0,n.nextTick(T,e,t))}(this,e)),e.paused=!1,this},E.prototype.pause=function(){return u("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(u("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this},E.prototype.wrap=function(e){var t=this,r=this._readableState,n=!1;for(var i in e.on("end",(function(){if(u("wrapped end"),r.decoder&&!r.ended){var e=r.decoder.end();e&&e.length&&t.push(e)}t.push(null)})),e.on("data",(function(i){(u("wrapped data"),r.decoder&&(i=r.decoder.write(i)),r.objectMode&&null==i)||(r.objectMode||i&&i.length)&&(t.push(i)||(n=!0,e.pause()))})),e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));for(var o=0;o-1))throw new M(e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(E.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(E.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),E.prototype._write=function(e,t,r){r(new m("_write()"))},E.prototype._writev=null,E.prototype.end=function(e,t,r){var i=this._writableState;return"function"==typeof e?(r=e,e=null,t=null):"function"==typeof t&&(r=t,t=null),null!=e&&this.write(e,t),i.corked&&(i.corked=1,this.uncork()),i.ending||function(e,t,r){t.ending=!0,x(e,t),r&&(t.finished?n.nextTick(r):e.once("finish",r));t.ended=!0,e.writable=!1}(this,i,r),this},Object.defineProperty(E.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}}),Object.defineProperty(E.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),E.prototype.destroy=h.destroy,E.prototype._undestroy=h.undestroy,E.prototype._destroy=function(e,t){t(e)}}).call(this,r(46),r(33))},function(e,t,r){"use strict";e.exports=l;var n=r(110).codes,i=n.ERR_METHOD_NOT_IMPLEMENTED,o=n.ERR_MULTIPLE_CALLBACK,a=n.ERR_TRANSFORM_ALREADY_TRANSFORMING,s=n.ERR_TRANSFORM_WITH_LENGTH_0,c=r(111);function u(e,t){var r=this._transformState;r.transforming=!1;var n=r.writecb;if(null===n)return this.emit("error",new o);r.writechunk=null,r.writecb=null,null!=t&&this.push(t),n(e);var i=this._readableState;i.reading=!1,(i.needReadable||i.length>8,a=255&i;o?r.push(o,a):r.push(a)}return r},n.zero2=i,n.toHex=o,n.encode=function(e,t){return"hex"===t?o(e):e}},function(e,t,r){"use strict";var n=t;n.base=r(151),n.short=r(399),n.mont=r(400),n.edwards=r(401)},function(e,t,r){"use strict";var n=r(70).rotr32;function i(e,t,r){return e&t^~e&r}function o(e,t,r){return e&t^e&r^t&r}function a(e,t,r){return e^t^r}t.ft_1=function(e,t,r,n){return 0===e?i(t,r,n):1===e||3===e?a(t,r,n):2===e?o(t,r,n):void 0},t.ch32=i,t.maj32=o,t.p32=a,t.s0_256=function(e){return n(e,2)^n(e,13)^n(e,22)},t.s1_256=function(e){return n(e,6)^n(e,11)^n(e,25)},t.g0_256=function(e){return n(e,7)^n(e,18)^e>>>3},t.g1_256=function(e){return n(e,17)^n(e,19)^e>>>10}},function(e,t,r){"use strict";var n=r(70),i=r(123),o=r(263),a=r(65),s=n.sum32,c=n.sum32_4,u=n.sum32_5,l=o.ch32,h=o.maj32,f=o.s0_256,d=o.s1_256,p=o.g0_256,m=o.g1_256,b=i.BlockHash,v=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function g(){if(!(this instanceof g))return new g;b.call(this),this.h=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],this.k=v,this.W=new Array(64)}n.inherits(g,b),e.exports=g,g.blockSize=512,g.outSize=256,g.hmacStrength=192,g.padLength=64,g.prototype._update=function(e,t){for(var r=this.W,n=0;n<16;n++)r[n]=e[t+n];for(;n=49&&u<=54?u-49+10:u>=17&&u<=22?u-17+10:u,a|=c}return n(!(240&a),"Invalid character in "+e),i}function c(e,t,r,i){for(var o=0,a=0,s=Math.min(e.length,r),c=t;c=49?u-49+10:u>=17?u-17+10:u,n(u>=0&&a0?e:t},o.min=function(e,t){return e.cmp(t)<0?e:t},o.prototype._init=function(e,t,r){if("number"==typeof e)return this._initNumber(e,t,r);if("object"==typeof e)return this._initArray(e,t,r);"hex"===t&&(t=16),n(t===(0|t)&&t>=2&&t<=36);var i=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&i++,16===t?this._parseHex(e,i):this._parseBase(e,t,i),"-"===e[0]&&(this.negative=1),this._strip(),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initNumber=function(e,t,r){e<0&&(this.negative=1,e=-e),e<67108864?(this.words=[67108863&e],this.length=1):e<4503599627370496?(this.words=[67108863&e,e/67108864&67108863],this.length=2):(n(e<9007199254740992),this.words=[67108863&e,e/67108864&67108863,1],this.length=3),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initArray=function(e,t,r){if(n("number"==typeof e.length),e.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(e.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)a=e[i]|e[i-1]<<8|e[i-2]<<16,this.words[o]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);else if("le"===r)for(i=0,o=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);return this._strip()},o.prototype._parseHex=function(e,t){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var r=0;r=t;r-=6)i=s(e,r,r+6),this.words[n]|=i<>>26-o&4194303,(o+=24)>=26&&(o-=26,n++);r+6!==t&&(i=s(e,t,r+6),this.words[n]|=i<>>26-o&4194303),this._strip()},o.prototype._parseBase=function(e,t,r){this.words=[0],this.length=1;for(var n=0,i=1;i<=67108863;i*=t)n++;n--,i=i/t|0;for(var o=e.length-r,a=o%n,s=Math.min(o,o-a)+r,u=0,l=r;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},o.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},"undefined"!=typeof Symbol&&"function"==typeof Symbol.for)try{o.prototype[Symbol.for("nodejs.util.inspect.custom")]=l}catch(e){o.prototype.inspect=l}else o.prototype.inspect=l;function l(){return(this.red?""}var h=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],f=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],d=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];o.prototype.toString=function(e,t){var r;if(t=0|t||1,16===(e=e||10)||"hex"===e){r="";for(var i=0,o=0,a=0;a>>24-i&16777215)||a!==this.length-1?h[6-c.length]+c+r:c+r,(i+=2)>=26&&(i-=26,a--)}for(0!==o&&(r=o.toString(16)+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}if(e===(0|e)&&e>=2&&e<=36){var u=f[e],l=d[e];r="";var p=this.clone();for(p.negative=0;!p.isZero();){var m=p.modrn(l).toString(e);r=(p=p.idivn(l)).isZero()?m+r:h[u-m.length]+m+r}for(this.isZero()&&(r="0"+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}n(!1,"Base should be between 2 and 36")},o.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&n(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},o.prototype.toJSON=function(){return this.toString(16,2)},a&&(o.prototype.toBuffer=function(e,t){return this.toArrayLike(a,e,t)}),o.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)};function p(e,t,r){r.negative=t.negative^e.negative;var n=e.length+t.length|0;r.length=n,n=n-1|0;var i=0|e.words[0],o=0|t.words[0],a=i*o,s=67108863&a,c=a/67108864|0;r.words[0]=s;for(var u=1;u>>26,h=67108863&c,f=Math.min(u,t.length-1),d=Math.max(0,u-e.length+1);d<=f;d++){var p=u-d|0;l+=(a=(i=0|e.words[p])*(o=0|t.words[d])+h)/67108864|0,h=67108863&a}r.words[u]=0|h,c=0|l}return 0!==c?r.words[u]=0|c:r.length--,r._strip()}o.prototype.toArrayLike=function(e,t,r){this._strip();var i=this.byteLength(),o=r||Math.max(1,i);n(i<=o,"byte array longer than desired length"),n(o>0,"Requested array length <= 0");var a=function(e,t){return e.allocUnsafe?e.allocUnsafe(t):new e(t)}(e,o);return this["_toArrayLike"+("le"===t?"LE":"BE")](a,i),a},o.prototype._toArrayLikeLE=function(e,t){for(var r=0,n=0,i=0,o=0;i>8&255),r>16&255),6===o?(r>24&255),n=0,o=0):(n=a>>>24,o+=2)}if(r=0&&(e[r--]=a>>8&255),r>=0&&(e[r--]=a>>16&255),6===o?(r>=0&&(e[r--]=a>>24&255),n=0,o=0):(n=a>>>24,o+=2)}if(r>=0)for(e[r--]=n;r>=0;)e[r--]=0},Math.clz32?o.prototype._countBits=function(e){return 32-Math.clz32(e)}:o.prototype._countBits=function(e){var t=e,r=0;return t>=4096&&(r+=13,t>>>=13),t>=64&&(r+=7,t>>>=7),t>=8&&(r+=4,t>>>=4),t>=2&&(r+=2,t>>>=2),r+t},o.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,r=0;return 0==(8191&t)&&(r+=13,t>>>=13),0==(127&t)&&(r+=7,t>>>=7),0==(15&t)&&(r+=4,t>>>=4),0==(3&t)&&(r+=2,t>>>=2),0==(1&t)&&r++,r},o.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},o.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},o.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},o.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var r=0;re.length?this.clone().iand(e):e.clone().iand(this)},o.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},o.prototype.iuxor=function(e){var t,r;this.length>e.length?(t=this,r=e):(t=e,r=this);for(var n=0;ne.length?this.clone().ixor(e):e.clone().ixor(this)},o.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},o.prototype.inotn=function(e){n("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),r=e%26;this._expand(t),r>0&&t--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-r),this._strip()},o.prototype.notn=function(e){return this.clone().inotn(e)},o.prototype.setn=function(e,t){n("number"==typeof e&&e>=0);var r=e/26|0,i=e%26;return this._expand(r+1),this.words[r]=t?this.words[r]|1<e.length?(r=this,n=e):(r=e,n=this);for(var i=0,o=0;o>>26;for(;0!==i&&o>>26;if(this.length=r.length,0!==i)this.words[this.length]=i,this.length++;else if(r!==this)for(;oe.length?this.clone().iadd(e):e.clone().iadd(this)},o.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var r,n,i=this.cmp(e);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(r=this,n=e):(r=e,n=this);for(var o=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==o&&a>26,this.words[a]=67108863&t;if(0===o&&a>>13,d=0|a[1],p=8191&d,m=d>>>13,b=0|a[2],v=8191&b,g=b>>>13,y=0|a[3],w=8191&y,M=y>>>13,_=0|a[4],O=8191&_,k=_>>>13,E=0|a[5],S=8191&E,A=E>>>13,C=0|a[6],j=8191&C,z=C>>>13,x=0|a[7],D=8191&x,P=x>>>13,R=0|a[8],T=8191&R,F=R>>>13,N=0|a[9],I=8191&N,L=N>>>13,B=0|s[0],H=8191&B,q=B>>>13,V=0|s[1],U=8191&V,W=V>>>13,K=0|s[2],G=8191&K,X=K>>>13,Y=0|s[3],Z=8191&Y,$=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],re=8191&te,ne=te>>>13,ie=0|s[6],oe=8191&ie,ae=ie>>>13,se=0|s[7],ce=8191&se,ue=se>>>13,le=0|s[8],he=8191&le,fe=le>>>13,de=0|s[9],pe=8191&de,me=de>>>13;r.negative=e.negative^t.negative,r.length=19;var be=(u+(n=Math.imul(h,H))|0)+((8191&(i=(i=Math.imul(h,q))+Math.imul(f,H)|0))<<13)|0;u=((o=Math.imul(f,q))+(i>>>13)|0)+(be>>>26)|0,be&=67108863,n=Math.imul(p,H),i=(i=Math.imul(p,q))+Math.imul(m,H)|0,o=Math.imul(m,q);var ve=(u+(n=n+Math.imul(h,U)|0)|0)+((8191&(i=(i=i+Math.imul(h,W)|0)+Math.imul(f,U)|0))<<13)|0;u=((o=o+Math.imul(f,W)|0)+(i>>>13)|0)+(ve>>>26)|0,ve&=67108863,n=Math.imul(v,H),i=(i=Math.imul(v,q))+Math.imul(g,H)|0,o=Math.imul(g,q),n=n+Math.imul(p,U)|0,i=(i=i+Math.imul(p,W)|0)+Math.imul(m,U)|0,o=o+Math.imul(m,W)|0;var ge=(u+(n=n+Math.imul(h,G)|0)|0)+((8191&(i=(i=i+Math.imul(h,X)|0)+Math.imul(f,G)|0))<<13)|0;u=((o=o+Math.imul(f,X)|0)+(i>>>13)|0)+(ge>>>26)|0,ge&=67108863,n=Math.imul(w,H),i=(i=Math.imul(w,q))+Math.imul(M,H)|0,o=Math.imul(M,q),n=n+Math.imul(v,U)|0,i=(i=i+Math.imul(v,W)|0)+Math.imul(g,U)|0,o=o+Math.imul(g,W)|0,n=n+Math.imul(p,G)|0,i=(i=i+Math.imul(p,X)|0)+Math.imul(m,G)|0,o=o+Math.imul(m,X)|0;var ye=(u+(n=n+Math.imul(h,Z)|0)|0)+((8191&(i=(i=i+Math.imul(h,$)|0)+Math.imul(f,Z)|0))<<13)|0;u=((o=o+Math.imul(f,$)|0)+(i>>>13)|0)+(ye>>>26)|0,ye&=67108863,n=Math.imul(O,H),i=(i=Math.imul(O,q))+Math.imul(k,H)|0,o=Math.imul(k,q),n=n+Math.imul(w,U)|0,i=(i=i+Math.imul(w,W)|0)+Math.imul(M,U)|0,o=o+Math.imul(M,W)|0,n=n+Math.imul(v,G)|0,i=(i=i+Math.imul(v,X)|0)+Math.imul(g,G)|0,o=o+Math.imul(g,X)|0,n=n+Math.imul(p,Z)|0,i=(i=i+Math.imul(p,$)|0)+Math.imul(m,Z)|0,o=o+Math.imul(m,$)|0;var we=(u+(n=n+Math.imul(h,Q)|0)|0)+((8191&(i=(i=i+Math.imul(h,ee)|0)+Math.imul(f,Q)|0))<<13)|0;u=((o=o+Math.imul(f,ee)|0)+(i>>>13)|0)+(we>>>26)|0,we&=67108863,n=Math.imul(S,H),i=(i=Math.imul(S,q))+Math.imul(A,H)|0,o=Math.imul(A,q),n=n+Math.imul(O,U)|0,i=(i=i+Math.imul(O,W)|0)+Math.imul(k,U)|0,o=o+Math.imul(k,W)|0,n=n+Math.imul(w,G)|0,i=(i=i+Math.imul(w,X)|0)+Math.imul(M,G)|0,o=o+Math.imul(M,X)|0,n=n+Math.imul(v,Z)|0,i=(i=i+Math.imul(v,$)|0)+Math.imul(g,Z)|0,o=o+Math.imul(g,$)|0,n=n+Math.imul(p,Q)|0,i=(i=i+Math.imul(p,ee)|0)+Math.imul(m,Q)|0,o=o+Math.imul(m,ee)|0;var Me=(u+(n=n+Math.imul(h,re)|0)|0)+((8191&(i=(i=i+Math.imul(h,ne)|0)+Math.imul(f,re)|0))<<13)|0;u=((o=o+Math.imul(f,ne)|0)+(i>>>13)|0)+(Me>>>26)|0,Me&=67108863,n=Math.imul(j,H),i=(i=Math.imul(j,q))+Math.imul(z,H)|0,o=Math.imul(z,q),n=n+Math.imul(S,U)|0,i=(i=i+Math.imul(S,W)|0)+Math.imul(A,U)|0,o=o+Math.imul(A,W)|0,n=n+Math.imul(O,G)|0,i=(i=i+Math.imul(O,X)|0)+Math.imul(k,G)|0,o=o+Math.imul(k,X)|0,n=n+Math.imul(w,Z)|0,i=(i=i+Math.imul(w,$)|0)+Math.imul(M,Z)|0,o=o+Math.imul(M,$)|0,n=n+Math.imul(v,Q)|0,i=(i=i+Math.imul(v,ee)|0)+Math.imul(g,Q)|0,o=o+Math.imul(g,ee)|0,n=n+Math.imul(p,re)|0,i=(i=i+Math.imul(p,ne)|0)+Math.imul(m,re)|0,o=o+Math.imul(m,ne)|0;var _e=(u+(n=n+Math.imul(h,oe)|0)|0)+((8191&(i=(i=i+Math.imul(h,ae)|0)+Math.imul(f,oe)|0))<<13)|0;u=((o=o+Math.imul(f,ae)|0)+(i>>>13)|0)+(_e>>>26)|0,_e&=67108863,n=Math.imul(D,H),i=(i=Math.imul(D,q))+Math.imul(P,H)|0,o=Math.imul(P,q),n=n+Math.imul(j,U)|0,i=(i=i+Math.imul(j,W)|0)+Math.imul(z,U)|0,o=o+Math.imul(z,W)|0,n=n+Math.imul(S,G)|0,i=(i=i+Math.imul(S,X)|0)+Math.imul(A,G)|0,o=o+Math.imul(A,X)|0,n=n+Math.imul(O,Z)|0,i=(i=i+Math.imul(O,$)|0)+Math.imul(k,Z)|0,o=o+Math.imul(k,$)|0,n=n+Math.imul(w,Q)|0,i=(i=i+Math.imul(w,ee)|0)+Math.imul(M,Q)|0,o=o+Math.imul(M,ee)|0,n=n+Math.imul(v,re)|0,i=(i=i+Math.imul(v,ne)|0)+Math.imul(g,re)|0,o=o+Math.imul(g,ne)|0,n=n+Math.imul(p,oe)|0,i=(i=i+Math.imul(p,ae)|0)+Math.imul(m,oe)|0,o=o+Math.imul(m,ae)|0;var Oe=(u+(n=n+Math.imul(h,ce)|0)|0)+((8191&(i=(i=i+Math.imul(h,ue)|0)+Math.imul(f,ce)|0))<<13)|0;u=((o=o+Math.imul(f,ue)|0)+(i>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,n=Math.imul(T,H),i=(i=Math.imul(T,q))+Math.imul(F,H)|0,o=Math.imul(F,q),n=n+Math.imul(D,U)|0,i=(i=i+Math.imul(D,W)|0)+Math.imul(P,U)|0,o=o+Math.imul(P,W)|0,n=n+Math.imul(j,G)|0,i=(i=i+Math.imul(j,X)|0)+Math.imul(z,G)|0,o=o+Math.imul(z,X)|0,n=n+Math.imul(S,Z)|0,i=(i=i+Math.imul(S,$)|0)+Math.imul(A,Z)|0,o=o+Math.imul(A,$)|0,n=n+Math.imul(O,Q)|0,i=(i=i+Math.imul(O,ee)|0)+Math.imul(k,Q)|0,o=o+Math.imul(k,ee)|0,n=n+Math.imul(w,re)|0,i=(i=i+Math.imul(w,ne)|0)+Math.imul(M,re)|0,o=o+Math.imul(M,ne)|0,n=n+Math.imul(v,oe)|0,i=(i=i+Math.imul(v,ae)|0)+Math.imul(g,oe)|0,o=o+Math.imul(g,ae)|0,n=n+Math.imul(p,ce)|0,i=(i=i+Math.imul(p,ue)|0)+Math.imul(m,ce)|0,o=o+Math.imul(m,ue)|0;var ke=(u+(n=n+Math.imul(h,he)|0)|0)+((8191&(i=(i=i+Math.imul(h,fe)|0)+Math.imul(f,he)|0))<<13)|0;u=((o=o+Math.imul(f,fe)|0)+(i>>>13)|0)+(ke>>>26)|0,ke&=67108863,n=Math.imul(I,H),i=(i=Math.imul(I,q))+Math.imul(L,H)|0,o=Math.imul(L,q),n=n+Math.imul(T,U)|0,i=(i=i+Math.imul(T,W)|0)+Math.imul(F,U)|0,o=o+Math.imul(F,W)|0,n=n+Math.imul(D,G)|0,i=(i=i+Math.imul(D,X)|0)+Math.imul(P,G)|0,o=o+Math.imul(P,X)|0,n=n+Math.imul(j,Z)|0,i=(i=i+Math.imul(j,$)|0)+Math.imul(z,Z)|0,o=o+Math.imul(z,$)|0,n=n+Math.imul(S,Q)|0,i=(i=i+Math.imul(S,ee)|0)+Math.imul(A,Q)|0,o=o+Math.imul(A,ee)|0,n=n+Math.imul(O,re)|0,i=(i=i+Math.imul(O,ne)|0)+Math.imul(k,re)|0,o=o+Math.imul(k,ne)|0,n=n+Math.imul(w,oe)|0,i=(i=i+Math.imul(w,ae)|0)+Math.imul(M,oe)|0,o=o+Math.imul(M,ae)|0,n=n+Math.imul(v,ce)|0,i=(i=i+Math.imul(v,ue)|0)+Math.imul(g,ce)|0,o=o+Math.imul(g,ue)|0,n=n+Math.imul(p,he)|0,i=(i=i+Math.imul(p,fe)|0)+Math.imul(m,he)|0,o=o+Math.imul(m,fe)|0;var Ee=(u+(n=n+Math.imul(h,pe)|0)|0)+((8191&(i=(i=i+Math.imul(h,me)|0)+Math.imul(f,pe)|0))<<13)|0;u=((o=o+Math.imul(f,me)|0)+(i>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,n=Math.imul(I,U),i=(i=Math.imul(I,W))+Math.imul(L,U)|0,o=Math.imul(L,W),n=n+Math.imul(T,G)|0,i=(i=i+Math.imul(T,X)|0)+Math.imul(F,G)|0,o=o+Math.imul(F,X)|0,n=n+Math.imul(D,Z)|0,i=(i=i+Math.imul(D,$)|0)+Math.imul(P,Z)|0,o=o+Math.imul(P,$)|0,n=n+Math.imul(j,Q)|0,i=(i=i+Math.imul(j,ee)|0)+Math.imul(z,Q)|0,o=o+Math.imul(z,ee)|0,n=n+Math.imul(S,re)|0,i=(i=i+Math.imul(S,ne)|0)+Math.imul(A,re)|0,o=o+Math.imul(A,ne)|0,n=n+Math.imul(O,oe)|0,i=(i=i+Math.imul(O,ae)|0)+Math.imul(k,oe)|0,o=o+Math.imul(k,ae)|0,n=n+Math.imul(w,ce)|0,i=(i=i+Math.imul(w,ue)|0)+Math.imul(M,ce)|0,o=o+Math.imul(M,ue)|0,n=n+Math.imul(v,he)|0,i=(i=i+Math.imul(v,fe)|0)+Math.imul(g,he)|0,o=o+Math.imul(g,fe)|0;var Se=(u+(n=n+Math.imul(p,pe)|0)|0)+((8191&(i=(i=i+Math.imul(p,me)|0)+Math.imul(m,pe)|0))<<13)|0;u=((o=o+Math.imul(m,me)|0)+(i>>>13)|0)+(Se>>>26)|0,Se&=67108863,n=Math.imul(I,G),i=(i=Math.imul(I,X))+Math.imul(L,G)|0,o=Math.imul(L,X),n=n+Math.imul(T,Z)|0,i=(i=i+Math.imul(T,$)|0)+Math.imul(F,Z)|0,o=o+Math.imul(F,$)|0,n=n+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,ee)|0)+Math.imul(P,Q)|0,o=o+Math.imul(P,ee)|0,n=n+Math.imul(j,re)|0,i=(i=i+Math.imul(j,ne)|0)+Math.imul(z,re)|0,o=o+Math.imul(z,ne)|0,n=n+Math.imul(S,oe)|0,i=(i=i+Math.imul(S,ae)|0)+Math.imul(A,oe)|0,o=o+Math.imul(A,ae)|0,n=n+Math.imul(O,ce)|0,i=(i=i+Math.imul(O,ue)|0)+Math.imul(k,ce)|0,o=o+Math.imul(k,ue)|0,n=n+Math.imul(w,he)|0,i=(i=i+Math.imul(w,fe)|0)+Math.imul(M,he)|0,o=o+Math.imul(M,fe)|0;var Ae=(u+(n=n+Math.imul(v,pe)|0)|0)+((8191&(i=(i=i+Math.imul(v,me)|0)+Math.imul(g,pe)|0))<<13)|0;u=((o=o+Math.imul(g,me)|0)+(i>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,n=Math.imul(I,Z),i=(i=Math.imul(I,$))+Math.imul(L,Z)|0,o=Math.imul(L,$),n=n+Math.imul(T,Q)|0,i=(i=i+Math.imul(T,ee)|0)+Math.imul(F,Q)|0,o=o+Math.imul(F,ee)|0,n=n+Math.imul(D,re)|0,i=(i=i+Math.imul(D,ne)|0)+Math.imul(P,re)|0,o=o+Math.imul(P,ne)|0,n=n+Math.imul(j,oe)|0,i=(i=i+Math.imul(j,ae)|0)+Math.imul(z,oe)|0,o=o+Math.imul(z,ae)|0,n=n+Math.imul(S,ce)|0,i=(i=i+Math.imul(S,ue)|0)+Math.imul(A,ce)|0,o=o+Math.imul(A,ue)|0,n=n+Math.imul(O,he)|0,i=(i=i+Math.imul(O,fe)|0)+Math.imul(k,he)|0,o=o+Math.imul(k,fe)|0;var Ce=(u+(n=n+Math.imul(w,pe)|0)|0)+((8191&(i=(i=i+Math.imul(w,me)|0)+Math.imul(M,pe)|0))<<13)|0;u=((o=o+Math.imul(M,me)|0)+(i>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,n=Math.imul(I,Q),i=(i=Math.imul(I,ee))+Math.imul(L,Q)|0,o=Math.imul(L,ee),n=n+Math.imul(T,re)|0,i=(i=i+Math.imul(T,ne)|0)+Math.imul(F,re)|0,o=o+Math.imul(F,ne)|0,n=n+Math.imul(D,oe)|0,i=(i=i+Math.imul(D,ae)|0)+Math.imul(P,oe)|0,o=o+Math.imul(P,ae)|0,n=n+Math.imul(j,ce)|0,i=(i=i+Math.imul(j,ue)|0)+Math.imul(z,ce)|0,o=o+Math.imul(z,ue)|0,n=n+Math.imul(S,he)|0,i=(i=i+Math.imul(S,fe)|0)+Math.imul(A,he)|0,o=o+Math.imul(A,fe)|0;var je=(u+(n=n+Math.imul(O,pe)|0)|0)+((8191&(i=(i=i+Math.imul(O,me)|0)+Math.imul(k,pe)|0))<<13)|0;u=((o=o+Math.imul(k,me)|0)+(i>>>13)|0)+(je>>>26)|0,je&=67108863,n=Math.imul(I,re),i=(i=Math.imul(I,ne))+Math.imul(L,re)|0,o=Math.imul(L,ne),n=n+Math.imul(T,oe)|0,i=(i=i+Math.imul(T,ae)|0)+Math.imul(F,oe)|0,o=o+Math.imul(F,ae)|0,n=n+Math.imul(D,ce)|0,i=(i=i+Math.imul(D,ue)|0)+Math.imul(P,ce)|0,o=o+Math.imul(P,ue)|0,n=n+Math.imul(j,he)|0,i=(i=i+Math.imul(j,fe)|0)+Math.imul(z,he)|0,o=o+Math.imul(z,fe)|0;var ze=(u+(n=n+Math.imul(S,pe)|0)|0)+((8191&(i=(i=i+Math.imul(S,me)|0)+Math.imul(A,pe)|0))<<13)|0;u=((o=o+Math.imul(A,me)|0)+(i>>>13)|0)+(ze>>>26)|0,ze&=67108863,n=Math.imul(I,oe),i=(i=Math.imul(I,ae))+Math.imul(L,oe)|0,o=Math.imul(L,ae),n=n+Math.imul(T,ce)|0,i=(i=i+Math.imul(T,ue)|0)+Math.imul(F,ce)|0,o=o+Math.imul(F,ue)|0,n=n+Math.imul(D,he)|0,i=(i=i+Math.imul(D,fe)|0)+Math.imul(P,he)|0,o=o+Math.imul(P,fe)|0;var xe=(u+(n=n+Math.imul(j,pe)|0)|0)+((8191&(i=(i=i+Math.imul(j,me)|0)+Math.imul(z,pe)|0))<<13)|0;u=((o=o+Math.imul(z,me)|0)+(i>>>13)|0)+(xe>>>26)|0,xe&=67108863,n=Math.imul(I,ce),i=(i=Math.imul(I,ue))+Math.imul(L,ce)|0,o=Math.imul(L,ue),n=n+Math.imul(T,he)|0,i=(i=i+Math.imul(T,fe)|0)+Math.imul(F,he)|0,o=o+Math.imul(F,fe)|0;var De=(u+(n=n+Math.imul(D,pe)|0)|0)+((8191&(i=(i=i+Math.imul(D,me)|0)+Math.imul(P,pe)|0))<<13)|0;u=((o=o+Math.imul(P,me)|0)+(i>>>13)|0)+(De>>>26)|0,De&=67108863,n=Math.imul(I,he),i=(i=Math.imul(I,fe))+Math.imul(L,he)|0,o=Math.imul(L,fe);var Pe=(u+(n=n+Math.imul(T,pe)|0)|0)+((8191&(i=(i=i+Math.imul(T,me)|0)+Math.imul(F,pe)|0))<<13)|0;u=((o=o+Math.imul(F,me)|0)+(i>>>13)|0)+(Pe>>>26)|0,Pe&=67108863;var Re=(u+(n=Math.imul(I,pe))|0)+((8191&(i=(i=Math.imul(I,me))+Math.imul(L,pe)|0))<<13)|0;return u=((o=Math.imul(L,me))+(i>>>13)|0)+(Re>>>26)|0,Re&=67108863,c[0]=be,c[1]=ve,c[2]=ge,c[3]=ye,c[4]=we,c[5]=Me,c[6]=_e,c[7]=Oe,c[8]=ke,c[9]=Ee,c[10]=Se,c[11]=Ae,c[12]=Ce,c[13]=je,c[14]=ze,c[15]=xe,c[16]=De,c[17]=Pe,c[18]=Re,0!==u&&(c[19]=u,r.length++),r};function b(e,t,r){r.negative=t.negative^e.negative,r.length=e.length+t.length;for(var n=0,i=0,o=0;o>>26)|0)>>>26,a&=67108863}r.words[o]=s,n=a,a=i}return 0!==n?r.words[o]=n:r.length--,r._strip()}function v(e,t,r){return b(e,t,r)}function g(e,t){this.x=e,this.y=t}Math.imul||(m=p),o.prototype.mulTo=function(e,t){var r=this.length+e.length;return 10===this.length&&10===e.length?m(this,e,t):r<63?p(this,e,t):r<1024?b(this,e,t):v(this,e,t)},g.prototype.makeRBT=function(e){for(var t=new Array(e),r=o.prototype._countBits(e)-1,n=0;n>=1;return n},g.prototype.permute=function(e,t,r,n,i,o){for(var a=0;a>>=1)i++;return 1<>>=13,r[2*a+1]=8191&o,o>>>=13;for(a=2*t;a>=26,r+=o/67108864|0,r+=a>>>26,this.words[i]=67108863&a}return 0!==r&&(this.words[i]=r,this.length++),t?this.ineg():this},o.prototype.muln=function(e){return this.clone().imuln(e)},o.prototype.sqr=function(){return this.mul(this)},o.prototype.isqr=function(){return this.imul(this.clone())},o.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),r=0;r>>i&1}return t}(e);if(0===t.length)return new o(1);for(var r=this,n=0;n=0);var t,r=e%26,i=(e-r)/26,o=67108863>>>26-r<<26-r;if(0!==r){var a=0;for(t=0;t>>26-r}a&&(this.words[t]=a,this.length++)}if(0!==i){for(t=this.length-1;t>=0;t--)this.words[t+i]=this.words[t];for(t=0;t=0),i=t?(t-t%26)/26:0;var o=e%26,a=Math.min((e-o)/26,this.length),s=67108863^67108863>>>o<a)for(this.length-=a,u=0;u=0&&(0!==l||u>=i);u--){var h=0|this.words[u];this.words[u]=l<<26-o|h>>>o,l=h&s}return c&&0!==l&&(c.words[c.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this._strip()},o.prototype.ishrn=function(e,t,r){return n(0===this.negative),this.iushrn(e,t,r)},o.prototype.shln=function(e){return this.clone().ishln(e)},o.prototype.ushln=function(e){return this.clone().iushln(e)},o.prototype.shrn=function(e){return this.clone().ishrn(e)},o.prototype.ushrn=function(e){return this.clone().iushrn(e)},o.prototype.testn=function(e){n("number"==typeof e&&e>=0);var t=e%26,r=(e-t)/26,i=1<=0);var t=e%26,r=(e-t)/26;if(n(0===this.negative,"imaskn works only with positive numbers"),this.length<=r)return this;if(0!==t&&r++,this.length=Math.min(r,this.length),0!==t){var i=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},o.prototype.isubn=function(e){if(n("number"==typeof e),n(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(c/67108864|0),this.words[i+r]=67108863&o}for(;i>26,this.words[i+r]=67108863&o;if(0===s)return this._strip();for(n(-1===s),s=0,i=0;i>26,this.words[i]=67108863&o;return this.negative=1,this._strip()},o.prototype._wordDiv=function(e,t){var r=(this.length,e.length),n=this.clone(),i=e,a=0|i.words[i.length-1];0!==(r=26-this._countBits(a))&&(i=i.ushln(r),n.iushln(r),a=0|i.words[i.length-1]);var s,c=n.length-i.length;if("mod"!==t){(s=new o(null)).length=c+1,s.words=new Array(s.length);for(var u=0;u=0;h--){var f=67108864*(0|n.words[i.length+h])+(0|n.words[i.length+h-1]);for(f=Math.min(f/a|0,67108863),n._ishlnsubmul(i,f,h);0!==n.negative;)f--,n.negative=0,n._ishlnsubmul(i,1,h),n.isZero()||(n.negative^=1);s&&(s.words[h]=f)}return s&&s._strip(),n._strip(),"div"!==t&&0!==r&&n.iushrn(r),{div:s||null,mod:n}},o.prototype.divmod=function(e,t,r){return n(!e.isZero()),this.isZero()?{div:new o(0),mod:new o(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(i=s.div.neg()),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.iadd(e)),{div:i,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new o(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new o(this.modrn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new o(this.modrn(e.words[0]))}:this._wordDiv(e,t);var i,a,s},o.prototype.div=function(e){return this.divmod(e,"div",!1).div},o.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},o.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},o.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var r=0!==t.div.negative?t.mod.isub(e):t.mod,n=e.ushrn(1),i=e.andln(1),o=r.cmp(n);return o<0||1===i&&0===o?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},o.prototype.modrn=function(e){var t=e<0;t&&(e=-e),n(e<=67108863);for(var r=(1<<26)%e,i=0,o=this.length-1;o>=0;o--)i=(r*i+(0|this.words[o]))%e;return t?-i:i},o.prototype.modn=function(e){return this.modrn(e)},o.prototype.idivn=function(e){var t=e<0;t&&(e=-e),n(e<=67108863);for(var r=0,i=this.length-1;i>=0;i--){var o=(0|this.words[i])+67108864*r;this.words[i]=o/e|0,r=o%e}return this._strip(),t?this.ineg():this},o.prototype.divn=function(e){return this.clone().idivn(e)},o.prototype.egcd=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i=new o(1),a=new o(0),s=new o(0),c=new o(1),u=0;t.isEven()&&r.isEven();)t.iushrn(1),r.iushrn(1),++u;for(var l=r.clone(),h=t.clone();!t.isZero();){for(var f=0,d=1;0==(t.words[0]&d)&&f<26;++f,d<<=1);if(f>0)for(t.iushrn(f);f-- >0;)(i.isOdd()||a.isOdd())&&(i.iadd(l),a.isub(h)),i.iushrn(1),a.iushrn(1);for(var p=0,m=1;0==(r.words[0]&m)&&p<26;++p,m<<=1);if(p>0)for(r.iushrn(p);p-- >0;)(s.isOdd()||c.isOdd())&&(s.iadd(l),c.isub(h)),s.iushrn(1),c.iushrn(1);t.cmp(r)>=0?(t.isub(r),i.isub(s),a.isub(c)):(r.isub(t),s.isub(i),c.isub(a))}return{a:s,b:c,gcd:r.iushln(u)}},o.prototype._invmp=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i,a=new o(1),s=new o(0),c=r.clone();t.cmpn(1)>0&&r.cmpn(1)>0;){for(var u=0,l=1;0==(t.words[0]&l)&&u<26;++u,l<<=1);if(u>0)for(t.iushrn(u);u-- >0;)a.isOdd()&&a.iadd(c),a.iushrn(1);for(var h=0,f=1;0==(r.words[0]&f)&&h<26;++h,f<<=1);if(h>0)for(r.iushrn(h);h-- >0;)s.isOdd()&&s.iadd(c),s.iushrn(1);t.cmp(r)>=0?(t.isub(r),a.isub(s)):(r.isub(t),s.isub(a))}return(i=0===t.cmpn(1)?a:s).cmpn(0)<0&&i.iadd(e),i},o.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),r=e.clone();t.negative=0,r.negative=0;for(var n=0;t.isEven()&&r.isEven();n++)t.iushrn(1),r.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;r.isEven();)r.iushrn(1);var i=t.cmp(r);if(i<0){var o=t;t=r,r=o}else if(0===i||0===r.cmpn(1))break;t.isub(r)}return r.iushln(n)},o.prototype.invm=function(e){return this.egcd(e).a.umod(e)},o.prototype.isEven=function(){return 0==(1&this.words[0])},o.prototype.isOdd=function(){return 1==(1&this.words[0])},o.prototype.andln=function(e){return this.words[0]&e},o.prototype.bincn=function(e){n("number"==typeof e);var t=e%26,r=(e-t)/26,i=1<>>26,s&=67108863,this.words[a]=s}return 0!==o&&(this.words[a]=o,this.length++),this},o.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},o.prototype.cmpn=function(e){var t,r=e<0;if(0!==this.negative&&!r)return-1;if(0===this.negative&&r)return 1;if(this._strip(),this.length>1)t=1;else{r&&(e=-e),n(e<=67108863,"Number is too big");var i=0|this.words[0];t=i===e?0:ie.length)return 1;if(this.length=0;r--){var n=0|this.words[r],i=0|e.words[r];if(n!==i){ni&&(t=1);break}}return t},o.prototype.gtn=function(e){return 1===this.cmpn(e)},o.prototype.gt=function(e){return 1===this.cmp(e)},o.prototype.gten=function(e){return this.cmpn(e)>=0},o.prototype.gte=function(e){return this.cmp(e)>=0},o.prototype.ltn=function(e){return-1===this.cmpn(e)},o.prototype.lt=function(e){return-1===this.cmp(e)},o.prototype.lten=function(e){return this.cmpn(e)<=0},o.prototype.lte=function(e){return this.cmp(e)<=0},o.prototype.eqn=function(e){return 0===this.cmpn(e)},o.prototype.eq=function(e){return 0===this.cmp(e)},o.red=function(e){return new E(e)},o.prototype.toRed=function(e){return n(!this.red,"Already a number in reduction context"),n(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},o.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},o.prototype._forceRed=function(e){return this.red=e,this},o.prototype.forceRed=function(e){return n(!this.red,"Already a number in reduction context"),this._forceRed(e)},o.prototype.redAdd=function(e){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},o.prototype.redIAdd=function(e){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},o.prototype.redSub=function(e){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},o.prototype.redISub=function(e){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},o.prototype.redShl=function(e){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},o.prototype.redMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},o.prototype.redIMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},o.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},o.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},o.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},o.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},o.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},o.prototype.redPow=function(e){return n(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var y={k256:null,p224:null,p192:null,p25519:null};function w(e,t){this.name=e,this.p=new o(t,16),this.n=this.p.bitLength(),this.k=new o(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function M(){w.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function _(){w.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function O(){w.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function k(){w.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=o._prime(e);this.m=t.p,this.prime=t}else n(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function S(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new o(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}w.prototype._tmp=function(){var e=new o(null);return e.words=new Array(Math.ceil(this.n/13)),e},w.prototype.ireduce=function(e){var t,r=e;do{this.split(r,this.tmp),t=(r=(r=this.imulK(r)).iadd(this.tmp)).bitLength()}while(t>this.n);var n=t0?r.isub(this.p):void 0!==r.strip?r.strip():r._strip(),r},w.prototype.split=function(e,t){e.iushrn(this.n,0,t)},w.prototype.imulK=function(e){return e.imul(this.k)},i(M,w),M.prototype.split=function(e,t){for(var r=Math.min(e.length,9),n=0;n>>22,i=o}i>>>=22,e.words[n-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},M.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,r=0;r>>=26,e.words[r]=i,t=n}return 0!==t&&(e.words[e.length++]=t),e},o._prime=function(e){if(y[e])return y[e];var t;if("k256"===e)t=new M;else if("p224"===e)t=new _;else if("p192"===e)t=new O;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new k}return y[e]=t,t},E.prototype._verify1=function(e){n(0===e.negative,"red works only with positives"),n(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){n(0==(e.negative|t.negative),"red works only with positives"),n(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):(u(e,e.umod(this.m)._forceRed(this)),e)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var r=e.add(t);return r.cmp(this.m)>=0&&r.isub(this.m),r._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var r=e.iadd(t);return r.cmp(this.m)>=0&&r.isub(this.m),r},E.prototype.sub=function(e,t){this._verify2(e,t);var r=e.sub(t);return r.cmpn(0)<0&&r.iadd(this.m),r._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var r=e.isub(t);return r.cmpn(0)<0&&r.iadd(this.m),r},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(n(t%2==1),3===t){var r=this.m.add(new o(1)).iushrn(2);return this.pow(e,r)}for(var i=this.m.subn(1),a=0;!i.isZero()&&0===i.andln(1);)a++,i.iushrn(1);n(!i.isZero());var s=new o(1).toRed(this),c=s.redNeg(),u=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new o(2*l*l).toRed(this);0!==this.pow(l,u).cmp(c);)l.redIAdd(c);for(var h=this.pow(l,i),f=this.pow(e,i.addn(1).iushrn(1)),d=this.pow(e,i),p=a;0!==d.cmp(s);){for(var m=d,b=0;0!==m.cmp(s);b++)m=m.redSqr();n(b=0;n--){for(var u=t.words[n],l=c-1;l>=0;l--){var h=u>>l&1;i!==r[0]&&(i=this.sqr(i)),0!==h||0!==a?(a<<=1,a|=h,(4===++s||0===n&&0===l)&&(i=this.mul(i,r[a]),s=0,a=0)):s=0}c=26}return i},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},o.mont=function(e){return new S(e)},i(S,E),S.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},S.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},S.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var r=e.imul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},S.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new o(0)._forceRed(this);var r=e.mul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},S.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e,this)}).call(this,r(80)(e))},function(e,t,r){"use strict";const n=t;n.bignum=r(268),n.define=r(419).define,n.base=r(422),n.constants=r(423),n.decoders=r(271),n.encoders=r(269)},function(e,t,r){(function(e){!function(e,t){"use strict";function n(e,t){if(!e)throw new Error(t||"Assertion failed")}function i(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e}function o(e,t,r){if(o.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(r=t,t=10),this._init(e||0,t||10,r||"be"))}var a;"object"==typeof e?e.exports=o:t.BN=o,o.BN=o,o.wordSize=26;try{a=r(418).Buffer}catch(e){}function s(e,t,r){for(var n=0,i=Math.min(e.length,r),o=t;o=49&&a<=54?a-49+10:a>=17&&a<=22?a-17+10:15&a}return n}function c(e,t,r,n){for(var i=0,o=Math.min(e.length,r),a=t;a=49?s-49+10:s>=17?s-17+10:s}return i}o.isBN=function(e){return e instanceof o||null!==e&&"object"==typeof e&&e.constructor.wordSize===o.wordSize&&Array.isArray(e.words)},o.max=function(e,t){return e.cmp(t)>0?e:t},o.min=function(e,t){return e.cmp(t)<0?e:t},o.prototype._init=function(e,t,r){if("number"==typeof e)return this._initNumber(e,t,r);if("object"==typeof e)return this._initArray(e,t,r);"hex"===t&&(t=16),n(t===(0|t)&&t>=2&&t<=36);var i=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&i++,16===t?this._parseHex(e,i):this._parseBase(e,t,i),"-"===e[0]&&(this.negative=1),this.strip(),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initNumber=function(e,t,r){e<0&&(this.negative=1,e=-e),e<67108864?(this.words=[67108863&e],this.length=1):e<4503599627370496?(this.words=[67108863&e,e/67108864&67108863],this.length=2):(n(e<9007199254740992),this.words=[67108863&e,e/67108864&67108863,1],this.length=3),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initArray=function(e,t,r){if(n("number"==typeof e.length),e.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(e.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)a=e[i]|e[i-1]<<8|e[i-2]<<16,this.words[o]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);else if("le"===r)for(i=0,o=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);return this.strip()},o.prototype._parseHex=function(e,t){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var r=0;r=t;r-=6)i=s(e,r,r+6),this.words[n]|=i<>>26-o&4194303,(o+=24)>=26&&(o-=26,n++);r+6!==t&&(i=s(e,t,r+6),this.words[n]|=i<>>26-o&4194303),this.strip()},o.prototype._parseBase=function(e,t,r){this.words=[0],this.length=1;for(var n=0,i=1;i<=67108863;i*=t)n++;n--,i=i/t|0;for(var o=e.length-r,a=o%n,s=Math.min(o,o-a)+r,u=0,l=r;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},o.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},o.prototype.inspect=function(){return(this.red?""};var u=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],l=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function f(e,t,r){r.negative=t.negative^e.negative;var n=e.length+t.length|0;r.length=n,n=n-1|0;var i=0|e.words[0],o=0|t.words[0],a=i*o,s=67108863&a,c=a/67108864|0;r.words[0]=s;for(var u=1;u>>26,h=67108863&c,f=Math.min(u,t.length-1),d=Math.max(0,u-e.length+1);d<=f;d++){var p=u-d|0;l+=(a=(i=0|e.words[p])*(o=0|t.words[d])+h)/67108864|0,h=67108863&a}r.words[u]=0|h,c=0|l}return 0!==c?r.words[u]=0|c:r.length--,r.strip()}o.prototype.toString=function(e,t){var r;if(t=0|t||1,16===(e=e||10)||"hex"===e){r="";for(var i=0,o=0,a=0;a>>24-i&16777215)||a!==this.length-1?u[6-c.length]+c+r:c+r,(i+=2)>=26&&(i-=26,a--)}for(0!==o&&(r=o.toString(16)+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}if(e===(0|e)&&e>=2&&e<=36){var f=l[e],d=h[e];r="";var p=this.clone();for(p.negative=0;!p.isZero();){var m=p.modn(d).toString(e);r=(p=p.idivn(d)).isZero()?m+r:u[f-m.length]+m+r}for(this.isZero()&&(r="0"+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}n(!1,"Base should be between 2 and 36")},o.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&n(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},o.prototype.toJSON=function(){return this.toString(16)},o.prototype.toBuffer=function(e,t){return n(void 0!==a),this.toArrayLike(a,e,t)},o.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},o.prototype.toArrayLike=function(e,t,r){var i=this.byteLength(),o=r||Math.max(1,i);n(i<=o,"byte array longer than desired length"),n(o>0,"Requested array length <= 0"),this.strip();var a,s,c="le"===t,u=new e(o),l=this.clone();if(c){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),u[s]=a;for(;s=4096&&(r+=13,t>>>=13),t>=64&&(r+=7,t>>>=7),t>=8&&(r+=4,t>>>=4),t>=2&&(r+=2,t>>>=2),r+t},o.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,r=0;return 0==(8191&t)&&(r+=13,t>>>=13),0==(127&t)&&(r+=7,t>>>=7),0==(15&t)&&(r+=4,t>>>=4),0==(3&t)&&(r+=2,t>>>=2),0==(1&t)&&r++,r},o.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},o.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},o.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},o.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var r=0;re.length?this.clone().iand(e):e.clone().iand(this)},o.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},o.prototype.iuxor=function(e){var t,r;this.length>e.length?(t=this,r=e):(t=e,r=this);for(var n=0;ne.length?this.clone().ixor(e):e.clone().ixor(this)},o.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},o.prototype.inotn=function(e){n("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),r=e%26;this._expand(t),r>0&&t--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-r),this.strip()},o.prototype.notn=function(e){return this.clone().inotn(e)},o.prototype.setn=function(e,t){n("number"==typeof e&&e>=0);var r=e/26|0,i=e%26;return this._expand(r+1),this.words[r]=t?this.words[r]|1<e.length?(r=this,n=e):(r=e,n=this);for(var i=0,o=0;o>>26;for(;0!==i&&o>>26;if(this.length=r.length,0!==i)this.words[this.length]=i,this.length++;else if(r!==this)for(;oe.length?this.clone().iadd(e):e.clone().iadd(this)},o.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var r,n,i=this.cmp(e);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(r=this,n=e):(r=e,n=this);for(var o=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==o&&a>26,this.words[a]=67108863&t;if(0===o&&a>>13,d=0|a[1],p=8191&d,m=d>>>13,b=0|a[2],v=8191&b,g=b>>>13,y=0|a[3],w=8191&y,M=y>>>13,_=0|a[4],O=8191&_,k=_>>>13,E=0|a[5],S=8191&E,A=E>>>13,C=0|a[6],j=8191&C,z=C>>>13,x=0|a[7],D=8191&x,P=x>>>13,R=0|a[8],T=8191&R,F=R>>>13,N=0|a[9],I=8191&N,L=N>>>13,B=0|s[0],H=8191&B,q=B>>>13,V=0|s[1],U=8191&V,W=V>>>13,K=0|s[2],G=8191&K,X=K>>>13,Y=0|s[3],Z=8191&Y,$=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],re=8191&te,ne=te>>>13,ie=0|s[6],oe=8191&ie,ae=ie>>>13,se=0|s[7],ce=8191&se,ue=se>>>13,le=0|s[8],he=8191&le,fe=le>>>13,de=0|s[9],pe=8191&de,me=de>>>13;r.negative=e.negative^t.negative,r.length=19;var be=(u+(n=Math.imul(h,H))|0)+((8191&(i=(i=Math.imul(h,q))+Math.imul(f,H)|0))<<13)|0;u=((o=Math.imul(f,q))+(i>>>13)|0)+(be>>>26)|0,be&=67108863,n=Math.imul(p,H),i=(i=Math.imul(p,q))+Math.imul(m,H)|0,o=Math.imul(m,q);var ve=(u+(n=n+Math.imul(h,U)|0)|0)+((8191&(i=(i=i+Math.imul(h,W)|0)+Math.imul(f,U)|0))<<13)|0;u=((o=o+Math.imul(f,W)|0)+(i>>>13)|0)+(ve>>>26)|0,ve&=67108863,n=Math.imul(v,H),i=(i=Math.imul(v,q))+Math.imul(g,H)|0,o=Math.imul(g,q),n=n+Math.imul(p,U)|0,i=(i=i+Math.imul(p,W)|0)+Math.imul(m,U)|0,o=o+Math.imul(m,W)|0;var ge=(u+(n=n+Math.imul(h,G)|0)|0)+((8191&(i=(i=i+Math.imul(h,X)|0)+Math.imul(f,G)|0))<<13)|0;u=((o=o+Math.imul(f,X)|0)+(i>>>13)|0)+(ge>>>26)|0,ge&=67108863,n=Math.imul(w,H),i=(i=Math.imul(w,q))+Math.imul(M,H)|0,o=Math.imul(M,q),n=n+Math.imul(v,U)|0,i=(i=i+Math.imul(v,W)|0)+Math.imul(g,U)|0,o=o+Math.imul(g,W)|0,n=n+Math.imul(p,G)|0,i=(i=i+Math.imul(p,X)|0)+Math.imul(m,G)|0,o=o+Math.imul(m,X)|0;var ye=(u+(n=n+Math.imul(h,Z)|0)|0)+((8191&(i=(i=i+Math.imul(h,$)|0)+Math.imul(f,Z)|0))<<13)|0;u=((o=o+Math.imul(f,$)|0)+(i>>>13)|0)+(ye>>>26)|0,ye&=67108863,n=Math.imul(O,H),i=(i=Math.imul(O,q))+Math.imul(k,H)|0,o=Math.imul(k,q),n=n+Math.imul(w,U)|0,i=(i=i+Math.imul(w,W)|0)+Math.imul(M,U)|0,o=o+Math.imul(M,W)|0,n=n+Math.imul(v,G)|0,i=(i=i+Math.imul(v,X)|0)+Math.imul(g,G)|0,o=o+Math.imul(g,X)|0,n=n+Math.imul(p,Z)|0,i=(i=i+Math.imul(p,$)|0)+Math.imul(m,Z)|0,o=o+Math.imul(m,$)|0;var we=(u+(n=n+Math.imul(h,Q)|0)|0)+((8191&(i=(i=i+Math.imul(h,ee)|0)+Math.imul(f,Q)|0))<<13)|0;u=((o=o+Math.imul(f,ee)|0)+(i>>>13)|0)+(we>>>26)|0,we&=67108863,n=Math.imul(S,H),i=(i=Math.imul(S,q))+Math.imul(A,H)|0,o=Math.imul(A,q),n=n+Math.imul(O,U)|0,i=(i=i+Math.imul(O,W)|0)+Math.imul(k,U)|0,o=o+Math.imul(k,W)|0,n=n+Math.imul(w,G)|0,i=(i=i+Math.imul(w,X)|0)+Math.imul(M,G)|0,o=o+Math.imul(M,X)|0,n=n+Math.imul(v,Z)|0,i=(i=i+Math.imul(v,$)|0)+Math.imul(g,Z)|0,o=o+Math.imul(g,$)|0,n=n+Math.imul(p,Q)|0,i=(i=i+Math.imul(p,ee)|0)+Math.imul(m,Q)|0,o=o+Math.imul(m,ee)|0;var Me=(u+(n=n+Math.imul(h,re)|0)|0)+((8191&(i=(i=i+Math.imul(h,ne)|0)+Math.imul(f,re)|0))<<13)|0;u=((o=o+Math.imul(f,ne)|0)+(i>>>13)|0)+(Me>>>26)|0,Me&=67108863,n=Math.imul(j,H),i=(i=Math.imul(j,q))+Math.imul(z,H)|0,o=Math.imul(z,q),n=n+Math.imul(S,U)|0,i=(i=i+Math.imul(S,W)|0)+Math.imul(A,U)|0,o=o+Math.imul(A,W)|0,n=n+Math.imul(O,G)|0,i=(i=i+Math.imul(O,X)|0)+Math.imul(k,G)|0,o=o+Math.imul(k,X)|0,n=n+Math.imul(w,Z)|0,i=(i=i+Math.imul(w,$)|0)+Math.imul(M,Z)|0,o=o+Math.imul(M,$)|0,n=n+Math.imul(v,Q)|0,i=(i=i+Math.imul(v,ee)|0)+Math.imul(g,Q)|0,o=o+Math.imul(g,ee)|0,n=n+Math.imul(p,re)|0,i=(i=i+Math.imul(p,ne)|0)+Math.imul(m,re)|0,o=o+Math.imul(m,ne)|0;var _e=(u+(n=n+Math.imul(h,oe)|0)|0)+((8191&(i=(i=i+Math.imul(h,ae)|0)+Math.imul(f,oe)|0))<<13)|0;u=((o=o+Math.imul(f,ae)|0)+(i>>>13)|0)+(_e>>>26)|0,_e&=67108863,n=Math.imul(D,H),i=(i=Math.imul(D,q))+Math.imul(P,H)|0,o=Math.imul(P,q),n=n+Math.imul(j,U)|0,i=(i=i+Math.imul(j,W)|0)+Math.imul(z,U)|0,o=o+Math.imul(z,W)|0,n=n+Math.imul(S,G)|0,i=(i=i+Math.imul(S,X)|0)+Math.imul(A,G)|0,o=o+Math.imul(A,X)|0,n=n+Math.imul(O,Z)|0,i=(i=i+Math.imul(O,$)|0)+Math.imul(k,Z)|0,o=o+Math.imul(k,$)|0,n=n+Math.imul(w,Q)|0,i=(i=i+Math.imul(w,ee)|0)+Math.imul(M,Q)|0,o=o+Math.imul(M,ee)|0,n=n+Math.imul(v,re)|0,i=(i=i+Math.imul(v,ne)|0)+Math.imul(g,re)|0,o=o+Math.imul(g,ne)|0,n=n+Math.imul(p,oe)|0,i=(i=i+Math.imul(p,ae)|0)+Math.imul(m,oe)|0,o=o+Math.imul(m,ae)|0;var Oe=(u+(n=n+Math.imul(h,ce)|0)|0)+((8191&(i=(i=i+Math.imul(h,ue)|0)+Math.imul(f,ce)|0))<<13)|0;u=((o=o+Math.imul(f,ue)|0)+(i>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,n=Math.imul(T,H),i=(i=Math.imul(T,q))+Math.imul(F,H)|0,o=Math.imul(F,q),n=n+Math.imul(D,U)|0,i=(i=i+Math.imul(D,W)|0)+Math.imul(P,U)|0,o=o+Math.imul(P,W)|0,n=n+Math.imul(j,G)|0,i=(i=i+Math.imul(j,X)|0)+Math.imul(z,G)|0,o=o+Math.imul(z,X)|0,n=n+Math.imul(S,Z)|0,i=(i=i+Math.imul(S,$)|0)+Math.imul(A,Z)|0,o=o+Math.imul(A,$)|0,n=n+Math.imul(O,Q)|0,i=(i=i+Math.imul(O,ee)|0)+Math.imul(k,Q)|0,o=o+Math.imul(k,ee)|0,n=n+Math.imul(w,re)|0,i=(i=i+Math.imul(w,ne)|0)+Math.imul(M,re)|0,o=o+Math.imul(M,ne)|0,n=n+Math.imul(v,oe)|0,i=(i=i+Math.imul(v,ae)|0)+Math.imul(g,oe)|0,o=o+Math.imul(g,ae)|0,n=n+Math.imul(p,ce)|0,i=(i=i+Math.imul(p,ue)|0)+Math.imul(m,ce)|0,o=o+Math.imul(m,ue)|0;var ke=(u+(n=n+Math.imul(h,he)|0)|0)+((8191&(i=(i=i+Math.imul(h,fe)|0)+Math.imul(f,he)|0))<<13)|0;u=((o=o+Math.imul(f,fe)|0)+(i>>>13)|0)+(ke>>>26)|0,ke&=67108863,n=Math.imul(I,H),i=(i=Math.imul(I,q))+Math.imul(L,H)|0,o=Math.imul(L,q),n=n+Math.imul(T,U)|0,i=(i=i+Math.imul(T,W)|0)+Math.imul(F,U)|0,o=o+Math.imul(F,W)|0,n=n+Math.imul(D,G)|0,i=(i=i+Math.imul(D,X)|0)+Math.imul(P,G)|0,o=o+Math.imul(P,X)|0,n=n+Math.imul(j,Z)|0,i=(i=i+Math.imul(j,$)|0)+Math.imul(z,Z)|0,o=o+Math.imul(z,$)|0,n=n+Math.imul(S,Q)|0,i=(i=i+Math.imul(S,ee)|0)+Math.imul(A,Q)|0,o=o+Math.imul(A,ee)|0,n=n+Math.imul(O,re)|0,i=(i=i+Math.imul(O,ne)|0)+Math.imul(k,re)|0,o=o+Math.imul(k,ne)|0,n=n+Math.imul(w,oe)|0,i=(i=i+Math.imul(w,ae)|0)+Math.imul(M,oe)|0,o=o+Math.imul(M,ae)|0,n=n+Math.imul(v,ce)|0,i=(i=i+Math.imul(v,ue)|0)+Math.imul(g,ce)|0,o=o+Math.imul(g,ue)|0,n=n+Math.imul(p,he)|0,i=(i=i+Math.imul(p,fe)|0)+Math.imul(m,he)|0,o=o+Math.imul(m,fe)|0;var Ee=(u+(n=n+Math.imul(h,pe)|0)|0)+((8191&(i=(i=i+Math.imul(h,me)|0)+Math.imul(f,pe)|0))<<13)|0;u=((o=o+Math.imul(f,me)|0)+(i>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,n=Math.imul(I,U),i=(i=Math.imul(I,W))+Math.imul(L,U)|0,o=Math.imul(L,W),n=n+Math.imul(T,G)|0,i=(i=i+Math.imul(T,X)|0)+Math.imul(F,G)|0,o=o+Math.imul(F,X)|0,n=n+Math.imul(D,Z)|0,i=(i=i+Math.imul(D,$)|0)+Math.imul(P,Z)|0,o=o+Math.imul(P,$)|0,n=n+Math.imul(j,Q)|0,i=(i=i+Math.imul(j,ee)|0)+Math.imul(z,Q)|0,o=o+Math.imul(z,ee)|0,n=n+Math.imul(S,re)|0,i=(i=i+Math.imul(S,ne)|0)+Math.imul(A,re)|0,o=o+Math.imul(A,ne)|0,n=n+Math.imul(O,oe)|0,i=(i=i+Math.imul(O,ae)|0)+Math.imul(k,oe)|0,o=o+Math.imul(k,ae)|0,n=n+Math.imul(w,ce)|0,i=(i=i+Math.imul(w,ue)|0)+Math.imul(M,ce)|0,o=o+Math.imul(M,ue)|0,n=n+Math.imul(v,he)|0,i=(i=i+Math.imul(v,fe)|0)+Math.imul(g,he)|0,o=o+Math.imul(g,fe)|0;var Se=(u+(n=n+Math.imul(p,pe)|0)|0)+((8191&(i=(i=i+Math.imul(p,me)|0)+Math.imul(m,pe)|0))<<13)|0;u=((o=o+Math.imul(m,me)|0)+(i>>>13)|0)+(Se>>>26)|0,Se&=67108863,n=Math.imul(I,G),i=(i=Math.imul(I,X))+Math.imul(L,G)|0,o=Math.imul(L,X),n=n+Math.imul(T,Z)|0,i=(i=i+Math.imul(T,$)|0)+Math.imul(F,Z)|0,o=o+Math.imul(F,$)|0,n=n+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,ee)|0)+Math.imul(P,Q)|0,o=o+Math.imul(P,ee)|0,n=n+Math.imul(j,re)|0,i=(i=i+Math.imul(j,ne)|0)+Math.imul(z,re)|0,o=o+Math.imul(z,ne)|0,n=n+Math.imul(S,oe)|0,i=(i=i+Math.imul(S,ae)|0)+Math.imul(A,oe)|0,o=o+Math.imul(A,ae)|0,n=n+Math.imul(O,ce)|0,i=(i=i+Math.imul(O,ue)|0)+Math.imul(k,ce)|0,o=o+Math.imul(k,ue)|0,n=n+Math.imul(w,he)|0,i=(i=i+Math.imul(w,fe)|0)+Math.imul(M,he)|0,o=o+Math.imul(M,fe)|0;var Ae=(u+(n=n+Math.imul(v,pe)|0)|0)+((8191&(i=(i=i+Math.imul(v,me)|0)+Math.imul(g,pe)|0))<<13)|0;u=((o=o+Math.imul(g,me)|0)+(i>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,n=Math.imul(I,Z),i=(i=Math.imul(I,$))+Math.imul(L,Z)|0,o=Math.imul(L,$),n=n+Math.imul(T,Q)|0,i=(i=i+Math.imul(T,ee)|0)+Math.imul(F,Q)|0,o=o+Math.imul(F,ee)|0,n=n+Math.imul(D,re)|0,i=(i=i+Math.imul(D,ne)|0)+Math.imul(P,re)|0,o=o+Math.imul(P,ne)|0,n=n+Math.imul(j,oe)|0,i=(i=i+Math.imul(j,ae)|0)+Math.imul(z,oe)|0,o=o+Math.imul(z,ae)|0,n=n+Math.imul(S,ce)|0,i=(i=i+Math.imul(S,ue)|0)+Math.imul(A,ce)|0,o=o+Math.imul(A,ue)|0,n=n+Math.imul(O,he)|0,i=(i=i+Math.imul(O,fe)|0)+Math.imul(k,he)|0,o=o+Math.imul(k,fe)|0;var Ce=(u+(n=n+Math.imul(w,pe)|0)|0)+((8191&(i=(i=i+Math.imul(w,me)|0)+Math.imul(M,pe)|0))<<13)|0;u=((o=o+Math.imul(M,me)|0)+(i>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,n=Math.imul(I,Q),i=(i=Math.imul(I,ee))+Math.imul(L,Q)|0,o=Math.imul(L,ee),n=n+Math.imul(T,re)|0,i=(i=i+Math.imul(T,ne)|0)+Math.imul(F,re)|0,o=o+Math.imul(F,ne)|0,n=n+Math.imul(D,oe)|0,i=(i=i+Math.imul(D,ae)|0)+Math.imul(P,oe)|0,o=o+Math.imul(P,ae)|0,n=n+Math.imul(j,ce)|0,i=(i=i+Math.imul(j,ue)|0)+Math.imul(z,ce)|0,o=o+Math.imul(z,ue)|0,n=n+Math.imul(S,he)|0,i=(i=i+Math.imul(S,fe)|0)+Math.imul(A,he)|0,o=o+Math.imul(A,fe)|0;var je=(u+(n=n+Math.imul(O,pe)|0)|0)+((8191&(i=(i=i+Math.imul(O,me)|0)+Math.imul(k,pe)|0))<<13)|0;u=((o=o+Math.imul(k,me)|0)+(i>>>13)|0)+(je>>>26)|0,je&=67108863,n=Math.imul(I,re),i=(i=Math.imul(I,ne))+Math.imul(L,re)|0,o=Math.imul(L,ne),n=n+Math.imul(T,oe)|0,i=(i=i+Math.imul(T,ae)|0)+Math.imul(F,oe)|0,o=o+Math.imul(F,ae)|0,n=n+Math.imul(D,ce)|0,i=(i=i+Math.imul(D,ue)|0)+Math.imul(P,ce)|0,o=o+Math.imul(P,ue)|0,n=n+Math.imul(j,he)|0,i=(i=i+Math.imul(j,fe)|0)+Math.imul(z,he)|0,o=o+Math.imul(z,fe)|0;var ze=(u+(n=n+Math.imul(S,pe)|0)|0)+((8191&(i=(i=i+Math.imul(S,me)|0)+Math.imul(A,pe)|0))<<13)|0;u=((o=o+Math.imul(A,me)|0)+(i>>>13)|0)+(ze>>>26)|0,ze&=67108863,n=Math.imul(I,oe),i=(i=Math.imul(I,ae))+Math.imul(L,oe)|0,o=Math.imul(L,ae),n=n+Math.imul(T,ce)|0,i=(i=i+Math.imul(T,ue)|0)+Math.imul(F,ce)|0,o=o+Math.imul(F,ue)|0,n=n+Math.imul(D,he)|0,i=(i=i+Math.imul(D,fe)|0)+Math.imul(P,he)|0,o=o+Math.imul(P,fe)|0;var xe=(u+(n=n+Math.imul(j,pe)|0)|0)+((8191&(i=(i=i+Math.imul(j,me)|0)+Math.imul(z,pe)|0))<<13)|0;u=((o=o+Math.imul(z,me)|0)+(i>>>13)|0)+(xe>>>26)|0,xe&=67108863,n=Math.imul(I,ce),i=(i=Math.imul(I,ue))+Math.imul(L,ce)|0,o=Math.imul(L,ue),n=n+Math.imul(T,he)|0,i=(i=i+Math.imul(T,fe)|0)+Math.imul(F,he)|0,o=o+Math.imul(F,fe)|0;var De=(u+(n=n+Math.imul(D,pe)|0)|0)+((8191&(i=(i=i+Math.imul(D,me)|0)+Math.imul(P,pe)|0))<<13)|0;u=((o=o+Math.imul(P,me)|0)+(i>>>13)|0)+(De>>>26)|0,De&=67108863,n=Math.imul(I,he),i=(i=Math.imul(I,fe))+Math.imul(L,he)|0,o=Math.imul(L,fe);var Pe=(u+(n=n+Math.imul(T,pe)|0)|0)+((8191&(i=(i=i+Math.imul(T,me)|0)+Math.imul(F,pe)|0))<<13)|0;u=((o=o+Math.imul(F,me)|0)+(i>>>13)|0)+(Pe>>>26)|0,Pe&=67108863;var Re=(u+(n=Math.imul(I,pe))|0)+((8191&(i=(i=Math.imul(I,me))+Math.imul(L,pe)|0))<<13)|0;return u=((o=Math.imul(L,me))+(i>>>13)|0)+(Re>>>26)|0,Re&=67108863,c[0]=be,c[1]=ve,c[2]=ge,c[3]=ye,c[4]=we,c[5]=Me,c[6]=_e,c[7]=Oe,c[8]=ke,c[9]=Ee,c[10]=Se,c[11]=Ae,c[12]=Ce,c[13]=je,c[14]=ze,c[15]=xe,c[16]=De,c[17]=Pe,c[18]=Re,0!==u&&(c[19]=u,r.length++),r};function p(e,t,r){return(new m).mulp(e,t,r)}function m(e,t){this.x=e,this.y=t}Math.imul||(d=f),o.prototype.mulTo=function(e,t){var r=this.length+e.length;return 10===this.length&&10===e.length?d(this,e,t):r<63?f(this,e,t):r<1024?function(e,t,r){r.negative=t.negative^e.negative,r.length=e.length+t.length;for(var n=0,i=0,o=0;o>>26)|0)>>>26,a&=67108863}r.words[o]=s,n=a,a=i}return 0!==n?r.words[o]=n:r.length--,r.strip()}(this,e,t):p(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),r=o.prototype._countBits(e)-1,n=0;n>=1;return n},m.prototype.permute=function(e,t,r,n,i,o){for(var a=0;a>>=1)i++;return 1<>>=13,r[2*a+1]=8191&o,o>>>=13;for(a=2*t;a>=26,t+=i/67108864|0,t+=o>>>26,this.words[r]=67108863&o}return 0!==t&&(this.words[r]=t,this.length++),this},o.prototype.muln=function(e){return this.clone().imuln(e)},o.prototype.sqr=function(){return this.mul(this)},o.prototype.isqr=function(){return this.imul(this.clone())},o.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),r=0;r>>i}return t}(e);if(0===t.length)return new o(1);for(var r=this,n=0;n=0);var t,r=e%26,i=(e-r)/26,o=67108863>>>26-r<<26-r;if(0!==r){var a=0;for(t=0;t>>26-r}a&&(this.words[t]=a,this.length++)}if(0!==i){for(t=this.length-1;t>=0;t--)this.words[t+i]=this.words[t];for(t=0;t=0),i=t?(t-t%26)/26:0;var o=e%26,a=Math.min((e-o)/26,this.length),s=67108863^67108863>>>o<a)for(this.length-=a,u=0;u=0&&(0!==l||u>=i);u--){var h=0|this.words[u];this.words[u]=l<<26-o|h>>>o,l=h&s}return c&&0!==l&&(c.words[c.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},o.prototype.ishrn=function(e,t,r){return n(0===this.negative),this.iushrn(e,t,r)},o.prototype.shln=function(e){return this.clone().ishln(e)},o.prototype.ushln=function(e){return this.clone().iushln(e)},o.prototype.shrn=function(e){return this.clone().ishrn(e)},o.prototype.ushrn=function(e){return this.clone().iushrn(e)},o.prototype.testn=function(e){n("number"==typeof e&&e>=0);var t=e%26,r=(e-t)/26,i=1<=0);var t=e%26,r=(e-t)/26;if(n(0===this.negative,"imaskn works only with positive numbers"),this.length<=r)return this;if(0!==t&&r++,this.length=Math.min(r,this.length),0!==t){var i=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},o.prototype.isubn=function(e){if(n("number"==typeof e),n(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(c/67108864|0),this.words[i+r]=67108863&o}for(;i>26,this.words[i+r]=67108863&o;if(0===s)return this.strip();for(n(-1===s),s=0,i=0;i>26,this.words[i]=67108863&o;return this.negative=1,this.strip()},o.prototype._wordDiv=function(e,t){var r=(this.length,e.length),n=this.clone(),i=e,a=0|i.words[i.length-1];0!==(r=26-this._countBits(a))&&(i=i.ushln(r),n.iushln(r),a=0|i.words[i.length-1]);var s,c=n.length-i.length;if("mod"!==t){(s=new o(null)).length=c+1,s.words=new Array(s.length);for(var u=0;u=0;h--){var f=67108864*(0|n.words[i.length+h])+(0|n.words[i.length+h-1]);for(f=Math.min(f/a|0,67108863),n._ishlnsubmul(i,f,h);0!==n.negative;)f--,n.negative=0,n._ishlnsubmul(i,1,h),n.isZero()||(n.negative^=1);s&&(s.words[h]=f)}return s&&s.strip(),n.strip(),"div"!==t&&0!==r&&n.iushrn(r),{div:s||null,mod:n}},o.prototype.divmod=function(e,t,r){return n(!e.isZero()),this.isZero()?{div:new o(0),mod:new o(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(i=s.div.neg()),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.iadd(e)),{div:i,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new o(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new o(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new o(this.modn(e.words[0]))}:this._wordDiv(e,t);var i,a,s},o.prototype.div=function(e){return this.divmod(e,"div",!1).div},o.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},o.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},o.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var r=0!==t.div.negative?t.mod.isub(e):t.mod,n=e.ushrn(1),i=e.andln(1),o=r.cmp(n);return o<0||1===i&&0===o?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},o.prototype.modn=function(e){n(e<=67108863);for(var t=(1<<26)%e,r=0,i=this.length-1;i>=0;i--)r=(t*r+(0|this.words[i]))%e;return r},o.prototype.idivn=function(e){n(e<=67108863);for(var t=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*t;this.words[r]=i/e|0,t=i%e}return this.strip()},o.prototype.divn=function(e){return this.clone().idivn(e)},o.prototype.egcd=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i=new o(1),a=new o(0),s=new o(0),c=new o(1),u=0;t.isEven()&&r.isEven();)t.iushrn(1),r.iushrn(1),++u;for(var l=r.clone(),h=t.clone();!t.isZero();){for(var f=0,d=1;0==(t.words[0]&d)&&f<26;++f,d<<=1);if(f>0)for(t.iushrn(f);f-- >0;)(i.isOdd()||a.isOdd())&&(i.iadd(l),a.isub(h)),i.iushrn(1),a.iushrn(1);for(var p=0,m=1;0==(r.words[0]&m)&&p<26;++p,m<<=1);if(p>0)for(r.iushrn(p);p-- >0;)(s.isOdd()||c.isOdd())&&(s.iadd(l),c.isub(h)),s.iushrn(1),c.iushrn(1);t.cmp(r)>=0?(t.isub(r),i.isub(s),a.isub(c)):(r.isub(t),s.isub(i),c.isub(a))}return{a:s,b:c,gcd:r.iushln(u)}},o.prototype._invmp=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i,a=new o(1),s=new o(0),c=r.clone();t.cmpn(1)>0&&r.cmpn(1)>0;){for(var u=0,l=1;0==(t.words[0]&l)&&u<26;++u,l<<=1);if(u>0)for(t.iushrn(u);u-- >0;)a.isOdd()&&a.iadd(c),a.iushrn(1);for(var h=0,f=1;0==(r.words[0]&f)&&h<26;++h,f<<=1);if(h>0)for(r.iushrn(h);h-- >0;)s.isOdd()&&s.iadd(c),s.iushrn(1);t.cmp(r)>=0?(t.isub(r),a.isub(s)):(r.isub(t),s.isub(a))}return(i=0===t.cmpn(1)?a:s).cmpn(0)<0&&i.iadd(e),i},o.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),r=e.clone();t.negative=0,r.negative=0;for(var n=0;t.isEven()&&r.isEven();n++)t.iushrn(1),r.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;r.isEven();)r.iushrn(1);var i=t.cmp(r);if(i<0){var o=t;t=r,r=o}else if(0===i||0===r.cmpn(1))break;t.isub(r)}return r.iushln(n)},o.prototype.invm=function(e){return this.egcd(e).a.umod(e)},o.prototype.isEven=function(){return 0==(1&this.words[0])},o.prototype.isOdd=function(){return 1==(1&this.words[0])},o.prototype.andln=function(e){return this.words[0]&e},o.prototype.bincn=function(e){n("number"==typeof e);var t=e%26,r=(e-t)/26,i=1<>>26,s&=67108863,this.words[a]=s}return 0!==o&&(this.words[a]=o,this.length++),this},o.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},o.prototype.cmpn=function(e){var t,r=e<0;if(0!==this.negative&&!r)return-1;if(0===this.negative&&r)return 1;if(this.strip(),this.length>1)t=1;else{r&&(e=-e),n(e<=67108863,"Number is too big");var i=0|this.words[0];t=i===e?0:ie.length)return 1;if(this.length=0;r--){var n=0|this.words[r],i=0|e.words[r];if(n!==i){ni&&(t=1);break}}return t},o.prototype.gtn=function(e){return 1===this.cmpn(e)},o.prototype.gt=function(e){return 1===this.cmp(e)},o.prototype.gten=function(e){return this.cmpn(e)>=0},o.prototype.gte=function(e){return this.cmp(e)>=0},o.prototype.ltn=function(e){return-1===this.cmpn(e)},o.prototype.lt=function(e){return-1===this.cmp(e)},o.prototype.lten=function(e){return this.cmpn(e)<=0},o.prototype.lte=function(e){return this.cmp(e)<=0},o.prototype.eqn=function(e){return 0===this.cmpn(e)},o.prototype.eq=function(e){return 0===this.cmp(e)},o.red=function(e){return new _(e)},o.prototype.toRed=function(e){return n(!this.red,"Already a number in reduction context"),n(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},o.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},o.prototype._forceRed=function(e){return this.red=e,this},o.prototype.forceRed=function(e){return n(!this.red,"Already a number in reduction context"),this._forceRed(e)},o.prototype.redAdd=function(e){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},o.prototype.redIAdd=function(e){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},o.prototype.redSub=function(e){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},o.prototype.redISub=function(e){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},o.prototype.redShl=function(e){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},o.prototype.redMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},o.prototype.redIMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},o.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},o.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},o.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},o.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},o.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},o.prototype.redPow=function(e){return n(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var b={k256:null,p224:null,p192:null,p25519:null};function v(e,t){this.name=e,this.p=new o(t,16),this.n=this.p.bitLength(),this.k=new o(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function g(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function y(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function w(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function M(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function _(e){if("string"==typeof e){var t=o._prime(e);this.m=t.p,this.prime=t}else n(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function O(e){_.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new o(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var e=new o(null);return e.words=new Array(Math.ceil(this.n/13)),e},v.prototype.ireduce=function(e){var t,r=e;do{this.split(r,this.tmp),t=(r=(r=this.imulK(r)).iadd(this.tmp)).bitLength()}while(t>this.n);var n=t0?r.isub(this.p):void 0!==r.strip?r.strip():r._strip(),r},v.prototype.split=function(e,t){e.iushrn(this.n,0,t)},v.prototype.imulK=function(e){return e.imul(this.k)},i(g,v),g.prototype.split=function(e,t){for(var r=Math.min(e.length,9),n=0;n>>22,i=o}i>>>=22,e.words[n-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},g.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,r=0;r>>=26,e.words[r]=i,t=n}return 0!==t&&(e.words[e.length++]=t),e},o._prime=function(e){if(b[e])return b[e];var t;if("k256"===e)t=new g;else if("p224"===e)t=new y;else if("p192"===e)t=new w;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new M}return b[e]=t,t},_.prototype._verify1=function(e){n(0===e.negative,"red works only with positives"),n(e.red,"red works only with red numbers")},_.prototype._verify2=function(e,t){n(0==(e.negative|t.negative),"red works only with positives"),n(e.red&&e.red===t.red,"red works only with red numbers")},_.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},_.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},_.prototype.add=function(e,t){this._verify2(e,t);var r=e.add(t);return r.cmp(this.m)>=0&&r.isub(this.m),r._forceRed(this)},_.prototype.iadd=function(e,t){this._verify2(e,t);var r=e.iadd(t);return r.cmp(this.m)>=0&&r.isub(this.m),r},_.prototype.sub=function(e,t){this._verify2(e,t);var r=e.sub(t);return r.cmpn(0)<0&&r.iadd(this.m),r._forceRed(this)},_.prototype.isub=function(e,t){this._verify2(e,t);var r=e.isub(t);return r.cmpn(0)<0&&r.iadd(this.m),r},_.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},_.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},_.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},_.prototype.isqr=function(e){return this.imul(e,e.clone())},_.prototype.sqr=function(e){return this.mul(e,e)},_.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(n(t%2==1),3===t){var r=this.m.add(new o(1)).iushrn(2);return this.pow(e,r)}for(var i=this.m.subn(1),a=0;!i.isZero()&&0===i.andln(1);)a++,i.iushrn(1);n(!i.isZero());var s=new o(1).toRed(this),c=s.redNeg(),u=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new o(2*l*l).toRed(this);0!==this.pow(l,u).cmp(c);)l.redIAdd(c);for(var h=this.pow(l,i),f=this.pow(e,i.addn(1).iushrn(1)),d=this.pow(e,i),p=a;0!==d.cmp(s);){for(var m=d,b=0;0!==m.cmp(s);b++)m=m.redSqr();n(b=0;n--){for(var u=t.words[n],l=c-1;l>=0;l--){var h=u>>l&1;i!==r[0]&&(i=this.sqr(i)),0!==h||0!==a?(a<<=1,a|=h,(4===++s||0===n&&0===l)&&(i=this.mul(i,r[a]),s=0,a=0)):s=0}c=26}return i},_.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},_.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},o.mont=function(e){return new O(e)},i(O,_),O.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},O.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},O.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var r=e.imul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},O.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new o(0)._forceRed(this);var r=e.mul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},O.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e,this)}).call(this,r(80)(e))},function(e,t,r){"use strict";const n=t;n.der=r(270),n.pem=r(420)},function(e,t,r){"use strict";const n=r(25),i=r(184).Buffer,o=r(185),a=r(187);function s(e){this.enc="der",this.name=e.name,this.entity=e,this.tree=new c,this.tree._init(e.body)}function c(e){o.call(this,"der",e)}function u(e){return e<10?"0"+e:e}e.exports=s,s.prototype.encode=function(e,t){return this.tree._encode(e,t).join()},n(c,o),c.prototype._encodeComposite=function(e,t,r,n){const o=function(e,t,r,n){let i;"seqof"===e?e="seq":"setof"===e&&(e="set");if(a.tagByName.hasOwnProperty(e))i=a.tagByName[e];else{if("number"!=typeof e||(0|e)!==e)return n.error("Unknown tag: "+e);i=e}if(i>=31)return n.error("Multi-octet tag encoding unsupported");t||(i|=32);return i|=a.tagClassByName[r||"universal"]<<6,i}(e,t,r,this.reporter);if(n.length<128){const e=i.alloc(2);return e[0]=o,e[1]=n.length,this._createEncoderBuffer([e,n])}let s=1;for(let e=n.length;e>=256;e>>=8)s++;const c=i.alloc(2+s);c[0]=o,c[1]=128|s;for(let e=1+s,t=n.length;t>0;e--,t>>=8)c[e]=255&t;return this._createEncoderBuffer([c,n])},c.prototype._encodeStr=function(e,t){if("bitstr"===t)return this._createEncoderBuffer([0|e.unused,e.data]);if("bmpstr"===t){const t=i.alloc(2*e.length);for(let r=0;r=40)return this.reporter.error("Second objid identifier OOB");e.splice(0,2,40*e[0]+e[1])}let n=0;for(let t=0;t=128;r>>=7)n++}const o=i.alloc(n);let a=o.length-1;for(let t=e.length-1;t>=0;t--){let r=e[t];for(o[a--]=127&r;(r>>=7)>0;)o[a--]=128|127&r}return this._createEncoderBuffer(o)},c.prototype._encodeTime=function(e,t){let r;const n=new Date(e);return"gentime"===t?r=[u(n.getUTCFullYear()),u(n.getUTCMonth()+1),u(n.getUTCDate()),u(n.getUTCHours()),u(n.getUTCMinutes()),u(n.getUTCSeconds()),"Z"].join(""):"utctime"===t?r=[u(n.getUTCFullYear()%100),u(n.getUTCMonth()+1),u(n.getUTCDate()),u(n.getUTCHours()),u(n.getUTCMinutes()),u(n.getUTCSeconds()),"Z"].join(""):this.reporter.error("Encoding "+t+" time is not supported yet"),this._encodeStr(r,"octstr")},c.prototype._encodeNull=function(){return this._createEncoderBuffer("")},c.prototype._encodeInt=function(e,t){if("string"==typeof e){if(!t)return this.reporter.error("String int or enum given, but no values map");if(!t.hasOwnProperty(e))return this.reporter.error("Values map doesn't contain: "+JSON.stringify(e));e=t[e]}if("number"!=typeof e&&!i.isBuffer(e)){const t=e.toArray();!e.sign&&128&t[0]&&t.unshift(0),e=i.from(t)}if(i.isBuffer(e)){let t=e.length;0===e.length&&t++;const r=i.alloc(t);return e.copy(r),0===e.length&&(r[0]=0),this._createEncoderBuffer(r)}if(e<128)return this._createEncoderBuffer(e);if(e<256)return this._createEncoderBuffer([0,e]);let r=1;for(let t=e;t>=256;t>>=8)r++;const n=new Array(r);for(let t=n.length-1;t>=0;t--)n[t]=255&e,e>>=8;return 128&n[0]&&n.unshift(0),this._createEncoderBuffer(i.from(n))},c.prototype._encodeBool=function(e){return this._createEncoderBuffer(e?255:0)},c.prototype._use=function(e,t){return"function"==typeof e&&(e=e(t)),e._getEncoder("der").tree},c.prototype._skipDefault=function(e,t,r){const n=this._baseState;let i;if(null===n.default)return!1;const o=e.join();if(void 0===n.defaultBuffer&&(n.defaultBuffer=this._encodeValue(n.default,t,r).join()),o.length!==n.defaultBuffer.length)return!1;for(i=0;i>6],i=0==(32&r);if(31==(31&r)){let n=r;for(r=0;128==(128&n);){if(n=e.readUInt8(t),e.isError(n))return n;r<<=7,r|=127&n}}else r&=31;return{cls:n,primitive:i,tag:r,tagStr:s.tag[r]}}function h(e,t,r){let n=e.readUInt8(r);if(e.isError(n))return n;if(!t&&128===n)return null;if(0==(128&n))return n;const i=127&n;if(i>4)return e.error("length octect is too long");n=0;for(let t=0;t=0||(i[r]=e[r]);return i}},function(e,t,r){"use strict";e.exports=r(307)},function(e,t,r){"use strict";(function(t){var n=t.Symbol,i=r(454);e.exports=function(){return"function"==typeof n&&("function"==typeof Symbol&&("symbol"==typeof n("foo")&&("symbol"==typeof Symbol("bar")&&i())))}}).call(this,r(46))},function(e,t){var r=/^\[object .+?Constructor\]$/;function n(e){return!!e&&"object"==typeof e}var i,o,a,s=Object.prototype,c=Function.prototype.toString,u=s.hasOwnProperty,l=s.toString,h=RegExp("^"+c.call(u).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),f=(o="isArray",function(e){return null!=e&&(function(e){return function(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}(e)&&"[object Function]"==l.call(e)}(e)?h.test(c.call(e)):n(e)&&r.test(e))}(a=null==(i=Array)?void 0:i[o])?a:void 0);var d=f||function(e){return n(e)&&function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}(e.length)&&"[object Array]"==l.call(e)};e.exports=d},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t){e.exports={}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){return!(!n.default.isMoment(e)||!n.default.isMoment(t))&&(!(0,i.default)(e,t)&&!(0,o.default)(e,t))};var n=a(r(16)),i=a(r(218)),o=a(r(204));function a(e){return e&&e.__esModule?e:{default:e}}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var r=n.default.isMoment(e)?e:(0,i.default)(e,t);return r?r.format(o.ISO_MONTH_FORMAT):null};var n=a(r(16)),i=a(r(205)),o=r(52);function a(e){return e&&e.__esModule?e:{default:e}}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var r=n.default.isMoment(e)?e:(0,i.default)(e,t);return r?r.format(o.ISO_FORMAT):null};var n=a(r(16)),i=a(r(205)),o=r(52);function a(e){return e&&e.__esModule?e:{default:e}}},function(e,t,r){"use strict";r.r(t),r.d(t,"addEventListener",(function(){return c}));var n=!("undefined"==typeof window||!window.document||!window.document.createElement);var i=void 0;function o(){return void 0===i&&(i=function(){if(!n)return!1;if(!window.addEventListener||!window.removeEventListener||!Object.defineProperty)return!1;var e=!1;try{var t=Object.defineProperty({},"passive",{get:function(){e=!0}}),r=function(){};window.addEventListener("testPassiveEventSupport",r,t),window.removeEventListener("testPassiveEventSupport",r,t)}catch(e){}return e}()),i}function a(e){e.handlers===e.nextHandlers&&(e.nextHandlers=e.handlers.slice())}function s(e){this.target=e,this.events={}}s.prototype.getEventHandlers=function(e,t){var r,n=String(e)+" "+String((r=t)?!0===r?100:(r.capture<<0)+(r.passive<<1)+(r.once<<2):0);return this.events[n]||(this.events[n]={handlers:[],handleEvent:void 0},this.events[n].nextHandlers=this.events[n].handlers),this.events[n]},s.prototype.handleEvent=function(e,t,r){var n=this.getEventHandlers(e,t);n.handlers=n.nextHandlers,n.handlers.forEach((function(e){e&&e(r)}))},s.prototype.add=function(e,t,r){var n=this,i=this.getEventHandlers(e,r);a(i),0===i.nextHandlers.length&&(i.handleEvent=this.handleEvent.bind(this,e,r),this.target.addEventListener(e,i.handleEvent,r)),i.nextHandlers.push(t);var o=!0;return function(){if(o){o=!1,a(i);var s=i.nextHandlers.indexOf(t);i.nextHandlers.splice(s,1),0===i.nextHandlers.length&&(n.target&&n.target.removeEventListener(e,i.handleEvent,r),i.handleEvent=void 0)}}};function c(e,t,r,n){e.__consolidated_events_handlers__||(e.__consolidated_events_handlers__=new s(e));var i=function(e){if(e)return o()?e:!!e.capture}(n);return e.__consolidated_events_handlers__.add(t,r,i)}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,i=r(1),o=(n=i)&&n.__esModule?n:{default:n},a=r(69);function s(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e){if(Array.isArray(e)){for(var t=0,r=Array(e.length);t2?r-2:0),i=2;i0&&this.setState({visibleDays:(0,o.default)({},O,x)})}},{key:"componentWillUpdate",value:function(){this.today=(0,l.default)()}},{key:"onDayClick",value:function(e,t){if(t&&t.preventDefault(),!this.isBlocked(e)){var r=this.props,n=r.onDateChange,i=r.keepOpenOnDateSelect,o=r.onFocusChange,a=r.onClose;n(e),i||(o({focused:!1}),a({date:e}))}}},{key:"onDayMouseEnter",value:function(e){if(!this.isTouchDevice){var t=this.state,r=t.hoverDate,n=t.visibleDays,i=this.deleteModifier({},r,"hovered");i=this.addModifier(i,e,"hovered"),this.setState({hoverDate:e,visibleDays:(0,o.default)({},n,i)})}}},{key:"onDayMouseLeave",value:function(){var e=this.state,t=e.hoverDate,r=e.visibleDays;if(!this.isTouchDevice&&t){var n=this.deleteModifier({},t,"hovered");this.setState({hoverDate:null,visibleDays:(0,o.default)({},r,n)})}}},{key:"onPrevMonthClick",value:function(){var e=this.props,t=e.onPrevMonthClick,r=e.numberOfMonths,n=e.enableOutsideDays,i=this.state,a=i.currentMonth,s=i.visibleDays,c={};Object.keys(s).sort().slice(0,r+1).forEach((function(e){c[e]=s[e]}));var u=a.clone().subtract(1,"month"),l=(0,v.default)(u,1,n);this.setState({currentMonth:u,visibleDays:(0,o.default)({},c,this.getModifiers(l))},(function(){t(u.clone())}))}},{key:"onNextMonthClick",value:function(){var e=this.props,t=e.onNextMonthClick,r=e.numberOfMonths,n=e.enableOutsideDays,i=this.state,a=i.currentMonth,s=i.visibleDays,c={};Object.keys(s).sort().slice(1).forEach((function(e){c[e]=s[e]}));var u=a.clone().add(r,"month"),l=(0,v.default)(u,1,n),h=a.clone().add(1,"month");this.setState({currentMonth:h,visibleDays:(0,o.default)({},c,this.getModifiers(l))},(function(){t(h.clone())}))}},{key:"onMonthChange",value:function(e){var t=this.props,r=t.numberOfMonths,n=t.enableOutsideDays,i=t.orientation===k.VERTICAL_SCROLLABLE,o=(0,v.default)(e,r,n,i);this.setState({currentMonth:e.clone(),visibleDays:this.getModifiers(o)})}},{key:"onYearChange",value:function(e){var t=this.props,r=t.numberOfMonths,n=t.enableOutsideDays,i=t.orientation===k.VERTICAL_SCROLLABLE,o=(0,v.default)(e,r,n,i);this.setState({currentMonth:e.clone(),visibleDays:this.getModifiers(o)})}},{key:"getFirstFocusableDay",value:function(e){var t=this,r=this.props,i=r.date,o=r.numberOfMonths,a=e.clone().startOf("month");if(i&&(a=i.clone()),this.isBlocked(a)){for(var s=[],c=e.clone().add(o-1,"months").endOf("month"),u=a.clone();!(0,b.default)(u,c);)u=u.clone().add(1,"day"),s.push(u);var l=s.filter((function(e){return!t.isBlocked(e)&&(0,b.default)(e,a)}));if(l.length>0){var h=n(l,1);a=h[0]}}return a}},{key:"getModifiers",value:function(e){var t=this,r={};return Object.keys(e).forEach((function(n){r[n]={},e[n].forEach((function(e){r[n][(0,y.default)(e)]=t.getModifiersForDay(e)}))})),r}},{key:"getModifiersForDay",value:function(e){var t=this;return new Set(Object.keys(this.modifiers).filter((function(r){return t.modifiers[r](e)})))}},{key:"getStateForNewMonth",value:function(e){var t=this,r=e.initialVisibleMonth,n=e.date,i=e.numberOfMonths,o=e.enableOutsideDays,a=(r||(n?function(){return n}:function(){return t.today}))();return{currentMonth:a,visibleDays:this.getModifiers((0,v.default)(a,i,o))}}},{key:"addModifier",value:function(e,t,r){var n=this.props,i=n.numberOfMonths,a=n.enableOutsideDays,s=n.orientation,c=this.state,u=c.currentMonth,l=c.visibleDays,h=u,f=i;if(s===k.VERTICAL_SCROLLABLE?f=Object.keys(l).length:(h=h.clone().subtract(1,"month"),f+=2),!t||!(0,g.default)(t,h,f,a))return e;var d=(0,y.default)(t),p=(0,o.default)({},e);if(a)p=Object.keys(l).filter((function(e){return Object.keys(l[e]).indexOf(d)>-1})).reduce((function(t,n){var i=e[n]||l[n],a=new Set(i[d]);return a.add(r),(0,o.default)({},t,A({},n,(0,o.default)({},i,A({},d,a))))}),p);else{var m=(0,w.default)(t),b=e[m]||l[m],v=new Set(b[d]);v.add(r),p=(0,o.default)({},p,A({},m,(0,o.default)({},b,A({},d,v))))}return p}},{key:"deleteModifier",value:function(e,t,r){var n=this.props,i=n.numberOfMonths,a=n.enableOutsideDays,s=n.orientation,c=this.state,u=c.currentMonth,l=c.visibleDays,h=u,f=i;if(s===k.VERTICAL_SCROLLABLE?f=Object.keys(l).length:(h=h.clone().subtract(1,"month"),f+=2),!t||!(0,g.default)(t,h,f,a))return e;var d=(0,y.default)(t),p=(0,o.default)({},e);if(a)p=Object.keys(l).filter((function(e){return Object.keys(l[e]).indexOf(d)>-1})).reduce((function(t,n){var i=e[n]||l[n],a=new Set(i[d]);return a.delete(r),(0,o.default)({},t,A({},n,(0,o.default)({},i,A({},d,a))))}),p);else{var m=(0,w.default)(t),b=e[m]||l[m],v=new Set(b[d]);v.delete(r),p=(0,o.default)({},p,A({},m,(0,o.default)({},b,A({},d,v))))}return p}},{key:"isBlocked",value:function(e){var t=this.props,r=t.isDayBlocked,n=t.isOutsideRange;return r(e)||n(e)}},{key:"isHovered",value:function(e){var t=(this.state||{}).hoverDate;return(0,m.default)(e,t)}},{key:"isSelected",value:function(e){var t=this.props.date;return(0,m.default)(e,t)}},{key:"isToday",value:function(e){return(0,m.default)(e,this.today)}},{key:"isFirstDayOfWeek",value:function(e){var t=this.props.firstDayOfWeek;return e.day()===(t||l.default.localeData().firstDayOfWeek())}},{key:"isLastDayOfWeek",value:function(e){var t=this.props.firstDayOfWeek;return e.day()===((t||l.default.localeData().firstDayOfWeek())+6)%7}},{key:"render",value:function(){var e=this.props,t=e.numberOfMonths,r=e.orientation,n=e.monthFormat,i=e.renderMonthText,o=e.navPrev,s=e.navNext,c=e.onOutsideClick,u=e.withPortal,l=e.focused,h=e.enableOutsideDays,f=e.hideKeyboardShortcutsPanel,d=e.daySize,p=e.firstDayOfWeek,m=e.renderCalendarDay,b=e.renderDayContents,v=e.renderCalendarInfo,g=e.renderMonthElement,y=e.calendarInfoPosition,w=e.isFocused,M=e.isRTL,_=e.phrases,O=e.dayAriaLabelFormat,k=e.onBlur,S=e.showKeyboardShortcuts,A=e.weekDayFormat,C=e.verticalHeight,j=e.noBorder,z=e.transitionDuration,x=e.verticalBorderSpacing,D=e.horizontalMonthPadding,P=this.state,R=P.currentMonth,T=P.visibleDays;return a.default.createElement(E.default,{orientation:r,enableOutsideDays:h,modifiers:T,numberOfMonths:t,onDayClick:this.onDayClick,onDayMouseEnter:this.onDayMouseEnter,onDayMouseLeave:this.onDayMouseLeave,onPrevMonthClick:this.onPrevMonthClick,onNextMonthClick:this.onNextMonthClick,onMonthChange:this.onMonthChange,onYearChange:this.onYearChange,monthFormat:n,withPortal:u,hidden:!l,hideKeyboardShortcutsPanel:f,initialVisibleMonth:function(){return R},firstDayOfWeek:p,onOutsideClick:c,navPrev:o,navNext:s,renderMonthText:i,renderCalendarDay:m,renderDayContents:b,renderCalendarInfo:v,renderMonthElement:g,calendarInfoPosition:y,isFocused:w,getFirstFocusableDay:this.getFirstFocusableDay,onBlur:k,phrases:_,daySize:d,isRTL:M,showKeyboardShortcuts:S,weekDayFormat:A,dayAriaLabelFormat:O,verticalHeight:C,noBorder:j,transitionDuration:z,verticalBorderSpacing:x,horizontalMonthPadding:D})}}]),t}(a.default.Component);t.default=z,z.propTypes=C,z.defaultProps=j},,,,,,,,,,,,function(e,t,r){"use strict";var n=r(0),i=r(112),o={huge:1440,wide:1280,large:960,medium:782,small:600,mobile:480},a={">=":"min-width","<":"max-width"},s={">=":function(e,t){return t>=e},"<":function(e,t){return t1&&void 0!==arguments[1]?arguments[1]:">=",r=Object(n.useContext)(c),u=!r&&"(".concat(a[t],": ").concat(o[e],"px)"),l=Object(i.a)(u);return r?s[t](o[e],r):l};u.__experimentalWidthProvider=c.Provider,t.a=u},function(e,t,r){"use strict";var n="function"==typeof Symbol&&Symbol.for,i=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,a=n?Symbol.for("react.fragment"):60107,s=n?Symbol.for("react.strict_mode"):60108,c=n?Symbol.for("react.profiler"):60114,u=n?Symbol.for("react.provider"):60109,l=n?Symbol.for("react.context"):60110,h=n?Symbol.for("react.async_mode"):60111,f=n?Symbol.for("react.concurrent_mode"):60111,d=n?Symbol.for("react.forward_ref"):60112,p=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,b=n?Symbol.for("react.memo"):60115,v=n?Symbol.for("react.lazy"):60116,g=n?Symbol.for("react.block"):60121,y=n?Symbol.for("react.fundamental"):60117,w=n?Symbol.for("react.responder"):60118,M=n?Symbol.for("react.scope"):60119;function _(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case i:switch(e=e.type){case h:case f:case a:case c:case s:case p:return e;default:switch(e=e&&e.$$typeof){case l:case d:case v:case b:case u:return e;default:return t}}case o:return t}}}function O(e){return _(e)===f}t.AsyncMode=h,t.ConcurrentMode=f,t.ContextConsumer=l,t.ContextProvider=u,t.Element=i,t.ForwardRef=d,t.Fragment=a,t.Lazy=v,t.Memo=b,t.Portal=o,t.Profiler=c,t.StrictMode=s,t.Suspense=p,t.isAsyncMode=function(e){return O(e)||_(e)===h},t.isConcurrentMode=O,t.isContextConsumer=function(e){return _(e)===l},t.isContextProvider=function(e){return _(e)===u},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===i},t.isForwardRef=function(e){return _(e)===d},t.isFragment=function(e){return _(e)===a},t.isLazy=function(e){return _(e)===v},t.isMemo=function(e){return _(e)===b},t.isPortal=function(e){return _(e)===o},t.isProfiler=function(e){return _(e)===c},t.isStrictMode=function(e){return _(e)===s},t.isSuspense=function(e){return _(e)===p},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===f||e===c||e===s||e===p||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===v||e.$$typeof===b||e.$$typeof===u||e.$$typeof===l||e.$$typeof===d||e.$$typeof===y||e.$$typeof===w||e.$$typeof===M||e.$$typeof===g)},t.typeOf=_},function(e,t,r){"use strict";var n=r(215),i=r(61),o=i("%Function.prototype.apply%"),a=i("%Function.prototype.call%"),s=i("%Reflect.apply%",!0)||n.call(a,o),c=i("%Object.defineProperty%",!0);if(c)try{c({},"a",{value:1})}catch(e){c=null}e.exports=function(){return s(n,a,arguments)};var u=function(){return s(n,o,arguments)};c?c(e.exports,"apply",{value:u}):e.exports.apply=u},function(e,t,r){"use strict";var n=r(61)("%TypeError%"),i=r(586),o=r(198),a=r(119);e.exports=function(e,t){if("Object"!==a(e))throw new n("Assertion failed: Type(O) is not Object");if(!o(t))throw new n("Assertion failed: IsPropertyKey(P) is not true, got "+i(t));return e[t]}},function(e,t,r){"use strict";var n=r(61)("%Array%"),i=!n.isArray&&r(199)("Object.prototype.toString");e.exports=n.isArray||function(e){return"[object Array]"===i(e)}},function(e,t,r){"use strict";var n=r(61),i=n("%TypeError%"),o=n("%SyntaxError%"),a=r(157),s={"Property Descriptor":function(e,t){if("Object"!==e(t))return!1;var r={"[[Configurable]]":!0,"[[Enumerable]]":!0,"[[Get]]":!0,"[[Set]]":!0,"[[Value]]":!0,"[[Writable]]":!0};for(var n in t)if(a(t,n)&&!r[n])return!1;var o=a(t,"[[Value]]"),s=a(t,"[[Get]]")||a(t,"[[Set]]");if(o&&s)throw new i("Property Descriptors may not be both accessor and data descriptors");return!0}};e.exports=function(e,t,r,n){var a=s[t];if("function"!=typeof a)throw new o("unknown record type: "+t);if(!a(e,n))throw new i(r+" must be a "+t)}},function(e,t,r){"use strict";e.exports=Number.isNaN||function(e){return e!=e}},function(e,t,r){var n=r(628),i=r(629),o=r(283),a=/^\d+$/,s=Object.prototype.hasOwnProperty,c=n(Object,"keys");var u,l=(u="length",function(e){return null==e?void 0:e[u]});function h(e,t){return t=null==t?9007199254740991:t,(e="number"==typeof e||a.test(e)?+e:-1)>-1&&e%1==0&&e-1&&e%1==0&&e<=9007199254740991}function d(e){for(var t=function(e){if(null==e)return[];p(e)||(e=Object(e));var t=e.length;t=t&&f(t)&&(o(e)||i(e))&&t||0;var r=e.constructor,n=-1,a="function"==typeof r&&r.prototype===e,c=Array(t),u=t>0;for(;++n0?n:r)(e)}},function(e,t){e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(e,t,r){var n=r(316);e.exports=function(e){return Object(n(e))}},function(e,t,r){"use strict";var n=r(145),i=r(500),o=r(501),a=r(673),s=o();n(s,{getPolyfill:o,implementation:i,shim:a}),e.exports=s},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,r,o){var a=t.clone().startOf("month");o&&(a=a.startOf("week"));if((0,n.default)(e,a))return!1;var s=t.clone().add(r-1,"months").endOf("month");o&&(s=s.endOf("week"));return!(0,i.default)(e,s)};var n=o(r(218)),i=o(r(286));function o(e){return e&&e.__esModule?e:{default:e}}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.PureDayPicker=t.defaultProps=void 0;var n=Object.assign||function(e){for(var t=1;t0?a-4:a;for(r=0;r>16&255,c[l++]=t>>8&255,c[l++]=255&t;2===s&&(t=i[e.charCodeAt(r)]<<2|i[e.charCodeAt(r+1)]>>4,c[l++]=255&t);1===s&&(t=i[e.charCodeAt(r)]<<10|i[e.charCodeAt(r+1)]<<4|i[e.charCodeAt(r+2)]>>2,c[l++]=t>>8&255,c[l++]=255&t);return c},t.fromByteArray=function(e){for(var t,r=e.length,i=r%3,o=[],a=0,s=r-i;as?s:a+16383));1===i?(t=e[r-1],o.push(n[t>>2]+n[t<<4&63]+"==")):2===i&&(t=(e[r-2]<<8)+e[r-1],o.push(n[t>>10]+n[t>>4&63]+n[t<<2&63]+"="));return o.join("")};for(var n=[],i=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,c=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");return-1===r&&(r=t),[r,r===t?0:4-r%4]}function l(e,t,r){for(var i,o,a=[],s=t;s>18&63]+n[o>>12&63]+n[o>>6&63]+n[63&o]);return a.join("")}i["-".charCodeAt(0)]=62,i["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,r,n,i){var o,a,s=8*i-n-1,c=(1<>1,l=-7,h=r?i-1:0,f=r?-1:1,d=e[t+h];for(h+=f,o=d&(1<<-l)-1,d>>=-l,l+=s;l>0;o=256*o+e[t+h],h+=f,l-=8);for(a=o&(1<<-l)-1,o>>=-l,l+=n;l>0;a=256*a+e[t+h],h+=f,l-=8);if(0===o)o=1-u;else{if(o===c)return a?NaN:1/0*(d?-1:1);a+=Math.pow(2,n),o-=u}return(d?-1:1)*a*Math.pow(2,o-n)},t.write=function(e,t,r,n,i,o){var a,s,c,u=8*o-i-1,l=(1<>1,f=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=n?0:o-1,p=n?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(c=Math.pow(2,-a))<1&&(a--,c*=2),(t+=a+h>=1?f/c:f*Math.pow(2,1-h))*c>=2&&(a++,c/=2),a+h>=l?(s=0,a=l):a+h>=1?(s=(t*c-1)*Math.pow(2,i),a+=h):(s=t*Math.pow(2,h-1)*Math.pow(2,i),a=0));i>=8;e[r+d]=255&s,d+=p,s/=256,i-=8);for(a=a<0;e[r+d]=255&a,d+=p,a/=256,u-=8);e[r+d-p]|=128*m}},function(e,t,r){var n=r(44),i=n.Buffer;function o(e,t){for(var r in e)t[r]=e[r]}function a(e,t,r){return i(e,t,r)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?e.exports=n:(o(n,t),t.Buffer=a),a.prototype=Object.create(i.prototype),o(i,a),a.from=function(e,t,r){if("number"==typeof e)throw new TypeError("Argument must not be a number");return i(e,t,r)},a.alloc=function(e,t,r){if("number"!=typeof e)throw new TypeError("Argument must be a number");var n=i(e);return void 0!==t?"string"==typeof r?n.fill(t,r):n.fill(t):n.fill(0),n},a.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return i(e)},a.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return n.SlowBuffer(e)}},function(e,t,r){(t=e.exports=r(225)).Stream=t,t.Readable=t,t.Writable=r(229),t.Duplex=r(108),t.Transform=r(230),t.PassThrough=r(343),t.finished=r(169),t.pipeline=r(344)},function(e,t){},function(e,t,r){"use strict";function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){for(var r=0;r0?this.tail.next=t:this.head=t,this.tail=t,++this.length}},{key:"unshift",value:function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length}},{key:"shift",value:function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(e){if(0===this.length)return"";for(var t=this.head,r=""+t.data;t=t.next;)r+=e+t.data;return r}},{key:"concat",value:function(e){if(0===this.length)return a.alloc(0);for(var t,r,n,i=a.allocUnsafe(e>>>0),o=this.head,s=0;o;)t=o.data,r=i,n=s,a.prototype.copy.call(t,r,n),s+=o.data.length,o=o.next;return i}},{key:"consume",value:function(e,t){var r;return ei.length?i.length:e;if(o===i.length?n+=i:n+=i.slice(0,e),0==(e-=o)){o===i.length?(++r,t.next?this.head=t.next:this.head=this.tail=null):(this.head=t,t.data=i.slice(o));break}++r}return this.length-=r,n}},{key:"_getBuffer",value:function(e){var t=a.allocUnsafe(e),r=this.head,n=1;for(r.data.copy(t),e-=r.data.length;r=r.next;){var i=r.data,o=e>i.length?i.length:e;if(i.copy(t,t.length-e,0,o),0==(e-=o)){o===i.length?(++n,r.next?this.head=r.next:this.head=this.tail=null):(this.head=r,r.data=i.slice(o));break}++n}return this.length-=n,t}},{key:c,value:function(e,t){return s(this,function(e){for(var t=1;t0,(function(e){n||(n=e),e&&a.forEach(u),o||(a.forEach(u),i(n))}))}));return t.reduce(l)}},function(e,t,r){var n=r(25),i=r(109),o=r(28).Buffer,a=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function c(){this.init(),this._w=s,i.call(this,64,56)}function u(e){return e<<30|e>>>2}function l(e,t,r,n){return 0===e?t&r|~t&n:2===e?t&r|t&n|r&n:t^r^n}n(c,i),c.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},c.prototype._update=function(e){for(var t,r=this._w,n=0|this._a,i=0|this._b,o=0|this._c,s=0|this._d,c=0|this._e,h=0;h<16;++h)r[h]=e.readInt32BE(4*h);for(;h<80;++h)r[h]=r[h-3]^r[h-8]^r[h-14]^r[h-16];for(var f=0;f<80;++f){var d=~~(f/20),p=0|((t=n)<<5|t>>>27)+l(d,i,o,s)+c+r[f]+a[d];c=s,s=o,o=u(i),i=n,n=p}this._a=n+this._a|0,this._b=i+this._b|0,this._c=o+this._c|0,this._d=s+this._d|0,this._e=c+this._e|0},c.prototype._hash=function(){var e=o.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},e.exports=c},function(e,t,r){var n=r(25),i=r(109),o=r(28).Buffer,a=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function c(){this.init(),this._w=s,i.call(this,64,56)}function u(e){return e<<5|e>>>27}function l(e){return e<<30|e>>>2}function h(e,t,r,n){return 0===e?t&r|~t&n:2===e?t&r|t&n|r&n:t^r^n}n(c,i),c.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},c.prototype._update=function(e){for(var t,r=this._w,n=0|this._a,i=0|this._b,o=0|this._c,s=0|this._d,c=0|this._e,f=0;f<16;++f)r[f]=e.readInt32BE(4*f);for(;f<80;++f)r[f]=(t=r[f-3]^r[f-8]^r[f-14]^r[f-16])<<1|t>>>31;for(var d=0;d<80;++d){var p=~~(d/20),m=u(n)+h(p,i,o,s)+c+r[d]+a[p]|0;c=s,s=o,o=l(i),i=n,n=m}this._a=n+this._a|0,this._b=i+this._b|0,this._c=o+this._c|0,this._d=s+this._d|0,this._e=c+this._e|0},c.prototype._hash=function(){var e=o.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},e.exports=c},function(e,t,r){var n=r(25),i=r(231),o=r(109),a=r(28).Buffer,s=new Array(64);function c(){this.init(),this._w=s,o.call(this,64,56)}n(c,i),c.prototype.init=function(){return this._a=3238371032,this._b=914150663,this._c=812702999,this._d=4144912697,this._e=4290775857,this._f=1750603025,this._g=1694076839,this._h=3204075428,this},c.prototype._hash=function(){var e=a.allocUnsafe(28);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e},e.exports=c},function(e,t,r){var n=r(25),i=r(232),o=r(109),a=r(28).Buffer,s=new Array(160);function c(){this.init(),this._w=s,o.call(this,128,112)}n(c,i),c.prototype.init=function(){return this._ah=3418070365,this._bh=1654270250,this._ch=2438529370,this._dh=355462360,this._eh=1731405415,this._fh=2394180231,this._gh=3675008525,this._hh=1203062813,this._al=3238371032,this._bl=914150663,this._cl=812702999,this._dl=4144912697,this._el=4290775857,this._fl=1750603025,this._gl=1694076839,this._hl=3204075428,this},c.prototype._hash=function(){var e=a.allocUnsafe(48);function t(t,r,n){e.writeInt32BE(t,n),e.writeInt32BE(r,n+4)}return t(this._ah,this._al,0),t(this._bh,this._bl,8),t(this._ch,this._cl,16),t(this._dh,this._dl,24),t(this._eh,this._el,32),t(this._fh,this._fl,40),e},e.exports=c},function(e,t,r){e.exports=i;var n=r(93).EventEmitter;function i(){n.call(this)}r(25)(i,n),i.Readable=r(172),i.Writable=r(356),i.Duplex=r(357),i.Transform=r(358),i.PassThrough=r(359),i.Stream=i,i.prototype.pipe=function(e,t){var r=this;function i(t){e.writable&&!1===e.write(t)&&r.pause&&r.pause()}function o(){r.readable&&r.resume&&r.resume()}r.on("data",i),e.on("drain",o),e._isStdio||t&&!1===t.end||(r.on("end",s),r.on("close",c));var a=!1;function s(){a||(a=!0,e.end())}function c(){a||(a=!0,"function"==typeof e.destroy&&e.destroy())}function u(e){if(l(),0===n.listenerCount(this,"error"))throw e}function l(){r.removeListener("data",i),e.removeListener("drain",o),r.removeListener("end",s),r.removeListener("close",c),r.removeListener("error",u),e.removeListener("error",u),r.removeListener("end",l),r.removeListener("close",l),e.removeListener("close",l)}return r.on("error",u),e.on("error",u),r.on("end",l),r.on("close",l),e.on("close",l),e.emit("pipe",r),e}},function(e,t){},function(e,t,r){"use strict";var n=r(28).Buffer,i=r(352);e.exports=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.head=null,this.tail=null,this.length=0}return e.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,r=""+t.data;t=t.next;)r+=e+t.data;return r},e.prototype.concat=function(e){if(0===this.length)return n.alloc(0);if(1===this.length)return this.head.data;for(var t,r,i,o=n.allocUnsafe(e>>>0),a=this.head,s=0;a;)t=a.data,r=o,i=s,t.copy(r,i),s+=a.data.length,a=a.next;return o},e}(),i&&i.inspect&&i.inspect.custom&&(e.exports.prototype[i.inspect.custom]=function(){var e=i.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,r){(function(e){var n=void 0!==e&&e||"undefined"!=typeof self&&self||window,i=Function.prototype.apply;function o(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new o(i.call(setTimeout,n,arguments),clearTimeout)},t.setInterval=function(){return new o(i.call(setInterval,n,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},o.prototype.unref=o.prototype.ref=function(){},o.prototype.close=function(){this._clearFn.call(n,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout((function(){e._onTimeout&&e._onTimeout()}),t))},r(354),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,r(46))},function(e,t,r){(function(e,t){!function(e,r){"use strict";if(!e.setImmediate){var n,i,o,a,s,c=1,u={},l=!1,h=e.document,f=Object.getPrototypeOf&&Object.getPrototypeOf(e);f=f&&f.setTimeout?f:e,"[object process]"==={}.toString.call(e.process)?n=function(e){t.nextTick((function(){p(e)}))}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,r=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=r,t}}()?e.MessageChannel?((o=new MessageChannel).port1.onmessage=function(e){p(e.data)},n=function(e){o.port2.postMessage(e)}):h&&"onreadystatechange"in h.createElement("script")?(i=h.documentElement,n=function(e){var t=h.createElement("script");t.onreadystatechange=function(){p(e),t.onreadystatechange=null,i.removeChild(t),t=null},i.appendChild(t)}):n=function(e){setTimeout(p,0,e)}:(a="setImmediate$"+Math.random()+"$",s=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(a)&&p(+t.data.slice(a.length))},e.addEventListener?e.addEventListener("message",s,!1):e.attachEvent("onmessage",s),n=function(t){e.postMessage(a+t,"*")}),f.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),r=0;r64?t=e(t):t.length<64&&(t=i.concat([t,a],64));for(var r=this._ipad=i.allocUnsafe(64),n=this._opad=i.allocUnsafe(64),s=0;s<64;s++)r[s]=54^t[s],n[s]=92^t[s];this._hash=[r]}n(s,o),s.prototype._update=function(e){this._hash.push(e)},s.prototype._final=function(){var e=this._alg(i.concat(this._hash));return this._alg(i.concat([this._opad,e]))},e.exports=s},function(e,t,r){e.exports=r(239)},function(e,t,r){(function(t,n){var i,o=r(28).Buffer,a=r(241),s=r(242),c=r(243),u=r(244),l=t.crypto&&t.crypto.subtle,h={sha:"SHA-1","sha-1":"SHA-1",sha1:"SHA-1",sha256:"SHA-256","sha-256":"SHA-256",sha384:"SHA-384","sha-384":"SHA-384","sha-512":"SHA-512",sha512:"SHA-512"},f=[];function d(e,t,r,n,i){return l.importKey("raw",e,{name:"PBKDF2"},!1,["deriveBits"]).then((function(e){return l.deriveBits({name:"PBKDF2",salt:t,iterations:r,hash:{name:i}},e,n<<3)})).then((function(e){return o.from(e)}))}e.exports=function(e,r,p,m,b,v){"function"==typeof b&&(v=b,b=void 0);var g=h[(b=b||"sha1").toLowerCase()];if(!g||"function"!=typeof t.Promise)return n.nextTick((function(){var t;try{t=c(e,r,p,m,b)}catch(e){return v(e)}v(null,t)}));if(a(p,m),e=u(e,s,"Password"),r=u(r,s,"Salt"),"function"!=typeof v)throw new Error("No callback provided to pbkdf2");!function(e,t){e.then((function(e){n.nextTick((function(){t(null,e)}))}),(function(e){n.nextTick((function(){t(e)}))}))}(function(e){if(t.process&&!t.process.browser)return Promise.resolve(!1);if(!l||!l.importKey||!l.deriveBits)return Promise.resolve(!1);if(void 0!==f[e])return f[e];var r=d(i=i||o.alloc(8),i,10,128,e).then((function(){return!0})).catch((function(){return!1}));return f[e]=r,r}(g).then((function(t){return t?d(e,r,p,m,g):c(e,r,p,m,b)})),v)}}).call(this,r(46),r(33))},function(e,t,r){var n=r(364),i=r(175),o=r(176),a=r(377),s=r(150);function c(e,t,r){if(e=e.toLowerCase(),o[e])return i.createCipheriv(e,t,r);if(a[e])return new n({key:t,iv:r,mode:e});throw new TypeError("invalid suite type")}function u(e,t,r){if(e=e.toLowerCase(),o[e])return i.createDecipheriv(e,t,r);if(a[e])return new n({key:t,iv:r,mode:e,decrypt:!0});throw new TypeError("invalid suite type")}t.createCipher=t.Cipher=function(e,t){var r,n;if(e=e.toLowerCase(),o[e])r=o[e].key,n=o[e].iv;else{if(!a[e])throw new TypeError("invalid suite type");r=8*a[e].key,n=a[e].iv}var i=s(t,!1,r,n);return c(e,i.key,i.iv)},t.createCipheriv=t.Cipheriv=c,t.createDecipher=t.Decipher=function(e,t){var r,n;if(e=e.toLowerCase(),o[e])r=o[e].key,n=o[e].iv;else{if(!a[e])throw new TypeError("invalid suite type");r=8*a[e].key,n=a[e].iv}var i=s(t,!1,r,n);return u(e,i.key,i.iv)},t.createDecipheriv=t.Decipheriv=u,t.listCiphers=t.getCiphers=function(){return Object.keys(a).concat(i.getCiphers())}},function(e,t,r){var n=r(85),i=r(365),o=r(25),a=r(28).Buffer,s={"des-ede3-cbc":i.CBC.instantiate(i.EDE),"des-ede3":i.EDE,"des-ede-cbc":i.CBC.instantiate(i.EDE),"des-ede":i.EDE,"des-cbc":i.CBC.instantiate(i.DES),"des-ecb":i.DES};function c(e){n.call(this);var t,r=e.mode.toLowerCase(),i=s[r];t=e.decrypt?"decrypt":"encrypt";var o=e.key;a.isBuffer(o)||(o=a.from(o)),"des-ede"!==r&&"des-ede-cbc"!==r||(o=a.concat([o,o.slice(0,8)]));var c=e.iv;a.isBuffer(c)||(c=a.from(c)),this._des=i.create({key:o,iv:c,type:t})}s.des=s["des-cbc"],s.des3=s["des-ede3-cbc"],e.exports=c,o(c,n),c.prototype._update=function(e){return a.from(this._des.update(e))},c.prototype._final=function(){return a.from(this._des.final())}},function(e,t,r){"use strict";t.utils=r(245),t.Cipher=r(174),t.DES=r(246),t.CBC=r(366),t.EDE=r(367)},function(e,t,r){"use strict";var n=r(65),i=r(25),o={};function a(e){n.equal(e.length,8,"Invalid IV length"),this.iv=new Array(8);for(var t=0;t15){var e=this.cache.slice(0,16);return this.cache=this.cache.slice(16),e}return null},f.prototype.flush=function(){for(var e=16-this.cache.length,t=o.allocUnsafe(e),r=-1;++r>a%8,e._prev=o(e._prev,r?n:i);return s}function o(e,t){var r=e.length,i=-1,o=n.allocUnsafe(e.length);for(e=n.concat([e,n.from([t])]);++i>7;return o}t.encrypt=function(e,t,r){for(var o=t.length,a=n.allocUnsafe(o),s=-1;++s>>0,0),t.writeUInt32BE(e[1]>>>0,4),t.writeUInt32BE(e[2]>>>0,8),t.writeUInt32BE(e[3]>>>0,12),t}function a(e){this.h=e,this.state=n.alloc(16,0),this.cache=n.allocUnsafe(0)}a.prototype.ghash=function(e){for(var t=-1;++t0;t--)n[t]=n[t]>>>1|(1&n[t-1])<<31;n[0]=n[0]>>>1,r&&(n[0]=n[0]^225<<24)}this.state=o(i)},a.prototype.update=function(e){var t;for(this.cache=n.concat([this.cache,e]);this.cache.length>=16;)t=this.cache.slice(0,16),this.cache=this.cache.slice(16),this.ghash(t)},a.prototype.final=function(e,t){return this.cache.length&&this.ghash(n.concat([this.cache,i],16)),this.ghash(o([0,e,0,t])),this.state},e.exports=a},function(e,t,r){var n=r(250),i=r(28).Buffer,o=r(176),a=r(251),s=r(85),c=r(149),u=r(150);function l(e,t,r){s.call(this),this._cache=new h,this._last=void 0,this._cipher=new c.AES(t),this._prev=i.from(r),this._mode=e,this._autopadding=!0}function h(){this.cache=i.allocUnsafe(0)}function f(e,t,r){var s=o[e.toLowerCase()];if(!s)throw new TypeError("invalid suite type");if("string"==typeof r&&(r=i.from(r)),"GCM"!==s.mode&&r.length!==s.iv)throw new TypeError("invalid iv length "+r.length);if("string"==typeof t&&(t=i.from(t)),t.length!==s.key/8)throw new TypeError("invalid key length "+t.length);return"stream"===s.type?new a(s.module,t,r,!0):"auth"===s.type?new n(s.module,t,r,!0):new l(s.module,t,r)}r(25)(l,s),l.prototype._update=function(e){var t,r;this._cache.add(e);for(var n=[];t=this._cache.get(this._autopadding);)r=this._mode.decrypt(this,t),n.push(r);return i.concat(n)},l.prototype._final=function(){var e=this._cache.flush();if(this._autopadding)return function(e){var t=e[15];if(t<1||t>16)throw new Error("unable to decrypt data");var r=-1;for(;++r16)return t=this.cache.slice(0,16),this.cache=this.cache.slice(16),t}else if(this.cache.length>=16)return t=this.cache.slice(0,16),this.cache=this.cache.slice(16),t;return null},h.prototype.flush=function(){if(this.cache.length)return this.cache},t.createDecipher=function(e,t){var r=o[e.toLowerCase()];if(!r)throw new TypeError("invalid suite type");var n=u(t,!1,r.key,r.iv);return f(e,n.key,n.iv)},t.createDecipheriv=f},function(e,t){t["des-ecb"]={key:8,iv:0},t["des-cbc"]=t.des={key:8,iv:8},t["des-ede3-cbc"]=t.des3={key:24,iv:8},t["des-ede3"]={key:24,iv:0},t["des-ede-cbc"]={key:16,iv:8},t["des-ede"]={key:16,iv:0}},function(e,t,r){(function(e){var n=r(252),i=r(383),o=r(384);var a={binary:!0,hex:!0,base64:!0};t.DiffieHellmanGroup=t.createDiffieHellmanGroup=t.getDiffieHellman=function(t){var r=new e(i[t].prime,"hex"),n=new e(i[t].gen,"hex");return new o(r,n)},t.createDiffieHellman=t.DiffieHellman=function t(r,i,s,c){return e.isBuffer(i)||void 0===a[i]?t(r,"binary",i,s):(i=i||"binary",c=c||"binary",s=s||new e([2]),e.isBuffer(s)||(s=new e(s,c)),"number"==typeof r?new o(n(r,s),s,!0):(e.isBuffer(r)||(r=new e(r,i)),new o(r,s,!0)))}}).call(this,r(44).Buffer)},function(e,t){},function(e,t,r){(function(e){!function(e,t){"use strict";function n(e,t){if(!e)throw new Error(t||"Assertion failed")}function i(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e}function o(e,t,r){if(o.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(r=t,t=10),this._init(e||0,t||10,r||"be"))}var a;"object"==typeof e?e.exports=o:t.BN=o,o.BN=o,o.wordSize=26;try{a=r(381).Buffer}catch(e){}function s(e,t,r){for(var n=0,i=Math.min(e.length,r),o=t;o=49&&a<=54?a-49+10:a>=17&&a<=22?a-17+10:15&a}return n}function c(e,t,r,n){for(var i=0,o=Math.min(e.length,r),a=t;a=49?s-49+10:s>=17?s-17+10:s}return i}o.isBN=function(e){return e instanceof o||null!==e&&"object"==typeof e&&e.constructor.wordSize===o.wordSize&&Array.isArray(e.words)},o.max=function(e,t){return e.cmp(t)>0?e:t},o.min=function(e,t){return e.cmp(t)<0?e:t},o.prototype._init=function(e,t,r){if("number"==typeof e)return this._initNumber(e,t,r);if("object"==typeof e)return this._initArray(e,t,r);"hex"===t&&(t=16),n(t===(0|t)&&t>=2&&t<=36);var i=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&i++,16===t?this._parseHex(e,i):this._parseBase(e,t,i),"-"===e[0]&&(this.negative=1),this.strip(),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initNumber=function(e,t,r){e<0&&(this.negative=1,e=-e),e<67108864?(this.words=[67108863&e],this.length=1):e<4503599627370496?(this.words=[67108863&e,e/67108864&67108863],this.length=2):(n(e<9007199254740992),this.words=[67108863&e,e/67108864&67108863,1],this.length=3),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initArray=function(e,t,r){if(n("number"==typeof e.length),e.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(e.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)a=e[i]|e[i-1]<<8|e[i-2]<<16,this.words[o]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);else if("le"===r)for(i=0,o=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);return this.strip()},o.prototype._parseHex=function(e,t){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var r=0;r=t;r-=6)i=s(e,r,r+6),this.words[n]|=i<>>26-o&4194303,(o+=24)>=26&&(o-=26,n++);r+6!==t&&(i=s(e,t,r+6),this.words[n]|=i<>>26-o&4194303),this.strip()},o.prototype._parseBase=function(e,t,r){this.words=[0],this.length=1;for(var n=0,i=1;i<=67108863;i*=t)n++;n--,i=i/t|0;for(var o=e.length-r,a=o%n,s=Math.min(o,o-a)+r,u=0,l=r;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},o.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},o.prototype.inspect=function(){return(this.red?""};var u=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],l=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function f(e,t,r){r.negative=t.negative^e.negative;var n=e.length+t.length|0;r.length=n,n=n-1|0;var i=0|e.words[0],o=0|t.words[0],a=i*o,s=67108863&a,c=a/67108864|0;r.words[0]=s;for(var u=1;u>>26,h=67108863&c,f=Math.min(u,t.length-1),d=Math.max(0,u-e.length+1);d<=f;d++){var p=u-d|0;l+=(a=(i=0|e.words[p])*(o=0|t.words[d])+h)/67108864|0,h=67108863&a}r.words[u]=0|h,c=0|l}return 0!==c?r.words[u]=0|c:r.length--,r.strip()}o.prototype.toString=function(e,t){var r;if(t=0|t||1,16===(e=e||10)||"hex"===e){r="";for(var i=0,o=0,a=0;a>>24-i&16777215)||a!==this.length-1?u[6-c.length]+c+r:c+r,(i+=2)>=26&&(i-=26,a--)}for(0!==o&&(r=o.toString(16)+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}if(e===(0|e)&&e>=2&&e<=36){var f=l[e],d=h[e];r="";var p=this.clone();for(p.negative=0;!p.isZero();){var m=p.modn(d).toString(e);r=(p=p.idivn(d)).isZero()?m+r:u[f-m.length]+m+r}for(this.isZero()&&(r="0"+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}n(!1,"Base should be between 2 and 36")},o.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&n(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},o.prototype.toJSON=function(){return this.toString(16)},o.prototype.toBuffer=function(e,t){return n(void 0!==a),this.toArrayLike(a,e,t)},o.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},o.prototype.toArrayLike=function(e,t,r){var i=this.byteLength(),o=r||Math.max(1,i);n(i<=o,"byte array longer than desired length"),n(o>0,"Requested array length <= 0"),this.strip();var a,s,c="le"===t,u=new e(o),l=this.clone();if(c){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),u[s]=a;for(;s=4096&&(r+=13,t>>>=13),t>=64&&(r+=7,t>>>=7),t>=8&&(r+=4,t>>>=4),t>=2&&(r+=2,t>>>=2),r+t},o.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,r=0;return 0==(8191&t)&&(r+=13,t>>>=13),0==(127&t)&&(r+=7,t>>>=7),0==(15&t)&&(r+=4,t>>>=4),0==(3&t)&&(r+=2,t>>>=2),0==(1&t)&&r++,r},o.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},o.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},o.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},o.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var r=0;re.length?this.clone().iand(e):e.clone().iand(this)},o.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},o.prototype.iuxor=function(e){var t,r;this.length>e.length?(t=this,r=e):(t=e,r=this);for(var n=0;ne.length?this.clone().ixor(e):e.clone().ixor(this)},o.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},o.prototype.inotn=function(e){n("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),r=e%26;this._expand(t),r>0&&t--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-r),this.strip()},o.prototype.notn=function(e){return this.clone().inotn(e)},o.prototype.setn=function(e,t){n("number"==typeof e&&e>=0);var r=e/26|0,i=e%26;return this._expand(r+1),this.words[r]=t?this.words[r]|1<e.length?(r=this,n=e):(r=e,n=this);for(var i=0,o=0;o>>26;for(;0!==i&&o>>26;if(this.length=r.length,0!==i)this.words[this.length]=i,this.length++;else if(r!==this)for(;oe.length?this.clone().iadd(e):e.clone().iadd(this)},o.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var r,n,i=this.cmp(e);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(r=this,n=e):(r=e,n=this);for(var o=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==o&&a>26,this.words[a]=67108863&t;if(0===o&&a>>13,d=0|a[1],p=8191&d,m=d>>>13,b=0|a[2],v=8191&b,g=b>>>13,y=0|a[3],w=8191&y,M=y>>>13,_=0|a[4],O=8191&_,k=_>>>13,E=0|a[5],S=8191&E,A=E>>>13,C=0|a[6],j=8191&C,z=C>>>13,x=0|a[7],D=8191&x,P=x>>>13,R=0|a[8],T=8191&R,F=R>>>13,N=0|a[9],I=8191&N,L=N>>>13,B=0|s[0],H=8191&B,q=B>>>13,V=0|s[1],U=8191&V,W=V>>>13,K=0|s[2],G=8191&K,X=K>>>13,Y=0|s[3],Z=8191&Y,$=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],re=8191&te,ne=te>>>13,ie=0|s[6],oe=8191&ie,ae=ie>>>13,se=0|s[7],ce=8191&se,ue=se>>>13,le=0|s[8],he=8191&le,fe=le>>>13,de=0|s[9],pe=8191&de,me=de>>>13;r.negative=e.negative^t.negative,r.length=19;var be=(u+(n=Math.imul(h,H))|0)+((8191&(i=(i=Math.imul(h,q))+Math.imul(f,H)|0))<<13)|0;u=((o=Math.imul(f,q))+(i>>>13)|0)+(be>>>26)|0,be&=67108863,n=Math.imul(p,H),i=(i=Math.imul(p,q))+Math.imul(m,H)|0,o=Math.imul(m,q);var ve=(u+(n=n+Math.imul(h,U)|0)|0)+((8191&(i=(i=i+Math.imul(h,W)|0)+Math.imul(f,U)|0))<<13)|0;u=((o=o+Math.imul(f,W)|0)+(i>>>13)|0)+(ve>>>26)|0,ve&=67108863,n=Math.imul(v,H),i=(i=Math.imul(v,q))+Math.imul(g,H)|0,o=Math.imul(g,q),n=n+Math.imul(p,U)|0,i=(i=i+Math.imul(p,W)|0)+Math.imul(m,U)|0,o=o+Math.imul(m,W)|0;var ge=(u+(n=n+Math.imul(h,G)|0)|0)+((8191&(i=(i=i+Math.imul(h,X)|0)+Math.imul(f,G)|0))<<13)|0;u=((o=o+Math.imul(f,X)|0)+(i>>>13)|0)+(ge>>>26)|0,ge&=67108863,n=Math.imul(w,H),i=(i=Math.imul(w,q))+Math.imul(M,H)|0,o=Math.imul(M,q),n=n+Math.imul(v,U)|0,i=(i=i+Math.imul(v,W)|0)+Math.imul(g,U)|0,o=o+Math.imul(g,W)|0,n=n+Math.imul(p,G)|0,i=(i=i+Math.imul(p,X)|0)+Math.imul(m,G)|0,o=o+Math.imul(m,X)|0;var ye=(u+(n=n+Math.imul(h,Z)|0)|0)+((8191&(i=(i=i+Math.imul(h,$)|0)+Math.imul(f,Z)|0))<<13)|0;u=((o=o+Math.imul(f,$)|0)+(i>>>13)|0)+(ye>>>26)|0,ye&=67108863,n=Math.imul(O,H),i=(i=Math.imul(O,q))+Math.imul(k,H)|0,o=Math.imul(k,q),n=n+Math.imul(w,U)|0,i=(i=i+Math.imul(w,W)|0)+Math.imul(M,U)|0,o=o+Math.imul(M,W)|0,n=n+Math.imul(v,G)|0,i=(i=i+Math.imul(v,X)|0)+Math.imul(g,G)|0,o=o+Math.imul(g,X)|0,n=n+Math.imul(p,Z)|0,i=(i=i+Math.imul(p,$)|0)+Math.imul(m,Z)|0,o=o+Math.imul(m,$)|0;var we=(u+(n=n+Math.imul(h,Q)|0)|0)+((8191&(i=(i=i+Math.imul(h,ee)|0)+Math.imul(f,Q)|0))<<13)|0;u=((o=o+Math.imul(f,ee)|0)+(i>>>13)|0)+(we>>>26)|0,we&=67108863,n=Math.imul(S,H),i=(i=Math.imul(S,q))+Math.imul(A,H)|0,o=Math.imul(A,q),n=n+Math.imul(O,U)|0,i=(i=i+Math.imul(O,W)|0)+Math.imul(k,U)|0,o=o+Math.imul(k,W)|0,n=n+Math.imul(w,G)|0,i=(i=i+Math.imul(w,X)|0)+Math.imul(M,G)|0,o=o+Math.imul(M,X)|0,n=n+Math.imul(v,Z)|0,i=(i=i+Math.imul(v,$)|0)+Math.imul(g,Z)|0,o=o+Math.imul(g,$)|0,n=n+Math.imul(p,Q)|0,i=(i=i+Math.imul(p,ee)|0)+Math.imul(m,Q)|0,o=o+Math.imul(m,ee)|0;var Me=(u+(n=n+Math.imul(h,re)|0)|0)+((8191&(i=(i=i+Math.imul(h,ne)|0)+Math.imul(f,re)|0))<<13)|0;u=((o=o+Math.imul(f,ne)|0)+(i>>>13)|0)+(Me>>>26)|0,Me&=67108863,n=Math.imul(j,H),i=(i=Math.imul(j,q))+Math.imul(z,H)|0,o=Math.imul(z,q),n=n+Math.imul(S,U)|0,i=(i=i+Math.imul(S,W)|0)+Math.imul(A,U)|0,o=o+Math.imul(A,W)|0,n=n+Math.imul(O,G)|0,i=(i=i+Math.imul(O,X)|0)+Math.imul(k,G)|0,o=o+Math.imul(k,X)|0,n=n+Math.imul(w,Z)|0,i=(i=i+Math.imul(w,$)|0)+Math.imul(M,Z)|0,o=o+Math.imul(M,$)|0,n=n+Math.imul(v,Q)|0,i=(i=i+Math.imul(v,ee)|0)+Math.imul(g,Q)|0,o=o+Math.imul(g,ee)|0,n=n+Math.imul(p,re)|0,i=(i=i+Math.imul(p,ne)|0)+Math.imul(m,re)|0,o=o+Math.imul(m,ne)|0;var _e=(u+(n=n+Math.imul(h,oe)|0)|0)+((8191&(i=(i=i+Math.imul(h,ae)|0)+Math.imul(f,oe)|0))<<13)|0;u=((o=o+Math.imul(f,ae)|0)+(i>>>13)|0)+(_e>>>26)|0,_e&=67108863,n=Math.imul(D,H),i=(i=Math.imul(D,q))+Math.imul(P,H)|0,o=Math.imul(P,q),n=n+Math.imul(j,U)|0,i=(i=i+Math.imul(j,W)|0)+Math.imul(z,U)|0,o=o+Math.imul(z,W)|0,n=n+Math.imul(S,G)|0,i=(i=i+Math.imul(S,X)|0)+Math.imul(A,G)|0,o=o+Math.imul(A,X)|0,n=n+Math.imul(O,Z)|0,i=(i=i+Math.imul(O,$)|0)+Math.imul(k,Z)|0,o=o+Math.imul(k,$)|0,n=n+Math.imul(w,Q)|0,i=(i=i+Math.imul(w,ee)|0)+Math.imul(M,Q)|0,o=o+Math.imul(M,ee)|0,n=n+Math.imul(v,re)|0,i=(i=i+Math.imul(v,ne)|0)+Math.imul(g,re)|0,o=o+Math.imul(g,ne)|0,n=n+Math.imul(p,oe)|0,i=(i=i+Math.imul(p,ae)|0)+Math.imul(m,oe)|0,o=o+Math.imul(m,ae)|0;var Oe=(u+(n=n+Math.imul(h,ce)|0)|0)+((8191&(i=(i=i+Math.imul(h,ue)|0)+Math.imul(f,ce)|0))<<13)|0;u=((o=o+Math.imul(f,ue)|0)+(i>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,n=Math.imul(T,H),i=(i=Math.imul(T,q))+Math.imul(F,H)|0,o=Math.imul(F,q),n=n+Math.imul(D,U)|0,i=(i=i+Math.imul(D,W)|0)+Math.imul(P,U)|0,o=o+Math.imul(P,W)|0,n=n+Math.imul(j,G)|0,i=(i=i+Math.imul(j,X)|0)+Math.imul(z,G)|0,o=o+Math.imul(z,X)|0,n=n+Math.imul(S,Z)|0,i=(i=i+Math.imul(S,$)|0)+Math.imul(A,Z)|0,o=o+Math.imul(A,$)|0,n=n+Math.imul(O,Q)|0,i=(i=i+Math.imul(O,ee)|0)+Math.imul(k,Q)|0,o=o+Math.imul(k,ee)|0,n=n+Math.imul(w,re)|0,i=(i=i+Math.imul(w,ne)|0)+Math.imul(M,re)|0,o=o+Math.imul(M,ne)|0,n=n+Math.imul(v,oe)|0,i=(i=i+Math.imul(v,ae)|0)+Math.imul(g,oe)|0,o=o+Math.imul(g,ae)|0,n=n+Math.imul(p,ce)|0,i=(i=i+Math.imul(p,ue)|0)+Math.imul(m,ce)|0,o=o+Math.imul(m,ue)|0;var ke=(u+(n=n+Math.imul(h,he)|0)|0)+((8191&(i=(i=i+Math.imul(h,fe)|0)+Math.imul(f,he)|0))<<13)|0;u=((o=o+Math.imul(f,fe)|0)+(i>>>13)|0)+(ke>>>26)|0,ke&=67108863,n=Math.imul(I,H),i=(i=Math.imul(I,q))+Math.imul(L,H)|0,o=Math.imul(L,q),n=n+Math.imul(T,U)|0,i=(i=i+Math.imul(T,W)|0)+Math.imul(F,U)|0,o=o+Math.imul(F,W)|0,n=n+Math.imul(D,G)|0,i=(i=i+Math.imul(D,X)|0)+Math.imul(P,G)|0,o=o+Math.imul(P,X)|0,n=n+Math.imul(j,Z)|0,i=(i=i+Math.imul(j,$)|0)+Math.imul(z,Z)|0,o=o+Math.imul(z,$)|0,n=n+Math.imul(S,Q)|0,i=(i=i+Math.imul(S,ee)|0)+Math.imul(A,Q)|0,o=o+Math.imul(A,ee)|0,n=n+Math.imul(O,re)|0,i=(i=i+Math.imul(O,ne)|0)+Math.imul(k,re)|0,o=o+Math.imul(k,ne)|0,n=n+Math.imul(w,oe)|0,i=(i=i+Math.imul(w,ae)|0)+Math.imul(M,oe)|0,o=o+Math.imul(M,ae)|0,n=n+Math.imul(v,ce)|0,i=(i=i+Math.imul(v,ue)|0)+Math.imul(g,ce)|0,o=o+Math.imul(g,ue)|0,n=n+Math.imul(p,he)|0,i=(i=i+Math.imul(p,fe)|0)+Math.imul(m,he)|0,o=o+Math.imul(m,fe)|0;var Ee=(u+(n=n+Math.imul(h,pe)|0)|0)+((8191&(i=(i=i+Math.imul(h,me)|0)+Math.imul(f,pe)|0))<<13)|0;u=((o=o+Math.imul(f,me)|0)+(i>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,n=Math.imul(I,U),i=(i=Math.imul(I,W))+Math.imul(L,U)|0,o=Math.imul(L,W),n=n+Math.imul(T,G)|0,i=(i=i+Math.imul(T,X)|0)+Math.imul(F,G)|0,o=o+Math.imul(F,X)|0,n=n+Math.imul(D,Z)|0,i=(i=i+Math.imul(D,$)|0)+Math.imul(P,Z)|0,o=o+Math.imul(P,$)|0,n=n+Math.imul(j,Q)|0,i=(i=i+Math.imul(j,ee)|0)+Math.imul(z,Q)|0,o=o+Math.imul(z,ee)|0,n=n+Math.imul(S,re)|0,i=(i=i+Math.imul(S,ne)|0)+Math.imul(A,re)|0,o=o+Math.imul(A,ne)|0,n=n+Math.imul(O,oe)|0,i=(i=i+Math.imul(O,ae)|0)+Math.imul(k,oe)|0,o=o+Math.imul(k,ae)|0,n=n+Math.imul(w,ce)|0,i=(i=i+Math.imul(w,ue)|0)+Math.imul(M,ce)|0,o=o+Math.imul(M,ue)|0,n=n+Math.imul(v,he)|0,i=(i=i+Math.imul(v,fe)|0)+Math.imul(g,he)|0,o=o+Math.imul(g,fe)|0;var Se=(u+(n=n+Math.imul(p,pe)|0)|0)+((8191&(i=(i=i+Math.imul(p,me)|0)+Math.imul(m,pe)|0))<<13)|0;u=((o=o+Math.imul(m,me)|0)+(i>>>13)|0)+(Se>>>26)|0,Se&=67108863,n=Math.imul(I,G),i=(i=Math.imul(I,X))+Math.imul(L,G)|0,o=Math.imul(L,X),n=n+Math.imul(T,Z)|0,i=(i=i+Math.imul(T,$)|0)+Math.imul(F,Z)|0,o=o+Math.imul(F,$)|0,n=n+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,ee)|0)+Math.imul(P,Q)|0,o=o+Math.imul(P,ee)|0,n=n+Math.imul(j,re)|0,i=(i=i+Math.imul(j,ne)|0)+Math.imul(z,re)|0,o=o+Math.imul(z,ne)|0,n=n+Math.imul(S,oe)|0,i=(i=i+Math.imul(S,ae)|0)+Math.imul(A,oe)|0,o=o+Math.imul(A,ae)|0,n=n+Math.imul(O,ce)|0,i=(i=i+Math.imul(O,ue)|0)+Math.imul(k,ce)|0,o=o+Math.imul(k,ue)|0,n=n+Math.imul(w,he)|0,i=(i=i+Math.imul(w,fe)|0)+Math.imul(M,he)|0,o=o+Math.imul(M,fe)|0;var Ae=(u+(n=n+Math.imul(v,pe)|0)|0)+((8191&(i=(i=i+Math.imul(v,me)|0)+Math.imul(g,pe)|0))<<13)|0;u=((o=o+Math.imul(g,me)|0)+(i>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,n=Math.imul(I,Z),i=(i=Math.imul(I,$))+Math.imul(L,Z)|0,o=Math.imul(L,$),n=n+Math.imul(T,Q)|0,i=(i=i+Math.imul(T,ee)|0)+Math.imul(F,Q)|0,o=o+Math.imul(F,ee)|0,n=n+Math.imul(D,re)|0,i=(i=i+Math.imul(D,ne)|0)+Math.imul(P,re)|0,o=o+Math.imul(P,ne)|0,n=n+Math.imul(j,oe)|0,i=(i=i+Math.imul(j,ae)|0)+Math.imul(z,oe)|0,o=o+Math.imul(z,ae)|0,n=n+Math.imul(S,ce)|0,i=(i=i+Math.imul(S,ue)|0)+Math.imul(A,ce)|0,o=o+Math.imul(A,ue)|0,n=n+Math.imul(O,he)|0,i=(i=i+Math.imul(O,fe)|0)+Math.imul(k,he)|0,o=o+Math.imul(k,fe)|0;var Ce=(u+(n=n+Math.imul(w,pe)|0)|0)+((8191&(i=(i=i+Math.imul(w,me)|0)+Math.imul(M,pe)|0))<<13)|0;u=((o=o+Math.imul(M,me)|0)+(i>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,n=Math.imul(I,Q),i=(i=Math.imul(I,ee))+Math.imul(L,Q)|0,o=Math.imul(L,ee),n=n+Math.imul(T,re)|0,i=(i=i+Math.imul(T,ne)|0)+Math.imul(F,re)|0,o=o+Math.imul(F,ne)|0,n=n+Math.imul(D,oe)|0,i=(i=i+Math.imul(D,ae)|0)+Math.imul(P,oe)|0,o=o+Math.imul(P,ae)|0,n=n+Math.imul(j,ce)|0,i=(i=i+Math.imul(j,ue)|0)+Math.imul(z,ce)|0,o=o+Math.imul(z,ue)|0,n=n+Math.imul(S,he)|0,i=(i=i+Math.imul(S,fe)|0)+Math.imul(A,he)|0,o=o+Math.imul(A,fe)|0;var je=(u+(n=n+Math.imul(O,pe)|0)|0)+((8191&(i=(i=i+Math.imul(O,me)|0)+Math.imul(k,pe)|0))<<13)|0;u=((o=o+Math.imul(k,me)|0)+(i>>>13)|0)+(je>>>26)|0,je&=67108863,n=Math.imul(I,re),i=(i=Math.imul(I,ne))+Math.imul(L,re)|0,o=Math.imul(L,ne),n=n+Math.imul(T,oe)|0,i=(i=i+Math.imul(T,ae)|0)+Math.imul(F,oe)|0,o=o+Math.imul(F,ae)|0,n=n+Math.imul(D,ce)|0,i=(i=i+Math.imul(D,ue)|0)+Math.imul(P,ce)|0,o=o+Math.imul(P,ue)|0,n=n+Math.imul(j,he)|0,i=(i=i+Math.imul(j,fe)|0)+Math.imul(z,he)|0,o=o+Math.imul(z,fe)|0;var ze=(u+(n=n+Math.imul(S,pe)|0)|0)+((8191&(i=(i=i+Math.imul(S,me)|0)+Math.imul(A,pe)|0))<<13)|0;u=((o=o+Math.imul(A,me)|0)+(i>>>13)|0)+(ze>>>26)|0,ze&=67108863,n=Math.imul(I,oe),i=(i=Math.imul(I,ae))+Math.imul(L,oe)|0,o=Math.imul(L,ae),n=n+Math.imul(T,ce)|0,i=(i=i+Math.imul(T,ue)|0)+Math.imul(F,ce)|0,o=o+Math.imul(F,ue)|0,n=n+Math.imul(D,he)|0,i=(i=i+Math.imul(D,fe)|0)+Math.imul(P,he)|0,o=o+Math.imul(P,fe)|0;var xe=(u+(n=n+Math.imul(j,pe)|0)|0)+((8191&(i=(i=i+Math.imul(j,me)|0)+Math.imul(z,pe)|0))<<13)|0;u=((o=o+Math.imul(z,me)|0)+(i>>>13)|0)+(xe>>>26)|0,xe&=67108863,n=Math.imul(I,ce),i=(i=Math.imul(I,ue))+Math.imul(L,ce)|0,o=Math.imul(L,ue),n=n+Math.imul(T,he)|0,i=(i=i+Math.imul(T,fe)|0)+Math.imul(F,he)|0,o=o+Math.imul(F,fe)|0;var De=(u+(n=n+Math.imul(D,pe)|0)|0)+((8191&(i=(i=i+Math.imul(D,me)|0)+Math.imul(P,pe)|0))<<13)|0;u=((o=o+Math.imul(P,me)|0)+(i>>>13)|0)+(De>>>26)|0,De&=67108863,n=Math.imul(I,he),i=(i=Math.imul(I,fe))+Math.imul(L,he)|0,o=Math.imul(L,fe);var Pe=(u+(n=n+Math.imul(T,pe)|0)|0)+((8191&(i=(i=i+Math.imul(T,me)|0)+Math.imul(F,pe)|0))<<13)|0;u=((o=o+Math.imul(F,me)|0)+(i>>>13)|0)+(Pe>>>26)|0,Pe&=67108863;var Re=(u+(n=Math.imul(I,pe))|0)+((8191&(i=(i=Math.imul(I,me))+Math.imul(L,pe)|0))<<13)|0;return u=((o=Math.imul(L,me))+(i>>>13)|0)+(Re>>>26)|0,Re&=67108863,c[0]=be,c[1]=ve,c[2]=ge,c[3]=ye,c[4]=we,c[5]=Me,c[6]=_e,c[7]=Oe,c[8]=ke,c[9]=Ee,c[10]=Se,c[11]=Ae,c[12]=Ce,c[13]=je,c[14]=ze,c[15]=xe,c[16]=De,c[17]=Pe,c[18]=Re,0!==u&&(c[19]=u,r.length++),r};function p(e,t,r){return(new m).mulp(e,t,r)}function m(e,t){this.x=e,this.y=t}Math.imul||(d=f),o.prototype.mulTo=function(e,t){var r=this.length+e.length;return 10===this.length&&10===e.length?d(this,e,t):r<63?f(this,e,t):r<1024?function(e,t,r){r.negative=t.negative^e.negative,r.length=e.length+t.length;for(var n=0,i=0,o=0;o>>26)|0)>>>26,a&=67108863}r.words[o]=s,n=a,a=i}return 0!==n?r.words[o]=n:r.length--,r.strip()}(this,e,t):p(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),r=o.prototype._countBits(e)-1,n=0;n>=1;return n},m.prototype.permute=function(e,t,r,n,i,o){for(var a=0;a>>=1)i++;return 1<>>=13,r[2*a+1]=8191&o,o>>>=13;for(a=2*t;a>=26,t+=i/67108864|0,t+=o>>>26,this.words[r]=67108863&o}return 0!==t&&(this.words[r]=t,this.length++),this},o.prototype.muln=function(e){return this.clone().imuln(e)},o.prototype.sqr=function(){return this.mul(this)},o.prototype.isqr=function(){return this.imul(this.clone())},o.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),r=0;r>>i}return t}(e);if(0===t.length)return new o(1);for(var r=this,n=0;n=0);var t,r=e%26,i=(e-r)/26,o=67108863>>>26-r<<26-r;if(0!==r){var a=0;for(t=0;t>>26-r}a&&(this.words[t]=a,this.length++)}if(0!==i){for(t=this.length-1;t>=0;t--)this.words[t+i]=this.words[t];for(t=0;t=0),i=t?(t-t%26)/26:0;var o=e%26,a=Math.min((e-o)/26,this.length),s=67108863^67108863>>>o<a)for(this.length-=a,u=0;u=0&&(0!==l||u>=i);u--){var h=0|this.words[u];this.words[u]=l<<26-o|h>>>o,l=h&s}return c&&0!==l&&(c.words[c.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},o.prototype.ishrn=function(e,t,r){return n(0===this.negative),this.iushrn(e,t,r)},o.prototype.shln=function(e){return this.clone().ishln(e)},o.prototype.ushln=function(e){return this.clone().iushln(e)},o.prototype.shrn=function(e){return this.clone().ishrn(e)},o.prototype.ushrn=function(e){return this.clone().iushrn(e)},o.prototype.testn=function(e){n("number"==typeof e&&e>=0);var t=e%26,r=(e-t)/26,i=1<=0);var t=e%26,r=(e-t)/26;if(n(0===this.negative,"imaskn works only with positive numbers"),this.length<=r)return this;if(0!==t&&r++,this.length=Math.min(r,this.length),0!==t){var i=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},o.prototype.isubn=function(e){if(n("number"==typeof e),n(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(c/67108864|0),this.words[i+r]=67108863&o}for(;i>26,this.words[i+r]=67108863&o;if(0===s)return this.strip();for(n(-1===s),s=0,i=0;i>26,this.words[i]=67108863&o;return this.negative=1,this.strip()},o.prototype._wordDiv=function(e,t){var r=(this.length,e.length),n=this.clone(),i=e,a=0|i.words[i.length-1];0!==(r=26-this._countBits(a))&&(i=i.ushln(r),n.iushln(r),a=0|i.words[i.length-1]);var s,c=n.length-i.length;if("mod"!==t){(s=new o(null)).length=c+1,s.words=new Array(s.length);for(var u=0;u=0;h--){var f=67108864*(0|n.words[i.length+h])+(0|n.words[i.length+h-1]);for(f=Math.min(f/a|0,67108863),n._ishlnsubmul(i,f,h);0!==n.negative;)f--,n.negative=0,n._ishlnsubmul(i,1,h),n.isZero()||(n.negative^=1);s&&(s.words[h]=f)}return s&&s.strip(),n.strip(),"div"!==t&&0!==r&&n.iushrn(r),{div:s||null,mod:n}},o.prototype.divmod=function(e,t,r){return n(!e.isZero()),this.isZero()?{div:new o(0),mod:new o(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(i=s.div.neg()),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.iadd(e)),{div:i,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new o(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new o(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new o(this.modn(e.words[0]))}:this._wordDiv(e,t);var i,a,s},o.prototype.div=function(e){return this.divmod(e,"div",!1).div},o.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},o.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},o.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var r=0!==t.div.negative?t.mod.isub(e):t.mod,n=e.ushrn(1),i=e.andln(1),o=r.cmp(n);return o<0||1===i&&0===o?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},o.prototype.modn=function(e){n(e<=67108863);for(var t=(1<<26)%e,r=0,i=this.length-1;i>=0;i--)r=(t*r+(0|this.words[i]))%e;return r},o.prototype.idivn=function(e){n(e<=67108863);for(var t=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*t;this.words[r]=i/e|0,t=i%e}return this.strip()},o.prototype.divn=function(e){return this.clone().idivn(e)},o.prototype.egcd=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i=new o(1),a=new o(0),s=new o(0),c=new o(1),u=0;t.isEven()&&r.isEven();)t.iushrn(1),r.iushrn(1),++u;for(var l=r.clone(),h=t.clone();!t.isZero();){for(var f=0,d=1;0==(t.words[0]&d)&&f<26;++f,d<<=1);if(f>0)for(t.iushrn(f);f-- >0;)(i.isOdd()||a.isOdd())&&(i.iadd(l),a.isub(h)),i.iushrn(1),a.iushrn(1);for(var p=0,m=1;0==(r.words[0]&m)&&p<26;++p,m<<=1);if(p>0)for(r.iushrn(p);p-- >0;)(s.isOdd()||c.isOdd())&&(s.iadd(l),c.isub(h)),s.iushrn(1),c.iushrn(1);t.cmp(r)>=0?(t.isub(r),i.isub(s),a.isub(c)):(r.isub(t),s.isub(i),c.isub(a))}return{a:s,b:c,gcd:r.iushln(u)}},o.prototype._invmp=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i,a=new o(1),s=new o(0),c=r.clone();t.cmpn(1)>0&&r.cmpn(1)>0;){for(var u=0,l=1;0==(t.words[0]&l)&&u<26;++u,l<<=1);if(u>0)for(t.iushrn(u);u-- >0;)a.isOdd()&&a.iadd(c),a.iushrn(1);for(var h=0,f=1;0==(r.words[0]&f)&&h<26;++h,f<<=1);if(h>0)for(r.iushrn(h);h-- >0;)s.isOdd()&&s.iadd(c),s.iushrn(1);t.cmp(r)>=0?(t.isub(r),a.isub(s)):(r.isub(t),s.isub(a))}return(i=0===t.cmpn(1)?a:s).cmpn(0)<0&&i.iadd(e),i},o.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),r=e.clone();t.negative=0,r.negative=0;for(var n=0;t.isEven()&&r.isEven();n++)t.iushrn(1),r.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;r.isEven();)r.iushrn(1);var i=t.cmp(r);if(i<0){var o=t;t=r,r=o}else if(0===i||0===r.cmpn(1))break;t.isub(r)}return r.iushln(n)},o.prototype.invm=function(e){return this.egcd(e).a.umod(e)},o.prototype.isEven=function(){return 0==(1&this.words[0])},o.prototype.isOdd=function(){return 1==(1&this.words[0])},o.prototype.andln=function(e){return this.words[0]&e},o.prototype.bincn=function(e){n("number"==typeof e);var t=e%26,r=(e-t)/26,i=1<>>26,s&=67108863,this.words[a]=s}return 0!==o&&(this.words[a]=o,this.length++),this},o.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},o.prototype.cmpn=function(e){var t,r=e<0;if(0!==this.negative&&!r)return-1;if(0===this.negative&&r)return 1;if(this.strip(),this.length>1)t=1;else{r&&(e=-e),n(e<=67108863,"Number is too big");var i=0|this.words[0];t=i===e?0:ie.length)return 1;if(this.length=0;r--){var n=0|this.words[r],i=0|e.words[r];if(n!==i){ni&&(t=1);break}}return t},o.prototype.gtn=function(e){return 1===this.cmpn(e)},o.prototype.gt=function(e){return 1===this.cmp(e)},o.prototype.gten=function(e){return this.cmpn(e)>=0},o.prototype.gte=function(e){return this.cmp(e)>=0},o.prototype.ltn=function(e){return-1===this.cmpn(e)},o.prototype.lt=function(e){return-1===this.cmp(e)},o.prototype.lten=function(e){return this.cmpn(e)<=0},o.prototype.lte=function(e){return this.cmp(e)<=0},o.prototype.eqn=function(e){return 0===this.cmpn(e)},o.prototype.eq=function(e){return 0===this.cmp(e)},o.red=function(e){return new _(e)},o.prototype.toRed=function(e){return n(!this.red,"Already a number in reduction context"),n(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},o.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},o.prototype._forceRed=function(e){return this.red=e,this},o.prototype.forceRed=function(e){return n(!this.red,"Already a number in reduction context"),this._forceRed(e)},o.prototype.redAdd=function(e){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},o.prototype.redIAdd=function(e){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},o.prototype.redSub=function(e){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},o.prototype.redISub=function(e){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},o.prototype.redShl=function(e){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},o.prototype.redMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},o.prototype.redIMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},o.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},o.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},o.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},o.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},o.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},o.prototype.redPow=function(e){return n(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var b={k256:null,p224:null,p192:null,p25519:null};function v(e,t){this.name=e,this.p=new o(t,16),this.n=this.p.bitLength(),this.k=new o(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function g(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function y(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function w(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function M(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function _(e){if("string"==typeof e){var t=o._prime(e);this.m=t.p,this.prime=t}else n(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function O(e){_.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new o(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var e=new o(null);return e.words=new Array(Math.ceil(this.n/13)),e},v.prototype.ireduce=function(e){var t,r=e;do{this.split(r,this.tmp),t=(r=(r=this.imulK(r)).iadd(this.tmp)).bitLength()}while(t>this.n);var n=t0?r.isub(this.p):void 0!==r.strip?r.strip():r._strip(),r},v.prototype.split=function(e,t){e.iushrn(this.n,0,t)},v.prototype.imulK=function(e){return e.imul(this.k)},i(g,v),g.prototype.split=function(e,t){for(var r=Math.min(e.length,9),n=0;n>>22,i=o}i>>>=22,e.words[n-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},g.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,r=0;r>>=26,e.words[r]=i,t=n}return 0!==t&&(e.words[e.length++]=t),e},o._prime=function(e){if(b[e])return b[e];var t;if("k256"===e)t=new g;else if("p224"===e)t=new y;else if("p192"===e)t=new w;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new M}return b[e]=t,t},_.prototype._verify1=function(e){n(0===e.negative,"red works only with positives"),n(e.red,"red works only with red numbers")},_.prototype._verify2=function(e,t){n(0==(e.negative|t.negative),"red works only with positives"),n(e.red&&e.red===t.red,"red works only with red numbers")},_.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},_.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},_.prototype.add=function(e,t){this._verify2(e,t);var r=e.add(t);return r.cmp(this.m)>=0&&r.isub(this.m),r._forceRed(this)},_.prototype.iadd=function(e,t){this._verify2(e,t);var r=e.iadd(t);return r.cmp(this.m)>=0&&r.isub(this.m),r},_.prototype.sub=function(e,t){this._verify2(e,t);var r=e.sub(t);return r.cmpn(0)<0&&r.iadd(this.m),r._forceRed(this)},_.prototype.isub=function(e,t){this._verify2(e,t);var r=e.isub(t);return r.cmpn(0)<0&&r.iadd(this.m),r},_.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},_.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},_.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},_.prototype.isqr=function(e){return this.imul(e,e.clone())},_.prototype.sqr=function(e){return this.mul(e,e)},_.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(n(t%2==1),3===t){var r=this.m.add(new o(1)).iushrn(2);return this.pow(e,r)}for(var i=this.m.subn(1),a=0;!i.isZero()&&0===i.andln(1);)a++,i.iushrn(1);n(!i.isZero());var s=new o(1).toRed(this),c=s.redNeg(),u=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new o(2*l*l).toRed(this);0!==this.pow(l,u).cmp(c);)l.redIAdd(c);for(var h=this.pow(l,i),f=this.pow(e,i.addn(1).iushrn(1)),d=this.pow(e,i),p=a;0!==d.cmp(s);){for(var m=d,b=0;0!==m.cmp(s);b++)m=m.redSqr();n(b=0;n--){for(var u=t.words[n],l=c-1;l>=0;l--){var h=u>>l&1;i!==r[0]&&(i=this.sqr(i)),0!==h||0!==a?(a<<=1,a|=h,(4===++s||0===n&&0===l)&&(i=this.mul(i,r[a]),s=0,a=0)):s=0}c=26}return i},_.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},_.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},o.mont=function(e){return new O(e)},i(O,_),O.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},O.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},O.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var r=e.imul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},O.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new o(0)._forceRed(this);var r=e.mul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},O.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e,this)}).call(this,r(80)(e))},function(e,t){},function(e,t){},function(e){e.exports=JSON.parse('{"modp1":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff"},"modp2":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff"},"modp5":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff"},"modp14":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff"},"modp15":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"},"modp16":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff"},"modp17":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"},"modp18":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"}}')},function(e,t,r){(function(t){var n=r(253),i=new(r(254)),o=new n(24),a=new n(11),s=new n(10),c=new n(3),u=new n(7),l=r(252),h=r(106);function f(e,r){return r=r||"utf8",t.isBuffer(e)||(e=new t(e,r)),this._pub=new n(e),this}function d(e,r){return r=r||"utf8",t.isBuffer(e)||(e=new t(e,r)),this._priv=new n(e),this}e.exports=m;var p={};function m(e,t,r){this.setGenerator(t),this.__prime=new n(e),this._prime=n.mont(this.__prime),this._primeLen=e.length,this._pub=void 0,this._priv=void 0,this._primeCode=void 0,r?(this.setPublicKey=f,this.setPrivateKey=d):this._primeCode=8}function b(e,r){var n=new t(e.toArray());return r?n.toString(r):n}Object.defineProperty(m.prototype,"verifyError",{enumerable:!0,get:function(){return"number"!=typeof this._primeCode&&(this._primeCode=function(e,t){var r=t.toString("hex"),n=[r,e.toString(16)].join("_");if(n in p)return p[n];var h,f=0;if(e.isEven()||!l.simpleSieve||!l.fermatTest(e)||!i.test(e))return f+=1,f+="02"===r||"05"===r?8:4,p[n]=f,f;switch(i.test(e.shrn(1))||(f+=2),r){case"02":e.mod(o).cmp(a)&&(f+=8);break;case"05":(h=e.mod(s)).cmp(c)&&h.cmp(u)&&(f+=8);break;default:f+=4}return p[n]=f,f}(this.__prime,this.__gen)),this._primeCode}}),m.prototype.generateKeys=function(){return this._priv||(this._priv=new n(h(this._primeLen))),this._pub=this._gen.toRed(this._prime).redPow(this._priv).fromRed(),this.getPublicKey()},m.prototype.computeSecret=function(e){var r=(e=(e=new n(e)).toRed(this._prime)).redPow(this._priv).fromRed(),i=new t(r.toArray()),o=this.getPrime();if(i.length0?this.tail.next=t:this.head=t,this.tail=t,++this.length}},{key:"unshift",value:function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length}},{key:"shift",value:function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(e){if(0===this.length)return"";for(var t=this.head,r=""+t.data;t=t.next;)r+=e+t.data;return r}},{key:"concat",value:function(e){if(0===this.length)return a.alloc(0);for(var t,r,n,i=a.allocUnsafe(e>>>0),o=this.head,s=0;o;)t=o.data,r=i,n=s,a.prototype.copy.call(t,r,n),s+=o.data.length,o=o.next;return i}},{key:"consume",value:function(e,t){var r;return ei.length?i.length:e;if(o===i.length?n+=i:n+=i.slice(0,e),0==(e-=o)){o===i.length?(++r,t.next?this.head=t.next:this.head=this.tail=null):(this.head=t,t.data=i.slice(o));break}++r}return this.length-=r,n}},{key:"_getBuffer",value:function(e){var t=a.allocUnsafe(e),r=this.head,n=1;for(r.data.copy(t),e-=r.data.length;r=r.next;){var i=r.data,o=e>i.length?i.length:e;if(i.copy(t,t.length-e,0,o),0==(e-=o)){o===i.length?(++n,r.next?this.head=r.next:this.head=this.tail=null):(this.head=r,r.data=i.slice(o));break}++n}return this.length-=n,t}},{key:c,value:function(e,t){return s(this,function(e){for(var t=1;t0,(function(e){n||(n=e),e&&a.forEach(u),o||(a.forEach(u),i(n))}))}));return t.reduce(l)}},function(e,t,r){var n=r(178).Buffer,i=r(237),o=r(180),a=r(181).ec,s=r(266),c=r(152),u=r(273);function l(e,t,r,o){if((e=n.from(e.toArray())).length0&&r.ishrn(n),r}function f(e,t,r){var o,a;do{for(o=n.alloc(0);8*o.length=49&&a<=54?a-49+10:a>=17&&a<=22?a-17+10:15&a}return n}function c(e,t,r,n){for(var i=0,o=Math.min(e.length,r),a=t;a=49?s-49+10:s>=17?s-17+10:s}return i}o.isBN=function(e){return e instanceof o||null!==e&&"object"==typeof e&&e.constructor.wordSize===o.wordSize&&Array.isArray(e.words)},o.max=function(e,t){return e.cmp(t)>0?e:t},o.min=function(e,t){return e.cmp(t)<0?e:t},o.prototype._init=function(e,t,r){if("number"==typeof e)return this._initNumber(e,t,r);if("object"==typeof e)return this._initArray(e,t,r);"hex"===t&&(t=16),n(t===(0|t)&&t>=2&&t<=36);var i=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&i++,16===t?this._parseHex(e,i):this._parseBase(e,t,i),"-"===e[0]&&(this.negative=1),this.strip(),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initNumber=function(e,t,r){e<0&&(this.negative=1,e=-e),e<67108864?(this.words=[67108863&e],this.length=1):e<4503599627370496?(this.words=[67108863&e,e/67108864&67108863],this.length=2):(n(e<9007199254740992),this.words=[67108863&e,e/67108864&67108863,1],this.length=3),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initArray=function(e,t,r){if(n("number"==typeof e.length),e.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(e.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)a=e[i]|e[i-1]<<8|e[i-2]<<16,this.words[o]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);else if("le"===r)for(i=0,o=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);return this.strip()},o.prototype._parseHex=function(e,t){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var r=0;r=t;r-=6)i=s(e,r,r+6),this.words[n]|=i<>>26-o&4194303,(o+=24)>=26&&(o-=26,n++);r+6!==t&&(i=s(e,t,r+6),this.words[n]|=i<>>26-o&4194303),this.strip()},o.prototype._parseBase=function(e,t,r){this.words=[0],this.length=1;for(var n=0,i=1;i<=67108863;i*=t)n++;n--,i=i/t|0;for(var o=e.length-r,a=o%n,s=Math.min(o,o-a)+r,u=0,l=r;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},o.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},o.prototype.inspect=function(){return(this.red?""};var u=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],l=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function f(e,t,r){r.negative=t.negative^e.negative;var n=e.length+t.length|0;r.length=n,n=n-1|0;var i=0|e.words[0],o=0|t.words[0],a=i*o,s=67108863&a,c=a/67108864|0;r.words[0]=s;for(var u=1;u>>26,h=67108863&c,f=Math.min(u,t.length-1),d=Math.max(0,u-e.length+1);d<=f;d++){var p=u-d|0;l+=(a=(i=0|e.words[p])*(o=0|t.words[d])+h)/67108864|0,h=67108863&a}r.words[u]=0|h,c=0|l}return 0!==c?r.words[u]=0|c:r.length--,r.strip()}o.prototype.toString=function(e,t){var r;if(t=0|t||1,16===(e=e||10)||"hex"===e){r="";for(var i=0,o=0,a=0;a>>24-i&16777215)||a!==this.length-1?u[6-c.length]+c+r:c+r,(i+=2)>=26&&(i-=26,a--)}for(0!==o&&(r=o.toString(16)+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}if(e===(0|e)&&e>=2&&e<=36){var f=l[e],d=h[e];r="";var p=this.clone();for(p.negative=0;!p.isZero();){var m=p.modn(d).toString(e);r=(p=p.idivn(d)).isZero()?m+r:u[f-m.length]+m+r}for(this.isZero()&&(r="0"+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}n(!1,"Base should be between 2 and 36")},o.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&n(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},o.prototype.toJSON=function(){return this.toString(16)},o.prototype.toBuffer=function(e,t){return n(void 0!==a),this.toArrayLike(a,e,t)},o.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},o.prototype.toArrayLike=function(e,t,r){var i=this.byteLength(),o=r||Math.max(1,i);n(i<=o,"byte array longer than desired length"),n(o>0,"Requested array length <= 0"),this.strip();var a,s,c="le"===t,u=new e(o),l=this.clone();if(c){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),u[s]=a;for(;s=4096&&(r+=13,t>>>=13),t>=64&&(r+=7,t>>>=7),t>=8&&(r+=4,t>>>=4),t>=2&&(r+=2,t>>>=2),r+t},o.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,r=0;return 0==(8191&t)&&(r+=13,t>>>=13),0==(127&t)&&(r+=7,t>>>=7),0==(15&t)&&(r+=4,t>>>=4),0==(3&t)&&(r+=2,t>>>=2),0==(1&t)&&r++,r},o.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},o.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},o.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},o.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var r=0;re.length?this.clone().iand(e):e.clone().iand(this)},o.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},o.prototype.iuxor=function(e){var t,r;this.length>e.length?(t=this,r=e):(t=e,r=this);for(var n=0;ne.length?this.clone().ixor(e):e.clone().ixor(this)},o.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},o.prototype.inotn=function(e){n("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),r=e%26;this._expand(t),r>0&&t--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-r),this.strip()},o.prototype.notn=function(e){return this.clone().inotn(e)},o.prototype.setn=function(e,t){n("number"==typeof e&&e>=0);var r=e/26|0,i=e%26;return this._expand(r+1),this.words[r]=t?this.words[r]|1<e.length?(r=this,n=e):(r=e,n=this);for(var i=0,o=0;o>>26;for(;0!==i&&o>>26;if(this.length=r.length,0!==i)this.words[this.length]=i,this.length++;else if(r!==this)for(;oe.length?this.clone().iadd(e):e.clone().iadd(this)},o.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var r,n,i=this.cmp(e);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(r=this,n=e):(r=e,n=this);for(var o=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==o&&a>26,this.words[a]=67108863&t;if(0===o&&a>>13,d=0|a[1],p=8191&d,m=d>>>13,b=0|a[2],v=8191&b,g=b>>>13,y=0|a[3],w=8191&y,M=y>>>13,_=0|a[4],O=8191&_,k=_>>>13,E=0|a[5],S=8191&E,A=E>>>13,C=0|a[6],j=8191&C,z=C>>>13,x=0|a[7],D=8191&x,P=x>>>13,R=0|a[8],T=8191&R,F=R>>>13,N=0|a[9],I=8191&N,L=N>>>13,B=0|s[0],H=8191&B,q=B>>>13,V=0|s[1],U=8191&V,W=V>>>13,K=0|s[2],G=8191&K,X=K>>>13,Y=0|s[3],Z=8191&Y,$=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],re=8191&te,ne=te>>>13,ie=0|s[6],oe=8191&ie,ae=ie>>>13,se=0|s[7],ce=8191&se,ue=se>>>13,le=0|s[8],he=8191&le,fe=le>>>13,de=0|s[9],pe=8191&de,me=de>>>13;r.negative=e.negative^t.negative,r.length=19;var be=(u+(n=Math.imul(h,H))|0)+((8191&(i=(i=Math.imul(h,q))+Math.imul(f,H)|0))<<13)|0;u=((o=Math.imul(f,q))+(i>>>13)|0)+(be>>>26)|0,be&=67108863,n=Math.imul(p,H),i=(i=Math.imul(p,q))+Math.imul(m,H)|0,o=Math.imul(m,q);var ve=(u+(n=n+Math.imul(h,U)|0)|0)+((8191&(i=(i=i+Math.imul(h,W)|0)+Math.imul(f,U)|0))<<13)|0;u=((o=o+Math.imul(f,W)|0)+(i>>>13)|0)+(ve>>>26)|0,ve&=67108863,n=Math.imul(v,H),i=(i=Math.imul(v,q))+Math.imul(g,H)|0,o=Math.imul(g,q),n=n+Math.imul(p,U)|0,i=(i=i+Math.imul(p,W)|0)+Math.imul(m,U)|0,o=o+Math.imul(m,W)|0;var ge=(u+(n=n+Math.imul(h,G)|0)|0)+((8191&(i=(i=i+Math.imul(h,X)|0)+Math.imul(f,G)|0))<<13)|0;u=((o=o+Math.imul(f,X)|0)+(i>>>13)|0)+(ge>>>26)|0,ge&=67108863,n=Math.imul(w,H),i=(i=Math.imul(w,q))+Math.imul(M,H)|0,o=Math.imul(M,q),n=n+Math.imul(v,U)|0,i=(i=i+Math.imul(v,W)|0)+Math.imul(g,U)|0,o=o+Math.imul(g,W)|0,n=n+Math.imul(p,G)|0,i=(i=i+Math.imul(p,X)|0)+Math.imul(m,G)|0,o=o+Math.imul(m,X)|0;var ye=(u+(n=n+Math.imul(h,Z)|0)|0)+((8191&(i=(i=i+Math.imul(h,$)|0)+Math.imul(f,Z)|0))<<13)|0;u=((o=o+Math.imul(f,$)|0)+(i>>>13)|0)+(ye>>>26)|0,ye&=67108863,n=Math.imul(O,H),i=(i=Math.imul(O,q))+Math.imul(k,H)|0,o=Math.imul(k,q),n=n+Math.imul(w,U)|0,i=(i=i+Math.imul(w,W)|0)+Math.imul(M,U)|0,o=o+Math.imul(M,W)|0,n=n+Math.imul(v,G)|0,i=(i=i+Math.imul(v,X)|0)+Math.imul(g,G)|0,o=o+Math.imul(g,X)|0,n=n+Math.imul(p,Z)|0,i=(i=i+Math.imul(p,$)|0)+Math.imul(m,Z)|0,o=o+Math.imul(m,$)|0;var we=(u+(n=n+Math.imul(h,Q)|0)|0)+((8191&(i=(i=i+Math.imul(h,ee)|0)+Math.imul(f,Q)|0))<<13)|0;u=((o=o+Math.imul(f,ee)|0)+(i>>>13)|0)+(we>>>26)|0,we&=67108863,n=Math.imul(S,H),i=(i=Math.imul(S,q))+Math.imul(A,H)|0,o=Math.imul(A,q),n=n+Math.imul(O,U)|0,i=(i=i+Math.imul(O,W)|0)+Math.imul(k,U)|0,o=o+Math.imul(k,W)|0,n=n+Math.imul(w,G)|0,i=(i=i+Math.imul(w,X)|0)+Math.imul(M,G)|0,o=o+Math.imul(M,X)|0,n=n+Math.imul(v,Z)|0,i=(i=i+Math.imul(v,$)|0)+Math.imul(g,Z)|0,o=o+Math.imul(g,$)|0,n=n+Math.imul(p,Q)|0,i=(i=i+Math.imul(p,ee)|0)+Math.imul(m,Q)|0,o=o+Math.imul(m,ee)|0;var Me=(u+(n=n+Math.imul(h,re)|0)|0)+((8191&(i=(i=i+Math.imul(h,ne)|0)+Math.imul(f,re)|0))<<13)|0;u=((o=o+Math.imul(f,ne)|0)+(i>>>13)|0)+(Me>>>26)|0,Me&=67108863,n=Math.imul(j,H),i=(i=Math.imul(j,q))+Math.imul(z,H)|0,o=Math.imul(z,q),n=n+Math.imul(S,U)|0,i=(i=i+Math.imul(S,W)|0)+Math.imul(A,U)|0,o=o+Math.imul(A,W)|0,n=n+Math.imul(O,G)|0,i=(i=i+Math.imul(O,X)|0)+Math.imul(k,G)|0,o=o+Math.imul(k,X)|0,n=n+Math.imul(w,Z)|0,i=(i=i+Math.imul(w,$)|0)+Math.imul(M,Z)|0,o=o+Math.imul(M,$)|0,n=n+Math.imul(v,Q)|0,i=(i=i+Math.imul(v,ee)|0)+Math.imul(g,Q)|0,o=o+Math.imul(g,ee)|0,n=n+Math.imul(p,re)|0,i=(i=i+Math.imul(p,ne)|0)+Math.imul(m,re)|0,o=o+Math.imul(m,ne)|0;var _e=(u+(n=n+Math.imul(h,oe)|0)|0)+((8191&(i=(i=i+Math.imul(h,ae)|0)+Math.imul(f,oe)|0))<<13)|0;u=((o=o+Math.imul(f,ae)|0)+(i>>>13)|0)+(_e>>>26)|0,_e&=67108863,n=Math.imul(D,H),i=(i=Math.imul(D,q))+Math.imul(P,H)|0,o=Math.imul(P,q),n=n+Math.imul(j,U)|0,i=(i=i+Math.imul(j,W)|0)+Math.imul(z,U)|0,o=o+Math.imul(z,W)|0,n=n+Math.imul(S,G)|0,i=(i=i+Math.imul(S,X)|0)+Math.imul(A,G)|0,o=o+Math.imul(A,X)|0,n=n+Math.imul(O,Z)|0,i=(i=i+Math.imul(O,$)|0)+Math.imul(k,Z)|0,o=o+Math.imul(k,$)|0,n=n+Math.imul(w,Q)|0,i=(i=i+Math.imul(w,ee)|0)+Math.imul(M,Q)|0,o=o+Math.imul(M,ee)|0,n=n+Math.imul(v,re)|0,i=(i=i+Math.imul(v,ne)|0)+Math.imul(g,re)|0,o=o+Math.imul(g,ne)|0,n=n+Math.imul(p,oe)|0,i=(i=i+Math.imul(p,ae)|0)+Math.imul(m,oe)|0,o=o+Math.imul(m,ae)|0;var Oe=(u+(n=n+Math.imul(h,ce)|0)|0)+((8191&(i=(i=i+Math.imul(h,ue)|0)+Math.imul(f,ce)|0))<<13)|0;u=((o=o+Math.imul(f,ue)|0)+(i>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,n=Math.imul(T,H),i=(i=Math.imul(T,q))+Math.imul(F,H)|0,o=Math.imul(F,q),n=n+Math.imul(D,U)|0,i=(i=i+Math.imul(D,W)|0)+Math.imul(P,U)|0,o=o+Math.imul(P,W)|0,n=n+Math.imul(j,G)|0,i=(i=i+Math.imul(j,X)|0)+Math.imul(z,G)|0,o=o+Math.imul(z,X)|0,n=n+Math.imul(S,Z)|0,i=(i=i+Math.imul(S,$)|0)+Math.imul(A,Z)|0,o=o+Math.imul(A,$)|0,n=n+Math.imul(O,Q)|0,i=(i=i+Math.imul(O,ee)|0)+Math.imul(k,Q)|0,o=o+Math.imul(k,ee)|0,n=n+Math.imul(w,re)|0,i=(i=i+Math.imul(w,ne)|0)+Math.imul(M,re)|0,o=o+Math.imul(M,ne)|0,n=n+Math.imul(v,oe)|0,i=(i=i+Math.imul(v,ae)|0)+Math.imul(g,oe)|0,o=o+Math.imul(g,ae)|0,n=n+Math.imul(p,ce)|0,i=(i=i+Math.imul(p,ue)|0)+Math.imul(m,ce)|0,o=o+Math.imul(m,ue)|0;var ke=(u+(n=n+Math.imul(h,he)|0)|0)+((8191&(i=(i=i+Math.imul(h,fe)|0)+Math.imul(f,he)|0))<<13)|0;u=((o=o+Math.imul(f,fe)|0)+(i>>>13)|0)+(ke>>>26)|0,ke&=67108863,n=Math.imul(I,H),i=(i=Math.imul(I,q))+Math.imul(L,H)|0,o=Math.imul(L,q),n=n+Math.imul(T,U)|0,i=(i=i+Math.imul(T,W)|0)+Math.imul(F,U)|0,o=o+Math.imul(F,W)|0,n=n+Math.imul(D,G)|0,i=(i=i+Math.imul(D,X)|0)+Math.imul(P,G)|0,o=o+Math.imul(P,X)|0,n=n+Math.imul(j,Z)|0,i=(i=i+Math.imul(j,$)|0)+Math.imul(z,Z)|0,o=o+Math.imul(z,$)|0,n=n+Math.imul(S,Q)|0,i=(i=i+Math.imul(S,ee)|0)+Math.imul(A,Q)|0,o=o+Math.imul(A,ee)|0,n=n+Math.imul(O,re)|0,i=(i=i+Math.imul(O,ne)|0)+Math.imul(k,re)|0,o=o+Math.imul(k,ne)|0,n=n+Math.imul(w,oe)|0,i=(i=i+Math.imul(w,ae)|0)+Math.imul(M,oe)|0,o=o+Math.imul(M,ae)|0,n=n+Math.imul(v,ce)|0,i=(i=i+Math.imul(v,ue)|0)+Math.imul(g,ce)|0,o=o+Math.imul(g,ue)|0,n=n+Math.imul(p,he)|0,i=(i=i+Math.imul(p,fe)|0)+Math.imul(m,he)|0,o=o+Math.imul(m,fe)|0;var Ee=(u+(n=n+Math.imul(h,pe)|0)|0)+((8191&(i=(i=i+Math.imul(h,me)|0)+Math.imul(f,pe)|0))<<13)|0;u=((o=o+Math.imul(f,me)|0)+(i>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,n=Math.imul(I,U),i=(i=Math.imul(I,W))+Math.imul(L,U)|0,o=Math.imul(L,W),n=n+Math.imul(T,G)|0,i=(i=i+Math.imul(T,X)|0)+Math.imul(F,G)|0,o=o+Math.imul(F,X)|0,n=n+Math.imul(D,Z)|0,i=(i=i+Math.imul(D,$)|0)+Math.imul(P,Z)|0,o=o+Math.imul(P,$)|0,n=n+Math.imul(j,Q)|0,i=(i=i+Math.imul(j,ee)|0)+Math.imul(z,Q)|0,o=o+Math.imul(z,ee)|0,n=n+Math.imul(S,re)|0,i=(i=i+Math.imul(S,ne)|0)+Math.imul(A,re)|0,o=o+Math.imul(A,ne)|0,n=n+Math.imul(O,oe)|0,i=(i=i+Math.imul(O,ae)|0)+Math.imul(k,oe)|0,o=o+Math.imul(k,ae)|0,n=n+Math.imul(w,ce)|0,i=(i=i+Math.imul(w,ue)|0)+Math.imul(M,ce)|0,o=o+Math.imul(M,ue)|0,n=n+Math.imul(v,he)|0,i=(i=i+Math.imul(v,fe)|0)+Math.imul(g,he)|0,o=o+Math.imul(g,fe)|0;var Se=(u+(n=n+Math.imul(p,pe)|0)|0)+((8191&(i=(i=i+Math.imul(p,me)|0)+Math.imul(m,pe)|0))<<13)|0;u=((o=o+Math.imul(m,me)|0)+(i>>>13)|0)+(Se>>>26)|0,Se&=67108863,n=Math.imul(I,G),i=(i=Math.imul(I,X))+Math.imul(L,G)|0,o=Math.imul(L,X),n=n+Math.imul(T,Z)|0,i=(i=i+Math.imul(T,$)|0)+Math.imul(F,Z)|0,o=o+Math.imul(F,$)|0,n=n+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,ee)|0)+Math.imul(P,Q)|0,o=o+Math.imul(P,ee)|0,n=n+Math.imul(j,re)|0,i=(i=i+Math.imul(j,ne)|0)+Math.imul(z,re)|0,o=o+Math.imul(z,ne)|0,n=n+Math.imul(S,oe)|0,i=(i=i+Math.imul(S,ae)|0)+Math.imul(A,oe)|0,o=o+Math.imul(A,ae)|0,n=n+Math.imul(O,ce)|0,i=(i=i+Math.imul(O,ue)|0)+Math.imul(k,ce)|0,o=o+Math.imul(k,ue)|0,n=n+Math.imul(w,he)|0,i=(i=i+Math.imul(w,fe)|0)+Math.imul(M,he)|0,o=o+Math.imul(M,fe)|0;var Ae=(u+(n=n+Math.imul(v,pe)|0)|0)+((8191&(i=(i=i+Math.imul(v,me)|0)+Math.imul(g,pe)|0))<<13)|0;u=((o=o+Math.imul(g,me)|0)+(i>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,n=Math.imul(I,Z),i=(i=Math.imul(I,$))+Math.imul(L,Z)|0,o=Math.imul(L,$),n=n+Math.imul(T,Q)|0,i=(i=i+Math.imul(T,ee)|0)+Math.imul(F,Q)|0,o=o+Math.imul(F,ee)|0,n=n+Math.imul(D,re)|0,i=(i=i+Math.imul(D,ne)|0)+Math.imul(P,re)|0,o=o+Math.imul(P,ne)|0,n=n+Math.imul(j,oe)|0,i=(i=i+Math.imul(j,ae)|0)+Math.imul(z,oe)|0,o=o+Math.imul(z,ae)|0,n=n+Math.imul(S,ce)|0,i=(i=i+Math.imul(S,ue)|0)+Math.imul(A,ce)|0,o=o+Math.imul(A,ue)|0,n=n+Math.imul(O,he)|0,i=(i=i+Math.imul(O,fe)|0)+Math.imul(k,he)|0,o=o+Math.imul(k,fe)|0;var Ce=(u+(n=n+Math.imul(w,pe)|0)|0)+((8191&(i=(i=i+Math.imul(w,me)|0)+Math.imul(M,pe)|0))<<13)|0;u=((o=o+Math.imul(M,me)|0)+(i>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,n=Math.imul(I,Q),i=(i=Math.imul(I,ee))+Math.imul(L,Q)|0,o=Math.imul(L,ee),n=n+Math.imul(T,re)|0,i=(i=i+Math.imul(T,ne)|0)+Math.imul(F,re)|0,o=o+Math.imul(F,ne)|0,n=n+Math.imul(D,oe)|0,i=(i=i+Math.imul(D,ae)|0)+Math.imul(P,oe)|0,o=o+Math.imul(P,ae)|0,n=n+Math.imul(j,ce)|0,i=(i=i+Math.imul(j,ue)|0)+Math.imul(z,ce)|0,o=o+Math.imul(z,ue)|0,n=n+Math.imul(S,he)|0,i=(i=i+Math.imul(S,fe)|0)+Math.imul(A,he)|0,o=o+Math.imul(A,fe)|0;var je=(u+(n=n+Math.imul(O,pe)|0)|0)+((8191&(i=(i=i+Math.imul(O,me)|0)+Math.imul(k,pe)|0))<<13)|0;u=((o=o+Math.imul(k,me)|0)+(i>>>13)|0)+(je>>>26)|0,je&=67108863,n=Math.imul(I,re),i=(i=Math.imul(I,ne))+Math.imul(L,re)|0,o=Math.imul(L,ne),n=n+Math.imul(T,oe)|0,i=(i=i+Math.imul(T,ae)|0)+Math.imul(F,oe)|0,o=o+Math.imul(F,ae)|0,n=n+Math.imul(D,ce)|0,i=(i=i+Math.imul(D,ue)|0)+Math.imul(P,ce)|0,o=o+Math.imul(P,ue)|0,n=n+Math.imul(j,he)|0,i=(i=i+Math.imul(j,fe)|0)+Math.imul(z,he)|0,o=o+Math.imul(z,fe)|0;var ze=(u+(n=n+Math.imul(S,pe)|0)|0)+((8191&(i=(i=i+Math.imul(S,me)|0)+Math.imul(A,pe)|0))<<13)|0;u=((o=o+Math.imul(A,me)|0)+(i>>>13)|0)+(ze>>>26)|0,ze&=67108863,n=Math.imul(I,oe),i=(i=Math.imul(I,ae))+Math.imul(L,oe)|0,o=Math.imul(L,ae),n=n+Math.imul(T,ce)|0,i=(i=i+Math.imul(T,ue)|0)+Math.imul(F,ce)|0,o=o+Math.imul(F,ue)|0,n=n+Math.imul(D,he)|0,i=(i=i+Math.imul(D,fe)|0)+Math.imul(P,he)|0,o=o+Math.imul(P,fe)|0;var xe=(u+(n=n+Math.imul(j,pe)|0)|0)+((8191&(i=(i=i+Math.imul(j,me)|0)+Math.imul(z,pe)|0))<<13)|0;u=((o=o+Math.imul(z,me)|0)+(i>>>13)|0)+(xe>>>26)|0,xe&=67108863,n=Math.imul(I,ce),i=(i=Math.imul(I,ue))+Math.imul(L,ce)|0,o=Math.imul(L,ue),n=n+Math.imul(T,he)|0,i=(i=i+Math.imul(T,fe)|0)+Math.imul(F,he)|0,o=o+Math.imul(F,fe)|0;var De=(u+(n=n+Math.imul(D,pe)|0)|0)+((8191&(i=(i=i+Math.imul(D,me)|0)+Math.imul(P,pe)|0))<<13)|0;u=((o=o+Math.imul(P,me)|0)+(i>>>13)|0)+(De>>>26)|0,De&=67108863,n=Math.imul(I,he),i=(i=Math.imul(I,fe))+Math.imul(L,he)|0,o=Math.imul(L,fe);var Pe=(u+(n=n+Math.imul(T,pe)|0)|0)+((8191&(i=(i=i+Math.imul(T,me)|0)+Math.imul(F,pe)|0))<<13)|0;u=((o=o+Math.imul(F,me)|0)+(i>>>13)|0)+(Pe>>>26)|0,Pe&=67108863;var Re=(u+(n=Math.imul(I,pe))|0)+((8191&(i=(i=Math.imul(I,me))+Math.imul(L,pe)|0))<<13)|0;return u=((o=Math.imul(L,me))+(i>>>13)|0)+(Re>>>26)|0,Re&=67108863,c[0]=be,c[1]=ve,c[2]=ge,c[3]=ye,c[4]=we,c[5]=Me,c[6]=_e,c[7]=Oe,c[8]=ke,c[9]=Ee,c[10]=Se,c[11]=Ae,c[12]=Ce,c[13]=je,c[14]=ze,c[15]=xe,c[16]=De,c[17]=Pe,c[18]=Re,0!==u&&(c[19]=u,r.length++),r};function p(e,t,r){return(new m).mulp(e,t,r)}function m(e,t){this.x=e,this.y=t}Math.imul||(d=f),o.prototype.mulTo=function(e,t){var r=this.length+e.length;return 10===this.length&&10===e.length?d(this,e,t):r<63?f(this,e,t):r<1024?function(e,t,r){r.negative=t.negative^e.negative,r.length=e.length+t.length;for(var n=0,i=0,o=0;o>>26)|0)>>>26,a&=67108863}r.words[o]=s,n=a,a=i}return 0!==n?r.words[o]=n:r.length--,r.strip()}(this,e,t):p(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),r=o.prototype._countBits(e)-1,n=0;n>=1;return n},m.prototype.permute=function(e,t,r,n,i,o){for(var a=0;a>>=1)i++;return 1<>>=13,r[2*a+1]=8191&o,o>>>=13;for(a=2*t;a>=26,t+=i/67108864|0,t+=o>>>26,this.words[r]=67108863&o}return 0!==t&&(this.words[r]=t,this.length++),this},o.prototype.muln=function(e){return this.clone().imuln(e)},o.prototype.sqr=function(){return this.mul(this)},o.prototype.isqr=function(){return this.imul(this.clone())},o.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),r=0;r>>i}return t}(e);if(0===t.length)return new o(1);for(var r=this,n=0;n=0);var t,r=e%26,i=(e-r)/26,o=67108863>>>26-r<<26-r;if(0!==r){var a=0;for(t=0;t>>26-r}a&&(this.words[t]=a,this.length++)}if(0!==i){for(t=this.length-1;t>=0;t--)this.words[t+i]=this.words[t];for(t=0;t=0),i=t?(t-t%26)/26:0;var o=e%26,a=Math.min((e-o)/26,this.length),s=67108863^67108863>>>o<a)for(this.length-=a,u=0;u=0&&(0!==l||u>=i);u--){var h=0|this.words[u];this.words[u]=l<<26-o|h>>>o,l=h&s}return c&&0!==l&&(c.words[c.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},o.prototype.ishrn=function(e,t,r){return n(0===this.negative),this.iushrn(e,t,r)},o.prototype.shln=function(e){return this.clone().ishln(e)},o.prototype.ushln=function(e){return this.clone().iushln(e)},o.prototype.shrn=function(e){return this.clone().ishrn(e)},o.prototype.ushrn=function(e){return this.clone().iushrn(e)},o.prototype.testn=function(e){n("number"==typeof e&&e>=0);var t=e%26,r=(e-t)/26,i=1<=0);var t=e%26,r=(e-t)/26;if(n(0===this.negative,"imaskn works only with positive numbers"),this.length<=r)return this;if(0!==t&&r++,this.length=Math.min(r,this.length),0!==t){var i=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},o.prototype.isubn=function(e){if(n("number"==typeof e),n(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(c/67108864|0),this.words[i+r]=67108863&o}for(;i>26,this.words[i+r]=67108863&o;if(0===s)return this.strip();for(n(-1===s),s=0,i=0;i>26,this.words[i]=67108863&o;return this.negative=1,this.strip()},o.prototype._wordDiv=function(e,t){var r=(this.length,e.length),n=this.clone(),i=e,a=0|i.words[i.length-1];0!==(r=26-this._countBits(a))&&(i=i.ushln(r),n.iushln(r),a=0|i.words[i.length-1]);var s,c=n.length-i.length;if("mod"!==t){(s=new o(null)).length=c+1,s.words=new Array(s.length);for(var u=0;u=0;h--){var f=67108864*(0|n.words[i.length+h])+(0|n.words[i.length+h-1]);for(f=Math.min(f/a|0,67108863),n._ishlnsubmul(i,f,h);0!==n.negative;)f--,n.negative=0,n._ishlnsubmul(i,1,h),n.isZero()||(n.negative^=1);s&&(s.words[h]=f)}return s&&s.strip(),n.strip(),"div"!==t&&0!==r&&n.iushrn(r),{div:s||null,mod:n}},o.prototype.divmod=function(e,t,r){return n(!e.isZero()),this.isZero()?{div:new o(0),mod:new o(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(i=s.div.neg()),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.iadd(e)),{div:i,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new o(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new o(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new o(this.modn(e.words[0]))}:this._wordDiv(e,t);var i,a,s},o.prototype.div=function(e){return this.divmod(e,"div",!1).div},o.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},o.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},o.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var r=0!==t.div.negative?t.mod.isub(e):t.mod,n=e.ushrn(1),i=e.andln(1),o=r.cmp(n);return o<0||1===i&&0===o?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},o.prototype.modn=function(e){n(e<=67108863);for(var t=(1<<26)%e,r=0,i=this.length-1;i>=0;i--)r=(t*r+(0|this.words[i]))%e;return r},o.prototype.idivn=function(e){n(e<=67108863);for(var t=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*t;this.words[r]=i/e|0,t=i%e}return this.strip()},o.prototype.divn=function(e){return this.clone().idivn(e)},o.prototype.egcd=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i=new o(1),a=new o(0),s=new o(0),c=new o(1),u=0;t.isEven()&&r.isEven();)t.iushrn(1),r.iushrn(1),++u;for(var l=r.clone(),h=t.clone();!t.isZero();){for(var f=0,d=1;0==(t.words[0]&d)&&f<26;++f,d<<=1);if(f>0)for(t.iushrn(f);f-- >0;)(i.isOdd()||a.isOdd())&&(i.iadd(l),a.isub(h)),i.iushrn(1),a.iushrn(1);for(var p=0,m=1;0==(r.words[0]&m)&&p<26;++p,m<<=1);if(p>0)for(r.iushrn(p);p-- >0;)(s.isOdd()||c.isOdd())&&(s.iadd(l),c.isub(h)),s.iushrn(1),c.iushrn(1);t.cmp(r)>=0?(t.isub(r),i.isub(s),a.isub(c)):(r.isub(t),s.isub(i),c.isub(a))}return{a:s,b:c,gcd:r.iushln(u)}},o.prototype._invmp=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i,a=new o(1),s=new o(0),c=r.clone();t.cmpn(1)>0&&r.cmpn(1)>0;){for(var u=0,l=1;0==(t.words[0]&l)&&u<26;++u,l<<=1);if(u>0)for(t.iushrn(u);u-- >0;)a.isOdd()&&a.iadd(c),a.iushrn(1);for(var h=0,f=1;0==(r.words[0]&f)&&h<26;++h,f<<=1);if(h>0)for(r.iushrn(h);h-- >0;)s.isOdd()&&s.iadd(c),s.iushrn(1);t.cmp(r)>=0?(t.isub(r),a.isub(s)):(r.isub(t),s.isub(a))}return(i=0===t.cmpn(1)?a:s).cmpn(0)<0&&i.iadd(e),i},o.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),r=e.clone();t.negative=0,r.negative=0;for(var n=0;t.isEven()&&r.isEven();n++)t.iushrn(1),r.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;r.isEven();)r.iushrn(1);var i=t.cmp(r);if(i<0){var o=t;t=r,r=o}else if(0===i||0===r.cmpn(1))break;t.isub(r)}return r.iushln(n)},o.prototype.invm=function(e){return this.egcd(e).a.umod(e)},o.prototype.isEven=function(){return 0==(1&this.words[0])},o.prototype.isOdd=function(){return 1==(1&this.words[0])},o.prototype.andln=function(e){return this.words[0]&e},o.prototype.bincn=function(e){n("number"==typeof e);var t=e%26,r=(e-t)/26,i=1<>>26,s&=67108863,this.words[a]=s}return 0!==o&&(this.words[a]=o,this.length++),this},o.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},o.prototype.cmpn=function(e){var t,r=e<0;if(0!==this.negative&&!r)return-1;if(0===this.negative&&r)return 1;if(this.strip(),this.length>1)t=1;else{r&&(e=-e),n(e<=67108863,"Number is too big");var i=0|this.words[0];t=i===e?0:ie.length)return 1;if(this.length=0;r--){var n=0|this.words[r],i=0|e.words[r];if(n!==i){ni&&(t=1);break}}return t},o.prototype.gtn=function(e){return 1===this.cmpn(e)},o.prototype.gt=function(e){return 1===this.cmp(e)},o.prototype.gten=function(e){return this.cmpn(e)>=0},o.prototype.gte=function(e){return this.cmp(e)>=0},o.prototype.ltn=function(e){return-1===this.cmpn(e)},o.prototype.lt=function(e){return-1===this.cmp(e)},o.prototype.lten=function(e){return this.cmpn(e)<=0},o.prototype.lte=function(e){return this.cmp(e)<=0},o.prototype.eqn=function(e){return 0===this.cmpn(e)},o.prototype.eq=function(e){return 0===this.cmp(e)},o.red=function(e){return new _(e)},o.prototype.toRed=function(e){return n(!this.red,"Already a number in reduction context"),n(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},o.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},o.prototype._forceRed=function(e){return this.red=e,this},o.prototype.forceRed=function(e){return n(!this.red,"Already a number in reduction context"),this._forceRed(e)},o.prototype.redAdd=function(e){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},o.prototype.redIAdd=function(e){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},o.prototype.redSub=function(e){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},o.prototype.redISub=function(e){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},o.prototype.redShl=function(e){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},o.prototype.redMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},o.prototype.redIMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},o.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},o.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},o.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},o.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},o.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},o.prototype.redPow=function(e){return n(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var b={k256:null,p224:null,p192:null,p25519:null};function v(e,t){this.name=e,this.p=new o(t,16),this.n=this.p.bitLength(),this.k=new o(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function g(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function y(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function w(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function M(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function _(e){if("string"==typeof e){var t=o._prime(e);this.m=t.p,this.prime=t}else n(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function O(e){_.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new o(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var e=new o(null);return e.words=new Array(Math.ceil(this.n/13)),e},v.prototype.ireduce=function(e){var t,r=e;do{this.split(r,this.tmp),t=(r=(r=this.imulK(r)).iadd(this.tmp)).bitLength()}while(t>this.n);var n=t0?r.isub(this.p):void 0!==r.strip?r.strip():r._strip(),r},v.prototype.split=function(e,t){e.iushrn(this.n,0,t)},v.prototype.imulK=function(e){return e.imul(this.k)},i(g,v),g.prototype.split=function(e,t){for(var r=Math.min(e.length,9),n=0;n>>22,i=o}i>>>=22,e.words[n-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},g.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,r=0;r>>=26,e.words[r]=i,t=n}return 0!==t&&(e.words[e.length++]=t),e},o._prime=function(e){if(b[e])return b[e];var t;if("k256"===e)t=new g;else if("p224"===e)t=new y;else if("p192"===e)t=new w;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new M}return b[e]=t,t},_.prototype._verify1=function(e){n(0===e.negative,"red works only with positives"),n(e.red,"red works only with red numbers")},_.prototype._verify2=function(e,t){n(0==(e.negative|t.negative),"red works only with positives"),n(e.red&&e.red===t.red,"red works only with red numbers")},_.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},_.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},_.prototype.add=function(e,t){this._verify2(e,t);var r=e.add(t);return r.cmp(this.m)>=0&&r.isub(this.m),r._forceRed(this)},_.prototype.iadd=function(e,t){this._verify2(e,t);var r=e.iadd(t);return r.cmp(this.m)>=0&&r.isub(this.m),r},_.prototype.sub=function(e,t){this._verify2(e,t);var r=e.sub(t);return r.cmpn(0)<0&&r.iadd(this.m),r._forceRed(this)},_.prototype.isub=function(e,t){this._verify2(e,t);var r=e.isub(t);return r.cmpn(0)<0&&r.iadd(this.m),r},_.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},_.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},_.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},_.prototype.isqr=function(e){return this.imul(e,e.clone())},_.prototype.sqr=function(e){return this.mul(e,e)},_.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(n(t%2==1),3===t){var r=this.m.add(new o(1)).iushrn(2);return this.pow(e,r)}for(var i=this.m.subn(1),a=0;!i.isZero()&&0===i.andln(1);)a++,i.iushrn(1);n(!i.isZero());var s=new o(1).toRed(this),c=s.redNeg(),u=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new o(2*l*l).toRed(this);0!==this.pow(l,u).cmp(c);)l.redIAdd(c);for(var h=this.pow(l,i),f=this.pow(e,i.addn(1).iushrn(1)),d=this.pow(e,i),p=a;0!==d.cmp(s);){for(var m=d,b=0;0!==m.cmp(s);b++)m=m.redSqr();n(b=0;n--){for(var u=t.words[n],l=c-1;l>=0;l--){var h=u>>l&1;i!==r[0]&&(i=this.sqr(i)),0!==h||0!==a?(a<<=1,a|=h,(4===++s||0===n&&0===l)&&(i=this.mul(i,r[a]),s=0,a=0)):s=0}c=26}return i},_.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},_.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},o.mont=function(e){return new O(e)},i(O,_),O.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},O.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},O.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var r=e.imul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},O.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new o(0)._forceRed(this);var r=e.mul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},O.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e,this)}).call(this,r(80)(e))},function(e,t){},function(e){e.exports=JSON.parse('{"_args":[["elliptic@6.5.3","/Users/timmyc/code/woocommerce-admin"]],"_development":true,"_from":"elliptic@6.5.3","_id":"elliptic@6.5.3","_inBundle":false,"_integrity":"sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==","_location":"/elliptic","_phantomChildren":{},"_requested":{"type":"version","registry":true,"raw":"elliptic@6.5.3","name":"elliptic","escapedName":"elliptic","rawSpec":"6.5.3","saveSpec":null,"fetchSpec":"6.5.3"},"_requiredBy":["/browserify-sign","/create-ecdh"],"_resolved":"https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz","_spec":"6.5.3","_where":"/Users/timmyc/code/woocommerce-admin","author":{"name":"Fedor Indutny","email":"fedor@indutny.com"},"bugs":{"url":"https://github.com/indutny/elliptic/issues"},"dependencies":{"bn.js":"^4.4.0","brorand":"^1.0.1","hash.js":"^1.0.0","hmac-drbg":"^1.0.0","inherits":"^2.0.1","minimalistic-assert":"^1.0.0","minimalistic-crypto-utils":"^1.0.0"},"description":"EC cryptography","devDependencies":{"brfs":"^1.4.3","coveralls":"^3.0.8","grunt":"^1.0.4","grunt-browserify":"^5.0.0","grunt-cli":"^1.2.0","grunt-contrib-connect":"^1.0.0","grunt-contrib-copy":"^1.0.0","grunt-contrib-uglify":"^1.0.1","grunt-mocha-istanbul":"^3.0.1","grunt-saucelabs":"^9.0.1","istanbul":"^0.4.2","jscs":"^3.0.7","jshint":"^2.10.3","mocha":"^6.2.2"},"files":["lib"],"homepage":"https://github.com/indutny/elliptic","keywords":["EC","Elliptic","curve","Cryptography"],"license":"MIT","main":"lib/elliptic.js","name":"elliptic","repository":{"type":"git","url":"git+ssh://git@github.com/indutny/elliptic.git"},"scripts":{"jscs":"jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js","jshint":"jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js","lint":"npm run jscs && npm run jshint","test":"npm run lint && npm run unit","unit":"istanbul test _mocha --reporter=spec test/index.js","version":"grunt dist && git add dist/"},"version":"6.5.3"}')},function(e,t){},function(e,t,r){"use strict";var n=r(66),i=r(75),o=r(25),a=r(151),s=n.assert;function c(e){a.call(this,"short",e),this.a=new i(e.a,16).toRed(this.red),this.b=new i(e.b,16).toRed(this.red),this.tinv=this.two.redInvm(),this.zeroA=0===this.a.fromRed().cmpn(0),this.threeA=0===this.a.fromRed().sub(this.p).cmpn(-3),this.endo=this._getEndomorphism(e),this._endoWnafT1=new Array(4),this._endoWnafT2=new Array(4)}function u(e,t,r,n){a.BasePoint.call(this,e,"affine"),null===t&&null===r?(this.x=null,this.y=null,this.inf=!0):(this.x=new i(t,16),this.y=new i(r,16),n&&(this.x.forceRed(this.curve.red),this.y.forceRed(this.curve.red)),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.inf=!1)}function l(e,t,r,n){a.BasePoint.call(this,e,"jacobian"),null===t&&null===r&&null===n?(this.x=this.curve.one,this.y=this.curve.one,this.z=new i(0)):(this.x=new i(t,16),this.y=new i(r,16),this.z=new i(n,16)),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)),this.zOne=this.z===this.curve.one}o(c,a),e.exports=c,c.prototype._getEndomorphism=function(e){if(this.zeroA&&this.g&&this.n&&1===this.p.modn(3)){var t,r;if(e.beta)t=new i(e.beta,16).toRed(this.red);else{var n=this._getEndoRoots(this.p);t=(t=n[0].cmp(n[1])<0?n[0]:n[1]).toRed(this.red)}if(e.lambda)r=new i(e.lambda,16);else{var o=this._getEndoRoots(this.n);0===this.g.mul(o[0]).x.cmp(this.g.x.redMul(t))?r=o[0]:(r=o[1],s(0===this.g.mul(r).x.cmp(this.g.x.redMul(t))))}return{beta:t,lambda:r,basis:e.basis?e.basis.map((function(e){return{a:new i(e.a,16),b:new i(e.b,16)}})):this._getEndoBasis(r)}}},c.prototype._getEndoRoots=function(e){var t=e===this.p?this.red:i.mont(e),r=new i(2).toRed(t).redInvm(),n=r.redNeg(),o=new i(3).toRed(t).redNeg().redSqrt().redMul(r);return[n.redAdd(o).fromRed(),n.redSub(o).fromRed()]},c.prototype._getEndoBasis=function(e){for(var t,r,n,o,a,s,c,u,l,h=this.n.ushrn(Math.floor(this.n.bitLength()/2)),f=e,d=this.n.clone(),p=new i(1),m=new i(0),b=new i(0),v=new i(1),g=0;0!==f.cmpn(0);){var y=d.div(f);u=d.sub(y.mul(f)),l=b.sub(y.mul(p));var w=v.sub(y.mul(m));if(!n&&u.cmp(h)<0)t=c.neg(),r=p,n=u.neg(),o=l;else if(n&&2==++g)break;c=u,d=f,f=u,b=p,p=l,v=m,m=w}a=u.neg(),s=l;var M=n.sqr().add(o.sqr());return a.sqr().add(s.sqr()).cmp(M)>=0&&(a=t,s=r),n.negative&&(n=n.neg(),o=o.neg()),a.negative&&(a=a.neg(),s=s.neg()),[{a:n,b:o},{a:a,b:s}]},c.prototype._endoSplit=function(e){var t=this.endo.basis,r=t[0],n=t[1],i=n.b.mul(e).divRound(this.n),o=r.b.neg().mul(e).divRound(this.n),a=i.mul(r.a),s=o.mul(n.a),c=i.mul(r.b),u=o.mul(n.b);return{k1:e.sub(a).sub(s),k2:c.add(u).neg()}},c.prototype.pointFromX=function(e,t){(e=new i(e,16)).red||(e=e.toRed(this.red));var r=e.redSqr().redMul(e).redIAdd(e.redMul(this.a)).redIAdd(this.b),n=r.redSqrt();if(0!==n.redSqr().redSub(r).cmp(this.zero))throw new Error("invalid point");var o=n.fromRed().isOdd();return(t&&!o||!t&&o)&&(n=n.redNeg()),this.point(e,n)},c.prototype.validate=function(e){if(e.inf)return!0;var t=e.x,r=e.y,n=this.a.redMul(t),i=t.redSqr().redMul(t).redIAdd(n).redIAdd(this.b);return 0===r.redSqr().redISub(i).cmpn(0)},c.prototype._endoWnafMulAdd=function(e,t,r){for(var n=this._endoWnafT1,i=this._endoWnafT2,o=0;o":""},u.prototype.isInfinity=function(){return this.inf},u.prototype.add=function(e){if(this.inf)return e;if(e.inf)return this;if(this.eq(e))return this.dbl();if(this.neg().eq(e))return this.curve.point(null,null);if(0===this.x.cmp(e.x))return this.curve.point(null,null);var t=this.y.redSub(e.y);0!==t.cmpn(0)&&(t=t.redMul(this.x.redSub(e.x).redInvm()));var r=t.redSqr().redISub(this.x).redISub(e.x),n=t.redMul(this.x.redSub(r)).redISub(this.y);return this.curve.point(r,n)},u.prototype.dbl=function(){if(this.inf)return this;var e=this.y.redAdd(this.y);if(0===e.cmpn(0))return this.curve.point(null,null);var t=this.curve.a,r=this.x.redSqr(),n=e.redInvm(),i=r.redAdd(r).redIAdd(r).redIAdd(t).redMul(n),o=i.redSqr().redISub(this.x.redAdd(this.x)),a=i.redMul(this.x.redSub(o)).redISub(this.y);return this.curve.point(o,a)},u.prototype.getX=function(){return this.x.fromRed()},u.prototype.getY=function(){return this.y.fromRed()},u.prototype.mul=function(e){return e=new i(e,16),this.isInfinity()?this:this._hasDoubles(e)?this.curve._fixedNafMul(this,e):this.curve.endo?this.curve._endoWnafMulAdd([this],[e]):this.curve._wnafMul(this,e)},u.prototype.mulAdd=function(e,t,r){var n=[this,t],i=[e,r];return this.curve.endo?this.curve._endoWnafMulAdd(n,i):this.curve._wnafMulAdd(1,n,i,2)},u.prototype.jmulAdd=function(e,t,r){var n=[this,t],i=[e,r];return this.curve.endo?this.curve._endoWnafMulAdd(n,i,!0):this.curve._wnafMulAdd(1,n,i,2,!0)},u.prototype.eq=function(e){return this===e||this.inf===e.inf&&(this.inf||0===this.x.cmp(e.x)&&0===this.y.cmp(e.y))},u.prototype.neg=function(e){if(this.inf)return this;var t=this.curve.point(this.x,this.y.redNeg());if(e&&this.precomputed){var r=this.precomputed,n=function(e){return e.neg()};t.precomputed={naf:r.naf&&{wnd:r.naf.wnd,points:r.naf.points.map(n)},doubles:r.doubles&&{step:r.doubles.step,points:r.doubles.points.map(n)}}}return t},u.prototype.toJ=function(){return this.inf?this.curve.jpoint(null,null,null):this.curve.jpoint(this.x,this.y,this.curve.one)},o(l,a.BasePoint),c.prototype.jpoint=function(e,t,r){return new l(this,e,t,r)},l.prototype.toP=function(){if(this.isInfinity())return this.curve.point(null,null);var e=this.z.redInvm(),t=e.redSqr(),r=this.x.redMul(t),n=this.y.redMul(t).redMul(e);return this.curve.point(r,n)},l.prototype.neg=function(){return this.curve.jpoint(this.x,this.y.redNeg(),this.z)},l.prototype.add=function(e){if(this.isInfinity())return e;if(e.isInfinity())return this;var t=e.z.redSqr(),r=this.z.redSqr(),n=this.x.redMul(t),i=e.x.redMul(r),o=this.y.redMul(t.redMul(e.z)),a=e.y.redMul(r.redMul(this.z)),s=n.redSub(i),c=o.redSub(a);if(0===s.cmpn(0))return 0!==c.cmpn(0)?this.curve.jpoint(null,null,null):this.dbl();var u=s.redSqr(),l=u.redMul(s),h=n.redMul(u),f=c.redSqr().redIAdd(l).redISub(h).redISub(h),d=c.redMul(h.redISub(f)).redISub(o.redMul(l)),p=this.z.redMul(e.z).redMul(s);return this.curve.jpoint(f,d,p)},l.prototype.mixedAdd=function(e){if(this.isInfinity())return e.toJ();if(e.isInfinity())return this;var t=this.z.redSqr(),r=this.x,n=e.x.redMul(t),i=this.y,o=e.y.redMul(t).redMul(this.z),a=r.redSub(n),s=i.redSub(o);if(0===a.cmpn(0))return 0!==s.cmpn(0)?this.curve.jpoint(null,null,null):this.dbl();var c=a.redSqr(),u=c.redMul(a),l=r.redMul(c),h=s.redSqr().redIAdd(u).redISub(l).redISub(l),f=s.redMul(l.redISub(h)).redISub(i.redMul(u)),d=this.z.redMul(a);return this.curve.jpoint(h,f,d)},l.prototype.dblp=function(e){if(0===e)return this;if(this.isInfinity())return this;if(!e)return this.dbl();if(this.curve.zeroA||this.curve.threeA){for(var t=this,r=0;r=0)return!1;if(r.redIAdd(i),0===this.x.cmp(r))return!0}},l.prototype.inspect=function(){return this.isInfinity()?"":""},l.prototype.isInfinity=function(){return 0===this.z.cmpn(0)}},function(e,t,r){"use strict";var n=r(75),i=r(25),o=r(151),a=r(66);function s(e){o.call(this,"mont",e),this.a=new n(e.a,16).toRed(this.red),this.b=new n(e.b,16).toRed(this.red),this.i4=new n(4).toRed(this.red).redInvm(),this.two=new n(2).toRed(this.red),this.a24=this.i4.redMul(this.a.redAdd(this.two))}function c(e,t,r){o.BasePoint.call(this,e,"projective"),null===t&&null===r?(this.x=this.curve.one,this.z=this.curve.zero):(this.x=new n(t,16),this.z=new n(r,16),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)))}i(s,o),e.exports=s,s.prototype.validate=function(e){var t=e.normalize().x,r=t.redSqr(),n=r.redMul(t).redAdd(r.redMul(this.a)).redAdd(t);return 0===n.redSqrt().redSqr().cmp(n)},i(c,o.BasePoint),s.prototype.decodePoint=function(e,t){return this.point(a.toArray(e,t),1)},s.prototype.point=function(e,t){return new c(this,e,t)},s.prototype.pointFromJSON=function(e){return c.fromJSON(this,e)},c.prototype.precompute=function(){},c.prototype._encode=function(){return this.getX().toArray("be",this.curve.p.byteLength())},c.fromJSON=function(e,t){return new c(e,t[0],t[1]||e.one)},c.prototype.inspect=function(){return this.isInfinity()?"":""},c.prototype.isInfinity=function(){return 0===this.z.cmpn(0)},c.prototype.dbl=function(){var e=this.x.redAdd(this.z).redSqr(),t=this.x.redSub(this.z).redSqr(),r=e.redSub(t),n=e.redMul(t),i=r.redMul(t.redAdd(this.curve.a24.redMul(r)));return this.curve.point(n,i)},c.prototype.add=function(){throw new Error("Not supported on Montgomery curve")},c.prototype.diffAdd=function(e,t){var r=this.x.redAdd(this.z),n=this.x.redSub(this.z),i=e.x.redAdd(e.z),o=e.x.redSub(e.z).redMul(r),a=i.redMul(n),s=t.z.redMul(o.redAdd(a).redSqr()),c=t.x.redMul(o.redISub(a).redSqr());return this.curve.point(s,c)},c.prototype.mul=function(e){for(var t=e.clone(),r=this,n=this.curve.point(null,null),i=[];0!==t.cmpn(0);t.iushrn(1))i.push(t.andln(1));for(var o=i.length-1;o>=0;o--)0===i[o]?(r=r.diffAdd(n,this),n=n.dbl()):(n=r.diffAdd(n,this),r=r.dbl());return n},c.prototype.mulAdd=function(){throw new Error("Not supported on Montgomery curve")},c.prototype.jumlAdd=function(){throw new Error("Not supported on Montgomery curve")},c.prototype.eq=function(e){return 0===this.getX().cmp(e.getX())},c.prototype.normalize=function(){return this.x=this.x.redMul(this.z.redInvm()),this.z=this.curve.one,this},c.prototype.getX=function(){return this.normalize(),this.x.fromRed()}},function(e,t,r){"use strict";var n=r(66),i=r(75),o=r(25),a=r(151),s=n.assert;function c(e){this.twisted=1!=(0|e.a),this.mOneA=this.twisted&&-1==(0|e.a),this.extended=this.mOneA,a.call(this,"edwards",e),this.a=new i(e.a,16).umod(this.red.m),this.a=this.a.toRed(this.red),this.c=new i(e.c,16).toRed(this.red),this.c2=this.c.redSqr(),this.d=new i(e.d,16).toRed(this.red),this.dd=this.d.redAdd(this.d),s(!this.twisted||0===this.c.fromRed().cmpn(1)),this.oneC=1==(0|e.c)}function u(e,t,r,n,o){a.BasePoint.call(this,e,"projective"),null===t&&null===r&&null===n?(this.x=this.curve.zero,this.y=this.curve.one,this.z=this.curve.one,this.t=this.curve.zero,this.zOne=!0):(this.x=new i(t,16),this.y=new i(r,16),this.z=n?new i(n,16):this.curve.one,this.t=o&&new i(o,16),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)),this.t&&!this.t.red&&(this.t=this.t.toRed(this.curve.red)),this.zOne=this.z===this.curve.one,this.curve.extended&&!this.t&&(this.t=this.x.redMul(this.y),this.zOne||(this.t=this.t.redMul(this.z.redInvm()))))}o(c,a),e.exports=c,c.prototype._mulA=function(e){return this.mOneA?e.redNeg():this.a.redMul(e)},c.prototype._mulC=function(e){return this.oneC?e:this.c.redMul(e)},c.prototype.jpoint=function(e,t,r,n){return this.point(e,t,r,n)},c.prototype.pointFromX=function(e,t){(e=new i(e,16)).red||(e=e.toRed(this.red));var r=e.redSqr(),n=this.c2.redSub(this.a.redMul(r)),o=this.one.redSub(this.c2.redMul(this.d).redMul(r)),a=n.redMul(o.redInvm()),s=a.redSqrt();if(0!==s.redSqr().redSub(a).cmp(this.zero))throw new Error("invalid point");var c=s.fromRed().isOdd();return(t&&!c||!t&&c)&&(s=s.redNeg()),this.point(e,s)},c.prototype.pointFromY=function(e,t){(e=new i(e,16)).red||(e=e.toRed(this.red));var r=e.redSqr(),n=r.redSub(this.c2),o=r.redMul(this.d).redMul(this.c2).redSub(this.a),a=n.redMul(o.redInvm());if(0===a.cmp(this.zero)){if(t)throw new Error("invalid point");return this.point(this.zero,e)}var s=a.redSqrt();if(0!==s.redSqr().redSub(a).cmp(this.zero))throw new Error("invalid point");return s.fromRed().isOdd()!==t&&(s=s.redNeg()),this.point(s,e)},c.prototype.validate=function(e){if(e.isInfinity())return!0;e.normalize();var t=e.x.redSqr(),r=e.y.redSqr(),n=t.redMul(this.a).redAdd(r),i=this.c2.redMul(this.one.redAdd(this.d.redMul(t).redMul(r)));return 0===n.cmp(i)},o(u,a.BasePoint),c.prototype.pointFromJSON=function(e){return u.fromJSON(this,e)},c.prototype.point=function(e,t,r,n){return new u(this,e,t,r,n)},u.fromJSON=function(e,t){return new u(e,t[0],t[1],t[2])},u.prototype.inspect=function(){return this.isInfinity()?"":""},u.prototype.isInfinity=function(){return 0===this.x.cmpn(0)&&(0===this.y.cmp(this.z)||this.zOne&&0===this.y.cmp(this.curve.c))},u.prototype._extDbl=function(){var e=this.x.redSqr(),t=this.y.redSqr(),r=this.z.redSqr();r=r.redIAdd(r);var n=this.curve._mulA(e),i=this.x.redAdd(this.y).redSqr().redISub(e).redISub(t),o=n.redAdd(t),a=o.redSub(r),s=n.redSub(t),c=i.redMul(a),u=o.redMul(s),l=i.redMul(s),h=a.redMul(o);return this.curve.point(c,u,h,l)},u.prototype._projDbl=function(){var e,t,r,n=this.x.redAdd(this.y).redSqr(),i=this.x.redSqr(),o=this.y.redSqr();if(this.curve.twisted){var a=(u=this.curve._mulA(i)).redAdd(o);if(this.zOne)e=n.redSub(i).redSub(o).redMul(a.redSub(this.curve.two)),t=a.redMul(u.redSub(o)),r=a.redSqr().redSub(a).redSub(a);else{var s=this.z.redSqr(),c=a.redSub(s).redISub(s);e=n.redSub(i).redISub(o).redMul(c),t=a.redMul(u.redSub(o)),r=a.redMul(c)}}else{var u=i.redAdd(o);s=this.curve._mulC(this.z).redSqr(),c=u.redSub(s).redSub(s);e=this.curve._mulC(n.redISub(u)).redMul(c),t=this.curve._mulC(u).redMul(i.redISub(o)),r=u.redMul(c)}return this.curve.point(e,t,r)},u.prototype.dbl=function(){return this.isInfinity()?this:this.curve.extended?this._extDbl():this._projDbl()},u.prototype._extAdd=function(e){var t=this.y.redSub(this.x).redMul(e.y.redSub(e.x)),r=this.y.redAdd(this.x).redMul(e.y.redAdd(e.x)),n=this.t.redMul(this.curve.dd).redMul(e.t),i=this.z.redMul(e.z.redAdd(e.z)),o=r.redSub(t),a=i.redSub(n),s=i.redAdd(n),c=r.redAdd(t),u=o.redMul(a),l=s.redMul(c),h=o.redMul(c),f=a.redMul(s);return this.curve.point(u,l,f,h)},u.prototype._projAdd=function(e){var t,r,n=this.z.redMul(e.z),i=n.redSqr(),o=this.x.redMul(e.x),a=this.y.redMul(e.y),s=this.curve.d.redMul(o).redMul(a),c=i.redSub(s),u=i.redAdd(s),l=this.x.redAdd(this.y).redMul(e.x.redAdd(e.y)).redISub(o).redISub(a),h=n.redMul(c).redMul(l);return this.curve.twisted?(t=n.redMul(u).redMul(a.redSub(this.curve._mulA(o))),r=c.redMul(u)):(t=n.redMul(u).redMul(a.redSub(o)),r=this.curve._mulC(c).redMul(u)),this.curve.point(h,t,r)},u.prototype.add=function(e){return this.isInfinity()?e:e.isInfinity()?this:this.curve.extended?this._extAdd(e):this._projAdd(e)},u.prototype.mul=function(e){return this._hasDoubles(e)?this.curve._fixedNafMul(this,e):this.curve._wnafMul(this,e)},u.prototype.mulAdd=function(e,t,r){return this.curve._wnafMulAdd(1,[this,t],[e,r],2,!1)},u.prototype.jmulAdd=function(e,t,r){return this.curve._wnafMulAdd(1,[this,t],[e,r],2,!0)},u.prototype.normalize=function(){if(this.zOne)return this;var e=this.z.redInvm();return this.x=this.x.redMul(e),this.y=this.y.redMul(e),this.t&&(this.t=this.t.redMul(e)),this.z=this.curve.one,this.zOne=!0,this},u.prototype.neg=function(){return this.curve.point(this.x.redNeg(),this.y,this.z,this.t&&this.t.redNeg())},u.prototype.getX=function(){return this.normalize(),this.x.fromRed()},u.prototype.getY=function(){return this.normalize(),this.y.fromRed()},u.prototype.eq=function(e){return this===e||0===this.getX().cmp(e.getX())&&0===this.getY().cmp(e.getY())},u.prototype.eqXToP=function(e){var t=e.toRed(this.curve.red).redMul(this.z);if(0===this.x.cmp(t))return!0;for(var r=e.clone(),n=this.curve.redN.redMul(this.z);;){if(r.iadd(this.curve.n),r.cmp(this.curve.p)>=0)return!1;if(t.redIAdd(n),0===this.x.cmp(t))return!0}},u.prototype.toP=u.prototype.normalize,u.prototype.mixedAdd=u.prototype.add},function(e,t,r){"use strict";t.sha1=r(403),t.sha224=r(404),t.sha256=r(264),t.sha384=r(405),t.sha512=r(265)},function(e,t,r){"use strict";var n=r(70),i=r(123),o=r(263),a=n.rotl32,s=n.sum32,c=n.sum32_5,u=o.ft_1,l=i.BlockHash,h=[1518500249,1859775393,2400959708,3395469782];function f(){if(!(this instanceof f))return new f;l.call(this),this.h=[1732584193,4023233417,2562383102,271733878,3285377520],this.W=new Array(80)}n.inherits(f,l),e.exports=f,f.blockSize=512,f.outSize=160,f.hmacStrength=80,f.padLength=64,f.prototype._update=function(e,t){for(var r=this.W,n=0;n<16;n++)r[n]=e[t+n];for(;nthis.blockSize&&(e=(new this.Hash).update(e).digest()),i(e.length<=this.blockSize);for(var t=e.length;t0))return a.iaddn(1),this.keyFromPrivate(a)}},h.prototype._truncateToN=function(e,t){var r=8*e.byteLength()-this.n.bitLength();return r>0&&(e=e.ushrn(r)),!t&&e.cmp(this.n)>=0?e.sub(this.n):e},h.prototype.sign=function(e,t,r,o){"object"==typeof r&&(o=r,r=null),o||(o={}),t=this.keyFromPrivate(t,r),e=this._truncateToN(new n(e,16));for(var a=this.n.byteLength(),s=t.getPrivate().toArray("be",a),c=e.toArray("be",a),u=new i({hash:this.hash,entropy:s,nonce:c,pers:o.pers,persEnc:o.persEnc||"utf8"}),h=this.n.sub(new n(1)),f=0;;f++){var d=o.k?o.k(f):new n(u.generate(this.n.byteLength()));if(!((d=this._truncateToN(d,!0)).cmpn(1)<=0||d.cmp(h)>=0)){var p=this.g.mul(d);if(!p.isInfinity()){var m=p.getX(),b=m.umod(this.n);if(0!==b.cmpn(0)){var v=d.invm(this.n).mul(b.mul(t.getPrivate()).iadd(e));if(0!==(v=v.umod(this.n)).cmpn(0)){var g=(p.getY().isOdd()?1:0)|(0!==m.cmp(b)?2:0);return o.canonical&&v.cmp(this.nh)>0&&(v=this.n.sub(v),g^=1),new l({r:b,s:v,recoveryParam:g})}}}}}},h.prototype.verify=function(e,t,r,i){e=this._truncateToN(new n(e,16)),r=this.keyFromPublic(r,i);var o=(t=new l(t,"hex")).r,a=t.s;if(o.cmpn(1)<0||o.cmp(this.n)>=0)return!1;if(a.cmpn(1)<0||a.cmp(this.n)>=0)return!1;var s,c=a.invm(this.n),u=c.mul(e).umod(this.n),h=c.mul(o).umod(this.n);return this.curve._maxwellTrick?!(s=this.g.jmulAdd(u,r.getPublic(),h)).isInfinity()&&s.eqXToP(o):!(s=this.g.mulAdd(u,r.getPublic(),h)).isInfinity()&&0===s.getX().umod(this.n).cmp(o)},h.prototype.recoverPubKey=function(e,t,r,i){c((3&r)===r,"The recovery param is more than two bits"),t=new l(t,i);var o=this.n,a=new n(e),s=t.r,u=t.s,h=1&r,f=r>>1;if(s.cmp(this.curve.p.umod(this.curve.n))>=0&&f)throw new Error("Unable to find sencond key candinate");s=f?this.curve.pointFromX(s.add(this.curve.n),h):this.curve.pointFromX(s,h);var d=t.r.invm(o),p=o.sub(a).mul(d).umod(o),m=u.mul(d).umod(o);return this.g.mulAdd(p,s,m)},h.prototype.getKeyRecoveryParam=function(e,t,r,n){if(null!==(t=new l(t,n)).recoveryParam)return t.recoveryParam;for(var i=0;i<4;i++){var o;try{o=this.recoverPubKey(e,t,i)}catch(e){continue}if(o.eq(r))return i}throw new Error("Unable to find valid recovery factor")}},function(e,t,r){"use strict";var n=r(183),i=r(261),o=r(65);function a(e){if(!(this instanceof a))return new a(e);this.hash=e.hash,this.predResist=!!e.predResist,this.outLen=this.hash.outSize,this.minEntropy=e.minEntropy||this.hash.hmacStrength,this._reseed=null,this.reseedInterval=null,this.K=null,this.V=null;var t=i.toArray(e.entropy,e.entropyEnc||"hex"),r=i.toArray(e.nonce,e.nonceEnc||"hex"),n=i.toArray(e.pers,e.persEnc||"hex");o(t.length>=this.minEntropy/8,"Not enough entropy. Minimum is: "+this.minEntropy+" bits"),this._init(t,r,n)}e.exports=a,a.prototype._init=function(e,t,r){var n=e.concat(t).concat(r);this.K=new Array(this.outLen/8),this.V=new Array(this.outLen/8);for(var i=0;i=this.minEntropy/8,"Not enough entropy. Minimum is: "+this.minEntropy+" bits"),this._update(e.concat(r||[])),this._reseed=1},a.prototype.generate=function(e,t,r,n){if(this._reseed>this.reseedInterval)throw new Error("Reseed is required");"string"!=typeof t&&(n=r,r=t,t=null),r&&(r=i.toArray(r,n||"hex"),this._update(r));for(var o=[];o.length"}},function(e,t,r){"use strict";var n=r(75),i=r(66),o=i.assert;function a(e,t){if(e instanceof a)return e;this._importDER(e,t)||(o(e.r&&e.s,"Signature without r or s"),this.r=new n(e.r,16),this.s=new n(e.s,16),void 0===e.recoveryParam?this.recoveryParam=null:this.recoveryParam=e.recoveryParam)}function s(){this.place=0}function c(e,t){var r=e[t.place++];if(!(128&r))return r;var n=15&r;if(0===n||n>4)return!1;for(var i=0,o=0,a=t.place;o>>=0;return!(i<=127)&&(t.place=a,i)}function u(e){for(var t=0,r=e.length-1;!e[t]&&!(128&e[t+1])&&t>>3);for(e.push(128|r);--r;)e.push(t>>>(r<<3)&255);e.push(t)}}e.exports=a,a.prototype._importDER=function(e,t){e=i.toArray(e,t);var r=new s;if(48!==e[r.place++])return!1;var o=c(e,r);if(!1===o)return!1;if(o+r.place!==e.length)return!1;if(2!==e[r.place++])return!1;var a=c(e,r);if(!1===a)return!1;var u=e.slice(r.place,a+r.place);if(r.place+=a,2!==e[r.place++])return!1;var l=c(e,r);if(!1===l)return!1;if(e.length!==l+r.place)return!1;var h=e.slice(r.place,l+r.place);if(0===u[0]){if(!(128&u[1]))return!1;u=u.slice(1)}if(0===h[0]){if(!(128&h[1]))return!1;h=h.slice(1)}return this.r=new n(u),this.s=new n(h),this.recoveryParam=null,!0},a.prototype.toDER=function(e){var t=this.r.toArray(),r=this.s.toArray();for(128&t[0]&&(t=[0].concat(t)),128&r[0]&&(r=[0].concat(r)),t=u(t),r=u(r);!(r[0]||128&r[1]);)r=r.slice(1);var n=[2];l(n,t.length),(n=n.concat(t)).push(2),l(n,r.length);var o=n.concat(r),a=[48];return l(a,o.length),a=a.concat(o),i.encode(a,e)}},function(e,t,r){"use strict";var n=r(183),i=r(182),o=r(66),a=o.assert,s=o.parseBytes,c=r(414),u=r(415);function l(e){if(a("ed25519"===e,"only tested with ed25519 so far"),!(this instanceof l))return new l(e);e=i[e].curve;this.curve=e,this.g=e.g,this.g.precompute(e.n.bitLength()+1),this.pointClass=e.point().constructor,this.encodingLength=Math.ceil(e.n.bitLength()/8),this.hash=n.sha512}e.exports=l,l.prototype.sign=function(e,t){e=s(e);var r=this.keyFromSecret(t),n=this.hashInt(r.messagePrefix(),e),i=this.g.mul(n),o=this.encodePoint(i),a=this.hashInt(o,r.pubBytes(),e).mul(r.priv()),c=n.add(a).umod(this.curve.n);return this.makeSignature({R:i,S:c,Rencoded:o})},l.prototype.verify=function(e,t,r){e=s(e),t=this.makeSignature(t);var n=this.keyFromPublic(r),i=this.hashInt(t.Rencoded(),n.pubBytes(),e),o=this.g.mul(t.S());return t.R().add(n.pub().mul(i)).eq(o)},l.prototype.hashInt=function(){for(var e=this.hash(),t=0;t=t)throw new Error("invalid sig")}e.exports=function(e,t,r,u,l){var h=a(r);if("ec"===h.type){if("ecdsa"!==u&&"ecdsa/rsa"!==u)throw new Error("wrong public key type");return function(e,t,r){var n=s[r.data.algorithm.curve.join(".")];if(!n)throw new Error("unknown curve "+r.data.algorithm.curve.join("."));var i=new o(n),a=r.data.subjectPrivateKey.data;return i.verify(t,e,a)}(e,t,h)}if("dsa"===h.type){if("dsa"!==u)throw new Error("wrong public key type");return function(e,t,r){var n=r.data.p,o=r.data.q,s=r.data.g,u=r.data.pub_key,l=a.signature.decode(e,"der"),h=l.s,f=l.r;c(h,o),c(f,o);var d=i.mont(n),p=h.invm(o);return 0===s.toRed(d).redPow(new i(t).mul(p).mod(o)).fromRed().mul(u.toRed(d).redPow(f.mul(p).mod(o)).fromRed()).mod(n).mod(o).cmp(f)}(e,t,h)}if("rsa"!==u&&"ecdsa/rsa"!==u)throw new Error("wrong public key type");t=n.concat([l,t]);for(var f=h.modulus.byteLength(),d=[1],p=0;t.length+d.length+2=49&&a<=54?a-49+10:a>=17&&a<=22?a-17+10:15&a}return n}function c(e,t,r,n){for(var i=0,o=Math.min(e.length,r),a=t;a=49?s-49+10:s>=17?s-17+10:s}return i}o.isBN=function(e){return e instanceof o||null!==e&&"object"==typeof e&&e.constructor.wordSize===o.wordSize&&Array.isArray(e.words)},o.max=function(e,t){return e.cmp(t)>0?e:t},o.min=function(e,t){return e.cmp(t)<0?e:t},o.prototype._init=function(e,t,r){if("number"==typeof e)return this._initNumber(e,t,r);if("object"==typeof e)return this._initArray(e,t,r);"hex"===t&&(t=16),n(t===(0|t)&&t>=2&&t<=36);var i=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&i++,16===t?this._parseHex(e,i):this._parseBase(e,t,i),"-"===e[0]&&(this.negative=1),this.strip(),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initNumber=function(e,t,r){e<0&&(this.negative=1,e=-e),e<67108864?(this.words=[67108863&e],this.length=1):e<4503599627370496?(this.words=[67108863&e,e/67108864&67108863],this.length=2):(n(e<9007199254740992),this.words=[67108863&e,e/67108864&67108863,1],this.length=3),"le"===r&&this._initArray(this.toArray(),t,r)},o.prototype._initArray=function(e,t,r){if(n("number"==typeof e.length),e.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(e.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)a=e[i]|e[i-1]<<8|e[i-2]<<16,this.words[o]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);else if("le"===r)for(i=0,o=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);return this.strip()},o.prototype._parseHex=function(e,t){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var r=0;r=t;r-=6)i=s(e,r,r+6),this.words[n]|=i<>>26-o&4194303,(o+=24)>=26&&(o-=26,n++);r+6!==t&&(i=s(e,t,r+6),this.words[n]|=i<>>26-o&4194303),this.strip()},o.prototype._parseBase=function(e,t,r){this.words=[0],this.length=1;for(var n=0,i=1;i<=67108863;i*=t)n++;n--,i=i/t|0;for(var o=e.length-r,a=o%n,s=Math.min(o,o-a)+r,u=0,l=r;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},o.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},o.prototype.inspect=function(){return(this.red?""};var u=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],l=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function f(e,t,r){r.negative=t.negative^e.negative;var n=e.length+t.length|0;r.length=n,n=n-1|0;var i=0|e.words[0],o=0|t.words[0],a=i*o,s=67108863&a,c=a/67108864|0;r.words[0]=s;for(var u=1;u>>26,h=67108863&c,f=Math.min(u,t.length-1),d=Math.max(0,u-e.length+1);d<=f;d++){var p=u-d|0;l+=(a=(i=0|e.words[p])*(o=0|t.words[d])+h)/67108864|0,h=67108863&a}r.words[u]=0|h,c=0|l}return 0!==c?r.words[u]=0|c:r.length--,r.strip()}o.prototype.toString=function(e,t){var r;if(t=0|t||1,16===(e=e||10)||"hex"===e){r="";for(var i=0,o=0,a=0;a>>24-i&16777215)||a!==this.length-1?u[6-c.length]+c+r:c+r,(i+=2)>=26&&(i-=26,a--)}for(0!==o&&(r=o.toString(16)+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}if(e===(0|e)&&e>=2&&e<=36){var f=l[e],d=h[e];r="";var p=this.clone();for(p.negative=0;!p.isZero();){var m=p.modn(d).toString(e);r=(p=p.idivn(d)).isZero()?m+r:u[f-m.length]+m+r}for(this.isZero()&&(r="0"+r);r.length%t!=0;)r="0"+r;return 0!==this.negative&&(r="-"+r),r}n(!1,"Base should be between 2 and 36")},o.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&n(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},o.prototype.toJSON=function(){return this.toString(16)},o.prototype.toBuffer=function(e,t){return n(void 0!==a),this.toArrayLike(a,e,t)},o.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},o.prototype.toArrayLike=function(e,t,r){var i=this.byteLength(),o=r||Math.max(1,i);n(i<=o,"byte array longer than desired length"),n(o>0,"Requested array length <= 0"),this.strip();var a,s,c="le"===t,u=new e(o),l=this.clone();if(c){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),u[s]=a;for(;s=4096&&(r+=13,t>>>=13),t>=64&&(r+=7,t>>>=7),t>=8&&(r+=4,t>>>=4),t>=2&&(r+=2,t>>>=2),r+t},o.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,r=0;return 0==(8191&t)&&(r+=13,t>>>=13),0==(127&t)&&(r+=7,t>>>=7),0==(15&t)&&(r+=4,t>>>=4),0==(3&t)&&(r+=2,t>>>=2),0==(1&t)&&r++,r},o.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},o.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},o.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},o.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var r=0;re.length?this.clone().iand(e):e.clone().iand(this)},o.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},o.prototype.iuxor=function(e){var t,r;this.length>e.length?(t=this,r=e):(t=e,r=this);for(var n=0;ne.length?this.clone().ixor(e):e.clone().ixor(this)},o.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},o.prototype.inotn=function(e){n("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),r=e%26;this._expand(t),r>0&&t--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-r),this.strip()},o.prototype.notn=function(e){return this.clone().inotn(e)},o.prototype.setn=function(e,t){n("number"==typeof e&&e>=0);var r=e/26|0,i=e%26;return this._expand(r+1),this.words[r]=t?this.words[r]|1<e.length?(r=this,n=e):(r=e,n=this);for(var i=0,o=0;o>>26;for(;0!==i&&o>>26;if(this.length=r.length,0!==i)this.words[this.length]=i,this.length++;else if(r!==this)for(;oe.length?this.clone().iadd(e):e.clone().iadd(this)},o.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var r,n,i=this.cmp(e);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(r=this,n=e):(r=e,n=this);for(var o=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==o&&a>26,this.words[a]=67108863&t;if(0===o&&a>>13,d=0|a[1],p=8191&d,m=d>>>13,b=0|a[2],v=8191&b,g=b>>>13,y=0|a[3],w=8191&y,M=y>>>13,_=0|a[4],O=8191&_,k=_>>>13,E=0|a[5],S=8191&E,A=E>>>13,C=0|a[6],j=8191&C,z=C>>>13,x=0|a[7],D=8191&x,P=x>>>13,R=0|a[8],T=8191&R,F=R>>>13,N=0|a[9],I=8191&N,L=N>>>13,B=0|s[0],H=8191&B,q=B>>>13,V=0|s[1],U=8191&V,W=V>>>13,K=0|s[2],G=8191&K,X=K>>>13,Y=0|s[3],Z=8191&Y,$=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],re=8191&te,ne=te>>>13,ie=0|s[6],oe=8191&ie,ae=ie>>>13,se=0|s[7],ce=8191&se,ue=se>>>13,le=0|s[8],he=8191&le,fe=le>>>13,de=0|s[9],pe=8191&de,me=de>>>13;r.negative=e.negative^t.negative,r.length=19;var be=(u+(n=Math.imul(h,H))|0)+((8191&(i=(i=Math.imul(h,q))+Math.imul(f,H)|0))<<13)|0;u=((o=Math.imul(f,q))+(i>>>13)|0)+(be>>>26)|0,be&=67108863,n=Math.imul(p,H),i=(i=Math.imul(p,q))+Math.imul(m,H)|0,o=Math.imul(m,q);var ve=(u+(n=n+Math.imul(h,U)|0)|0)+((8191&(i=(i=i+Math.imul(h,W)|0)+Math.imul(f,U)|0))<<13)|0;u=((o=o+Math.imul(f,W)|0)+(i>>>13)|0)+(ve>>>26)|0,ve&=67108863,n=Math.imul(v,H),i=(i=Math.imul(v,q))+Math.imul(g,H)|0,o=Math.imul(g,q),n=n+Math.imul(p,U)|0,i=(i=i+Math.imul(p,W)|0)+Math.imul(m,U)|0,o=o+Math.imul(m,W)|0;var ge=(u+(n=n+Math.imul(h,G)|0)|0)+((8191&(i=(i=i+Math.imul(h,X)|0)+Math.imul(f,G)|0))<<13)|0;u=((o=o+Math.imul(f,X)|0)+(i>>>13)|0)+(ge>>>26)|0,ge&=67108863,n=Math.imul(w,H),i=(i=Math.imul(w,q))+Math.imul(M,H)|0,o=Math.imul(M,q),n=n+Math.imul(v,U)|0,i=(i=i+Math.imul(v,W)|0)+Math.imul(g,U)|0,o=o+Math.imul(g,W)|0,n=n+Math.imul(p,G)|0,i=(i=i+Math.imul(p,X)|0)+Math.imul(m,G)|0,o=o+Math.imul(m,X)|0;var ye=(u+(n=n+Math.imul(h,Z)|0)|0)+((8191&(i=(i=i+Math.imul(h,$)|0)+Math.imul(f,Z)|0))<<13)|0;u=((o=o+Math.imul(f,$)|0)+(i>>>13)|0)+(ye>>>26)|0,ye&=67108863,n=Math.imul(O,H),i=(i=Math.imul(O,q))+Math.imul(k,H)|0,o=Math.imul(k,q),n=n+Math.imul(w,U)|0,i=(i=i+Math.imul(w,W)|0)+Math.imul(M,U)|0,o=o+Math.imul(M,W)|0,n=n+Math.imul(v,G)|0,i=(i=i+Math.imul(v,X)|0)+Math.imul(g,G)|0,o=o+Math.imul(g,X)|0,n=n+Math.imul(p,Z)|0,i=(i=i+Math.imul(p,$)|0)+Math.imul(m,Z)|0,o=o+Math.imul(m,$)|0;var we=(u+(n=n+Math.imul(h,Q)|0)|0)+((8191&(i=(i=i+Math.imul(h,ee)|0)+Math.imul(f,Q)|0))<<13)|0;u=((o=o+Math.imul(f,ee)|0)+(i>>>13)|0)+(we>>>26)|0,we&=67108863,n=Math.imul(S,H),i=(i=Math.imul(S,q))+Math.imul(A,H)|0,o=Math.imul(A,q),n=n+Math.imul(O,U)|0,i=(i=i+Math.imul(O,W)|0)+Math.imul(k,U)|0,o=o+Math.imul(k,W)|0,n=n+Math.imul(w,G)|0,i=(i=i+Math.imul(w,X)|0)+Math.imul(M,G)|0,o=o+Math.imul(M,X)|0,n=n+Math.imul(v,Z)|0,i=(i=i+Math.imul(v,$)|0)+Math.imul(g,Z)|0,o=o+Math.imul(g,$)|0,n=n+Math.imul(p,Q)|0,i=(i=i+Math.imul(p,ee)|0)+Math.imul(m,Q)|0,o=o+Math.imul(m,ee)|0;var Me=(u+(n=n+Math.imul(h,re)|0)|0)+((8191&(i=(i=i+Math.imul(h,ne)|0)+Math.imul(f,re)|0))<<13)|0;u=((o=o+Math.imul(f,ne)|0)+(i>>>13)|0)+(Me>>>26)|0,Me&=67108863,n=Math.imul(j,H),i=(i=Math.imul(j,q))+Math.imul(z,H)|0,o=Math.imul(z,q),n=n+Math.imul(S,U)|0,i=(i=i+Math.imul(S,W)|0)+Math.imul(A,U)|0,o=o+Math.imul(A,W)|0,n=n+Math.imul(O,G)|0,i=(i=i+Math.imul(O,X)|0)+Math.imul(k,G)|0,o=o+Math.imul(k,X)|0,n=n+Math.imul(w,Z)|0,i=(i=i+Math.imul(w,$)|0)+Math.imul(M,Z)|0,o=o+Math.imul(M,$)|0,n=n+Math.imul(v,Q)|0,i=(i=i+Math.imul(v,ee)|0)+Math.imul(g,Q)|0,o=o+Math.imul(g,ee)|0,n=n+Math.imul(p,re)|0,i=(i=i+Math.imul(p,ne)|0)+Math.imul(m,re)|0,o=o+Math.imul(m,ne)|0;var _e=(u+(n=n+Math.imul(h,oe)|0)|0)+((8191&(i=(i=i+Math.imul(h,ae)|0)+Math.imul(f,oe)|0))<<13)|0;u=((o=o+Math.imul(f,ae)|0)+(i>>>13)|0)+(_e>>>26)|0,_e&=67108863,n=Math.imul(D,H),i=(i=Math.imul(D,q))+Math.imul(P,H)|0,o=Math.imul(P,q),n=n+Math.imul(j,U)|0,i=(i=i+Math.imul(j,W)|0)+Math.imul(z,U)|0,o=o+Math.imul(z,W)|0,n=n+Math.imul(S,G)|0,i=(i=i+Math.imul(S,X)|0)+Math.imul(A,G)|0,o=o+Math.imul(A,X)|0,n=n+Math.imul(O,Z)|0,i=(i=i+Math.imul(O,$)|0)+Math.imul(k,Z)|0,o=o+Math.imul(k,$)|0,n=n+Math.imul(w,Q)|0,i=(i=i+Math.imul(w,ee)|0)+Math.imul(M,Q)|0,o=o+Math.imul(M,ee)|0,n=n+Math.imul(v,re)|0,i=(i=i+Math.imul(v,ne)|0)+Math.imul(g,re)|0,o=o+Math.imul(g,ne)|0,n=n+Math.imul(p,oe)|0,i=(i=i+Math.imul(p,ae)|0)+Math.imul(m,oe)|0,o=o+Math.imul(m,ae)|0;var Oe=(u+(n=n+Math.imul(h,ce)|0)|0)+((8191&(i=(i=i+Math.imul(h,ue)|0)+Math.imul(f,ce)|0))<<13)|0;u=((o=o+Math.imul(f,ue)|0)+(i>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,n=Math.imul(T,H),i=(i=Math.imul(T,q))+Math.imul(F,H)|0,o=Math.imul(F,q),n=n+Math.imul(D,U)|0,i=(i=i+Math.imul(D,W)|0)+Math.imul(P,U)|0,o=o+Math.imul(P,W)|0,n=n+Math.imul(j,G)|0,i=(i=i+Math.imul(j,X)|0)+Math.imul(z,G)|0,o=o+Math.imul(z,X)|0,n=n+Math.imul(S,Z)|0,i=(i=i+Math.imul(S,$)|0)+Math.imul(A,Z)|0,o=o+Math.imul(A,$)|0,n=n+Math.imul(O,Q)|0,i=(i=i+Math.imul(O,ee)|0)+Math.imul(k,Q)|0,o=o+Math.imul(k,ee)|0,n=n+Math.imul(w,re)|0,i=(i=i+Math.imul(w,ne)|0)+Math.imul(M,re)|0,o=o+Math.imul(M,ne)|0,n=n+Math.imul(v,oe)|0,i=(i=i+Math.imul(v,ae)|0)+Math.imul(g,oe)|0,o=o+Math.imul(g,ae)|0,n=n+Math.imul(p,ce)|0,i=(i=i+Math.imul(p,ue)|0)+Math.imul(m,ce)|0,o=o+Math.imul(m,ue)|0;var ke=(u+(n=n+Math.imul(h,he)|0)|0)+((8191&(i=(i=i+Math.imul(h,fe)|0)+Math.imul(f,he)|0))<<13)|0;u=((o=o+Math.imul(f,fe)|0)+(i>>>13)|0)+(ke>>>26)|0,ke&=67108863,n=Math.imul(I,H),i=(i=Math.imul(I,q))+Math.imul(L,H)|0,o=Math.imul(L,q),n=n+Math.imul(T,U)|0,i=(i=i+Math.imul(T,W)|0)+Math.imul(F,U)|0,o=o+Math.imul(F,W)|0,n=n+Math.imul(D,G)|0,i=(i=i+Math.imul(D,X)|0)+Math.imul(P,G)|0,o=o+Math.imul(P,X)|0,n=n+Math.imul(j,Z)|0,i=(i=i+Math.imul(j,$)|0)+Math.imul(z,Z)|0,o=o+Math.imul(z,$)|0,n=n+Math.imul(S,Q)|0,i=(i=i+Math.imul(S,ee)|0)+Math.imul(A,Q)|0,o=o+Math.imul(A,ee)|0,n=n+Math.imul(O,re)|0,i=(i=i+Math.imul(O,ne)|0)+Math.imul(k,re)|0,o=o+Math.imul(k,ne)|0,n=n+Math.imul(w,oe)|0,i=(i=i+Math.imul(w,ae)|0)+Math.imul(M,oe)|0,o=o+Math.imul(M,ae)|0,n=n+Math.imul(v,ce)|0,i=(i=i+Math.imul(v,ue)|0)+Math.imul(g,ce)|0,o=o+Math.imul(g,ue)|0,n=n+Math.imul(p,he)|0,i=(i=i+Math.imul(p,fe)|0)+Math.imul(m,he)|0,o=o+Math.imul(m,fe)|0;var Ee=(u+(n=n+Math.imul(h,pe)|0)|0)+((8191&(i=(i=i+Math.imul(h,me)|0)+Math.imul(f,pe)|0))<<13)|0;u=((o=o+Math.imul(f,me)|0)+(i>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,n=Math.imul(I,U),i=(i=Math.imul(I,W))+Math.imul(L,U)|0,o=Math.imul(L,W),n=n+Math.imul(T,G)|0,i=(i=i+Math.imul(T,X)|0)+Math.imul(F,G)|0,o=o+Math.imul(F,X)|0,n=n+Math.imul(D,Z)|0,i=(i=i+Math.imul(D,$)|0)+Math.imul(P,Z)|0,o=o+Math.imul(P,$)|0,n=n+Math.imul(j,Q)|0,i=(i=i+Math.imul(j,ee)|0)+Math.imul(z,Q)|0,o=o+Math.imul(z,ee)|0,n=n+Math.imul(S,re)|0,i=(i=i+Math.imul(S,ne)|0)+Math.imul(A,re)|0,o=o+Math.imul(A,ne)|0,n=n+Math.imul(O,oe)|0,i=(i=i+Math.imul(O,ae)|0)+Math.imul(k,oe)|0,o=o+Math.imul(k,ae)|0,n=n+Math.imul(w,ce)|0,i=(i=i+Math.imul(w,ue)|0)+Math.imul(M,ce)|0,o=o+Math.imul(M,ue)|0,n=n+Math.imul(v,he)|0,i=(i=i+Math.imul(v,fe)|0)+Math.imul(g,he)|0,o=o+Math.imul(g,fe)|0;var Se=(u+(n=n+Math.imul(p,pe)|0)|0)+((8191&(i=(i=i+Math.imul(p,me)|0)+Math.imul(m,pe)|0))<<13)|0;u=((o=o+Math.imul(m,me)|0)+(i>>>13)|0)+(Se>>>26)|0,Se&=67108863,n=Math.imul(I,G),i=(i=Math.imul(I,X))+Math.imul(L,G)|0,o=Math.imul(L,X),n=n+Math.imul(T,Z)|0,i=(i=i+Math.imul(T,$)|0)+Math.imul(F,Z)|0,o=o+Math.imul(F,$)|0,n=n+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,ee)|0)+Math.imul(P,Q)|0,o=o+Math.imul(P,ee)|0,n=n+Math.imul(j,re)|0,i=(i=i+Math.imul(j,ne)|0)+Math.imul(z,re)|0,o=o+Math.imul(z,ne)|0,n=n+Math.imul(S,oe)|0,i=(i=i+Math.imul(S,ae)|0)+Math.imul(A,oe)|0,o=o+Math.imul(A,ae)|0,n=n+Math.imul(O,ce)|0,i=(i=i+Math.imul(O,ue)|0)+Math.imul(k,ce)|0,o=o+Math.imul(k,ue)|0,n=n+Math.imul(w,he)|0,i=(i=i+Math.imul(w,fe)|0)+Math.imul(M,he)|0,o=o+Math.imul(M,fe)|0;var Ae=(u+(n=n+Math.imul(v,pe)|0)|0)+((8191&(i=(i=i+Math.imul(v,me)|0)+Math.imul(g,pe)|0))<<13)|0;u=((o=o+Math.imul(g,me)|0)+(i>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,n=Math.imul(I,Z),i=(i=Math.imul(I,$))+Math.imul(L,Z)|0,o=Math.imul(L,$),n=n+Math.imul(T,Q)|0,i=(i=i+Math.imul(T,ee)|0)+Math.imul(F,Q)|0,o=o+Math.imul(F,ee)|0,n=n+Math.imul(D,re)|0,i=(i=i+Math.imul(D,ne)|0)+Math.imul(P,re)|0,o=o+Math.imul(P,ne)|0,n=n+Math.imul(j,oe)|0,i=(i=i+Math.imul(j,ae)|0)+Math.imul(z,oe)|0,o=o+Math.imul(z,ae)|0,n=n+Math.imul(S,ce)|0,i=(i=i+Math.imul(S,ue)|0)+Math.imul(A,ce)|0,o=o+Math.imul(A,ue)|0,n=n+Math.imul(O,he)|0,i=(i=i+Math.imul(O,fe)|0)+Math.imul(k,he)|0,o=o+Math.imul(k,fe)|0;var Ce=(u+(n=n+Math.imul(w,pe)|0)|0)+((8191&(i=(i=i+Math.imul(w,me)|0)+Math.imul(M,pe)|0))<<13)|0;u=((o=o+Math.imul(M,me)|0)+(i>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,n=Math.imul(I,Q),i=(i=Math.imul(I,ee))+Math.imul(L,Q)|0,o=Math.imul(L,ee),n=n+Math.imul(T,re)|0,i=(i=i+Math.imul(T,ne)|0)+Math.imul(F,re)|0,o=o+Math.imul(F,ne)|0,n=n+Math.imul(D,oe)|0,i=(i=i+Math.imul(D,ae)|0)+Math.imul(P,oe)|0,o=o+Math.imul(P,ae)|0,n=n+Math.imul(j,ce)|0,i=(i=i+Math.imul(j,ue)|0)+Math.imul(z,ce)|0,o=o+Math.imul(z,ue)|0,n=n+Math.imul(S,he)|0,i=(i=i+Math.imul(S,fe)|0)+Math.imul(A,he)|0,o=o+Math.imul(A,fe)|0;var je=(u+(n=n+Math.imul(O,pe)|0)|0)+((8191&(i=(i=i+Math.imul(O,me)|0)+Math.imul(k,pe)|0))<<13)|0;u=((o=o+Math.imul(k,me)|0)+(i>>>13)|0)+(je>>>26)|0,je&=67108863,n=Math.imul(I,re),i=(i=Math.imul(I,ne))+Math.imul(L,re)|0,o=Math.imul(L,ne),n=n+Math.imul(T,oe)|0,i=(i=i+Math.imul(T,ae)|0)+Math.imul(F,oe)|0,o=o+Math.imul(F,ae)|0,n=n+Math.imul(D,ce)|0,i=(i=i+Math.imul(D,ue)|0)+Math.imul(P,ce)|0,o=o+Math.imul(P,ue)|0,n=n+Math.imul(j,he)|0,i=(i=i+Math.imul(j,fe)|0)+Math.imul(z,he)|0,o=o+Math.imul(z,fe)|0;var ze=(u+(n=n+Math.imul(S,pe)|0)|0)+((8191&(i=(i=i+Math.imul(S,me)|0)+Math.imul(A,pe)|0))<<13)|0;u=((o=o+Math.imul(A,me)|0)+(i>>>13)|0)+(ze>>>26)|0,ze&=67108863,n=Math.imul(I,oe),i=(i=Math.imul(I,ae))+Math.imul(L,oe)|0,o=Math.imul(L,ae),n=n+Math.imul(T,ce)|0,i=(i=i+Math.imul(T,ue)|0)+Math.imul(F,ce)|0,o=o+Math.imul(F,ue)|0,n=n+Math.imul(D,he)|0,i=(i=i+Math.imul(D,fe)|0)+Math.imul(P,he)|0,o=o+Math.imul(P,fe)|0;var xe=(u+(n=n+Math.imul(j,pe)|0)|0)+((8191&(i=(i=i+Math.imul(j,me)|0)+Math.imul(z,pe)|0))<<13)|0;u=((o=o+Math.imul(z,me)|0)+(i>>>13)|0)+(xe>>>26)|0,xe&=67108863,n=Math.imul(I,ce),i=(i=Math.imul(I,ue))+Math.imul(L,ce)|0,o=Math.imul(L,ue),n=n+Math.imul(T,he)|0,i=(i=i+Math.imul(T,fe)|0)+Math.imul(F,he)|0,o=o+Math.imul(F,fe)|0;var De=(u+(n=n+Math.imul(D,pe)|0)|0)+((8191&(i=(i=i+Math.imul(D,me)|0)+Math.imul(P,pe)|0))<<13)|0;u=((o=o+Math.imul(P,me)|0)+(i>>>13)|0)+(De>>>26)|0,De&=67108863,n=Math.imul(I,he),i=(i=Math.imul(I,fe))+Math.imul(L,he)|0,o=Math.imul(L,fe);var Pe=(u+(n=n+Math.imul(T,pe)|0)|0)+((8191&(i=(i=i+Math.imul(T,me)|0)+Math.imul(F,pe)|0))<<13)|0;u=((o=o+Math.imul(F,me)|0)+(i>>>13)|0)+(Pe>>>26)|0,Pe&=67108863;var Re=(u+(n=Math.imul(I,pe))|0)+((8191&(i=(i=Math.imul(I,me))+Math.imul(L,pe)|0))<<13)|0;return u=((o=Math.imul(L,me))+(i>>>13)|0)+(Re>>>26)|0,Re&=67108863,c[0]=be,c[1]=ve,c[2]=ge,c[3]=ye,c[4]=we,c[5]=Me,c[6]=_e,c[7]=Oe,c[8]=ke,c[9]=Ee,c[10]=Se,c[11]=Ae,c[12]=Ce,c[13]=je,c[14]=ze,c[15]=xe,c[16]=De,c[17]=Pe,c[18]=Re,0!==u&&(c[19]=u,r.length++),r};function p(e,t,r){return(new m).mulp(e,t,r)}function m(e,t){this.x=e,this.y=t}Math.imul||(d=f),o.prototype.mulTo=function(e,t){var r=this.length+e.length;return 10===this.length&&10===e.length?d(this,e,t):r<63?f(this,e,t):r<1024?function(e,t,r){r.negative=t.negative^e.negative,r.length=e.length+t.length;for(var n=0,i=0,o=0;o>>26)|0)>>>26,a&=67108863}r.words[o]=s,n=a,a=i}return 0!==n?r.words[o]=n:r.length--,r.strip()}(this,e,t):p(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),r=o.prototype._countBits(e)-1,n=0;n>=1;return n},m.prototype.permute=function(e,t,r,n,i,o){for(var a=0;a>>=1)i++;return 1<>>=13,r[2*a+1]=8191&o,o>>>=13;for(a=2*t;a>=26,t+=i/67108864|0,t+=o>>>26,this.words[r]=67108863&o}return 0!==t&&(this.words[r]=t,this.length++),this},o.prototype.muln=function(e){return this.clone().imuln(e)},o.prototype.sqr=function(){return this.mul(this)},o.prototype.isqr=function(){return this.imul(this.clone())},o.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),r=0;r>>i}return t}(e);if(0===t.length)return new o(1);for(var r=this,n=0;n=0);var t,r=e%26,i=(e-r)/26,o=67108863>>>26-r<<26-r;if(0!==r){var a=0;for(t=0;t>>26-r}a&&(this.words[t]=a,this.length++)}if(0!==i){for(t=this.length-1;t>=0;t--)this.words[t+i]=this.words[t];for(t=0;t=0),i=t?(t-t%26)/26:0;var o=e%26,a=Math.min((e-o)/26,this.length),s=67108863^67108863>>>o<a)for(this.length-=a,u=0;u=0&&(0!==l||u>=i);u--){var h=0|this.words[u];this.words[u]=l<<26-o|h>>>o,l=h&s}return c&&0!==l&&(c.words[c.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},o.prototype.ishrn=function(e,t,r){return n(0===this.negative),this.iushrn(e,t,r)},o.prototype.shln=function(e){return this.clone().ishln(e)},o.prototype.ushln=function(e){return this.clone().iushln(e)},o.prototype.shrn=function(e){return this.clone().ishrn(e)},o.prototype.ushrn=function(e){return this.clone().iushrn(e)},o.prototype.testn=function(e){n("number"==typeof e&&e>=0);var t=e%26,r=(e-t)/26,i=1<=0);var t=e%26,r=(e-t)/26;if(n(0===this.negative,"imaskn works only with positive numbers"),this.length<=r)return this;if(0!==t&&r++,this.length=Math.min(r,this.length),0!==t){var i=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},o.prototype.isubn=function(e){if(n("number"==typeof e),n(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(c/67108864|0),this.words[i+r]=67108863&o}for(;i>26,this.words[i+r]=67108863&o;if(0===s)return this.strip();for(n(-1===s),s=0,i=0;i>26,this.words[i]=67108863&o;return this.negative=1,this.strip()},o.prototype._wordDiv=function(e,t){var r=(this.length,e.length),n=this.clone(),i=e,a=0|i.words[i.length-1];0!==(r=26-this._countBits(a))&&(i=i.ushln(r),n.iushln(r),a=0|i.words[i.length-1]);var s,c=n.length-i.length;if("mod"!==t){(s=new o(null)).length=c+1,s.words=new Array(s.length);for(var u=0;u=0;h--){var f=67108864*(0|n.words[i.length+h])+(0|n.words[i.length+h-1]);for(f=Math.min(f/a|0,67108863),n._ishlnsubmul(i,f,h);0!==n.negative;)f--,n.negative=0,n._ishlnsubmul(i,1,h),n.isZero()||(n.negative^=1);s&&(s.words[h]=f)}return s&&s.strip(),n.strip(),"div"!==t&&0!==r&&n.iushrn(r),{div:s||null,mod:n}},o.prototype.divmod=function(e,t,r){return n(!e.isZero()),this.isZero()?{div:new o(0),mod:new o(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(i=s.div.neg()),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.iadd(e)),{div:i,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),r&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new o(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new o(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new o(this.modn(e.words[0]))}:this._wordDiv(e,t);var i,a,s},o.prototype.div=function(e){return this.divmod(e,"div",!1).div},o.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},o.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},o.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var r=0!==t.div.negative?t.mod.isub(e):t.mod,n=e.ushrn(1),i=e.andln(1),o=r.cmp(n);return o<0||1===i&&0===o?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},o.prototype.modn=function(e){n(e<=67108863);for(var t=(1<<26)%e,r=0,i=this.length-1;i>=0;i--)r=(t*r+(0|this.words[i]))%e;return r},o.prototype.idivn=function(e){n(e<=67108863);for(var t=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*t;this.words[r]=i/e|0,t=i%e}return this.strip()},o.prototype.divn=function(e){return this.clone().idivn(e)},o.prototype.egcd=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i=new o(1),a=new o(0),s=new o(0),c=new o(1),u=0;t.isEven()&&r.isEven();)t.iushrn(1),r.iushrn(1),++u;for(var l=r.clone(),h=t.clone();!t.isZero();){for(var f=0,d=1;0==(t.words[0]&d)&&f<26;++f,d<<=1);if(f>0)for(t.iushrn(f);f-- >0;)(i.isOdd()||a.isOdd())&&(i.iadd(l),a.isub(h)),i.iushrn(1),a.iushrn(1);for(var p=0,m=1;0==(r.words[0]&m)&&p<26;++p,m<<=1);if(p>0)for(r.iushrn(p);p-- >0;)(s.isOdd()||c.isOdd())&&(s.iadd(l),c.isub(h)),s.iushrn(1),c.iushrn(1);t.cmp(r)>=0?(t.isub(r),i.isub(s),a.isub(c)):(r.isub(t),s.isub(i),c.isub(a))}return{a:s,b:c,gcd:r.iushln(u)}},o.prototype._invmp=function(e){n(0===e.negative),n(!e.isZero());var t=this,r=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var i,a=new o(1),s=new o(0),c=r.clone();t.cmpn(1)>0&&r.cmpn(1)>0;){for(var u=0,l=1;0==(t.words[0]&l)&&u<26;++u,l<<=1);if(u>0)for(t.iushrn(u);u-- >0;)a.isOdd()&&a.iadd(c),a.iushrn(1);for(var h=0,f=1;0==(r.words[0]&f)&&h<26;++h,f<<=1);if(h>0)for(r.iushrn(h);h-- >0;)s.isOdd()&&s.iadd(c),s.iushrn(1);t.cmp(r)>=0?(t.isub(r),a.isub(s)):(r.isub(t),s.isub(a))}return(i=0===t.cmpn(1)?a:s).cmpn(0)<0&&i.iadd(e),i},o.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),r=e.clone();t.negative=0,r.negative=0;for(var n=0;t.isEven()&&r.isEven();n++)t.iushrn(1),r.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;r.isEven();)r.iushrn(1);var i=t.cmp(r);if(i<0){var o=t;t=r,r=o}else if(0===i||0===r.cmpn(1))break;t.isub(r)}return r.iushln(n)},o.prototype.invm=function(e){return this.egcd(e).a.umod(e)},o.prototype.isEven=function(){return 0==(1&this.words[0])},o.prototype.isOdd=function(){return 1==(1&this.words[0])},o.prototype.andln=function(e){return this.words[0]&e},o.prototype.bincn=function(e){n("number"==typeof e);var t=e%26,r=(e-t)/26,i=1<>>26,s&=67108863,this.words[a]=s}return 0!==o&&(this.words[a]=o,this.length++),this},o.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},o.prototype.cmpn=function(e){var t,r=e<0;if(0!==this.negative&&!r)return-1;if(0===this.negative&&r)return 1;if(this.strip(),this.length>1)t=1;else{r&&(e=-e),n(e<=67108863,"Number is too big");var i=0|this.words[0];t=i===e?0:ie.length)return 1;if(this.length=0;r--){var n=0|this.words[r],i=0|e.words[r];if(n!==i){ni&&(t=1);break}}return t},o.prototype.gtn=function(e){return 1===this.cmpn(e)},o.prototype.gt=function(e){return 1===this.cmp(e)},o.prototype.gten=function(e){return this.cmpn(e)>=0},o.prototype.gte=function(e){return this.cmp(e)>=0},o.prototype.ltn=function(e){return-1===this.cmpn(e)},o.prototype.lt=function(e){return-1===this.cmp(e)},o.prototype.lten=function(e){return this.cmpn(e)<=0},o.prototype.lte=function(e){return this.cmp(e)<=0},o.prototype.eqn=function(e){return 0===this.cmpn(e)},o.prototype.eq=function(e){return 0===this.cmp(e)},o.red=function(e){return new _(e)},o.prototype.toRed=function(e){return n(!this.red,"Already a number in reduction context"),n(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},o.prototype.fromRed=function(){return n(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},o.prototype._forceRed=function(e){return this.red=e,this},o.prototype.forceRed=function(e){return n(!this.red,"Already a number in reduction context"),this._forceRed(e)},o.prototype.redAdd=function(e){return n(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},o.prototype.redIAdd=function(e){return n(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},o.prototype.redSub=function(e){return n(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},o.prototype.redISub=function(e){return n(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},o.prototype.redShl=function(e){return n(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},o.prototype.redMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},o.prototype.redIMul=function(e){return n(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},o.prototype.redSqr=function(){return n(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},o.prototype.redISqr=function(){return n(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},o.prototype.redSqrt=function(){return n(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},o.prototype.redInvm=function(){return n(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},o.prototype.redNeg=function(){return n(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},o.prototype.redPow=function(e){return n(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var b={k256:null,p224:null,p192:null,p25519:null};function v(e,t){this.name=e,this.p=new o(t,16),this.n=this.p.bitLength(),this.k=new o(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function g(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function y(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function w(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function M(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function _(e){if("string"==typeof e){var t=o._prime(e);this.m=t.p,this.prime=t}else n(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function O(e){_.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new o(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var e=new o(null);return e.words=new Array(Math.ceil(this.n/13)),e},v.prototype.ireduce=function(e){var t,r=e;do{this.split(r,this.tmp),t=(r=(r=this.imulK(r)).iadd(this.tmp)).bitLength()}while(t>this.n);var n=t0?r.isub(this.p):void 0!==r.strip?r.strip():r._strip(),r},v.prototype.split=function(e,t){e.iushrn(this.n,0,t)},v.prototype.imulK=function(e){return e.imul(this.k)},i(g,v),g.prototype.split=function(e,t){for(var r=Math.min(e.length,9),n=0;n>>22,i=o}i>>>=22,e.words[n-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},g.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,r=0;r>>=26,e.words[r]=i,t=n}return 0!==t&&(e.words[e.length++]=t),e},o._prime=function(e){if(b[e])return b[e];var t;if("k256"===e)t=new g;else if("p224"===e)t=new y;else if("p192"===e)t=new w;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new M}return b[e]=t,t},_.prototype._verify1=function(e){n(0===e.negative,"red works only with positives"),n(e.red,"red works only with red numbers")},_.prototype._verify2=function(e,t){n(0==(e.negative|t.negative),"red works only with positives"),n(e.red&&e.red===t.red,"red works only with red numbers")},_.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},_.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},_.prototype.add=function(e,t){this._verify2(e,t);var r=e.add(t);return r.cmp(this.m)>=0&&r.isub(this.m),r._forceRed(this)},_.prototype.iadd=function(e,t){this._verify2(e,t);var r=e.iadd(t);return r.cmp(this.m)>=0&&r.isub(this.m),r},_.prototype.sub=function(e,t){this._verify2(e,t);var r=e.sub(t);return r.cmpn(0)<0&&r.iadd(this.m),r._forceRed(this)},_.prototype.isub=function(e,t){this._verify2(e,t);var r=e.isub(t);return r.cmpn(0)<0&&r.iadd(this.m),r},_.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},_.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},_.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},_.prototype.isqr=function(e){return this.imul(e,e.clone())},_.prototype.sqr=function(e){return this.mul(e,e)},_.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(n(t%2==1),3===t){var r=this.m.add(new o(1)).iushrn(2);return this.pow(e,r)}for(var i=this.m.subn(1),a=0;!i.isZero()&&0===i.andln(1);)a++,i.iushrn(1);n(!i.isZero());var s=new o(1).toRed(this),c=s.redNeg(),u=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new o(2*l*l).toRed(this);0!==this.pow(l,u).cmp(c);)l.redIAdd(c);for(var h=this.pow(l,i),f=this.pow(e,i.addn(1).iushrn(1)),d=this.pow(e,i),p=a;0!==d.cmp(s);){for(var m=d,b=0;0!==m.cmp(s);b++)m=m.redSqr();n(b=0;n--){for(var u=t.words[n],l=c-1;l>=0;l--){var h=u>>l&1;i!==r[0]&&(i=this.sqr(i)),0!==h||0!==a?(a<<=1,a|=h,(4===++s||0===n&&0===l)&&(i=this.mul(i,r[a]),s=0,a=0)):s=0}c=26}return i},_.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},_.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},o.mont=function(e){return new O(e)},i(O,_),O.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},O.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},O.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var r=e.imul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},O.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new o(0)._forceRed(this);var r=e.mul(t),n=r.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=r.isub(n).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},O.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e,this)}).call(this,r(80)(e))},function(e,t){},function(e,t,r){t.publicEncrypt=r(432),t.privateDecrypt=r(434),t.privateEncrypt=function(e,r){return t.publicEncrypt(e,r,!0)},t.publicDecrypt=function(e,r){return t.privateDecrypt(e,r,!0)}},function(e,t,r){var n=r(152),i=r(106),o=r(120),a=r(274),s=r(275),c=r(188),u=r(276),l=r(180),h=r(28).Buffer;e.exports=function(e,t,r){var f;f=e.padding?e.padding:r?1:4;var d,p=n(e);if(4===f)d=function(e,t){var r=e.modulus.byteLength(),n=t.length,u=o("sha1").update(h.alloc(0)).digest(),l=u.length,f=2*l;if(n>r-f-2)throw new Error("message too long");var d=h.alloc(r-n-f-2),p=r-l-1,m=i(l),b=s(h.concat([u,d,h.alloc(1,1),t],p),a(m,p)),v=s(m,a(b,l));return new c(h.concat([h.alloc(1),v,b],r))}(p,t);else if(1===f)d=function(e,t,r){var n,o=t.length,a=e.modulus.byteLength();if(o>a-11)throw new Error("message too long");n=r?h.alloc(a-o-3,255):function(e){var t,r=h.allocUnsafe(e),n=0,o=i(2*e),a=0;for(;n=0)throw new Error("data too long for modulus")}return r?l(d,p):u(d,p)}},function(e,t){},function(e,t,r){var n=r(152),i=r(274),o=r(275),a=r(188),s=r(180),c=r(120),u=r(276),l=r(28).Buffer;e.exports=function(e,t,r){var h;h=e.padding?e.padding:r?1:4;var f,d=n(e),p=d.modulus.byteLength();if(t.length>p||new a(t).cmp(d.modulus)>=0)throw new Error("decryption error");f=r?u(new a(t),d):s(t,d);var m=l.alloc(p-f.length);if(f=l.concat([m,f],p),4===h)return function(e,t){var r=e.modulus.byteLength(),n=c("sha1").update(l.alloc(0)).digest(),a=n.length;if(0!==t[0])throw new Error("decryption error");var s=t.slice(1,a+1),u=t.slice(a+1),h=o(s,i(u,a)),f=o(u,i(h,r-a-1));if(function(e,t){e=l.from(e),t=l.from(t);var r=0,n=e.length;e.length!==t.length&&(r++,n=Math.min(e.length,t.length));var i=-1;for(;++i=t.length){o++;break}var a=t.slice(2,i-1);("0002"!==n.toString("hex")&&!r||"0001"!==n.toString("hex")&&r)&&o++;a.length<8&&o++;if(o)throw new Error("decryption error");return t.slice(i)}(0,f,r);if(3===h)return f;throw new Error("unknown padding")}},function(e,t,r){"use strict";(function(e,n){function i(){throw new Error("secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11")}var o=r(28),a=r(106),s=o.Buffer,c=o.kMaxLength,u=e.crypto||e.msCrypto,l=Math.pow(2,32)-1;function h(e,t){if("number"!=typeof e||e!=e)throw new TypeError("offset must be a number");if(e>l||e<0)throw new TypeError("offset must be a uint32");if(e>c||e>t)throw new RangeError("offset out of range")}function f(e,t,r){if("number"!=typeof e||e!=e)throw new TypeError("size must be a number");if(e>l||e<0)throw new TypeError("size must be a uint32");if(e+t>r||e>c)throw new RangeError("buffer too small")}function d(e,t,r,i){if(n.browser){var o=e.buffer,s=new Uint8Array(o,t,r);return u.getRandomValues(s),i?void n.nextTick((function(){i(null,e)})):e}if(!i)return a(r).copy(e,t),e;a(r,(function(r,n){if(r)return i(r);n.copy(e,t),i(null,e)}))}u&&u.getRandomValues||!n.browser?(t.randomFill=function(t,r,n,i){if(!(s.isBuffer(t)||t instanceof e.Uint8Array))throw new TypeError('"buf" argument must be a Buffer or Uint8Array');if("function"==typeof r)i=r,r=0,n=t.length;else if("function"==typeof n)i=n,n=t.length-r;else if("function"!=typeof i)throw new TypeError('"cb" argument must be a function');return h(r,t.length),f(n,r,t.length),d(t,r,n,i)},t.randomFillSync=function(t,r,n){void 0===r&&(r=0);if(!(s.isBuffer(t)||t instanceof e.Uint8Array))throw new TypeError('"buf" argument must be a Buffer or Uint8Array');h(r,t.length),void 0===n&&(n=t.length-r);return f(n,r,t.length),d(t,r,n)}):(t.randomFill=i,t.randomFillSync=i)}).call(this,r(46),r(33))},,,function(e,t,r){"use strict";var n=r(709),i=r(710);function o(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}t.parse=y,t.resolve=function(e,t){return y(e,!1,!0).resolve(t)},t.resolveObject=function(e,t){return e?y(e,!1,!0).resolveObject(t):t},t.format=function(e){i.isString(e)&&(e=y(e));return e instanceof o?e.format():o.prototype.format.call(e)},t.Url=o;var a=/^([a-z0-9.+-]+:)/i,s=/:[0-9]*$/,c=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,u=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),l=["'"].concat(u),h=["%","/","?",";","#"].concat(l),f=["/","?","#"],d=/^[+a-z0-9A-Z_-]{0,63}$/,p=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,m={javascript:!0,"javascript:":!0},b={javascript:!0,"javascript:":!0},v={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},g=r(711);function y(e,t,r){if(e&&i.isObject(e)&&e instanceof o)return e;var n=new o;return n.parse(e,t,r),n}o.prototype.parse=function(e,t,r){if(!i.isString(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var o=e.indexOf("?"),s=-1!==o&&o127?P+="x":P+=D[R];if(!P.match(d)){var F=z.slice(0,A),N=z.slice(A+1),I=D.match(p);I&&(F.push(I[1]),N.unshift(I[2])),N.length&&(y="/"+N.join(".")+y),this.hostname=F.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),j||(this.hostname=n.toASCII(this.hostname));var L=this.port?":"+this.port:"",B=this.hostname||"";this.host=B+L,this.href+=this.host,j&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==y[0]&&(y="/"+y))}if(!m[_])for(A=0,x=l.length;A0)&&r.host.split("@"))&&(r.auth=j.shift(),r.host=r.hostname=j.shift());return r.search=e.search,r.query=e.query,i.isNull(r.pathname)&&i.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.href=r.format(),r}if(!O.length)return r.pathname=null,r.search?r.path="/"+r.search:r.path=null,r.href=r.format(),r;for(var E=O.slice(-1)[0],S=(r.host||e.host||O.length>1)&&("."===E||".."===E)||""===E,A=0,C=O.length;C>=0;C--)"."===(E=O[C])?O.splice(C,1):".."===E?(O.splice(C,1),A++):A&&(O.splice(C,1),A--);if(!M&&!_)for(;A--;A)O.unshift("..");!M||""===O[0]||O[0]&&"/"===O[0].charAt(0)||O.unshift(""),S&&"/"!==O.join("/").substr(-1)&&O.push("");var j,z=""===O[0]||O[0]&&"/"===O[0].charAt(0);k&&(r.hostname=r.host=z?"":O.length?O.shift():"",(j=!!(r.host&&r.host.indexOf("@")>0)&&r.host.split("@"))&&(r.auth=j.shift(),r.host=r.hostname=j.shift()));return(M=M||r.host&&O.length)&&!z&&O.unshift(""),O.length?r.pathname=O.join("/"):(r.pathname=null,r.path=null),i.isNull(r.pathname)&&i.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.auth=e.auth||r.auth,r.slashes=r.slashes||e.slashes,r.href=r.format(),r},o.prototype.parseHost=function(){var e=this.host,t=s.exec(e);t&&(":"!==(t=t[0])&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},,,,,function(e,t,r){!function(t,n){"use strict";e.exports?e.exports=n(r(16)):"function"==typeof define&&define.amd?define(["moment"],n):n(t.moment)}(this,(function(e){"use strict";void 0===e.version&&e.default&&(e=e.default);var t,r={},n={},i={},o={},a={};e&&"string"==typeof e.version||j("Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/");var s=e.version.split("."),c=+s[0],u=+s[1];function l(e){return e>96?e-87:e>64?e-29:e-48}function h(e){var t=0,r=e.split("."),n=r[0],i=r[1]||"",o=1,a=0,s=1;for(45===e.charCodeAt(0)&&(t=1,s=-1);t3){var t=o[k(e)];if(t)return t;j("Moment Timezone found "+e+" from the Intl api, but did not have that data loaded.")}}catch(e){}var r,n,i,a=function(){var e,t,r,n=(new Date).getFullYear()-2,i=new v(new Date(n,0,1)),o=[i];for(r=1;r<48;r++)(t=new v(new Date(n,r,1))).offset!==i.offset&&(e=y(i,t),o.push(e),o.push(new v(new Date(e.at+6e4)))),i=t;for(r=0;r<4;r++)o.push(new v(new Date(n+r,0,1))),o.push(new v(new Date(n+r,6,1)));return o}(),s=a.length,c=_(a),u=[];for(n=0;n0?u[0].zone.name:void 0}function k(e){return(e||"").toLowerCase().replace(/\//g,"_")}function E(e){var t,n,i,a;for("string"==typeof e&&(e=[e]),t=0;t= 2.6.0. You are using Moment.js "+e.version+". See momentjs.com"),m.prototype={_set:function(e){this.name=e.name,this.abbrs=e.abbrs,this.untils=e.untils,this.offsets=e.offsets,this.population=e.population},_index:function(e){var t,r=+e,n=this.untils;for(t=0;tn&&z.moveInvalidForward&&(t=n),o0&&(this._z=null),x.apply(this,arguments)}),e.tz.setDefault=function(t){return(c<2||2===c&&u<9)&&j("Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js "+e.version+"."),e.defaultZone=t?S(t):null,e};var T=e.momentProperties;return"[object Array]"===Object.prototype.toString.call(T)?(T.push("_z"),T.push("_a")):T&&(T._z=null),e}))},,,,function(e,t,r){"use strict";r.d(t,"a",(function(){return g}));var n={};r.r(n),r.d(n,"find",(function(){return s}));var i={};r.r(i),r.d(i,"isTabbableIndex",(function(){return l})),r.d(i,"find",(function(){return m})),r.d(i,"findPrevious",(function(){return b})),r.d(i,"findNext",(function(){return v}));var o=["[tabindex]","a[href]","button:not([disabled])",'input:not([type="hidden"]):not([disabled])',"select:not([disabled])","textarea:not([disabled])","iframe","object","embed","area[href]","[contenteditable]:not([contenteditable=false])"].join(",");function a(e){return e.offsetWidth>0||e.offsetHeight>0||e.getClientRects().length>0}function s(e){var t=e.querySelectorAll(o);return Array.from(t).filter((function(e){return!!a(e)&&("AREA"!==e.nodeName||function(e){var t=e.closest("map[name]");if(!t)return!1;var r=document.querySelector('img[usemap="#'+t.name+'"]');return!!r&&a(r)}(e))}))}var c=r(2);function u(e){var t=e.getAttribute("tabindex");return null===t?0:parseInt(t,10)}function l(e){return-1!==u(e)}function h(e,t){return{element:e,index:t}}function f(e){return e.element}function d(e,t){var r=u(e.element),n=u(t.element);return r===n?e.index-t.index:r-n}function p(e){return e.filter(l).map(h).sort(d).map(f).reduce((t={},function(e,r){var n=r.nodeName,i=r.type,o=r.checked,a=r.name;if("INPUT"!==n||"radio"!==i||!a)return e.concat(r);var s=t.hasOwnProperty(a);if(!o&&s)return e;if(s){var u=t[a];e=Object(c.without)(e,u)}return t[a]=r,e.concat(r)}),[]);var t}function m(e){return p(s(e))}function b(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.activeElement,t=s(document.body),r=t.indexOf(e);return t.length=r,Object(c.last)(p(t))}function v(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.activeElement,t=s(document.body),r=t.indexOf(e),n=t.slice(r+1).filter((function(t){return!e.contains(t)}));return Object(c.first)(p(n))}var g={focusable:n,tabbable:i}},,,,,function(e,t,r){"use strict";var n=Array.prototype.slice,i=r(453),o=Object.keys,a=o?function(e){return o(e)}:r(583),s=Object.keys;a.shim=function(){Object.keys?function(){var e=Object.keys(arguments);return e&&e.length===arguments.length}(1,2)||(Object.keys=function(e){return i(e)?s(n.call(e)):s(e)}):Object.keys=a;return Object.keys||a},e.exports=a},function(e,t,r){"use strict";var n=Object.prototype.toString;e.exports=function(e){var t=n.call(e),r="[object Arguments]"===t;return r||(r="[object Array]"!==t&&null!==e&&"object"==typeof e&&"number"==typeof e.length&&e.length>=0&&"[object Function]"===n.call(e.callee)),r}},function(e,t,r){"use strict";e.exports=function(){if("function"!=typeof Symbol||"function"!=typeof Object.getOwnPropertySymbols)return!1;if("symbol"==typeof Symbol.iterator)return!0;var e={},t=Symbol("test"),r=Object(t);if("string"==typeof t)return!1;if("[object Symbol]"!==Object.prototype.toString.call(t))return!1;if("[object Symbol]"!==Object.prototype.toString.call(r))return!1;for(t in e[t]=42,e)return!1;if("function"==typeof Object.keys&&0!==Object.keys(e).length)return!1;if("function"==typeof Object.getOwnPropertyNames&&0!==Object.getOwnPropertyNames(e).length)return!1;var n=Object.getOwnPropertySymbols(e);if(1!==n.length||n[0]!==t)return!1;if(!Object.prototype.propertyIsEnumerable.call(e,t))return!1;if("function"==typeof Object.getOwnPropertyDescriptor){var i=Object.getOwnPropertyDescriptor(e,t);if(42!==i.value||!0!==i.enumerable)return!1}return!0}},function(e,t,r){"use strict";var n=r(585),i=r(595),o=r(309),a=r(467),s=r(466),c=r(615);e.exports=function(){var e=c(this),t=s(o(e,"length")),r=1;arguments.length>0&&void 0!==arguments[0]&&(r=a(arguments[0]));var u=n(e,0);return i(u,e,t,0,r),u}},function(e,t,r){"use strict";var n=r(61)("%Object.defineProperty%",!0);if(n)try{n({},"a",{value:1})}catch(e){n=null}var i=r(199)("Object.prototype.propertyIsEnumerable");e.exports=function(e,t,r,o,a,s){if(!n){if(!e(s))return!1;if(!s["[[Configurable]]"]||!s["[[Writable]]"])return!1;if(a in o&&i(o,a)!==!!s["[[Enumerable]]"])return!1;var c=s["[[Value]]"];return o[a]=c,t(o[a],c)}return n(o,a,r(s)),!0}},function(e,t,r){"use strict";var n=r(311),i=r(119);e.exports=function(e){if(void 0===e)return e;n(i,"Property Descriptor","Desc",e);var t={};return"[[Value]]"in e&&(t.value=e["[[Value]]"]),"[[Writable]]"in e&&(t.writable=e["[[Writable]]"]),"[[Get]]"in e&&(t.get=e["[[Get]]"]),"[[Set]]"in e&&(t.set=e["[[Set]]"]),"[[Enumerable]]"in e&&(t.enumerable=e["[[Enumerable]]"]),"[[Configurable]]"in e&&(t.configurable=e["[[Configurable]]"]),t}},function(e,t,r){"use strict";var n=r(157),i=r(311),o=r(119);e.exports=function(e){return void 0!==e&&(i(o,"Property Descriptor","Desc",e),!(!n(e,"[[Value]]")&&!n(e,"[[Writable]]")))}},function(e,t,r){"use strict";var n=r(312);e.exports=function(e,t){return e===t?0!==e||1/e==1/t:n(e)&&n(t)}},function(e,t,r){"use strict";var n=r(157),i=r(61)("%TypeError%"),o=r(119),a=r(461),s=r(593);e.exports=function(e){if("Object"!==o(e))throw new i("ToPropertyDescriptor requires an object");var t={};if(n(e,"enumerable")&&(t["[[Enumerable]]"]=a(e.enumerable)),n(e,"configurable")&&(t["[[Configurable]]"]=a(e.configurable)),n(e,"value")&&(t["[[Value]]"]=e.value),n(e,"writable")&&(t["[[Writable]]"]=a(e.writable)),n(e,"get")){var r=e.get;if(void 0!==r&&!s(r))throw new i("getter must be a function");t["[[Get]]"]=r}if(n(e,"set")){var c=e.set;if(void 0!==c&&!s(c))throw new i("setter must be a function");t["[[Set]]"]=c}if((n(t,"[[Get]]")||n(t,"[[Set]]"))&&(n(t,"[[Value]]")||n(t,"[[Writable]]")))throw new i("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute");return t}},function(e,t,r){"use strict";e.exports=function(e){return!!e}},function(e,t,r){"use strict";var n,i,o=Function.prototype.toString,a="object"==typeof Reflect&&null!==Reflect&&Reflect.apply;if("function"==typeof a&&"function"==typeof Object.defineProperty)try{n=Object.defineProperty({},"length",{get:function(){throw i}}),i={},a((function(){throw 42}),null,n)}catch(e){e!==i&&(a=null)}else a=null;var s=/^\s*class\b/,c=function(e){try{var t=o.call(e);return s.test(t)}catch(e){return!1}},u=Object.prototype.toString,l="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;e.exports=a?function(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if("function"==typeof e&&!e.prototype)return!0;try{a(e,null,n)}catch(e){if(e!==i)return!1}return!c(e)}:function(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if("function"==typeof e&&!e.prototype)return!0;if(l)return function(e){try{return!c(e)&&(o.call(e),!0)}catch(e){return!1}}(e);if(c(e))return!1;var t=u.call(e);return"[object Function]"===t||"[object GeneratorFunction]"===t}},function(e,t,r){"use strict";var n=Number.isNaN||function(e){return e!=e};e.exports=Number.isFinite||function(e){return"number"==typeof e&&!n(e)&&e!==1/0&&e!==-1/0}},function(e,t,r){"use strict";var n=r(61),i=n("%Math%"),o=n("%Number%");e.exports=o.MAX_SAFE_INTEGER||i.pow(2,53)-1},function(e,t,r){"use strict";e.exports=function(e){return null===e||"function"!=typeof e&&"object"!=typeof e}},function(e,t,r){"use strict";var n=r(464),i=r(467);e.exports=function(e){var t=i(e);return t<=0?0:t>n?n:t}},function(e,t,r){"use strict";var n=r(605),i=r(608);e.exports=function(e){var t=i(e);return n(t)}},function(e,t,r){"use strict";var n=Object.prototype.toString;if(r(282)()){var i=Symbol.prototype.toString,o=/^Symbol\(.*\)$/;e.exports=function(e){if("symbol"==typeof e)return!0;if("[object Symbol]"!==n.call(e))return!1;try{return function(e){return"symbol"==typeof e.valueOf()&&o.test(i.call(e))}(e)}catch(e){return!1}}}else e.exports=function(e){return!1}},function(e,t,r){"use strict";e.exports=r(616)},function(e,t,r){"use strict";var n=r(455);e.exports=function(){return Array.prototype.flat||n}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=void 0,i=void 0;function o(e,t){var r=t(e(i));return function(){return r}}function a(e){return o(e,n.createLTR||n.create)}function s(){for(var e=arguments.length,t=Array(e),r=0;rc;)n(s,r=t[c++])&&(~o(u,r)||u.push(r));return u}},function(e,t,r){var n=r(323),i=Math.min;e.exports=function(e){return e>0?i(n(e),9007199254740991):0}},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t,r){var n=r(487),i=r(324);e.exports=Object.keys||function(e){return n(e,i)}},function(e,t,r){var n=r(645);e.exports=n},function(e,t,r){"use strict";var n,i,o,a=r(493),s=r(201),c=r(146),u=r(158),l=r(320),h=u("iterator"),f=!1;[].keys&&("next"in(o=[].keys())?(i=a(a(o)))!==Object.prototype&&(n=i):f=!0),null==n&&(n={}),l||c(n,h)||s(n,h,(function(){return this})),e.exports={IteratorPrototype:n,BUGGY_SAFARI_ITERATORS:f}},function(e,t,r){var n=r(146),i=r(325),o=r(319),a=r(650),s=o("IE_PROTO"),c=Object.prototype;e.exports=a?Object.getPrototypeOf:function(e){return e=i(e),n(e,s)?e[s]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?c:null}},function(e,t,r){var n=r(165);e.exports=!!Object.getOwnPropertySymbols&&!n((function(){return!String(Symbol())}))},function(e,t,r){var n=r(217).f,i=r(146),o=r(158)("toStringTag");e.exports=function(e,t,r){e&&!i(e=r?e:e.prototype,o)&&n(e,o,{configurable:!0,value:t})}},function(e,t,r){"use strict";var n=r(215),i=r(497),o=i("%Function.prototype.apply%"),a=i("%Function.prototype.call%"),s=i("%Reflect.apply%",!0)||n.call(a,o),c=i("%Object.defineProperty%",!0);if(c)try{c({},"a",{value:1})}catch(e){c=null}e.exports=function(){return s(n,a,arguments)};var u=function(){return s(n,o,arguments)};c?c(e.exports,"apply",{value:u}):e.exports.apply=u},function(e,t,r){"use strict";var n=SyntaxError,i=Function,o=TypeError,a=function(e){try{return Function('"use strict"; return ('+e+").constructor;")()}catch(e){}},s=Object.getOwnPropertyDescriptor;if(s)try{s({},"")}catch(e){s=null}var c=function(){throw new o},u=s?function(){try{return c}catch(e){try{return s(arguments,"callee").get}catch(e){return c}}}():c,l=r(282)(),h=Object.getPrototypeOf||function(e){return e.__proto__},f=a("async function* () {}"),d=f?f.prototype:void 0,p=d?d.prototype:void 0,m="undefined"==typeof Uint8Array?void 0:h(Uint8Array),b={"%AggregateError%":"undefined"==typeof AggregateError?void 0:AggregateError,"%Array%":Array,"%ArrayBuffer%":"undefined"==typeof ArrayBuffer?void 0:ArrayBuffer,"%ArrayIteratorPrototype%":l?h([][Symbol.iterator]()):void 0,"%AsyncFromSyncIteratorPrototype%":void 0,"%AsyncFunction%":a("async function () {}"),"%AsyncGenerator%":d,"%AsyncGeneratorFunction%":f,"%AsyncIteratorPrototype%":p?h(p):void 0,"%Atomics%":"undefined"==typeof Atomics?void 0:Atomics,"%BigInt%":"undefined"==typeof BigInt?void 0:BigInt,"%Boolean%":Boolean,"%DataView%":"undefined"==typeof DataView?void 0:DataView,"%Date%":Date,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":Error,"%eval%":eval,"%EvalError%":EvalError,"%Float32Array%":"undefined"==typeof Float32Array?void 0:Float32Array,"%Float64Array%":"undefined"==typeof Float64Array?void 0:Float64Array,"%FinalizationRegistry%":"undefined"==typeof FinalizationRegistry?void 0:FinalizationRegistry,"%Function%":i,"%GeneratorFunction%":a("function* () {}"),"%Int8Array%":"undefined"==typeof Int8Array?void 0:Int8Array,"%Int16Array%":"undefined"==typeof Int16Array?void 0:Int16Array,"%Int32Array%":"undefined"==typeof Int32Array?void 0:Int32Array,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":l?h(h([][Symbol.iterator]())):void 0,"%JSON%":"object"==typeof JSON?JSON:void 0,"%Map%":"undefined"==typeof Map?void 0:Map,"%MapIteratorPrototype%":"undefined"!=typeof Map&&l?h((new Map)[Symbol.iterator]()):void 0,"%Math%":Math,"%Number%":Number,"%Object%":Object,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":"undefined"==typeof Promise?void 0:Promise,"%Proxy%":"undefined"==typeof Proxy?void 0:Proxy,"%RangeError%":RangeError,"%ReferenceError%":ReferenceError,"%Reflect%":"undefined"==typeof Reflect?void 0:Reflect,"%RegExp%":RegExp,"%Set%":"undefined"==typeof Set?void 0:Set,"%SetIteratorPrototype%":"undefined"!=typeof Set&&l?h((new Set)[Symbol.iterator]()):void 0,"%SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?void 0:SharedArrayBuffer,"%String%":String,"%StringIteratorPrototype%":l?h(""[Symbol.iterator]()):void 0,"%Symbol%":l?Symbol:void 0,"%SyntaxError%":n,"%ThrowTypeError%":u,"%TypedArray%":m,"%TypeError%":o,"%Uint8Array%":"undefined"==typeof Uint8Array?void 0:Uint8Array,"%Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?void 0:Uint8ClampedArray,"%Uint16Array%":"undefined"==typeof Uint16Array?void 0:Uint16Array,"%Uint32Array%":"undefined"==typeof Uint32Array?void 0:Uint32Array,"%URIError%":URIError,"%WeakMap%":"undefined"==typeof WeakMap?void 0:WeakMap,"%WeakRef%":"undefined"==typeof WeakRef?void 0:WeakRef,"%WeakSet%":"undefined"==typeof WeakSet?void 0:WeakSet},v={"%ArrayBufferPrototype%":["ArrayBuffer","prototype"],"%ArrayPrototype%":["Array","prototype"],"%ArrayProto_entries%":["Array","prototype","entries"],"%ArrayProto_forEach%":["Array","prototype","forEach"],"%ArrayProto_keys%":["Array","prototype","keys"],"%ArrayProto_values%":["Array","prototype","values"],"%AsyncFunctionPrototype%":["AsyncFunction","prototype"],"%AsyncGenerator%":["AsyncGeneratorFunction","prototype"],"%AsyncGeneratorPrototype%":["AsyncGeneratorFunction","prototype","prototype"],"%BooleanPrototype%":["Boolean","prototype"],"%DataViewPrototype%":["DataView","prototype"],"%DatePrototype%":["Date","prototype"],"%ErrorPrototype%":["Error","prototype"],"%EvalErrorPrototype%":["EvalError","prototype"],"%Float32ArrayPrototype%":["Float32Array","prototype"],"%Float64ArrayPrototype%":["Float64Array","prototype"],"%FunctionPrototype%":["Function","prototype"],"%Generator%":["GeneratorFunction","prototype"],"%GeneratorPrototype%":["GeneratorFunction","prototype","prototype"],"%Int8ArrayPrototype%":["Int8Array","prototype"],"%Int16ArrayPrototype%":["Int16Array","prototype"],"%Int32ArrayPrototype%":["Int32Array","prototype"],"%JSONParse%":["JSON","parse"],"%JSONStringify%":["JSON","stringify"],"%MapPrototype%":["Map","prototype"],"%NumberPrototype%":["Number","prototype"],"%ObjectPrototype%":["Object","prototype"],"%ObjProto_toString%":["Object","prototype","toString"],"%ObjProto_valueOf%":["Object","prototype","valueOf"],"%PromisePrototype%":["Promise","prototype"],"%PromiseProto_then%":["Promise","prototype","then"],"%Promise_all%":["Promise","all"],"%Promise_reject%":["Promise","reject"],"%Promise_resolve%":["Promise","resolve"],"%RangeErrorPrototype%":["RangeError","prototype"],"%ReferenceErrorPrototype%":["ReferenceError","prototype"],"%RegExpPrototype%":["RegExp","prototype"],"%SetPrototype%":["Set","prototype"],"%SharedArrayBufferPrototype%":["SharedArrayBuffer","prototype"],"%StringPrototype%":["String","prototype"],"%SymbolPrototype%":["Symbol","prototype"],"%SyntaxErrorPrototype%":["SyntaxError","prototype"],"%TypedArrayPrototype%":["TypedArray","prototype"],"%TypeErrorPrototype%":["TypeError","prototype"],"%Uint8ArrayPrototype%":["Uint8Array","prototype"],"%Uint8ClampedArrayPrototype%":["Uint8ClampedArray","prototype"],"%Uint16ArrayPrototype%":["Uint16Array","prototype"],"%Uint32ArrayPrototype%":["Uint32Array","prototype"],"%URIErrorPrototype%":["URIError","prototype"],"%WeakMapPrototype%":["WeakMap","prototype"],"%WeakSetPrototype%":["WeakSet","prototype"]},g=r(215),y=r(157),w=g.call(Function.call,Array.prototype.concat),M=g.call(Function.apply,Array.prototype.splice),_=g.call(Function.call,String.prototype.replace),O=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,k=/\\(\\)?/g,E=function(e){var t=[];return _(e,O,(function(e,r,n,i){t[t.length]=n?_(i,k,"$1"):r||e})),t},S=function(e,t){var r,i=e;if(y(v,i)&&(i="%"+(r=v[i])[0]+"%"),y(b,i)){var a=b[i];if(void 0===a&&!t)throw new o("intrinsic "+e+" exists, but is not available. Please file an issue!");return{alias:r,name:i,value:a}}throw new n("intrinsic "+e+" does not exist!")};e.exports=function(e,t){if("string"!=typeof e||0===e.length)throw new o("intrinsic name must be a non-empty string");if(arguments.length>1&&"boolean"!=typeof t)throw new o('"allowMissing" argument must be a boolean');var r=E(e),n=r.length>0?r[0]:"",i=S("%"+n+"%",t),a=i.name,c=i.value,u=!1,l=i.alias;l&&(n=l[0],M(r,w([0,1],l)));for(var h=1,f=!0;h=r.length){var p=s(c,d);if(f=!!p,!t&&!(d in c))throw new o("base intrinsic for "+e+" exists, but the property is not available.");c=f&&"get"in p&&!("originalValue"in p.get)?p.get:c[d]}else f=y(c,d),c=c[d];f&&!u&&(b[a]=c)}}return c}},function(e,t,r){"use strict";var n=r(452),i=function(e){return null!=e},o=r(454)(),a=r(668),s=Object,c=a("Array.prototype.push"),u=a("Object.prototype.propertyIsEnumerable"),l=o?Object.getOwnPropertySymbols:null;e.exports=function(e,t){if(!i(e))throw new TypeError("target must be an object");var r,a,h,f,d,p,m,b=s(e);for(r=1;r=i&&o2&&void 0!==arguments[2]&&arguments[2],n=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(!e)return 0;var i="width"===t?"Left":"Top",o="width"===t?"Right":"Bottom",a=!r||n?window.getComputedStyle(e):null,s=e.offsetWidth,c=e.offsetHeight,u="width"===t?s:c;r||(u-=parseFloat(a["padding"+i])+parseFloat(a["padding"+o])+parseFloat(a["border"+i+"Width"])+parseFloat(a["border"+o+"Width"]));n&&(u+=parseFloat(a["margin"+i])+parseFloat(a["margin"+o]));return u}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){return 7*e+2*t+1}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){return!(!o.default.isMoment(e)||!o.default.isMoment(t))&&(e.month()===t.month()&&e.year()===t.year())};var n,i=r(16),o=(n=i)&&n.__esModule?n:{default:n}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,i=r(6),o=(n=i)&&n.__esModule?n:{default:n};var a=function(e){return o.default.createElement("svg",e,o.default.createElement("path",{d:"M336.2 274.5l-210.1 210h805.4c13 0 23 10 23 23s-10 23-23 23H126.1l210.1 210.1c11 11 11 21 0 32-5 5-10 7-16 7s-11-2-16-7l-249.1-249c-11-11-11-21 0-32l249.1-249.1c21-21.1 53 10.9 32 32z"}))};a.defaultProps={viewBox:"0 0 1000 1000"},t.default=a},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,i=r(6),o=(n=i)&&n.__esModule?n:{default:n};var a=function(e){return o.default.createElement("svg",e,o.default.createElement("path",{d:"M694.4 242.4l249.1 249.1c11 11 11 21 0 32L694.4 772.7c-5 5-10 7-16 7s-11-2-16-7c-11-11-11-21 0-32l210.1-210.1H67.1c-13 0-23-10-23-23s10-23 23-23h805.4L662.4 274.5c-21-21.1 11-53.1 32-32.1z"}))};a.defaultProps={viewBox:"0 0 1000 1000"},t.default=a},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=b(r(1)),i=b(r(147)),o=r(69),a=r(89),s=b(r(99)),c=b(r(517)),u=b(r(221)),l=b(r(518)),h=b(r(291)),f=b(r(519)),d=b(r(208)),p=b(r(166)),m=b(r(219));function b(e){return e&&e.__esModule?e:{default:e}}t.default={startDate:i.default.momentObj,endDate:i.default.momentObj,onDatesChange:n.default.func.isRequired,focusedInput:c.default,onFocusChange:n.default.func.isRequired,onClose:n.default.func,startDateId:n.default.string.isRequired,startDatePlaceholderText:n.default.string,endDateId:n.default.string.isRequired,endDatePlaceholderText:n.default.string,disabled:h.default,required:n.default.bool,readOnly:n.default.bool,screenReaderInputMessage:n.default.string,showClearDates:n.default.bool,showDefaultInputIcon:n.default.bool,inputIconPosition:u.default,customInputIcon:n.default.node,customArrowIcon:n.default.node,customCloseIcon:n.default.node,noBorder:n.default.bool,block:n.default.bool,small:n.default.bool,regular:n.default.bool,keepFocusOnInput:n.default.bool,renderMonthText:(0,o.mutuallyExclusiveProps)(n.default.func,"renderMonthText","renderMonthElement"),renderMonthElement:(0,o.mutuallyExclusiveProps)(n.default.func,"renderMonthText","renderMonthElement"),orientation:l.default,anchorDirection:f.default,openDirection:d.default,horizontalMargin:n.default.number,withPortal:n.default.bool,withFullScreenPortal:n.default.bool,appendToBody:n.default.bool,disableScroll:n.default.bool,daySize:o.nonNegativeInteger,isRTL:n.default.bool,firstDayOfWeek:p.default,initialVisibleMonth:n.default.func,numberOfMonths:n.default.number,keepOpenOnDateSelect:n.default.bool,reopenPickerOnClearDates:n.default.bool,renderCalendarInfo:n.default.func,calendarInfoPosition:m.default,hideKeyboardShortcutsPanel:n.default.bool,verticalHeight:o.nonNegativeInteger,transitionDuration:o.nonNegativeInteger,verticalSpacing:o.nonNegativeInteger,navPrev:n.default.node,navNext:n.default.node,onPrevMonthClick:n.default.func,onNextMonthClick:n.default.func,renderCalendarDay:n.default.func,renderDayContents:n.default.func,minimumNights:n.default.number,enableOutsideDays:n.default.bool,isDayBlocked:n.default.func,isOutsideRange:n.default.func,isDayHighlighted:n.default.func,displayFormat:n.default.oneOfType([n.default.string,n.default.func]),monthFormat:n.default.string,weekDayFormat:n.default.string,phrases:n.default.shape((0,s.default)(a.DateRangePickerPhrases)),dayAriaLabelFormat:n.default.string}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,i=r(1),o=(n=i)&&n.__esModule?n:{default:n},a=r(52);t.default=o.default.oneOf([a.START_DATE,a.END_DATE])},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,i=r(1),o=(n=i)&&n.__esModule?n:{default:n},a=r(52);t.default=o.default.oneOf([a.HORIZONTAL_ORIENTATION,a.VERTICAL_ORIENTATION])},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,i=r(1),o=(n=i)&&n.__esModule?n:{default:n},a=r(52);t.default=o.default.oneOf([a.ANCHOR_LEFT,a.ANCHOR_RIGHT])},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,r,i){var o="undefined"!=typeof window?window.innerWidth:0,a=e===n.ANCHOR_LEFT?o-r:r,s=i||0;return function(e,t,r){t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r;return e}({},e,Math.min(t+a-s,0))};var n=r(52)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,r){var i=r.getBoundingClientRect(),o=i.left,a=i.top;e===n.OPEN_UP&&(a=-(window.innerHeight-i.bottom));t===n.ANCHOR_RIGHT&&(o=-(window.innerWidth-i.right));return{transform:"translate3d("+String(Math.round(o))+"px, "+String(Math.round(a))+"px, 0)"}};var n=r(52)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getScrollParent=i,t.getScrollAncestorsOverflowY=o,t.default=function(e){var t=o(e),r=function(e){return t.forEach((function(t,r){r.style.setProperty("overflow-y",e?"hidden":t)}))};return r(!0),function(){return r(!1)}};var n=function(){return document.scrollingElement||document.documentElement};function i(e){var t=e.parentElement;if(null==t)return n();var r=window.getComputedStyle(t).overflowY;return"visible"!==r&&"hidden"!==r&&t.scrollHeight>t.clientHeight?t:i(t)}function o(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new Map,r=n(),a=i(e);return t.set(a,a.style.overflowY),a===r?t:o(a,t)}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var r=0;r0&&(I||T||a!==M)){var K=g||this.today;H=this.deleteModifierFromRange(H,K,K.clone().add(M,"days"),"blocked-minimum-nights"),H=this.deleteModifierFromRange(H,K,K.clone().add(M,"days"),"blocked")}(I||R)&&(0,h.default)(j).forEach((function(e){Object.keys(e).forEach((function(e){var r=(0,l.default)(e),n=!1;(I||x)&&(s(r)?(H=t.addModifier(H,r,"blocked-out-of-range"),n=!0):H=t.deleteModifier(H,r,"blocked-out-of-range")),(I||D)&&(c(r)?(H=t.addModifier(H,r,"blocked-calendar"),n=!0):H=t.deleteModifier(H,r,"blocked-calendar")),H=n?t.addModifier(H,r,"blocked"):t.deleteModifier(H,r,"blocked"),(I||P)&&(H=u(r)?t.addModifier(H,r,"highlighted-calendar"):t.deleteModifier(H,r,"highlighted-calendar"))}))})),a>0&&r&&i===z.END_DATE&&(H=this.addModifierToRange(H,r,r.clone().add(a,"days"),"blocked-minimum-nights"),H=this.addModifierToRange(H,r,r.clone().add(a,"days"),"blocked"));var G=(0,l.default)();if((0,v.default)(this.today,G)||(H=this.deleteModifier(H,this.today,"today"),H=this.addModifier(H,G,"today"),this.today=G),Object.keys(H).length>0&&this.setState({visibleDays:(0,o.default)({},j,H)}),I||f!==E){var X=F(f,i);this.setState({phrases:(0,o.default)({},f,{chooseAvailableDate:X})})}}},{key:"onDayClick",value:function(e,t){var r=this.props,n=r.keepOpenOnDateSelect,i=r.minimumNights,o=r.onBlur,a=r.focusedInput,s=r.onFocusChange,c=r.onClose,u=r.onDatesChange,l=r.startDateOffset,h=r.endDateOffset,f=r.disabled;if(t&&t.preventDefault(),!this.isBlocked(e)){var d=this.props,p=d.startDate,b=d.endDate;if(l||h)p=(0,_.default)(l,e),b=(0,_.default)(h,e),n||(s(null),c({startDate:p,endDate:b}));else if(a===z.START_DATE){var v=b&&b.clone().subtract(i,"days"),w=(0,y.default)(v,e)||(0,g.default)(p,b),M=f===z.END_DATE;M&&w||(p=e,w&&(b=null)),M&&!w?(s(null),c({startDate:p,endDate:b})):M||s(z.END_DATE)}else if(a===z.END_DATE){var O=p&&p.clone().add(i,"days");p?(0,m.default)(e,O)?(b=e,n||(s(null),c({startDate:p,endDate:b}))):f!==z.START_DATE&&(p=e,b=null):(b=e,s(z.START_DATE))}u({startDate:p,endDate:b}),o()}}},{key:"onDayMouseEnter",value:function(e){if(!this.isTouchDevice){var t=this.props,r=t.startDate,n=t.endDate,i=t.focusedInput,a=t.minimumNights,s=t.startDateOffset,c=t.endDateOffset,u=this.state,l=u.hoverDate,h=u.visibleDays,f=null;if(i){var d=s||c,p={};if(d){var m=(0,_.default)(s,e),b=(0,_.default)(c,e,(function(e){return e.add(1,"day")}));f={start:m,end:b},this.state.dateOffset&&this.state.dateOffset.start&&this.state.dateOffset.end&&(p=this.deleteModifierFromRange(p,this.state.dateOffset.start,this.state.dateOffset.end,"hovered-offset")),p=this.addModifierToRange(p,m,b,"hovered-offset")}if(!d){if(p=this.deleteModifier(p,l,"hovered"),p=this.addModifier(p,e,"hovered"),r&&!n&&i===z.END_DATE){if((0,g.default)(l,r)){var w=l.clone().add(1,"day");p=this.deleteModifierFromRange(p,r,w,"hovered-span")}if(!this.isBlocked(e)&&(0,g.default)(e,r)){var M=e.clone().add(1,"day");p=this.addModifierToRange(p,r,M,"hovered-span")}}if(!r&&n&&i===z.START_DATE&&((0,y.default)(l,n)&&(p=this.deleteModifierFromRange(p,l,n,"hovered-span")),!this.isBlocked(e)&&(0,y.default)(e,n)&&(p=this.addModifierToRange(p,e,n,"hovered-span"))),r){var O=r.clone().add(1,"day"),k=r.clone().add(a+1,"days");if(p=this.deleteModifierFromRange(p,O,k,"after-hovered-start"),(0,v.default)(e,r)){var E=r.clone().add(1,"day"),S=r.clone().add(a+1,"days");p=this.addModifierToRange(p,E,S,"after-hovered-start")}}}this.setState({hoverDate:e,dateOffset:f,visibleDays:(0,o.default)({},h,p)})}}}},{key:"onDayMouseLeave",value:function(e){var t=this.props,r=t.startDate,n=t.endDate,i=t.minimumNights,a=this.state,s=a.hoverDate,c=a.visibleDays,u=a.dateOffset;if(!this.isTouchDevice&&s){var l={};if(l=this.deleteModifier(l,s,"hovered"),u&&(l=this.deleteModifierFromRange(l,this.state.dateOffset.start,this.state.dateOffset.end,"hovered-offset")),r&&!n&&(0,g.default)(s,r)){var h=s.clone().add(1,"day");l=this.deleteModifierFromRange(l,r,h,"hovered-span")}if(!r&&n&&(0,g.default)(n,s)&&(l=this.deleteModifierFromRange(l,s,n,"hovered-span")),r&&(0,v.default)(e,r)){var f=r.clone().add(1,"day"),d=r.clone().add(i+1,"days");l=this.deleteModifierFromRange(l,f,d,"after-hovered-start")}this.setState({hoverDate:null,visibleDays:(0,o.default)({},c,l)})}}},{key:"onPrevMonthClick",value:function(){var e=this.props,t=e.onPrevMonthClick,r=e.numberOfMonths,n=e.enableOutsideDays,i=this.state,a=i.currentMonth,s=i.visibleDays,c={};Object.keys(s).sort().slice(0,r+1).forEach((function(e){c[e]=s[e]}));var u=a.clone().subtract(2,"months"),l=(0,w.default)(u,1,n,!0),h=a.clone().subtract(1,"month");this.setState({currentMonth:h,visibleDays:(0,o.default)({},c,this.getModifiers(l))},(function(){t(h.clone())}))}},{key:"onNextMonthClick",value:function(){var e=this.props,t=e.onNextMonthClick,r=e.numberOfMonths,n=e.enableOutsideDays,i=this.state,a=i.currentMonth,s=i.visibleDays,c={};Object.keys(s).sort().slice(1).forEach((function(e){c[e]=s[e]}));var u=a.clone().add(r+1,"month"),l=(0,w.default)(u,1,n,!0),h=a.clone().add(1,"month");this.setState({currentMonth:h,visibleDays:(0,o.default)({},c,this.getModifiers(l))},(function(){t(h.clone())}))}},{key:"onMonthChange",value:function(e){var t=this.props,r=t.numberOfMonths,n=t.enableOutsideDays,i=t.orientation===z.VERTICAL_SCROLLABLE,o=(0,w.default)(e,r,n,i);this.setState({currentMonth:e.clone(),visibleDays:this.getModifiers(o)})}},{key:"onYearChange",value:function(e){var t=this.props,r=t.numberOfMonths,n=t.enableOutsideDays,i=t.orientation===z.VERTICAL_SCROLLABLE,o=(0,w.default)(e,r,n,i);this.setState({currentMonth:e.clone(),visibleDays:this.getModifiers(o)})}},{key:"onMultiplyScrollableMonths",value:function(){var e=this.props,t=e.numberOfMonths,r=e.enableOutsideDays,n=this.state,i=n.currentMonth,a=n.visibleDays,s=Object.keys(a).length,c=i.clone().add(s,"month"),u=(0,w.default)(c,t,r,!0);this.setState({visibleDays:(0,o.default)({},a,this.getModifiers(u))})}},{key:"getFirstFocusableDay",value:function(e){var t=this,r=this.props,i=r.startDate,o=r.endDate,a=r.focusedInput,s=r.minimumNights,c=r.numberOfMonths,u=e.clone().startOf("month");if(a===z.START_DATE&&i?u=i.clone():a===z.END_DATE&&!o&&i?u=i.clone().add(s,"days"):a===z.END_DATE&&o&&(u=o.clone()),this.isBlocked(u)){for(var l=[],h=e.clone().add(c-1,"months").endOf("month"),f=u.clone();!(0,g.default)(f,h);)f=f.clone().add(1,"day"),l.push(f);var d=l.filter((function(e){return!t.isBlocked(e)}));d.length>0&&(u=n(d,1)[0])}return u}},{key:"getModifiers",value:function(e){var t=this,r={};return Object.keys(e).forEach((function(n){r[n]={},e[n].forEach((function(e){r[n][(0,O.default)(e)]=t.getModifiersForDay(e)}))})),r}},{key:"getModifiersForDay",value:function(e){var t=this;return new Set(Object.keys(this.modifiers).filter((function(r){return t.modifiers[r](e)})))}},{key:"getStateForNewMonth",value:function(e){var t=this,r=e.initialVisibleMonth,n=e.numberOfMonths,i=e.enableOutsideDays,o=e.orientation,a=e.startDate,s=(r||(a?function(){return a}:function(){return t.today}))(),c=o===z.VERTICAL_SCROLLABLE;return{currentMonth:s,visibleDays:this.getModifiers((0,w.default)(s,n,i,c))}}},{key:"addModifier",value:function(e,t,r){var n=this.props,i=n.numberOfMonths,a=n.enableOutsideDays,s=n.orientation,c=this.state,u=c.currentMonth,l=c.visibleDays,h=u,f=i;if(s===z.VERTICAL_SCROLLABLE?f=Object.keys(l).length:(h=h.clone().subtract(1,"month"),f+=2),!t||!(0,M.default)(t,h,f,a))return e;var d=(0,O.default)(t),p=(0,o.default)({},e);if(a)p=Object.keys(l).filter((function(e){return Object.keys(l[e]).indexOf(d)>-1})).reduce((function(t,n){var i=e[n]||l[n],a=new Set(i[d]);return a.add(r),(0,o.default)({},t,P({},n,(0,o.default)({},i,P({},d,a))))}),p);else{var m=(0,k.default)(t),b=e[m]||l[m],v=new Set(b[d]);v.add(r),p=(0,o.default)({},p,P({},m,(0,o.default)({},b,P({},d,v))))}return p}},{key:"addModifierToRange",value:function(e,t,r,n){for(var i=e,o=t.clone();(0,y.default)(o,r);)i=this.addModifier(i,o,n),o=o.clone().add(1,"day");return i}},{key:"deleteModifier",value:function(e,t,r){var n=this.props,i=n.numberOfMonths,a=n.enableOutsideDays,s=n.orientation,c=this.state,u=c.currentMonth,l=c.visibleDays,h=u,f=i;if(s===z.VERTICAL_SCROLLABLE?f=Object.keys(l).length:(h=h.clone().subtract(1,"month"),f+=2),!t||!(0,M.default)(t,h,f,a))return e;var d=(0,O.default)(t),p=(0,o.default)({},e);if(a)p=Object.keys(l).filter((function(e){return Object.keys(l[e]).indexOf(d)>-1})).reduce((function(t,n){var i=e[n]||l[n],a=new Set(i[d]);return a.delete(r),(0,o.default)({},t,P({},n,(0,o.default)({},i,P({},d,a))))}),p);else{var m=(0,k.default)(t),b=e[m]||l[m],v=new Set(b[d]);v.delete(r),p=(0,o.default)({},p,P({},m,(0,o.default)({},b,P({},d,v))))}return p}},{key:"deleteModifierFromRange",value:function(e,t,r,n){for(var i=e,o=t.clone();(0,y.default)(o,r);)i=this.deleteModifier(i,o,n),o=o.clone().add(1,"day");return i}},{key:"doesNotMeetMinimumNights",value:function(e){var t=this.props,r=t.startDate,n=t.isOutsideRange,i=t.focusedInput,o=t.minimumNights;if(i!==z.END_DATE)return!1;if(r){var a=e.diff(r.clone().startOf("day").hour(12),"days");return a=0}return n((0,l.default)(e).subtract(o,"days"))}},{key:"isDayAfterHoveredStartDate",value:function(e){var t=this.props,r=t.startDate,n=t.endDate,i=t.minimumNights,o=(this.state||{}).hoverDate;return!!r&&!n&&!this.isBlocked(e)&&(0,b.default)(o,e)&&i>0&&(0,v.default)(o,r)}},{key:"isEndDate",value:function(e){var t=this.props.endDate;return(0,v.default)(e,t)}},{key:"isHovered",value:function(e){var t=(this.state||{}).hoverDate;return!!this.props.focusedInput&&(0,v.default)(e,t)}},{key:"isInHoveredSpan",value:function(e){var t=this.props,r=t.startDate,n=t.endDate,i=(this.state||{}).hoverDate,o=!!r&&!n&&(e.isBetween(r,i)||(0,v.default)(i,e)),a=!!n&&!r&&(e.isBetween(i,n)||(0,v.default)(i,e)),s=i&&!this.isBlocked(i);return(o||a)&&s}},{key:"isInSelectedSpan",value:function(e){var t=this.props,r=t.startDate,n=t.endDate;return e.isBetween(r,n)}},{key:"isLastInRange",value:function(e){var t=this.props.endDate;return this.isInSelectedSpan(e)&&(0,b.default)(e,t)}},{key:"isStartDate",value:function(e){var t=this.props.startDate;return(0,v.default)(e,t)}},{key:"isBlocked",value:function(e){var t=this.props,r=t.isDayBlocked,n=t.isOutsideRange;return r(e)||n(e)||this.doesNotMeetMinimumNights(e)}},{key:"isToday",value:function(e){return(0,v.default)(e,this.today)}},{key:"isFirstDayOfWeek",value:function(e){var t=this.props.firstDayOfWeek;return e.day()===(t||l.default.localeData().firstDayOfWeek())}},{key:"isLastDayOfWeek",value:function(e){var t=this.props.firstDayOfWeek;return e.day()===((t||l.default.localeData().firstDayOfWeek())+6)%7}},{key:"render",value:function(){var e=this.props,t=e.numberOfMonths,r=e.orientation,n=e.monthFormat,i=e.renderMonthText,o=e.navPrev,s=e.navNext,c=e.noNavButtons,u=e.onOutsideClick,l=e.withPortal,h=e.enableOutsideDays,f=e.firstDayOfWeek,d=e.hideKeyboardShortcutsPanel,p=e.daySize,m=e.focusedInput,b=e.renderCalendarDay,v=e.renderDayContents,g=e.renderCalendarInfo,y=e.renderMonthElement,w=e.calendarInfoPosition,M=e.onBlur,_=e.isFocused,O=e.showKeyboardShortcuts,k=e.isRTL,E=e.weekDayFormat,S=e.dayAriaLabelFormat,A=e.verticalHeight,C=e.noBorder,j=e.transitionDuration,z=e.verticalBorderSpacing,D=e.horizontalMonthPadding,P=this.state,R=P.currentMonth,T=P.phrases,F=P.visibleDays;return a.default.createElement(x.default,{orientation:r,enableOutsideDays:h,modifiers:F,numberOfMonths:t,onDayClick:this.onDayClick,onDayMouseEnter:this.onDayMouseEnter,onDayMouseLeave:this.onDayMouseLeave,onPrevMonthClick:this.onPrevMonthClick,onNextMonthClick:this.onNextMonthClick,onMonthChange:this.onMonthChange,onYearChange:this.onYearChange,onMultiplyScrollableMonths:this.onMultiplyScrollableMonths,monthFormat:n,renderMonthText:i,withPortal:l,hidden:!m,initialVisibleMonth:function(){return R},daySize:p,onOutsideClick:u,navPrev:o,navNext:s,noNavButtons:c,renderCalendarDay:b,renderDayContents:v,renderCalendarInfo:g,renderMonthElement:y,calendarInfoPosition:w,firstDayOfWeek:f,hideKeyboardShortcutsPanel:d,isFocused:_,getFirstFocusableDay:this.getFirstFocusableDay,onBlur:M,showKeyboardShortcuts:O,phrases:T,isRTL:k,weekDayFormat:E,dayAriaLabelFormat:S,verticalHeight:A,verticalBorderSpacing:z,noBorder:C,transitionDuration:j,horizontalMonthPadding:D})}}]),t}(a.default.Component);t.default=N,N.propTypes=R,N.defaultProps=T},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){if(!n.default.isMoment(e)||!n.default.isMoment(t))return!1;var r=(0,n.default)(e).add(1,"day");return(0,i.default)(r,t)};var n=o(r(16)),i=o(r(204));function o(e){return e&&e.__esModule?e:{default:e}}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=p(r(1)),i=p(r(147)),o=r(69),a=r(89),s=p(r(99)),c=p(r(221)),u=p(r(518)),l=p(r(519)),h=p(r(208)),f=p(r(166)),d=p(r(219));function p(e){return e&&e.__esModule?e:{default:e}}t.default={date:i.default.momentObj,onDateChange:n.default.func.isRequired,focused:n.default.bool,onFocusChange:n.default.func.isRequired,id:n.default.string.isRequired,placeholder:n.default.string,disabled:n.default.bool,required:n.default.bool,readOnly:n.default.bool,screenReaderInputMessage:n.default.string,showClearDate:n.default.bool,customCloseIcon:n.default.node,showDefaultInputIcon:n.default.bool,inputIconPosition:c.default,customInputIcon:n.default.node,noBorder:n.default.bool,block:n.default.bool,small:n.default.bool,regular:n.default.bool,verticalSpacing:o.nonNegativeInteger,keepFocusOnInput:n.default.bool,renderMonthText:(0,o.mutuallyExclusiveProps)(n.default.func,"renderMonthText","renderMonthElement"),renderMonthElement:(0,o.mutuallyExclusiveProps)(n.default.func,"renderMonthText","renderMonthElement"),orientation:u.default,anchorDirection:l.default,openDirection:h.default,horizontalMargin:n.default.number,withPortal:n.default.bool,withFullScreenPortal:n.default.bool,appendToBody:n.default.bool,disableScroll:n.default.bool,initialVisibleMonth:n.default.func,firstDayOfWeek:f.default,numberOfMonths:n.default.number,keepOpenOnDateSelect:n.default.bool,reopenPickerOnClearDate:n.default.bool,renderCalendarInfo:n.default.func,calendarInfoPosition:d.default,hideKeyboardShortcutsPanel:n.default.bool,daySize:o.nonNegativeInteger,isRTL:n.default.bool,verticalHeight:o.nonNegativeInteger,transitionDuration:o.nonNegativeInteger,horizontalMonthPadding:o.nonNegativeInteger,navPrev:n.default.node,navNext:n.default.node,onPrevMonthClick:n.default.func,onNextMonthClick:n.default.func,onClose:n.default.func,renderCalendarDay:n.default.func,renderDayContents:n.default.func,enableOutsideDays:n.default.bool,isDayBlocked:n.default.func,isOutsideRange:n.default.func,isDayHighlighted:n.default.func,displayFormat:n.default.oneOfType([n.default.string,n.default.func]),monthFormat:n.default.string,weekDayFormat:n.default.string,phrases:n.default.shape((0,s.default)(a.SingleDatePickerPhrases)),dayAriaLabelFormat:n.default.string}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=Object.assign||function(e){for(var t=1;t0;)r-=1,e*=60,n=Math.floor(e+1e-6),i+=t[n],e-=n,n&&(o+=i,i="");return o}(i-o,Math.min(~~r,10));o>0;)n=t[o%60]+n,o=Math.floor(o/60);return e<0&&(n="-"+n),n&&a?n+a:(a||"-"!==n)&&(n||a)||"0"}function n(e){var t,n=[],i=0;for(t=0;ts.population||a.population===s.population&&n&&n[a.name]?c.unshift(a):c.push(a),l=!0);l||h.push([a])}for(i=0;ir&&(i=t,t=r,r=i),i=0;ir&&(a=Math.min(a,i+1)));return[o,a]}(e.untils,t,r),o=n.apply(e.untils,i);return o[o.length-1]=null,{name:e.name,abbrs:n.apply(e.abbrs,i),untils:o,offsets:n.apply(e.offsets,i),population:e.population,countries:e.countries}}return e.tz.pack=a,e.tz.packBase60=r,e.tz.createLinks=l,e.tz.filterYears=h,e.tz.filterLinkPack=function(e,t,r,n){var i,o,c=e.zones,u=[];for(i=0;i0&&!i.call(e,0))for(var m=0;m0)for(var b=0;b= 0");var r,n=0===t?0:t;if(c(e)&&(r=s(e,"constructor"),o&&"Object"===h(r)&&null===(r=s(r,o))&&(r=void 0)),void 0===r)return i(n);if(!u(r))throw new a("C must be a constructor");return new r(n)}},function(e,t,r){var n="function"==typeof Map&&Map.prototype,i=Object.getOwnPropertyDescriptor&&n?Object.getOwnPropertyDescriptor(Map.prototype,"size"):null,o=n&&i&&"function"==typeof i.get?i.get:null,a=n&&Map.prototype.forEach,s="function"==typeof Set&&Set.prototype,c=Object.getOwnPropertyDescriptor&&s?Object.getOwnPropertyDescriptor(Set.prototype,"size"):null,u=s&&c&&"function"==typeof c.get?c.get:null,l=s&&Set.prototype.forEach,h="function"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,f="function"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,d=Boolean.prototype.valueOf,p=Object.prototype.toString,m=Function.prototype.toString,b=String.prototype.match,v="function"==typeof BigInt?BigInt.prototype.valueOf:null,g=r(587).custom,y=g&&O(g)?g:null;function w(e,t,r){var n="double"===(r.quoteStyle||t)?'"':"'";return n+e+n}function M(e){return String(e).replace(/"/g,""")}function _(e){return"[object Array]"===S(e)}function O(e){return"[object Symbol]"===S(e)}e.exports=function e(t,r,n,i){var s=r||{};if(E(s,"quoteStyle")&&"single"!==s.quoteStyle&&"double"!==s.quoteStyle)throw new TypeError('option "quoteStyle" must be "single" or "double"');if(E(s,"maxStringLength")&&("number"==typeof s.maxStringLength?s.maxStringLength<0&&s.maxStringLength!==1/0:null!==s.maxStringLength))throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');var c=!E(s,"customInspect")||s.customInspect;if("boolean"!=typeof c)throw new TypeError('option "customInspect", if provided, must be `true` or `false`');if(E(s,"indent")&&null!==s.indent&&"\t"!==s.indent&&!(parseInt(s.indent,10)===s.indent&&s.indent>0))throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`');if(void 0===t)return"undefined";if(null===t)return"null";if("boolean"==typeof t)return t?"true":"false";if("string"==typeof t)return function e(t,r){if(t.length>r.maxStringLength){var n=t.length-r.maxStringLength,i="... "+n+" more character"+(n>1?"s":"");return e(t.slice(0,r.maxStringLength),r)+i}return w(t.replace(/(['\\])/g,"\\$1").replace(/[\x00-\x1f]/g,C),"single",r)}(t,s);if("number"==typeof t)return 0===t?1/0/t>0?"0":"-0":String(t);if("bigint"==typeof t)return String(t)+"n";var p=void 0===s.depth?5:s.depth;if(void 0===n&&(n=0),n>=p&&p>0&&"object"==typeof t)return _(t)?"[Array]":"[Object]";var g=function(e,t){var r;if("\t"===e.indent)r="\t";else{if(!("number"==typeof e.indent&&e.indent>0))return null;r=Array(e.indent+1).join(" ")}return{base:r,prev:Array(t+1).join(r)}}(s,n);if(void 0===i)i=[];else if(A(i,t)>=0)return"[Circular]";function k(t,r,o){if(r&&(i=i.slice()).push(r),o){var a={depth:s.depth};return E(s,"quoteStyle")&&(a.quoteStyle=s.quoteStyle),e(t,a,n+1,i)}return e(t,s,n+1,i)}if("function"==typeof t){var R=function(e){if(e.name)return e.name;var t=b.call(m.call(e),/^function\s*([\w$]+)/);if(t)return t[1];return null}(t);return"[Function"+(R?": "+R:" (anonymous)")+"]"}if(O(t)){var T=Symbol.prototype.toString.call(t);return"object"==typeof t?j(T):T}if(function(e){if(!e||"object"!=typeof e)return!1;if("undefined"!=typeof HTMLElement&&e instanceof HTMLElement)return!0;return"string"==typeof e.nodeName&&"function"==typeof e.getAttribute}(t)){for(var F="<"+String(t.nodeName).toLowerCase(),N=t.attributes||[],I=0;I"}if(_(t)){if(0===t.length)return"[]";var L=P(t,k);return g&&!function(e){for(var t=0;t=0)return!1;return!0}(L)?"["+D(L,g)+"]":"[ "+L.join(", ")+" ]"}if(function(e){return"[object Error]"===S(e)}(t)){var B=P(t,k);return 0===B.length?"["+String(t)+"]":"{ ["+String(t)+"] "+B.join(", ")+" }"}if("object"==typeof t&&c){if(y&&"function"==typeof t[y])return t[y]();if("function"==typeof t.inspect)return t.inspect()}if(function(e){if(!o||!e||"object"!=typeof e)return!1;try{o.call(e);try{u.call(e)}catch(e){return!0}return e instanceof Map}catch(e){}return!1}(t)){var H=[];return a.call(t,(function(e,r){H.push(k(r,t,!0)+" => "+k(e,t))})),x("Map",o.call(t),H,g)}if(function(e){if(!u||!e||"object"!=typeof e)return!1;try{u.call(e);try{o.call(e)}catch(e){return!0}return e instanceof Set}catch(e){}return!1}(t)){var q=[];return l.call(t,(function(e){q.push(k(e,t))})),x("Set",u.call(t),q,g)}if(function(e){if(!h||!e||"object"!=typeof e)return!1;try{h.call(e,h);try{f.call(e,f)}catch(e){return!0}return e instanceof WeakMap}catch(e){}return!1}(t))return z("WeakMap");if(function(e){if(!f||!e||"object"!=typeof e)return!1;try{f.call(e,f);try{h.call(e,h)}catch(e){return!0}return e instanceof WeakSet}catch(e){}return!1}(t))return z("WeakSet");if(function(e){return"[object Number]"===S(e)}(t))return j(k(Number(t)));if(function(e){return"[object BigInt]"===S(e)}(t))return j(k(v.call(t)));if(function(e){return"[object Boolean]"===S(e)}(t))return j(d.call(t));if(function(e){return"[object String]"===S(e)}(t))return j(k(String(t)));if(!function(e){return"[object Date]"===S(e)}(t)&&!function(e){return"[object RegExp]"===S(e)}(t)){var V=P(t,k);return 0===V.length?"{}":g?"{"+D(V,g)+"}":"{ "+V.join(", ")+" }"}return String(t)};var k=Object.prototype.hasOwnProperty||function(e){return e in this};function E(e,t){return k.call(e,t)}function S(e){return p.call(e)}function A(e,t){if(e.indexOf)return e.indexOf(t);for(var r=0,n=e.length;r5&&(m=arguments[5]);for(var b=d,v=0;v0&&(M=u(w)),M){var _=l(s(w,"length"));b=e(t,w,_,b,p-1)}else{if(b>=i)throw new n("index too large");a(t,h(b),w),b+=1}}v+=1}return b}},function(e,t,r){"use strict";var n=r(61),i=r(199),o=n("%Reflect.apply%",!0)||i("%Function.prototype.apply%");e.exports=function(e,t){var r=arguments.length>2?arguments[2]:[];return o(e,t,r)}},function(e,t,r){"use strict";var n=r(61)("%TypeError%"),i=r(598),o=r(198),a=r(119);e.exports=function(e,t,r){if("Object"!==a(e))throw new n("Assertion failed: Type(O) is not Object");if(!o(t))throw new n("Assertion failed: IsPropertyKey(P) is not true");var s=i(e,t,r);if(!s)throw new n("unable to create data property");return s}},function(e,t,r){"use strict";var n=r(61)("%TypeError%"),i=r(456),o=r(457),a=r(599),s=r(458),c=r(603),u=r(198),l=r(459),h=r(119);e.exports=function(e,t,r){if("Object"!==h(e))throw new n("Assertion failed: Type(O) is not Object");if(!u(t))throw new n("Assertion failed: IsPropertyKey(P) is not true");var f=a(e,t),d=!f||c(e);return!(f&&(!f["[[Writable]]"]||!f["[[Configurable]]"])||!d)&&i(s,l,o,e,t,{"[[Configurable]]":!0,"[[Enumerable]]":!0,"[[Value]]":r,"[[Writable]]":!0})}},function(e,t,r){"use strict";var n=r(61),i=r(600),o=n("%TypeError%"),a=r(199)("Object.prototype.propertyIsEnumerable"),s=r(157),c=r(310),u=r(198),l=r(601),h=r(460),f=r(119);e.exports=function(e,t){if("Object"!==f(e))throw new o("Assertion failed: O must be an Object");if(!u(t))throw new o("Assertion failed: P must be a Property Key");if(s(e,t)){if(!i){var r=c(e)&&"length"===t,n=l(e)&&"lastIndex"===t;return{"[[Configurable]]":!(r||n),"[[Enumerable]]":a(e,t),"[[Value]]":e[t],"[[Writable]]":!0}}return h(i(e,t))}}},function(e,t,r){"use strict";var n=r(61)("%Object.getOwnPropertyDescriptor%");if(n)try{n([],"length")}catch(e){n=null}e.exports=n},function(e,t,r){"use strict";var n=r(61)("%Symbol.match%",!0),i=r(602),o=r(461);e.exports=function(e){if(!e||"object"!=typeof e)return!1;if(n){var t=e[n];if(void 0!==t)return o(t)}return i(e)}},function(e,t,r){"use strict";var n,i,o,a,s=r(282)()&&"symbol"==typeof Symbol.toStringTag;if(s){n=Function.call.bind(Object.prototype.hasOwnProperty),i=Function.call.bind(RegExp.prototype.exec),o={};var c=function(){throw o};a={toString:c,valueOf:c},"symbol"==typeof Symbol.toPrimitive&&(a[Symbol.toPrimitive]=c)}var u=Object.prototype.toString,l=Object.getOwnPropertyDescriptor;e.exports=s?function(e){if(!e||"object"!=typeof e)return!1;var t=l(e,"lastIndex");if(!(t&&n(t,"value")))return!1;try{i(e,a)}catch(e){return e===o}}:function(e){return!(!e||"object"!=typeof e&&"function"!=typeof e)&&"[object RegExp]"===u.call(e)}},function(e,t,r){"use strict";var n=r(61)("%Object%"),i=r(465),o=n.preventExtensions,a=n.isExtensible;e.exports=o?function(e){return!i(e)&&a(e)}:function(e){return!i(e)}},function(e,t,r){"use strict";var n=r(61)("%TypeError%"),i=r(198),o=r(119);e.exports=function(e,t){if("Object"!==o(e))throw new n("Assertion failed: `O` must be an Object");if(!i(t))throw new n("Assertion failed: `P` must be a Property Key");return t in e}},function(e,t,r){"use strict";var n=r(61)("%Math%"),i=r(606),o=r(312),a=r(463),s=r(607),c=n.floor,u=n.abs;e.exports=function(e){var t=i(e);return o(t)?0:0!==t&&a(t)?s(t)*c(u(t)):t}},function(e,t,r){"use strict";e.exports=function(e){return+e}},function(e,t,r){"use strict";e.exports=function(e){return e>=0?1:-1}},function(e,t,r){"use strict";var n=r(61),i=n("%TypeError%"),o=n("%Number%"),a=n("%RegExp%"),s=n("%parseInt%"),c=r(199),u=r(609),l=r(465),h=c("String.prototype.slice"),f=u(/^0b[01]+$/i),d=u(/^0o[0-7]+$/i),p=u(/^[-+]0x[0-9a-f]+$/i),m=u(new a("["+["…","​","￾"].join("")+"]","g")),b=["\t\n\v\f\r   ᠎    ","          \u2028","\u2029\ufeff"].join(""),v=new RegExp("(^["+b+"]+)|(["+b+"]+$)","g"),g=c("String.prototype.replace"),y=r(610);e.exports=function e(t){var r=l(t)?t:y(t,o);if("symbol"==typeof r)throw new i("Cannot convert a Symbol value to a number");if("string"==typeof r){if(f(r))return e(s(h(r,2),2));if(d(r))return e(s(h(r,2),8));if(m(r)||p(r))return NaN;var n=function(e){return g(e,v,"")}(r);if(n!==r)return e(n)}return o(r)}},function(e,t,r){"use strict";var n=r(61)("RegExp.prototype.test"),i=r(308);e.exports=function(e){return i(n,e)}},function(e,t,r){"use strict";var n=r(611);e.exports=function(e){return arguments.length>1?n(e,arguments[1]):n(e)}},function(e,t,r){"use strict";var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator,i=r(612),o=r(462),a=r(613),s=r(468),c=function(e,t){if(null==e)throw new TypeError("Cannot call method on "+e);if("string"!=typeof t||"number"!==t&&"string"!==t)throw new TypeError('hint must be "string" or "number"');var r,n,a,s="string"===t?["toString","valueOf"]:["valueOf","toString"];for(a=0;a1&&(arguments[1]===String?r="string":arguments[1]===Number&&(r="number")),n&&(Symbol.toPrimitive?t=u(e,Symbol.toPrimitive):s(e)&&(t=Symbol.prototype.valueOf)),void 0!==t){var o=t.call(e,r);if(i(o))return o;throw new TypeError("unable to convert exotic object to primitive")}return"default"===r&&(a(e)||s(e))&&(r="string"),c(e,"default"===r?"number":r)}},function(e,t,r){"use strict";e.exports=function(e){return null===e||"function"!=typeof e&&"object"!=typeof e}},function(e,t,r){"use strict";var n=Date.prototype.getDay,i=Object.prototype.toString,o="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;e.exports=function(e){return"object"==typeof e&&null!==e&&(o?function(e){try{return n.call(e),!0}catch(e){return!1}}(e):"[object Date]"===i.call(e))}},function(e,t,r){"use strict";var n=r(61),i=n("%String%"),o=n("%TypeError%");e.exports=function(e){if("symbol"==typeof e)throw new o("Cannot convert a Symbol value to a string");return i(e)}},function(e,t,r){"use strict";var n=r(61)("%Object%"),i=r(469);e.exports=function(e){return i(e),n(e)}},function(e,t,r){"use strict";var n=r(61)("%TypeError%");e.exports=function(e,t){if(null==e)throw new n(t||"Cannot call method on "+e);return e}},function(e,t,r){"use strict";var n=r(145),i=r(470);e.exports=function(){var e=i();return n(Array.prototype,{flat:e},{flat:function(){return Array.prototype.flat!==e}}),e}},function(e,t,r){"use strict";(function(t){var n=r(145),i=r(468),o="__ global cache key __";"function"==typeof Symbol&&i(Symbol("foo"))&&"function"==typeof Symbol.for&&(o=Symbol.for(o));var a=function(){return!0},s=function(){if(!t[o]){var e={};e[o]={};var r={};r[o]=a,n(t,e,r)}return t[o]},c=s(),u=function(e){return i(e)?Symbol.prototype.valueOf.call(e):typeof e+" | "+String(e)},l=function(e){if(!function(e){return null===e||"object"!=typeof e&&"function"!=typeof e}(e))throw new TypeError("key must not be an object")},h={clear:function(){delete t[o],c=s()},delete:function(e){return l(e),delete c[u(e)],!h.has(e)},get:function(e){return l(e),c[u(e)]},has:function(e){return l(e),u(e)in c},set:function(e,t){l(e);var r=u(e),i={};i[r]=t;var o={};return o[r]=a,n(c,i,o),h.has(e)},setIfMissingThenGet:function(e,t){if(h.has(e))return h.get(e);var r=t();return h.set(e,r),r}};e.exports=h}).call(this,r(46))},function(e,t){Object.defineProperty(t,"__esModule",{value:!0});t.GLOBAL_CACHE_KEY="reactWithStylesInterfaceCSS",t.MAX_SPECIFICITY=20},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){return(e.length>0?String(e)+"__":"")+String(t)}},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){for(var t=[],r=!1,n={},i=0;i-1?e[i]:void 0}return o(e,t,c)});e.exports=l},function(e,t,r){var n=r(626),i=r(630),o=r(283),a=r(631),s=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,c=/^\w*$/,u=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,l=/\\(\\)?/g;function h(e,t,r){if(null!=e){void 0!==r&&r in p(e)&&(t=[r]);for(var n=0,i=t.length;null!=e&&ni?0:i+t);(r=void 0===r||r>i?i:+r||0)<0&&(r+=i);i=t>r?0:r-t>>>0,t>>>=0;var o=Array(i);for(;++nc))return!1;for(;++s-1&&e%1==0&&e<=9007199254740991}(e.length)&&!!r[n.call(e)]}},function(e,t){var r=/^\[object .+?Constructor\]$/;var n=Object.prototype,i=Function.prototype.toString,o=n.hasOwnProperty,a=n.toString,s=RegExp("^"+i.call(o).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e,t){var n=null==e?void 0:e[t];return function(e){if(null==e)return!1;if(function(e){return function(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}(e)&&"[object Function]"==a.call(e)}(e))return s.test(i.call(e));return function(e){return!!e&&"object"==typeof e}(e)&&r.test(e)}(n)?n:void 0}},function(e,t){var r=Object.prototype,n=r.hasOwnProperty,i=r.toString,o=r.propertyIsEnumerable;e.exports=function(e){return function(e){return function(e){return!!e&&"object"==typeof e}(e)&&function(e){return null!=e&&function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}(e.length)&&!function(e){var t=function(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}(e)?i.call(e):"";return"[object Function]"==t||"[object GeneratorFunction]"==t}(e)}(e)}(e)&&n.call(e,"callee")&&(!o.call(e,"callee")||"[object Arguments]"==i.call(e))}},function(e,t){function r(e){return e}e.exports=function(e,t,n){if("function"!=typeof e)return r;if(void 0===t)return e;switch(n){case 1:return function(r){return e.call(t,r)};case 3:return function(r,n,i){return e.call(t,r,n,i)};case 4:return function(r,n,i,o){return e.call(t,r,n,i,o)};case 5:return function(r,n,i,o,a){return e.call(t,r,n,i,o,a)}}return function(){return e.apply(t,arguments)}}},function(e,t,r){var n=r(313);e.exports=function(e){var t;e=function(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}(t=e)?t:Object(t);for(var r=-1,i=n(e),o=i.length,a=Array(o);++r-1&&r%1==0&&r<=9007199254740991))return n(e,t);for(var a=i?o:-1,s=l(e);(i?a--:++al;)if((s=c[l++])!=s)return!0}else for(;u>l;l++)if((e||l in c)&&c[l]===r)return e||l||0;return!e&&-1}};e.exports={includes:a(!0),indexOf:a(!1)}},function(e,t,r){var n=r(323),i=Math.max,o=Math.min;e.exports=function(e,t){var r=n(e);return r<0?i(r+t,0):o(r,t)}},function(e,t,r){var n=r(165),i=/#|\.prototype\./,o=function(e,t){var r=s[a(e)];return r==u||r!=c&&("function"==typeof t?n(t):!!t)},a=o.normalize=function(e){return String(e).replace(i,".").toLowerCase()},s=o.data={},c=o.NATIVE="N",u=o.POLYFILL="P";e.exports=o},function(e,t,r){"use strict";var n=r(200),i=r(165),o=r(490),a=r(489),s=r(475),c=r(325),u=r(476),l=Object.assign,h=Object.defineProperty;e.exports=!l||i((function(){if(n&&1!==l({b:1},l(h({},"a",{enumerable:!0,get:function(){h(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},r=Symbol();return e[r]=7,"abcdefghijklmnopqrst".split("").forEach((function(e){t[e]=e})),7!=l({},e)[r]||"abcdefghijklmnopqrst"!=o(l({},t)).join("")}))?function(e,t){for(var r=c(e),i=arguments.length,l=1,h=a.f,f=s.f;i>l;)for(var d,p=u(arguments[l++]),m=h?o(p).concat(h(p)):o(p),b=m.length,v=0;b>v;)d=m[v++],n&&!f.call(p,d)||(r[d]=p[d]);return r}:l},function(e,t,r){r(646),r(657);var n=r(322);e.exports=n.Array.from},function(e,t,r){"use strict";var n=r(647).charAt,i=r(483),o=r(648),a=i.set,s=i.getterFor("String Iterator");o(String,"String",(function(e){a(this,{type:"String Iterator",string:String(e),index:0})}),(function(){var e,t=s(this),r=t.string,i=t.index;return i>=r.length?{value:void 0,done:!0}:(e=n(r,i),t.index+=e.length,{value:e,done:!1})}))},function(e,t,r){var n=r(323),i=r(316),o=function(e){return function(t,r){var o,a,s=String(i(t)),c=n(r),u=s.length;return c<0||c>=u?e?"":void 0:(o=s.charCodeAt(c))<55296||o>56319||c+1===u||(a=s.charCodeAt(c+1))<56320||a>57343?e?s.charAt(c):o:e?s.slice(c,c+2):a-56320+(o-55296<<10)+65536}};e.exports={codeAt:o(!1),charAt:o(!0)}},function(e,t,r){"use strict";var n=r(314),i=r(649),o=r(493),a=r(655),s=r(495),c=r(201),u=r(480),l=r(158),h=r(320),f=r(285),d=r(492),p=d.IteratorPrototype,m=d.BUGGY_SAFARI_ITERATORS,b=l("iterator"),v=function(){return this};e.exports=function(e,t,r,l,d,g,y){i(r,t,l);var w,M,_,O=function(e){if(e===d&&C)return C;if(!m&&e in S)return S[e];switch(e){case"keys":case"values":case"entries":return function(){return new r(this,e)}}return function(){return new r(this)}},k=t+" Iterator",E=!1,S=e.prototype,A=S[b]||S["@@iterator"]||d&&S[d],C=!m&&A||O(d),j="Array"==t&&S.entries||A;if(j&&(w=o(j.call(new e)),p!==Object.prototype&&w.next&&(h||o(w)===p||(a?a(w,p):"function"!=typeof w[b]&&c(w,b,v)),s(w,k,!0,!0),h&&(f[k]=v))),"values"==d&&A&&"values"!==A.name&&(E=!0,C=function(){return A.call(this)}),h&&!y||S[b]===C||c(S,b,C),f[t]=C,d)if(M={values:O("values"),keys:g?C:O("keys"),entries:O("entries")},y)for(_ in M)(m||E||!(_ in S))&&u(S,_,M[_]);else n({target:t,proto:!0,forced:m||E},M);return M}},function(e,t,r){"use strict";var n=r(492).IteratorPrototype,i=r(652),o=r(284),a=r(495),s=r(285),c=function(){return this};e.exports=function(e,t,r){var u=t+" Iterator";return e.prototype=i(n,{next:o(1,r)}),a(e,u,!1,!0),s[u]=c,e}},function(e,t,r){var n=r(165);e.exports=!n((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},function(e,t,r){var n=r(494);e.exports=n&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(e,t,r){var n,i=r(202),o=r(653),a=r(324),s=r(321),c=r(654),u=r(479),l=r(319),h=l("IE_PROTO"),f=function(){},d=function(e){return"'; + } + + /** + * Override parent method. + * + * @see AssetDataRegistry::get_core_data + * + * @return array An array of data to output for enqueued script. + */ + protected function get_core_data() { + global $wp_locale; + $core_data = parent::get_core_data(); + return array_merge( + $core_data, + [ + 'siteLocale' => $core_data['locale']['siteLocale'], + 'stockStatuses' => $core_data['orderStatuses'], + 'dataEndpoints' => [], + 'l10n' => [ + 'userLocale' => $core_data['locale']['userLocale'], + 'weekdaysShort' => $core_data['locale']['weekdaysShort'], + ], + 'currency' => array_merge( + $core_data['currency'], + [ + 'position' => $core_data['currency']['symbolPosition'], + 'decimal_separator' => $core_data['currency']['decimalSeparator'], + 'thousand_separator' => $core_data['currency']['thousandSeparator'], + 'price_format' => $core_data['currency']['priceFormat'], + ] + ), + ] + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractBlock.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractBlock.php new file mode 100644 index 0000000..336303b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractBlock.php @@ -0,0 +1,180 @@ +block_name = $block_name; + } + add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_editor_assets' ] ); + } + + /** + * Registers the block type with WordPress. + */ + public function register_block_type() { + register_block_type( + $this->namespace . '/' . $this->block_name, + array( + 'editor_script' => 'wc-' . $this->block_name, + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'supports' => [], + ) + ); + } + + /** + * Append frontend scripts when rendering the block. + * + * @param array|\WP_Block $attributes Block attributes, or an instance of a WP_Block. Defaults to an empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + public function render( $attributes = [], $content = '' ) { + $this->enqueue_assets( is_a( $attributes, '\WP_Block' ) ? $attributes->attributes : $attributes ); + return $content; + } + + /** + * Enqueue assets used for rendering the block. + * + * @param array $attributes Any attributes that currently are available from the block. + */ + public function enqueue_assets( array $attributes = [] ) { + if ( $this->enqueued_assets ) { + return; + } + $this->enqueue_data( $attributes ); + $this->enqueue_scripts( $attributes ); + $this->enqueued_assets = true; + } + + /** + * Enqueue assets used for rendering the block in editor context. + * + * This is needed if a block is not yet within the post content--`render` and `enqueue_assets` may not have ran. + */ + public function enqueue_editor_assets() { + if ( $this->enqueued_assets ) { + return; + } + $this->enqueue_data(); + } + + /** + * Injects block attributes into the block. + * + * @param string $content HTML content to inject into. + * @param array $attributes Key value pairs of attributes. + * @return string Rendered block with data attributes. + */ + protected function inject_html_data_attributes( $content, array $attributes ) { + return preg_replace( '/
    get_html_data_attributes( $attributes ) . ' ', $content, 1 ); + } + + /** + * Converts block attributes to HTML data attributes. + * + * @param array $attributes Key value pairs of attributes. + * @return string Rendered HTML attributes. + */ + protected function get_html_data_attributes( array $attributes ) { + $data = []; + + foreach ( $attributes as $key => $value ) { + if ( is_bool( $value ) ) { + $value = $value ? 'true' : 'false'; + } + if ( ! is_scalar( $value ) ) { + $value = wp_json_encode( $value ); + } + $data[] = 'data-' . esc_attr( strtolower( preg_replace( '/(? + var containers = document.querySelectorAll( 'div.wc-block-skeleton' ); + + if ( containers.length ) { + Array.prototype.forEach.call( containers, function( el, i ) { + var w = el.offsetWidth; + var classname = ''; + + if ( w > 700 ) + classname = 'is-large'; + else if ( w > 520 ) + classname = 'is-medium'; + else if ( w > 400 ) + classname = 'is-small'; + else + classname = 'is-mobile'; + + if ( ! el.classList.contains( classname ) ) { + el.classList.add( classname ); + } + + el.classList.remove( 'hidden' ); + } ); + } + "; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractDynamicBlock.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractDynamicBlock.php new file mode 100644 index 0000000..163d9b5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractDynamicBlock.php @@ -0,0 +1,123 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name, + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'attributes' => $this->get_attributes(), + 'supports' => [], + ) + ); + } + + /** + * Include and render a dynamic block. + * + * @param array $attributes Block attributes. Default empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + abstract public function render( $attributes = array(), $content = '' ); + + /** + * Get block attributes. + * + * @return array + */ + protected function get_attributes() { + return array(); + } + + /** + * Get the schema for the alignment property. + * + * @return array Property definition for align. + */ + protected function get_schema_align() { + return array( + 'type' => 'string', + 'enum' => array( 'left', 'center', 'right', 'wide', 'full' ), + ); + } + + /** + * Get the schema for a list of IDs. + * + * @return array Property definition for a list of numeric ids. + */ + protected function get_schema_list_ids() { + return array( + 'type' => 'array', + 'items' => array( + 'type' => 'number', + ), + 'default' => array(), + ); + } + + /** + * Get the schema for a boolean value. + * + * @param string $default The default value. + * @return array Property definition. + */ + protected function get_schema_boolean( $default = true ) { + return array( + 'type' => 'boolean', + 'default' => $default, + ); + } + + /** + * Get the schema for a numeric value. + * + * @param string $default The default value. + * @return array Property definition. + */ + protected function get_schema_number( $default ) { + return array( + 'type' => 'number', + 'default' => $default, + ); + } + + /** + * Get the schema for a string value. + * + * @param string $default The default value. + * @return array Property definition. + */ + protected function get_schema_string( $default = '' ) { + return array( + 'type' => 'string', + 'default' => $default, + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractProductGrid.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractProductGrid.php new file mode 100644 index 0000000..b0c6e8a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AbstractProductGrid.php @@ -0,0 +1,468 @@ + $this->get_schema_string(), + 'columns' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_columns', 3 ) ), + 'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 3 ) ), + 'categories' => $this->get_schema_list_ids(), + 'catOperator' => array( + 'type' => 'string', + 'default' => 'any', + ), + 'contentVisibility' => $this->get_schema_content_visibility(), + 'align' => $this->get_schema_align(), + 'alignButtons' => $this->get_schema_boolean( false ), + 'isPreview' => $this->get_schema_boolean( false ), + ); + } + + /** + * Include and render the dynamic block. + * + * @param array $attributes Block attributes. Default empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + public function render( $attributes = array(), $content = '' ) { + $this->attributes = $this->parse_attributes( $attributes ); + $this->content = $content; + $this->query_args = $this->parse_query_args(); + $products = $this->get_products(); + + if ( ! $products ) { + return ''; + } + + $classes = $this->get_container_classes(); + $output = implode( '', array_map( array( $this, 'render_product' ), $products ) ); + + return sprintf( '
      %s
    ', esc_attr( $classes ), $output ); + } + + /** + * Get the schema for the contentVisibility attribute + * + * @return array List of block attributes with type and defaults. + */ + protected function get_schema_content_visibility() { + return array( + 'type' => 'object', + 'properties' => array( + 'title' => $this->get_schema_boolean( true ), + 'price' => $this->get_schema_boolean( true ), + 'rating' => $this->get_schema_boolean( true ), + 'button' => $this->get_schema_boolean( true ), + ), + ); + } + + /** + * Get the schema for the orderby attribute. + * + * @return array Property definition of `orderby` attribute. + */ + protected function get_schema_orderby() { + return array( + 'type' => 'string', + 'enum' => array( 'date', 'popularity', 'price_asc', 'price_desc', 'rating', 'title', 'menu_order' ), + 'default' => 'date', + ); + } + + /** + * Get the block's attributes. + * + * @param array $attributes Block attributes. Default empty array. + * @return array Block attributes merged with defaults. + */ + protected function parse_attributes( $attributes ) { + // These should match what's set in JS `registerBlockType`. + $defaults = array( + 'columns' => wc_get_theme_support( 'product_blocks::default_columns', 3 ), + 'rows' => wc_get_theme_support( 'product_blocks::default_rows', 3 ), + 'alignButtons' => false, + 'categories' => array(), + 'catOperator' => 'any', + 'contentVisibility' => array( + 'title' => true, + 'price' => true, + 'rating' => true, + 'button' => true, + ), + ); + + return wp_parse_args( $attributes, $defaults ); + } + + /** + * Parse query args. + * + * @return array + */ + protected function parse_query_args() { + $query_args = array( + 'post_type' => 'product', + 'post_status' => 'publish', + 'fields' => 'ids', + 'ignore_sticky_posts' => true, + 'no_found_rows' => false, + 'orderby' => '', + 'order' => '', + 'meta_query' => WC()->query->get_meta_query(), // phpcs:ignore WordPress.DB.SlowDBQuery + 'tax_query' => array(), // phpcs:ignore WordPress.DB.SlowDBQuery + 'posts_per_page' => $this->get_products_limit(), + ); + + $this->set_block_query_args( $query_args ); + $this->set_ordering_query_args( $query_args ); + $this->set_categories_query_args( $query_args ); + $this->set_visibility_query_args( $query_args ); + + return $query_args; + } + + /** + * Parse query args. + * + * @param array $query_args Query args. + */ + protected function set_ordering_query_args( &$query_args ) { + if ( isset( $this->attributes['orderby'] ) ) { + if ( 'price_desc' === $this->attributes['orderby'] ) { + $query_args['orderby'] = 'price'; + $query_args['order'] = 'DESC'; + } elseif ( 'price_asc' === $this->attributes['orderby'] ) { + $query_args['orderby'] = 'price'; + $query_args['order'] = 'ASC'; + } elseif ( 'date' === $this->attributes['orderby'] ) { + $query_args['orderby'] = 'date'; + $query_args['order'] = 'DESC'; + } else { + $query_args['orderby'] = $this->attributes['orderby']; + } + } + + $query_args = array_merge( + $query_args, + WC()->query->get_catalog_ordering_args( $query_args['orderby'], $query_args['order'] ) + ); + } + + /** + * Set args specific to this block + * + * @param array $query_args Query args. + */ + abstract protected function set_block_query_args( &$query_args ); + + /** + * Set categories query args. + * + * @param array $query_args Query args. + */ + protected function set_categories_query_args( &$query_args ) { + if ( ! empty( $this->attributes['categories'] ) ) { + $categories = array_map( 'absint', $this->attributes['categories'] ); + + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_cat', + 'terms' => $categories, + 'field' => 'term_id', + 'operator' => 'all' === $this->attributes['catOperator'] ? 'AND' : 'IN', + + /* + * When cat_operator is AND, the children categories should be excluded, + * as only products belonging to all the children categories would be selected. + */ + 'include_children' => 'all' === $this->attributes['catOperator'] ? false : true, + ); + } + } + + /** + * Set visibility query args. + * + * @param array $query_args Query args. + */ + protected function set_visibility_query_args( &$query_args ) { + $product_visibility_terms = wc_get_product_visibility_term_ids(); + $product_visibility_not_in = array( $product_visibility_terms['exclude-from-catalog'] ); + + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) { + $product_visibility_not_in[] = $product_visibility_terms['outofstock']; + } + + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => $product_visibility_not_in, + 'operator' => 'NOT IN', + ); + } + + /** + * Works out the item limit based on rows and columns, or returns default. + * + * @return int + */ + protected function get_products_limit() { + if ( isset( $this->attributes['rows'], $this->attributes['columns'] ) && ! empty( $this->attributes['rows'] ) ) { + $this->attributes['limit'] = intval( $this->attributes['columns'] ) * intval( $this->attributes['rows'] ); + } + return intval( $this->attributes['limit'] ); + } + + /** + * Run the query and return an array of product IDs + * + * @return array List of product IDs + */ + protected function get_products() { + $is_cacheable = (bool) apply_filters( 'woocommerce_blocks_product_grid_is_cacheable', true, $this->query_args ); + $transient_version = \WC_Cache_Helper::get_transient_version( 'product_query' ); + + $query = new BlocksWpQuery( $this->query_args ); + $results = wp_parse_id_list( $is_cacheable ? $query->get_cached_posts( $transient_version ) : $query->get_posts() ); + + // Remove ordering query arguments which may have been added by get_catalog_ordering_args. + WC()->query->remove_ordering_args(); + + // Prime caches to reduce future queries. + if ( is_callable( '_prime_post_caches' ) ) { + _prime_post_caches( $results ); + } + + return $results; + } + + /** + * Get the list of classes to apply to this block. + * + * @return string space-separated list of classes. + */ + protected function get_container_classes() { + $classes = array( + 'wc-block-grid', + "wp-block-{$this->block_name}", + "wc-block-{$this->block_name}", + "has-{$this->attributes['columns']}-columns", + ); + + if ( $this->attributes['rows'] > 1 ) { + $classes[] = 'has-multiple-rows'; + } + + if ( isset( $this->attributes['align'] ) ) { + $classes[] = "align{$this->attributes['align']}"; + } + + if ( ! empty( $this->attributes['alignButtons'] ) ) { + $classes[] = 'has-aligned-buttons'; + } + + if ( ! empty( $this->attributes['className'] ) ) { + $classes[] = $this->attributes['className']; + } + + return implode( ' ', $classes ); + } + + /** + * Render a single products. + * + * @param int $id Product ID. + * @return string Rendered product output. + */ + public function render_product( $id ) { + $product = wc_get_product( $id ); + + if ( ! $product ) { + return ''; + } + + $data = (object) array( + 'permalink' => esc_url( $product->get_permalink() ), + 'image' => $this->get_image_html( $product ), + 'title' => $this->get_title_html( $product ), + 'rating' => $this->get_rating_html( $product ), + 'price' => $this->get_price_html( $product ), + 'badge' => $this->get_sale_badge_html( $product ), + 'button' => $this->get_button_html( $product ), + ); + + return apply_filters( + 'woocommerce_blocks_product_grid_item_html', + "
  • + permalink}\" class=\"wc-block-grid__product-link\"> + {$data->image} + {$data->title} + + {$data->badge} + {$data->price} + {$data->rating} + {$data->button} +
  • ", + $data, + $product + ); + } + + /** + * Get the product image. + * + * @param \WC_Product $product Product. + * @return string + */ + protected function get_image_html( $product ) { + return '
    ' . $product->get_image( 'woocommerce_thumbnail' ) . '
    '; + } + + /** + * Get the product title. + * + * @param \WC_Product $product Product. + * @return string + */ + protected function get_title_html( $product ) { + if ( empty( $this->attributes['contentVisibility']['title'] ) ) { + return ''; + } + return '
    ' . $product->get_title() . '
    '; + } + + /** + * Render the rating icons. + * + * @param WC_Product $product Product. + * @return string Rendered product output. + */ + protected function get_rating_html( $product ) { + if ( empty( $this->attributes['contentVisibility']['rating'] ) ) { + return ''; + } + $rating_count = $product->get_rating_count(); + $review_count = $product->get_review_count(); + $average = $product->get_average_rating(); + + if ( $rating_count > 0 ) { + return sprintf( + '
    %s
    ', + wc_get_rating_html( $average, $rating_count ) + ); + } + return ''; + } + + /** + * Get the price. + * + * @param \WC_Product $product Product. + * @return string Rendered product output. + */ + protected function get_price_html( $product ) { + if ( empty( $this->attributes['contentVisibility']['price'] ) ) { + return ''; + } + return sprintf( + '
    %s
    ', + $product->get_price_html() + ); + } + + /** + * Get the sale badge. + * + * @param \WC_Product $product Product. + * @return string Rendered product output. + */ + protected function get_sale_badge_html( $product ) { + if ( empty( $this->attributes['contentVisibility']['price'] ) ) { + return ''; + } + + if ( ! $product->is_on_sale() ) { + return; + } + + return '
    + + ' . esc_html__( 'Product on sale', 'woocommerce' ) . ' +
    '; + } + + /** + * Get the button. + * + * @param \WC_Product $product Product. + * @return string Rendered product output. + */ + protected function get_button_html( $product ) { + if ( empty( $this->attributes['contentVisibility']['button'] ) ) { + return ''; + } + return '
    ' . $this->get_add_to_cart( $product ) . '
    '; + } + + /** + * Get the "add to cart" button. + * + * @param \WC_Product $product Product. + * @return string Rendered product output. + */ + protected function get_add_to_cart( $product ) { + $attributes = array( + 'aria-label' => $product->add_to_cart_description(), + 'data-quantity' => '1', + 'data-product_id' => $product->get_id(), + 'data-product_sku' => $product->get_sku(), + 'rel' => 'nofollow', + 'class' => 'wp-block-button__link add_to_cart_button', + ); + + if ( $product->supports( 'ajax_add_to_cart' ) ) { + $attributes['class'] .= ' ajax_add_to_cart'; + } + + return sprintf( + '%s', + esc_url( $product->add_to_cart_url() ), + wc_implode_html_attributes( $attributes ), + esc_html( $product->add_to_cart_text() ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ActiveFilters.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ActiveFilters.php new file mode 100644 index 0000000..1f1135f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ActiveFilters.php @@ -0,0 +1,43 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name, + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'script' => 'wc-' . $this->block_name . '-frontend', + 'supports' => [], + ) + ); + } + + /** + * Register/enqueue scripts used for this block. + * + * @param array $attributes Any attributes that currently are available from the block. + */ + protected function enqueue_scripts( array $attributes = [] ) { + Assets::register_block_script( $this->block_name . '-frontend' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AllProducts.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AllProducts.php new file mode 100644 index 0000000..682dff5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AllProducts.php @@ -0,0 +1,44 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name, + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'script' => 'wc-' . $this->block_name . '-frontend', + 'supports' => [], + ) + ); + } + + /** + * Append frontend scripts when rendering the Product Categories List block. + * + * @param array $attributes Block attributes. Default empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + public function render( $attributes = array(), $content = '' ) { + \Automattic\WooCommerce\Blocks\Assets::register_block_script( $this->block_name . '-frontend' ); + + return $content; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AllReviews.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AllReviews.php new file mode 100644 index 0000000..1cff8ba --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AllReviews.php @@ -0,0 +1,42 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name, + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'script' => 'wc-' . $this->block_name . '-frontend', + 'supports' => [], + ) + ); + } + + /** + * Register/enqueue scripts used for this block. + * + * @param array $attributes Any attributes that currently are available from the block. + */ + protected function enqueue_scripts( array $attributes = [] ) { + Assets::register_block_script( 'reviews-frontend' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AtomicBlock.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AtomicBlock.php new file mode 100644 index 0000000..cc47d64 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AtomicBlock.php @@ -0,0 +1,45 @@ +attributes : $attributes; + return $this->inject_html_data_attributes( $content, $block_attributes ); + } + + /** + * Registers the block type with WordPress. + */ + public function register_block_type() { + register_block_type( + $this->namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'supports' => [], + ) + ); + } + + /** + * Converts block attributes to HTML data attributes. + * + * @param array $attributes Key value pairs of attributes. + * @return string Rendered HTML attributes. + */ + protected function get_html_data_attributes( array $attributes ) { + $data = parent::get_html_data_attributes( $attributes ); + return trim( $data . ' data-block-name="' . esc_attr( $this->namespace . '/' . $this->block_name ) . '"' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AttributeFilter.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AttributeFilter.php new file mode 100644 index 0000000..b4492fc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/AttributeFilter.php @@ -0,0 +1,43 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name, + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'script' => 'wc-' . $this->block_name . '-frontend', + 'supports' => [], + ) + ); + } + + /** + * Register/enqueue scripts used for this block. + * + * @param array $attributes Any attributes that currently are available from the block. + */ + protected function enqueue_scripts( array $attributes = [] ) { + Assets::register_block_script( $this->block_name . '-frontend' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/Cart.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/Cart.php new file mode 100644 index 0000000..947bdea --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/Cart.php @@ -0,0 +1,222 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name . '-block', + 'editor_style' => 'wc-block-editor', + 'style' => [ 'wc-block-style', 'wc-block-vendors-style' ], + 'script' => 'wc-' . $this->block_name . '-block-frontend', + 'supports' => [], + ) + ); + } + + + /** + * Append frontend scripts when rendering the Cart block. + * + * @param array|\WP_Block $attributes Block attributes, or an instance of a WP_Block. Defaults to an empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + public function render( $attributes = array(), $content = '' ) { + $block_attributes = is_a( $attributes, '\WP_Block' ) ? $attributes->attributes : $attributes; + + do_action( 'woocommerce_blocks_enqueue_cart_block_scripts_before' ); + $this->enqueue_assets( $block_attributes ); + do_action( 'woocommerce_blocks_enqueue_cart_block_scripts_after' ); + + // Deregister core cart scripts and styles. + wp_deregister_script( 'wc-cart' ); + wp_deregister_script( 'wc-password-strength-meter' ); + wp_deregister_script( 'selectWoo' ); + wp_deregister_style( 'select2' ); + + return $this->inject_html_data_attributes( $content . $this->get_skeleton(), $block_attributes ); + } + + /** + * Extra data passed through from server to client for block. + * + * @param array $attributes Any attributes that currently are available from the block. + * Note, this will be empty in the editor context when the block is + * not in the post content on editor load. + */ + protected function enqueue_data( array $attributes = [] ) { + $data_registry = Package::container()->get( + AssetDataRegistry::class + ); + + if ( ! $data_registry->exists( 'shippingCountries' ) ) { + $data_registry->add( 'shippingCountries', $this->deep_sort_with_accents( WC()->countries->get_shipping_countries() ) ); + } + + if ( ! $data_registry->exists( 'shippingStates' ) ) { + $data_registry->add( 'shippingStates', $this->deep_sort_with_accents( WC()->countries->get_shipping_country_states() ) ); + } + + $permalink = ! empty( $attributes['checkoutPageId'] ) ? get_permalink( $attributes['checkoutPageId'] ) : false; + + if ( $permalink && ! $data_registry->exists( 'page-' . $attributes['checkoutPageId'] ) ) { + $data_registry->add( 'page-' . $attributes['checkoutPageId'], $permalink ); + } + + // Hydrate the following data depending on admin or frontend context. + if ( ! is_admin() && ! WC()->is_rest_api_request() ) { + $this->hydrate_from_api( $data_registry ); + } + + do_action( 'woocommerce_blocks_cart_enqueue_data' ); + } + + /** + * Removes accents from an array of values, sorts by the values, then returns the original array values sorted. + * + * @param array $array Array of values to sort. + * @return array Sorted array. + */ + protected function deep_sort_with_accents( $array ) { + if ( ! is_array( $array ) || empty( $array ) ) { + return $array; + } + + if ( is_array( reset( $array ) ) ) { + return array_map( [ $this, 'deep_sort_with_accents' ], $array ); + } + + $array_without_accents = array_map( 'remove_accents', array_map( 'wc_strtolower', array_map( 'html_entity_decode', $array ) ) ); + asort( $array_without_accents ); + return array_replace( $array_without_accents, $array ); + } + + /** + * Register/enqueue scripts used for this block. + * + * @param array $attributes Any attributes that currently are available from the block. + * Note, this will be empty in the editor context when the block is + * not in the post content on editor load. + */ + protected function enqueue_scripts( array $attributes = [] ) { + Assets::register_block_script( $this->block_name . '-frontend', $this->block_name . '-block-frontend' ); + } + + /** + * Hydrate the cart block with data from the API. + * + * @param AssetDataRegistry $data_registry Data registry instance. + */ + protected function hydrate_from_api( AssetDataRegistry $data_registry ) { + if ( ! $data_registry->exists( 'cartData' ) ) { + $data_registry->add( 'cartData', WC()->api->get_endpoint_data( '/wc/store/cart' ) ); + } + } + + /** + * Render skeleton markup for the cart block. + */ + protected function get_skeleton() { + return ' + + ' . $this->get_skeleton_inline_script(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/Checkout.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/Checkout.php new file mode 100644 index 0000000..773e025 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/Checkout.php @@ -0,0 +1,280 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name . '-block', + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'script' => 'wc-' . $this->block_name . '-block-frontend', + 'supports' => [], + ) + ); + } + + /** + * Append frontend scripts when rendering the block. + * + * @param array|\WP_Block $attributes Block attributes, or an instance of a WP_Block. Defaults to an empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + public function render( $attributes = array(), $content = '' ) { + if ( $this->is_checkout_endpoint() ) { + // Note: Currently the block only takes care of the main checkout form -- if an endpoint is set, refer to the + // legacy shortcode instead and do not render block. + return '[woocommerce_checkout]'; + } + $block_attributes = is_a( $attributes, '\WP_Block' ) ? $attributes->attributes : $attributes; + + do_action( 'woocommerce_blocks_enqueue_checkout_block_scripts_before' ); + $this->enqueue_assets( $block_attributes ); + do_action( 'woocommerce_blocks_enqueue_checkout_block_scripts_after' ); + + // Deregister core checkout scripts and styles. + wp_deregister_script( 'wc-checkout' ); + wp_deregister_script( 'wc-password-strength-meter' ); + wp_deregister_script( 'selectWoo' ); + wp_deregister_style( 'select2' ); + + return $this->inject_html_data_attributes( $content . $this->get_skeleton(), $block_attributes ); + } + + /** + * Check if we're viewing a checkout page endpoint, rather than the main checkout page itself. + * + * @return boolean + */ + protected function is_checkout_endpoint() { + return is_wc_endpoint_url( 'order-pay' ) || is_wc_endpoint_url( 'order-received' ); + } + + /** + * Extra data passed through from server to client for block. + * + * @param array $attributes Any attributes that currently are available from the block. + * Note, this will be empty in the editor context when the block is + * not in the post content on editor load. + */ + protected function enqueue_data( array $attributes = [] ) { + $data_registry = Package::container()->get( + AssetDataRegistry::class + ); + + if ( ! $data_registry->exists( 'allowedCountries' ) ) { + $data_registry->add( 'allowedCountries', $this->deep_sort_with_accents( WC()->countries->get_allowed_countries() ) ); + } + + if ( ! $data_registry->exists( 'allowedStates' ) ) { + $data_registry->add( 'allowedStates', $this->deep_sort_with_accents( WC()->countries->get_allowed_country_states() ) ); + } + + if ( ! $data_registry->exists( 'shippingCountries' ) ) { + $data_registry->add( 'shippingCountries', $this->deep_sort_with_accents( WC()->countries->get_shipping_countries() ) ); + } + + if ( ! $data_registry->exists( 'shippingStates' ) ) { + $data_registry->add( 'shippingStates', $this->deep_sort_with_accents( WC()->countries->get_shipping_country_states() ) ); + } + + $permalink = ! empty( $attributes['cartPageId'] ) ? get_permalink( $attributes['cartPageId'] ) : false; + + if ( $permalink && ! $data_registry->exists( 'page-' . $attributes['cartPageId'] ) ) { + $data_registry->add( 'page-' . $attributes['cartPageId'], $permalink ); + } + + // Hydrate the following data depending on admin or frontend context. + if ( is_admin() ) { + $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : false; + + if ( $screen && $screen->is_block_editor() && ! $data_registry->exists( 'shippingMethodsExist' ) ) { + $methods_exist = wc_get_shipping_method_count( false, true ) > 0; + $data_registry->add( 'shippingMethodsExist', $methods_exist ); + } + } + + if ( ! is_admin() && ! WC()->is_rest_api_request() ) { + $this->hydrate_from_api( $data_registry ); + $this->hydrate_customer_payment_methods( $data_registry ); + } + + do_action( 'woocommerce_blocks_checkout_enqueue_data' ); + } + + /** + * Removes accents from an array of values, sorts by the values, then returns the original array values sorted. + * + * @param array $array Array of values to sort. + * @return array Sorted array. + */ + protected function deep_sort_with_accents( $array ) { + if ( ! is_array( $array ) || empty( $array ) ) { + return $array; + } + + if ( is_array( reset( $array ) ) ) { + return array_map( [ $this, 'deep_sort_with_accents' ], $array ); + } + + $array_without_accents = array_map( 'remove_accents', array_map( 'wc_strtolower', array_map( 'html_entity_decode', $array ) ) ); + asort( $array_without_accents ); + return array_replace( $array_without_accents, $array ); + } + + /** + * Register/enqueue scripts used for this block. + * + * @param array $attributes Any attributes that currently are available from the block. + * Note, this will be empty in the editor context when the block is + * not in the post content on editor load. + */ + protected function enqueue_scripts( array $attributes = [] ) { + Assets::register_block_script( $this->block_name . '-frontend', $this->block_name . '-block-frontend' ); + } + + /** + * Get customer payment methods for use in checkout. + * + * @param AssetDataRegistry $data_registry Data registry instance. + */ + protected function hydrate_customer_payment_methods( AssetDataRegistry $data_registry ) { + if ( ! is_user_logged_in() || $data_registry->exists( 'customerPaymentMethods' ) ) { + return; + } + add_filter( 'woocommerce_payment_methods_list_item', [ $this, 'include_token_id_with_payment_methods' ], 10, 2 ); + $data_registry->add( + 'customerPaymentMethods', + wc_get_customer_saved_methods_list( get_current_user_id() ) + ); + remove_filter( 'woocommerce_payment_methods_list_item', [ $this, 'include_token_id_with_payment_methods' ], 10, 2 ); + } + + /** + * Hydrate the checkout block with data from the API. + * + * @param AssetDataRegistry $data_registry Data registry instance. + */ + protected function hydrate_from_api( AssetDataRegistry $data_registry ) { + // Print existing notices now, otherwise they are caught by the Cart + // Controller and converted to exceptions. + wc_print_notices(); + + if ( ! $data_registry->exists( 'cartData' ) ) { + $data_registry->add( 'cartData', WC()->api->get_endpoint_data( '/wc/store/cart' ) ); + } + if ( ! $data_registry->exists( 'checkoutData' ) ) { + add_filter( 'woocommerce_store_api_disable_nonce_check', '__return_true' ); + $data_registry->add( 'checkoutData', WC()->api->get_endpoint_data( '/wc/store/checkout' ) ); + remove_filter( 'woocommerce_store_api_disable_nonce_check', '__return_true' ); + } + } + + /** + * Render skeleton markup for the checkout block. + */ + protected function get_skeleton() { + return ' + + ' . $this->get_skeleton_inline_script(); + } + + /** + * Callback for woocommerce_payment_methods_list_item filter to add token id + * to the generated list. + * + * @param array $list_item The current list item for the saved payment method. + * @param \WC_Token $token The token for the current list item. + * + * @return array The list item with the token id added. + */ + public static function include_token_id_with_payment_methods( $list_item, $token ) { + $list_item['tokenId'] = $token->get_id(); + $brand = ! empty( $list_item['method']['brand'] ) ? + strtolower( $list_item['method']['brand'] ) : + ''; + // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch -- need to match on translated value from core. + if ( ! empty( $brand ) && esc_html__( 'Credit card', 'woocommerce' ) !== $brand ) { + $list_item['method']['brand'] = wc_get_credit_card_type_label( $brand ); + } + return $list_item; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/FeaturedCategory.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/FeaturedCategory.php new file mode 100644 index 0000000..8413c07 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/FeaturedCategory.php @@ -0,0 +1,167 @@ + 'none', + 'contentAlign' => 'center', + 'dimRatio' => 50, + 'focalPoint' => false, + 'height' => false, + 'mediaId' => 0, + 'mediaSrc' => '', + 'showDesc' => true, + ); + + /** + * Render the Featured Category block. + * + * @param array $attributes Block attributes. Default empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + public function render( $attributes = array(), $content = '' ) { + $id = isset( $attributes['categoryId'] ) ? (int) $attributes['categoryId'] : 0; + $category = get_term( $id, 'product_cat' ); + if ( ! $category || is_wp_error( $category ) ) { + return ''; + } + $attributes = wp_parse_args( $attributes, $this->defaults ); + if ( ! $attributes['height'] ) { + $attributes['height'] = wc_get_theme_support( 'featured_block::default_height', 500 ); + } + + $title = sprintf( + '', + wp_kses_post( $category->name ) + ); + + $desc_str = sprintf( + '', + wc_format_content( $category->description ) + ); + + $output = sprintf( '
    ', esc_attr( $this->get_classes( $attributes ) ), esc_attr( $this->get_styles( $attributes, $category ) ) ); + + $output .= $title; + if ( $attributes['showDesc'] ) { + $output .= $desc_str; + } + $output .= ''; + $output .= '
    '; + + return $output; + } + + /** + * Get the styles for the wrapper element (background image, color). + * + * @param array $attributes Block attributes. Default empty array. + * @param \WP_Term $category Term object. + * @return string + */ + public function get_styles( $attributes, $category ) { + $style = ''; + $image_size = 'large'; + if ( 'none' !== $attributes['align'] || $attributes['height'] > 800 ) { + $image_size = 'full'; + } + + if ( $attributes['mediaId'] ) { + $image = wp_get_attachment_image_url( $attributes['mediaId'], $image_size ); + } else { + $image = $this->get_image( $category, $image_size ); + } + + if ( ! empty( $image ) ) { + $style .= sprintf( 'background-image:url(%s);', esc_url( $image ) ); + } + + if ( isset( $attributes['customOverlayColor'] ) ) { + $style .= sprintf( 'background-color:%s;', esc_attr( $attributes['customOverlayColor'] ) ); + } + + if ( isset( $attributes['height'] ) ) { + $style .= sprintf( 'min-height:%dpx;', intval( $attributes['height'] ) ); + } + + if ( is_array( $attributes['focalPoint'] ) && 2 === count( $attributes['focalPoint'] ) ) { + $style .= sprintf( + 'background-position: %s%% %s%%', + $attributes['focalPoint']['x'] * 100, + $attributes['focalPoint']['y'] * 100 + ); + } + + return $style; + } + + /** + * Get class names for the block container. + * + * @param array $attributes Block attributes. Default empty array. + * @return string + */ + public function get_classes( $attributes ) { + $classes = array( 'wc-block-' . $this->block_name ); + + if ( isset( $attributes['align'] ) ) { + $classes[] = "align{$attributes['align']}"; + } + + if ( isset( $attributes['dimRatio'] ) && ( 0 !== $attributes['dimRatio'] ) ) { + $classes[] = 'has-background-dim'; + + if ( 50 !== $attributes['dimRatio'] ) { + $classes[] = 'has-background-dim-' . 10 * round( $attributes['dimRatio'] / 10 ); + } + } + + if ( isset( $attributes['contentAlign'] ) && 'center' !== $attributes['contentAlign'] ) { + $classes[] = "has-{$attributes['contentAlign']}-content"; + } + + if ( isset( $attributes['overlayColor'] ) ) { + $classes[] = "has-{$attributes['overlayColor']}-background-color"; + } + + if ( isset( $attributes['className'] ) ) { + $classes[] = $attributes['className']; + } + + return implode( ' ', $classes ); + } + + /** + * Returns the main product image URL. + * + * @param \WP_Term $category Term object. + * @param string $size Image size, defaults to 'full'. + * @return string + */ + public function get_image( $category, $size = 'full' ) { + $image = ''; + $image_id = get_term_meta( $category->term_id, 'thumbnail_id', true ); + + if ( $image_id ) { + $image = wp_get_attachment_image_url( $image_id, $size ); + } + + return $image; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/FeaturedProduct.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/FeaturedProduct.php new file mode 100644 index 0000000..256e981 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/FeaturedProduct.php @@ -0,0 +1,186 @@ + 'none', + 'contentAlign' => 'center', + 'dimRatio' => 50, + 'focalPoint' => false, + 'height' => false, + 'mediaId' => 0, + 'mediaSrc' => '', + 'showDesc' => true, + 'showPrice' => true, + ); + + /** + * Render the Featured Product block. + * + * @param array $attributes Block attributes. Default empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + public function render( $attributes = array(), $content = '' ) { + $id = isset( $attributes['productId'] ) ? (int) $attributes['productId'] : 0; + $product = wc_get_product( $id ); + if ( ! $product ) { + return ''; + } + $attributes = wp_parse_args( $attributes, $this->defaults ); + if ( ! $attributes['height'] ) { + $attributes['height'] = wc_get_theme_support( 'featured_block::default_height', 500 ); + } + + $title = sprintf( + '', + wp_kses_post( $product->get_title() ) + ); + + if ( $product->is_type( 'variation' ) ) { + $title .= sprintf( + '', + wc_get_formatted_variation( $product, true, true, false ) + ); + } + + $desc_str = sprintf( + '', + apply_filters( 'woocommerce_short_description', $product->get_short_description() ? $product->get_short_description() : wc_trim_string( $product->get_description(), 400 ) ) + ); + + $price_str = sprintf( + '', + $product->get_price_html() + ); + + $output = sprintf( '
    ', esc_attr( $this->get_classes( $attributes ) ), esc_attr( $this->get_styles( $attributes, $product ) ) ); + + $output .= $title; + if ( $attributes['showDesc'] ) { + $output .= $desc_str; + } + if ( $attributes['showPrice'] ) { + $output .= $price_str; + } + $output .= ''; + $output .= '
    '; + + return $output; + } + + /** + * Get the styles for the wrapper element (background image, color). + * + * @param array $attributes Block attributes. Default empty array. + * @param \WC_Product $product Product object. + * @return string + */ + public function get_styles( $attributes, $product ) { + $style = ''; + $image_size = 'large'; + if ( 'none' !== $attributes['align'] || $attributes['height'] > 800 ) { + $image_size = 'full'; + } + + if ( $attributes['mediaId'] ) { + $image = wp_get_attachment_image_url( $attributes['mediaId'], $image_size ); + } else { + $image = $this->get_image( $product, $image_size ); + } + + if ( ! empty( $image ) ) { + $style .= sprintf( 'background-image:url(%s);', esc_url( $image ) ); + } + + if ( isset( $attributes['customOverlayColor'] ) ) { + $style .= sprintf( 'background-color:%s;', esc_attr( $attributes['customOverlayColor'] ) ); + } + + if ( isset( $attributes['height'] ) ) { + $style .= sprintf( 'min-height:%dpx;', intval( $attributes['height'] ) ); + } + + if ( is_array( $attributes['focalPoint'] ) && 2 === count( $attributes['focalPoint'] ) ) { + $style .= sprintf( + 'background-position: %s%% %s%%', + $attributes['focalPoint']['x'] * 100, + $attributes['focalPoint']['y'] * 100 + ); + } + + return $style; + } + + /** + * Get class names for the block container. + * + * @param array $attributes Block attributes. Default empty array. + * @return string + */ + public function get_classes( $attributes ) { + $classes = array( 'wc-block-' . $this->block_name ); + + if ( isset( $attributes['align'] ) ) { + $classes[] = "align{$attributes['align']}"; + } + + if ( isset( $attributes['dimRatio'] ) && ( 0 !== $attributes['dimRatio'] ) ) { + $classes[] = 'has-background-dim'; + + if ( 50 !== $attributes['dimRatio'] ) { + $classes[] = 'has-background-dim-' . 10 * round( $attributes['dimRatio'] / 10 ); + } + } + + if ( isset( $attributes['contentAlign'] ) && 'center' !== $attributes['contentAlign'] ) { + $classes[] = "has-{$attributes['contentAlign']}-content"; + } + + if ( isset( $attributes['overlayColor'] ) ) { + $classes[] = "has-{$attributes['overlayColor']}-background-color"; + } + + if ( isset( $attributes['className'] ) ) { + $classes[] = $attributes['className']; + } + + return implode( ' ', $classes ); + } + + /** + * Returns the main product image URL. + * + * @param \WC_Product $product Product object. + * @param string $size Image size, defaults to 'full'. + * @return string + */ + public function get_image( $product, $size = 'full' ) { + $image = ''; + if ( $product->get_image_id() ) { + $image = wp_get_attachment_image_url( $product->get_image_id(), $size ); + } elseif ( $product->get_parent_id() ) { + $parent_product = wc_get_product( $product->get_parent_id() ); + if ( $parent_product ) { + $image = wp_get_attachment_image_url( $parent_product->get_image_id(), $size ); + } + } + + return $image; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/HandpickedProducts.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/HandpickedProducts.php new file mode 100644 index 0000000..6dcb9c9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/HandpickedProducts.php @@ -0,0 +1,62 @@ +attributes['products'] ); + + $query_args['post__in'] = $ids; + $query_args['posts_per_page'] = count( $ids ); + } + + /** + * Set visibility query args. Handpicked products will show hidden products if chosen. + * + * @param array $query_args Query args. + */ + protected function set_visibility_query_args( &$query_args ) { + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) { + $product_visibility_terms = wc_get_product_visibility_term_ids(); + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( $product_visibility_terms['outofstock'] ), + 'operator' => 'NOT IN', + ); + } + } + + /** + * Get block attributes. + * + * @return array + */ + protected function get_attributes() { + return array( + 'align' => $this->get_schema_align(), + 'alignButtons' => $this->get_schema_boolean( false ), + 'className' => $this->get_schema_string(), + 'columns' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_columns', 3 ) ), + 'editMode' => $this->get_schema_boolean( true ), + 'orderby' => $this->get_schema_orderby(), + 'products' => $this->get_schema_list_ids(), + 'contentVisibility' => $this->get_schema_content_visibility(), + 'isPreview' => $this->get_schema_boolean( false ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/PriceFilter.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/PriceFilter.php new file mode 100644 index 0000000..5f98375 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/PriceFilter.php @@ -0,0 +1,43 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name, + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'script' => 'wc-' . $this->block_name . '-frontend', + 'supports' => [], + ) + ); + } + + /** + * Register/enqueue scripts used for this block. + * + * @param array $attributes Any attributes that currently are available from the block. + */ + protected function enqueue_scripts( array $attributes = [] ) { + Assets::register_block_script( $this->block_name . '-frontend' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductBestSellers.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductBestSellers.php new file mode 100644 index 0000000..b1cc446 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductBestSellers.php @@ -0,0 +1,24 @@ + true, + 'hasImage' => false, + 'hasEmpty' => false, + 'isDropdown' => false, + 'isHierarchical' => true, + ); + + /** + * Get block attributes. + * + * @return array + */ + protected function get_attributes() { + return array_merge( + parent::get_attributes(), + array( + 'align' => $this->get_schema_align(), + 'className' => $this->get_schema_string(), + 'hasCount' => $this->get_schema_boolean( true ), + 'hasImage' => $this->get_schema_boolean( false ), + 'hasEmpty' => $this->get_schema_boolean( false ), + 'isDropdown' => $this->get_schema_boolean( false ), + 'isHierarchical' => $this->get_schema_boolean( true ), + ) + ); + } + + /** + * Render the Product Categories List block. + * + * @param array $attributes Block attributes. Default empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + public function render( $attributes = array(), $content = '' ) { + $uid = uniqid( 'product-categories-' ); + $categories = $this->get_categories( $attributes ); + + if ( ! $categories ) { + return ''; + } + + if ( ! empty( $content ) ) { + // Deal with legacy attributes (before this was an SSR block) that differ from defaults. + if ( strstr( $content, 'data-has-count="false"' ) ) { + $attributes['hasCount'] = false; + } + if ( strstr( $content, 'data-is-dropdown="true"' ) ) { + $attributes['isDropdown'] = true; + } + if ( strstr( $content, 'data-is-hierarchical="false"' ) ) { + $attributes['isHierarchical'] = false; + } + if ( strstr( $content, 'data-has-empty="true"' ) ) { + $attributes['hasEmpty'] = true; + } + } + + $classes = $this->get_container_classes( $attributes ); + + $output = '
    '; + $output .= ! empty( $attributes['isDropdown'] ) ? $this->renderDropdown( $categories, $attributes, $uid ) : $this->renderList( $categories, $attributes, $uid ); + $output .= '
    '; + + return $output; + } + + /** + * Get the list of classes to apply to this block. + * + * @param array $attributes Block attributes. Default empty array. + * @return string space-separated list of classes. + */ + protected function get_container_classes( $attributes = array() ) { + $classes = array( 'wc-block-product-categories' ); + + if ( isset( $attributes['align'] ) ) { + $classes[] = "align{$attributes['align']}"; + } + + if ( ! empty( $attributes['className'] ) ) { + $classes[] = $attributes['className']; + } + + if ( $attributes['isDropdown'] ) { + $classes[] = 'is-dropdown'; + } else { + $classes[] = 'is-list'; + } + + return implode( ' ', $classes ); + } + + /** + * Get categories (terms) from the db. + * + * @param array $attributes Block attributes. Default empty array. + * @return array + */ + protected function get_categories( $attributes ) { + $hierarchical = wc_string_to_bool( $attributes['isHierarchical'] ); + $categories = get_terms( + 'product_cat', + [ + 'hide_empty' => ! $attributes['hasEmpty'], + 'pad_counts' => true, + 'hierarchical' => true, + ] + ); + + if ( ! $categories ) { + return []; + } + + return $hierarchical ? $this->build_category_tree( $categories ) : $categories; + } + + /** + * Build hierarchical tree of categories. + * + * @param array $categories List of terms. + * @return array + */ + protected function build_category_tree( $categories ) { + $categories_by_parent = []; + + foreach ( $categories as $category ) { + if ( ! isset( $categories_by_parent[ 'cat-' . $category->parent ] ) ) { + $categories_by_parent[ 'cat-' . $category->parent ] = []; + } + $categories_by_parent[ 'cat-' . $category->parent ][] = $category; + } + + $tree = $categories_by_parent['cat-0']; + unset( $categories_by_parent['cat-0'] ); + + foreach ( $tree as $category ) { + if ( ! empty( $categories_by_parent[ 'cat-' . $category->term_id ] ) ) { + $category->children = $this->fill_category_children( $categories_by_parent[ 'cat-' . $category->term_id ], $categories_by_parent ); + } + } + + return $tree; + } + + /** + * Build hierarchical tree of categories by appending children in the tree. + * + * @param array $categories List of terms. + * @param array $categories_by_parent List of terms grouped by parent. + * @return array + */ + protected function fill_category_children( $categories, $categories_by_parent ) { + foreach ( $categories as $category ) { + if ( ! empty( $categories_by_parent[ 'cat-' . $category->term_id ] ) ) { + $category->children = $this->fill_category_children( $categories_by_parent[ 'cat-' . $category->term_id ], $categories_by_parent ); + } + } + return $categories; + } + + /** + * Render the category list as a dropdown. + * + * @param array $categories List of terms. + * @param array $attributes Block attributes. Default empty array. + * @param int $uid Unique ID for the rendered block, used for HTML IDs. + * @return string Rendered output. + */ + protected function renderDropdown( $categories, $attributes, $uid ) { + $aria_label = empty( $attributes['hasCount'] ) ? + __( 'List of categories', 'woocommerce' ) : + __( 'List of categories with their product counts', 'woocommerce' ); + + $output = ' +
    + + +
    + + '; + return $output; + } + + /** + * Render dropdown options list. + * + * @param array $categories List of terms. + * @param array $attributes Block attributes. Default empty array. + * @param int $uid Unique ID for the rendered block, used for HTML IDs. + * @param int $depth Current depth. + * @return string Rendered output. + */ + protected function renderDropdownOptions( $categories, $attributes, $uid, $depth = 0 ) { + $output = ''; + + foreach ( $categories as $category ) { + $output .= ' + + ' . ( ! empty( $category->children ) ? $this->renderDropdownOptions( $category->children, $attributes, $uid, $depth + 1 ) : '' ) . ' + '; + } + + return $output; + } + + /** + * Render the category list as a list. + * + * @param array $categories List of terms. + * @param array $attributes Block attributes. Default empty array. + * @param int $uid Unique ID for the rendered block, used for HTML IDs. + * @param int $depth Current depth. + * @return string Rendered output. + */ + protected function renderList( $categories, $attributes, $uid, $depth = 0 ) { + $classes = [ + 'wc-block-product-categories-list', + 'wc-block-product-categories-list--depth-' . absint( $depth ), + ]; + if ( ! empty( $attributes['hasImage'] ) ) { + $classes[] = 'wc-block-product-categories-list--has-images'; + } + $output = '
      ' . $this->renderListItems( $categories, $attributes, $uid, $depth ) . '
    '; + + return $output; + } + + /** + * Render a list of terms. + * + * @param array $categories List of terms. + * @param array $attributes Block attributes. Default empty array. + * @param int $uid Unique ID for the rendered block, used for HTML IDs. + * @param int $depth Current depth. + * @return string Rendered output. + */ + protected function renderListItems( $categories, $attributes, $uid, $depth = 0 ) { + $output = ''; + + foreach ( $categories as $category ) { + $output .= ' +
  • + + ' . $this->get_image_html( $category, $attributes ) . esc_html( $category->name ) . ' + + ' . $this->getCount( $category, $attributes ) . ' + ' . ( ! empty( $category->children ) ? $this->renderList( $category->children, $attributes, $uid, $depth + 1 ) : '' ) . ' +
  • + '; + } + + return $output; + } + + /** + * Returns the category image html + * + * @param \WP_Term $category Term object. + * @param array $attributes Block attributes. Default empty array. + * @param string $size Image size, defaults to 'woocommerce_thumbnail'. + * @return string + */ + public function get_image_html( $category, $attributes, $size = 'woocommerce_thumbnail' ) { + if ( empty( $attributes['hasImage'] ) ) { + return ''; + } + + $image_id = get_term_meta( $category->term_id, 'thumbnail_id', true ); + + if ( ! $image_id ) { + return '' . wc_placeholder_img( 'woocommerce_thumbnail' ) . ''; + } + + return '' . wp_get_attachment_image( $image_id, 'woocommerce_thumbnail' ) . ''; + } + + /** + * Get the count, if displaying. + * + * @param object $category Term object. + * @param array $attributes Block attributes. Default empty array. + * @return string + */ + protected function getCount( $category, $attributes ) { + if ( empty( $attributes['hasCount'] ) ) { + return ''; + } + + if ( $attributes['isDropdown'] ) { + return '(' . absint( $category->count ) . ')'; + } + + $screen_reader_text = sprintf( + /* translators: %s number of products in cart. */ + _n( '%d product', '%d products', absint( $category->count ), 'woocommerce' ), + absint( $category->count ) + ); + + return '' + . '' + . '' . esc_html( $screen_reader_text ) . '' + . ''; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductCategory.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductCategory.php new file mode 100644 index 0000000..9a3c5cf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductCategory.php @@ -0,0 +1,37 @@ + $this->get_schema_string(), + 'orderby' => $this->get_schema_orderby(), + 'editMode' => $this->get_schema_boolean( true ), + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductNew.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductNew.php new file mode 100644 index 0000000..d2ac9ac --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductNew.php @@ -0,0 +1,25 @@ + $this->get_schema_string(), + 'orderby' => $this->get_schema_orderby(), + ) + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductSearch.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductSearch.php new file mode 100644 index 0000000..500a684 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductSearch.php @@ -0,0 +1,15 @@ +attributes['tags'] ) ) { + $query_args['tax_query'][] = array( + 'taxonomy' => 'product_tag', + 'terms' => array_map( 'absint', $this->attributes['tags'] ), + 'field' => 'id', + 'operator' => isset( $this->attributes['tagOperator'] ) && 'any' === $this->attributes['tagOperator'] ? 'IN' : 'AND', + ); + } + } + + /** + * Get block attributes. + * + * @return array + */ + protected function get_attributes() { + return array( + 'className' => $this->get_schema_string(), + 'columns' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_columns', 3 ) ), + 'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 3 ) ), + 'contentVisibility' => $this->get_schema_content_visibility(), + 'align' => $this->get_schema_align(), + 'alignButtons' => $this->get_schema_boolean( false ), + 'orderby' => $this->get_schema_orderby(), + 'tags' => $this->get_schema_list_ids(), + 'tagOperator' => array( + 'type' => 'string', + 'default' => 'any', + ), + 'isPreview' => $this->get_schema_boolean( false ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductTopRated.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductTopRated.php new file mode 100644 index 0000000..db3cfbc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ProductTopRated.php @@ -0,0 +1,24 @@ +attributes['attributes'] ) ) { + $taxonomy = sanitize_title( $this->attributes['attributes'][0]['attr_slug'] ); + $terms = wp_list_pluck( $this->attributes['attributes'], 'id' ); + + $query_args['tax_query'][] = array( + 'taxonomy' => $taxonomy, + 'terms' => array_map( 'absint', $terms ), + 'field' => 'term_id', + 'operator' => 'all' === $this->attributes['attrOperator'] ? 'AND' : 'IN', + ); + } + } + + /** + * Get block attributes. + * + * @return array + */ + protected function get_attributes() { + return array( + 'align' => $this->get_schema_align(), + 'alignButtons' => $this->get_schema_boolean( false ), + 'attributes' => array( + 'type' => 'array', + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'type' => 'number', + ), + 'attr_slug' => array( + 'type' => 'string', + ), + ), + ), + 'default' => array(), + ), + 'attrOperator' => array( + 'type' => 'string', + 'default' => 'any', + ), + 'className' => $this->get_schema_string(), + 'columns' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_columns', 3 ) ), + 'contentVisibility' => $this->get_schema_content_visibility(), + 'editMode' => $this->get_schema_boolean( true ), + 'orderby' => $this->get_schema_orderby(), + 'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 3 ) ), + 'isPreview' => $this->get_schema_boolean( false ), + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ReviewsByCategory.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ReviewsByCategory.php new file mode 100644 index 0000000..a83ee8f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ReviewsByCategory.php @@ -0,0 +1,42 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name, + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'script' => 'wc-' . $this->block_name . '-frontend', + 'supports' => [], + ) + ); + } + + /** + * Register/enqueue scripts used for this block. + * + * @param array $attributes Any attributes that currently are available from the block. + */ + protected function enqueue_scripts( array $attributes = [] ) { + Assets::register_block_script( 'reviews-frontend' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ReviewsByProduct.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ReviewsByProduct.php new file mode 100644 index 0000000..b769770 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/ReviewsByProduct.php @@ -0,0 +1,42 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name, + 'editor_style' => 'wc-block-editor', + 'style' => 'wc-block-style', + 'script' => 'wc-' . $this->block_name . '-frontend', + 'supports' => [], + ) + ); + } + + /** + * Register/enqueue scripts used for this block. + * + * @param array $attributes Any attributes that currently are available from the block. + */ + protected function enqueue_scripts( array $attributes = [] ) { + Assets::register_block_script( 'reviews-frontend' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/SingleProduct.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/SingleProduct.php new file mode 100644 index 0000000..71f4dc9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypes/SingleProduct.php @@ -0,0 +1,59 @@ +namespace . '/' . $this->block_name, + array( + 'render_callback' => array( $this, 'render' ), + 'editor_script' => 'wc-' . $this->block_name . '-block', + 'editor_style' => 'wc-block-editor', + 'style' => [ 'wc-block-style', 'wc-block-vendors-style' ], + 'script' => 'wc-' . $this->block_name . '-frontend', + 'supports' => [], + ) + ); + } + + /** + * Register/enqueue scripts used for this block. + * + * @param array $attributes Any attributes that currently are available from the block. + * Note, this will be empty in the editor context when the block is + * not in the post content on editor load. + */ + protected function enqueue_scripts( array $attributes = [] ) { + Assets::register_block_script( $this->block_name . '-frontend', $this->block_name . '-frontend' ); + } + + /** + * Render the block on the frontend. + * + * @param array $attributes Block attributes. Default empty array. + * @param string $content Block content. Default empty string. + * @return string Rendered block type output. + */ + public function render( $attributes = array(), $content = '' ) { + $block_attributes = is_a( $attributes, '\WP_Block' ) ? $attributes->attributes : $attributes; + + $this->enqueue_assets( $block_attributes ); + + return $this->inject_html_data_attributes( $content, $block_attributes ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Bootstrap.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Bootstrap.php new file mode 100644 index 0000000..15b4902 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Bootstrap.php @@ -0,0 +1,250 @@ +container = $container; + $this->package = $container->get( Package::class ); + $this->init(); + /** + * Usable as a safe event hook for when the plugin has been loaded. + */ + do_action( 'woocommerce_blocks_loaded' ); + } + + /** + * Init the package - load the blocks library and define constants. + */ + protected function init() { + if ( ! $this->has_core_dependencies() ) { + return; + } + $this->define_feature_flag(); + $this->register_dependencies(); + $this->register_payment_methods(); + + $is_rest = wc()->is_rest_api_request(); + + // Load assets in admin and on the frontend. + if ( ! $is_rest ) { + $this->add_build_notice(); + $this->container->get( AssetDataRegistry::class ); + $this->container->get( Installer::class ); + BlockAssets::init(); + } + $this->container->get( DraftOrders::class )->init(); + $this->container->get( CreateAccount::class )->init(); + $this->container->get( PaymentsApi::class ); + $this->container->get( RestApi::class ); + Library::init(); + } + + /** + * Check core dependencies exist. + * + * @return boolean + */ + protected function has_core_dependencies() { + return class_exists( 'WooCommerce' ) && function_exists( 'register_block_type' ); + } + + /** + * See if files have been built or not. + * + * @return bool + */ + protected function is_built() { + return file_exists( + $this->package->get_path( 'build/featured-product.js' ) + ); + } + + /** + * Add a notice stating that the build has not been done yet. + */ + protected function add_build_notice() { + if ( $this->is_built() ) { + return; + } + add_action( + 'admin_notices', + function() { + echo '

    '; + printf( + /* Translators: %1$s is the install command, %2$s is the build command, %3$s is the watch command. */ + esc_html__( 'WooCommerce Blocks development mode requires files to be built. From the plugin directory, run %1$s to install dependencies, %2$s to build the files or %3$s to build the files and watch for changes.', 'woocommerce' ), + 'npm install', + 'npm run build', + 'npm start' + ); + echo '

    '; + } + ); + } + + /** + * Define the global feature flag. + */ + protected function define_feature_flag() { + $default_flag = defined( 'WC_BLOCKS_IS_FEATURE_PLUGIN' ) ? '2' : '1'; + $allowed_flags = [ '1', '2', '3' ]; + + if ( file_exists( __DIR__ . '/../../blocks.ini' ) ) { + $woo_options = parse_ini_file( __DIR__ . '/../../blocks.ini' ); + $flag = is_array( $woo_options ) && in_array( $woo_options['woocommerce_blocks_phase'], $allowed_flags, true ) ? $woo_options['woocommerce_blocks_phase'] : $default_flag; + } else { + $flag = $default_flag; + } + + define( 'WOOCOMMERCE_BLOCKS_PHASE', intval( $flag ) ); + } + + /** + * Register core dependencies with the container. + */ + protected function register_dependencies() { + $this->container->register( + AssetApi::class, + function ( Container $container ) { + return new AssetApi( $container->get( Package::class ) ); + } + ); + $this->container->register( + AssetDataRegistry::class, + function( Container $container ) { + $asset_api = $container->get( AssetApi::class ); + $load_back_compat = defined( 'WC_ADMIN_VERSION_NUMBER' ) + && version_compare( WC_ADMIN_VERSION_NUMBER, '0.19.0', '<=' ); + return $load_back_compat + ? new BackCompatAssetDataRegistry( $asset_api ) + : new AssetDataRegistry( $asset_api ); + } + ); + $this->container->register( + PaymentMethodRegistry::class, + function( Container $container ) { + return new PaymentMethodRegistry(); + } + ); + $this->container->register( + PaymentsApi::class, + function ( Container $container ) { + $payment_method_registry = $container->get( PaymentMethodRegistry::class ); + $asset_data_registry = $container->get( AssetDataRegistry::class ); + return new PaymentsApi( $payment_method_registry, $asset_data_registry ); + } + ); + $this->container->register( + RestApi::class, + function ( Container $container ) { + return new RestApi(); + } + ); + $this->container->register( + Installer::class, + function ( Container $container ) { + return new Installer(); + } + ); + $this->container->register( + DraftOrders::class, + function( Container $container ) { + return new DraftOrders( $container->get( Package::class ) ); + } + ); + $this->container->register( + CreateAccount::class, + function( Container $container ) { + return new CreateAccount( $container->get( Package::class ) ); + } + ); + } + + /** + * Register payment method integrations with the container. + * + * @internal Stripe is a temporary method that is used for setting up payment method integrations with Cart and + * Checkout blocks. This logic should get moved to the payment gateway extensions. + */ + protected function register_payment_methods() { + $this->container->register( + Stripe::class, + function( Container $container ) { + $asset_api = $container->get( AssetApi::class ); + return new Stripe( $asset_api ); + } + ); + $this->container->register( + Cheque::class, + function( Container $container ) { + $asset_api = $container->get( AssetApi::class ); + return new Cheque( $asset_api ); + } + ); + $this->container->register( + PayPal::class, + function( Container $container ) { + $asset_api = $container->get( AssetApi::class ); + return new PayPal( $asset_api ); + } + ); + $this->container->register( + BankTransfer::class, + function( Container $container ) { + $asset_api = $container->get( AssetApi::class ); + return new BankTransfer( $asset_api ); + } + ); + $this->container->register( + CashOnDelivery::class, + function( Container $container ) { + $asset_api = $container->get( AssetApi::class ); + return new CashOnDelivery( $asset_api ); + } + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Package.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Package.php new file mode 100644 index 0000000..38f5e96 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Package.php @@ -0,0 +1,89 @@ +version = $version; + $this->path = $plugin_path; + } + + /** + * Returns the version of the plugin. + * + * @return string + */ + public function get_version() { + return $this->version; + } + + /** + * Returns the path to the plugin directory. + * + * @param string $relative_path If provided, the relative path will be + * appended to the plugin path. + * + * @return string + */ + public function get_path( $relative_path = '' ) { + return trailingslashit( $this->path ) . $relative_path; + } + + /** + * Returns the url to the blocks plugin directory. + * + * @param string $relative_url If provided, the relative url will be + * appended to the plugin url. + * + * @return string + */ + public function get_url( $relative_url = '' ) { + // Append index.php so WP does not return the parent directory. + return plugin_dir_url( $this->path . '/index.php' ) . $relative_url; + } + + /** + * Checks if we're executing the code in an experimental build mode. + * + * @return boolean + */ + public static function is_experimental_build() { + return WOOCOMMERCE_BLOCKS_PHASE > 2; + } + + /** + * Checks if we're executing the code in an feature plugin or experimental build mode. + * + * @return boolean + */ + public static function is_feature_plugin_build() { + return WOOCOMMERCE_BLOCKS_PHASE > 1; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Services/CreateAccount.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Services/CreateAccount.php new file mode 100644 index 0000000..0a81d49 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Services/CreateAccount.php @@ -0,0 +1,263 @@ +package = $package; + } + + /** + * Single method for feature gating logic. Used to gate all non-private methods. + * + * @return True if Checkout sign-up feature should be made available. + */ + private static function is_feature_enabled() { + // Checkout signup is feature gated to WooCommerce 4.7 and newer; + // uses updated my-account/lost-password screen from 4.7+ for + // setting initial password. + // This service is feature gated to plugin only, to match the + // availability of the Checkout block (feature plugin only). + return Package::is_feature_plugin_build() && defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '4.7', '>=' ); + } + + /** + * Init - register handlers for WooCommerce core email hooks. + */ + public function init() { + if ( ! self::is_feature_enabled() ) { + return; + } + + // Override core email handlers to add our new improved "new account" email. + add_action( + 'woocommerce_email', + function ( $wc_emails_instance ) { + // Remove core "new account" handler; we are going to replace it. + remove_action( 'woocommerce_created_customer_notification', array( $wc_emails_instance, 'customer_new_account' ), 10, 3 ); + + // Add custom "new account" handler. + add_action( + 'woocommerce_created_customer_notification', + function( $customer_id, $new_customer_data = array(), $password_generated = false ) use ( $wc_emails_instance ) { + // If this is a block-based signup, send a new email + // with password reset link (no password in email). + if ( isset( $new_customer_data['is_checkout_block_customer_signup'] ) ) { + $this->customer_new_account( $customer_id, $new_customer_data ); + return; + } + + // Otherwise, trigger the existing legacy email (with new password inline). + $wc_emails_instance->customer_new_account( $customer_id, $new_customer_data, $password_generated ); + }, + 10, + 3 + ); + } + ); + } + + /** + * Trigger new account email. + * This is intended as a replacement to WC_Emails::customer_new_account(), + * with a set password link instead of emailing the new password in email + * content. + * + * @param int $customer_id The ID of the new customer account. + * @param array $new_customer_data Assoc array of data for the new account. + */ + public function customer_new_account( $customer_id = 0, array $new_customer_data = array() ) { + if ( ! self::is_feature_enabled() ) { + return; + } + + if ( ! $customer_id ) { + return; + } + + $new_account_email = new CustomerNewAccount( $this->package ); + $new_account_email->trigger( $customer_id, $new_customer_data ); + } + + /** + * Create a user account for specified request (if necessary). + * If a new account is created: + * - The user is logged in. + * + * @param \WP_REST_Request $request The current request object being handled. + * + * @throws Exception On error. + * @return int The new user id, or 0 if no user was created. + */ + public function from_order_request( \WP_REST_Request $request ) { + if ( ! self::is_feature_enabled() || ! $this->should_create_customer_account( $request ) ) { + return 0; + } + + $customer_id = $this->create_customer_account( + $request['billing_address']['email'], + $request['billing_address']['first_name'], + $request['billing_address']['last_name'] + ); + // Log the customer in and associate with the order. + wc_set_customer_auth_cookie( $customer_id ); + + return $customer_id; + } + + /** + * Check request options and store (shop) config to determine if a user account + * should be created as part of order processing. + * + * @param \WP_REST_Request $request The current request object being handled. + * + * @return boolean True if a new user account should be created. + */ + protected function should_create_customer_account( \WP_REST_Request $request ) { + if ( is_user_logged_in() ) { + // User is already logged in - no need to create an account. + return false; + } + + // From here we know that the shopper is not logged in. + // check for whether account creation is enabled at the global level. + $checkout = WC()->checkout(); + if ( ! $checkout instanceof \WC_Checkout ) { + // If checkout class is not available, we have major problems, don't create account. + return false; + } + + if ( false === filter_var( $checkout->is_registration_enabled(), FILTER_VALIDATE_BOOLEAN ) ) { + // Registration is not enabled for the store, so return false. + return false; + } + + if ( true === filter_var( $checkout->is_registration_required(), FILTER_VALIDATE_BOOLEAN ) ) { + // Store requires an account for all checkouts (purchases). + // Create an account independent of shopper option in $request. + // Note - checkbox is not displayed to shopper in this case. + return true; + } + + // From here we know that the store allows guest checkout; + // shopper can choose whether they sign up (`should_create_account`). + + if ( true === filter_var( $request['should_create_account'], FILTER_VALIDATE_BOOLEAN ) ) { + // User has requested an account as part of checkout processing. + return true; + } + + return false; + } + + /** + * Convert an account creation error to an exception. + * + * @param \WP_Error $error An error object. + * + * @return Exception. + */ + private function map_create_account_error( \WP_Error $error ) { + switch ( $error->get_error_code() ) { + // WordPress core error codes. + case 'empty_username': + case 'invalid_username': + case 'empty_email': + case 'invalid_email': + case 'email_exists': + case 'registerfail': + return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); + } + + return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); + } + + /** + * Create a new account for a customer (using a new blocks-specific PHP API). + * + * The account is created with a generated username. The customer is sent + * an email notifying them about the account and containing a link to set + * their (initial) password. + * + * Intended as a replacement for wc_create_new_customer in WC core. + * + * @throws \Exception If an error is encountered when creating the user account. + * + * @param string $user_email The email address to use for the new account. + * @param string $first_name The first name to use for the new account. + * @param string $last_name The last name to use for the new account. + * + * @return int User id if successful + */ + private function create_customer_account( $user_email, $first_name, $last_name ) { + if ( empty( $user_email ) || ! is_email( $user_email ) ) { + throw new \Exception( 'registration-error-invalid-email' ); + } + + if ( email_exists( $user_email ) ) { + throw new \Exception( 'registration-error-email-exists' ); + } + + $username = wc_create_new_customer_username( $user_email ); + + // Handle password creation. + $password = wp_generate_password(); + $password_generated = true; + + // Use WP_Error to handle registration errors. + $errors = new \WP_Error(); + + do_action( 'woocommerce_register_post', $username, $user_email, $errors ); + + $errors = apply_filters( 'woocommerce_registration_errors', $errors, $username, $user_email ); + + if ( $errors->get_error_code() ) { + throw new \Exception( $errors->get_error_code() ); + } + + $new_customer_data = apply_filters( + 'woocommerce_new_customer_data', + array( + 'is_checkout_block_customer_signup' => true, + 'user_login' => $username, + 'user_pass' => $password, + 'user_email' => $user_email, + 'first_name' => $first_name, + 'last_name' => $last_name, + 'role' => 'customer', + ) + ); + + $customer_id = wp_insert_user( $new_customer_data ); + + if ( is_wp_error( $customer_id ) ) { + throw $this->map_create_account_error( $customer_id ); + } + + // Set account flag to remind customer to update generated password. + update_user_option( $customer_id, 'default_password_nag', true, true ); + + do_action( 'woocommerce_created_customer', $customer_id, $new_customer_data, $password_generated ); + + return $customer_id; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Services/DraftOrders.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Services/DraftOrders.php new file mode 100644 index 0000000..95e9486 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Services/DraftOrders.php @@ -0,0 +1,231 @@ +package = $package; + } + + /** + * Set all hooks related to adding Checkout Draft order functionality to Woo Core. + */ + public function init() { + if ( $this->package->is_feature_plugin_build() ) { + add_filter( 'wc_order_statuses', [ $this, 'register_draft_order_status' ] ); + add_filter( 'woocommerce_register_shop_order_post_statuses', [ $this, 'register_draft_order_post_status' ] ); + add_filter( 'woocommerce_valid_order_statuses_for_payment', [ $this, 'append_draft_order_post_status' ] ); + add_filter( 'woocommerce_valid_order_statuses_for_payment_complete', [ $this, 'append_draft_order_post_status' ] ); + add_action( 'woocommerce_cleanup_draft_orders', [ $this, 'delete_expired_draft_orders' ] ); + add_action( 'admin_init', [ $this, 'install' ] ); + } else { + // Maybe remove existing cronjob if present because it shouldn't be needed in the environment. + add_action( 'admin_init', [ $this, 'uninstall' ] ); + } + } + + /** + * Installation related logic for Draft order functionality. + * + * @internal + */ + public function install() { + $this->maybe_create_cronjobs(); + } + + /** + * Remove cronjobs if they exist (but only from admin). + * + * @internal + */ + public function uninstall() { + $this->maybe_remove_cronjobs(); + } + + /** + * Maybe create cron events. + */ + protected function maybe_create_cronjobs() { + if ( function_exists( 'as_next_scheduled_action' ) && false === as_next_scheduled_action( 'woocommerce_cleanup_draft_orders' ) ) { + as_schedule_recurring_action( strtotime( 'midnight tonight' ), DAY_IN_SECONDS, 'woocommerce_cleanup_draft_orders' ); + } + } + + /** + * Unschedule cron jobs that are present. + */ + protected function maybe_remove_cronjobs() { + if ( function_exists( 'as_next_scheduled_action' ) && as_next_scheduled_action( 'woocommerce_cleanup_draft_orders' ) ) { + as_unschedule_all_actions( 'woocommerce_cleanup_draft_orders' ); + } + } + + /** + * Register custom order status for orders created via the API during checkout. + * + * Draft order status is used before payment is attempted, during checkout, when a cart is converted to an order. + * + * @param array $statuses Array of statuses. + * @internal + * @return array + */ + public function register_draft_order_status( array $statuses ) { + $statuses[ self::DB_STATUS ] = _x( 'Draft', 'Order status', 'woocommerce' ); + return $statuses; + } + + /** + * Register custom order post status for orders created via the API during checkout. + * + * @param array $statuses Array of statuses. + * @internal + + * @return array + */ + public function register_draft_order_post_status( array $statuses ) { + $statuses[ self::DB_STATUS ] = $this->get_post_status_properties(); + return $statuses; + } + + /** + * Returns the properties of this post status for registration. + * + * @return array + */ + private function get_post_status_properties() { + return [ + 'label' => _x( 'Draft', 'Order status', 'woocommerce' ), + 'public' => false, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => false, + 'show_in_admin_status_list' => true, + /* translators: %s: number of orders */ + 'label_count' => _n_noop( 'Drafts (%s)', 'Drafts (%s)', 'woocommerce' ), + ]; + } + + /** + * Append draft status to a list of statuses. + * + * @param array $statuses Array of statuses. + * @internal + + * @return array + */ + public function append_draft_order_post_status( $statuses ) { + $statuses[] = self::STATUS; + return $statuses; + } + + /** + * Delete draft orders older than a day in batches of 20. + * + * Ran on a daily cron schedule. + * + * @internal + */ + public function delete_expired_draft_orders() { + $count = 0; + $batch_size = 20; + $this->ensure_draft_status_registered(); + $orders = wc_get_orders( + [ + 'date_modified' => '<=' . strtotime( '-1 DAY' ), + 'limit' => $batch_size, + 'status' => self::DB_STATUS, + 'type' => 'shop_order', + ] + ); + + // do we bail because the query results are unexpected? + try { + $this->assert_order_results( $orders, $batch_size ); + if ( $orders ) { + foreach ( $orders as $order ) { + $order->delete( true ); + $count ++; + } + } + if ( $batch_size === $count && function_exists( 'as_enqueue_async_action' ) ) { + as_enqueue_async_action( 'woocommerce_cleanup_draft_orders' ); + } + } catch ( Exception $error ) { + wc_caught_exception( $error, __METHOD__ ); + } + } + + /** + * Since it's possible for third party code to clobber the `$wp_post_statuses` global, + * we need to do a final check here to make sure the draft post status is + * registered with the global so that it is not removed by WP_Query status + * validation checks. + */ + private function ensure_draft_status_registered() { + $is_registered = get_post_stati( [ 'name' => self::DB_STATUS ] ); + if ( empty( $is_registered ) ) { + register_post_status( + self::DB_STATUS, + $this->get_post_status_properties() + ); + } + } + + /** + * Asserts whether incoming order results are expected given the query + * this service class executes. + * + * @param WC_Order[] $order_results The order results being asserted. + * @param int $expected_batch_size The expected batch size for the results. + * @throws Exception If any assertions fail, an exception is thrown. + */ + private function assert_order_results( $order_results, $expected_batch_size ) { + // if not an array, then just return because it won't get handled + // anyways. + if ( ! is_array( $order_results ) ) { + return; + } + + $suffix = ' This is an indicator that something is filtering WooCommerce or WordPress queries and modifying the query parameters.'; + + // if count is greater than our expected batch size, then that's a problem. + if ( count( $order_results ) > 20 ) { + throw new Exception( 'There are an unexpected number of results returned from the query.' . $suffix ); + } + + // if any of the returned orders are not draft (or not a WC_Order), then that's a problem. + foreach ( $order_results as $order ) { + if ( ! ( $order instanceof WC_Order ) ) { + throw new Exception( 'The returned results contain a value that is not a WC_Order.' . $suffix ); + } + if ( ! $order->has_status( self::STATUS ) ) { + throw new Exception( 'The results contain an order that is not a `wc-checkout-draft` status in the results.' . $suffix ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Services/Email/CustomerNewAccount.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Services/Email/CustomerNewAccount.php new file mode 100644 index 0000000..3647f49 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Domain/Services/Email/CustomerNewAccount.php @@ -0,0 +1,176 @@ + Emails) + // apply to this email (consistent with the core email). + $this->id = 'customer_new_account'; + $this->customer_email = true; + $this->title = __( 'New account', 'woocommerce' ); + $this->description = __( 'Customer "new account" emails are sent to the customer when a customer signs up via checkout or account blocks.', 'woocommerce' ); + $this->template_html = 'emails/customer-new-account-blocks.php'; + $this->template_plain = 'emails/plain/customer-new-account-blocks.php'; + $this->default_template_path = $package->get_path( '/templates/' ); + + // Call parent constructor. + parent::__construct(); + } + + /** + * Get email subject. + * + * @since 3.1.0 + * @return string + */ + public function get_default_subject() { + return __( 'Your {site_title} account has been created!', 'woocommerce' ); + } + + /** + * Get email heading. + * + * @since 3.1.0 + * @return string + */ + public function get_default_heading() { + return __( 'Welcome to {site_title}', 'woocommerce' ); + } + + /** + * Trigger. + * + * @param int $user_id User ID. + * @param string $user_pass User password. + * @param bool $password_generated Whether the password was generated automatically or not. + */ + public function trigger( $user_id, $user_pass = '', $password_generated = false ) { + $this->setup_locale(); + + if ( $user_id ) { + $this->object = new \WP_User( $user_id ); + + // Generate a magic link so user can set initial password. + $key = get_password_reset_key( $this->object ); + if ( ! is_wp_error( $key ) ) { + $action = 'newaccount'; + $this->set_password_url = wc_get_account_endpoint_url( 'lost-password' ) . "?action=$action&key=$key&login=" . rawurlencode( $this->object->user_login ); + } + + $this->user_login = stripslashes( $this->object->user_login ); + $this->user_email = stripslashes( $this->object->user_email ); + $this->recipient = $this->user_email; + } + + if ( $this->is_enabled() && $this->get_recipient() ) { + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments(), $this->set_password_url ); + } + + $this->restore_locale(); + } + + /** + * Get content html. + * + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'user_login' => $this->user_login, + 'blogname' => $this->get_blogname(), + 'set_password_url' => $this->set_password_url, + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ), + '', + $this->default_template_path + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'email_heading' => $this->get_heading(), + 'additional_content' => $this->get_additional_content(), + 'user_login' => $this->user_login, + 'blogname' => $this->get_blogname(), + 'set_password_url' => $this->set_password_url, + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ), + '', + $this->default_template_path + ); + } + + /** + * Default content to show below main email content. + * + * @since 3.7.0 + * @return string + */ + public function get_default_additional_content() { + return __( 'We look forward to seeing you soon.', 'woocommerce' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Installer.php new file mode 100644 index 0000000..9fd0949 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Installer.php @@ -0,0 +1,117 @@ +init(); + } + + /** + * Installation tasks ran on admin_init callback. + */ + public function install() { + $this->maybe_create_tables(); + } + + /** + * Initialize class features. + */ + protected function init() { + add_action( 'admin_init', array( $this, 'install' ) ); + } + + /** + * Set up the database tables which the plugin needs to function. + */ + public function maybe_create_tables() { + global $wpdb; + + $schema_version = 260; + $db_schema_version = (int) get_option( 'wc_blocks_db_schema_version', 0 ); + + if ( $db_schema_version >= $schema_version && 0 !== $db_schema_version ) { + return; + } + + $show_errors = $wpdb->hide_errors(); + $table_name = $wpdb->prefix . 'wc_reserved_stock'; + $collate = $wpdb->has_cap( 'collation' ) ? $wpdb->get_charset_collate() : ''; + $exists = $this->maybe_create_table( + $wpdb->prefix . 'wc_reserved_stock', + " + CREATE TABLE {$wpdb->prefix}wc_reserved_stock ( + `order_id` bigint(20) NOT NULL, + `product_id` bigint(20) NOT NULL, + `stock_quantity` double NOT NULL DEFAULT 0, + `timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`order_id`, `product_id`) + ) $collate; + " + ); + + if ( $show_errors ) { + $wpdb->show_errors(); + } + + if ( ! $exists ) { + return $this->add_create_table_notice( $table_name ); + } + + // Update succeeded. This is only updated when successful and validated. + // $schema_version should be incremented when changes to schema are made within this method. + update_option( 'wc_blocks_db_schema_version', $schema_version ); + } + + /** + * Create database table, if it doesn't already exist. + * + * Based on admin/install-helper.php maybe_create_table function. + * + * @param string $table_name Database table name. + * @param string $create_sql Create database table SQL. + * @return bool False on error, true if already exists or success. + */ + protected function maybe_create_table( $table_name, $create_sql ) { + global $wpdb; + + if ( in_array( $table_name, $wpdb->get_col( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ), 0 ), true ) ) { + return true; + } + + $wpdb->query( $create_sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + + return in_array( $table_name, $wpdb->get_col( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ), 0 ), true ); + } + + /** + * Add a notice if table creation fails. + * + * @param string $table_name Name of the missing table. + */ + protected function add_create_table_notice( $table_name ) { + add_action( + 'admin_notices', + function() use ( $table_name ) { + echo '

    '; + printf( + /* Translators: %1$s table name, %2$s database user, %3$s database name. */ + esc_html__( 'WooCommerce %1$s table creation failed. Does the %2$s user have CREATE privileges on the %3$s database?', 'woocommerce' ), + '' . esc_html( $table_name ) . '', + '' . esc_html( DB_USER ) . '', + '' . esc_html( DB_NAME ) . '' + ); + echo '

    '; + } + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Library.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Library.php new file mode 100644 index 0000000..52ffec8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Library.php @@ -0,0 +1,108 @@ + 'wc_reserved_stock', + ); + + foreach ( $tables as $name => $table ) { + $wpdb->$name = $wpdb->prefix . $table; + $wpdb->tables[] = $table; + } + } + + /** + * Register blocks, hooking up assets and render functions as needed. + */ + public static function register_blocks() { + global $wp_version; + $blocks = [ + 'AllReviews', + 'FeaturedCategory', + 'FeaturedProduct', + 'HandpickedProducts', + 'ProductBestSellers', + 'ProductCategories', + 'ProductCategory', + 'ProductNew', + 'ProductOnSale', + 'ProductsByAttribute', + 'ProductTopRated', + 'ReviewsByProduct', + 'ReviewsByCategory', + 'ProductSearch', + 'ProductTag', + ]; + // Note: as a part of refactoring dynamic block registration, this will be moved + // to block level config. + if ( version_compare( $wp_version, '5.3', '>=' ) ) { + $blocks[] = 'AllProducts'; + $blocks[] = 'PriceFilter'; + $blocks[] = 'AttributeFilter'; + $blocks[] = 'ActiveFilters'; + + if ( Package::is_feature_plugin_build() ) { + $blocks[] = 'Checkout'; + $blocks[] = 'Cart'; + } + } + if ( Package::is_experimental_build() ) { + $blocks[] = 'SingleProduct'; + } + foreach ( $blocks as $class ) { + $class = __NAMESPACE__ . '\\BlockTypes\\' . $class; + $instance = new $class(); + $instance->register_block_type(); + } + self::register_atomic_blocks(); + } + + /** + * Register atomic blocks on the PHP side. + */ + protected static function register_atomic_blocks() { + $atomic_blocks = [ + 'product-title', + 'product-button', + 'product-image', + 'product-price', + 'product-rating', + 'product-sale-badge', + 'product-summary', + 'product-sku', + 'product-category-list', + 'product-tag-list', + 'product-stock-indicator', + 'product-add-to-cart', + ]; + foreach ( $atomic_blocks as $atomic_block ) { + $instance = new \Automattic\WooCommerce\Blocks\BlockTypes\AtomicBlock( $atomic_block ); + $instance->register_block_type(); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Package.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Package.php new file mode 100644 index 0000000..b9dd026 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Package.php @@ -0,0 +1,117 @@ +get( NewPackage::class ); + } + + /** + * Init the package - load the blocks library and define constants. + * + * @since 2.5.0 Handled by new NewPackage. + */ + public static function init() { + self::container()->get( Bootstrap::class ); + } + + /** + * Return the version of the package. + * + * @return string + */ + public static function get_version() { + return self::get_package()->get_version(); + } + + /** + * Return the path to the package. + * + * @return string + */ + public static function get_path() { + return self::get_package()->get_path(); + } + + /** + * Checks if we're executing the code in an experimental build mode. + * + * @return boolean + */ + public static function is_experimental_build() { + return self::get_package()->is_experimental_build(); + } + + /** + * Checks if we're executing the code in an feature plugin or experimental build mode. + * + * @return boolean + */ + public static function is_feature_plugin_build() { + return self::get_package()->is_feature_plugin_build(); + } + /** + * Loads the dependency injection container for woocommerce blocks. + * + * @param boolean $reset Used to reset the container to a fresh instance. + * Note: this means all dependencies will be + * reconstructed. + */ + public static function container( $reset = false ) { + static $container; + if ( + ! $container instanceof Container + || $reset + ) { + $container = new Container(); + // register Package. + $container->register( + NewPackage::class, + function ( $container ) { + // leave for automated version bumping. + $version = '3.8.1'; + return new NewPackage( + $version, + dirname( __DIR__ ) + ); + } + ); + // register Bootstrap. + $container->register( + Bootstrap::class, + function ( $container ) { + return new Bootstrap( + $container + ); + } + ); + } + return $container; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Api.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Api.php new file mode 100644 index 0000000..5cd1e01 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Api.php @@ -0,0 +1,177 @@ +payment_method_registry = $payment_method_registry; + $this->asset_registry = $asset_registry; + $this->init(); + } + + /** + * Initialize class features. + */ + protected function init() { + add_action( 'init', array( $this->payment_method_registry, 'initialize' ), 5 ); + add_filter( 'woocommerce_blocks_register_script_dependencies', array( $this, 'add_payment_method_script_dependencies' ), 10, 2 ); + add_action( 'woocommerce_blocks_checkout_enqueue_data', array( $this, 'add_payment_method_script_data' ) ); + add_action( 'woocommerce_blocks_cart_enqueue_data', array( $this, 'add_payment_method_script_data' ) ); + add_action( 'woocommerce_blocks_payment_method_type_registration', array( $this, 'register_payment_method_integrations' ) ); + add_action( 'woocommerce_rest_checkout_process_payment_with_context', array( $this, 'process_legacy_payment' ), 999, 2 ); + } + + /** + * Add payment method script handles as script dependencies. + * + * @param array $dependencies Array of script dependencies. + * @param string $handle Script handle. + * @return array + */ + public function add_payment_method_script_dependencies( $dependencies, $handle ) { + if ( ! in_array( $handle, [ 'wc-checkout-block', 'wc-checkout-block-frontend', 'wc-cart-block', 'wc-cart-block-frontend' ], true ) ) { + return $dependencies; + } + return array_merge( $dependencies, $this->payment_method_registry->get_all_registered_script_handles() ); + } + + /** + * Returns true if the payment gateway is enabled. + * + * @param object $gateway Payment gateway. + * @return boolean + */ + private function is_payment_gateway_enabled( $gateway ) { + return filter_var( $gateway->enabled, FILTER_VALIDATE_BOOLEAN ); + } + + /** + * Add payment method data to Asset Registry. + */ + public function add_payment_method_script_data() { + // Enqueue the order of enabled gateways as `paymentGatewaySortOrder`. + if ( ! $this->asset_registry->exists( 'paymentGatewaySortOrder' ) ) { + $payment_gateways = WC()->payment_gateways->payment_gateways(); + $enabled_gateways = array_filter( $payment_gateways, array( $this, 'is_payment_gateway_enabled' ) ); + $this->asset_registry->add( 'paymentGatewaySortOrder', array_keys( $enabled_gateways ) ); + } + + // Enqueue all registered gateway data (settings/config etc). + $script_data = $this->payment_method_registry->get_all_registered_script_data(); + foreach ( $script_data as $asset_data_key => $asset_data_value ) { + if ( ! $this->asset_registry->exists( $asset_data_key ) ) { + $this->asset_registry->add( $asset_data_key, $asset_data_value ); + } + } + } + + /** + * Register payment method integrations bundled with blocks. + * + * @param PaymentMethodRegistry $payment_method_registry Payment method registry instance. + */ + public function register_payment_method_integrations( PaymentMethodRegistry $payment_method_registry ) { + // This is temporarily registering Stripe until it's moved to the extension. + if ( class_exists( '\WC_Stripe' ) && ! $payment_method_registry->is_registered( 'stripe' ) ) { + $payment_method_registry->register( + Package::container()->get( Stripe::class ) + ); + } + $payment_method_registry->register( + Package::container()->get( Cheque::class ) + ); + $payment_method_registry->register( + Package::container()->get( PayPal::class ) + ); + $payment_method_registry->register( + Package::container()->get( BankTransfer::class ) + ); + $payment_method_registry->register( + Package::container()->get( CashOnDelivery::class ) + ); + } + + /** + * Attempt to process a payment for the checkout API if no payment methods support the + * woocommerce_rest_checkout_process_payment_with_context action. + * + * @param PaymentContext $context Holds context for the payment. + * @param PaymentResult $result Result of the payment. + */ + public function process_legacy_payment( PaymentContext $context, PaymentResult &$result ) { + if ( $result->status ) { + return; + } + + // phpcs:ignore WordPress.Security.NonceVerification + $post_data = $_POST; + + // Set constants. + wc_maybe_define_constant( 'WOOCOMMERCE_CHECKOUT', true ); + + // Add the payment data from the API to the POST global. + $_POST = $context->payment_data; + + // Call the process payment method of the chosen gateway. + $payment_method_object = $context->get_payment_method_instance(); + + if ( ! $payment_method_object instanceof \WC_Payment_Gateway ) { + return; + } + + $payment_method_object->validate_fields(); + + // If errors were thrown, we need to abort. + NoticeHandler::convert_notices_to_exceptions( 'woocommerce_rest_payment_error' ); + + // Process Payment. + $gateway_result = $payment_method_object->process_payment( $context->order->get_id() ); + + // Restore $_POST data. + $_POST = $post_data; + + // If `process_payment` added notices, clear them. Notices are not displayed from the API -- payment should fail, + // and a generic notice will be shown instead if payment failed. + wc_clear_notices(); + + // Handle result. + $result->set_status( isset( $gateway_result['result'] ) && 'success' === $gateway_result['result'] ? 'success' : 'failure' ); + + // set payment_details from result. + $result->set_payment_details( array_merge( $result->payment_details, $gateway_result ) ); + $result->set_redirect_url( $gateway_result['redirect'] ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/AbstractPaymentMethodType.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/AbstractPaymentMethodType.php new file mode 100644 index 0000000..fcfc440 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/AbstractPaymentMethodType.php @@ -0,0 +1,82 @@ +settings[ $name ] ) ? $this->settings[ $name ] : $default; + } + + /** + * Returns the name of the payment method. + */ + public function get_name() { + return $this->name; + } + + /** + * Returns if this payment method should be active. If false, the scripts will not be enqueued. + * + * @return boolean + */ + public function is_active() { + return true; + } + + /** + * Returns an array of script handles to enqueue for this payment method in + * the frontend context + * + * @return string[] + */ + public function get_payment_method_script_handles() { + return []; + } + + /** + * Returns an array of script handles to enqueue for this payment method in + * the admin context + * + * @return string[] + */ + public function get_payment_method_script_handles_for_admin() { + return $this->get_payment_method_script_handles(); + } + + /** + * An array of key, value pairs of data made available to payment methods + * client side. + * + * @return array + */ + public function get_payment_method_data() { + return []; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/BankTransfer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/BankTransfer.php new file mode 100644 index 0000000..260a6cb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/BankTransfer.php @@ -0,0 +1,75 @@ +asset_api = $asset_api; + } + + /** + * Initializes the payment method type. + */ + public function initialize() { + $this->settings = get_option( 'woocommerce_bacs_settings', [] ); + } + + /** + * Returns if this payment method should be active. If false, the scripts will not be enqueued. + * + * @return boolean + */ + public function is_active() { + return filter_var( $this->get_setting( 'enabled', false ), FILTER_VALIDATE_BOOLEAN ); + } + + /** + * Returns an array of scripts/handles to be registered for this payment method. + * + * @return array + */ + public function get_payment_method_script_handles() { + $this->asset_api->register_script( + 'wc-payment-method-bacs', + 'build/wc-payment-method-bacs.js' + ); + return [ 'wc-payment-method-bacs' ]; + } + + /** + * Returns an array of key=>value pairs of data made available to the payment methods script. + * + * @return array + */ + public function get_payment_method_data() { + return [ + 'title' => $this->get_setting( 'title' ), + 'description' => $this->get_setting( 'description' ), + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/CashOnDelivery.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/CashOnDelivery.php new file mode 100644 index 0000000..cb6c938 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/CashOnDelivery.php @@ -0,0 +1,100 @@ +asset_api = $asset_api; + } + + /** + * Initializes the payment method type. + */ + public function initialize() { + $this->settings = get_option( 'woocommerce_cod_settings', [] ); + } + + /** + * Returns if this payment method should be active. If false, the scripts will not be enqueued. + * + * @return boolean + */ + public function is_active() { + return filter_var( $this->get_setting( 'enabled', false ), FILTER_VALIDATE_BOOLEAN ); + } + + /** + * Return enable_for_virtual option. + * + * @return boolean True if store allows COD payment for orders containing only virtual products. + */ + private function get_enable_for_virtual() { + return filter_var( $this->get_setting( 'enable_for_virtual', false ), FILTER_VALIDATE_BOOLEAN ); + } + + /** + * Return enable_for_methods option. + * + * @return array Array of shipping methods (string ids) that allow COD. (If empty, all support COD.) + */ + private function get_enable_for_methods() { + $enable_for_methods = $this->get_setting( 'enable_for_methods', [] ); + if ( '' === $enable_for_methods ) { + return []; + } + return $enable_for_methods; + } + + + /** + * Returns an array of scripts/handles to be registered for this payment method. + * + * @return array + */ + public function get_payment_method_script_handles() { + $this->asset_api->register_script( + 'wc-payment-method-cod', + 'build/wc-payment-method-cod.js' + ); + return [ 'wc-payment-method-cod' ]; + } + + /** + * Returns an array of key=>value pairs of data made available to the payment methods script. + * + * @return array + */ + public function get_payment_method_data() { + return [ + 'title' => $this->get_setting( 'title' ), + 'description' => $this->get_setting( 'description' ), + 'enableForVirtual' => $this->get_enable_for_virtual(), + 'enableForShippingMethods' => $this->get_enable_for_methods(), + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/Cheque.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/Cheque.php new file mode 100644 index 0000000..0702aed --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/Cheque.php @@ -0,0 +1,78 @@ +asset_api = $asset_api; + } + + /** + * Initializes the payment method type. + */ + public function initialize() { + $this->settings = get_option( 'woocommerce_cheque_settings', [] ); + } + + /** + * Returns if this payment method should be active. If false, the scripts will not be enqueued. + * + * @return boolean + */ + public function is_active() { + return filter_var( $this->get_setting( 'enabled', false ), FILTER_VALIDATE_BOOLEAN ); + } + + /** + * Returns an array of scripts/handles to be registered for this payment method. + * + * @return array + */ + public function get_payment_method_script_handles() { + $this->asset_api->register_script( + 'wc-payment-method-cheque', + 'build/wc-payment-method-cheque.js' + ); + return [ 'wc-payment-method-cheque' ]; + } + + /** + * Returns an array of key=>value pairs of data made available to the payment methods script. + * + * @return array + */ + public function get_payment_method_data() { + return [ + 'title' => $this->get_setting( 'title' ), + 'description' => $this->get_setting( 'description' ), + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/PayPal.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/PayPal.php new file mode 100644 index 0000000..3e87acf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/PayPal.php @@ -0,0 +1,78 @@ +asset_api = $asset_api; + } + + /** + * Initializes the payment method type. + */ + public function initialize() { + $this->settings = get_option( 'woocommerce_paypal_settings', [] ); + } + + /** + * Returns if this payment method should be active. If false, the scripts will not be enqueued. + * + * @return boolean + */ + public function is_active() { + return filter_var( $this->get_setting( 'enabled', false ), FILTER_VALIDATE_BOOLEAN ); + } + + /** + * Returns an array of scripts/handles to be registered for this payment method. + * + * @return array + */ + public function get_payment_method_script_handles() { + $this->asset_api->register_script( + 'wc-payment-method-paypal', + 'build/wc-payment-method-paypal.js' + ); + return [ 'wc-payment-method-paypal' ]; + } + + /** + * Returns an array of key=>value pairs of data made available to the payment methods script. + * + * @return array + */ + public function get_payment_method_data() { + return [ + 'title' => $this->get_setting( 'title' ), + 'description' => $this->get_setting( 'description' ), + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/Stripe.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/Stripe.php new file mode 100644 index 0000000..f04a805 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/Integrations/Stripe.php @@ -0,0 +1,298 @@ +asset_api = $asset_api; + add_action( 'woocommerce_rest_checkout_process_payment_with_context', [ $this, 'add_payment_request_order_meta' ], 8, 2 ); + add_action( 'woocommerce_rest_checkout_process_payment_with_context', [ $this, 'add_stripe_intents' ], 9999, 2 ); + } + + /** + * Initializes the payment method type. + */ + public function initialize() { + $this->settings = get_option( 'woocommerce_stripe_settings', [] ); + } + + /** + * Returns if this payment method should be active. If false, the scripts will not be enqueued. + * + * @return boolean + */ + public function is_active() { + return ! empty( $this->settings['enabled'] ) && 'yes' === $this->settings['enabled']; + } + + /** + * Returns an array of scripts/handles to be registered for this payment method. + * + * @return array + */ + public function get_payment_method_script_handles() { + $this->asset_api->register_script( + 'wc-payment-method-stripe', + 'build/wc-payment-method-stripe.js', + [] + ); + + return [ 'wc-payment-method-stripe' ]; + } + + /** + * Returns an array of key=>value pairs of data made available to the payment methods script. + * + * @return array + */ + public function get_payment_method_data() { + return [ + 'stripeTotalLabel' => $this->get_total_label(), + 'publicKey' => $this->get_publishable_key(), + 'allowPrepaidCard' => $this->get_allow_prepaid_card(), + 'button' => [ + 'type' => $this->get_button_type(), + 'theme' => $this->get_button_theme(), + 'height' => $this->get_button_height(), + 'locale' => $this->get_button_locale(), + ], + 'inline_cc_form' => $this->get_inline_cc_form(), + 'icons' => $this->get_icons(), + 'allowSavedCards' => $this->get_allow_saved_cards(), + 'allowPaymentRequest' => $this->get_allow_payment_request(), + ]; + } + + /** + * Determine if store allows cards to be saved during checkout. + * + * @return bool True if merchant allows shopper to save card (payment method) during checkout). + */ + private function get_allow_saved_cards() { + $saved_cards = isset( $this->settings['saved_cards'] ) ? $this->settings['saved_cards'] : false; + // This assumes that Stripe supports `tokenization` - currently this is true, based on + // https://github.com/woocommerce/woocommerce-gateway-stripe/blob/master/includes/class-wc-gateway-stripe.php#L95 . + // See https://github.com/woocommerce/woocommerce-gateway-stripe/blob/ad19168b63df86176cbe35c3e95203a245687640/includes/class-wc-gateway-stripe.php#L271 and + // https://github.com/woocommerce/woocommerce/wiki/Payment-Token-API . + return apply_filters( 'wc_stripe_display_save_payment_method_checkbox', filter_var( $saved_cards, FILTER_VALIDATE_BOOLEAN ) ); + } + + /** + * Returns the label to use accompanying the total in the stripe statement. + * + * @return string Statement descriptor. + */ + private function get_total_label() { + return ! empty( $this->settings['statement_descriptor'] ) ? WC_Stripe_Helper::clean_statement_descriptor( $this->settings['statement_descriptor'] ) : ''; + } + + /** + * Returns the publishable api key for the Stripe service. + * + * @return string Public api key. + */ + private function get_publishable_key() { + $test_mode = ( ! empty( $this->settings['testmode'] ) && 'yes' === $this->settings['testmode'] ); + $setting_key = $test_mode ? 'test_publishable_key' : 'publishable_key'; + return ! empty( $this->settings[ $setting_key ] ) ? $this->settings[ $setting_key ] : ''; + } + + /** + * Returns whether to allow prepaid cards for payments. + * + * @return bool True means to allow prepaid card (default). + */ + private function get_allow_prepaid_card() { + return apply_filters( 'wc_stripe_allow_prepaid_card', true ); + } + + /** + * Determine if store allows Payment Request buttons - e.g. Apple Pay / Chrome Pay. + * + * @return bool True if merchant has opted into payment request. + */ + private function get_allow_payment_request() { + $option = isset( $this->settings['payment_request'] ) ? $this->settings['payment_request'] : false; + return filter_var( $option, FILTER_VALIDATE_BOOLEAN ); + } + + /** + * Return the button type for the payment button. + * + * @return string Defaults to 'default'. + */ + private function get_button_type() { + return isset( $this->settings['payment_request_button_type'] ) ? $this->settings['payment_request_button_type'] : 'default'; + } + + /** + * Return the theme to use for the payment button. + * + * @return string Defaults to 'dark'. + */ + private function get_button_theme() { + return isset( $this->settings['payment_request_button_theme'] ) ? $this->settings['payment_request_button_theme'] : 'dark'; + } + + /** + * Return the height for the payment button. + * + * @return string A pixel value for the height (defaults to '64'). + */ + private function get_button_height() { + return isset( $this->settings['payment_request_button_height'] ) ? str_replace( 'px', '', $this->settings['payment_request_button_height'] ) : '64'; + } + + /** + * Return the inline cc option. + * + * @return boolean True if the inline CC form option is enabled. + */ + private function get_inline_cc_form() { + return isset( $this->settings['inline_cc_form'] ) && 'yes' === $this->settings['inline_cc_form']; + } + + /** + * Return the locale for the payment button. + * + * @return string Defaults to en_US. + */ + private function get_button_locale() { + return apply_filters( 'wc_stripe_payment_request_button_locale', substr( get_locale(), 0, 2 ) ); + } + + /** + * Return the icons urls. + * + * @return array Arrays of icons metadata. + */ + private function get_icons() { + $icons_src = [ + 'visa' => [ + 'src' => WC_STRIPE_PLUGIN_URL . '/assets/images/visa.svg', + 'alt' => __( 'Visa', 'woocommerce' ), + ], + 'amex' => [ + 'src' => WC_STRIPE_PLUGIN_URL . '/assets/images/amex.svg', + 'alt' => __( 'American Express', 'woocommerce' ), + ], + 'mastercard' => [ + 'src' => WC_STRIPE_PLUGIN_URL . '/assets/images/mastercard.svg', + 'alt' => __( 'Mastercard', 'woocommerce' ), + ], + ]; + + if ( 'USD' === get_woocommerce_currency() ) { + $icons_src['discover'] = [ + 'src' => WC_STRIPE_PLUGIN_URL . '/assets/images/discover.svg', + 'alt' => __( 'Discover', 'woocommerce' ), + ]; + $icons_src['jcb'] = [ + 'src' => WC_STRIPE_PLUGIN_URL . '/assets/images/jcb.svg', + 'alt' => __( 'JCB', 'woocommerce' ), + ]; + $icons_src['diners'] = [ + 'src' => WC_STRIPE_PLUGIN_URL . '/assets/images/diners.svg', + 'alt' => __( 'Diners', 'woocommerce' ), + ]; + } + return $icons_src; + } + + /** + * Add payment request data to the order meta as hooked on the + * woocommerce_rest_checkout_process_payment_with_context action. + * + * @param PaymentContext $context Holds context for the payment. + * @param PaymentResult $result Result object for the payment. + */ + public function add_payment_request_order_meta( PaymentContext $context, PaymentResult &$result ) { + $data = $context->payment_data; + if ( ! empty( $data['payment_request_type'] ) && 'stripe' === $context->payment_method ) { + // phpcs:ignore WordPress.Security.NonceVerification + $post_data = $_POST; + $_POST = $context->payment_data; + WC_Stripe_Payment_Request::add_order_meta( $context->order->id, $context->payment_data ); + $_POST = $post_data; + } + + // hook into stripe error processing so that we can capture the error to + // payment details (which is added to notices and thus not helpful for + // this context). + if ( 'stripe' === $context->payment_method ) { + add_action( + 'wc_gateway_stripe_process_payment_error', + function( $error ) use ( &$result ) { + $payment_details = $result->payment_details; + $payment_details['errorMessage'] = $error->getLocalizedMessage(); + $result->set_payment_details( $payment_details ); + } + ); + } + } + + /** + * Handles any potential stripe intents on the order that need handled. + * + * This is configured to execute after legacy payment processing has + * happened on the woocommerce_rest_checkout_process_payment_with_context + * action hook. + * + * @param PaymentContext $context Holds context for the payment. + * @param PaymentResult $result Result object for the payment. + */ + public function add_stripe_intents( PaymentContext $context, PaymentResult &$result ) { + if ( 'stripe' === $context->payment_method + && ( + ! empty( $result->payment_details['payment_intent_secret'] ) + || ! empty( $result->payment_details['setup_intent_secret'] ) + ) + ) { + $payment_details = $result->payment_details; + $payment_details['verification_endpoint'] = add_query_arg( + [ + 'order' => $context->order->get_id(), + 'nonce' => wp_create_nonce( 'wc_stripe_confirm_pi' ), + 'redirect_to' => rawurlencode( $result->redirect_url ), + ], + home_url() . \WC_Ajax::get_endpoint( 'wc_stripe_verify_intent' ) + ); + $result->set_payment_details( $payment_details ); + $result->set_status( 'success' ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/PaymentContext.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/PaymentContext.php new file mode 100644 index 0000000..66b23a2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/PaymentContext.php @@ -0,0 +1,84 @@ +$name; + } + return null; + } + + /** + * Set the chosen payment method ID context. + * + * @param string $payment_method Payment method ID. + */ + public function set_payment_method( $payment_method ) { + $this->payment_method = (string) $payment_method; + } + + /** + * Retrieve the payment method instance for the current set payment method. + * + * @return {\WC_Payment_Gateway|null} An instance of the payment gateway if it exists. + */ + public function get_payment_method_instance() { + $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); + if ( ! isset( $available_gateways[ $this->payment_method ] ) ) { + return; + } + return $available_gateways[ $this->payment_method ]; + } + + /** + * Set the order context. + * + * @param \WC_Order $order Order object. + */ + public function set_order( \WC_Order $order ) { + $this->order = $order; + } + + /** + * Set payment data context. + * + * @param array $payment_data Array of key value pairs of data. + */ + public function set_payment_data( $payment_data = [] ) { + $this->payment_data = []; + + foreach ( $payment_data as $key => $value ) { + $this->payment_data[ (string) $key ] = (string) $value; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/PaymentMethodRegistry.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/PaymentMethodRegistry.php new file mode 100644 index 0000000..3525ad0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/PaymentMethodRegistry.php @@ -0,0 +1,161 @@ + $instance` pairs. + * + * @var PaymentMethodTypeInterface[] + */ + private $registered_payment_methods = []; + + /** + * Registers a payment method. + * + * @param PaymentMethodTypeInterface $payment_method_type An instance of PaymentMethodTypeInterface. + * + * @return boolean True means registered successfully. + */ + public function register( PaymentMethodTypeInterface $payment_method_type ) { + $name = $payment_method_type->get_name(); + if ( $this->is_registered( $name ) ) { + /* translators: %s: Payment method name. */ + _doing_it_wrong( __METHOD__, esc_html( sprintf( __( 'Payment method "%s" is already registered.', 'woocommerce' ), $name ) ), '2.5.0' ); + return false; + } + $this->registered_payment_methods[ $name ] = $payment_method_type; + return true; + } + + /** + * Initializes all payment method types. + */ + public function initialize() { + /** + * Hook: payment_method_type_registration. + * + * Runs before payment methods are initialized allowing new methods to be registered for use. + * + * @param PaymentMethodRegistry $this Instance of the PaymentMethodRegistry class which exposes the + * PaymentMethodRegistry::register() method. + */ + do_action( 'woocommerce_blocks_payment_method_type_registration', $this ); + + $registered_payment_method_types = $this->get_all_registered(); + + foreach ( $registered_payment_method_types as $registered_type ) { + $registered_type->initialize(); + } + } + + /** + * Un-register a payment method. + * + * @param string|PaymentMethodTypeInterface $name Payment method name, or alternatively a PaymentMethodTypeInterface instance. + * @return boolean True means unregistered successfully. + */ + public function unregister( $name ) { + if ( $name instanceof PaymentMethodTypeInterface ) { + $name = $name->get_name(); + } + + if ( ! $this->is_registered( $name ) ) { + /* translators: %s: Payment method name. */ + _doing_it_wrong( __METHOD__, esc_html( sprintf( __( 'Payment method "%s" is not registered.', 'woocommerce' ), $name ) ), '2.5.0' ); + return false; + } + + $unregistered_payment_method = $this->registered_payment_methods[ $name ]; + unset( $this->registered_payment_methods[ $name ] ); + + return $unregistered_payment_method; + } + + /** + * Retrieves a registered payment method. + * + * @param string $name Payment method name. + * @return PaymentMethodTypeInterface|null The registered payment method, or null if it is not registered. + */ + public function get_registered( $name ) { + if ( ! $this->is_registered( $name ) ) { + return null; + } + + return $this->registered_payment_methods[ $name ]; + } + + /** + * Retrieves all registered payment methods. + * + * @return PaymentMethodTypeInterface[] + */ + public function get_all_registered() { + return $this->registered_payment_methods; + } + + /** + * Checks if a payment method is registered. + * + * @param string $name Payment method name. + * @return bool True if the payment method is registered, false otherwise. + */ + public function is_registered( $name ) { + return isset( $this->registered_payment_methods[ $name ] ); + } + + /** + * Retrieves all registered payment methods that are also active. + * + * @return PaymentMethodTypeInterface[] + */ + public function get_all_active_registered() { + return array_filter( + $this->get_all_registered(), + function( $payment_method ) { + return $payment_method->is_active(); + } + ); + } + + /** + * Gets an array of all registered payment method script handles. + * + * @return string[] + */ + public function get_all_registered_script_handles() { + $script_handles = []; + $payment_methods = $this->get_all_active_registered(); + + foreach ( $payment_methods as $payment_method ) { + $script_handles = array_merge( + $script_handles, + is_admin() ? $payment_method->get_payment_method_script_handles_for_admin() : $payment_method->get_payment_method_script_handles() + ); + } + + return array_unique( array_filter( $script_handles ) ); + } + + /** + * Gets an array of all registered payment method script data. + * + * @return array + */ + public function get_all_registered_script_data() { + $script_data = []; + $payment_methods = $this->get_all_active_registered(); + + foreach ( $payment_methods as $payment_method ) { + $script_data[ $payment_method->get_name() . '_data' ] = $payment_method->get_payment_method_data(); + } + + return array_filter( $script_data ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/PaymentMethodTypeInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/PaymentMethodTypeInterface.php new file mode 100644 index 0000000..71e6b3e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Payments/PaymentMethodTypeInterface.php @@ -0,0 +1,48 @@ +set_status( $status ); + } + } + + /** + * Magic getter for protected properties. + * + * @param string $name Property name. + */ + public function __get( $name ) { + if ( in_array( $name, [ 'status', 'payment_details', 'redirect_url' ], true ) ) { + return $this->$name; + } + return null; + } + + /** + * Set payment status. + * + * @throws \Exception When an invalid status is provided. + * + * @param string $payment_status Status to set. + */ + public function set_status( $payment_status ) { + if ( ! in_array( $payment_status, $this->valid_statuses, true ) ) { + throw new \Exception( sprintf( 'Invalid payment status %s. Use one of %s', $payment_status, implode( ', ', $this->valid_statuses ) ) ); + } + $this->status = $payment_status; + } + + /** + * Set payment details. + * + * @param array $payment_details Array of key value pairs of data. + */ + public function set_payment_details( $payment_details = [] ) { + $this->payment_details = []; + + foreach ( $payment_details as $key => $value ) { + $this->payment_details[ (string) $key ] = (string) $value; + } + } + + /** + * Set redirect URL. + * + * @param array $redirect_url URL to redirect the customer to after checkout. + */ + public function set_redirect_url( $redirect_url = [] ) { + $this->redirect_url = esc_url_raw( $redirect_url ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/AbstractDependencyType.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/AbstractDependencyType.php new file mode 100644 index 0000000..b6fd29a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/AbstractDependencyType.php @@ -0,0 +1,54 @@ +callable_or_value = $callable_or_value; + } + + /** + * Resolver for the internal dependency value. + * + * @param Container $container The Dependency Injection Container. + * + * @return mixed + */ + protected function resolve_value( Container $container ) { + $callback = $this->callable_or_value; + return \is_callable( $callback ) + ? $callback( $container ) + : $callback; + } + + /** + * Retrieves the value stored internally for this DependencyType + * + * @param Container $container The Dependency Injection Container. + * + * @return void + */ + abstract public function get( Container $container ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/Container.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/Container.php new file mode 100644 index 0000000..9776a60 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/Container.php @@ -0,0 +1,98 @@ +register( MyClass::class, $container->factory( $mycallback ) ); + * ``` + * + * @param Closure $instantiation_callback This will be invoked when the + * dependency is required. It will + * receive an instance of this + * container so the callback can + * retrieve dependencies from the + * container. + * + * @return FactoryType An instance of the FactoryType dependency. + */ + public function factory( Closure $instantiation_callback ) { + return new FactoryType( $instantiation_callback ); + } + + /** + * Interface for registering a new dependency with the container. + * + * By default, the $value will be added as a shared dependency. This means + * that it will be a single instance shared among any other classes having + * that dependency. + * + * If you want a new instance every time it's required, then wrap the value + * in a call to the factory method (@see Container::factory for example) + * + * Note: Currently if the provided id already is registered in the container, + * the provided value is ignored. + * + * @param string $id A unique string identifier for the provided value. + * Typically it's the fully qualified name for the + * dependency. + * @param mixed $value The value for the dependency. Typically, this is a + * closure that will create the class instance needed. + */ + public function register( $id, $value ) { + if ( empty( $this->registry[ $id ] ) ) { + if ( ! $value instanceof FactoryType ) { + $value = new SharedType( $value ); + } + $this->registry[ $id ] = $value; + } + } + + /** + * Interface for retrieving the dependency stored in the container for the + * given identifier. + * + * @param string $id The identifier for the dependency being retrieved. + * @throws Exception If there is no dependency for the given identifier in + * the container. + * + * @return mixed Typically a class instance. + */ + public function get( $id ) { + if ( ! isset( $this->registry[ $id ] ) ) { + // this is a developer facing exception, hence it is not localized. + throw new Exception( + sprintf( + 'Cannot construct an instance of %s because it has not been registered.', + $id + ) + ); + } + return $this->registry[ $id ]->get( $this ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/FactoryType.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/FactoryType.php new file mode 100644 index 0000000..ad99403 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/FactoryType.php @@ -0,0 +1,21 @@ +resolve_value( $container ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/SharedType.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/SharedType.php new file mode 100644 index 0000000..2b56e4d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Registry/SharedType.php @@ -0,0 +1,32 @@ +shared_instance ) ) { + $this->shared_instance = $this->resolve_value( $container ); + } + return $this->shared_instance; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/RestApi.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/RestApi.php new file mode 100644 index 0000000..d03d5ed --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/RestApi.php @@ -0,0 +1,87 @@ +init(); + } + + /** + * Initialize class features. + */ + protected function init() { + add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 ); + add_filter( 'rest_authentication_errors', array( $this, 'store_api_authentication' ) ); + } + + /** + * Register REST API routes. + */ + public function register_rest_routes() { + $schemas = new SchemaController(); + $routes = new RoutesController( $schemas ); + $routes->register_routes(); + } + + /** + * Get routes for a namespace. + * + * @param string $namespace Namespace to retrieve. + * @return array|null + */ + public function get_routes_from_namespace( $namespace ) { + $rest_server = rest_get_server(); + $namespace_index = $rest_server->get_namespace_index( + [ + 'namespace' => $namespace, + 'context' => 'view', + ] + ); + + $response_data = $namespace_index->get_data(); + + return isset( $response_data['routes'] ) ? $response_data['routes'] : null; + } + + /** + * The Store API does not require authentication. + * + * @param \WP_Error|mixed $result Error from another authentication handler, null if we should handle it, or another value if not. + * @return \WP_Error|null|bool + */ + public function store_api_authentication( $result ) { + // Pass through errors from other authentication methods used before this one. + if ( ! empty( $result ) || ! self::is_request_to_store_api() ) { + return $result; + } + return true; + } + + /** + * Check if is request to the Store API. + * + * @return bool + */ + protected function is_request_to_store_api() { + if ( empty( $_SERVER['REQUEST_URI'] ) ) { + return false; + } + + $rest_prefix = trailingslashit( rest_get_url_prefix() ); + $request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ); + + return false !== strpos( $request_uri, $rest_prefix . 'wc/store' ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractCartRoute.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractCartRoute.php new file mode 100644 index 0000000..272656d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractCartRoute.php @@ -0,0 +1,77 @@ +maybe_load_cart(); + $this->maybe_recalculate_totals(); + return parent::get_response( $request ); + } + + /** + * If shipping/tax data has changed on the server since last calculation, trigger a recalculation now. + * + * @return void + */ + protected function maybe_recalculate_totals() { + $current_hash = wc()->session->get( 'store_api_calculation_hash', '' ); + $new_hash = md5( + wp_json_encode( + [ + \WC_Cache_Helper::get_transient_version( 'shipping' ), + wc()->cart->get_cart_hash(), + ] + ) + ); + if ( ! hash_equals( $current_hash, $new_hash ) ) { + wc()->session->set( 'store_api_calculation_hash', $new_hash ); + wc()->cart->get_cart(); + wc()->cart->calculate_shipping(); + wc()->cart->calculate_totals(); + } + } + + /** + * Get route response when something went wrong. + * + * @param string $error_code String based error code. + * @param string $error_message User facing error message. + * @param int $http_status_code HTTP status. Defaults to 500. + * @param array $additional_data Extra data (key value pairs) to expose in the error response. + * @return \WP_Error WP Error object. + */ + protected function get_route_error_response( $error_code, $error_message, $http_status_code = 500, $additional_data = [] ) { + switch ( $http_status_code ) { + case 409: + // If there was a conflict, return the cart so the client can resolve it. + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + + return new \WP_Error( + $error_code, + $error_message, + array_merge( + $additional_data, + [ + 'status' => $http_status_code, + 'cart' => $this->schema->get_item_response( $cart ), + ] + ) + ); + } + return new \WP_Error( $error_code, $error_message, [ 'status' => $http_status_code ] ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractRoute.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractRoute.php new file mode 100644 index 0000000..329d023 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractRoute.php @@ -0,0 +1,275 @@ +schema = $schema; + } + + /** + * Get the namespace for this route. + * + * @return string + */ + public function get_namespace() { + return 'wc/store'; + } + + /** + * Get item schema properties. + * + * @return array + */ + public function get_item_schema() { + return $this->schema->get_item_schema(); + } + + /** + * Get the route response based on the type of request. + * + * @param \WP_REST_Request $request Request object. + * @return \WP_Error|\WP_REST_Response + */ + public function get_response( \WP_REST_Request $request ) { + $response = null; + try { + if ( 'GET' !== $request->get_method() ) { + $this->check_nonce( $request ); + } + switch ( $request->get_method() ) { + case 'POST': + $response = $this->get_route_post_response( $request ); + break; + case 'PUT': + case 'PATCH': + $response = $this->get_route_update_response( $request ); + break; + case 'DELETE': + $response = $this->get_route_delete_response( $request ); + break; + default: + $response = $this->get_route_response( $request ); + break; + } + if ( 'GET' !== $request->get_method() && ! is_wp_error( $response ) ) { + $response->header( 'X-WC-Store-API-Nonce', wp_create_nonce( 'wc_store_api' ) ); + } + } catch ( RouteException $error ) { + $response = $this->get_route_error_response( $error->getErrorCode(), $error->getMessage(), $error->getCode(), $error->getAdditionalData() ); + } catch ( \Exception $error ) { + $response = $this->get_route_error_response( 'unknown_server_error', $error->getMessage(), 500 ); + } + return $response; + } + + /** + * For non-GET endpoints, require and validate a nonce to prevent CSRF attacks. + * + * Nonces will mismatch if the logged in session cookie is different! If using a client to test, set this cookie + * to match the logged in cookie in your browser. + * + * @throws RouteException On error. + * + * @param \WP_REST_Request $request Request object. + */ + protected function check_nonce( \WP_REST_Request $request ) { + $nonce = $request->get_header( 'X-WC-Store-API-Nonce' ); + + if ( apply_filters( 'woocommerce_store_api_disable_nonce_check', false ) ) { + return; + } + + if ( null === $nonce ) { + throw new RouteException( 'woocommerce_rest_missing_nonce', __( 'Missing the X-WC-Store-API-Nonce header. This endpoint requires a valid nonce.', 'woocommerce' ), 401 ); + } + + $valid_nonce = wp_verify_nonce( $nonce, 'wc_store_api' ); + + if ( ! $valid_nonce ) { + throw new RouteException( 'woocommerce_rest_invalid_nonce', __( 'X-WC-Store-API-Nonce is invalid.', 'woocommerce' ), 403 ); + } + } + + /** + * Get route response for GET requests. + * + * When implemented, should return a \WP_REST_Response. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + */ + protected function get_route_response( \WP_REST_Request $request ) { + throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); + } + + /** + * Get route response for POST requests. + * + * When implemented, should return a \WP_REST_Response. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); + } + + /** + * Get route response for PUT requests. + * + * When implemented, should return a \WP_REST_Response. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + */ + protected function get_route_update_response( \WP_REST_Request $request ) { + throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); + } + + /** + * Get route response for DELETE requests. + * + * When implemented, should return a \WP_REST_Response. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + */ + protected function get_route_delete_response( \WP_REST_Request $request ) { + throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); + } + + /** + * Get route response when something went wrong. + * + * @param string $error_code String based error code. + * @param string $error_message User facing error message. + * @param int $http_status_code HTTP status. Defaults to 500. + * @param array $additional_data Extra data (key value pairs) to expose in the error response. + * @return \WP_Error WP Error object. + */ + protected function get_route_error_response( $error_code, $error_message, $http_status_code = 500, $additional_data = [] ) { + return new \WP_Error( $error_code, $error_message, array_merge( $additional_data, [ 'status' => $http_status_code ] ) ); + } + + /** + * Prepare a single item for response. + * + * @param mixed $item Item to format to schema. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, \WP_REST_Request $request ) { + $response = rest_ensure_response( $this->schema->get_item_response( $item ) ); + $response->add_links( $this->prepare_links( $item, $request ) ); + + return $response; + } + + /** + * Retrieves the context param. + * + * Ensures consistent descriptions between endpoints, and populates enum from schema. + * + * @param array $args Optional. Additional arguments for context parameter. Default empty array. + * @return array Context parameter details. + */ + protected function get_context_param( $args = array() ) { + $param_details = array( + 'description' => __( 'Scope under which the request is made; determines fields present in response.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $schema = $this->get_item_schema(); + + if ( empty( $schema['properties'] ) ) { + return array_merge( $param_details, $args ); + } + + $contexts = array(); + + foreach ( $schema['properties'] as $attributes ) { + if ( ! empty( $attributes['context'] ) ) { + $contexts = array_merge( $contexts, $attributes['context'] ); + } + } + + if ( ! empty( $contexts ) ) { + $param_details['enum'] = array_unique( $contexts ); + rsort( $param_details['enum'] ); + } + + return array_merge( $param_details, $args ); + } + + /** + * Prepares a response for insertion into a collection. + * + * @param \WP_REST_Response $response Response object. + * @return array|mixed Response data, ready for insertion into collection data. + */ + protected function prepare_response_for_collection( \WP_REST_Response $response ) { + $data = (array) $response->get_data(); + $server = rest_get_server(); + $links = $server::get_compact_response_links( $response ); + + if ( ! empty( $links ) ) { + $data['_links'] = $links; + } + + return $data; + } + + /** + * Prepare links for the request. + * + * @param mixed $item Item to prepare. + * @param \WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $item, $request ) { + return []; + } + + /** + * Retrieves the query params for the collections. + * + * @return array Query parameters for the collection. + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param(), + ); + } + + /** + * Makes the cart and sessions available to a route by loading them from core. + */ + protected function maybe_load_cart() { + if ( ! did_action( 'woocommerce_load_cart_from_session' ) && function_exists( 'wc_load_cart' ) ) { + include_once WC_ABSPATH . 'includes/wc-cart-functions.php'; + include_once WC_ABSPATH . 'includes/wc-notice-functions.php'; + wc_load_cart(); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractTermsRoute.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractTermsRoute.php new file mode 100644 index 0000000..2f3395f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractTermsRoute.php @@ -0,0 +1,152 @@ +get_context_param(); + $params['context']['default'] = 'view'; + + $params['page'] = array( + 'description' => __( 'Current page of the collection.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set. Defaults to no limit if left blank.', 'woocommerce' ), + 'type' => 'integer', + 'minimum' => 0, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['search'] = array( + 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + + $params['include'] = array( + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + 'sanitize_callback' => 'wp_parse_id_list', + ); + + $params['order'] = array( + 'description' => __( 'Sort ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'asc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['orderby'] = array( + 'description' => __( 'Sort by term property.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'name', + 'enum' => array( + 'name', + 'slug', + 'count', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['hide_empty'] = array( + 'description' => __( 'If true, empty terms will not be returned.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => true, + ); + + return $params; + } + + /** + * Get terms matching passed in args. + * + * @param string $taxonomy Taxonomy to get terms from. + * @param \WP_REST_Request $request Request object. + * + * @return \WP_REST_Response + */ + protected function get_terms_response( $taxonomy, $request ) { + $page = (int) $request['page']; + $per_page = $request['per_page'] ? $request['per_page'] : 0; + $prepared_args = array( + 'taxonomy' => $taxonomy, + 'exclude' => $request['exclude'], + 'include' => $request['include'], + 'order' => $request['order'], + 'orderby' => $request['orderby'], + 'hide_empty' => (bool) $request['hide_empty'], + 'number' => $per_page, + 'offset' => $per_page > 0 ? ( $page - 1 ) * $per_page : 0, + 'search' => $request['search'], + ); + + $term_query = new WP_Term_Query(); + $objects = $term_query->query( $prepared_args ); + $return = []; + + foreach ( $objects as $object ) { + $data = $this->prepare_item_for_response( $object, $request ); + $return[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $return ); + + // See if pagination is needed before calculating. + if ( $per_page > 0 && ( count( $objects ) === $per_page || $page > 1 ) ) { + $term_count = $this->get_term_count( $taxonomy, $prepared_args ); + $response = ( new Pagination() )->add_headers( $response, $request, $term_count, ceil( $term_count / $per_page ) ); + } + + return $response; + } + + /** + * Get count of terms for current query. + * + * @param string $taxonomy Taxonomy to get terms from. + * @param array $args Array of args to pass to wp_count_terms. + * @return int + */ + protected function get_term_count( $taxonomy, $args ) { + $count_args = $args; + unset( $count_args['number'], $count_args['offset'] ); + return (int) wp_count_terms( $taxonomy, $count_args ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/Cart.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/Cart.php new file mode 100644 index 0000000..6308189 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/Cart.php @@ -0,0 +1,53 @@ + \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'context' => $this->get_context_param( [ 'default' => 'view' ] ), + ], + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Handle the request and return a valid response for this endpoint. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + + return rest_ensure_response( $this->schema->get_item_response( $cart ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartAddItem.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartAddItem.php new file mode 100644 index 0000000..eb273c7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartAddItem.php @@ -0,0 +1,102 @@ + \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'id' => [ + 'description' => __( 'The cart item product or variation ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'arg_options' => [ + 'sanitize_callback' => 'absint', + ], + ], + 'quantity' => [ + 'description' => __( 'Quantity of this item in the cart.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'arg_options' => [ + 'sanitize_callback' => 'wc_stock_amount', + ], + ], + 'variation' => [ + 'description' => __( 'Chosen attributes (for variations).', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'attribute' => [ + 'description' => __( 'Variation attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'value' => [ + 'description' => __( 'Variation attribute value.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + ], + ], + ], + ], + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Handle the request and return a valid response for this endpoint. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + // Do not allow key to be specified during creation. + if ( ! empty( $request['key'] ) ) { + throw new RouteException( 'woocommerce_rest_cart_item_exists', __( 'Cannot create an existing cart item.', 'woocommerce' ), 400 ); + } + + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + $result = $controller->add_to_cart( + [ + 'id' => $request['id'], + 'quantity' => $request['quantity'], + 'variation' => $request['variation'], + ] + ); + + $response = rest_ensure_response( $this->schema->get_item_response( $cart ) ); + $response->set_status( 201 ); + return $response; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartApplyCoupon.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartApplyCoupon.php new file mode 100644 index 0000000..b607d2b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartApplyCoupon.php @@ -0,0 +1,67 @@ + \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'code' => [ + 'description' => __( 'Unique identifier for the coupon within the cart.', 'woocommerce' ), + 'type' => 'string', + ], + ], + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Handle the request and return a valid response for this endpoint. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + if ( ! wc_coupons_enabled() ) { + throw new RouteException( 'woocommerce_rest_cart_coupon_disabled', __( 'Coupons are disabled.', 'woocommerce' ), 404 ); + } + + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + $coupon_code = wc_format_coupon_code( wp_unslash( $request['code'] ) ); + + try { + $controller->apply_coupon( $coupon_code ); + } catch ( \WC_REST_Exception $e ) { + throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); + } + + return rest_ensure_response( $this->schema->get_item_response( $cart ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartCoupons.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartCoupons.php new file mode 100644 index 0000000..f22144e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartCoupons.php @@ -0,0 +1,137 @@ + \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'context' => $this->get_context_param( [ 'default' => 'view' ] ), + ], + ], + [ + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), + ], + [ + 'methods' => \WP_REST_Server::DELETABLE, + 'permission_callback' => '__return_true', + 'callback' => [ $this, 'get_response' ], + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a collection of cart coupons. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $cart_coupons = $controller->get_cart_coupons(); + $items = []; + + foreach ( $cart_coupons as $coupon_code ) { + $response = rest_ensure_response( $this->schema->get_item_response( $coupon_code ) ); + $response->add_links( $this->prepare_links( $coupon_code, $request ) ); + + $response = $this->prepare_response_for_collection( $response ); + $items[] = $response; + } + + $response = rest_ensure_response( $items ); + + return $response; + } + + /** + * Add a coupon to the cart and return the result. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + if ( ! wc_coupons_enabled() ) { + throw new RouteException( 'woocommerce_rest_cart_coupon_disabled', __( 'Coupons are disabled.', 'woocommerce' ), 404 ); + } + + $controller = new CartController(); + + try { + $controller->apply_coupon( $request['code'] ); + } catch ( \WC_REST_Exception $e ) { + throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); + } + + $response = $this->prepare_item_for_response( $request['code'], $request ); + $response->set_status( 201 ); + + return $response; + } + + /** + * Deletes all coupons in the cart. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_delete_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + $cart->remove_coupons(); + $cart->calculate_totals(); + + return new \WP_REST_Response( [], 200 ); + } + + /** + * Prepare links for the request. + * + * @param string $coupon_code Coupon code. + * @param \WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $coupon_code, $request ) { + $base = $this->get_namespace() . $this->get_path(); + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $coupon_code ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + return $links; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartCouponsByCode.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartCouponsByCode.php new file mode 100644 index 0000000..b545b07 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartCouponsByCode.php @@ -0,0 +1,88 @@ +[\w-]+)'; + } + + /** + * Get method arguments for this REST route. + * + * @return array An array of endpoints. + */ + public function get_args() { + return [ + 'args' => [ + 'code' => [ + 'description' => __( 'Unique identifier for the coupon within the cart.', 'woocommerce' ), + 'type' => 'string', + ], + ], + [ + 'methods' => \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'context' => $this->get_context_param( [ 'default' => 'view' ] ), + ], + ], + [ + 'methods' => \WP_REST_Server::DELETABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a single cart coupon. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $controller = new CartController(); + + if ( ! $controller->has_coupon( $request['code'] ) ) { + throw new RouteException( 'woocommerce_rest_cart_coupon_invalid_code', __( 'Coupon does not exist in the cart.', 'woocommerce' ), 404 ); + } + + return $this->prepare_item_for_response( $request['code'], $request ); + } + + /** + * Delete a single cart coupon. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_delete_response( \WP_REST_Request $request ) { + $controller = new CartController(); + + if ( ! $controller->has_coupon( $request['code'] ) ) { + throw new RouteException( 'woocommerce_rest_cart_coupon_invalid_code', __( 'Coupon does not exist in the cart.', 'woocommerce' ), 404 ); + } + + $cart = $controller->get_cart_instance(); + $cart->remove_coupon( $request['code'] ); + $cart->calculate_totals(); + + return new \WP_REST_Response( null, 204 ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartItems.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartItems.php new file mode 100644 index 0000000..bee5f7c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartItems.php @@ -0,0 +1,132 @@ + \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'context' => $this->get_context_param( [ 'default' => 'view' ] ), + ], + ], + [ + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'get_response' ), + 'permission_callback' => '__return_true', + 'args' => $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), + ], + [ + 'methods' => \WP_REST_Server::DELETABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a collection of cart items. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $cart_items = $controller->get_cart_items(); + $items = []; + + foreach ( $cart_items as $cart_item ) { + $data = $this->prepare_item_for_response( $cart_item, $request ); + $items[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $items ); + + return $response; + } + + /** + * Creates one item from the collection. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + // Do not allow key to be specified during creation. + if ( ! empty( $request['key'] ) ) { + throw new RouteException( 'woocommerce_rest_cart_item_exists', __( 'Cannot create an existing cart item.', 'woocommerce' ), 400 ); + } + + $controller = new CartController(); + $result = $controller->add_to_cart( + [ + 'id' => $request['id'], + 'quantity' => $request['quantity'], + 'variation' => $request['variation'], + ] + ); + + $response = rest_ensure_response( $this->prepare_item_for_response( $controller->get_cart_item( $result ), $request ) ); + $response->set_status( 201 ); + return $response; + } + + /** + * Deletes all items in the cart. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_delete_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $controller->empty_cart(); + return new \WP_REST_Response( [], 200 ); + } + + /** + * Prepare links for the request. + * + * @param array $cart_item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $cart_item, $request ) { + $base = $this->get_namespace() . $this->get_path(); + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $cart_item['key'] ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + return $links; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartItemsByKey.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartItemsByKey.php new file mode 100644 index 0000000..06d8ebc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartItemsByKey.php @@ -0,0 +1,136 @@ +[\w-]{32})'; + } + + /** + * Get method arguments for this REST route. + * + * @return array An array of endpoints. + */ + public function get_args() { + return [ + 'args' => [ + 'key' => [ + 'description' => __( 'Unique identifier for the item within the cart.', 'woocommerce' ), + 'type' => 'string', + ], + ], + [ + 'methods' => \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'context' => $this->get_context_param( [ 'default' => 'view' ] ), + ], + ], + [ + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'get_response' ), + 'permission_callback' => '__return_true', + 'args' => $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), + ], + [ + 'methods' => \WP_REST_Server::DELETABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a single cart items. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $cart_item = $controller->get_cart_item( $request['key'] ); + + if ( ! $cart_item ) { + throw new RouteException( 'woocommerce_rest_cart_invalid_key', __( 'Cart item does not exist.', 'woocommerce' ), 404 ); + } + + $data = $this->prepare_item_for_response( $cart_item, $request ); + $response = rest_ensure_response( $data ); + + return $response; + } + + /** + * Update a single cart item. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_update_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + + if ( isset( $request['quantity'] ) ) { + $controller->set_cart_item_quantity( $request['key'], $request['quantity'] ); + } + + return rest_ensure_response( $this->prepare_item_for_response( $controller->get_cart_item( $request['key'] ), $request ) ); + } + + /** + * Delete a single cart item. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_delete_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + $cart_item = $controller->get_cart_item( $request['key'] ); + + if ( ! $cart_item ) { + throw new RouteException( 'woocommerce_rest_cart_invalid_key', __( 'Cart item does not exist.', 'woocommerce' ), 404 ); + } + + $cart->remove_cart_item( $request['key'] ); + + return new \WP_REST_Response( null, 204 ); + } + + /** + * Prepare links for the request. + * + * @param array $cart_item Object to prepare. + * @param \WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $cart_item, $request ) { + $base = $this->get_namespace() . $this->get_path(); + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $cart_item['key'] ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + return $links; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartRemoveCoupon.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartRemoveCoupon.php new file mode 100644 index 0000000..ea42e06 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartRemoveCoupon.php @@ -0,0 +1,74 @@ + \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'code' => [ + 'description' => __( 'Unique identifier for the coupon within the cart.', 'woocommerce' ), + 'type' => 'string', + ], + ], + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Handle the request and return a valid response for this endpoint. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + if ( ! wc_coupons_enabled() ) { + throw new RouteException( 'woocommerce_rest_cart_coupon_disabled', __( 'Coupons are disabled.', 'woocommerce' ), 404 ); + } + + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + $coupon_code = wc_format_coupon_code( $request['code'] ); + $coupon = new \WC_Coupon( $coupon_code ); + + if ( $coupon->get_code() !== $coupon_code || ! $coupon->is_valid() ) { + throw new RouteException( 'woocommerce_rest_cart_coupon_error', __( 'Invalid coupon code.', 'woocommerce' ), 400 ); + } + + if ( ! $controller->has_coupon( $coupon_code ) ) { + throw new RouteException( 'woocommerce_rest_cart_coupon_invalid_code', __( 'Coupon cannot be removed because it is not already applied to the cart.', 'woocommerce' ), 409 ); + } + + $cart = $controller->get_cart_instance(); + $cart->remove_coupon( $coupon_code ); + $cart->calculate_totals(); + + return rest_ensure_response( $this->schema->get_item_response( $cart ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartRemoveItem.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartRemoveItem.php new file mode 100644 index 0000000..04e7168 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartRemoveItem.php @@ -0,0 +1,63 @@ + \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'key' => [ + 'description' => __( 'Unique identifier (key) for the cart item.', 'woocommerce' ), + 'type' => 'string', + ], + ], + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Handle the request and return a valid response for this endpoint. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + $cart_item = $controller->get_cart_item( $request['key'] ); + + if ( ! $cart_item ) { + throw new RouteException( 'woocommerce_rest_cart_invalid_key', __( 'Cart item no longer exists or is invalid.', 'woocommerce' ), 409 ); + } + + $cart->remove_cart_item( $request['key'] ); + + return rest_ensure_response( $this->schema->get_item_response( $cart ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartSelectShippingRate.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartSelectShippingRate.php new file mode 100644 index 0000000..4dc20b6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartSelectShippingRate.php @@ -0,0 +1,83 @@ +[\d]+)'; + } + + /** + * Get method arguments for this REST route. + * + * @return array An array of endpoints. + */ + public function get_args() { + return [ + [ + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'package_id' => array( + 'description' => __( 'The ID of the package being shipped.', 'woocommerce' ), + 'type' => 'integer', + 'required' => true, + ), + 'rate_id' => [ + 'description' => __( 'The chosen rate ID for the package.', 'woocommerce' ), + 'type' => 'string', + 'required' => true, + ], + ], + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Handle the request and return a valid response for this endpoint. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + if ( ! wc_shipping_enabled() ) { + throw new RouteException( 'woocommerce_rest_shipping_disabled', __( 'Shipping is disabled.', 'woocommerce' ), 404 ); + } + + if ( ! isset( $request['package_id'] ) || ! is_numeric( $request['package_id'] ) ) { + throw new RouteException( 'woocommerce_rest_cart_missing_package_id', __( 'Invalid Package ID.', 'woocommerce' ), 400 ); + } + + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + + if ( $cart->needs_shipping() ) { + $package_id = absint( $request['package_id'] ); + $rate_id = wc_clean( wp_unslash( $request['rate_id'] ) ); + + try { + $controller->select_shipping_rate( $package_id, $rate_id ); + } catch ( \WC_Rest_Exception $e ) { + throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); + } + } + $cart->calculate_shipping(); + $cart->calculate_totals(); + + return rest_ensure_response( $this->schema->get_item_response( $cart ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartUpdateItem.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartUpdateItem.php new file mode 100644 index 0000000..8868acd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartUpdateItem.php @@ -0,0 +1,64 @@ + \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'key' => [ + 'description' => __( 'Unique identifier (key) for the cart item to update.', 'woocommerce' ), + 'type' => 'string', + ], + 'quantity' => [ + 'description' => __( 'New quantity of the item in the cart.', 'woocommerce' ), + 'type' => 'integer', + ], + ], + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Handle the request and return a valid response for this endpoint. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + + if ( isset( $request['quantity'] ) ) { + $controller->set_cart_item_quantity( $request['key'], $request['quantity'] ); + } + + return rest_ensure_response( $this->schema->get_item_response( $cart ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartUpdateShipping.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartUpdateShipping.php new file mode 100644 index 0000000..f6b3bf5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/CartUpdateShipping.php @@ -0,0 +1,214 @@ + \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'first_name' => [ + 'description' => __( 'Customer first name.', 'woocommerce' ), + 'type' => 'string', + 'default' => '', + 'sanitize_callback' => 'wc_clean', + 'validate_callback' => 'rest_validate_request_arg', + + ], + 'last_name' => [ + 'description' => __( 'Customer last name.', 'woocommerce' ), + 'type' => 'string', + 'default' => '', + 'sanitize_callback' => 'wc_clean', + 'validate_callback' => 'rest_validate_request_arg', + + ], + 'address_1' => [ + 'description' => __( 'First line of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'default' => '', + 'sanitize_callback' => 'wc_clean', + 'validate_callback' => 'rest_validate_request_arg', + ], + 'address_2' => [ + 'description' => __( 'Second line of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'default' => '', + 'sanitize_callback' => 'wc_clean', + 'validate_callback' => 'rest_validate_request_arg', + ], + 'city' => [ + 'description' => __( 'City of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'default' => '', + 'sanitize_callback' => 'wc_clean', + 'validate_callback' => 'rest_validate_request_arg', + ], + 'state' => [ + 'description' => __( 'ISO code, or name, for the state, province, or district of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'default' => '', + 'sanitize_callback' => 'wc_clean', + 'validate_callback' => 'rest_validate_request_arg', + ], + 'postcode' => [ + 'description' => __( 'Zip or Postcode of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'default' => '', + 'sanitize_callback' => 'wc_clean', + 'validate_callback' => 'rest_validate_request_arg', + ], + 'country' => [ + 'description' => __( 'ISO code for the country of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'default' => '', + 'sanitize_callback' => 'wc_clean', + 'validate_callback' => 'rest_validate_request_arg', + ], + ], + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Handle the request and return a valid response for this endpoint. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + if ( ! wc_shipping_enabled() ) { + throw new RouteException( 'woocommerce_rest_shipping_disabled', __( 'Shipping is disabled.', 'woocommerce' ), 404 ); + } + + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + $request = $this->validate_shipping_address( $request ); + + // Update customer session. + wc()->customer->set_props( + array( + 'shipping_first_name' => isset( $request['first_name'] ) ? $request['first_name'] : null, + 'shipping_last_name' => isset( $request['last_name'] ) ? $request['last_name'] : null, + 'shipping_country' => isset( $request['country'] ) ? $request['country'] : null, + 'shipping_state' => isset( $request['state'] ) ? $request['state'] : null, + 'shipping_postcode' => isset( $request['postcode'] ) ? $request['postcode'] : null, + 'shipping_city' => isset( $request['city'] ) ? $request['city'] : null, + 'shipping_address_1' => isset( $request['address_1'] ) ? $request['address_1'] : null, + 'shipping_address_2' => isset( $request['address_2'] ) ? $request['address_2'] : null, + ) + ); + wc()->customer->save(); + + $cart->calculate_shipping(); + $cart->calculate_totals(); + + return rest_ensure_response( $this->schema->get_item_response( $cart ) ); + } + + /** + * Format the request address. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_REST_Response + */ + public function validate_shipping_address( $request ) { + $valid_countries = wc()->countries->get_shipping_countries(); + + if ( empty( $request['country'] ) ) { + throw new RouteException( + 'woocommerce_rest_cart_shipping_rates_missing_country', + sprintf( + /* translators: 1: valid country codes */ + __( 'No destination country code was given. Please provide one of the following: %s', 'woocommerce' ), + implode( ', ', array_keys( $valid_countries ) ) + ), + 400 + ); + } + + $request['country'] = wc_strtoupper( $request['country'] ); + + if ( + is_array( $valid_countries ) && + count( $valid_countries ) > 0 && + ! array_key_exists( $request['country'], $valid_countries ) + ) { + throw new RouteException( + 'woocommerce_rest_cart_shipping_rates_invalid_country', + sprintf( + /* translators: 1: valid country codes */ + __( 'Destination country code is not valid. Please enter one of the following: %s', 'woocommerce' ), + implode( ', ', array_keys( $valid_countries ) ) + ), + 400 + ); + } + + $request['postcode'] = $request['postcode'] ? wc_format_postcode( $request['postcode'], $request['country'] ) : null; + + if ( ! empty( $request['state'] ) ) { + $valid_states = wc()->countries->get_states( $request['country'] ); + + if ( is_array( $valid_states ) && count( $valid_states ) > 0 ) { + $valid_state_values = array_map( 'wc_strtoupper', array_flip( array_map( 'wc_strtoupper', $valid_states ) ) ); + $request['state'] = wc_strtoupper( $request['state'] ); + + if ( isset( $valid_state_values[ $request['state'] ] ) ) { + // With this part we consider state value to be valid as well, + // convert it to the state key for the valid_states check below. + $request['state'] = $valid_state_values[ $request['state'] ]; + } + + if ( ! in_array( $request['state'], $valid_state_values, true ) ) { + throw new RouteException( + 'woocommerce_rest_cart_shipping_rates_invalid_state', + sprintf( + /* translators: 1: valid states */ + __( 'Destination state is not valid. Please enter one of the following: %s', 'woocommerce' ), + implode( ', ', $valid_states ) + ), + 400 + ); + } + } + } + + return $request; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/Checkout.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/Checkout.php new file mode 100644 index 0000000..4fe8702 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/Checkout.php @@ -0,0 +1,541 @@ +maybe_load_cart(); + $response = null; + try { + $this->check_nonce( $request ); + $response = parent::get_response( $request ); + } catch ( RouteException $error ) { + $response = $this->get_route_error_response( $error->getErrorCode(), $error->getMessage(), $error->getCode() ); + } catch ( \Exception $error ) { + $response = $this->get_route_error_response( 'unknown_server_error', $error->getMessage(), 500 ); + } + return $response; + } + + /** + * Get method arguments for this REST route. + * + * @return array An array of endpoints. + */ + public function get_args() { + return [ + [ + 'methods' => \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => [ + 'context' => $this->get_context_param( [ 'default' => 'view' ] ), + ], + ], + [ + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'get_response' ), + 'permission_callback' => '__return_true', + 'args' => $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ), + ], + [ + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => array_merge( + [ + 'payment_data' => [ + 'description' => __( 'Data to pass through to the payment method when processing payment.', 'woocommerce' ), + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'key' => [ + 'type' => 'string', + ], + 'value' => [ + 'type' => 'string', + ], + ], + ], + ], + ], + $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ) + ), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Convert the cart into a new draft order, or update an existing draft order, and return an updated cart response. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $order_object = $this->create_or_update_draft_order(); + + return $this->prepare_item_for_response( + (object) [ + 'order' => $order_object, + 'payment_result' => new PaymentResult(), + ], + $request + ); + } + + /** + * Update the order. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_update_response( \WP_REST_Request $request ) { + $order_object = $this->create_or_update_draft_order(); + + $this->update_order_from_request( $order_object, $request ); + + return $this->prepare_item_for_response( + (object) [ + 'order' => $order_object, + 'payment_result' => new PaymentResult(), + ], + $request + ); + } + + /** + * Update and process payment for the order. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_post_response( \WP_REST_Request $request ) { + $order_controller = new OrderController(); + $order_object = $this->get_draft_order_object( $this->get_draft_order_id() ); + + if ( ! $order_object ) { + throw new RouteException( + 'woocommerce_rest_checkout_invalid_order', + __( 'This session has no orders pending payment.', 'woocommerce' ), + 500 + ); + } + + // Ensure order still matches cart. + $order_controller->update_order_from_cart( $order_object ); + + // Create a new user account as necessary. + // Note - CreateAccount class includes feature gating logic (i.e. this + // may not create an account depending on build). + if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '4.7', '>=' ) ) { + // Checkout signup is feature gated to WooCommerce 4.7 and newer; + // Because it requires updated my-account/lost-password screen in 4.7+ + // for setting initial password. + try { + $create_account = Package::container()->get( CreateAccount::class ); + $create_account->from_order_request( $request ); + $order_object->set_customer_id( get_current_user_id() ); + } catch ( Exception $error ) { + $this->handle_error( $error ); + } + } + // If any form fields were posted, update the order. + $this->update_order_from_request( $order_object, $request ); + + // Check order is still valid. + $order_controller->validate_order_before_payment( $order_object ); + + // Persist customer address data to account. + $order_controller->sync_customer_data_with_order( $order_object ); + + /* + * Fire woocommerce_blocks_checkout_order_processed, should work the same way as woocommerce_checkout_order_processed + * But we're opting for a new action because the original ones attaches POST data. + * NOTE: this hook is still experimental, and might change or get removed. + * @todo: Document and stabilize __experimental_woocommerce_blocks_checkout_order_processed + */ + do_action( '__experimental_woocommerce_blocks_checkout_order_processed', $order_object ); + + if ( ! $order_object->needs_payment() ) { + $payment_result = $this->process_without_payment( $order_object, $request ); + } else { + $payment_result = $this->process_payment( $order_object, $request ); + } + + $response = $this->prepare_item_for_response( + (object) [ + 'order' => wc_get_order( $order_object ), + 'payment_result' => $payment_result, + ], + $request + ); + + switch ( $payment_result->status ) { + case 'success': + $response->set_status( 200 ); + break; + case 'pending': + $response->set_status( 202 ); + break; + case 'failure': + $response->set_status( 400 ); + break; + case 'error': + $response->set_status( 500 ); + break; + } + + return $response; + } + + /** + * Get route response when something went wrong. + * + * @param string $error_code String based error code. + * @param string $error_message User facing error message. + * @param int $http_status_code HTTP status. Defaults to 500. + * @param array $additional_data Extra data (key value pairs) to expose in the error response. + * @return \WP_Error WP Error object. + */ + protected function get_route_error_response( $error_code, $error_message, $http_status_code = 500, $additional_data = [] ) { + switch ( $http_status_code ) { + case 409: + // If there was a conflict, return the cart so the client can resolve it. + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + + return new \WP_Error( + $error_code, + $error_message, + array_merge( + $additional_data, + [ + 'status' => $http_status_code, + 'cart' => wc()->api->get_endpoint_data( '/wc/store/cart' ), + ] + ) + ); + } + return new \WP_Error( $error_code, $error_message, [ 'status' => $http_status_code ] ); + } + + /** + * Gets draft order data from the customer session. + * + * @return array + */ + protected function get_draft_order_id() { + return wc()->session->get( 'store_api_draft_order', 0 ); + } + + /** + * Updates draft order data in the customer session. + * + * @param integer $order_id Draft order ID. + */ + protected function set_draft_order_id( $order_id ) { + wc()->session->set( 'store_api_draft_order', $order_id ); + } + + /** + * Get an order object, either using a current draft order, or returning a new one. + * + * @param integer $order_id Draft order ID. + * @return \WC_Order|boolean Either the draft order, or false if one has not yet been created. + */ + protected function get_draft_order_object( $order_id ) { + $draft_order_object = $order_id ? wc_get_order( $order_id ) : false; + + if ( ! $draft_order_object ) { + return false; + } + + // Draft orders are okay. + if ( $draft_order_object->has_status( 'checkout-draft' ) ) { + return $draft_order_object; + } + + // Pending and failed orders can be retried if the cart hasn't changed. + if ( $draft_order_object->needs_payment() && $draft_order_object->has_cart_hash( wc()->cart->get_cart_hash() ) ) { + return $draft_order_object; + } + + return false; + } + + /** + * Create or update a draft order based on the cart. + * + * @throws RouteException On error. + * + * @return \WC_Order Order object. + */ + protected function create_or_update_draft_order() { + $cart_controller = new CartController(); + $order_controller = new OrderController(); + $reserve_stock = \class_exists( '\Automattic\WooCommerce\Checkout\Helpers\ReserveStock' ) ? new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock() : new ReserveStock(); + $order_object = $this->get_draft_order_object( $this->get_draft_order_id() ); + $created = false; + + // Validate items etc are allowed in the order before it gets created. + $cart_controller->validate_cart_items(); + $cart_controller->validate_cart_coupons(); + + if ( ! $order_object ) { + $order_object = $order_controller->create_order_from_cart(); + $created = true; + } else { + $order_controller->update_order_from_cart( $order_object ); + } + + // Store order ID to session. + $this->set_draft_order_id( $order_object->get_id() ); + + // Try to reserve stock for 10 mins, if available. + try { + $reserve_stock->reserve_stock_for_order( $order_object, 10 ); + } catch ( ReserveStockException $e ) { + $error_data = $e->getErrorData(); + throw new RouteException( + $e->getErrorCode(), + $e->getMessage(), + $e->getCode() + ); + } + + return $order_object; + } + + /** + * Convert an account creation error to a Store API error. + * + * @param \Exception $error Caught exception. + * + * @throws RouteException API error object with error details. + */ + private function handle_error( Exception $error ) { + switch ( $error->getMessage() ) { + case 'registration-error-invalid-email': + throw new RouteException( + 'registration-error-invalid-email', + __( 'Please provide a valid email address.', 'woocommerce' ), + 400 + ); + + case 'registration-error-email-exists': + throw new RouteException( + 'registration-error-email-exists', + apply_filters( + 'woocommerce_registration_error_email_exists', + __( 'An account is already registered with your email address. Please log in.', 'woocommerce' ) + ), + 400 + ); + } + } + + /** + * Update an order using the posted values from the request. + * + * @param \WC_Order $order Object to prepare for the response. + * @param \WP_REST_Request $request Full details about the request. + */ + protected function update_order_from_request( \WC_Order $order, \WP_REST_Request $request ) { + $schema = $this->get_item_schema(); + + if ( isset( $request['billing_address'] ) ) { + $allowed_billing_values = array_intersect_key( $request['billing_address'], $schema['properties']['billing_address']['properties'] ); + foreach ( $allowed_billing_values as $key => $value ) { + $order->{"set_billing_$key"}( $value ); + } + } + + if ( isset( $request['shipping_address'] ) ) { + $allowed_shipping_values = array_intersect_key( $request['shipping_address'], $schema['properties']['shipping_address']['properties'] ); + foreach ( $allowed_shipping_values as $key => $value ) { + $order->{"set_shipping_$key"}( $value ); + } + } + + if ( isset( $request['customer_note'] ) ) { + $order->set_customer_note( $request['customer_note'] ); + } + + if ( isset( $request['payment_method'] ) ) { + $order->set_payment_method( $this->get_request_payment_method( $request ) ); + } + + $order->save(); + } + + /** + * For orders which do not require payment, just update status. + * + * @param \WC_Order $order Order object. + * @param \WP_REST_Request $request Request object. + * @return PaymentResult + */ + protected function process_without_payment( \WC_Order $order, \WP_REST_Request $request ) { + $order->payment_complete(); + + $result = new PaymentResult( 'success' ); + $result->set_redirect_url( $order->get_checkout_order_received_url() ); + return $result; + } + + /** + * Fires an action hook instructing active payment gateways to process the payment for an order and provide a result. + * + * @throws RouteException On error. + * @param \WC_Order $order Order object. + * @param \WP_REST_Request $request Request object. + * @return PaymentResult + */ + protected function process_payment( \WC_Order $order, \WP_REST_Request $request ) { + $context = new PaymentContext(); + $result = new PaymentResult(); + + $order->update_status( 'pending' ); + + $context->set_order( $order ); + $context->set_payment_method( $this->get_request_payment_method_id( $request ) ); + $context->set_payment_data( $this->get_request_payment_data( $request ) ); + + try { + /** + * Process payment with context. + * + * @hook woocommerce_rest_checkout_process_payment_with_context + * + * @throws \Exception If there is an error taking payment, an Exception object can be thrown + * with an error message. + * + * @param PaymentContext $context Holds context for the payment, including order ID and payment method. + * @param PaymentResult $result Result object for the transaction. + */ + do_action_ref_array( 'woocommerce_rest_checkout_process_payment_with_context', [ $context, &$result ] ); + + if ( ! $result instanceof PaymentResult ) { + throw new RouteException( 'woocommerce_rest_checkout_invalid_payment_result', __( 'Invalid payment result received from payment method.', 'woocommerce' ), 500 ); + } + + return $result; + } catch ( \Exception $e ) { + throw new RouteException( 'woocommerce_rest_checkout_process_payment_error', $e->getMessage(), 400 ); + } + } + + /** + * Gets the chosen payment method ID from the request. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return string + */ + protected function get_request_payment_method_id( \WP_REST_Request $request ) { + $payment_method = isset( $request['payment_method'] ) + ? wc_clean( wp_unslash( $request['payment_method'] ) ) + : ''; + $valid_methods = wc()->payment_gateways->get_payment_gateway_ids(); + + if ( empty( $payment_method ) ) { + throw new RouteException( + 'woocommerce_rest_checkout_missing_payment_method', + __( 'No payment method provided.', 'woocommerce' ), + 400 + ); + } + + if ( ! in_array( $payment_method, $valid_methods, true ) ) { + throw new RouteException( + 'woocommerce_rest_checkout_invalid_payment_method', + sprintf( + // Translators: %s list of gateway ids. + __( 'Invalid payment method provided. Please provide one of the following: %s', 'woocommerce' ), + '`' . implode( '`, `', $valid_methods ) . '`' + ), + 400 + ); + } + + return $payment_method; + } + + /** + * Gets the chosen payment method from the request. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WC_Payment_Gateway + */ + protected function get_request_payment_method( \WP_REST_Request $request ) { + $payment_method = $this->get_request_payment_method_id( $request ); + $gateways = wc()->payment_gateways->payment_gateways(); + $payment_method_object = isset( $gateways[ $payment_method ] ) ? $gateways[ $payment_method ] : false; + + // The abstract gateway is available method uses the cart global, so instead, check enabled directly. + if ( ! $payment_method_object || ! wc_string_to_bool( $payment_method_object->enabled ) ) { + throw new RouteException( + 'woocommerce_rest_checkout_payment_method_disabled', + __( 'This payment gateway is not available.', 'woocommerce' ), + 400 + ); + } + + return $payment_method_object; + } + + /** + * Gets and formats payment request data. + * + * @param \WP_REST_Request $request Request object. + * @return array + */ + protected function get_request_payment_data( \WP_REST_Request $request ) { + static $payment_data = []; + if ( ! empty( $payment_data ) ) { + return $payment_data; + } + if ( ! empty( $request['payment_data'] ) ) { + foreach ( $request['payment_data'] as $data ) { + $payment_data[ sanitize_key( $data['key'] ) ] = wc_clean( $data['value'] ); + } + } + + return $payment_data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributeTerms.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributeTerms.php new file mode 100644 index 0000000..1034115 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributeTerms.php @@ -0,0 +1,58 @@ +[\d]+)/terms'; + } + + /** + * Get method arguments for this REST route. + * + * @return array An array of endpoints. + */ + public function get_args() { + return [ + 'args' => array( + 'attribute_id' => array( + 'description' => __( 'Unique identifier for the attribute.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + [ + 'methods' => \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => $this->get_collection_params(), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a collection of attribute terms. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $attribute = wc_get_attribute( $request['attribute_id'] ); + + if ( ! $attribute || ! taxonomy_exists( $attribute->slug ) ) { + throw new RouteException( 'woocommerce_rest_taxonomy_invalid', __( 'Attribute does not exist.', 'woocommerce' ), 404 ); + } + + return $this->get_terms_response( $attribute->slug, $request ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributes.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributes.php new file mode 100644 index 0000000..b7e14ea --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributes.php @@ -0,0 +1,55 @@ + \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => $this->get_collection_params(), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a collection of attributes. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $ids = wc_get_attribute_taxonomy_ids(); + $return = []; + + foreach ( $ids as $id ) { + $object = wc_get_attribute( $id ); + $data = $this->prepare_item_for_response( $object, $request ); + $return[] = $this->prepare_response_for_collection( $data ); + } + + return rest_ensure_response( $return ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributesById.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributesById.php new file mode 100644 index 0000000..e25f87b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributesById.php @@ -0,0 +1,67 @@ +[\d]+)'; + } + + /** + * Get method arguments for this REST route. + * + * @return array An array of endpoints. + */ + public function get_args() { + return [ + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + [ + 'methods' => \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a single item. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $object = wc_get_attribute( (int) $request['id'] ); + + if ( ! $object || 0 === $object->id ) { + throw new RouteException( 'woocommerce_rest_attribute_invalid_id', __( 'Invalid attribute ID.', 'woocommerce' ), 404 ); + } + + $data = $this->prepare_item_for_response( $object, $request ); + $response = rest_ensure_response( $data ); + + return $response; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCategories.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCategories.php new file mode 100644 index 0000000..3161d27 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCategories.php @@ -0,0 +1,46 @@ + \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => $this->get_collection_params(), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a collection of terms. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + return $this->get_terms_response( 'product_cat', $request ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCategoriesById.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCategoriesById.php new file mode 100644 index 0000000..230b498 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCategoriesById.php @@ -0,0 +1,65 @@ +[\d]+)'; + } + + /** + * Get method arguments for this REST route. + * + * @return array An array of endpoints. + */ + public function get_args() { + return [ + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + [ + 'methods' => \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a single item. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $object = get_term( (int) $request['id'], 'product_cat' ); + + if ( ! $object || 0 === $object->id ) { + throw new RouteException( 'woocommerce_rest_category_invalid_id', __( 'Invalid category ID.', 'woocommerce' ), 404 ); + } + + $data = $this->prepare_item_for_response( $object, $request ); + return rest_ensure_response( $data ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCollectionData.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCollectionData.php new file mode 100644 index 0000000..03000dc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCollectionData.php @@ -0,0 +1,183 @@ + \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => $this->get_collection_params(), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a collection of posts and add the post title filter option to \WP_Query. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $data = [ + 'min_price' => null, + 'max_price' => null, + 'attribute_counts' => null, + 'rating_counts' => null, + ]; + $filters = new ProductQueryFilters(); + + if ( ! empty( $request['calculate_price_range'] ) ) { + $filter_request = clone $request; + $filter_request->set_param( 'min_price', null ); + $filter_request->set_param( 'max_price', null ); + + $price_results = $filters->get_filtered_price( $filter_request ); + $data['min_price'] = $price_results->min_price; + $data['max_price'] = $price_results->max_price; + } + + if ( ! empty( $request['calculate_attribute_counts'] ) ) { + $taxonomy__or_queries = []; + $taxonomy__and_queries = []; + + foreach ( $request['calculate_attribute_counts'] as $attributes_to_count ) { + if ( ! empty( $attributes_to_count['taxonomy'] ) ) { + if ( empty( $attributes_to_count['query_type'] ) || 'or' === $attributes_to_count['query_type'] ) { + $taxonomy__or_queries[] = $attributes_to_count['taxonomy']; + } else { + $taxonomy__and_queries[] = $attributes_to_count['taxonomy']; + } + } + } + + $data['attribute_counts'] = []; + // Or type queries need special handling because the attribute, if set, needs removing from the query first otherwise counts would not be correct. + if ( $taxonomy__or_queries ) { + foreach ( $taxonomy__or_queries as $taxonomy ) { + $filter_request = clone $request; + $filter_attributes = $filter_request->get_param( 'attributes' ); + + if ( ! empty( $filter_attributes ) ) { + $filter_attributes = array_filter( + $filter_attributes, + function( $query ) use ( $taxonomy ) { + return $query['attribute'] !== $taxonomy; + } + ); + } + + $filter_request->set_param( 'attributes', $filter_attributes ); + $counts = $filters->get_attribute_counts( $filter_request, [ $taxonomy ] ); + + foreach ( $counts as $key => $value ) { + $data['attribute_counts'][] = (object) [ + 'term' => $key, + 'count' => $value, + ]; + } + } + } + + if ( $taxonomy__and_queries ) { + $counts = $filters->get_attribute_counts( $request, $taxonomy__and_queries ); + + foreach ( $counts as $key => $value ) { + $data['attribute_counts'][] = (object) [ + 'term' => $key, + 'count' => $value, + ]; + } + } + } + + if ( ! empty( $request['calculate_rating_counts'] ) ) { + $filter_request = clone $request; + $counts = $filters->get_rating_counts( $filter_request ); + $data['rating_counts'] = []; + + foreach ( $counts as $key => $value ) { + $data['rating_counts'][] = (object) [ + 'rating' => $key, + 'count' => $value, + ]; + } + } + + return rest_ensure_response( $this->schema->get_item_response( $data ) ); + } + + /** + * Get the query params for collections of products. + * + * @return array + */ + public function get_collection_params() { + $params = ( new Products( $this->schema ) )->get_collection_params(); + + $params['calculate_price_range'] = [ + 'description' => __( 'If true, calculates the minimum and maximum product prices for the collection.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + ]; + + $params['calculate_attribute_counts'] = [ + 'description' => __( 'If requested, calculates attribute term counts for products in the collection.', 'woocommerce' ), + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'taxonomy' => [ + 'description' => __( 'Taxonomy name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'query_type' => [ + 'description' => __( 'Query type being performed which may affect counts. Valid values include "and" and "or".', 'woocommerce' ), + 'type' => 'string', + 'enum' => [ 'and', 'or' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + 'default' => [], + ]; + + $params['calculate_rating_counts'] = [ + 'description' => __( 'If true, calculates rating counts for products in the collection.', 'woocommerce' ), + 'type' => 'boolean', + 'default' => false, + ]; + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductReviews.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductReviews.php new file mode 100644 index 0000000..db2e495 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductReviews.php @@ -0,0 +1,220 @@ + \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => $this->get_collection_params(), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a collection of reviews. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $prepared_args = array( + 'type' => 'review', + 'status' => 'approve', + 'no_found_rows' => false, + 'offset' => $request['offset'], + 'order' => $request['order'], + 'number' => $request['per_page'], + 'post__in' => $request['product_id'], + ); + + /** + * Map category id to list of product ids. + */ + if ( ! empty( $request['category_id'] ) ) { + $category_ids = $request['category_id']; + $child_ids = []; + foreach ( $category_ids as $category_id ) { + $child_ids = array_merge( $child_ids, get_term_children( $category_id, 'product_cat' ) ); + } + $category_ids = array_unique( array_merge( $category_ids, $child_ids ) ); + $product_ids = get_objects_in_term( $category_ids, 'product_cat' ); + $prepared_args['post__in'] = isset( $prepared_args['post__in'] ) ? array_merge( $prepared_args['post__in'], $product_ids ) : $product_ids; + } + + if ( 'rating' === $request['orderby'] ) { + $prepared_args['meta_query'] = array( // phpcs:ignore + 'relation' => 'OR', + array( + 'key' => 'rating', + 'compare' => 'EXISTS', + ), + array( + 'key' => 'rating', + 'compare' => 'NOT EXISTS', + ), + ); + } + $prepared_args['orderby'] = $this->normalize_query_param( $request['orderby'] ); + + if ( empty( $request['offset'] ) ) { + $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); + } + + $query = new WP_Comment_Query(); + $query_result = $query->query( $prepared_args ); + $response_objects = array(); + + foreach ( $query_result as $review ) { + $data = $this->prepare_item_for_response( $review, $request ); + $response_objects[] = $this->prepare_response_for_collection( $data ); + } + + $total_reviews = (int) $query->found_comments; + $max_pages = (int) $query->max_num_pages; + + if ( $total_reviews < 1 ) { + // Out-of-bounds, run the query again without LIMIT for total count. + unset( $prepared_args['number'], $prepared_args['offset'] ); + + $query = new WP_Comment_Query(); + $prepared_args['count'] = true; + + $total_reviews = $query->query( $prepared_args ); + $max_pages = $request['per_page'] ? ceil( $total_reviews / $request['per_page'] ) : 1; + } + + $response = rest_ensure_response( $response_objects ); + $response = ( new Pagination() )->add_headers( $response, $request, $total_reviews, $max_pages ); + + return $response; + } + + /** + * Prepends internal property prefix to query parameters to match our response fields. + * + * @param string $query_param Query parameter. + * @return string + */ + protected function normalize_query_param( $query_param ) { + $prefix = 'comment_'; + + switch ( $query_param ) { + case 'id': + $normalized = $prefix . 'ID'; + break; + case 'product': + $normalized = $prefix . 'post_ID'; + break; + case 'rating': + $normalized = 'meta_value_num'; + break; + default: + $normalized = $prefix . $query_param; + break; + } + + return $normalized; + } + + /** + * Get the query params for collections of products. + * + * @return array + */ + public function get_collection_params() { + $params = array(); + $params['context'] = $this->get_context_param(); + $params['context']['default'] = 'view'; + + $params['page'] = array( + 'description' => __( 'Current page of the collection.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set. Defaults to no limit if left blank.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 0, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( + 'date', + 'date_gmt', + 'id', + 'rating', + 'product', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['category_id'] = array( + 'description' => __( 'Limit result set to reviews from specific category IDs.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['product_id'] = array( + 'description' => __( 'Limit result set to reviews from specific product IDs.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductTags.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductTags.php new file mode 100644 index 0000000..b0b0953 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductTags.php @@ -0,0 +1,46 @@ + \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => $this->get_collection_params(), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a collection of terms. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + return $this->get_terms_response( 'product_tag', $request ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/Products.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/Products.php new file mode 100644 index 0000000..13bcbcf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/Products.php @@ -0,0 +1,385 @@ + \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => $this->get_collection_params(), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a collection of posts and add the post title filter option to \WP_Query. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $response = new \WP_REST_Response(); + $product_query = new ProductQuery(); + + // Only get objects during GET requests. + if ( \WP_REST_Server::READABLE === $request->get_method() ) { + $query_results = $product_query->get_objects( $request ); + $response_objects = []; + + foreach ( $query_results['objects'] as $object ) { + $data = rest_ensure_response( $this->schema->get_item_response( $object ) ); + $response_objects[] = $this->prepare_response_for_collection( $data ); + } + + $response->set_data( $response_objects ); + } else { + $query_results = $product_query->get_results( $request ); + } + + $response = ( new Pagination() )->add_headers( $response, $request, $query_results['total'], $query_results['pages'] ); + $response->header( 'Last-Modified', $product_query->get_last_modified() ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param \WC_Product $item Product object. + * @param \WP_REST_Request $request Request object. + * @return array + */ + protected function prepare_links( $item, $request ) { + $links = array( + 'self' => array( + 'href' => rest_url( $this->get_namespace() . $this->get_path() . '/' . $item->get_id() ), + ), + 'collection' => array( + 'href' => rest_url( $this->get_namespace() . $this->get_path() ), + ), + ); + + if ( $item->get_parent_id() ) { + $links['up'] = array( + 'href' => rest_url( $this->get_namespace() . $this->get_path() . '/' . $item->get_parent_id() ), + ); + } + + return $links; + } + + /** + * Get the query params for collections of products. + * + * @return array + */ + public function get_collection_params() { + $params = []; + $params['context'] = $this->get_context_param(); + $params['context']['default'] = 'view'; + + $params['page'] = array( + 'description' => __( 'Current page of the collection.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ); + + $params['per_page'] = array( + 'description' => __( 'Maximum number of items to be returned in result set. Defaults to no limit if left blank.', 'woocommerce' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 0, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['search'] = array( + 'description' => __( 'Limit results to those matching a string.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['after'] = array( + 'description' => __( 'Limit response to resources created after a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['before'] = array( + 'description' => __( 'Limit response to resources created before a given ISO8601 compliant date.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['date_column'] = array( + 'description' => __( 'When limiting response using after/before, which date column to compare against.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( + 'date', + 'date_gmt', + 'modified', + 'modified_gmt', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['exclude'] = array( + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => [], + 'sanitize_callback' => 'wp_parse_id_list', + ); + + $params['include'] = array( + 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => [], + 'sanitize_callback' => 'wp_parse_id_list', + ); + + $params['offset'] = array( + 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['order'] = array( + 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['orderby'] = array( + 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( + 'date', + 'modified', + 'id', + 'include', + 'title', + 'slug', + 'price', + 'popularity', + 'rating', + 'menu_order', + 'comment_count', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['parent'] = array( + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'default' => [], + 'sanitize_callback' => 'wp_parse_id_list', + ); + + $params['parent_exclude'] = array( + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + ), + 'sanitize_callback' => 'wp_parse_id_list', + 'default' => [], + ); + + $params['type'] = array( + 'description' => __( 'Limit result set to products assigned a specific type.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_merge( array_keys( wc_get_product_types() ), [ 'variation' ] ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['sku'] = array( + 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['featured'] = array( + 'description' => __( 'Limit result set to featured products.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['category'] = array( + 'description' => __( 'Limit result set to products assigned a specific category ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['category_operator'] = array( + 'description' => __( 'Operator to compare product category terms.', 'woocommerce' ), + 'type' => 'string', + 'enum' => [ 'in', 'not in', 'and' ], + 'default' => 'in', + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['tag'] = array( + 'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['tag_operator'] = array( + 'description' => __( 'Operator to compare product tags.', 'woocommerce' ), + 'type' => 'string', + 'enum' => [ 'in', 'not in', 'and' ], + 'default' => 'in', + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['on_sale'] = array( + 'description' => __( 'Limit result set to products on sale.', 'woocommerce' ), + 'type' => 'boolean', + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['min_price'] = array( + 'description' => __( 'Limit result set to products based on a minimum price, provided using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['max_price'] = array( + 'description' => __( 'Limit result set to products based on a maximum price, provided using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['stock_status'] = array( + 'description' => __( 'Limit result set to products with specified stock status.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array_keys( wc_get_product_stock_status_options() ), + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['attributes'] = array( + 'description' => __( 'Limit result set to products with selected global attributes.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'attribute' => array( + 'description' => __( 'Attribute taxonomy name.', 'woocommerce' ), + 'type' => 'string', + 'sanitize_callback' => 'wc_sanitize_taxonomy_name', + ), + 'term_id' => array( + 'description' => __( 'List of attribute term IDs.', 'woocommerce' ), + 'type' => 'array', + 'items' => [ + 'type' => 'integer', + ], + 'sanitize_callback' => 'wp_parse_id_list', + ), + 'slug' => array( + 'description' => __( 'List of attribute slug(s). If a term ID is provided, this will be ignored.', 'woocommerce' ), + 'type' => 'array', + 'items' => [ + 'type' => 'string', + ], + 'sanitize_callback' => 'wp_parse_slug_list', + ), + 'operator' => array( + 'description' => __( 'Operator to compare product attribute terms.', 'woocommerce' ), + 'type' => 'string', + 'enum' => [ 'in', 'not in', 'and' ], + ), + ), + ), + 'default' => [], + ); + + $params['attribute_relation'] = array( + 'description' => __( 'The logical relationship between attributes when filtering across multiple at once.', 'woocommerce' ), + 'type' => 'string', + 'enum' => [ 'in', 'and' ], + 'default' => 'and', + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['catalog_visibility'] = array( + 'description' => __( 'Determines if hidden or visible catalog products are shown.', 'woocommerce' ), + 'type' => 'string', + 'enum' => array( 'any', 'visible', 'catalog', 'search', 'hidden' ), + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + + $params['rating'] = array( + 'description' => __( 'Limit result set to products with a certain average rating.', 'woocommerce' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', + 'enum' => range( 1, 5 ), + ), + 'default' => [], + 'sanitize_callback' => 'wp_parse_id_list', + ); + + return $params; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductsById.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductsById.php new file mode 100644 index 0000000..3eff916 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/ProductsById.php @@ -0,0 +1,64 @@ +[\d]+)'; + } + + /** + * Get method arguments for this REST route. + * + * @return array An array of endpoints. + */ + public function get_args() { + return [ + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + ), + ), + [ + 'methods' => \WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_response' ], + 'permission_callback' => '__return_true', + 'args' => array( + 'context' => $this->get_context_param( + array( + 'default' => 'view', + ) + ), + ), + ], + 'schema' => [ $this->schema, 'get_public_item_schema' ], + ]; + } + + /** + * Get a single item. + * + * @throws RouteException On error. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response + */ + protected function get_route_response( \WP_REST_Request $request ) { + $object = wc_get_product( (int) $request['id'] ); + + if ( ! $object || 0 === $object->get_id() ) { + throw new RouteException( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), 404 ); + } + + return rest_ensure_response( $this->schema->get_item_response( $object ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/RouteException.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/RouteException.php new file mode 100644 index 0000000..9f7fd78 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/RouteException.php @@ -0,0 +1,55 @@ +error_code = $error_code; + $this->additional_data = array_filter( (array) $additional_data ); + parent::__construct( $message, $http_status_code ); + } + + /** + * Returns the error code. + * + * @return string + */ + public function getErrorCode() { + return $this->error_code; + } + + /** + * Returns additional error data. + * + * @return array + */ + public function getAdditionalData() { + return $this->additional_data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/RouteInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/RouteInterface.php new file mode 100644 index 0000000..66711f7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/RouteInterface.php @@ -0,0 +1,30 @@ +schemas = $schemas; + $this->initialize(); + } + + /** + * Get a route class instance. + * + * @throws Exception If the schema does not exist. + * + * @param string $name Name of schema. + * @return AbstractRoute + */ + public function get( $name ) { + if ( ! isset( $this->routes[ $name ] ) ) { + throw new Exception( $name . ' route does not exist' ); + } + return $this->routes[ $name ]; + } + + /** + * Register defined list of routes with WordPress. + */ + public function register_routes() { + foreach ( $this->routes as $route ) { + register_rest_route( + $route->get_namespace(), + $route->get_path(), + $route->get_args() + ); + } + } + + /** + * Load route class instances. + */ + protected function initialize() { + $this->routes = [ + 'cart' => new Routes\Cart( $this->schemas->get( 'cart' ) ), + 'cart-add-item' => new Routes\CartAddItem( $this->schemas->get( 'cart' ) ), + 'cart-apply-coupon' => new Routes\CartApplyCoupon( $this->schemas->get( 'cart' ) ), + 'cart-coupons' => new Routes\CartCoupons( $this->schemas->get( 'cart-coupon' ) ), + 'cart-coupons-by-code' => new Routes\CartCouponsByCode( $this->schemas->get( 'cart-coupon' ) ), + 'cart-items' => new Routes\CartItems( $this->schemas->get( 'cart-item' ) ), + 'cart-items-by-key' => new Routes\CartItemsByKey( $this->schemas->get( 'cart-item' ) ), + 'cart-remove-coupon' => new Routes\CartRemoveCoupon( $this->schemas->get( 'cart' ) ), + 'cart-remove-item' => new Routes\CartRemoveItem( $this->schemas->get( 'cart' ) ), + 'cart-select-shipping-rate' => new Routes\CartSelectShippingRate( $this->schemas->get( 'cart' ) ), + 'cart-update-item' => new Routes\CartUpdateItem( $this->schemas->get( 'cart' ) ), + 'cart-update-shipping' => new Routes\CartUpdateShipping( $this->schemas->get( 'cart' ) ), + 'checkout' => new Routes\Checkout( $this->schemas->get( 'checkout' ) ), + 'product-attributes' => new Routes\ProductAttributes( $this->schemas->get( 'product-attribute' ) ), + 'product-attributes-by-id' => new Routes\ProductAttributesById( $this->schemas->get( 'product-attribute' ) ), + 'product-attribute-terms' => new Routes\ProductAttributeTerms( $this->schemas->get( 'term' ) ), + 'product-categories' => new Routes\ProductCategories( $this->schemas->get( 'product-category' ) ), + 'product-categories-by-id' => new Routes\ProductCategoriesById( $this->schemas->get( 'product-category' ) ), + 'product-collection-data' => new Routes\ProductCollectionData( $this->schemas->get( 'product-collection-data' ) ), + 'product-reviews' => new Routes\ProductReviews( $this->schemas->get( 'product-review' ) ), + 'product-tags' => new Routes\ProductTags( $this->schemas->get( 'term' ) ), + 'products' => new Routes\Products( $this->schemas->get( 'product' ) ), + 'products-by-id' => new Routes\ProductsById( $this->schemas->get( 'product' ) ), + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/SchemaController.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/SchemaController.php new file mode 100644 index 0000000..ff4d38f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/SchemaController.php @@ -0,0 +1,79 @@ +initialize(); + } + + /** + * Get a schema class instance. + * + * @throws Exception If the schema does not exist. + * + * @param string $name Name of schema. + * @return AbstractSchema + */ + public function get( $name ) { + if ( ! isset( $this->schemas[ $name ] ) ) { + throw new Exception( $name . ' schema does not exist' ); + } + return $this->schemas[ $name ]; + } + + /** + * Load schema class instances. + */ + protected function initialize() { + $this->schemas = [ + 'cart' => new Schemas\CartSchema( + new Schemas\CartItemSchema( + new Schemas\ImageAttachmentSchema() + ), + new Schemas\CartCouponSchema(), + new Schemas\CartShippingRateSchema(), + new Schemas\ShippingAddressSchema(), + new Schemas\ErrorSchema() + ), + 'cart-coupon' => new Schemas\CartCouponSchema(), + 'cart-item' => new Schemas\CartItemSchema( + new Schemas\ImageAttachmentSchema() + ), + 'checkout' => new Schemas\CheckoutSchema( + new Schemas\BillingAddressSchema(), + new Schemas\ShippingAddressSchema() + ), + 'product' => new Schemas\ProductSchema( + new Schemas\ImageAttachmentSchema() + ), + 'product-attribute' => new Schemas\ProductAttributeSchema(), + 'product-category' => new Schemas\ProductCategorySchema( + new Schemas\ImageAttachmentSchema() + ), + 'product-collection-data' => new Schemas\ProductCollectionDataSchema(), + 'product-review' => new Schemas\ProductReviewSchema( + new Schemas\ImageAttachmentSchema() + ), + 'term' => new Schemas\TermSchema(), + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/AbstractSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/AbstractSchema.php new file mode 100644 index 0000000..6c4cf0b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/AbstractSchema.php @@ -0,0 +1,258 @@ + 'http://json-schema.org/draft-04/schema#', + 'title' => $this->title, + 'type' => 'object', + 'properties' => $this->get_properties(), + ); + } + + /** + * Returns the public schema. + * + * @return array + */ + public function get_public_item_schema() { + $schema = $this->get_item_schema(); + + foreach ( $schema['properties'] as &$property ) { + unset( $property['arg_options'] ); + } + + return $schema; + } + + /** + * Retrieves an array of endpoint arguments from the item schema for the controller. + * + * @param string $method Optional. HTTP method of the request. + * @return array Endpoint arguments. + */ + public function get_endpoint_args_for_item_schema( $method = \WP_REST_Server::CREATABLE ) { + $schema = $this->get_item_schema(); + $schema_properties = ! empty( $schema['properties'] ) ? $schema['properties'] : array(); + $endpoint_args = array(); + + foreach ( $schema_properties as $field_id => $params ) { + + // Arguments specified as `readonly` are not allowed to be set. + if ( ! empty( $params['readonly'] ) ) { + continue; + } + + $endpoint_args[ $field_id ] = array( + 'validate_callback' => 'rest_validate_request_arg', + 'sanitize_callback' => 'rest_sanitize_request_arg', + ); + + if ( isset( $params['description'] ) ) { + $endpoint_args[ $field_id ]['description'] = $params['description']; + } + + if ( \WP_REST_Server::CREATABLE === $method && isset( $params['default'] ) ) { + $endpoint_args[ $field_id ]['default'] = $params['default']; + } + + if ( \WP_REST_Server::CREATABLE === $method && ! empty( $params['required'] ) ) { + $endpoint_args[ $field_id ]['required'] = true; + } + + foreach ( array( 'type', 'format', 'enum', 'items', 'properties', 'additionalProperties' ) as $schema_prop ) { + if ( isset( $params[ $schema_prop ] ) ) { + $endpoint_args[ $field_id ][ $schema_prop ] = $params[ $schema_prop ]; + } + } + + // Merge in any options provided by the schema property. + if ( isset( $params['arg_options'] ) ) { + + // Only use required / default from arg_options on CREATABLE endpoints. + if ( \WP_REST_Server::CREATABLE !== $method ) { + $params['arg_options'] = array_diff_key( + $params['arg_options'], + array( + 'required' => '', + 'default' => '', + ) + ); + } + + $endpoint_args[ $field_id ] = array_merge( $endpoint_args[ $field_id ], $params['arg_options'] ); + } + } + + return $endpoint_args; + } + + /** + * Force all schema properties to be readonly. + * + * @param array $properties Schema. + * @return array Updated schema. + */ + protected function force_schema_readonly( $properties ) { + return array_map( + function( $property ) { + $property['readonly'] = true; + if ( isset( $property['items']['properties'] ) ) { + $property['items']['properties'] = $this->force_schema_readonly( $property['items']['properties'] ); + } + return $property; + }, + $properties + ); + } + + /** + * Returns consistent currency schema used across endpoints for prices. + * + * @return array + */ + protected function get_store_currency_properties() { + return [ + 'currency_code' => [ + 'description' => __( 'Currency code (in ISO format) for returned prices.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'currency_symbol' => [ + 'description' => __( 'Currency symbol for the currency which can be used to format returned prices.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'currency_minor_unit' => [ + 'description' => __( 'Currency minor unit (number of digits after the decimal separator) for returned prices.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'currency_decimal_separator' => array( + 'description' => __( 'Decimal separator for the currency which can be used to format returned prices.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'currency_thousand_separator' => array( + 'description' => __( 'Thousand separator for the currency which can be used to format returned prices.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'currency_prefix' => array( + 'description' => __( 'Price prefix for the currency which can be used to format returned prices.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'currency_suffix' => array( + 'description' => __( 'Price prefix for the currency which can be used to format returned prices.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ]; + } + + /** + * Prepares a list of store currency data to return in responses. + * + * @todo Core could use a more defined currency object format, making use of + * constants for currency format rather than strings, and holding this type + * of information instead of plugins/blocks needed to normalize things + * themselves. + * + * @return array + */ + protected function get_store_currency_response() { + $position = get_option( 'woocommerce_currency_pos' ); + $symbol = html_entity_decode( get_woocommerce_currency_symbol() ); + $prefix = ''; + $suffix = ''; + + switch ( $position ) { + case 'left_space': + $prefix = $symbol . ' '; + break; + case 'left': + $prefix = $symbol; + break; + case 'right_space': + $suffix = ' ' . $symbol; + break; + case 'right': + $suffix = $symbol; + break; + } + + return [ + 'currency_code' => get_woocommerce_currency(), + 'currency_symbol' => $symbol, + 'currency_minor_unit' => wc_get_price_decimals(), + 'currency_decimal_separator' => wc_get_price_decimal_separator(), + 'currency_thousand_separator' => wc_get_price_thousand_separator(), + 'currency_prefix' => $prefix, + 'currency_suffix' => $suffix, + ]; + } + + /** + * Convert monetary values from WooCommerce to string based integers, using + * the smallest unit of a currency. + * + * @param string|float $amount Monetary amount with decimals. + * @param int $decimals Number of decimals the amount is formatted with. + * @param int $rounding_mode Defaults to the PHP_ROUND_HALF_UP constant. + * @return string The new amount. + */ + protected function prepare_money_response( $amount, $decimals = 2, $rounding_mode = PHP_ROUND_HALF_UP ) { + return (string) intval( + round( + ( (float) wc_format_decimal( $amount ) ) * ( 10 ** $decimals ), + 0, + absint( $rounding_mode ) + ) + ); + } + + /** + * Prepares HTML based content, such as post titles and content, for the API response. + * + * The wptexturize, convert_chars, and trim functions are also used in the `the_title` filter. + * The function wp_kses_post removes disallowed HTML tags. + * + * @param string|array $response Data to format. + * @return string|array Formatted data. + */ + protected function prepare_html_response( $response ) { + if ( is_array( $response ) ) { + return array_map( [ $this, 'prepare_html_response' ], $response ); + } + return is_scalar( $response ) ? wp_kses_post( trim( convert_chars( wptexturize( $response ) ) ) ) : $response; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/BillingAddressSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/BillingAddressSchema.php new file mode 100644 index 0000000..e475eac --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/BillingAddressSchema.php @@ -0,0 +1,125 @@ + [ + 'description' => __( 'First name', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'last_name' => [ + 'description' => __( 'Last name', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'company' => [ + 'description' => __( 'Company', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'address_1' => [ + 'description' => __( 'Address', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'address_2' => [ + 'description' => __( 'Apartment, suite, etc.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'city' => [ + 'description' => __( 'City', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'state' => [ + 'description' => __( 'State/County code, or name of the state, county, province, or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'postcode' => [ + 'description' => __( 'Postal code', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'country' => [ + 'description' => __( 'Country/Region code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'email' => [ + 'description' => __( 'Email', 'woocommerce' ), + 'type' => 'string', + 'format' => 'email', + 'context' => [ 'view', 'edit' ], + ], + 'phone' => [ + 'description' => __( 'Phone', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + ]; + } + + /** + * Convert a term object into an object suitable for the response. + * + * @param \WC_Order|\WC_Customer $address An object with billing address. + * + * @throws RouteException When the invalid object types are provided. + * @return stdClass + */ + public function get_item_response( $address ) { + if ( ( $address instanceof \WC_Customer || $address instanceof \WC_Order ) ) { + return (object) $this->prepare_html_response( + [ + 'first_name' => $address->get_billing_first_name(), + 'last_name' => $address->get_billing_last_name(), + 'company' => $address->get_billing_company(), + 'address_1' => $address->get_billing_address_1(), + 'address_2' => $address->get_billing_address_2(), + 'city' => $address->get_billing_city(), + 'state' => $address->get_billing_state(), + 'postcode' => $address->get_billing_postcode(), + 'country' => $address->get_billing_country(), + 'email' => $address->get_billing_email(), + 'phone' => $address->get_billing_phone(), + ] + ); + } + throw new RouteException( + 'invalid_object_type', + sprintf( + /* translators: Placeholders are class and method names */ + __( '%1$s requires an instance of %2$s or %3$s for the address', 'woocommerce' ), + 'BillingAddressSchema::get_item_response', + 'WC_Customer', + 'WC_Order' + ), + 500 + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartCouponSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartCouponSchema.php new file mode 100644 index 0000000..18995b5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartCouponSchema.php @@ -0,0 +1,95 @@ + [ + 'description' => __( 'The coupons unique code.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'arg_options' => [ + 'sanitize_callback' => 'wc_format_coupon_code', + 'validate_callback' => [ $this, 'coupon_exists' ], + ], + ], + 'totals' => [ + 'description' => __( 'Total amounts provided using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => array_merge( + $this->get_store_currency_properties(), + [ + 'total_discount' => [ + 'description' => __( 'Total discount applied by this coupon.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_discount_tax' => [ + 'description' => __( 'Total tax removed due to discount applied by this coupon.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ] + ), + ], + ]; + } + + /** + * Check given coupon exists. + * + * @param string $coupon_code Coupon code. + * @return bool + */ + public function coupon_exists( $coupon_code ) { + $coupon = new \WC_Coupon( $coupon_code ); + return (bool) $coupon->get_id() || $coupon->get_virtual(); + } + + /** + * Convert a WooCommerce cart item to an object suitable for the response. + * + * @param string $coupon_code Coupon code from the cart. + * @return array + */ + public function get_item_response( $coupon_code ) { + $controller = new CartController(); + $cart = $controller->get_cart_instance(); + $total_discounts = $cart->get_coupon_discount_totals(); + $total_discount_taxes = $cart->get_coupon_discount_tax_totals(); + return [ + 'code' => $coupon_code, + 'totals' => (object) array_merge( + $this->get_store_currency_response(), + [ + 'total_discount' => $this->prepare_money_response( isset( $total_discounts[ $coupon_code ] ) ? $total_discounts[ $coupon_code ] : 0, wc_get_price_decimals() ), + 'total_discount_tax' => $this->prepare_money_response( isset( $total_discount_taxes[ $coupon_code ] ) ? $total_discount_taxes[ $coupon_code ] : 0, wc_get_price_decimals(), PHP_ROUND_HALF_DOWN ), + ] + ), + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartItemSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartItemSchema.php new file mode 100644 index 0000000..8d91f31 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartItemSchema.php @@ -0,0 +1,392 @@ +image_attachment_schema = $image_attachment_schema; + } + + /** + * Cart schema properties. + * + * @return array + */ + public function get_properties() { + return [ + 'key' => [ + 'description' => __( 'Unique identifier for the item within the cart.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'id' => [ + 'description' => __( 'The cart item product or variation ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'quantity' => [ + 'description' => __( 'Quantity of this item in the cart.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'quantity_limit' => [ + 'description' => __( 'The maximum quantity than can be added to the cart at once.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'name' => [ + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'short_description' => [ + 'description' => __( 'Product short description in HTML format.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'description' => [ + 'description' => __( 'Product full description in HTML format.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'sku' => [ + 'description' => __( 'Stock keeping unit, if applicable.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'low_stock_remaining' => [ + 'description' => __( 'Quantity left in stock if stock is low, or null if not applicable.', 'woocommerce' ), + 'type' => [ 'integer', 'null' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'backorders_allowed' => [ + 'description' => __( 'True if backorders are allowed past stock availability.', 'woocommerce' ), + 'type' => [ 'boolean' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'show_backorder_badge' => [ + 'description' => __( 'True if the product is on backorder.', 'woocommerce' ), + 'type' => [ 'boolean' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'sold_individually' => [ + 'description' => __( 'If true, only one item of this product is allowed for purchase in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'permalink' => [ + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'images' => [ + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => $this->image_attachment_schema->get_properties(), + ], + ], + 'variation' => [ + 'description' => __( 'Chosen attributes (for variations).', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'attribute' => [ + 'description' => __( 'Variation attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'value' => [ + 'description' => __( 'Variation attribute value.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + 'prices' => [ + 'description' => __( 'Price data for the product in the current line item, including or excluding taxes based on the "display prices during cart and checkout" setting. Provided using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => array_merge( + $this->get_store_currency_properties(), + [ + 'price' => [ + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'regular_price' => [ + 'description' => __( 'Regular product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'sale_price' => [ + 'description' => __( 'Sale product price, if applicable.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'price_range' => [ + 'description' => __( 'Price range, if applicable.', 'woocommerce' ), + 'type' => [ 'object', 'null' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => [ + 'min_amount' => [ + 'description' => __( 'Price amount.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'max_amount' => [ + 'description' => __( 'Price amount.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + 'raw_prices' => [ + 'description' => __( 'Raw unrounded product prices used in calculations. Provided using a higher unit of precision than the currency.', 'woocommerce' ), + 'type' => [ 'object', 'null' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => [ + 'precision' => [ + 'description' => __( 'Decimal precision of the returned prices.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'price' => [ + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'regular_price' => [ + 'description' => __( 'Regular product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'sale_price' => [ + 'description' => __( 'Sale product price, if applicable.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ] + ), + ], + 'totals' => [ + 'description' => __( 'Item total amounts provided using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => array_merge( + $this->get_store_currency_properties(), + [ + 'line_subtotal' => [ + 'description' => __( 'Line subtotal (the price of the product before coupon discounts have been applied).', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'line_subtotal_tax' => [ + 'description' => __( 'Line subtotal tax.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'line_total' => [ + 'description' => __( 'Line total (the price of the product after coupon discounts have been applied).', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'line_total_tax' => [ + 'description' => __( 'Line total tax.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ] + ), + ], + ]; + } + + /** + * Convert a WooCommerce cart item to an object suitable for the response. + * + * @param array $cart_item Cart item array. + * @return array + */ + public function get_item_response( $cart_item ) { + $product = $cart_item['data']; + + return [ + 'key' => $cart_item['key'], + 'id' => $product->get_id(), + 'quantity' => wc_stock_amount( $cart_item['quantity'] ), + 'quantity_limit' => $this->get_product_quantity_limit( $product ), + 'name' => $this->prepare_html_response( $product->get_title() ), + 'short_description' => $this->prepare_html_response( wc_format_content( $product->get_short_description() ) ), + 'description' => $this->prepare_html_response( wc_format_content( $product->get_description() ) ), + 'sku' => $this->prepare_html_response( $product->get_sku() ), + 'low_stock_remaining' => $this->get_low_stock_remaining( $product ), + 'backorders_allowed' => (bool) $product->backorders_allowed(), + 'show_backorder_badge' => (bool) $product->backorders_require_notification() && $product->is_on_backorder( $cart_item['quantity'] ), + 'sold_individually' => $product->is_sold_individually(), + 'permalink' => $product->get_permalink(), + 'images' => $this->get_images( $product ), + 'variation' => $this->format_variation_data( $cart_item['variation'], $product ), + 'prices' => (object) $this->prepare_product_price_response( $product, get_option( 'woocommerce_tax_display_cart' ) ), + 'totals' => (object) array_merge( + $this->get_store_currency_response(), + [ + 'line_subtotal' => $this->prepare_money_response( $cart_item['line_subtotal'], wc_get_price_decimals() ), + 'line_subtotal_tax' => $this->prepare_money_response( $cart_item['line_subtotal_tax'], wc_get_price_decimals() ), + 'line_total' => $this->prepare_money_response( $cart_item['line_total'], wc_get_price_decimals() ), + 'line_total_tax' => $this->prepare_money_response( $cart_item['line_tax'], wc_get_price_decimals() ), + ] + ), + ]; + } + + /** + * Get an array of pricing data. + * + * @param \WC_Product $product Product instance. + * @param string $tax_display_mode If returned prices are incl or excl of tax. + * @return array + */ + protected function prepare_product_price_response( \WC_Product $product, $tax_display_mode = '' ) { + $tax_display_mode = $this->get_tax_display_mode( $tax_display_mode ); + $price_function = $this->get_price_function_from_tax_display_mode( $tax_display_mode ); + $prices = parent::prepare_product_price_response( $product, $tax_display_mode ); + + // Add raw prices (prices with greater precision). + $prices['raw_prices'] = [ + 'precision' => wc_get_rounding_precision(), + 'price' => $this->prepare_money_response( $price_function( $product ), wc_get_rounding_precision() ), + 'regular_price' => $this->prepare_money_response( $price_function( $product, [ 'price' => $product->get_regular_price() ] ), wc_get_rounding_precision() ), + 'sale_price' => $this->prepare_money_response( $price_function( $product, [ 'price' => $product->get_sale_price() ] ), wc_get_rounding_precision() ), + ]; + + return $prices; + } + + /** + * Returns the remaining stock for a product if it has stock. + * + * This also factors in draft orders. + * + * @param \WC_Product $product Product instance. + * @return integer|null + */ + protected function get_remaining_stock( \WC_Product $product ) { + if ( is_null( $product->get_stock_quantity() ) ) { + return null; + } + + $draft_order = wc()->session->get( 'store_api_draft_order', 0 ); + + if ( \class_exists( '\Automattic\WooCommerce\Checkout\Helpers\ReserveStock' ) ) { + $reserve_stock = new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock(); + } else { + $reserve_stock = new \Automattic\WooCommerce\Blocks\StoreApi\Utilities\ReserveStock(); + } + + $reserved_stock = $reserve_stock->get_reserved_stock( $product, $draft_order ); + return $product->get_stock_quantity() - $reserved_stock; + } + + /** + * Format variation data, for example convert slugs such as attribute_pa_size to Size. + * + * @param array $variation_data Array of data from the cart. + * @param \WC_Product $product Product data. + * @return array + */ + protected function format_variation_data( $variation_data, $product ) { + $return = []; + + foreach ( $variation_data as $key => $value ) { + $taxonomy = wc_attribute_taxonomy_name( str_replace( 'attribute_pa_', '', urldecode( $key ) ) ); + + if ( taxonomy_exists( $taxonomy ) ) { + // If this is a term slug, get the term's nice name. + $term = get_term_by( 'slug', $value, $taxonomy ); + if ( ! is_wp_error( $term ) && $term && $term->name ) { + $value = $term->name; + } + $label = wc_attribute_label( $taxonomy ); + } else { + // If this is a custom option slug, get the options name. + $value = apply_filters( 'woocommerce_variation_option_name', $value, null, $taxonomy, $product ); + $label = wc_attribute_label( str_replace( 'attribute_', '', $key ), $product ); + } + + $return[] = [ + 'attribute' => $this->prepare_html_response( $label ), + 'value' => $this->prepare_html_response( $value ), + ]; + } + + return $return; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartSchema.php new file mode 100644 index 0000000..394be9e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartSchema.php @@ -0,0 +1,332 @@ +item_schema = $item_schema; + $this->coupon_schema = $coupon_schema; + $this->shipping_rate_schema = $shipping_rate_schema; + $this->shipping_address_schema = $shipping_address_schema; + $this->error_schema = $error_schema; + } + + /** + * Cart schema properties. + * + * @return array + */ + public function get_properties() { + return [ + 'coupons' => [ + 'description' => __( 'List of applied cart coupons.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => $this->force_schema_readonly( $this->coupon_schema->get_properties() ), + ], + ], + 'shipping_rates' => [ + 'description' => __( 'List of available shipping rates for the cart.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => $this->force_schema_readonly( $this->shipping_rate_schema->get_properties() ), + ], + ], + 'shipping_address' => [ + 'description' => __( 'Current set shipping address for the customer.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => $this->force_schema_readonly( $this->shipping_address_schema->get_properties() ), + ], + ], + 'items' => [ + 'description' => __( 'List of cart items.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => $this->force_schema_readonly( $this->item_schema->get_properties() ), + ], + ], + 'items_count' => [ + 'description' => __( 'Number of items in the cart.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'items_weight' => [ + 'description' => __( 'Total weight (in grams) of all products in the cart.', 'woocommerce' ), + 'type' => 'number', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'needs_payment' => [ + 'description' => __( 'True if the cart needs payment. False for carts with only free products and no shipping costs.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'needs_shipping' => [ + 'description' => __( 'True if the cart needs shipping. False for carts with only digital goods or stores with no shipping methods set-up.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'totals' => [ + 'description' => __( 'Cart total amounts provided using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => array_merge( + $this->get_store_currency_properties(), + [ + 'total_items' => [ + 'description' => __( 'Total price of items in the cart.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_items_tax' => [ + 'description' => __( 'Total tax on items in the cart.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_fees' => [ + 'description' => __( 'Total price of any applied fees.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_fees_tax' => [ + 'description' => __( 'Total tax on fees.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_discount' => [ + 'description' => __( 'Total discount from applied coupons.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_discount_tax' => [ + 'description' => __( 'Total tax removed due to discount from applied coupons.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_shipping' => [ + 'description' => __( 'Total price of shipping.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_shipping_tax' => [ + 'description' => __( 'Total tax on shipping.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_price' => [ + 'description' => __( 'Total price the customer will pay.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_tax' => [ + 'description' => __( 'Total tax applied to items and shipping.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'tax_lines' => [ + 'description' => __( 'Lines of taxes applied to items and shipping.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'name' => [ + 'description' => __( 'The name of the tax.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'price' => [ + 'description' => __( 'The amount of tax charged.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + ] + ), + ], + 'errors' => [ + 'description' => __( 'List of cart item errors, for example, items in the cart which are out of stock.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => $this->force_schema_readonly( $this->error_schema->get_properties() ), + ], + ], + ]; + } + + /** + * Convert a woo cart into an object suitable for the response. + * + * @param \WC_Cart $cart Cart class instance. + * @return array + */ + public function get_item_response( $cart ) { + $controller = new CartController(); + + // Get cart errors first so if recalculations are performed, it's reflected in the response. + $cart_errors = $this->get_cart_errors( $cart ); + + return [ + 'coupons' => array_values( array_map( [ $this->coupon_schema, 'get_item_response' ], array_filter( $cart->get_applied_coupons() ) ) ), + 'shipping_rates' => array_values( array_map( [ $this->shipping_rate_schema, 'get_item_response' ], $controller->get_shipping_packages() ) ), + 'shipping_address' => $this->shipping_address_schema->get_item_response( wc()->customer ), + 'items' => array_values( array_map( [ $this->item_schema, 'get_item_response' ], array_filter( $cart->get_cart() ) ) ), + 'items_count' => $cart->get_cart_contents_count(), + 'items_weight' => wc_get_weight( $cart->get_cart_contents_weight(), 'g' ), + 'needs_payment' => $cart->needs_payment(), + 'needs_shipping' => $cart->needs_shipping(), + 'totals' => (object) array_merge( + $this->get_store_currency_response(), + [ + 'total_items' => $this->prepare_money_response( $cart->get_subtotal(), wc_get_price_decimals() ), + 'total_items_tax' => $this->prepare_money_response( $cart->get_subtotal_tax(), wc_get_price_decimals() ), + 'total_fees' => $this->prepare_money_response( $cart->get_fee_total(), wc_get_price_decimals() ), + 'total_fees_tax' => $this->prepare_money_response( $cart->get_fee_tax(), wc_get_price_decimals() ), + 'total_discount' => $this->prepare_money_response( $cart->get_discount_total(), wc_get_price_decimals() ), + 'total_discount_tax' => $this->prepare_money_response( $cart->get_discount_tax(), wc_get_price_decimals() ), + 'total_shipping' => $this->prepare_money_response( $cart->get_shipping_total(), wc_get_price_decimals() ), + 'total_shipping_tax' => $this->prepare_money_response( $cart->get_shipping_tax(), wc_get_price_decimals() ), + + // Explicitly request context='edit'; default ('view') will render total as markup. + 'total_price' => $this->prepare_money_response( $cart->get_total( 'edit' ), wc_get_price_decimals() ), + 'total_tax' => $this->prepare_money_response( $cart->get_total_tax(), wc_get_price_decimals() ), + 'tax_lines' => $this->get_tax_lines( $cart ), + ] + ), + 'errors' => $cart_errors, + ]; + } + + /** + * Get tax lines from the cart and format to match schema. + * + * @param \WC_Cart $cart Cart class instance. + * @return array + */ + protected function get_tax_lines( $cart ) { + $cart_tax_totals = $cart->get_tax_totals(); + $tax_lines = []; + + foreach ( $cart_tax_totals as $cart_tax_total ) { + $tax_lines[] = array( + 'name' => $cart_tax_total->label, + 'price' => $this->prepare_money_response( $cart_tax_total->amount, wc_get_price_decimals() ), + ); + } + + return $tax_lines; + } + + /** + * Get cart validation errors. + * + * @param \WC_Cart $cart Cart class instance. + * @return array + */ + protected function get_cart_errors( $cart ) { + $controller = new CartController(); + $item_errors = $controller->get_cart_item_errors(); + $coupon_errors = $controller->get_cart_coupon_errors(); + + return array_values( array_map( [ $this->error_schema, 'get_item_response' ], array_merge( $item_errors, $coupon_errors ) ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartShippingRateSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartShippingRateSchema.php new file mode 100644 index 0000000..49da083 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CartShippingRateSchema.php @@ -0,0 +1,345 @@ + [ + 'description' => __( 'The ID of the package the shipping rates belong to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'name' => [ + 'description' => __( 'Name of the package.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'destination' => [ + 'description' => __( 'Shipping destination address.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => [ + 'address_1' => [ + 'description' => __( 'First line of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'address_2' => [ + 'description' => __( 'Second line of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'city' => [ + 'description' => __( 'City of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'state' => [ + 'description' => __( 'ISO code, or name, for the state, province, or district of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'postcode' => [ + 'description' => __( 'Zip or Postcode of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'country' => [ + 'description' => __( 'ISO code for the country of the address being shipped to.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + 'items' => [ + 'description' => __( 'List of cart items the returned shipping rates apply to.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'key' => [ + 'description' => __( 'Unique identifier for the item within the cart.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'name' => [ + 'description' => __( 'Name of the item.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'quantity' => [ + 'description' => __( 'Quantity of the item in the current package.', 'woocommerce' ), + 'type' => 'number', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + 'shipping_rates' => [ + 'description' => __( 'List of shipping rates.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => $this->get_rate_properties(), + ], + ], + ]; + } + + /** + * Schema for a single rate. + * + * @return array + */ + protected function get_rate_properties() { + return array_merge( + [ + 'rate_id' => [ + 'description' => __( 'ID of the shipping rate.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'name' => [ + 'description' => __( 'Name of the shipping rate, e.g. Express shipping.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'description' => [ + 'description' => __( 'Description of the shipping rate, e.g. Dispatched via USPS.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'delivery_time' => [ + 'description' => __( 'Delivery time estimate text, e.g. 3-5 business days.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'price' => [ + 'description' => __( 'Price of this shipping rate using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'taxes' => [ + 'description' => __( 'Taxes applied to this shipping rate using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'method_id' => [ + 'description' => __( 'ID of the shipping method that provided the rate.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'instance_id' => [ + 'description' => __( 'Instance ID of the shipping method that provided the rate.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'meta_data' => [ + 'description' => __( 'Meta data attached to the shipping rate.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'key' => [ + 'description' => __( 'Meta key.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'value' => [ + 'description' => __( 'Meta value.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + 'selected' => [ + 'description' => __( 'True if this is the rate currently selected by the customer for the cart.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + $this->get_store_currency_properties() + ); + } + + /** + * Convert a shipping rate from WooCommerce into a valid response. + * + * @param array $package Shipping package complete with rates from WooCommerce. + * @return array + */ + public function get_item_response( $package ) { + // Add product names and quantities. + $items = array(); + foreach ( $package['contents'] as $item_id => $values ) { + $items[] = [ + 'key' => $item_id, + 'name' => $values['data']->get_name(), + 'quantity' => $values['quantity'], + ]; + } + + // Generate package name. + $package_number = absint( $package['package_id'] ) + 1; + $package_display_name = apply_filters( + 'woocommerce_shipping_package_name', + $package_number > 1 ? + sprintf( + /* translators: %d: shipping package number */ + _x( 'Shipping %d', 'shipping packages', 'woocommerce' ), + $package_number + ) : + _x( 'Shipping', 'shipping packages', 'woocommerce' ), + $package['package_id'], + $package + ); + + return [ + 'package_id' => $package['package_id'], + 'name' => $package_display_name, + 'destination' => (object) $this->prepare_html_response( + [ + 'address_1' => $package['destination']['address_1'], + 'address_2' => $package['destination']['address_2'], + 'city' => $package['destination']['city'], + 'state' => $package['destination']['state'], + 'postcode' => $package['destination']['postcode'], + 'country' => $package['destination']['country'], + ] + ), + 'items' => $items, + 'shipping_rates' => $this->prepare_rates_response( $package ), + ]; + } + + /** + * Prepare an array of rates from a package for the response. + * + * @param array $package Shipping package complete with rates from WooCommerce. + * @return array + */ + protected function prepare_rates_response( $package ) { + $rates = $package['rates']; + $selected_rates = wc()->session->get( 'chosen_shipping_methods', array() ); + $selected_rate = isset( $chosen_shipping_methods[ $package['package_id'] ] ) ? $chosen_shipping_methods[ $package['package_id'] ] : ''; + + if ( empty( $selected_rate ) && ! empty( $package['rates'] ) ) { + $selected_rate = wc_get_chosen_shipping_method_for_package( $package['package_id'], $package ); + } + + $response = []; + + foreach ( $package['rates'] as $rate ) { + $response[] = $this->get_rate_response( $rate, $selected_rate ); + } + + return $response; + } + + /** + * Response for a single rate. + * + * @param WC_Shipping_Rate $rate Rate object. + * @param string $selected_rate Selected rate. + * @return array + */ + protected function get_rate_response( $rate, $selected_rate = '' ) { + return array_merge( + [ + 'rate_id' => $this->get_rate_prop( $rate, 'id' ), + 'name' => $this->prepare_html_response( $this->get_rate_prop( $rate, 'label' ) ), + 'description' => $this->prepare_html_response( $this->get_rate_prop( $rate, 'description' ) ), + 'delivery_time' => $this->prepare_html_response( $this->get_rate_prop( $rate, 'delivery_time' ) ), + 'price' => $this->prepare_money_response( $this->get_rate_prop( $rate, 'cost' ), wc_get_price_decimals() ), + 'taxes' => $this->prepare_money_response( array_sum( $this->get_rate_prop( $rate, 'taxes' ) ), wc_get_price_decimals() ), + 'instance_id' => $this->get_rate_prop( $rate, 'instance_id' ), + 'method_id' => $this->get_rate_prop( $rate, 'method_id' ), + 'meta_data' => $this->get_rate_meta_data( $rate ), + 'selected' => $selected_rate === $this->get_rate_prop( $rate, 'id' ), + ], + $this->get_store_currency_response() + ); + } + + /** + * Gets a prop of the rate object, if callable. + * + * @param WC_Shipping_Rate $rate Rate object. + * @param string $prop Prop name. + * @return string + */ + protected function get_rate_prop( $rate, $prop ) { + $getter = 'get_' . $prop; + return \is_callable( array( $rate, $getter ) ) ? $rate->$getter() : ''; + } + + /** + * Converts rate meta data into a suitable response object. + * + * @param WC_Shipping_Rate $rate Rate object. + * @return array + */ + protected function get_rate_meta_data( $rate ) { + $meta_data = $rate->get_meta_data(); + + return array_reduce( + array_keys( $meta_data ), + function( $return, $key ) use ( $meta_data ) { + $return[] = [ + 'key' => $key, + 'value' => $meta_data[ $key ], + ]; + return $return; + }, + [] + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CheckoutSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CheckoutSchema.php new file mode 100644 index 0000000..ba4e546 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/CheckoutSchema.php @@ -0,0 +1,195 @@ +billing_address_schema = $billing_address_schema; + $this->shipping_address_schema = $shipping_address_schema; + } + + /** + * Checkout schema properties. + * + * @return array + */ + public function get_properties() { + return [ + 'order_id' => [ + 'description' => __( 'The order ID to process during checkout.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'status' => [ + 'description' => __( 'Order status. Payment providers will update this value after payment.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'order_key' => [ + 'description' => __( 'Order key used to check validity or protect access to certain order data.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'customer_note' => [ + 'description' => __( 'Note added to the order by the customer during checkout.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'customer_id' => [ + 'description' => __( 'Customer ID if registered. Will return 0 for guests.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'billing_address' => [ + 'description' => __( 'Billing address.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'properties' => $this->billing_address_schema->get_properties(), + ], + 'shipping_address' => [ + 'description' => __( 'Shipping address.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'properties' => $this->shipping_address_schema->get_properties(), + ], + 'payment_method' => [ + 'description' => __( 'The ID of the payment method being used to process the payment.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'create_account' => [ + 'description' => __( 'Whether to create a new user account as part of order processing.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + ], + 'payment_result' => [ + 'description' => __( 'Result of payment processing, or false if not yet processed.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => [ + 'payment_status' => [ + 'description' => __( 'Status of the payment returned by the gateway. One of success, pending, failure, error.', 'woocommerce' ), + 'readonly' => true, + 'type' => 'string', + ], + 'payment_details' => [ + 'description' => __( 'An array of data being returned from the payment gateway.', 'woocommerce' ), + 'readonly' => true, + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'key' => [ + 'type' => 'string', + ], + 'value' => [ + 'type' => 'string', + ], + ], + ], + ], + 'redirect_url' => [ + 'description' => __( 'A URL to redirect the customer after checkout. This could be, for example, a link to the payment processors website.', 'woocommerce' ), + 'readonly' => true, + 'type' => 'string', + ], + ], + ], + ]; + } + + /** + * Return the response for checkout. + * + * @param object $item Results from checkout action. + * @return array + */ + public function get_item_response( $item ) { + return $this->get_checkout_response( $item->order, $item->payment_result ); + } + + /** + * Get the checkout response based on the current order and any payments. + * + * @param \WC_Order $order Order object. + * @param PaymentResult $payment_result Payment result object. + * @return array + */ + protected function get_checkout_response( \WC_Order $order, PaymentResult $payment_result = null ) { + return [ + 'order_id' => $order->get_id(), + 'status' => $order->get_status(), + 'order_key' => $order->get_order_key(), + 'customer_note' => $order->get_customer_note(), + 'customer_id' => $order->get_customer_id(), + 'billing_address' => $this->billing_address_schema->get_item_response( $order ), + 'shipping_address' => $this->shipping_address_schema->get_item_response( $order ), + 'payment_method' => $order->get_payment_method(), + 'payment_result' => [ + 'payment_status' => $payment_result->status, + 'payment_details' => $this->prepare_payment_details_for_response( $payment_result->payment_details ), + 'redirect_url' => $payment_result->redirect_url, + ], + ]; + } + + /** + * This prepares the payment details for the response so it's following the + * schema where it's an array of objects. + * + * @param array $payment_details An array of payment details from the processed payment. + * + * @return array An array of objects where each object has the key and value + * as distinct properties. + */ + protected function prepare_payment_details_for_response( array $payment_details ) { + return array_map( + function( $key, $value ) { + return (object) [ + 'key' => $key, + 'value' => $value, + ]; + }, + array_keys( $payment_details ), + $payment_details + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ErrorSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ErrorSchema.php new file mode 100644 index 0000000..2aa5e6a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ErrorSchema.php @@ -0,0 +1,53 @@ + [ + 'description' => __( 'Error code', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'message' => [ + 'description' => __( 'Error message', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ]; + } + + /** + * Convert a WooCommerce product into an object suitable for the response. + * + * @param \WP_Error $error Error object. + * @return array + */ + public function get_item_response( \WP_Error $error ) { + return [ + 'code' => $this->prepare_html_response( $error->get_error_code() ), + 'message' => $this->prepare_html_response( $error->get_error_message() ), + ]; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ImageAttachmentSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ImageAttachmentSchema.php new file mode 100644 index 0000000..ec59ab3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ImageAttachmentSchema.php @@ -0,0 +1,94 @@ + [ + 'description' => __( 'Image ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + ], + 'src' => [ + 'description' => __( 'Full size image URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => [ 'view', 'edit' ], + ], + 'thumbnail' => [ + 'description' => __( 'Thumbnail URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => [ 'view', 'edit' ], + ], + 'srcset' => [ + 'description' => __( 'Thumbnail srcset for responsive images.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'sizes' => [ + 'description' => __( 'Thumbnail sizes for responsive images.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'name' => [ + 'description' => __( 'Image name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'alt' => [ + 'description' => __( 'Image alternative text.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + ]; + } + + /** + * Convert a WooCommerce product into an object suitable for the response. + * + * @param int $attachment_id Image attachment ID. + * @return array|null + */ + public function get_item_response( $attachment_id ) { + if ( ! $attachment_id ) { + return null; + } + + $attachment = wp_get_attachment_image_src( $attachment_id, 'full' ); + + if ( ! is_array( $attachment ) ) { + return []; + } + + $thumbnail = wp_get_attachment_image_src( $attachment_id, 'woocommerce_thumbnail' ); + + return [ + 'id' => (int) $attachment_id, + 'src' => current( $attachment ), + 'thumbnail' => current( $thumbnail ), + 'srcset' => (string) wp_get_attachment_image_srcset( $attachment_id, 'full' ), + 'sizes' => (string) wp_get_attachment_image_sizes( $attachment_id, 'full' ), + 'name' => get_the_title( $attachment_id ), + 'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ), + ]; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/OrderCouponSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/OrderCouponSchema.php new file mode 100644 index 0000000..dd83bcb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/OrderCouponSchema.php @@ -0,0 +1,74 @@ + [ + 'description' => __( 'The coupons unique code.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'totals' => [ + 'description' => __( 'Total amounts provided using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => array_merge( + $this->get_store_currency_properties(), + [ + 'total_discount' => [ + 'description' => __( 'Total discount applied by this coupon.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'total_discount_tax' => [ + 'description' => __( 'Total tax removed due to discount applied by this coupon.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ] + ), + ], + ]; + } + + /** + * Convert an order coupon to an object suitable for the response. + * + * @param \WC_Order_Item_Coupon $coupon Order coupon array. + * @return array + */ + public function get_item_response( \WC_Order_Item_Coupon $coupon ) { + return [ + 'code' => $coupon->get_code(), + 'totals' => (object) array_merge( + $this->get_store_currency_response(), + [ + 'total_discount' => $this->prepare_money_response( $coupon->get_discount(), wc_get_price_decimals() ), + 'total_discount_tax' => $this->prepare_money_response( $coupon->get_discount_tax(), wc_get_price_decimals(), PHP_ROUND_HALF_DOWN ), + ] + ), + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductAttributeSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductAttributeSchema.php new file mode 100644 index 0000000..6ed591d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductAttributeSchema.php @@ -0,0 +1,87 @@ + array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'taxonomy' => array( + 'description' => __( 'The attribute taxonomy name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'type' => array( + 'description' => __( 'Attribute type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order' => array( + 'description' => __( 'How terms in this attribute are sorted by default.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'has_archives' => array( + 'description' => __( 'If this attribute has term archive pages.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'count' => array( + 'description' => __( 'Number of terms in the attribute taxonomy.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ]; + } + + /** + * Convert an attribute object into an object suitable for the response. + * + * @param object $attribute Attribute object. + * @return array + */ + public function get_item_response( $attribute ) { + return [ + 'id' => (int) $attribute->id, + 'name' => $this->prepare_html_response( $attribute->name ), + 'taxonomy' => $attribute->slug, + 'type' => $attribute->type, + 'order' => $attribute->order_by, + 'has_archives' => $attribute->has_archives, + 'count' => (int) \wp_count_terms( $attribute->slug ), + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductCategorySchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductCategorySchema.php new file mode 100644 index 0000000..0fec9e7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductCategorySchema.php @@ -0,0 +1,105 @@ +image_attachment_schema = $image_attachment_schema; + } + + /** + * Term properties. + * + * @return array + */ + public function get_properties() { + $schema = parent::get_properties(); + $schema['image'] = [ + 'description' => __( 'Category image.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit', 'embed' ], + 'readonly' => true, + 'properties' => $this->image_attachment_schema->get_properties(), + ]; + $schema['review_count'] = [ + 'description' => __( 'Number of reviews for products in this category.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ]; + $schema['permalink'] = [ + 'description' => __( 'Category URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => [ 'view', 'edit', 'embed' ], + 'readonly' => true, + ]; + return $schema; + } + + /** + * Convert a term object into an object suitable for the response. + * + * @param \WP_Term $term Term object. + * @return array + */ + public function get_item_response( $term ) { + $response = parent::get_item_response( $term ); + $count = get_term_meta( $term->term_id, 'product_count_product_cat', true ); + + if ( $count ) { + $response['count'] = (int) $count; + } + + $response['image'] = $this->image_attachment_schema->get_item_response( get_term_meta( $term->term_id, 'thumbnail_id', true ) ); + $response['review_count'] = $this->get_category_review_count( $term ); + $response['permalink'] = get_term_link( $term->term_id, 'product_cat' ); + + return $response; + } + + /** + * Get total number of reviews for products in a category. + * + * @param \WP_Term $term Term object. + * @return int + */ + protected function get_category_review_count( $term ) { + global $wpdb; + + $products_of_category_sql = $wpdb->prepare( + "SELECT SUM( DISTINCT comment_count) as review_count + FROM {$wpdb->posts} AS posts + INNER JOIN {$wpdb->term_relationships} AS term_relationships ON posts.ID = term_relationships.object_id + WHERE term_relationships.term_taxonomy_id=%d", + $term->term_id + ); + + $review_count = $wpdb->get_var( $products_of_category_sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + + return (int) $review_count; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductCollectionDataSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductCollectionDataSchema.php new file mode 100644 index 0000000..d2d538d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductCollectionDataSchema.php @@ -0,0 +1,116 @@ + [ + 'description' => __( 'Min and max prices found in collection of products, provided using the smallest unit of the currency.', 'woocommerce' ), + 'type' => [ 'object', 'null' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => array_merge( + $this->get_store_currency_properties(), + [ + 'min_price' => [ + 'description' => __( 'Min price found in collection of products.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'max_price' => [ + 'description' => __( 'Max price found in collection of products.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ] + ), + ], + 'attribute_counts' => [ + 'description' => __( 'Returns number of products within attribute terms.', 'woocommerce' ), + 'type' => [ 'array', 'null' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'term' => [ + 'description' => __( 'Term ID', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'count' => [ + 'description' => __( 'Number of products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + 'rating_counts' => [ + 'description' => __( 'Returns number of products with each average rating.', 'woocommerce' ), + 'type' => [ 'array', 'null' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'rating' => [ + 'description' => __( 'Average rating', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'count' => [ + 'description' => __( 'Number of products.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + ]; + } + + /** + * Format data. + * + * @param array $data Collection data to format and return. + * @return array + */ + public function get_item_response( $data ) { + return [ + 'price_range' => ! is_null( $data['min_price'] ) && ! is_null( $data['max_price'] ) ? (object) array_merge( + $this->get_store_currency_response(), + [ + 'min_price' => $this->prepare_money_response( $data['min_price'], wc_get_price_decimals() ), + 'max_price' => $this->prepare_money_response( $data['max_price'], wc_get_price_decimals() ), + ] + ) : null, + 'attribute_counts' => $data['attribute_counts'], + 'rating_counts' => $data['rating_counts'], + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductReviewSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductReviewSchema.php new file mode 100644 index 0000000..3c04ebe --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductReviewSchema.php @@ -0,0 +1,176 @@ +image_attachment_schema = $image_attachment_schema; + } + + /** + * Product review schema properties. + * + * @return array + */ + public function get_properties() { + $properties = [ + 'id' => [ + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'date_created' => [ + 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'formatted_date_created' => [ + 'description' => __( "The date the review was created, in the site's timezone in human-readable format.", 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'date_created_gmt' => [ + 'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'date-time', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'product_id' => [ + 'description' => __( 'Unique identifier for the product that the review belongs to.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'product_name' => [ + 'description' => __( 'Name of the product that the review belongs to.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'product_permalink' => [ + 'description' => __( 'Permalink of the product that the review belongs to.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'product_image' => [ + 'description' => __( 'Image of the product that the review belongs to.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => $this->image_attachment_schema->get_properties(), + ], + 'reviewer' => [ + 'description' => __( 'Reviewer name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'review' => [ + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'arg_options' => [ + 'sanitize_callback' => 'wp_filter_post_kses', + ], + 'readonly' => true, + ], + 'rating' => [ + 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'verified' => [ + 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ]; + + if ( get_option( 'show_avatars' ) ) { + $avatar_properties = array(); + $avatar_sizes = rest_get_avatar_sizes(); + + foreach ( $avatar_sizes as $size ) { + $avatar_properties[ $size ] = array( + /* translators: %d: avatar image size in pixels */ + 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.', 'woocommerce' ), $size ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'embed', 'view', 'edit' ), + ); + } + $properties['reviewer_avatar_urls'] = array( + 'description' => __( 'Avatar URLs for the object reviewer.', 'woocommerce' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $avatar_properties, + ); + } + + return $properties; + } + + /** + * Convert a WooCommerce product into an object suitable for the response. + * + * @param \WP_Comment $review Product review object. + * @return array + */ + public function get_item_response( \WP_Comment $review ) { + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $rating = get_comment_meta( $review->comment_ID, 'rating', true ) === '' ? null : (int) get_comment_meta( $review->comment_ID, 'rating', true ); + $data = [ + 'id' => (int) $review->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $review->comment_date ), + 'formatted_date_created' => get_comment_date( 'F j, Y', $review->comment_ID ), + 'date_created_gmt' => wc_rest_prepare_date_response( $review->comment_date_gmt ), + 'product_id' => (int) $review->comment_post_ID, + 'product_name' => get_the_title( (int) $review->comment_post_ID ), + 'product_permalink' => get_permalink( (int) $review->comment_post_ID ), + 'product_image' => $this->image_attachment_schema->get_item_response( get_post_thumbnail_id( (int) $review->comment_post_ID ) ), + 'reviewer' => $review->comment_author, + 'review' => $review->comment_content, + 'rating' => $rating, + 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), + 'reviewer_avatar_urls' => rest_get_avatar_urls( $review->comment_author_email ), + ]; + + if ( 'view' === $context ) { + $data['review'] = wpautop( $data['review'] ); + } + + return $data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductSchema.php new file mode 100644 index 0000000..428c5e0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductSchema.php @@ -0,0 +1,779 @@ +image_attachment_schema = $image_attachment_schema; + } + + /** + * Product schema properties. + * + * @return array + */ + public function get_properties() { + return [ + 'id' => [ + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'name' => [ + 'description' => __( 'Product name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'parent' => [ + 'description' => __( 'ID of the parent product, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'type' => [ + 'description' => __( 'Product type.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'variation' => [ + 'description' => __( 'Product variation attributes, if applicable.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'permalink' => [ + 'description' => __( 'Product URL.', 'woocommerce' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'short_description' => [ + 'description' => __( 'Product short description in HTML format.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'description' => [ + 'description' => __( 'Product full description in HTML format.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'on_sale' => [ + 'description' => __( 'Is the product on sale?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'sku' => [ + 'description' => __( 'Unique identifier.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'prices' => [ + 'description' => __( 'Price data provided using the smallest unit of the currency.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => array_merge( + $this->get_store_currency_properties(), + [ + 'price' => [ + 'description' => __( 'Current product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'regular_price' => [ + 'description' => __( 'Regular product price.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'sale_price' => [ + 'description' => __( 'Sale product price, if applicable.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'price_range' => [ + 'description' => __( 'Price range, if applicable.', 'woocommerce' ), + 'type' => [ 'object', 'null' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => [ + 'min_amount' => [ + 'description' => __( 'Price amount.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'max_amount' => [ + 'description' => __( 'Price amount.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ] + ), + ], + 'price_html' => array( + 'description' => __( 'Price string formatted as HTML.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'average_rating' => [ + 'description' => __( 'Reviews average rating.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'review_count' => [ + 'description' => __( 'Amount of reviews that the product has.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'images' => [ + 'description' => __( 'List of images.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'items' => [ + 'type' => 'object', + 'properties' => $this->image_attachment_schema->get_properties(), + ], + ], + 'categories' => [ + 'description' => __( 'List of categories, if applicable.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'id' => [ + 'description' => __( 'Category ID', 'woocommerce' ), + 'type' => 'number', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'name' => [ + 'description' => __( 'Category name', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'slug' => [ + 'description' => __( 'Category slug', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'link' => [ + 'description' => __( 'Category link', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + 'tags' => [ + 'description' => __( 'List of tags, if applicable.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'id' => [ + 'description' => __( 'Tag ID', 'woocommerce' ), + 'type' => 'number', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'name' => [ + 'description' => __( 'Tag name', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'slug' => [ + 'description' => __( 'Tag slug', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'link' => [ + 'description' => __( 'Tag link', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + 'attributes' => [ + 'description' => __( 'List of attributes assigned to the product/variation that are visible or used for variations.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'id' => [ + 'description' => __( 'The attribute ID, or 0 if the attribute is not taxonomy based.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'name' => [ + 'description' => __( 'The attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'taxonomy' => [ + 'description' => __( 'The attribute taxonomy, or null if the attribute is not taxonomy based.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'has_variations' => [ + 'description' => __( 'True if this attribute is used by product variations.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'terms' => [ + 'description' => __( 'List of assigned attribute terms.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'id' => [ + 'description' => __( 'The term ID, or 0 if the attribute is not a global attribute.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'name' => [ + 'description' => __( 'The term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'slug' => [ + 'description' => __( 'The term slug.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + ], + ], + ], + 'variations' => [ + 'description' => __( 'List of variation IDs, if applicable.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'id' => [ + 'description' => __( 'The attribute ID, or 0 if the attribute is not taxonomy based.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'attributes' => [ + 'description' => __( 'List of variation attributes.', 'woocommerce' ), + 'type' => 'array', + 'context' => [ 'view', 'edit' ], + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'name' => [ + 'description' => __( 'The attribute name.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'value' => [ + 'description' => __( 'The assigned attribute.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ], + ], + ], + ], + 'has_options' => [ + 'description' => __( 'Does the product have additional options before it can be added to the cart?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'is_purchasable' => [ + 'description' => __( 'Is the product purchasable?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'is_in_stock' => [ + 'description' => __( 'Is the product in stock?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'is_on_backorder' => [ + 'description' => __( 'Is the product stock backordered? This will also return false if backorder notifications are turned off.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'low_stock_remaining' => [ + 'description' => __( 'Quantity left in stock if stock is low, or null if not applicable.', 'woocommerce' ), + 'type' => [ 'integer', 'null' ], + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'sold_individually' => [ + 'description' => __( 'If true, only one item of this product is allowed for purchase in a single order.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'quantity_limit' => [ + 'description' => __( 'The maximum quantity than can be added to the cart at once.', 'woocommerce' ), + 'type' => 'integer', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'add_to_cart' => [ + 'description' => __( 'Add to cart button parameters.', 'woocommerce' ), + 'type' => 'object', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + 'properties' => [ + 'text' => [ + 'description' => __( 'Button text.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'description' => [ + 'description' => __( 'Button description.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + 'url' => [ + 'description' => __( 'Add to cart URL.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + 'readonly' => true, + ], + ], + ], + ]; + } + + /** + * Convert a WooCommerce product into an object suitable for the response. + * + * @param \WC_Product $product Product instance. + * @return array + */ + public function get_item_response( $product ) { + return [ + 'id' => $product->get_id(), + 'name' => $this->prepare_html_response( $product->get_title() ), + 'parent' => $product->get_parent_id(), + 'type' => $product->get_type(), + 'variation' => $this->prepare_html_response( $product->is_type( 'variation' ) ? wc_get_formatted_variation( $product, true, true, false ) : '' ), + 'permalink' => $product->get_permalink(), + 'sku' => $this->prepare_html_response( $product->get_sku() ), + 'short_description' => $this->prepare_html_response( wc_format_content( $product->get_short_description() ) ), + 'description' => $this->prepare_html_response( wc_format_content( $product->get_description() ) ), + 'on_sale' => $product->is_on_sale(), + 'prices' => (object) $this->prepare_product_price_response( $product ), + 'price_html' => $product->get_price_html(), + 'average_rating' => $product->get_average_rating(), + 'review_count' => $product->get_review_count(), + 'images' => $this->get_images( $product ), + 'categories' => $this->get_term_list( $product, 'product_cat' ), + 'tags' => $this->get_term_list( $product, 'product_tag' ), + 'attributes' => $this->get_attributes( $product ), + 'variations' => $this->get_variations( $product ), + 'has_options' => $product->has_options(), + 'is_purchasable' => $product->is_purchasable(), + 'is_in_stock' => $product->is_in_stock(), + 'is_on_backorder' => 'onbackorder' === $product->get_stock_status(), + 'low_stock_remaining' => $this->get_low_stock_remaining( $product ), + 'sold_individually' => $product->is_sold_individually(), + 'quantity_limit' => $this->get_product_quantity_limit( $product ), + 'add_to_cart' => (object) $this->prepare_html_response( + [ + 'text' => $product->add_to_cart_text(), + 'description' => $product->add_to_cart_description(), + 'url' => $product->add_to_cart_url(), + ] + ), + ]; + } + + /** + * Get list of product images. + * + * @param \WC_Product $product Product instance. + * @return array + */ + protected function get_images( \WC_Product $product ) { + $attachment_ids = array_merge( [ $product->get_image_id() ], $product->get_gallery_image_ids() ); + + return array_filter( array_map( [ $this->image_attachment_schema, 'get_item_response' ], $attachment_ids ) ); + } + + /** + * Gets remaining stock amount for a product. + * + * @param \WC_Product $product Product instance. + * @return integer|null + */ + protected function get_remaining_stock( \WC_Product $product ) { + if ( is_null( $product->get_stock_quantity() ) ) { + return null; + } + return $product->get_stock_quantity(); + } + + /** + * If a product has low stock, return the remaining stock amount for display. + * + * @param \WC_Product $product Product instance. + * @return integer|null + */ + protected function get_low_stock_remaining( \WC_Product $product ) { + $remaining_stock = $this->get_remaining_stock( $product ); + + if ( ! is_null( $remaining_stock ) && $remaining_stock <= wc_get_low_stock_amount( $product ) ) { + return max( $remaining_stock, 0 ); + } + + return null; + } + + /** + * Get the quantity limit for an item in the cart. + * + * @param \WC_Product $product Product instance. + * @return int + */ + protected function get_product_quantity_limit( \WC_Product $product ) { + $limits = [ 99 ]; + + if ( $product->is_sold_individually() ) { + $limits[] = 1; + } elseif ( ! $product->backorders_allowed() ) { + $limits[] = $this->get_remaining_stock( $product ); + } + + return apply_filters( 'woocommerce_store_api_product_quantity_limit', max( min( array_filter( $limits ) ), 1 ), $product ); + } + + /** + * Returns true if the given attribute is valid. + * + * @param mixed $attribute Object or variable to check. + * @return boolean + */ + protected function filter_valid_attribute( $attribute ) { + return is_a( $attribute, '\WC_Product_Attribute' ); + } + + /** + * Returns true if the given attribute is valid and used for variations. + * + * @param mixed $attribute Object or variable to check. + * @return boolean + */ + protected function filter_variation_attribute( $attribute ) { + return $this->filter_valid_attribute( $attribute ) && $attribute->get_variation(); + } + + /** + * Get variation IDs and attributes from the DB. + * + * @param \WC_Product $product Product instance. + * @returns array + */ + protected function get_variations( \WC_Product $product ) { + if ( ! $product->is_type( 'variable' ) ) { + return []; + } + global $wpdb; + + $variation_ids = $product->get_visible_children(); + $attributes = array_filter( $product->get_attributes(), [ $this, 'filter_variation_attribute' ] ); + $default_variation_meta_data = array_reduce( + $attributes, + function( $defaults, $attribute ) use ( $product ) { + $meta_key = wc_variation_attribute_name( $attribute->get_name() ); + $defaults[ $meta_key ] = [ + 'name' => wc_attribute_label( $attribute->get_name(), $product ), + 'value' => null, + ]; + return $defaults; + }, + [] + ); + + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared + $variation_meta_data = $wpdb->get_results( + " + SELECT post_id as variation_id, meta_key as attribute_key, meta_value as attribute_value + FROM {$wpdb->postmeta} + WHERE post_id IN (" . implode( ',', array_map( 'esc_sql', $variation_ids ) ) . ") + AND meta_key IN ('" . implode( "','", array_map( 'esc_sql', array_keys( $default_variation_meta_data ) ) ) . "') + " + ); + // phpcs:enable + + $attributes_by_variation = array_reduce( + $variation_meta_data, + function( $values, $data ) { + $values[ $data->variation_id ][ $data->attribute_key ] = $data->attribute_value; + return $values; + }, + array_fill_keys( $variation_ids, [] ) + ); + + $variations = []; + + foreach ( $variation_ids as $variation_id ) { + $attribute_data = $default_variation_meta_data; + + foreach ( $attributes_by_variation[ $variation_id ] as $meta_key => $meta_value ) { + if ( '' !== $meta_value ) { + $attribute_data[ $meta_key ]['value'] = $meta_value; + } + } + + $variations[] = (object) [ + 'id' => $variation_id, + 'attributes' => array_values( $attribute_data ), + ]; + } + + return $variations; + } + + /** + * Get list of product attributes and attribute terms. + * + * @param \WC_Product $product Product instance. + * @return array + */ + protected function get_attributes( \WC_Product $product ) { + $attributes = array_filter( $product->get_attributes(), [ $this, 'filter_valid_attribute' ] ); + $return = []; + + foreach ( $attributes as $attribute_slug => $attribute ) { + // Only visible and variation attributes will be exposed by this API. + if ( ! $attribute->get_visible() || ! $attribute->get_variation() ) { + continue; + } + $return[] = (object) [ + 'id' => $attribute->get_id(), + 'name' => wc_attribute_label( $attribute->get_name(), $product ), + 'taxonomy' => $attribute->is_taxonomy() ? $attribute->get_name() : null, + 'has_variations' => true === $attribute->get_variation(), + 'terms' => $attribute->is_taxonomy() ? array_map( [ $this, 'prepare_product_attribute_taxonomy_value' ], $attribute->get_terms() ) : array_map( [ $this, 'prepare_product_attribute_value' ], $attribute->get_options() ), + ]; + } + + return $return; + } + + /** + * Prepare an attribute term for the response. + * + * @param \WP_Term $term Term object. + * @return object + */ + protected function prepare_product_attribute_taxonomy_value( \WP_Term $term ) { + return $this->prepare_product_attribute_value( $term->name, $term->term_id, $term->slug ); + } + + /** + * Prepare an attribute term for the response. + * + * @param string $name Attribute term name. + * @param int $id Attribute term ID. + * @param string $slug Attribute term slug. + * @return object + */ + protected function prepare_product_attribute_value( $name, $id = 0, $slug = '' ) { + return (object) [ + 'id' => (int) $id, + 'name' => $name, + 'slug' => $slug ? $slug : $name, + ]; + } + + /** + * Get an array of pricing data. + * + * @param \WC_Product $product Product instance. + * @param string $tax_display_mode If returned prices are incl or excl of tax. + * @return array + */ + protected function prepare_product_price_response( \WC_Product $product, $tax_display_mode = '' ) { + $prices = $this->get_store_currency_response(); + $tax_display_mode = $this->get_tax_display_mode( $tax_display_mode ); + $price_function = $this->get_price_function_from_tax_display_mode( $tax_display_mode ); + + $prices['price'] = $this->prepare_money_response( $price_function( $product ), wc_get_price_decimals() ); + $prices['regular_price'] = $this->prepare_money_response( $price_function( $product, [ 'price' => $product->get_regular_price() ] ), wc_get_price_decimals() ); + $prices['sale_price'] = $this->prepare_money_response( $price_function( $product, [ 'price' => $product->get_sale_price() ] ), wc_get_price_decimals() ); + $prices['price_range'] = $this->get_price_range( $product, $tax_display_mode ); + + return $prices; + } + + /** + * WooCommerce can return prices including or excluding tax; choose the correct method based on tax display mode. + * + * @param string $tax_display_mode Provided tax display mode. + * @return string Valid tax display mode. + */ + protected function get_tax_display_mode( $tax_display_mode = '' ) { + return in_array( $tax_display_mode, [ 'incl', 'excl' ], true ) ? $tax_display_mode : get_option( 'woocommerce_tax_display_shop' ); + } + + /** + * WooCommerce can return prices including or excluding tax; choose the correct method based on tax display mode. + * + * @param string $tax_display_mode If returned prices are incl or excl of tax. + * @return string Function name. + */ + protected function get_price_function_from_tax_display_mode( $tax_display_mode ) { + return 'incl' === $tax_display_mode ? 'wc_get_price_including_tax' : 'wc_get_price_excluding_tax'; + } + + /** + * Get price range from certain product types. + * + * @param \WC_Product $product Product instance. + * @param string $tax_display_mode If returned prices are incl or excl of tax. + * @return object|null + */ + protected function get_price_range( \WC_Product $product, $tax_display_mode = '' ) { + $tax_display_mode = $this->get_tax_display_mode( $tax_display_mode ); + + if ( $product->is_type( 'variable' ) ) { + $prices = $product->get_variation_prices( true ); + + if ( ! empty( $prices['price'] ) && ( min( $prices['price'] ) !== max( $prices['price'] ) ) ) { + return (object) [ + 'min_amount' => $this->prepare_money_response( min( $prices['price'] ), wc_get_price_decimals() ), + 'max_amount' => $this->prepare_money_response( max( $prices['price'] ), wc_get_price_decimals() ), + ]; + } + } + + if ( $product->is_type( 'grouped' ) ) { + $children = array_filter( array_map( 'wc_get_product', $product->get_children() ), 'wc_products_array_filter_visible_grouped' ); + $price_function = 'incl' === $tax_display_mode ? 'wc_get_price_including_tax' : 'wc_get_price_excluding_tax'; + + foreach ( $children as $child ) { + if ( '' !== $child->get_price() ) { + $child_prices[] = $price_function( $child ); + } + } + + if ( ! empty( $child_prices ) ) { + return (object) [ + 'min_amount' => $this->prepare_money_response( min( $child_prices ), wc_get_price_decimals() ), + 'max_amount' => $this->prepare_money_response( max( $child_prices ), wc_get_price_decimals() ), + ]; + } + } + + return null; + } + + /** + * Returns a list of terms assigned to the product. + * + * @param \WC_Product $product Product object. + * @param string $taxonomy Taxonomy name. + * @return array Array of terms (id, name, slug). + */ + protected function get_term_list( \WC_Product $product, $taxonomy = '' ) { + if ( ! $taxonomy ) { + return []; + } + + $terms = get_the_terms( $product->get_id(), $taxonomy ); + + if ( ! $terms || is_wp_error( $terms ) ) { + return []; + } + + $return = []; + $default_category = (int) get_option( 'default_product_cat', 0 ); + + foreach ( $terms as $term ) { + $link = get_term_link( $term, $taxonomy ); + + if ( is_wp_error( $link ) ) { + continue; + } + + if ( $term->term_id === $default_category ) { + continue; + } + + $return[] = (object) [ + 'id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'link' => $link, + ]; + } + + return $return; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ShippingAddressSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ShippingAddressSchema.php new file mode 100644 index 0000000..c3deb95 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/ShippingAddressSchema.php @@ -0,0 +1,113 @@ + [ + 'description' => __( 'First name', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'last_name' => [ + 'description' => __( 'Last name', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'company' => [ + 'description' => __( 'Company', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'address_1' => [ + 'description' => __( 'Address', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'address_2' => [ + 'description' => __( 'Apartment, suite, etc.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'city' => [ + 'description' => __( 'City', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'state' => [ + 'description' => __( 'State/County code, or name of the state, county, province, or district.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'postcode' => [ + 'description' => __( 'Postal code', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + 'country' => [ + 'description' => __( 'Country/Region code in ISO 3166-1 alpha-2 format.', 'woocommerce' ), + 'type' => 'string', + 'context' => [ 'view', 'edit' ], + ], + ]; + } + + /** + * Convert a term object into an object suitable for the response. + * + * @param \WC_Order|\WC_Customer $address An object with shipping address. + * + * @throws RouteException When the invalid object types are provided. + * @return stdClass + */ + public function get_item_response( $address ) { + if ( ( $address instanceof \WC_Customer || $address instanceof \WC_Order ) ) { + return (object) $this->prepare_html_response( + [ + 'first_name' => $address->get_shipping_first_name(), + 'last_name' => $address->get_shipping_last_name(), + 'company' => $address->get_shipping_company(), + 'address_1' => $address->get_shipping_address_1(), + 'address_2' => $address->get_shipping_address_2(), + 'city' => $address->get_shipping_city(), + 'state' => $address->get_shipping_state(), + 'postcode' => $address->get_shipping_postcode(), + 'country' => $address->get_shipping_country(), + ] + ); + } + throw new RouteException( + 'invalid_object_type', + sprintf( + /* translators: Placeholders are class and method names */ + __( '%1$s requires an instance of %2$s or %3$s for the address', 'woocommerce' ), + 'ShippingAddressSchema::get_item_response', + 'WC_Customer', + 'WC_Order' + ), + 500 + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/TermSchema.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/TermSchema.php new file mode 100644 index 0000000..0f393b7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/TermSchema.php @@ -0,0 +1,80 @@ + array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Term name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'slug' => array( + 'description' => __( 'String based identifier for the term.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'description' => array( + 'description' => __( 'Term description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'parent' => array( + 'description' => __( 'Parent term ID, if applicable.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'count' => array( + 'description' => __( 'Number of objects (posts of any type) assigned to the term.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ]; + } + + /** + * Convert a term object into an object suitable for the response. + * + * @param \WP_Term $term Term object. + * @return array + */ + public function get_item_response( $term ) { + return [ + 'id' => (int) $term->term_id, + 'name' => $this->prepare_html_response( $term->name ), + 'slug' => $term->slug, + 'description' => $this->prepare_html_response( $term->description ), + 'parent' => (int) $term->parent, + 'count' => (int) $term->count, + ]; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/CartController.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/CartController.php new file mode 100644 index 0000000..1352f1c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/CartController.php @@ -0,0 +1,915 @@ +get_cart_instance(); + $request = wp_parse_args( + $request, + [ + 'id' => 0, + 'quantity' => 1, + 'variation' => [], + 'cart_item_data' => [], + ] + ); + + $request = $this->filter_request_data( $this->parse_variation_data( $request ) ); + $product = $this->get_product_for_cart( $request ); + $cart_id = $cart->generate_cart_id( + $this->get_product_id( $product ), + $this->get_variation_id( $product ), + $request['variation'], + $request['cart_item_data'] + ); + + $this->validate_add_to_cart( $product, $request ); + + $existing_cart_id = $cart->find_product_in_cart( $cart_id ); + + if ( $existing_cart_id ) { + if ( $product->is_sold_individually() ) { + throw new RouteException( + 'woocommerce_rest_cart_product_sold_individually', + sprintf( + /* translators: %s: product name */ + __( 'You cannot add another "%s" to your cart.', 'woocommerce' ), + $product->get_name() + ), + 400 + ); + } + $cart->set_quantity( $existing_cart_id, $request['quantity'] + $cart->cart_contents[ $existing_cart_id ]['quantity'], true ); + + return $existing_cart_id; + } + + $cart->cart_contents[ $cart_id ] = apply_filters( + 'woocommerce_add_cart_item', + array_merge( + $request['cart_item_data'], + array( + 'key' => $cart_id, + 'product_id' => $this->get_product_id( $product ), + 'variation_id' => $this->get_variation_id( $product ), + 'variation' => $request['variation'], + 'quantity' => $request['quantity'], + 'data' => $product, + 'data_hash' => wc_get_cart_item_data_hash( $product ), + ) + ), + $cart_id + ); + + $cart->cart_contents = apply_filters( 'woocommerce_cart_contents_changed', $cart->cart_contents ); + + do_action( + 'woocommerce_add_to_cart', + $cart_id, + $this->get_product_id( $product ), + $request['quantity'], + $this->get_variation_id( $product ), + $request['variation'], + $request['cart_item_data'] + ); + + return $cart_id; + } + + /** + * Based on core `set_quantity` method, but validates if an item is sold individually first. + * + * @throws RouteException Exception if invalid data is detected. + * + * @param string $item_id Cart item id. + * @param integer $quantity Cart quantity. + */ + public function set_cart_item_quantity( $item_id, $quantity = 1 ) { + $cart_item = $this->get_cart_item( $item_id ); + + if ( ! $cart_item ) { + throw new RouteException( 'woocommerce_rest_cart_invalid_key', __( 'Cart item does not exist.', 'woocommerce' ), 404 ); + } + + $product = $cart_item['data']; + + if ( ! $product instanceof \WC_Product ) { + throw new RouteException( 'woocommerce_rest_cart_invalid_product', __( 'Cart item is invalid.', 'woocommerce' ), 404 ); + } + + if ( $product->is_sold_individually() && $quantity > 1 ) { + throw new RouteException( + 'woocommerce_rest_cart_product_sold_individually', + sprintf( + /* translators: %s: product name */ + __( 'You cannot add another "%s" to your cart.', 'woocommerce' ), + $product->get_name() + ), + 400 + ); + } + $cart = $this->get_cart_instance(); + $cart->set_quantity( $item_id, $quantity ); + } + + /** + * Validate all items in the cart and check for errors. + * + * @throws RouteException Exception if invalid data is detected. + * + * @param \WC_Product $product Product object associated with the cart item. + * @param array $request Add to cart request params. + */ + public function validate_add_to_cart( \WC_Product $product, $request ) { + if ( ! $product->is_purchasable() ) { + $this->throw_default_product_exception( $product ); + } + + if ( ! $product->is_in_stock() ) { + throw new RouteException( + 'woocommerce_rest_cart_product_no_stock', + sprintf( + /* translators: %s: product name */ + __( 'You cannot add "%s" to the cart because the product is out of stock.', 'woocommerce' ), + $product->get_name() + ), + 400 + ); + } + + if ( $product->managing_stock() && ! $product->backorders_allowed() ) { + $qty_remaining = $this->get_remaining_stock_for_product( $product ); + $qty_in_cart = $this->get_product_quantity_in_cart( $product ); + + if ( $qty_remaining < $qty_in_cart + $request['quantity'] ) { + throw new RouteException( + 'woocommerce_rest_cart_product_no_stock', + sprintf( + /* translators: 1: product name 2: quantity in stock */ + __( 'You cannot add that amount of "%1$s" to the cart because there is not enough stock (%2$s remaining).', 'woocommerce' ), + $product->get_name(), + wc_format_stock_quantity_for_display( $qty_remaining, $product ) + ), + 400 + ); + } + } + + /** + * Hook: woocommerce_add_to_cart_validation (legacy). + * + * Allow 3rd parties to validate if an item can be added to the cart. This is a legacy hook from Woo core. + * This filter will be deprecated because it encourages usage of wc_add_notice. For the API we need to capture + * notices and convert to exceptions instead. + */ + $passed_validation = apply_filters( + 'woocommerce_add_to_cart_validation', + true, + $this->get_product_id( $product ), + $request['quantity'], + $this->get_variation_id( $product ), + $request['variation'] + ); + + if ( ! $passed_validation ) { + // Validation did not pass - see if an error notice was thrown. + NoticeHandler::convert_notices_to_exceptions( 'woocommerce_rest_add_to_cart_error' ); + + // If no notice was thrown, throw the default notice instead. + $this->throw_default_product_exception( $product ); + } + + /** + * Fire action to validate add to cart. Functions hooking into this should throw an \Exception to prevent + * add to cart from occuring. + * + * @param \WC_Product $product Product object being added to the cart. + * @param array $request Add to cart request params including id, quantity, and variation attributes. + */ + do_action( 'wooocommerce_store_api_validate_add_to_cart', $product, $request ); + } + + /** + * Validate all items in the cart and check for errors. + * + * @throws RouteException Exception if invalid data is detected. + */ + public function validate_cart_items() { + $cart = $this->get_cart_instance(); + $cart_items = $this->get_cart_items(); + + foreach ( $cart_items as $cart_item_key => $cart_item ) { + $this->validate_cart_item( $cart_item ); + } + + // Before running the woocommerce_check_cart_items hook, unhook validation from the core cart. + remove_action( 'woocommerce_check_cart_items', array( $cart, 'check_cart_items' ), 1 ); + remove_action( 'woocommerce_check_cart_items', array( $cart, 'check_cart_coupons' ), 1 ); + + /** + * Hook: woocommerce_check_cart_items + * + * Allow 3rd parties to validate cart items. This is a legacy hook from Woo core. + * This filter will be deprecated because it encourages usage of wc_add_notice. For the API we need to capture + * notices and convert to exceptions instead. + */ + do_action( 'woocommerce_check_cart_items' ); + NoticeHandler::convert_notices_to_exceptions( 'woocommerce_rest_cart_item_error' ); + } + + /** + * Validates an existing cart item and returns any errors. + * + * @throws RouteException Exception if invalid data is detected. + * + * @param array $cart_item Cart item array. + */ + public function validate_cart_item( $cart_item ) { + $product = $cart_item['data']; + + if ( ! $product instanceof \WC_Product ) { + return; + } + + if ( ! $product->is_purchasable() ) { + $this->throw_default_product_exception( $product ); + } + + if ( $product->is_sold_individually() && $cart_item['quantity'] > 1 ) { + throw new RouteException( + 'woocommerce_rest_cart_product_sold_individually', + sprintf( + /* translators: %s: product name */ + __( 'There are too many "%s" in the cart. Only 1 can be purchased.', 'woocommerce' ), + $product->get_name() + ), + 400 + ); + } + + if ( ! $product->is_in_stock() ) { + throw new RouteException( + 'woocommerce_rest_cart_product_no_stock', + sprintf( + /* translators: %s: product name */ + __( '"%s" is out of stock and cannot be purchased.', 'woocommerce' ), + $product->get_name() + ), + 400 + ); + } + + if ( $product->managing_stock() && ! $product->backorders_allowed() ) { + $qty_remaining = $this->get_remaining_stock_for_product( $product ); + $qty_in_cart = $this->get_product_quantity_in_cart( $product ); + + if ( $qty_remaining < $qty_in_cart ) { + throw new RouteException( + 'woocommerce_rest_cart_product_no_stock', + sprintf( + /* translators: 1: quantity in stock, 2: product name */ + _n( + 'There is only %1$s unit of "%2$s" in stock.', + 'There are only %1$s units of "%2$s" in stock.', + $qty_remaining, + 'woocommerce' + ), + wc_format_stock_quantity_for_display( $qty_remaining, $product ), + $product->get_name() + ), + 400 + ); + } + } + + /** + * Fire action to validate add to cart. Functions hooking into this should throw an \Exception to prevent + * add to cart from occurring. + * + * @param \WC_Product $product Product object being added to the cart. + * @param array $cart_item Cart item array. + */ + do_action( 'wooocommerce_store_api_validate_cart_item', $product, $cart_item ); + } + + /** + * Validate all coupons in the cart and check for errors. + * + * @throws RouteException Exception if invalid data is detected. + */ + public function validate_cart_coupons() { + $cart_coupons = $this->get_cart_coupons(); + + foreach ( $cart_coupons as $code ) { + $coupon = new \WC_Coupon( $code ); + $this->validate_cart_coupon( $coupon ); + } + } + + /** + * Validate all items in the cart and get a list of errors. + * + * @throws RouteException Exception if invalid data is detected. + */ + public function get_cart_item_errors() { + $errors = []; + $cart_items = $this->get_cart_items(); + + foreach ( $cart_items as $cart_item_key => $cart_item ) { + try { + $this->validate_cart_item( $cart_item ); + } catch ( RouteException $error ) { + $errors[] = new \WP_Error( $error->getErrorCode(), $error->getMessage() ); + } + } + + return $errors; + } + + /** + * Validate all items in the cart and get a list of errors. + * + * @throws RouteException Exception if invalid data is detected. + */ + public function get_cart_coupon_errors() { + $errors = []; + $cart_coupons = $this->get_cart_coupons(); + + foreach ( $cart_coupons as $code ) { + try { + $coupon = new \WC_Coupon( $code ); + $this->validate_cart_coupon( $coupon ); + } catch ( RouteException $error ) { + $errors[] = new \WP_Error( $error->getErrorCode(), $error->getMessage() ); + } + } + + return $errors; + } + + /** + * Get main instance of cart class. + * + * @throws RouteException When cart cannot be loaded. + * @return \WC_Cart + */ + public function get_cart_instance() { + $cart = wc()->cart; + + if ( ! $cart || ! $cart instanceof \WC_Cart ) { + throw new RouteException( 'woocommerce_rest_cart_error', __( 'Unable to retrieve cart.', 'woocommerce' ), 500 ); + } + + return $cart; + } + + /** + * Return a cart item from the woo core cart class. + * + * @param string $item_id Cart item id. + * @return array + */ + public function get_cart_item( $item_id ) { + $cart = $this->get_cart_instance(); + return isset( $cart->cart_contents[ $item_id ] ) ? $cart->cart_contents[ $item_id ] : []; + } + + /** + * Returns all cart items. + * + * @param callable $callback Optional callback to apply to the array filter. + * @return array + */ + public function get_cart_items( $callback = null ) { + $cart = $this->get_cart_instance(); + return $callback ? array_filter( $cart->get_cart(), $callback ) : array_filter( $cart->get_cart() ); + } + + /** + * Get hashes for items in the current cart. Useful for tracking changes. + * + * @return array + */ + public function get_cart_hashes() { + $cart = $this->get_cart_instance(); + return [ + 'line_items' => $cart->get_cart_hash(), + 'shipping' => md5( wp_json_encode( $cart->shipping_methods ) ), + 'fees' => md5( wp_json_encode( $cart->get_fees() ) ), + 'coupons' => md5( wp_json_encode( $cart->get_applied_coupons() ) ), + 'taxes' => md5( wp_json_encode( $cart->get_taxes() ) ), + ]; + } + + /** + * Empty cart contents. + */ + public function empty_cart() { + $cart = $this->get_cart_instance(); + $cart->empty_cart(); + } + + /** + * See if cart has applied coupon by code. + * + * @param string $coupon_code Cart coupon code. + * @return bool + */ + public function has_coupon( $coupon_code ) { + $cart = $this->get_cart_instance(); + return $cart->has_discount( $coupon_code ); + } + + /** + * Returns all applied coupons. + * + * @param callable $callback Optional callback to apply to the array filter. + * @return array + */ + public function get_cart_coupons( $callback = null ) { + $cart = $this->get_cart_instance(); + return $callback ? array_filter( $cart->get_applied_coupons(), $callback ) : array_filter( $cart->get_applied_coupons() ); + } + + /** + * Get shipping packages from the cart with calculated shipping rates. + * + * @todo this can be refactored once https://github.com/woocommerce/woocommerce/pull/26101 lands. + * + * @param bool $calculate_rates Should rates for the packages also be returned. + * @return array + */ + public function get_shipping_packages( $calculate_rates = true ) { + $cart = $this->get_cart_instance(); + + // See if we need to calculate anything. + if ( ! $cart->needs_shipping() ) { + return []; + } + + $packages = $cart->get_shipping_packages(); + + // Add package ID to array. + foreach ( $packages as $key => $package ) { + if ( ! isset( $packages[ $key ]['package_id'] ) ) { + $packages[ $key ]['package_id'] = $key; + } + } + + return $calculate_rates ? wc()->shipping()->calculate_shipping( $packages ) : $packages; + } + + /** + * Selects a shipping rate. + * + * @param int $package_id ID of the package to choose a rate for. + * @param string $rate_id ID of the rate being chosen. + */ + public function select_shipping_rate( $package_id, $rate_id ) { + $cart = $this->get_cart_instance(); + $session_data = wc()->session->get( 'chosen_shipping_methods' ) ? wc()->session->get( 'chosen_shipping_methods' ) : []; + $session_data[ $package_id ] = $rate_id; + + wc()->session->set( 'chosen_shipping_methods', $session_data ); + } + + /** + * Based on the core cart class but returns errors rather than rendering notices directly. + * + * @todo Overriding the core apply_coupon method was necessary because core outputs notices when a coupon gets + * applied. For us this would cause notices to build up and output on the store, out of context. Core would need + * refactoring to split notices out from other cart actions. + * + * @throws RouteException Exception if invalid data is detected. + * + * @param string $coupon_code Coupon code. + */ + public function apply_coupon( $coupon_code ) { + $cart = $this->get_cart_instance(); + $applied_coupons = $this->get_cart_coupons(); + $coupon = new \WC_Coupon( $coupon_code ); + + if ( $coupon->get_code() !== $coupon_code ) { + throw new RouteException( + 'woocommerce_rest_cart_coupon_error', + sprintf( + /* Translators: %s coupon code */ + __( '"%s" is an invalid coupon code.', 'woocommerce' ), + esc_html( $coupon_code ) + ), + 400 + ); + } + + if ( $this->has_coupon( $coupon_code ) ) { + throw new RouteException( + 'woocommerce_rest_cart_coupon_error', + sprintf( + /* Translators: %s coupon code */ + __( 'Coupon code "%s" has already been applied.', 'woocommerce' ), + esc_html( $coupon_code ) + ), + 400 + ); + } + + if ( ! $coupon->is_valid() ) { + throw new RouteException( + 'woocommerce_rest_cart_coupon_error', + wp_strip_all_tags( $coupon->get_error_message() ), + 400 + ); + } + + // Prevents new coupons being added if individual use coupons are already in the cart. + $individual_use_coupons = $this->get_cart_coupons( + function( $code ) { + $coupon = new \WC_Coupon( $code ); + return $coupon->get_individual_use(); + } + ); + + foreach ( $individual_use_coupons as $code ) { + $individual_use_coupon = new \WC_Coupon( $code ); + + if ( false === apply_filters( 'woocommerce_apply_with_individual_use_coupon', false, $coupon, $individual_use_coupon, $applied_coupons ) ) { + throw new RouteException( + 'woocommerce_rest_cart_coupon_error', + sprintf( + /* translators: %s: coupon code */ + __( '"%s" has already been applied and cannot be used in conjunction with other coupons.', 'woocommerce' ), + $code + ), + 400 + ); + } + } + + if ( $coupon->get_individual_use() ) { + $coupons_to_remove = array_diff( $applied_coupons, apply_filters( 'woocommerce_apply_individual_use_coupon', array(), $coupon, $applied_coupons ) ); + + foreach ( $coupons_to_remove as $code ) { + $cart->remove_coupon( $code ); + } + + $applied_coupons = array_diff( $applied_coupons, $coupons_to_remove ); + } + + $applied_coupons[] = $coupon_code; + $cart->set_applied_coupons( $applied_coupons ); + + do_action( 'woocommerce_applied_coupon', $coupon_code ); + } + + /** + * Validates an existing cart coupon and returns any errors. + * + * @throws RouteException Exception if invalid data is detected. + * + * @param \WC_Coupon $coupon Coupon object applied to the cart. + */ + protected function validate_cart_coupon( \WC_Coupon $coupon ) { + if ( ! $coupon->is_valid() ) { + $cart = $this->get_cart_instance(); + $cart->remove_coupon( $coupon->get_code() ); + $cart->calculate_totals(); + throw new RouteException( + 'woocommerce_rest_cart_coupon_error', + sprintf( + // translators: %1$s coupon code, %2$s reason. + __( 'The "%1$s" coupon has been removed from your cart: %2$s', 'woocommerce' ), + $coupon->get_code(), + wp_strip_all_tags( $coupon->get_error_message() ) + ), + 409 + ); + } + } + + /** + * Gets the qty of a product across line items. + * + * @param \WC_Product $product Product object. + * @return int + */ + protected function get_product_quantity_in_cart( $product ) { + $cart = $this->get_cart_instance(); + $product_quantities = $cart->get_cart_item_quantities(); + $product_id = $product->get_stock_managed_by_id(); + + return isset( $product_quantities[ $product_id ] ) ? $product_quantities[ $product_id ] : 0; + } + + /** + * Gets remaining stock for a product. + * + * @param \WC_Product $product Product object. + * @return int + */ + protected function get_remaining_stock_for_product( $product ) { + if ( \class_exists( '\Automattic\WooCommerce\Checkout\Helpers\ReserveStock' ) ) { + $reserve_stock_controller = new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock(); + } else { + $reserve_stock_controller = new \Automattic\WooCommerce\Blocks\StoreApi\Utilities\ReserveStock(); + } + + $draft_order = wc()->session->get( 'store_api_draft_order', 0 ); + $qty_reserved = $reserve_stock_controller->get_reserved_stock( $product, $draft_order ); + + return $product->get_stock_quantity() - $qty_reserved; + } + + /** + * Get a product object to be added to the cart. + * + * @throws RouteException Exception if invalid data is detected. + * + * @param array $request Add to cart request params. + * @return \WC_Product|Error Returns a product object if purchasable. + */ + protected function get_product_for_cart( $request ) { + $product = wc_get_product( $request['id'] ); + + if ( ! $product || 'trash' === $product->get_status() ) { + throw new RouteException( + 'woocommerce_rest_cart_invalid_product', + __( 'This product cannot be added to the cart.', 'woocommerce' ), + 400 + ); + } + + return $product; + } + + /** + * For a given product, get the product ID. + * + * @param \WC_Product $product Product object associated with the cart item. + * @return int + */ + protected function get_product_id( \WC_Product $product ) { + return $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id(); + } + + /** + * For a given product, get the variation ID. + * + * @param \WC_Product $product Product object associated with the cart item. + * @return int + */ + protected function get_variation_id( \WC_Product $product ) { + return $product->is_type( 'variation' ) ? $product->get_id() : 0; + } + + /** + * Default exception thrown when an item cannot be added to the cart. + * + * @throws RouteException Exception with code woocommerce_rest_cart_product_is_not_purchasable. + * + * @param \WC_Product $product Product object associated with the cart item. + */ + protected function throw_default_product_exception( \WC_Product $product ) { + throw new RouteException( + 'woocommerce_rest_cart_product_is_not_purchasable', + sprintf( + /* translators: %s: product name */ + __( '"%s" is not available for purchase.', 'woocommerce' ), + $product->get_name() + ), + 400 + ); + } + + /** + * Filter data for add to cart requests. + * + * @param array $request Add to cart request params. + * @return array Updated request array. + */ + protected function filter_request_data( $request ) { + $product_id = $request['id']; + $variation_id = 0; + $product = wc_get_product( $product_id ); + + if ( $product->is_type( 'variation' ) ) { + $product_id = $product->get_parent_id(); + $variation_id = $product->get_id(); + } + + $request['cart_item_data'] = (array) apply_filters( + 'woocommerce_add_cart_item_data', + $request['cart_item_data'], + $product_id, + $variation_id, + $request['quantity'] + ); + + if ( $product->is_sold_individually() ) { + $request['quantity'] = apply_filters( 'woocommerce_add_to_cart_sold_individually_quantity', 1, $request['quantity'], $product_id, $variation_id, $request['cart_item_data'] ); + } + + return $request; + } + + /** + * If variations are set, validate and format the values ready to add to the cart. + * + * @throws RouteException Exception if invalid data is detected. + * + * @param array $request Add to cart request params. + * @return array Updated request array. + */ + protected function parse_variation_data( $request ) { + $product = $this->get_product_for_cart( $request ); + + // Remove variation request if not needed. + if ( ! $product->is_type( array( 'variation', 'variable' ) ) ) { + $request['variation'] = []; + return $request; + } + + // Flatten data and format posted values. + $variable_product_attributes = $this->get_variable_product_attributes( $product ); + $request['variation'] = $this->sanitize_variation_data( wp_list_pluck( $request['variation'], 'value', 'attribute' ), $variable_product_attributes ); + + // If we have a parent product, find the variation ID. + if ( $product->is_type( 'variable' ) ) { + $request['id'] = $this->get_variation_id_from_variation_data( $request, $product ); + } + + // Now we have a variation ID, get the valid set of attributes for this variation. They will have an attribute_ prefix since they are from meta. + $expected_attributes = wc_get_product_variation_attributes( $request['id'] ); + $missing_attributes = []; + + foreach ( $variable_product_attributes as $attribute ) { + if ( ! $attribute['is_variation'] ) { + continue; + } + + $prefixed_attribute_name = 'attribute_' . sanitize_title( $attribute['name'] ); + $expected_value = isset( $expected_attributes[ $prefixed_attribute_name ] ) ? $expected_attributes[ $prefixed_attribute_name ] : ''; + $attribute_label = wc_attribute_label( $attribute['name'] ); + + if ( isset( $request['variation'][ wc_variation_attribute_name( $attribute['name'] ) ] ) ) { + $given_value = $request['variation'][ wc_variation_attribute_name( $attribute['name'] ) ]; + + if ( $expected_value === $given_value ) { + continue; + } + + // If valid values are empty, this is an 'any' variation so get all possible values. + if ( '' === $expected_value && in_array( $given_value, $attribute->get_slugs(), true ) ) { + continue; + } + + throw new RouteException( + 'woocommerce_rest_invalid_variation_data', + /* translators: %1$s: Attribute name, %2$s: Allowed values. */ + sprintf( __( 'Invalid value posted for %1$s. Allowed values: %2$s', 'woocommerce' ), $attribute_label, implode( ', ', $attribute->get_slugs() ) ), + 400 + ); + } + + // If no attribute was posted, only error if the variation has an 'any' attribute which requires a value. + if ( '' === $expected_value ) { + $missing_attributes[] = $attribute_label; + } + } + + if ( ! empty( $missing_attributes ) ) { + throw new RouteException( + 'woocommerce_rest_missing_variation_data', + /* translators: %s: Attribute name. */ + __( 'Missing variation data for variable product.', 'woocommerce' ) . ' ' . sprintf( _n( '%s is a required field', '%s are required fields', count( $missing_attributes ), 'woocommerce' ), wc_format_list_of_items( $missing_attributes ) ), + 400 + ); + } + + return $request; + } + + /** + * Try to match request data to a variation ID and return the ID. + * + * @throws RouteException Exception if variation cannot be found. + * + * @param array $request Add to cart request params. + * @param \WC_Product $product Product being added to the cart. + * @return int Matching variation ID. + */ + protected function get_variation_id_from_variation_data( $request, $product ) { + $data_store = \WC_Data_Store::load( 'product' ); + $match_attributes = $request['variation']; + $variation_id = $data_store->find_matching_product_variation( $product, $match_attributes ); + + if ( empty( $variation_id ) ) { + throw new RouteException( + 'woocommerce_rest_variation_id_from_variation_data', + __( 'No matching variation found.', 'woocommerce' ), + 400 + ); + } + + return $variation_id; + } + + /** + * Format and sanitize variation data posted to the API. + * + * Labels are converted to names (e.g. Size to pa_size), and values are cleaned. + * + * @throws RouteException Exception if variation cannot be found. + * + * @param array $variation_data Key value pairs of attributes and values. + * @param array $variable_product_attributes Product attributes we're expecting. + * @return array + */ + protected function sanitize_variation_data( $variation_data, $variable_product_attributes ) { + $return = []; + + foreach ( $variable_product_attributes as $attribute ) { + if ( ! $attribute['is_variation'] ) { + continue; + } + $attribute_label = wc_attribute_label( $attribute['name'] ); + $variation_attribute_name = wc_variation_attribute_name( $attribute['name'] ); + + // Attribute labels e.g. Size. + if ( isset( $variation_data[ $attribute_label ] ) ) { + $return[ $variation_attribute_name ] = + $attribute['is_taxonomy'] + ? + sanitize_title( $variation_data[ $attribute_label ] ) + : + html_entity_decode( + wc_clean( $variation_data[ $attribute_label ] ), + ENT_QUOTES, + get_bloginfo( 'charset' ) + ); + continue; + } + + // Attribute slugs e.g. pa_size. + if ( isset( $variation_data[ $attribute['name'] ] ) ) { + $return[ $variation_attribute_name ] = + $attribute['is_taxonomy'] + ? + sanitize_title( $variation_data[ $attribute['name'] ] ) + : + html_entity_decode( + wc_clean( $variation_data[ $attribute['name'] ] ), + ENT_QUOTES, + get_bloginfo( 'charset' ) + ); + } + } + return $return; + } + + /** + * Get product attributes from the variable product (which may be the parent if the product object is a variation). + * + * @throws RouteException Exception if product is invalid. + * + * @param \WC_Product $product Product being added to the cart. + * @return array + */ + protected function get_variable_product_attributes( $product ) { + if ( $product->is_type( 'variation' ) ) { + $product = wc_get_product( $product->get_parent_id() ); + } + + if ( ! $product || 'trash' === $product->get_status() ) { + throw new RouteException( + 'woocommerce_rest_cart_invalid_parent_product', + __( 'This product cannot be added to the cart.', 'woocommerce' ), + 400 + ); + } + + return $product->get_attributes(); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/NoticeHandler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/NoticeHandler.php new file mode 100644 index 0000000..2f6ddc9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/NoticeHandler.php @@ -0,0 +1,40 @@ +cart->is_empty() ) { + throw new RouteException( + 'woocommerce_rest_cart_empty', + __( 'Cannot create order from empty cart.', 'woocommerce' ), + 400 + ); + } + + add_filter( 'woocommerce_default_order_status', array( $this, 'default_order_status' ) ); + + $order = new \WC_Order(); + $order->set_status( 'checkout-draft' ); + $order->set_created_via( 'store-api' ); + $this->update_order_from_cart( $order ); + + remove_filter( 'woocommerce_default_order_status', array( $this, 'default_order_status' ) ); + + return $order; + } + + /** + * Update an order using data from the current cart. + * + * @param \WC_Order $order The order object to update. + */ + public function update_order_from_cart( \WC_Order $order ) { + // Ensure cart is current. + wc()->cart->calculate_shipping(); + wc()->cart->calculate_totals(); + + // Update the current order to match the current cart. + $this->update_line_items_from_cart( $order ); + $this->update_addresses_from_cart( $order ); + $order->set_currency( get_woocommerce_currency() ); + $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $order->set_customer_id( get_current_user_id() ); + $order->set_customer_ip_address( \WC_Geolocation::get_ip_address() ); + $order->set_customer_user_agent( wc_get_user_agent() ); + $order->update_meta_data( 'is_vat_exempt', wc()->cart->get_customer()->get_is_vat_exempt() ? 'yes' : 'no' ); + $order->calculate_totals(); + } + + /** + * Copies order data to customer object (not the session), so values persist for future checkouts. + * + * @param \WC_Order $order Order object. + */ + public function sync_customer_data_with_order( \WC_Order $order ) { + if ( $order->get_customer_id() ) { + $customer = new \WC_Customer( $order->get_customer_id() ); + $customer->set_props( + [ + 'billing_first_name' => $order->get_billing_first_name(), + 'billing_last_name' => $order->get_billing_last_name(), + 'billing_company' => $order->get_billing_company(), + 'billing_address_1' => $order->get_billing_address_1(), + 'billing_address_2' => $order->get_billing_address_2(), + 'billing_city' => $order->get_billing_city(), + 'billing_state' => $order->get_billing_state(), + 'billing_postcode' => $order->get_billing_postcode(), + 'billing_country' => $order->get_billing_country(), + 'billing_email' => $order->get_billing_email(), + 'billing_phone' => $order->get_billing_phone(), + 'shipping_first_name' => $order->get_shipping_first_name(), + 'shipping_last_name' => $order->get_shipping_last_name(), + 'shipping_company' => $order->get_shipping_company(), + 'shipping_address_1' => $order->get_shipping_address_1(), + 'shipping_address_2' => $order->get_shipping_address_2(), + 'shipping_city' => $order->get_shipping_city(), + 'shipping_state' => $order->get_shipping_state(), + 'shipping_postcode' => $order->get_shipping_postcode(), + 'shipping_country' => $order->get_shipping_country(), + ] + ); + $customer->save(); + }; + } + + /** + * Final validation ran before payment is taken. + * + * By this point we have an order populated with customer data and items. + * + * @throws RouteException Exception if invalid data is detected. + * + * @param \WC_Order $order Order object. + */ + public function validate_order_before_payment( \WC_Order $order ) { + $coupons = $order->get_coupon_codes(); + + $coupon_errors = []; + + foreach ( $coupons as $coupon_code ) { + $coupon = new \WC_Coupon( $coupon_code ); + + try { + $this->validate_coupon_email_restriction( $coupon, $order ); + } catch ( \Exception $error ) { + $coupon_errors[ $coupon_code ] = $error->getMessage(); + } + try { + $this->validate_coupon_usage_limit( $coupon, $order ); + } catch ( \Exception $error ) { + $coupon_errors[ $coupon_code ] = $error->getMessage(); + } + } + + if ( $coupon_errors ) { + // Remove all coupons that were not valid. + foreach ( $coupon_errors as $coupon_code => $message ) { + wc()->cart->remove_coupon( $coupon_code ); + } + + // Recalculate totals. + wc()->cart->calculate_totals(); + + // Re-sync order with cart. + $this->update_order_from_cart( $order ); + + // Return exception so customer can review before payment. + throw new RouteException( + 'woocommerce_rest_cart_coupon_errors', + sprintf( + // Translators: %s Coupon codes. + __( 'Invalid coupons were removed from the cart: "%s"', 'woocommerce' ), + implode( '", "', array_keys( $coupon_errors ) ) + ), + 409, + [ + 'removed_coupons' => $coupon_errors, + ] + ); + } + } + + /** + * Check email restrictions of a coupon against the order. + * + * @throws \Exception Exception if invalid data is detected. + * + * @param \WC_Coupon $coupon Coupon object applied to the cart. + * @param \WC_Order $order Order object. + */ + protected function validate_coupon_email_restriction( \WC_Coupon $coupon, $order ) { + $restrictions = $coupon->get_email_restrictions(); + + if ( ! empty( $restrictions ) && $order->get_billing_email() && ! wc()->cart->is_coupon_emails_allowed( [ $order->get_billing_email() ], $restrictions ) ) { + throw new \Exception( $coupon->get_coupon_error( \WC_Coupon::E_WC_COUPON_NOT_YOURS_REMOVED ) ); + } + } + + /** + * Check usage restrictions of a coupon against the order. + * + * @throws \Exception Exception if invalid data is detected. + * + * @param \WC_Coupon $coupon Coupon object applied to the cart. + * @param \WC_Order $order Order object. + */ + protected function validate_coupon_usage_limit( \WC_Coupon $coupon, $order ) { + $coupon_usage_limit = $coupon->get_usage_limit_per_user(); + + if ( $coupon_usage_limit > 0 ) { + $data_store = $coupon->get_data_store(); + $usage_count = $order->get_customer_id() ? $data_store->get_usage_by_user_id( $coupon, $order->get_customer_id() ) : $data_store->get_usage_by_email( $coupon, $order->get_billing_email() ); + + if ( $usage_count >= $coupon_usage_limit ) { + throw new \Exception( $coupon->get_coupon_error( \WC_Coupon::E_WC_COUPON_USAGE_LIMIT_REACHED ) ); + } + } + } + + /** + * Changes default order status to draft for orders created via this API. + * + * @return string + */ + public function default_order_status() { + return 'checkout-draft'; + } + + /** + * Create order line items. + * + * @param \WC_Order $order The order object to update. + */ + protected function update_line_items_from_cart( \WC_Order $order ) { + $cart_controller = new CartController(); + $cart = $cart_controller->get_cart_instance(); + $cart_hashes = $cart_controller->get_cart_hashes(); + + if ( $order->get_cart_hash() !== $cart_hashes['line_items'] ) { + $order->set_cart_hash( $cart_hashes['line_items'] ); + $order->remove_order_items( 'line_item' ); + wc()->checkout->create_order_line_items( $order, $cart ); + } + + if ( $order->get_meta_data( '_shipping_hash' ) !== $cart_hashes['shipping'] ) { + $order->update_meta_data( '_shipping_hash', $cart_hashes['shipping'] ); + $order->remove_order_items( 'shipping' ); + wc()->checkout->create_order_shipping_lines( $order, wc()->session->get( 'chosen_shipping_methods' ), wc()->shipping()->get_packages() ); + } + + if ( $order->get_meta_data( '_coupons_hash' ) !== $cart_hashes['coupons'] ) { + $order->remove_order_items( 'coupon' ); + $order->update_meta_data( '_coupons_hash', $cart_hashes['coupons'] ); + wc()->checkout->create_order_coupon_lines( $order, $cart ); + } + + if ( $order->get_meta_data( '_fees_hash' ) !== $cart_hashes['fees'] ) { + $order->update_meta_data( '_fees_hash', $cart_hashes['fees'] ); + $order->remove_order_items( 'fee' ); + wc()->checkout->create_order_fee_lines( $order, $cart ); + } + + if ( $order->get_meta_data( '_taxes_hash' ) !== $cart_hashes['taxes'] ) { + $order->update_meta_data( '_taxes_hash', $cart_hashes['taxes'] ); + $order->remove_order_items( 'tax' ); + wc()->checkout->create_order_tax_lines( $order, $cart ); + } + } + + /** + * Update address data from cart and/or customer session data. + * + * @param \WC_Order $order The order object to update. + */ + protected function update_addresses_from_cart( \WC_Order $order ) { + $customer_billing = wc()->customer->get_billing(); + $customer_billing = array_combine( + array_map( + function( $key ) { + return 'billing_' . $key; + }, + array_keys( $customer_billing ) + ), + $customer_billing + ); + $order->set_props( $customer_billing ); + + $customer_shipping = wc()->customer->get_shipping(); + $customer_shipping = array_combine( + array_map( + function( $key ) { + return 'shipping_' . $key; + }, + array_keys( $customer_shipping ) + ), + $customer_shipping + ); + $order->set_props( $customer_shipping ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/Pagination.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/Pagination.php new file mode 100644 index 0000000..ccb8f4a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/Pagination.php @@ -0,0 +1,74 @@ +header( 'X-WP-Total', $total_items ); + $response->header( 'X-WP-TotalPages', $total_pages ); + + $current_page = $this->get_current_page( $request ); + $link_base = $this->get_link_base( $request ); + + if ( $current_page > 1 ) { + $previous_page = $current_page - 1; + if ( $previous_page > $total_pages ) { + $previous_page = $total_pages; + } + $this->add_page_link( $response, 'prev', $previous_page, $link_base ); + } + + if ( $total_pages > $current_page ) { + $this->add_page_link( $response, 'next', ( $current_page + 1 ), $link_base ); + } + + return $response; + } + + /** + * Get current page. + * + * @param \WP_REST_Request $request The request object. + * @return int Get the page from the request object. + */ + protected function get_current_page( $request ) { + return (int) $request->get_param( 'page' ); + } + + /** + * Get base for links from the request object. + * + * @param \WP_REST_Request $request The request object. + * @return string + */ + protected function get_link_base( $request ) { + return add_query_arg( $request->get_query_params(), rest_url( $request->get_route() ) ); + } + + /** + * Add a page link. + * + * @param \WP_REST_Response $response Reference to the response object. + * @param string $name Page link name. e.g. prev. + * @param int $page Page number. + * @param string $link_base Base URL. + */ + protected function add_page_link( &$response, $name, $page, $link_base ) { + $response->link_header( $name, add_query_arg( 'page', $page, $link_base ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ProductQuery.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ProductQuery.php new file mode 100644 index 0000000..74970ea --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ProductQuery.php @@ -0,0 +1,471 @@ + $request['offset'], + 'order' => $request['order'], + 'orderby' => $request['orderby'], + 'paged' => $request['page'], + 'post__in' => $request['include'], + 'post__not_in' => $request['exclude'], + 'posts_per_page' => $request['per_page'] ? $request['per_page'] : -1, + 'post_parent__in' => $request['parent'], + 'post_parent__not_in' => $request['parent_exclude'], + 's' => $request['search'], + 'fields' => 'ids', + 'ignore_sticky_posts' => true, + 'post_status' => 'publish', + 'date_query' => [], + 'post_type' => 'product', + ]; + + // If searching for a specific SKU, allow any post type. + if ( ! empty( $request['sku'] ) ) { + $args['post_type'] = [ 'product', 'product_variation' ]; + } + + // Filter product type by slug. + if ( ! empty( $request['type'] ) ) { + if ( 'variation' === $request['type'] ) { + $args['post_type'] = 'product_variation'; + } else { + $args['post_type'] = 'product'; + $tax_query[] = [ + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => $request['type'], + ]; + } + } + + if ( 'date' === $args['orderby'] ) { + $args['orderby'] = 'date ID'; + } + + // Set before into date query. Date query must be specified as an array of an array. + if ( isset( $request['before'] ) ) { + $args['date_query'][0]['before'] = $request['before']; + } + + // Set after into date query. Date query must be specified as an array of an array. + if ( isset( $request['after'] ) ) { + $args['date_query'][0]['after'] = $request['after']; + } + + // Set date query column. Defaults to post_date. + if ( isset( $request['date_column'] ) && ! empty( $args['date_query'][0] ) ) { + $args['date_query'][0]['column'] = 'post_' . $request['date_column']; + } + + // Set custom args to handle later during clauses. + $custom_keys = [ + 'sku', + 'min_price', + 'max_price', + 'stock_status', + ]; + + foreach ( $custom_keys as $key ) { + if ( ! empty( $request[ $key ] ) ) { + $args[ $key ] = $request[ $key ]; + } + } + + // Taxonomy query to filter products by type, category, tag, shipping class, and attribute. + $tax_query = []; + + $operator_mapping = [ + 'in' => 'IN', + 'not_in' => 'NOT IN', + 'and' => 'AND', + ]; + + // Map between taxonomy name and arg key. + $taxonomies = [ + 'product_cat' => 'category', + 'product_tag' => 'tag', + ]; + + // Set tax_query for each passed arg. + foreach ( $taxonomies as $taxonomy => $key ) { + if ( ! empty( $request[ $key ] ) ) { + $operator = $request->get_param( $key . '_operator' ) && isset( $operator_mapping[ $request->get_param( $key . '_operator' ) ] ) ? $operator_mapping[ $request->get_param( $key . '_operator' ) ] : 'IN'; + $tax_query[] = [ + 'taxonomy' => $taxonomy, + 'field' => 'term_id', + 'terms' => $request[ $key ], + 'operator' => $operator, + ]; + } + } + + // Filter by attributes. + if ( ! empty( $request['attributes'] ) ) { + $att_queries = []; + + foreach ( $request['attributes'] as $attribute ) { + if ( empty( $attribute['term_id'] ) && empty( $attribute['slug'] ) ) { + continue; + } + if ( in_array( $attribute['attribute'], wc_get_attribute_taxonomy_names(), true ) ) { + $operator = isset( $attribute['operator'], $operator_mapping[ $attribute['operator'] ] ) ? $operator_mapping[ $attribute['operator'] ] : 'IN'; + $att_queries[] = [ + 'taxonomy' => $attribute['attribute'], + 'field' => ! empty( $attribute['term_id'] ) ? 'term_id' : 'slug', + 'terms' => ! empty( $attribute['term_id'] ) ? $attribute['term_id'] : $attribute['slug'], + 'operator' => $operator, + ]; + } + } + + if ( 1 < count( $att_queries ) ) { + // Add relation arg when using multiple attributes. + $relation = $request->get_param( 'attribute_relation' ) && isset( $operator_mapping[ $request->get_param( 'attribute_relation' ) ] ) ? $operator_mapping[ $request->get_param( 'attribute_relation' ) ] : 'IN'; + $tax_query[] = [ + 'relation' => $relation, + $att_queries, + ]; + } else { + $tax_query = array_merge( $tax_query, $att_queries ); + } + } + + // Build tax_query if taxonomies are set. + if ( ! empty( $tax_query ) ) { + if ( ! empty( $args['tax_query'] ) ) { + $args['tax_query'] = array_merge( $tax_query, $args['tax_query'] ); // phpcs:ignore + } else { + $args['tax_query'] = $tax_query; // phpcs:ignore + } + } + + // Filter featured. + if ( is_bool( $request['featured'] ) ) { + $args['tax_query'][] = [ + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => 'featured', + 'operator' => true === $request['featured'] ? 'IN' : 'NOT IN', + ]; + } + + // Filter by on sale products. + if ( is_bool( $request['on_sale'] ) ) { + $on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in'; + $on_sale_ids = wc_get_product_ids_on_sale(); + + // Use 0 when there's no on sale products to avoid return all products. + $on_sale_ids = empty( $on_sale_ids ) ? [ 0 ] : $on_sale_ids; + + $args[ $on_sale_key ] += $on_sale_ids; + } + + $catalog_visibility = $request->get_param( 'catalog_visibility' ); + $rating = $request->get_param( 'rating' ); + $visibility_options = wc_get_product_visibility_options(); + + if ( in_array( $catalog_visibility, array_keys( $visibility_options ), true ) ) { + $exclude_from_catalog = 'search' === $catalog_visibility ? '' : 'exclude-from-catalog'; + $exclude_from_search = 'catalog' === $catalog_visibility ? '' : 'exclude-from-search'; + + $args['tax_query'][] = [ + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => [ $exclude_from_catalog, $exclude_from_search ], + 'operator' => 'hidden' === $catalog_visibility ? 'AND' : 'NOT IN', + 'rating_filter' => true, + ]; + } + + if ( $rating ) { + $rating_terms = []; + foreach ( $rating as $value ) { + $rating_terms[] = 'rated-' . $value; + } + $args['tax_query'][] = [ + 'taxonomy' => 'product_visibility', + 'field' => 'name', + 'terms' => $rating_terms, + ]; + } + + $orderby = $request->get_param( 'orderby' ); + $order = $request->get_param( 'order' ); + + $ordering_args = wc()->query->get_catalog_ordering_args( $orderby, $order ); + $args['orderby'] = $ordering_args['orderby']; + $args['order'] = $ordering_args['order']; + + if ( 'include' === $orderby ) { + $args['orderby'] = 'post__in'; + } elseif ( 'id' === $orderby ) { + $args['orderby'] = 'ID'; // ID must be capitalized. + } elseif ( 'slug' === $orderby ) { + $args['orderby'] = 'name'; + } + + if ( $ordering_args['meta_key'] ) { + $args['meta_key'] = $ordering_args['meta_key']; // phpcs:ignore + } + + return $args; + } + + /** + * Get results of query. + * + * @param \WP_REST_Request $request Request data. + * @return array + */ + public function get_results( $request ) { + $query_args = $this->prepare_objects_query( $request ); + + add_filter( 'posts_clauses', [ $this, 'add_query_clauses' ], 10, 2 ); + + $query = new \WP_Query(); + $results = $query->query( $query_args ); + $total_posts = $query->found_posts; + + // Out-of-bounds, run the query again without LIMIT for total count. + if ( $total_posts < 1 && $query_args['paged'] > 1 ) { + unset( $query_args['paged'] ); + $count_query = new \WP_Query(); + $count_query->query( $query_args ); + $total_posts = $count_query->found_posts; + } + + remove_filter( 'posts_clauses', [ $this, 'add_query_clauses' ], 10 ); + + return [ + 'results' => $results, + 'total' => (int) $total_posts, + 'pages' => $query->query_vars['posts_per_page'] > 0 ? (int) ceil( $total_posts / (int) $query->query_vars['posts_per_page'] ) : 1, + ]; + } + + /** + * Get objects. + * + * @param \WP_REST_Request $request Request data. + * @return array + */ + public function get_objects( $request ) { + $results = $this->get_results( $request ); + + return [ + 'objects' => array_map( 'wc_get_product', $results['results'] ), + 'total' => $results['total'], + 'pages' => $results['pages'], + ]; + } + + /** + * Get last modified date for all products. + * + * @return int timestamp. + */ + public function get_last_modified() { + global $wpdb; + + return strtotime( $wpdb->get_var( "SELECT MAX( post_modified_gmt ) FROM {$wpdb->posts} WHERE post_type IN ( 'product', 'product_variation' );" ) ); + } + + /** + * Add in conditional search filters for products. + * + * @param array $args Query args. + * @param \WC_Query $wp_query WC_Query object. + * @return array + */ + public function add_query_clauses( $args, $wp_query ) { + global $wpdb; + + if ( $wp_query->get( 'search' ) ) { + $search = "'%" . $wpdb->esc_like( $wp_query->get( 'search' ) ) . "%'"; + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= " AND ({$wpdb->posts}.post_title LIKE {$search}"; + $args['where'] .= wc_product_sku_enabled() ? ' OR wc_product_meta_lookup.sku LIKE ' . $search . ')' : ')'; + } + + if ( $wp_query->get( 'sku' ) ) { + $skus = explode( ',', $wp_query->get( 'sku' ) ); + // Include the current string as a SKU too. + if ( 1 < count( $skus ) ) { + $skus[] = $wp_query->get( 'sku' ); + } + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= ' AND wc_product_meta_lookup.sku IN ("' . implode( '","', array_map( 'esc_sql', $skus ) ) . '")'; + } + + if ( $wp_query->get( 'stock_status' ) ) { + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.stock_status = %s ', $wp_query->get( 'stock_status' ) ); + } + + if ( $wp_query->get( 'min_price' ) || $wp_query->get( 'max_price' ) ) { + $args = $this->add_price_filter_clauses( $args, $wp_query ); + } + + return $args; + } + + /** + * Add in conditional price filters. + * + * @param array $args Query args. + * @param \WC_Query $wp_query WC_Query object. + * @return array + */ + protected function add_price_filter_clauses( $args, $wp_query ) { + global $wpdb; + + $adjust_for_taxes = $this->adjust_price_filters_for_displayed_taxes(); + $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); + + if ( $wp_query->get( 'min_price' ) ) { + $min_price_filter = $this->prepare_price_filter( $wp_query->get( 'min_price' ) ); + + if ( $adjust_for_taxes ) { + $args['where'] .= $this->get_price_filter_query_for_displayed_taxes( $min_price_filter, 'min_price', '>=' ); + } else { + $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.min_price >= %f ', $min_price_filter ); + } + } + + if ( $wp_query->get( 'max_price' ) ) { + $max_price_filter = $this->prepare_price_filter( $wp_query->get( 'max_price' ) ); + + if ( $adjust_for_taxes ) { + $args['where'] .= $this->get_price_filter_query_for_displayed_taxes( $max_price_filter, 'max_price', '<=' ); + } else { + $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.max_price <= %f ', $max_price_filter ); + } + } + + return $args; + } + + /** + * Get query for price filters when dealing with displayed taxes. + * + * @param float $price_filter Price filter to apply. + * @param string $column Price being filtered (min or max). + * @param string $operator Comparison operator for column. + * @return string Constructed query. + */ + protected function get_price_filter_query_for_displayed_taxes( $price_filter, $column = 'min_price', $operator = '>=' ) { + global $wpdb; + + // Select only used tax classes to avoid unwanted calculations. + $product_tax_classes = $wpdb->get_col( "SELECT DISTINCT tax_class FROM {$wpdb->wc_product_meta_lookup};" ); + + if ( empty( $product_tax_classes ) ) { + return ''; + } + + $or_queries = []; + + // We need to adjust the filter for each possible tax class and combine the queries into one. + foreach ( $product_tax_classes as $tax_class ) { + $adjusted_price_filter = $this->adjust_price_filter_for_tax_class( $price_filter, $tax_class ); + $or_queries[] = $wpdb->prepare( + '( wc_product_meta_lookup.tax_class = %s AND wc_product_meta_lookup.`' . esc_sql( $column ) . '` ' . esc_sql( $operator ) . ' %f )', + $tax_class, + $adjusted_price_filter + ); + } + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared + return $wpdb->prepare( + ' AND ( + wc_product_meta_lookup.tax_status = "taxable" AND ( 0=1 OR ' . implode( ' OR ', $or_queries ) . ') + OR ( wc_product_meta_lookup.tax_status != "taxable" AND wc_product_meta_lookup.`' . esc_sql( $column ) . '` ' . esc_sql( $operator ) . ' %f ) + ) ', + $price_filter + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared + } + + /** + * If price filters need adjustment to work with displayed taxes, this returns true. + * + * This logic is used when prices are stored in the database differently to how they are being displayed, with regards + * to taxes. + * + * @return boolean + */ + protected function adjust_price_filters_for_displayed_taxes() { + $display = get_option( 'woocommerce_tax_display_shop' ); + $database = wc_prices_include_tax() ? 'incl' : 'excl'; + + return $display !== $database; + } + + /** + * Converts price filter from subunits to decimal. + * + * @param string|int $price_filter Raw price filter in subunit format. + * @return float Price filter in decimal format. + */ + protected function prepare_price_filter( $price_filter ) { + return floatval( $price_filter / ( 10 ** wc_get_price_decimals() ) ); + } + + /** + * Adjusts a price filter based on a tax class and whether or not the amount includes or excludes taxes. + * + * This calculation logic is based on `wc_get_price_excluding_tax` and `wc_get_price_including_tax` in core. + * + * @param float $price_filter Price filter amount as entered. + * @param string $tax_class Tax class for adjustment. + * @return float + */ + protected function adjust_price_filter_for_tax_class( $price_filter, $tax_class ) { + $tax_display = get_option( 'woocommerce_tax_display_shop' ); + $tax_rates = WC_Tax::get_rates( $tax_class ); + $base_tax_rates = WC_Tax::get_base_tax_rates( $tax_class ); + + // If prices are shown incl. tax, we want to remove the taxes from the filter amount to match prices stored excl. tax. + if ( 'incl' === $tax_display ) { + $taxes = apply_filters( 'woocommerce_adjust_non_base_location_prices', true ) ? WC_Tax::calc_tax( $price_filter, $base_tax_rates, true ) : WC_Tax::calc_tax( $price_filter, $tax_rates, true ); + return $price_filter - array_sum( $taxes ); + } + + // If prices are shown excl. tax, add taxes to match the prices stored in the DB. + $taxes = WC_Tax::calc_tax( $price_filter, $tax_rates, false ); + + return $price_filter + array_sum( $taxes ); + } + + /** + * Join wc_product_meta_lookup to posts if not already joined. + * + * @param string $sql SQL join. + * @return string + */ + protected function append_product_sorting_table_join( $sql ) { + global $wpdb; + + if ( ! strstr( $sql, 'wc_product_meta_lookup' ) ) { + $sql .= " LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON $wpdb->posts.ID = wc_product_meta_lookup.product_id "; + } + return $sql; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ProductQueryFilters.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ProductQueryFilters.php new file mode 100644 index 0000000..d8ebb76 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ProductQueryFilters.php @@ -0,0 +1,145 @@ +prepare_objects_query( $request ); + $query_args['no_found_rows'] = true; + $query_args['posts_per_page'] = -1; + $query = new \WP_Query(); + $result = $query->query( $query_args ); + $product_query_sql = $query->request; + + remove_filter( 'posts_clauses', array( $product_query, 'add_query_clauses' ), 10 ); + remove_filter( 'posts_pre_query', '__return_empty_array' ); + + $price_filter_sql = " + SELECT min( min_price ) as min_price, MAX( max_price ) as max_price + FROM {$wpdb->wc_product_meta_lookup} + WHERE product_id IN ( {$product_query_sql} ) + "; + + return $wpdb->get_row( $price_filter_sql ); // phpcs:ignore + } + + /** + * Get attribute counts for the current products. + * + * @param \WP_REST_Request $request The request object. + * @param array $attributes Attributes to count, either names or ids. + * @return array termId=>count pairs. + */ + public function get_attribute_counts( $request, $attributes = [] ) { + global $wpdb; + + // Remove paging and sorting params from the request. + $request->set_param( 'page', null ); + $request->set_param( 'per_page', null ); + $request->set_param( 'order', null ); + $request->set_param( 'orderby', null ); + + // Grab the request from the WP Query object, and remove SQL_CALC_FOUND_ROWS and Limits so we get a list of all products. + $product_query = new ProductQuery(); + + add_filter( 'posts_clauses', array( $product_query, 'add_query_clauses' ), 10, 2 ); + add_filter( 'posts_pre_query', '__return_empty_array' ); + + $query_args = $product_query->prepare_objects_query( $request ); + $query_args['no_found_rows'] = true; + $query_args['posts_per_page'] = -1; + $query = new \WP_Query(); + $result = $query->query( $query_args ); + $product_query_sql = $query->request; + + remove_filter( 'posts_clauses', array( $product_query, 'add_query_clauses' ), 10 ); + remove_filter( 'posts_pre_query', '__return_empty_array' ); + + if ( count( $attributes ) === count( array_filter( $attributes, 'is_numeric' ) ) ) { + $attributes = array_map( 'wc_attribute_taxonomy_name_by_id', wp_parse_id_list( $attributes ) ); + } + + $attributes_to_count = array_map( 'wc_sanitize_taxonomy_name', $attributes ); + $attributes_to_count_sql = 'AND term_taxonomy.taxonomy IN ("' . implode( '","', $attributes_to_count ) . '")'; + $attribute_count_sql = " + SELECT COUNT( DISTINCT posts.ID ) as term_count, terms.term_id as term_count_id + FROM {$wpdb->posts} AS posts + INNER JOIN {$wpdb->term_relationships} AS term_relationships ON posts.ID = term_relationships.object_id + INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id ) + INNER JOIN {$wpdb->terms} AS terms USING( term_id ) + WHERE posts.ID IN ( {$product_query_sql} ) + {$attributes_to_count_sql} + GROUP BY terms.term_id + "; + + $results = $wpdb->get_results( $attribute_count_sql ); // phpcs:ignore + + return array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) ); + } + + /** + * Get rating counts for the current products. + * + * @param \WP_REST_Request $request The request object. + * @return array rating=>count pairs. + */ + public function get_rating_counts( $request ) { + global $wpdb; + + // Regenerate the products query without rating request params. + unset( $request['rating'] ); + + // Grab the request from the WP Query object, and remove SQL_CALC_FOUND_ROWS and Limits so we get a list of all products. + $product_query = new ProductQuery(); + + add_filter( 'posts_clauses', array( $product_query, 'add_query_clauses' ), 10, 2 ); + add_filter( 'posts_pre_query', '__return_empty_array' ); + + $query_args = $product_query->prepare_objects_query( $request ); + $query_args['no_found_rows'] = true; + $query_args['posts_per_page'] = -1; + $query = new \WP_Query(); + $result = $query->query( $query_args ); + $product_query_sql = $query->request; + + remove_filter( 'posts_clauses', array( $product_query, 'add_query_clauses' ), 10 ); + remove_filter( 'posts_pre_query', '__return_empty_array' ); + + $rating_count_sql = " + SELECT COUNT( DISTINCT product_id ) as product_count, ROUND( average_rating, 0 ) as rounded_average_rating + FROM {$wpdb->wc_product_meta_lookup} + WHERE product_id IN ( {$product_query_sql} ) + AND average_rating > 0 + GROUP BY rounded_average_rating + ORDER BY rounded_average_rating ASC + "; + + $results = $wpdb->get_results( $rating_count_sql ); // phpcs:ignore + + return array_map( 'absint', wp_list_pluck( $results, 'product_count', 'rounded_average_rating' ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ReserveStock.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ReserveStock.php new file mode 100644 index 0000000..1b914f5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ReserveStock.php @@ -0,0 +1,230 @@ +enabled = get_option( 'wc_blocks_db_schema_version', 0 ) >= 260; + } + + /** + * Is stock reservation enabled? + * + * @return boolean + */ + protected function is_enabled() { + return $this->enabled; + } + + /** + * Query for any existing holds on stock for this item. + * + * @param \WC_Product $product Product to get reserved stock for. + * @param integer $exclude_order_id Optional order to exclude from the results. + * + * @return integer Amount of stock already reserved. + */ + public function get_reserved_stock( \WC_Product $product, $exclude_order_id = 0 ) { + global $wpdb; + + if ( ! $this->is_enabled() ) { + return 0; + } + + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared + return (int) $wpdb->get_var( $this->get_query_for_reserved_stock( $product->get_stock_managed_by_id(), $exclude_order_id ) ); + } + + /** + * Put a temporary hold on stock for an order if enough is available. + * + * @throws ReserveStockException If stock cannot be reserved. + * + * @param \WC_Order $order Order object. + * @param int $minutes How long to reserve stock in minutes. Defaults to woocommerce_hold_stock_minutes. + */ + public function reserve_stock_for_order( \WC_Order $order, $minutes = 0 ) { + $minutes = $minutes ? $minutes : (int) get_option( 'woocommerce_hold_stock_minutes', 60 ); + + if ( ! $minutes || ! $this->is_enabled() ) { + return; + } + + try { + $items = array_filter( + $order->get_items(), + function( $item ) { + return $item->is_type( 'line_item' ) && $item->get_product() instanceof \WC_Product && $item->get_quantity() > 0; + } + ); + $rows = []; + + foreach ( $items as $item ) { + $product = $item->get_product(); + + if ( ! $product->is_in_stock() ) { + throw new ReserveStockException( + 'woocommerce_product_out_of_stock', + sprintf( + /* translators: %s: product name */ + __( '"%s" is out of stock and cannot be purchased.', 'woocommerce' ), + $product->get_name() + ), + 400 + ); + } + + // If stock management is off, no need to reserve any stock here. + if ( ! $product->managing_stock() || $product->backorders_allowed() ) { + continue; + } + + $managed_by_id = $product->get_stock_managed_by_id(); + $rows[ $managed_by_id ] = isset( $rows[ $managed_by_id ] ) ? $rows[ $managed_by_id ] + $item->get_quantity() : $item->get_quantity(); + } + + if ( ! empty( $rows ) ) { + foreach ( $rows as $product_id => $quantity ) { + $this->reserve_stock_for_product( $product_id, $quantity, $order, $minutes ); + } + } + } catch ( ReserveStockException $e ) { + $this->release_stock_for_order( $order ); + throw $e; + } + } + + /** + * Release a temporary hold on stock for an order. + * + * @param \WC_Order $order Order object. + */ + public function release_stock_for_order( \WC_Order $order ) { + global $wpdb; + + if ( ! $this->is_enabled() ) { + return; + } + + $wpdb->delete( + $wpdb->wc_reserved_stock, + [ + 'order_id' => $order->get_id(), + ] + ); + } + + /** + * Reserve stock for a product by inserting rows into the DB. + * + * @throws ReserveStockException If a row cannot be inserted. + * + * @param int $product_id Product ID which is having stock reserved. + * @param int $stock_quantity Stock amount to reserve. + * @param \WC_Order $order Order object which contains the product. + * @param int $minutes How long to reserve stock in minutes. + */ + private function reserve_stock_for_product( $product_id, $stock_quantity, \WC_Order $order, $minutes ) { + global $wpdb; + + $query_for_stock = $this->get_query_for_stock( $product_id ); + $query_for_reserved_stock = $this->get_query_for_reserved_stock( $product_id, $order->get_id() ); + $required_stock = $stock_quantity; + + // Deals with legacy stock reservations from woo core. + $support_legacy_held_stock = ! \class_exists( '\Automattic\WooCommerce\Checkout\Helpers\ReserveStock' ) && absint( get_option( 'woocommerce_hold_stock_minutes', 0 ) ) > 0; + + if ( $support_legacy_held_stock ) { + $required_stock += wc_get_held_stock_quantity( wc_get_product( $product_id ) ); + } + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared + $result = $wpdb->query( + $wpdb->prepare( + " + INSERT INTO {$wpdb->wc_reserved_stock} ( `order_id`, `product_id`, `stock_quantity`, `timestamp`, `expires` ) + SELECT %d, %d, %d, NOW(), ( NOW() + INTERVAL %d MINUTE ) FROM DUAL + WHERE ( $query_for_stock FOR UPDATE ) - ( $query_for_reserved_stock FOR UPDATE ) >= %d + ON DUPLICATE KEY UPDATE `expires` = VALUES( `expires` ), `stock_quantity` = VALUES( `stock_quantity` ) + ", + $order->get_id(), + $product_id, + $stock_quantity, + $minutes, + $required_stock + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared + + if ( ! $result ) { + $product = wc_get_product( $product_id ); + throw new ReserveStockException( + 'product_not_enough_stock', + sprintf( + /* translators: %s: product name */ + __( 'Not enough units of %s are available in stock to fulfil this order.', 'woocommerce' ), + $product ? $product->get_name() : '#' . $product_id + ), + 400 + ); + } + } + + /** + * Returns query statement for getting current `_stock` of a product. + * + * @todo Once merged to woo core data store, this method can be removed. + * @internal MAX function below is used to make sure result is a scalar. + * @param int $product_id Product ID. + * @return string|void Query statement. + */ + private function get_query_for_stock( $product_id ) { + global $wpdb; + return $wpdb->prepare( + " + SELECT COALESCE ( MAX( meta_value ), 0 ) FROM $wpdb->postmeta as meta_table + WHERE meta_table.meta_key = '_stock' + AND meta_table.post_id = %d + ", + $product_id + ); + } + + /** + * Returns query statement for getting reserved stock of a product. + * + * @param int $product_id Product ID. + * @param integer $exclude_order_id Optional order to exclude from the results. + * @return string|void Query statement. + */ + private function get_query_for_reserved_stock( $product_id, $exclude_order_id = 0 ) { + global $wpdb; + return $wpdb->prepare( + " + SELECT COALESCE( SUM( stock_table.`stock_quantity` ), 0 ) FROM $wpdb->wc_reserved_stock stock_table + LEFT JOIN $wpdb->posts posts ON stock_table.`order_id` = posts.ID + WHERE posts.post_status IN ( 'wc-checkout-draft', 'wc-pending' ) + AND stock_table.`expires` > NOW() + AND stock_table.`product_id` = %d + AND stock_table.`order_id` != %d + ", + $product_id, + $exclude_order_id + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ReserveStockException.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ReserveStockException.php new file mode 100644 index 0000000..19546fd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/ReserveStockException.php @@ -0,0 +1,57 @@ +error_code = $code; + $this->error_data = $data; + + parent::__construct( $message, $http_status_code ); + } + + /** + * Returns the error code. + * + * @return string + */ + public function getErrorCode() { + return $this->error_code; + } + + /** + * Returns error data. + * + * @return array + */ + public function getErrorData() { + return $this->error_data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Utils/BlocksWpQuery.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Utils/BlocksWpQuery.php new file mode 100644 index 0000000..40992be --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/Utils/BlocksWpQuery.php @@ -0,0 +1,71 @@ +init(); + $this->query = wp_parse_args( $query ); + $this->query_vars = $this->query; + $this->parse_query_vars(); + } + } + + /** + * Get cached posts, if a cache exists. + * + * A hash is generated using the array of query_vars. If doing custom queries via filters such as posts_where + * (where the SQL query is manipulated directly) you can still ensure there is a unique hash by injecting custom + * query vars via the parse_query filter. For example: + * + * add_filter( 'parse_query', function( $wp_query ) { + * $wp_query->query_vars['my_custom_query_var'] = true; + * } ); + * + * Doing so won't have any negative effect on the query itself, and it will cause the hash to change. + * + * @param string $transient_version Transient version to allow for invalidation. + * @return WP_Post[]|int[] Array of post objects or post IDs. + */ + public function get_cached_posts( $transient_version = '' ) { + $hash = md5( wp_json_encode( $this->query_vars ) ); + $transient_name = 'wc_blocks_query_' . $hash; + $transient_value = get_transient( $transient_name ); + + if ( isset( $transient_value, $transient_value['version'], $transient_value['value'] ) && $transient_value['version'] === $transient_version ) { + return $transient_value['value']; + } + + $results = $this->get_posts(); + + set_transient( + $transient_name, + array( + 'version' => $transient_version, + 'value' => $results, + ), + DAY_IN_SECONDS * 30 + ); + + return $results; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/templates/emails/customer-new-account-blocks.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/templates/emails/customer-new-account-blocks.php new file mode 100644 index 0000000..a37cf11 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/templates/emails/customer-new-account-blocks.php @@ -0,0 +1,32 @@ + + + +

    + +

    ' . esc_html( $user_login ) . '', make_clickable( esc_url( wc_get_page_permalink( 'myaccount' ) ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>

    + +

    + + +io = $io; + $this->filesystem = new Filesystem(); + } + + /** + * Dump the Jetpack autoloader files. + * + * @param Config $config Config object. + * @param InstalledRepositoryInterface $localRepo Installed Reposetories object. + * @param PackageInterface $mainPackage Main Package object. + * @param InstallationManager $installationManager Manager for installing packages. + * @param string $targetDir Path to the current target directory. + * @param bool $scanPsrPackages Whether or not PSR packages should be converted to a classmap. + * @param string $suffix The autoloader suffix. + */ + public function dump( + Config $config, + InstalledRepositoryInterface $localRepo, + PackageInterface $mainPackage, + InstallationManager $installationManager, + $targetDir, + $scanPsrPackages = false, + $suffix = null + ) { + $this->filesystem->ensureDirectoryExists( $config->get( 'vendor-dir' ) ); + + $packageMap = $this->buildPackageMap( $installationManager, $mainPackage, $localRepo->getCanonicalPackages() ); + $autoloads = $this->parseAutoloads( $packageMap, $mainPackage ); + + // Convert the autoloads into a format that the manifest generator can consume more easily. + $basePath = $this->filesystem->normalizePath( realpath( getcwd() ) ); + $vendorPath = $this->filesystem->normalizePath( realpath( $config->get( 'vendor-dir' ) ) ); + $processedAutoloads = $this->processAutoloads( $autoloads, $scanPsrPackages, $vendorPath, $basePath ); + unset( $packageMap, $autoloads ); + + // Make sure none of the legacy files remain that can lead to problems with the autoloader. + $this->removeLegacyFiles( $vendorPath ); + + // Write all of the files now that we're done. + $this->writeAutoloaderFiles( $vendorPath . '/jetpack-autoloader/', $suffix ); + $this->writeManifests( $vendorPath . '/' . $targetDir, $processedAutoloads ); + + if ( ! $scanPsrPackages ) { + $this->io->writeError( 'You are generating an unoptimized autoloader. If this is a production build, consider using the -o option.' ); + } + } + + /** + * This function differs from the composer parseAutoloadsType in that beside returning the path. + * It also return the path and the version of a package. + * + * Supports PSR-4, PSR-0, and classmap parsing. + * + * @param array $packageMap Map of all the packages. + * @param string $type Type of autoloader to use. + * @param PackageInterface $mainPackage Instance of the Package Object. + * + * @return array + */ + protected function parseAutoloadsType( array $packageMap, $type, PackageInterface $mainPackage ) { + $autoloads = array(); + + if ( 'psr-4' !== $type && 'classmap' !== $type && 'files' !== $type && 'psr-0' !== $type ) { + return parent::parseAutoloadsType( $packageMap, $type, $mainPackage ); + } + + foreach ( $packageMap as $item ) { + list($package, $installPath) = $item; + $autoload = $package->getAutoload(); + + if ( $package === $mainPackage ) { + $autoload = array_merge_recursive( $autoload, $package->getDevAutoload() ); + } + + if ( null !== $package->getTargetDir() && $package !== $mainPackage ) { + $installPath = substr( $installPath, 0, -strlen( '/' . $package->getTargetDir() ) ); + } + + if ( in_array( $type, array( 'psr-4', 'psr-0' ), true ) && isset( $autoload[ $type ] ) && is_array( $autoload[ $type ] ) ) { + foreach ( $autoload[ $type ] as $namespace => $paths ) { + $paths = is_array( $paths ) ? $paths : array( $paths ); + foreach ( $paths as $path ) { + $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path; + $autoloads[ $namespace ][] = array( + 'path' => $relativePath, + 'version' => $package->getVersion(), // Version of the class comes from the package - should we try to parse it? + ); + } + } + } + + if ( 'classmap' === $type && isset( $autoload['classmap'] ) && is_array( $autoload['classmap'] ) ) { + foreach ( $autoload['classmap'] as $paths ) { + $paths = is_array( $paths ) ? $paths : array( $paths ); + foreach ( $paths as $path ) { + $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path; + $autoloads[] = array( + 'path' => $relativePath, + 'version' => $package->getVersion(), // Version of the class comes from the package - should we try to parse it? + ); + } + } + } + if ( 'files' === $type && isset( $autoload['files'] ) && is_array( $autoload['files'] ) ) { + foreach ( $autoload['files'] as $paths ) { + $paths = is_array( $paths ) ? $paths : array( $paths ); + foreach ( $paths as $path ) { + $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path; + $autoloads[ $this->getFileIdentifier( $package, $path ) ] = array( + 'path' => $relativePath, + 'version' => $package->getVersion(), // Version of the file comes from the package - should we try to parse it? + ); + } + } + } + } + + return $autoloads; + } + + /** + * Given Composer's autoloads this will convert them to a version that we can use to generate the manifests. + * + * When the $scanPsrPackages argument is true, PSR-4 namespaces are converted to classmaps. When $scanPsrPackages + * is false, PSR-4 namespaces are not converted to classmaps. + * + * PSR-0 namespaces are always converted to classmaps. + * + * @param array $autoloads The autoloads we want to process. + * @param bool $scanPsrPackages Whether or not PSR-4 packages should be converted to a classmap. + * @param string $vendorPath The path to the vendor directory. + * @param string $basePath The path to the current directory. + * + * @return array $processedAutoloads + */ + private function processAutoloads( $autoloads, $scanPsrPackages, $vendorPath, $basePath ) { + $processor = new AutoloadProcessor( + function ( $path, $excludedClasses, $namespace ) use ( $basePath ) { + $dir = $this->filesystem->normalizePath( + $this->filesystem->isAbsolutePath( $path ) ? $path : $basePath . '/' . $path + ); + return ClassMapGenerator::createMap( + $dir, + $excludedClasses, + null, // Don't pass the IOInterface since the normal autoload generation will have reported already. + empty( $namespace ) ? null : $namespace + ); + }, + function ( $path ) use ( $basePath, $vendorPath ) { + return $this->getPathCode( $this->filesystem, $basePath, $vendorPath, $path ); + } + ); + + return array( + 'psr-4' => $processor->processPsr4Packages( $autoloads, $scanPsrPackages ), + 'classmap' => $processor->processClassmap( $autoloads, $scanPsrPackages ), + 'files' => $processor->processFiles( $autoloads ), + ); + } + + /** + * Removes all of the legacy autoloader files so they don't cause any problems. + * + * @param string $outDir The directory legacy files are written to. + */ + private function removeLegacyFiles( $outDir ) { + $files = array( + 'autoload_functions.php', + 'class-autoloader-handler.php', + 'class-classes-handler.php', + 'class-files-handler.php', + 'class-plugins-handler.php', + 'class-version-selector.php', + ); + foreach ( $files as $file ) { + $this->filesystem->remove( $outDir . '/' . $file ); + } + } + + /** + * Writes all of the autoloader files to disk. + * + * @param string $outDir The directory to write to. + * @param string $suffix The unique autoloader suffix. + */ + private function writeAutoloaderFiles( $outDir, $suffix ) { + $this->io->writeError( "Generating jetpack autoloader ($outDir)" ); + + // We will remove all autoloader files to generate this again. + $this->filesystem->emptyDirectory( $outDir ); + + $packageFiles = array( + 'autoload.php' => '../autoload_packages.php', + 'functions.php' => 'autoload_functions.php', + 'class-autoloader-locator.php' => null, + 'class-autoloader-handler.php' => null, + 'class-manifest-handler.php' => null, + 'class-plugins-handler.php' => null, + 'class-version-selector.php' => null, + 'class-version-loader.php' => null, + ); + + foreach ( $packageFiles as $file => $newFile ) { + $newFile = isset( $newFile ) ? $newFile : $file; + + $content = $this->getAutoloadPackageFile( $file, $suffix ); + + if ( file_put_contents( $outDir . '/' . $newFile, $content ) ) { + $this->io->writeError( " Generated: $newFile" ); + } else { + $this->io->writeError( " Error: $newFile" ); + } + } + } + + /** + * Writes all of the manifest files to disk. + * + * @param string $outDir The directory to write to. + * @param array $processedAutoloads The processed autoloads. + */ + private function writeManifests( $outDir, $processedAutoloads ) { + $this->io->writeError( "Generating jetpack autoloader manifests ($outDir)" ); + + $manifestFiles = array( + 'classmap' => 'jetpack_autoload_classmap.php', + 'psr-4' => 'jetpack_autoload_psr4.php', + 'files' => 'jetpack_autoload_filemap.php', + ); + + foreach ( $manifestFiles as $key => $file ) { + // Make sure the file doesn't exist so it isn't there if we don't write it. + $this->filesystem->remove( $outDir . '/' . $file ); + if ( empty( $processedAutoloads[ $key ] ) ) { + continue; + } + + $content = ManifestGenerator::buildManifest( $key, $file, $processedAutoloads[ $key ] ); + if ( empty( $content ) ) { + continue; + } + + if ( file_put_contents( $outDir . '/' . $file, $content ) ) { + $this->io->writeError( " Generated: $file" ); + } else { + $this->io->writeError( " Error: $file" ); + } + } + } + + /** + * Generate the PHP that will be used in the autoload_packages.php files. + * + * @param String $filename a file to prepare. + * @param String $suffix Unique suffix used in the namespace. + * + * @return string + */ + private function getAutoloadPackageFile( $filename, $suffix ) { + $header = self::COMMENT; + $header .= PHP_EOL; + $header .= 'namespace Automattic\Jetpack\Autoloader\jp' . $suffix . ';'; + $header .= PHP_EOL . PHP_EOL; + + $sourceLoader = fopen( __DIR__ . '/' . $filename, 'r' ); + $file_contents = stream_get_contents( $sourceLoader ); + return str_replace( + '/* HEADER */', + $header, + $file_contents + ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/AutoloadProcessor.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/AutoloadProcessor.php new file mode 100644 index 0000000..4db5bb1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/AutoloadProcessor.php @@ -0,0 +1,182 @@ +classmapScanner = $classmapScanner; + $this->pathCodeTransformer = $pathCodeTransformer; + } + + /** + * Processes the classmap autoloads into a relative path format including the version for each file. + * + * @param array $autoloads The autoloads we are processing. + * @param bool $scanPsrPackages Whether or not PSR packages should be converted to a classmap. + * + * @return array $processed + */ + public function processClassmap( $autoloads, $scanPsrPackages ) { + // We can't scan PSR packages if we don't actually have any. + if ( empty( $autoloads['psr-4'] ) ) { + $scanPsrPackages = false; + } + + if ( empty( $autoloads['classmap'] ) && ! $scanPsrPackages ) { + return null; + } + + $excludedClasses = null; + if ( ! empty( $autoloads['exclude-from-classmap'] ) ) { + $excludedClasses = '{(' . implode( '|', $autoloads['exclude-from-classmap'] ) . ')}'; + } + + $processed = array(); + + if ( $scanPsrPackages ) { + foreach ( $autoloads['psr-4'] as $namespace => $sources ) { + $namespace = empty( $namespace ) ? null : $namespace; + + foreach ( $sources as $source ) { + $classmap = call_user_func( $this->classmapScanner, $source['path'], $excludedClasses, $namespace ); + + foreach ( $classmap as $class => $path ) { + $processed[ $class ] = array( + 'version' => $source['version'], + 'path' => call_user_func( $this->pathCodeTransformer, $path ), + ); + } + } + } + } + + /* + * PSR-0 namespaces are converted to classmaps for both optimized and unoptimized autoloaders because any new + * development should use classmap or PSR-4 autoloading. + */ + if ( ! empty( $autoloads['psr-0'] ) ) { + foreach ( $autoloads['psr-0'] as $namespace => $sources ) { + $namespace = empty( $namespace ) ? null : $namespace; + + foreach ( $sources as $source ) { + $classmap = call_user_func( $this->classmapScanner, $source['path'], $excludedClasses, $namespace ); + foreach ( $classmap as $class => $path ) { + $processed[ $class ] = array( + 'version' => $source['version'], + 'path' => call_user_func( $this->pathCodeTransformer, $path ), + ); + } + } + } + } + + if ( ! empty( $autoloads['classmap'] ) ) { + foreach ( $autoloads['classmap'] as $package ) { + $classmap = call_user_func( $this->classmapScanner, $package['path'], $excludedClasses, null ); + + foreach ( $classmap as $class => $path ) { + $processed[ $class ] = array( + 'version' => $package['version'], + 'path' => call_user_func( $this->pathCodeTransformer, $path ), + ); + } + } + } + + return $processed; + } + + /** + * Processes the PSR-4 autoloads into a relative path format including the version for each file. + * + * @param array $autoloads The autoloads we are processing. + * @param bool $scanPsrPackages Whether or not PSR packages should be converted to a classmap. + * + * @return array $processed + */ + public function processPsr4Packages( $autoloads, $scanPsrPackages ) { + if ( $scanPsrPackages || empty( $autoloads['psr-4'] ) ) { + return null; + } + + $processed = array(); + + foreach ( $autoloads['psr-4'] as $namespace => $packages ) { + $namespace = empty( $namespace ) ? null : $namespace; + $paths = array(); + + foreach ( $packages as $package ) { + $paths[] = call_user_func( $this->pathCodeTransformer, $package['path'] ); + } + + $processed[ $namespace ] = array( + 'version' => $package['version'], + 'path' => $paths, + ); + } + + return $processed; + } + + /** + * Processes the file autoloads into a relative format including the version for each file. + * + * @param array $autoloads The autoloads we are processing. + * + * @return array|null $processed + */ + public function processFiles( $autoloads ) { + if ( empty( $autoloads['files'] ) ) { + return null; + } + + $processed = array(); + + foreach ( $autoloads['files'] as $file_id => $package ) { + $processed[ $file_id ] = array( + 'version' => $package['version'], + 'path' => call_user_func( $this->pathCodeTransformer, $package['path'] ), + ); + } + + return $processed; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php new file mode 100644 index 0000000..159c748 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php @@ -0,0 +1,126 @@ +composer = $composer; + $this->io = $io; + } + + /** + * Do nothing. + * phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + * + * @param Composer $composer Composer object. + * @param IOInterface $io IO object. + */ + public function deactivate( Composer $composer, IOInterface $io ) { + /* + * Intentionally left empty. This is a PluginInterface method. + * phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + */ + } + + /** + * Do nothing. + * phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + * + * @param Composer $composer Composer object. + * @param IOInterface $io IO object. + */ + public function uninstall( Composer $composer, IOInterface $io ) { + /* + * Intentionally left empty. This is a PluginInterface method. + * phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + */ + } + + + /** + * Tell composer to listen for events and do something with them. + * + * @return array List of subscribed events. + */ + public static function getSubscribedEvents() { + return array( + ScriptEvents::POST_AUTOLOAD_DUMP => 'postAutoloadDump', + ); + } + + /** + * Generate the custom autolaoder. + * + * @param Event $event Script event object. + */ + public function postAutoloadDump( Event $event ) { + $config = $this->composer->getConfig(); + + if ( 'vendor' !== $config->raw()['config']['vendor-dir'] ) { + $this->io->writeError( "\nAn error occurred while generating the autoloader files:", true ); + $this->io->writeError( 'The project\'s composer.json or composer environment set a non-default vendor directory.', true ); + $this->io->writeError( 'The default composer vendor directory must be used.', true ); + exit(); + } + + $installationManager = $this->composer->getInstallationManager(); + $repoManager = $this->composer->getRepositoryManager(); + $localRepo = $repoManager->getLocalRepository(); + $package = $this->composer->getPackage(); + $optimize = $event->getFlags()['optimize']; + $suffix = $config->get( 'autoloader-suffix' ) + ? $config->get( 'autoloader-suffix' ) + : md5( uniqid( '', true ) ); + + $generator = new AutoloadGenerator( $this->io ); + + $generator->dump( $config, $localRepo, $package, $installationManager, 'composer', $optimize, $suffix ); + $this->generated = true; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/ManifestGenerator.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/ManifestGenerator.php new file mode 100644 index 0000000..595a97f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/ManifestGenerator.php @@ -0,0 +1,121 @@ + $data ) { + $key = var_export( $key, true ); + $versionCode = var_export( $data['version'], true ); + $fileContent .= << array( + 'version' => $versionCode, + 'path' => {$data['path']} + ), +MANIFEST_CODE; + $fileContent .= PHP_EOL; + } + + return self::buildFile( $fileName, $fileContent ); + } + + /** + * Builds the contents for the PSR-4 manifest file. + * + * @param string $fileName The filename we are building. + * @param array $namespaces The formatted PSR-4 data for the manifest. + * + * @return string|null $manifestFile + */ + private static function buildPsr4Manifest( $fileName, $namespaces ) { + $fileContent = PHP_EOL; + foreach ( $namespaces as $namespace => $data ) { + $namespaceCode = var_export( $namespace, true ); + $versionCode = var_export( $data['version'], true ); + $pathCode = 'array( ' . implode( ', ', $data['path'] ) . ' )'; + $fileContent .= << array( + 'version' => $versionCode, + 'path' => $pathCode + ), +MANIFEST_CODE; + $fileContent .= PHP_EOL; + } + + return self::buildFile( $fileName, $fileContent ); + } + + /** + * Generate the PHP that will be used in the file. + * + * @param string $fileName The filename we are building. + * @param string $content The content to be written into the file. + * + * @return string $fileContent + */ + private static function buildFile( $fileName, $content ) { + return <<current_plugin_path = $current_plugin_path; + $this->active_plugin_paths = $active_plugin_paths; + $this->autoloader_locator = $autoloader_locator; + $this->version_selector = $version_selector; + } + + /** + * Finds the latest installed autoloader. + * + * @return bool True if this autoloader is the latest, false otherwise. + */ + public function is_latest_autoloader() { + global $jetpack_autoloader_latest_version; + + if ( isset( $jetpack_autoloader_latest_version ) ) { + return $jetpack_autoloader_latest_version === $this->autoloader_locator->get_autoloader_version( $this->current_plugin_path ); + } + + $latest_plugin = $this->autoloader_locator->find_latest_autoloader( $this->active_plugin_paths, $jetpack_autoloader_latest_version ); + if ( ! isset( $latest_plugin ) ) { + return true; + } + + if ( $latest_plugin !== $this->current_plugin_path ) { + require $this->autoloader_locator->get_autoloader_path( $latest_plugin ); + return false; + } + + return true; + } + + /** + * Checks whether the autoloader should be reset. The autoloader should be reset: + * + * - When a plugin is activated via a method other than a request, for example using WP-CLI. + * - When the active plugins list changes between autoloader checks, for example when filtered by a plugin. + * + * We perform this reset because the manifest files for the plugin will have been initially unknown when + * selecting versions for classes and files. + * + * If the current plugin is not already known, this method will add it to the + * $jetpack_autoloader_activating_plugins_paths global. + * The $jetpack_autoloader_cached_plugin_paths global will store a cache of the + * active plugin paths when last changed. + * + * @return boolean True if the autoloader must be reset, else false. + */ + public function should_autoloader_reset() { + global $jetpack_autoloader_activating_plugins_paths; + global $jetpack_autoloader_cached_plugin_paths; + + $plugin_unknown = ! in_array( $this->current_plugin_path, $this->active_plugin_paths, true ); + if ( $plugin_unknown ) { + if ( ! isset( $jetpack_autoloader_activating_plugins_paths ) ) { + $jetpack_autoloader_activating_plugins_paths = array(); + } + + // If the current plugin isn't known, add it to the activating plugins list. + $jetpack_autoloader_activating_plugins_paths[] = $this->current_plugin_path; + $this->active_plugin_paths[] = $this->current_plugin_path; + } + + $cache_invalidated = $jetpack_autoloader_cached_plugin_paths !== $this->active_plugin_paths; + if ( $cache_invalidated ) { + $jetpack_autoloader_cached_plugin_paths = $this->active_plugin_paths; + } + + return $plugin_unknown || $cache_invalidated; + } + + /** + * Builds the Version_Autoloader class that is used for autoloading. + * + * @return Version_Loader + */ + public function build_autoloader() { + $manifest_handler = new Manifest_Handler( $this->active_plugin_paths, $this->version_selector ); + + global $jetpack_packages_psr4; + $jetpack_packages_psr4 = array(); + $manifest_handler->register_plugin_manifests( 'vendor/composer/jetpack_autoload_psr4.php', $jetpack_packages_psr4 ); + + global $jetpack_packages_classmap; + $jetpack_packages_classmap = array(); + $manifest_handler->register_plugin_manifests( 'vendor/composer/jetpack_autoload_classmap.php', $jetpack_packages_classmap ); + + global $jetpack_packages_filemap; + $jetpack_packages_filemap = array(); + $manifest_handler->register_plugin_manifests( 'vendor/composer/jetpack_autoload_filemap.php', $jetpack_packages_filemap ); + + // Store the generated autoloader data in the loader so we can use it. + return new Version_Loader( + $this->version_selector, + $jetpack_packages_classmap, + $jetpack_packages_psr4, + $jetpack_packages_filemap + ); + } + + /** + * Updates the spl autoloader chain: + * - Registers this namespace's autoloader function. + * - If a v1 autoloader function is registered, moves it to the end of the chain. + * - Removes any other v2 autoloader functions that have already been registered. This + * can occur when the autoloader is being reset by an activating plugin. + */ + public function update_autoloader_chain() { + spl_autoload_register( __NAMESPACE__ . '\autoloader' ); + + $autoload_chain = spl_autoload_functions(); + + foreach ( $autoload_chain as $autoloader ) { + if ( ! is_string( $autoloader ) ) { + /* + * The Jetpack Autoloader functions are registered as strings, so + * just continue if $autoloader isn't a string. + */ + continue; + } + + if ( self::V1_AUTOLOADER_NAME === $autoloader ) { + // Move the v1.* autoloader function to the end of the spl autoloader chain. + spl_autoload_unregister( $autoloader ); + spl_autoload_register( $autoloader ); + + } elseif ( + self::V2_AUTOLOADER_BASE === substr( $autoloader, 0, strlen( self::V2_AUTOLOADER_BASE ) ) + && __NAMESPACE__ !== substr( $autoloader, 0, strlen( __NAMESPACE__ ) ) + ) { + // Unregister any other v2.* autoloader functions if they're in the chain. + spl_autoload_unregister( $autoloader ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-autoloader-locator.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-autoloader-locator.php new file mode 100644 index 0000000..b418c5f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-autoloader-locator.php @@ -0,0 +1,82 @@ +version_selector = $version_selector; + } + + /** + * Finds the path to the plugin with the latest autoloader. + * + * @param array $plugin_paths An array of plugin paths. + * @param string $latest_version The latest version reference. + * + * @return string|null + */ + public function find_latest_autoloader( $plugin_paths, &$latest_version ) { + $latest_plugin = null; + + foreach ( $plugin_paths as $plugin_path ) { + $version = $this->get_autoloader_version( $plugin_path ); + if ( ! $this->version_selector->is_version_update_required( $latest_version, $version ) ) { + continue; + } + + $latest_version = $version; + $latest_plugin = $plugin_path; + } + + return $latest_plugin; + } + + /** + * Gets the path to the autoloader. + * + * @param string $plugin_path The path to the plugin. + * + * @return string + */ + public function get_autoloader_path( $plugin_path ) { + return trailingslashit( $plugin_path ) . 'vendor/autoload_packages.php'; + } + + /** + * Gets the version for the autoloader. + * + * @param string $plugin_path The path to the plugin. + * + * @return string|null + */ + public function get_autoloader_version( $plugin_path ) { + $classmap = trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; + if ( ! file_exists( $classmap ) ) { + return null; + } + + $classmap = require $classmap; + if ( isset( $classmap[ AutoloadGenerator::class ] ) ) { + return $classmap[ AutoloadGenerator::class ]['version']; + } + + return null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-manifest-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-manifest-handler.php new file mode 100644 index 0000000..f402716 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-manifest-handler.php @@ -0,0 +1,99 @@ +active_plugin_paths = $active_plugin_paths; + $this->version_selector = $version_selector; + } + + /** + * Registers all of the paths in a given manifest. + * + * @param string $manifest_path The path that we're loading the manifest from in each plugin. + * @param array $path_map The path map to add the contents of the manifests to. + * + * @return array $path_map The path map we've built using the manifests in each plugin. + */ + public function register_plugin_manifests( $manifest_path, &$path_map ) { + $file_paths = array_map( + function ( $path ) use ( $manifest_path ) { + return trailingslashit( $path ) . $manifest_path; + }, + $this->active_plugin_paths + ); + + foreach ( $file_paths as $path ) { + $this->register_manifest( $path, $path_map ); + } + + return $path_map; + } + + /** + * Registers a plugin's manifest file with the path map. + * + * @param string $manifest_path The absolute path to the manifest that we're loading. + * @param array $path_map The path map to add the contents of the manifest to. + */ + protected function register_manifest( $manifest_path, &$path_map ) { + if ( ! is_readable( $manifest_path ) ) { + return; + } + + $manifest = require $manifest_path; + if ( ! is_array( $manifest ) ) { + return; + } + + foreach ( $manifest as $key => $data ) { + $this->register_record( $key, $data, $path_map ); + } + } + + /** + * Registers an entry from the manifest in the path map. + * + * @param string $key The identifier for the entry we're registering. + * @param array $data The data for the entry we're registering. + * @param array $path_map The path map to add the contents of the manifest to. + */ + protected function register_record( $key, $data, &$path_map ) { + if ( isset( $path_map[ $key ]['version'] ) ) { + $selected_version = $path_map[ $key ]['version']; + } else { + $selected_version = null; + } + + if ( $this->version_selector->is_version_update_required( $selected_version, $data['version'] ) ) { + $path_map[ $key ] = array( + 'version' => $data['version'], + 'path' => $data['path'], + ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php new file mode 100644 index 0000000..30b2bd2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php @@ -0,0 +1,129 @@ +get_active_plugins_paths(); + $multisite_plugins_paths = $this->get_multisite_plugins_paths(); + $activating_plugins_paths = $this->get_plugins_activating_via_request(); + + return array_unique( + array_merge( + $active_plugins_paths, + $activating_plugins_paths, + $multisite_plugins_paths, + (array) $jetpack_autoloader_activating_plugins_paths + ) + ); + } + + /** + * Returns an array containing the paths of the active sitewide plugins in a multisite environment. + * + * @return array The paths of the active sitewide plugins or an empty array. + */ + protected function get_multisite_plugins_paths() { + $plugin_slugs = is_multisite() + ? array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) + : array(); + + $plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + /** + * Returns an array containing the paths of the currently active plugins. + * + * @return array The active plugins' paths or an empty array. + */ + protected function get_active_plugins_paths() { + $plugin_slugs = (array) get_option( 'active_plugins', array() ); + $plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + /** + * Adds the plugin directory from the WP_PLUGIN_DIR constant to the plugin slug. + * + * @param string $plugin_slug The plugin slug. + */ + private function create_plugin_path( $plugin_slug ) { + $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR ); + return trailingslashit( $plugin_dir ) . substr( $plugin_slug, 0, strrpos( $plugin_slug, '/' ) ); + } + + /** + * Ensure the plugin has its own directory and not a single-file plugin. + * + * @param string $plugin Plugin name, may be prefixed with "/". + * + * @return bool + */ + public function is_directory_plugin( $plugin ) { + return strlen( $plugin ) > 1 && false !== strpos( $plugin, '/', 1 ); + } + + /** + * Returns an array containing the names of plugins that are activating via a request. + * + * @return array An array of names of the activating plugins or an empty array. + */ + private function get_plugins_activating_via_request() { + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + // phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash + // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : false; + $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : false; + $nonce = isset( $_REQUEST['_wpnonce'] ) ? $_REQUEST['_wpnonce'] : false; + + /** + * Note: we're not actually checking the nonce here becase it's too early + * in the execution. The pluggable functions are not yet loaded to give + * plugins a chance to plug their versions. Therefore we're doing the bare + * minimum: checking whether the nonce exists and it's in the right place. + * The request will fail later if the nonce doesn't pass the check. + */ + + // In case of a single plugin activation there will be a plugin slug. + if ( 'activate' === $action && ! empty( $nonce ) ) { + return array( $this->create_plugin_path( wp_unslash( $plugin ) ) ); + } + + $plugins = isset( $_REQUEST['checked'] ) ? $_REQUEST['checked'] : array(); + + // In case of bulk activation there will be an array of plugins. + if ( 'activate-selected' === $action && ! empty( $nonce ) ) { + $plugin_slugs = array_map( 'wp_unslash', $plugins ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + // phpcs:enable WordPress.Security.NonceVerification.Recommended + // phpcs:enable WordPress.Security.ValidatedSanitizedInput.MissingUnslash + // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + return array(); + } + + /** + * Returns the path of the current plugin. + * + * @return string The path of the current plugin. + */ + public function get_current_plugin_path() { + $vendor_path = str_replace( '\\', '/', dirname( dirname( __FILE__ ) ) ); + // Path to the plugin's folder (the parent of the vendor/jetpack-autoloader folder). + return substr( $vendor_path, 0, strrpos( $vendor_path, '/' ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-version-loader.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-version-loader.php new file mode 100644 index 0000000..a1169ce --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-version-loader.php @@ -0,0 +1,156 @@ +version_selector = $version_selector; + $this->classmap = $classmap; + $this->psr4_map = $psr4_map; + $this->filemap = $filemap; + } + + /** + * Finds the file path for the given class. + * + * @param string $class_name The class to find. + * + * @return string|null $file_path The path to the file if found, null if no class was found. + */ + public function find_class_file( $class_name ) { + $data = $this->select_newest_file( + isset( $this->classmap[ $class_name ] ) ? $this->classmap[ $class_name ] : null, + $this->find_psr4_file( $class_name ) + ); + if ( ! isset( $data ) ) { + return null; + } + + return $data['path']; + } + + /** + * Load all of the files in the filemap. + */ + public function load_filemap() { + if ( empty( $this->filemap ) ) { + return; + } + + foreach ( $this->filemap as $file_identifier => $file_data ) { + if ( empty( $GLOBALS['__composer_autoload_files'][ $file_identifier ] ) ) { + require_once $file_data['path']; + + $GLOBALS['__composer_autoload_files'][ $file_identifier ] = true; + } + } + } + + /** + * Compares different class sources and returns the newest. + * + * @param array|null $classmap_data The classmap class data. + * @param array|null $psr4_data The PSR-4 class data. + * + * @return array|null $data + */ + private function select_newest_file( $classmap_data, $psr4_data ) { + if ( ! isset( $classmap_data ) ) { + return $psr4_data; + } elseif ( ! isset( $psr4_data ) ) { + return $classmap_data; + } + + if ( $this->version_selector->is_version_update_required( $classmap_data['version'], $psr4_data['version'] ) ) { + return $psr4_data; + } + + return $classmap_data; + } + + /** + * Finds the file for a given class in a PSR-4 namespace. + * + * @param string $class_name The class to find. + * + * @return array|null $data The version and path path to the file if found, null otherwise. + */ + private function find_psr4_file( $class_name ) { + if ( ! isset( $this->psr4_map ) ) { + return null; + } + + // Don't bother with classes that have no namespace. + $class_index = strrpos( $class_name, '\\' ); + if ( ! $class_index ) { + return null; + } + $class_for_path = str_replace( '\\', '/', $class_name ); + + // Search for the namespace by iteratively cutting off the last segment until + // we find a match. This allows us to check the most-specific namespaces + // first as well as minimize the amount of time spent looking. + for ( + $class_namespace = substr( $class_name, 0, $class_index ); + ! empty( $class_namespace ); + $class_namespace = substr( $class_namespace, 0, strrpos( $class_namespace, '\\' ) ) + ) { + $namespace = $class_namespace . '\\'; + if ( ! isset( $this->psr4_map[ $namespace ] ) ) { + continue; + } + $data = $this->psr4_map[ $namespace ]; + + foreach ( $data['path'] as $path ) { + $path .= '/' . substr( $class_for_path, strlen( $namespace ) ) . '.php'; + if ( file_exists( $path ) ) { + return array( + 'version' => $data['version'], + 'path' => $path, + ); + } + } + } + + return null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-version-selector.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-version-selector.php new file mode 100644 index 0000000..02c002e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/class-version-selector.php @@ -0,0 +1,61 @@ +is_package_version_dev( $selected_version ) ) { + return false; + } + + if ( $this->is_package_version_dev( $compare_version ) ) { + if ( $use_dev_versions ) { + return true; + } else { + return false; + } + } + + if ( version_compare( $selected_version, $compare_version, '<' ) ) { + return true; + } + + return false; + } + + /** + * Checks whether the given package version is a development version. + * + * @param String $version The package version. + * + * @return Boolean True if the version is a dev version, else false. + */ + private function is_package_version_dev( $version ) { + if ( 'dev-' === substr( $version, 0, 4 ) || '9999999-dev' === $version ) { + return true; + } + + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/functions.php new file mode 100644 index 0000000..bb30095 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/automattic/jetpack-autoloader/src/functions.php @@ -0,0 +1,66 @@ +find_class_file( $class_name ); + if ( ! isset( $file ) ) { + return false; + } + + require_once $file; + return true; +} + +/** + * Finds the latest installed autoloader. If this is the latest autoloader, sets + * up the classmap and filemap. + */ +function set_up_autoloader() { + global $jetpack_autoloader_latest_version; + global $jetpack_autoloader_loader; + + require_once __DIR__ . '/class-plugins-handler.php'; + require_once __DIR__ . '/class-version-selector.php'; + require_once __DIR__ . '/class-autoloader-locator.php'; + require_once __DIR__ . '/class-autoloader-handler.php'; + + $plugins_handler = new Plugins_Handler(); + $version_selector = new Version_Selector(); + $autoloader_handler = new Autoloader_Handler( + $plugins_handler->get_current_plugin_path(), + $plugins_handler->get_all_active_plugins_paths(), + new Autoloader_Locator( $version_selector ), + $version_selector + ); + + // The autoloader must be reset when a plugin that was previously unknown is detected. + if ( $autoloader_handler->should_autoloader_reset() ) { + $jetpack_autoloader_latest_version = null; + $jetpack_autoloader_loader = null; + } + + if ( ! $autoloader_handler->is_latest_autoloader() || isset( $jetpack_autoloader_loader ) ) { + return; + } + + require_once __DIR__ . '/class-manifest-handler.php'; + require_once __DIR__ . '/class-version-loader.php'; + + $jetpack_autoloader_loader = $autoloader_handler->build_autoloader(); + $autoloader_handler->update_autoloader_chain(); + + // Now that the autoloader is ready we can load the files in the filemap safely. + $jetpack_autoloader_loader->load_filemap(); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/ClassLoader.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/ClassLoader.php new file mode 100644 index 0000000..1a58957 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/ClassLoader.php @@ -0,0 +1,445 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/InstalledVersions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..ae2780a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/InstalledVersions.php @@ -0,0 +1,241 @@ + + array ( + 'pretty_version' => 'dev-trunk', + 'version' => 'dev-trunk', + 'aliases' => + array ( + ), + 'reference' => '04b4d8d9fec5b03696f063d0d632d5fa5a6d1368', + 'name' => 'woocommerce/woocommerce-blocks', + ), + 'versions' => + array ( + 'automattic/jetpack-autoloader' => + array ( + 'pretty_version' => 'v2.5.0', + 'version' => '2.5.0.0', + 'aliases' => + array ( + ), + 'reference' => '7945e862473e39f05e6f698f1598ea30a12e5965', + ), + 'composer/installers' => + array ( + 'pretty_version' => 'v1.9.0', + 'version' => '1.9.0.0', + 'aliases' => + array ( + ), + 'reference' => 'b93bcf0fa1fccb0b7d176b0967d969691cd74cca', + ), + 'roundcube/plugin-installer' => + array ( + 'replaced' => + array ( + 0 => '*', + ), + ), + 'shama/baton' => + array ( + 'replaced' => + array ( + 0 => '*', + ), + ), + 'woocommerce/woocommerce-blocks' => + array ( + 'pretty_version' => 'dev-trunk', + 'version' => 'dev-trunk', + 'aliases' => + array ( + ), + 'reference' => '04b4d8d9fec5b03696f063d0d632d5fa5a6d1368', + ), + ), +); + + + + + + + +public static function getInstalledPackages() +{ +return array_keys(self::$installed['versions']); +} + + + + + + + + + +public static function isInstalled($packageName) +{ +return isset(self::$installed['versions'][$packageName]); +} + + + + + + + + + + + + + + +public static function satisfies(VersionParser $parser, $packageName, $constraint) +{ +$constraint = $parser->parseConstraints($constraint); +$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + +return $provided->matches($constraint); +} + + + + + + + + + + +public static function getVersionRanges($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +$ranges = array(); +if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = self::$installed['versions'][$packageName]['pretty_version']; +} +if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); +} +if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); +} +if (array_key_exists('provided', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); +} + +return implode(' || ', $ranges); +} + + + + + +public static function getVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['version']; +} + + + + + +public static function getPrettyVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['pretty_version']; +} + + + + + +public static function getReference($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['reference'])) { +return null; +} + +return self::$installed['versions'][$packageName]['reference']; +} + + + + + +public static function getRootPackage() +{ +return self::$installed['root']; +} + + + + + + + +public static function getRawData() +{ +return self::$installed; +} + + + + + + + + + + + + + + + + + + + +public static function reload($data) +{ +self::$installed = $data; +} +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/LICENSE b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_classmap.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..e63ebab --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_classmap.php @@ -0,0 +1,11 @@ + $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadGenerator.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_namespaces.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..b7fc012 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/composer/installers/src/Composer/Installers'), + 'Automattic\\WooCommerce\\Blocks\\' => array($baseDir . '/src'), + 'Automattic\\Jetpack\\Autoloader\\' => array($vendorDir . '/automattic/jetpack-autoloader/src'), +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_real.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_real.php new file mode 100644 index 0000000..b55baaf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_real.php @@ -0,0 +1,55 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit50079f60a6aee92920d5faa34d817888::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_static.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_static.php new file mode 100644 index 0000000..568dd8f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/autoload_static.php @@ -0,0 +1,50 @@ + + array ( + 'Composer\\Installers\\' => 20, + ), + 'A' => + array ( + 'Automattic\\WooCommerce\\Blocks\\' => 30, + 'Automattic\\Jetpack\\Autoloader\\' => 30, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Composer\\Installers\\' => + array ( + 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers', + ), + 'Automattic\\WooCommerce\\Blocks\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + 'Automattic\\Jetpack\\Autoloader\\' => + array ( + 0 => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src', + ), + ); + + public static $classMap = array ( + 'Automattic\\Jetpack\\Autoloader\\AutoloadGenerator' => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src/AutoloadGenerator.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit50079f60a6aee92920d5faa34d817888::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit50079f60a6aee92920d5faa34d817888::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit50079f60a6aee92920d5faa34d817888::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installed.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installed.json new file mode 100644 index 0000000..a432f61 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installed.json @@ -0,0 +1,195 @@ +{ + "packages": [ + { + "name": "automattic/jetpack-autoloader", + "version": "v2.5.0", + "version_normalized": "2.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/Automattic/jetpack-autoloader.git", + "reference": "7945e862473e39f05e6f698f1598ea30a12e5965" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/7945e862473e39f05e6f698f1598ea30a12e5965", + "reference": "7945e862473e39f05e6f698f1598ea30a12e5965", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1 || ^2.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5" + }, + "time": "2020-10-08T19:51:11+00:00", + "type": "composer-plugin", + "extra": { + "class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin" + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/AutoloadGenerator.php" + ], + "psr-4": { + "Automattic\\Jetpack\\Autoloader\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Creates a custom autoloader for a plugin or theme.", + "support": { + "source": "https://github.com/Automattic/jetpack-autoloader/tree/v2.5.0" + }, + "install-path": "../automattic/jetpack-autoloader" + }, + { + "name": "composer/installers", + "version": "v1.9.0", + "version_normalized": "1.9.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || 2.0.*@dev", + "composer/semver": "1.0.* || 2.0.*@dev", + "phpunit/phpunit": "^4.8.36", + "sebastian/comparator": "^1.2.4", + "symfony/process": "^2.3" + }, + "time": "2020-04-07T06:57:05+00:00", + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v1.9.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "install-path": "./installers" + } + ], + "dev": false, + "dev-package-names": [] +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installed.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installed.php new file mode 100644 index 0000000..5947905 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installed.php @@ -0,0 +1,56 @@ + + array ( + 'pretty_version' => 'dev-trunk', + 'version' => 'dev-trunk', + 'aliases' => + array ( + ), + 'reference' => '04b4d8d9fec5b03696f063d0d632d5fa5a6d1368', + 'name' => 'woocommerce/woocommerce-blocks', + ), + 'versions' => + array ( + 'automattic/jetpack-autoloader' => + array ( + 'pretty_version' => 'v2.5.0', + 'version' => '2.5.0.0', + 'aliases' => + array ( + ), + 'reference' => '7945e862473e39f05e6f698f1598ea30a12e5965', + ), + 'composer/installers' => + array ( + 'pretty_version' => 'v1.9.0', + 'version' => '1.9.0.0', + 'aliases' => + array ( + ), + 'reference' => 'b93bcf0fa1fccb0b7d176b0967d969691cd74cca', + ), + 'roundcube/plugin-installer' => + array ( + 'replaced' => + array ( + 0 => '*', + ), + ), + 'shama/baton' => + array ( + 'replaced' => + array ( + 0 => '*', + ), + ), + 'woocommerce/woocommerce-blocks' => + array ( + 'pretty_version' => 'dev-trunk', + 'version' => 'dev-trunk', + 'aliases' => + array ( + ), + 'reference' => '04b4d8d9fec5b03696f063d0d632d5fa5a6d1368', + ), + ), +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/LICENSE b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/LICENSE new file mode 100644 index 0000000..85f97fc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Kyle Robinson Young + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AglInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AglInstaller.php new file mode 100644 index 0000000..01b8a41 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AglInstaller.php @@ -0,0 +1,21 @@ + 'More/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) { + return strtoupper($matches[1]); + }, $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php new file mode 100644 index 0000000..79a0e95 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php @@ -0,0 +1,9 @@ + 'ext/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php new file mode 100644 index 0000000..89d7ad9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php @@ -0,0 +1,11 @@ + 'addons/modules/{$name}/', + 'component' => 'addons/components/{$name}/', + 'service' => 'addons/services/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php new file mode 100644 index 0000000..22dad1b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php @@ -0,0 +1,49 @@ + 'Modules/{$name}/', + 'theme' => 'Themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type asgard-module, cut off a trailing '-plugin' if present. + * + * For package type asgard-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'asgard-module') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'asgard-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php new file mode 100644 index 0000000..d62fd8f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php new file mode 100644 index 0000000..d9d6073 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php @@ -0,0 +1,137 @@ +composer = $composer; + $this->package = $package; + $this->io = $io; + } + + /** + * Return the install path based on package type. + * + * @param PackageInterface $package + * @param string $frameworkType + * @return string + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + $type = $this->package->getType(); + + $prettyName = $this->package->getPrettyName(); + if (strpos($prettyName, '/') !== false) { + list($vendor, $name) = explode('/', $prettyName); + } else { + $vendor = ''; + $name = $prettyName; + } + + $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type')); + + $extra = $package->getExtra(); + if (!empty($extra['installer-name'])) { + $availableVars['name'] = $extra['installer-name']; + } + + if ($this->composer->getPackage()) { + $extra = $this->composer->getPackage()->getExtra(); + if (!empty($extra['installer-paths'])) { + $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor); + if ($customPath !== false) { + return $this->templatePath($customPath, $availableVars); + } + } + } + + $packageType = substr($type, strlen($frameworkType) + 1); + $locations = $this->getLocations(); + if (!isset($locations[$packageType])) { + throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type)); + } + + return $this->templatePath($locations[$packageType], $availableVars); + } + + /** + * For an installer to override to modify the vars per installer. + * + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + return $vars; + } + + /** + * Gets the installer's locations + * + * @return array + */ + public function getLocations() + { + return $this->locations; + } + + /** + * Replace vars in a path + * + * @param string $path + * @param array $vars + * @return string + */ + protected function templatePath($path, array $vars = array()) + { + if (strpos($path, '{') !== false) { + extract($vars); + preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches); + if (!empty($matches[1])) { + foreach ($matches[1] as $var) { + $path = str_replace('{$' . $var . '}', $$var, $path); + } + } + } + + return $path; + } + + /** + * Search through a passed paths array for a custom install path. + * + * @param array $paths + * @param string $name + * @param string $type + * @param string $vendor = NULL + * @return string + */ + protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL) + { + foreach ($paths as $path => $names) { + $names = (array) $names; + if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) { + return $path; + } + } + + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php new file mode 100644 index 0000000..e80cd1e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php @@ -0,0 +1,126 @@ +.`. + * - `bitrix-d7-component` — copy the component to directory `bitrix/components//`. + * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/_`. + * + * You can set custom path to directory with Bitrix kernel in `composer.json`: + * + * ```json + * { + * "extra": { + * "bitrix-dir": "s1/bitrix" + * } + * } + * ``` + * + * @author Nik Samokhvalov + * @author Denis Kulichkin + */ +class BitrixInstaller extends BaseInstaller +{ + protected $locations = array( + 'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/', + 'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/', + 'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/', + ); + + /** + * @var array Storage for informations about duplicates at all the time of installation packages. + */ + private static $checkedDuplicates = array(); + + /** + * {@inheritdoc} + */ + public function inflectPackageVars($vars) + { + if ($this->composer->getPackage()) { + $extra = $this->composer->getPackage()->getExtra(); + + if (isset($extra['bitrix-dir'])) { + $vars['bitrix_dir'] = $extra['bitrix-dir']; + } + } + + if (!isset($vars['bitrix_dir'])) { + $vars['bitrix_dir'] = 'bitrix'; + } + + return parent::inflectPackageVars($vars); + } + + /** + * {@inheritdoc} + */ + protected function templatePath($path, array $vars = array()) + { + $templatePath = parent::templatePath($path, $vars); + $this->checkDuplicates($templatePath, $vars); + + return $templatePath; + } + + /** + * Duplicates search packages. + * + * @param string $path + * @param array $vars + */ + protected function checkDuplicates($path, array $vars = array()) + { + $packageType = substr($vars['type'], strlen('bitrix') + 1); + $localDir = explode('/', $vars['bitrix_dir']); + array_pop($localDir); + $localDir[] = 'local'; + $localDir = implode('/', $localDir); + + $oldPath = str_replace( + array('{$bitrix_dir}', '{$name}'), + array($localDir, $vars['name']), + $this->locations[$packageType] + ); + + if (in_array($oldPath, static::$checkedDuplicates)) { + return; + } + + if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) { + + $this->io->writeError(' Duplication of packages:'); + $this->io->writeError(' Package ' . $oldPath . ' will be called instead package ' . $path . ''); + + while (true) { + switch ($this->io->ask(' Delete ' . $oldPath . ' [y,n,?]? ', '?')) { + case 'y': + $fs = new Filesystem(); + $fs->removeDirectory($oldPath); + break 2; + + case 'n': + break 2; + + case '?': + default: + $this->io->writeError(array( + ' y - delete package ' . $oldPath . ' and to continue with the installation', + ' n - don\'t delete and to continue with the installation', + )); + $this->io->writeError(' ? - print help'); + break; + } + } + } + + static::$checkedDuplicates[] = $oldPath; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php new file mode 100644 index 0000000..da3aad2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php @@ -0,0 +1,9 @@ + 'Packages/{$vendor}/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php new file mode 100644 index 0000000..71ee2ef --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php @@ -0,0 +1,72 @@ + 'Plugin/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + if ($this->matchesCakeVersion('>=', '3.0.0')) { + return $vars; + } + + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + + return $vars; + } + + /** + * Change the default plugin location when cakephp >= 3.0 + */ + public function getLocations() + { + if ($this->matchesCakeVersion('>=', '3.0.0')) { + $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/'; + } + return $this->locations; + } + + /** + * Check if CakePHP version matches against a version + * + * @param string $matcher + * @param string $version + * @return bool + */ + protected function matchesCakeVersion($matcher, $version) + { + if (class_exists('Composer\Semver\Constraint\MultiConstraint')) { + $multiClass = 'Composer\Semver\Constraint\MultiConstraint'; + $constraintClass = 'Composer\Semver\Constraint\Constraint'; + } else { + $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint'; + $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint'; + } + + $repositoryManager = $this->composer->getRepositoryManager(); + if (! $repositoryManager) { + return false; + } + + $repos = $repositoryManager->getLocalRepository(); + if (!$repos) { + return false; + } + + return $repos->findPackage('cakephp/cakephp', new $constraintClass($matcher, $version)) !== null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php new file mode 100644 index 0000000..ab2f9aa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php @@ -0,0 +1,11 @@ + 'Chef/{$vendor}/{$name}/', + 'role' => 'Chef/roles/{$name}/', + ); +} + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php new file mode 100644 index 0000000..6673aea --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php @@ -0,0 +1,9 @@ + 'ext/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php new file mode 100644 index 0000000..c887815 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php @@ -0,0 +1,10 @@ + 'CCF/orbit/{$name}/', + 'theme' => 'CCF/app/themes/{$name}/', + ); +} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php new file mode 100644 index 0000000..c7816df --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php @@ -0,0 +1,34 @@ + 'cockpit/modules/addons/{$name}/', + ); + + /** + * Format module name. + * + * Strip `module-` prefix from package name. + * + * @param array @vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'cockpit-module') { + return $this->inflectModuleVars($vars); + } + + return $vars; + } + + public function inflectModuleVars($vars) + { + $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php new file mode 100644 index 0000000..3b4a4ec --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php @@ -0,0 +1,11 @@ + 'application/libraries/{$name}/', + 'third-party' => 'application/third_party/{$name}/', + 'module' => 'application/modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php new file mode 100644 index 0000000..5c01baf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php @@ -0,0 +1,13 @@ + 'concrete/', + 'block' => 'application/blocks/{$name}/', + 'package' => 'packages/{$name}/', + 'theme' => 'application/themes/{$name}/', + 'update' => 'updates/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php new file mode 100644 index 0000000..d37a77a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php @@ -0,0 +1,35 @@ + 'craft/plugins/{$name}/', + ); + + /** + * Strip `craft-` prefix and/or `-plugin` suffix from package names + * + * @param array $vars + * + * @return array + */ + final public function inflectPackageVars($vars) + { + return $this->inflectPluginVars($vars); + } + + private function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']); + $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php new file mode 100644 index 0000000..d94219d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php @@ -0,0 +1,21 @@ + 'Plugin/{$name}/', + 'theme' => 'View/Themed/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name'])); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php new file mode 100644 index 0000000..f4837a6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php @@ -0,0 +1,10 @@ + 'app/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php new file mode 100644 index 0000000..7078816 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php @@ -0,0 +1,10 @@ + 'modules/{$vendor}/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php new file mode 100644 index 0000000..cfd638d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php @@ -0,0 +1,50 @@ + 'lib/plugins/{$name}/', + 'template' => 'lib/tpl/{$name}/', + ); + + /** + * Format package name. + * + * For package type dokuwiki-plugin, cut off a trailing '-plugin', + * or leading dokuwiki_ if present. + * + * For package type dokuwiki-template, cut off a trailing '-template' if present. + * + */ + public function inflectPackageVars($vars) + { + + if ($vars['type'] === 'dokuwiki-plugin') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'dokuwiki-template') { + return $this->inflectTemplateVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']); + $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']); + + return $vars; + } + + protected function inflectTemplateVars($vars) + { + $vars['name'] = preg_replace('/-template$/', '', $vars['name']); + $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']); + + return $vars; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php new file mode 100644 index 0000000..21f7e8e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php @@ -0,0 +1,16 @@ + + */ +class DolibarrInstaller extends BaseInstaller +{ + //TODO: Add support for scripts and themes + protected $locations = array( + 'module' => 'htdocs/custom/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php new file mode 100644 index 0000000..7328239 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php @@ -0,0 +1,22 @@ + 'core/', + 'module' => 'modules/{$name}/', + 'theme' => 'themes/{$name}/', + 'library' => 'libraries/{$name}/', + 'profile' => 'profiles/{$name}/', + 'database-driver' => 'drivers/lib/Drupal/Driver/Database/{$name}/', + 'drush' => 'drush/{$name}/', + 'custom-theme' => 'themes/custom/{$name}/', + 'custom-module' => 'modules/custom/{$name}/', + 'custom-profile' => 'profiles/custom/{$name}/', + 'drupal-multisite' => 'sites/{$name}/', + 'console' => 'console/{$name}/', + 'console-language' => 'console/language/{$name}/', + 'config' => 'config/sync/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php new file mode 100644 index 0000000..c0bb609 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php @@ -0,0 +1,9 @@ + 'mod/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php new file mode 100644 index 0000000..6f3dc97 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php @@ -0,0 +1,12 @@ + 'components/{$name}/', + 'module' => 'modules/{$name}/', + 'plugin' => 'plugins/{$name}/', + 'template' => 'templates/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php new file mode 100644 index 0000000..d5321a8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php @@ -0,0 +1,29 @@ + 'system/expressionengine/third_party/{$name}/', + 'theme' => 'themes/third_party/{$name}/', + ); + + private $ee3Locations = array( + 'addon' => 'system/user/addons/{$name}/', + 'theme' => 'themes/user/{$name}/', + ); + + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + + $version = "{$frameworkType}Locations"; + $this->locations = $this->$version; + + return parent::getInstallPath($package, $frameworkType); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php new file mode 100644 index 0000000..f30ebcc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php @@ -0,0 +1,10 @@ + 'web/assets/ezplatform/', + 'assets' => 'web/assets/ezplatform/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php new file mode 100644 index 0000000..6eba2e3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php @@ -0,0 +1,11 @@ + 'fuel/app/modules/{$name}/', + 'package' => 'fuel/packages/{$name}/', + 'theme' => 'fuel/app/themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php new file mode 100644 index 0000000..29d980b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php @@ -0,0 +1,9 @@ + 'components/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/GravInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/GravInstaller.php new file mode 100644 index 0000000..dbe63e0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/GravInstaller.php @@ -0,0 +1,30 @@ + 'user/plugins/{$name}/', + 'theme' => 'user/themes/{$name}/', + ); + + /** + * Format package name + * + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $restrictedWords = implode('|', array_keys($this->locations)); + + $vars['name'] = strtolower($vars['name']); + $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui', + '$1', + $vars['name'] + ); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php new file mode 100644 index 0000000..8fe017f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php @@ -0,0 +1,25 @@ + 'plugins/{$name}/', + 'theme' => 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php new file mode 100644 index 0000000..5e2142e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php @@ -0,0 +1,11 @@ + 'templates/{$name}/', + 'module' => 'application/modules/{$name}/', + 'library' => 'application/libraries/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Installer.php new file mode 100644 index 0000000..d1d43b9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Installer.php @@ -0,0 +1,280 @@ + 'AimeosInstaller', + 'asgard' => 'AsgardInstaller', + 'attogram' => 'AttogramInstaller', + 'agl' => 'AglInstaller', + 'annotatecms' => 'AnnotateCmsInstaller', + 'bitrix' => 'BitrixInstaller', + 'bonefish' => 'BonefishInstaller', + 'cakephp' => 'CakePHPInstaller', + 'chef' => 'ChefInstaller', + 'civicrm' => 'CiviCrmInstaller', + 'ccframework' => 'ClanCatsFrameworkInstaller', + 'cockpit' => 'CockpitInstaller', + 'codeigniter' => 'CodeIgniterInstaller', + 'concrete5' => 'Concrete5Installer', + 'craft' => 'CraftInstaller', + 'croogo' => 'CroogoInstaller', + 'dframe' => 'DframeInstaller', + 'dokuwiki' => 'DokuWikiInstaller', + 'dolibarr' => 'DolibarrInstaller', + 'decibel' => 'DecibelInstaller', + 'drupal' => 'DrupalInstaller', + 'elgg' => 'ElggInstaller', + 'eliasis' => 'EliasisInstaller', + 'ee3' => 'ExpressionEngineInstaller', + 'ee2' => 'ExpressionEngineInstaller', + 'ezplatform' => 'EzPlatformInstaller', + 'fuel' => 'FuelInstaller', + 'fuelphp' => 'FuelphpInstaller', + 'grav' => 'GravInstaller', + 'hurad' => 'HuradInstaller', + 'imagecms' => 'ImageCMSInstaller', + 'itop' => 'ItopInstaller', + 'joomla' => 'JoomlaInstaller', + 'kanboard' => 'KanboardInstaller', + 'kirby' => 'KirbyInstaller', + 'known' => 'KnownInstaller', + 'kodicms' => 'KodiCMSInstaller', + 'kohana' => 'KohanaInstaller', + 'lms' => 'LanManagementSystemInstaller', + 'laravel' => 'LaravelInstaller', + 'lavalite' => 'LavaLiteInstaller', + 'lithium' => 'LithiumInstaller', + 'magento' => 'MagentoInstaller', + 'majima' => 'MajimaInstaller', + 'mantisbt' => 'MantisBTInstaller', + 'mako' => 'MakoInstaller', + 'maya' => 'MayaInstaller', + 'mautic' => 'MauticInstaller', + 'mediawiki' => 'MediaWikiInstaller', + 'microweber' => 'MicroweberInstaller', + 'modulework' => 'MODULEWorkInstaller', + 'modx' => 'ModxInstaller', + 'modxevo' => 'MODXEvoInstaller', + 'moodle' => 'MoodleInstaller', + 'october' => 'OctoberInstaller', + 'ontowiki' => 'OntoWikiInstaller', + 'oxid' => 'OxidInstaller', + 'osclass' => 'OsclassInstaller', + 'pxcms' => 'PxcmsInstaller', + 'phpbb' => 'PhpBBInstaller', + 'pimcore' => 'PimcoreInstaller', + 'piwik' => 'PiwikInstaller', + 'plentymarkets'=> 'PlentymarketsInstaller', + 'ppi' => 'PPIInstaller', + 'puppet' => 'PuppetInstaller', + 'radphp' => 'RadPHPInstaller', + 'phifty' => 'PhiftyInstaller', + 'porto' => 'PortoInstaller', + 'redaxo' => 'RedaxoInstaller', + 'redaxo5' => 'Redaxo5Installer', + 'reindex' => 'ReIndexInstaller', + 'roundcube' => 'RoundcubeInstaller', + 'shopware' => 'ShopwareInstaller', + 'sitedirect' => 'SiteDirectInstaller', + 'silverstripe' => 'SilverStripeInstaller', + 'smf' => 'SMFInstaller', + 'sydes' => 'SyDESInstaller', + 'sylius' => 'SyliusInstaller', + 'symfony1' => 'Symfony1Installer', + 'tao' => 'TaoInstaller', + 'thelia' => 'TheliaInstaller', + 'tusk' => 'TuskInstaller', + 'typo3-cms' => 'TYPO3CmsInstaller', + 'typo3-flow' => 'TYPO3FlowInstaller', + 'userfrosting' => 'UserFrostingInstaller', + 'vanilla' => 'VanillaInstaller', + 'whmcs' => 'WHMCSInstaller', + 'wolfcms' => 'WolfCMSInstaller', + 'wordpress' => 'WordPressInstaller', + 'yawik' => 'YawikInstaller', + 'zend' => 'ZendInstaller', + 'zikula' => 'ZikulaInstaller', + 'prestashop' => 'PrestashopInstaller' + ); + + /** + * Installer constructor. + * + * Disables installers specified in main composer extra installer-disable + * list + * + * @param IOInterface $io + * @param Composer $composer + * @param string $type + * @param Filesystem|null $filesystem + * @param BinaryInstaller|null $binaryInstaller + */ + public function __construct( + IOInterface $io, + Composer $composer, + $type = 'library', + Filesystem $filesystem = null, + BinaryInstaller $binaryInstaller = null + ) { + parent::__construct($io, $composer, $type, $filesystem, + $binaryInstaller); + $this->removeDisabledInstallers(); + } + + /** + * {@inheritDoc} + */ + public function getInstallPath(PackageInterface $package) + { + $type = $package->getType(); + $frameworkType = $this->findFrameworkType($type); + + if ($frameworkType === false) { + throw new \InvalidArgumentException( + 'Sorry the package type of this package is not yet supported.' + ); + } + + $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; + $installer = new $class($package, $this->composer, $this->getIO()); + + return $installer->getInstallPath($package, $frameworkType); + } + + public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package) + { + parent::uninstall($repo, $package); + $installPath = $this->getPackageBasePath($package); + $this->io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? 'deleted' : 'not deleted')); + } + + /** + * {@inheritDoc} + */ + public function supports($packageType) + { + $frameworkType = $this->findFrameworkType($packageType); + + if ($frameworkType === false) { + return false; + } + + $locationPattern = $this->getLocationPattern($frameworkType); + + return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1; + } + + /** + * Finds a supported framework type if it exists and returns it + * + * @param string $type + * @return string + */ + protected function findFrameworkType($type) + { + $frameworkType = false; + + krsort($this->supportedTypes); + + foreach ($this->supportedTypes as $key => $val) { + if ($key === substr($type, 0, strlen($key))) { + $frameworkType = substr($type, 0, strlen($key)); + break; + } + } + + return $frameworkType; + } + + /** + * Get the second part of the regular expression to check for support of a + * package type + * + * @param string $frameworkType + * @return string + */ + protected function getLocationPattern($frameworkType) + { + $pattern = false; + if (!empty($this->supportedTypes[$frameworkType])) { + $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; + /** @var BaseInstaller $framework */ + $framework = new $frameworkClass(null, $this->composer, $this->getIO()); + $locations = array_keys($framework->getLocations()); + $pattern = $locations ? '(' . implode('|', $locations) . ')' : false; + } + + return $pattern ? : '(\w+)'; + } + + /** + * Get I/O object + * + * @return IOInterface + */ + private function getIO() + { + return $this->io; + } + + /** + * Look for installers set to be disabled in composer's extra config and + * remove them from the list of supported installers. + * + * Globals: + * - true, "all", and "*" - disable all installers. + * - false - enable all installers (useful with + * wikimedia/composer-merge-plugin or similar) + * + * @return void + */ + protected function removeDisabledInstallers() + { + $extra = $this->composer->getPackage()->getExtra(); + + if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) { + // No installers are disabled + return; + } + + // Get installers to disable + $disable = $extra['installer-disable']; + + // Ensure $disabled is an array + if (!is_array($disable)) { + $disable = array($disable); + } + + // Check which installers should be disabled + $all = array(true, "all", "*"); + $intersect = array_intersect($all, $disable); + if (!empty($intersect)) { + // Disable all installers + $this->supportedTypes = array(); + } else { + // Disable specified installers + foreach ($disable as $key => $installer) { + if (is_string($installer) && key_exists($installer, $this->supportedTypes)) { + unset($this->supportedTypes[$installer]); + } + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php new file mode 100644 index 0000000..c6c1b33 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php @@ -0,0 +1,9 @@ + 'extensions/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php new file mode 100644 index 0000000..9ee7759 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php @@ -0,0 +1,15 @@ + 'components/{$name}/', + 'module' => 'modules/{$name}/', + 'template' => 'templates/{$name}/', + 'plugin' => 'plugins/{$name}/', + 'library' => 'libraries/{$name}/', + ); + + // TODO: Add inflector for mod_ and com_ names +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php new file mode 100644 index 0000000..9cb7b8c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php @@ -0,0 +1,18 @@ + 'plugins/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php new file mode 100644 index 0000000..36b2f84 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php @@ -0,0 +1,11 @@ + 'site/plugins/{$name}/', + 'field' => 'site/fields/{$name}/', + 'tag' => 'site/tags/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php new file mode 100644 index 0000000..c5d08c5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php @@ -0,0 +1,11 @@ + 'IdnoPlugins/{$name}/', + 'theme' => 'Themes/{$name}/', + 'console' => 'ConsolePlugins/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php new file mode 100644 index 0000000..7143e23 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php @@ -0,0 +1,10 @@ + 'cms/plugins/{$name}/', + 'media' => 'cms/media/vendor/{$name}/' + ); +} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php new file mode 100644 index 0000000..dcd6d26 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php new file mode 100644 index 0000000..903143a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php @@ -0,0 +1,27 @@ + 'plugins/{$name}/', + 'template' => 'templates/{$name}/', + 'document-template' => 'documents/templates/{$name}/', + 'userpanel-module' => 'userpanel/modules/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php new file mode 100644 index 0000000..be4d53a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php @@ -0,0 +1,9 @@ + 'libraries/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php new file mode 100644 index 0000000..412c0b5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php @@ -0,0 +1,10 @@ + 'packages/{$vendor}/{$name}/', + 'theme' => 'public/themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php new file mode 100644 index 0000000..47bbd4c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php @@ -0,0 +1,10 @@ + 'libraries/{$name}/', + 'source' => 'libraries/_source/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php new file mode 100644 index 0000000..9c2e9fb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php new file mode 100644 index 0000000..5a66460 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php @@ -0,0 +1,16 @@ + 'assets/snippets/{$name}/', + 'plugin' => 'assets/plugins/{$name}/', + 'module' => 'assets/modules/{$name}/', + 'template' => 'assets/templates/{$name}/', + 'lib' => 'assets/lib/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php new file mode 100644 index 0000000..cf18e94 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php @@ -0,0 +1,11 @@ + 'app/design/frontend/{$name}/', + 'skin' => 'skin/frontend/default/{$name}/', + 'library' => 'lib/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php new file mode 100644 index 0000000..e463756 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php @@ -0,0 +1,37 @@ + 'plugins/{$name}/', + ); + + /** + * Transforms the names + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + return $this->correctPluginName($vars); + } + + /** + * Change hyphenated names to camelcase + * @param array $vars + * @return array + */ + private function correctPluginName($vars) + { + $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, $vars['name']); + $vars['name'] = ucfirst($camelCasedName); + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php new file mode 100644 index 0000000..ca3cfac --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php @@ -0,0 +1,9 @@ + 'app/packages/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php new file mode 100644 index 0000000..dadb1db --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php @@ -0,0 +1,23 @@ + 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php new file mode 100644 index 0000000..3e1ce2b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php @@ -0,0 +1,25 @@ + 'plugins/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format package name of mautic-plugins to CamelCase + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'mautic-plugin') { + $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, ucfirst($vars['name'])); + } + + return $vars; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php new file mode 100644 index 0000000..30a9167 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php @@ -0,0 +1,33 @@ + 'modules/{$name}/', + ); + + /** + * Format package name. + * + * For package type maya-module, cut off a trailing '-module' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'maya-module') { + return $this->inflectModuleVars($vars); + } + + return $vars; + } + + protected function inflectModuleVars($vars) + { + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php new file mode 100644 index 0000000..f5a8957 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php @@ -0,0 +1,51 @@ + 'core/', + 'extension' => 'extensions/{$name}/', + 'skin' => 'skins/{$name}/', + ); + + /** + * Format package name. + * + * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform + * to CamelCase keeping existing uppercase chars. + * + * For package type mediawiki-skin, cut off a trailing '-skin' if present. + * + */ + public function inflectPackageVars($vars) + { + + if ($vars['type'] === 'mediawiki-extension') { + return $this->inflectExtensionVars($vars); + } + + if ($vars['type'] === 'mediawiki-skin') { + return $this->inflectSkinVars($vars); + } + + return $vars; + } + + protected function inflectExtensionVars($vars) + { + $vars['name'] = preg_replace('/-extension$/', '', $vars['name']); + $vars['name'] = str_replace('-', ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectSkinVars($vars) + { + $vars['name'] = preg_replace('/-skin$/', '', $vars['name']); + + return $vars; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php new file mode 100644 index 0000000..b7d9703 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php @@ -0,0 +1,119 @@ + 'userfiles/modules/{$install_item_dir}/', + 'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/', + 'template' => 'userfiles/templates/{$install_item_dir}/', + 'element' => 'userfiles/elements/{$install_item_dir}/', + 'vendor' => 'vendor/{$install_item_dir}/', + 'components' => 'components/{$install_item_dir}/' + ); + + /** + * Format package name. + * + * For package type microweber-module, cut off a trailing '-module' if present + * + * For package type microweber-template, cut off a trailing '-template' if present. + * + */ + public function inflectPackageVars($vars) + { + + + if ($this->package->getTargetDir()) { + $vars['install_item_dir'] = $this->package->getTargetDir(); + } else { + $vars['install_item_dir'] = $vars['name']; + if ($vars['type'] === 'microweber-template') { + return $this->inflectTemplateVars($vars); + } + if ($vars['type'] === 'microweber-templates') { + return $this->inflectTemplatesVars($vars); + } + if ($vars['type'] === 'microweber-core') { + return $this->inflectCoreVars($vars); + } + if ($vars['type'] === 'microweber-adapter') { + return $this->inflectCoreVars($vars); + } + if ($vars['type'] === 'microweber-module') { + return $this->inflectModuleVars($vars); + } + if ($vars['type'] === 'microweber-modules') { + return $this->inflectModulesVars($vars); + } + if ($vars['type'] === 'microweber-skin') { + return $this->inflectSkinVars($vars); + } + if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') { + return $this->inflectElementVars($vars); + } + } + + + return $vars; + } + + protected function inflectTemplateVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-template$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/template-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectTemplatesVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-templates$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/templates-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectCoreVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-providers$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/-provider$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/-adapter$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectModuleVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-module$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/module-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectModulesVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-modules$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/modules-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectSkinVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-skin$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/skin-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectElementVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-elements$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/elements-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/-element$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/element-$/', '', $vars['install_item_dir']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php new file mode 100644 index 0000000..0ee140a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php @@ -0,0 +1,12 @@ + 'core/packages/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php new file mode 100644 index 0000000..75dbe71 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php @@ -0,0 +1,58 @@ + 'mod/{$name}/', + 'admin_report' => 'admin/report/{$name}/', + 'atto' => 'lib/editor/atto/plugins/{$name}/', + 'tool' => 'admin/tool/{$name}/', + 'assignment' => 'mod/assignment/type/{$name}/', + 'assignsubmission' => 'mod/assign/submission/{$name}/', + 'assignfeedback' => 'mod/assign/feedback/{$name}/', + 'auth' => 'auth/{$name}/', + 'availability' => 'availability/condition/{$name}/', + 'block' => 'blocks/{$name}/', + 'booktool' => 'mod/book/tool/{$name}/', + 'cachestore' => 'cache/stores/{$name}/', + 'cachelock' => 'cache/locks/{$name}/', + 'calendartype' => 'calendar/type/{$name}/', + 'format' => 'course/format/{$name}/', + 'coursereport' => 'course/report/{$name}/', + 'customcertelement' => 'mod/customcert/element/{$name}/', + 'datafield' => 'mod/data/field/{$name}/', + 'datapreset' => 'mod/data/preset/{$name}/', + 'editor' => 'lib/editor/{$name}/', + 'enrol' => 'enrol/{$name}/', + 'filter' => 'filter/{$name}/', + 'gradeexport' => 'grade/export/{$name}/', + 'gradeimport' => 'grade/import/{$name}/', + 'gradereport' => 'grade/report/{$name}/', + 'gradingform' => 'grade/grading/form/{$name}/', + 'local' => 'local/{$name}/', + 'logstore' => 'admin/tool/log/store/{$name}/', + 'ltisource' => 'mod/lti/source/{$name}/', + 'ltiservice' => 'mod/lti/service/{$name}/', + 'message' => 'message/output/{$name}/', + 'mnetservice' => 'mnet/service/{$name}/', + 'plagiarism' => 'plagiarism/{$name}/', + 'portfolio' => 'portfolio/{$name}/', + 'qbehaviour' => 'question/behaviour/{$name}/', + 'qformat' => 'question/format/{$name}/', + 'qtype' => 'question/type/{$name}/', + 'quizaccess' => 'mod/quiz/accessrule/{$name}/', + 'quiz' => 'mod/quiz/report/{$name}/', + 'report' => 'report/{$name}/', + 'repository' => 'repository/{$name}/', + 'scormreport' => 'mod/scorm/report/{$name}/', + 'search' => 'search/engine/{$name}/', + 'theme' => 'theme/{$name}/', + 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/', + 'profilefield' => 'user/profile/field/{$name}/', + 'webservice' => 'webservice/{$name}/', + 'workshopallocation' => 'mod/workshop/allocation/{$name}/', + 'workshopeval' => 'mod/workshop/eval/{$name}/', + 'workshopform' => 'mod/workshop/form/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php new file mode 100644 index 0000000..08d5dc4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php @@ -0,0 +1,47 @@ + 'modules/{$name}/', + 'plugin' => 'plugins/{$vendor}/{$name}/', + 'theme' => 'themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type october-plugin, cut off a trailing '-plugin' if present. + * + * For package type october-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'october-plugin') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'october-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']); + $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php new file mode 100644 index 0000000..5dd3438 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php @@ -0,0 +1,24 @@ + 'extensions/{$name}/', + 'theme' => 'extensions/themes/{$name}/', + 'translation' => 'extensions/translations/{$name}/', + ); + + /** + * Format package name to lower case and remove ".ontowiki" suffix + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower($vars['name']); + $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']); + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = preg_replace('/-translation$/', '', $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php new file mode 100644 index 0000000..3ca7954 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php @@ -0,0 +1,14 @@ + 'oc-content/plugins/{$name}/', + 'theme' => 'oc-content/themes/{$name}/', + 'language' => 'oc-content/languages/{$name}/', + ); + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php new file mode 100644 index 0000000..49940ff --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php @@ -0,0 +1,59 @@ +.+)\/.+/'; + + protected $locations = array( + 'module' => 'modules/{$name}/', + 'theme' => 'application/views/{$name}/', + 'out' => 'out/{$name}/', + ); + + /** + * getInstallPath + * + * @param PackageInterface $package + * @param string $frameworkType + * @return void + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + $installPath = parent::getInstallPath($package, $frameworkType); + $type = $this->package->getType(); + if ($type === 'oxid-module') { + $this->prepareVendorDirectory($installPath); + } + return $installPath; + } + + /** + * prepareVendorDirectory + * + * Makes sure there is a vendormetadata.php file inside + * the vendor folder if there is a vendor folder. + * + * @param string $installPath + * @return void + */ + protected function prepareVendorDirectory($installPath) + { + $matches = ''; + $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches); + if (!$hasVendorDirectory) { + return; + } + + $vendorDirectory = $matches['vendor']; + $vendorPath = getcwd() . '/modules/' . $vendorDirectory; + if (!file_exists($vendorPath)) { + mkdir($vendorPath, 0755, true); + } + + $vendorMetaDataPath = $vendorPath . '/vendormetadata.php'; + touch($vendorMetaDataPath); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php new file mode 100644 index 0000000..170136f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php new file mode 100644 index 0000000..4e59a8a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php @@ -0,0 +1,11 @@ + 'bundles/{$name}/', + 'library' => 'libraries/{$name}/', + 'framework' => 'frameworks/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php new file mode 100644 index 0000000..deb2b77 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php @@ -0,0 +1,11 @@ + 'ext/{$vendor}/{$name}/', + 'language' => 'language/{$name}/', + 'style' => 'styles/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php new file mode 100644 index 0000000..4781fa6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php @@ -0,0 +1,21 @@ + 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php new file mode 100644 index 0000000..c17f457 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php @@ -0,0 +1,32 @@ + 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php new file mode 100644 index 0000000..903e55f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php @@ -0,0 +1,29 @@ + '{$name}/' + ); + + /** + * Remove hyphen, "plugin" and format to camelcase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = explode("-", $vars['name']); + foreach ($vars['name'] as $key => $name) { + $vars['name'][$key] = ucfirst($vars['name'][$key]); + if (strcasecmp($name, "Plugin") == 0) { + unset($vars['name'][$key]); + } + } + $vars['name'] = implode("",$vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Plugin.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Plugin.php new file mode 100644 index 0000000..e60da0e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Plugin.php @@ -0,0 +1,27 @@ +installer = new Installer($io, $composer); + $composer->getInstallationManager()->addInstaller($this->installer); + } + + public function deactivate(Composer $composer, IOInterface $io) + { + $composer->getInstallationManager()->removeInstaller($this->installer); + } + + public function uninstall(Composer $composer, IOInterface $io) + { + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php new file mode 100644 index 0000000..dbf85e6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php @@ -0,0 +1,9 @@ + 'app/Containers/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php new file mode 100644 index 0000000..4c8421e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php @@ -0,0 +1,10 @@ + 'modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php new file mode 100644 index 0000000..77cc3dd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php @@ -0,0 +1,11 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php new file mode 100644 index 0000000..6551058 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php @@ -0,0 +1,63 @@ + 'app/Modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format package name. + * + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'pxcms-module') { + return $this->inflectModuleVars($vars); + } + + if ($vars['type'] === 'pxcms-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + /** + * For package type pxcms-module, cut off a trailing '-plugin' if present. + * + * return string + */ + protected function inflectModuleVars($vars) + { + $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) + $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module- + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module + $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s + $vars['name'] = ucwords($vars['name']); // make module name camelcased + + return $vars; + } + + + /** + * For package type pxcms-module, cut off a trailing '-plugin' if present. + * + * return string + */ + protected function inflectThemeVars($vars) + { + $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) + $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme- + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme + $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s + $vars['name'] = ucwords($vars['name']); // make module name camelcased + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php new file mode 100644 index 0000000..0f78b5c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php @@ -0,0 +1,24 @@ + 'src/{$name}/' + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php new file mode 100644 index 0000000..252c733 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php @@ -0,0 +1,10 @@ + 'themes/{$name}/', + 'plugin' => 'plugins/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php new file mode 100644 index 0000000..23a2034 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php @@ -0,0 +1,10 @@ + 'redaxo/src/addons/{$name}/', + 'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php new file mode 100644 index 0000000..0954457 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php @@ -0,0 +1,10 @@ + 'redaxo/include/addons/{$name}/', + 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php new file mode 100644 index 0000000..d8d795b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php @@ -0,0 +1,22 @@ + 'plugins/{$name}/', + ); + + /** + * Lowercase name and changes the name to a underscores + * + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(str_replace('-', '_', $vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php new file mode 100644 index 0000000..1acd3b1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php @@ -0,0 +1,10 @@ + 'Sources/{$name}/', + 'theme' => 'Themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php new file mode 100644 index 0000000..7d20d27 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php @@ -0,0 +1,60 @@ + 'engine/Shopware/Plugins/Local/Backend/{$name}/', + 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/', + 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/', + 'theme' => 'templates/{$name}/', + 'plugin' => 'custom/plugins/{$name}/', + 'frontend-theme' => 'themes/Frontend/{$name}/', + ); + + /** + * Transforms the names + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'shopware-theme') { + return $this->correctThemeName($vars); + } + + return $this->correctPluginName($vars); + } + + /** + * Changes the name to a camelcased combination of vendor and name + * @param array $vars + * @return array + */ + private function correctPluginName($vars) + { + $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, $vars['name']); + + $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName); + + return $vars; + } + + /** + * Changes the name to a underscore separated name + * @param array $vars + * @return array + */ + private function correctThemeName($vars) + { + $vars['name'] = str_replace('-', '_', $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php new file mode 100644 index 0000000..81910e9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php @@ -0,0 +1,35 @@ + '{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Return the install path based on package type. + * + * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework + * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0 + * + * @param PackageInterface $package + * @param string $frameworkType + * @return string + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + if ( + $package->getName() == 'silverstripe/framework' + && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion()) + && version_compare($package->getVersion(), '2.999.999') < 0 + ) { + return $this->templatePath($this->locations['module'], array('name' => 'sapphire')); + } + + return parent::getInstallPath($package, $frameworkType); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php new file mode 100644 index 0000000..762d94c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php @@ -0,0 +1,25 @@ + 'modules/{$vendor}/{$name}/', + 'plugin' => 'plugins/{$vendor}/{$name}/' + ); + + public function inflectPackageVars($vars) + { + return $this->parseVars($vars); + } + + protected function parseVars($vars) + { + $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor']; + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php new file mode 100644 index 0000000..83ef9d0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php @@ -0,0 +1,49 @@ + 'app/modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format module name. + * + * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present. + * + * @param array @vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'sydes-module') { + return $this->inflectModuleVars($vars); + } + + if ($vars['type'] === 'sydes-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + public function inflectModuleVars($vars) + { + $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']); + $vars['name'] = strtolower($vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php new file mode 100644 index 0000000..4357a35 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php @@ -0,0 +1,9 @@ + 'themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php new file mode 100644 index 0000000..1675c4f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php @@ -0,0 +1,26 @@ + + */ +class Symfony1Installer extends BaseInstaller +{ + protected $locations = array( + 'plugin' => 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php new file mode 100644 index 0000000..b1663e8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php @@ -0,0 +1,16 @@ + + */ +class TYPO3CmsInstaller extends BaseInstaller +{ + protected $locations = array( + 'extension' => 'typo3conf/ext/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php new file mode 100644 index 0000000..42572f4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php @@ -0,0 +1,38 @@ + 'Packages/Application/{$name}/', + 'framework' => 'Packages/Framework/{$name}/', + 'plugin' => 'Packages/Plugins/{$name}/', + 'site' => 'Packages/Sites/{$name}/', + 'boilerplate' => 'Packages/Boilerplates/{$name}/', + 'build' => 'Build/{$name}/', + ); + + /** + * Modify the package name to be a TYPO3 Flow style key. + * + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + $autoload = $this->package->getAutoload(); + if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) { + $namespace = key($autoload['psr-0']); + $vars['name'] = str_replace('\\', '.', $namespace); + } + if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) { + $namespace = key($autoload['psr-4']); + $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.'); + } + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php new file mode 100644 index 0000000..108def1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php @@ -0,0 +1,12 @@ + '{$name}' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php new file mode 100644 index 0000000..158af52 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php @@ -0,0 +1,12 @@ + 'local/modules/{$name}/', + 'frontoffice-template' => 'templates/frontOffice/{$name}/', + 'backoffice-template' => 'templates/backOffice/{$name}/', + 'email-template' => 'templates/email/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php new file mode 100644 index 0000000..7c0113b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php @@ -0,0 +1,14 @@ + + */ + class TuskInstaller extends BaseInstaller + { + protected $locations = array( + 'task' => '.tusk/tasks/{$name}/', + 'command' => '.tusk/commands/{$name}/', + 'asset' => 'assets/tusk/{$name}/', + ); + } diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php new file mode 100644 index 0000000..fcb414a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php @@ -0,0 +1,9 @@ + 'app/sprinkles/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php new file mode 100644 index 0000000..24ca645 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php @@ -0,0 +1,10 @@ + 'plugins/{$name}/', + 'theme' => 'themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php new file mode 100644 index 0000000..7d90c5e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php @@ -0,0 +1,49 @@ + 'src/{$vendor}/{$name}/', + 'theme' => 'themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type vgmcp-bundle, cut off a trailing '-bundle' if present. + * + * For package type vgmcp-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'vgmcp-bundle') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'vgmcp-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php new file mode 100644 index 0000000..b65dbba --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php @@ -0,0 +1,21 @@ + 'modules/addons/{$vendor}_{$name}/', + 'fraud' => 'modules/fraud/{$vendor}_{$name}/', + 'gateways' => 'modules/gateways/{$vendor}_{$name}/', + 'notifications' => 'modules/notifications/{$vendor}_{$name}/', + 'registrars' => 'modules/registrars/{$vendor}_{$name}/', + 'reports' => 'modules/reports/{$vendor}_{$name}/', + 'security' => 'modules/security/{$vendor}_{$name}/', + 'servers' => 'modules/servers/{$vendor}_{$name}/', + 'social' => 'modules/social/{$vendor}_{$name}/', + 'support' => 'modules/support/{$vendor}_{$name}/', + 'templates' => 'templates/{$vendor}_{$name}/', + 'includes' => 'includes/{$vendor}_{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php new file mode 100644 index 0000000..cb38788 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php @@ -0,0 +1,9 @@ + 'wolf/plugins/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php new file mode 100644 index 0000000..91c46ad --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php @@ -0,0 +1,12 @@ + 'wp-content/plugins/{$name}/', + 'theme' => 'wp-content/themes/{$name}/', + 'muplugin' => 'wp-content/mu-plugins/{$name}/', + 'dropin' => 'wp-content/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php new file mode 100644 index 0000000..27f429f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php @@ -0,0 +1,32 @@ + 'module/{$name}/', + ); + + /** + * Format package name to CamelCase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php new file mode 100644 index 0000000..bde9bc8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php @@ -0,0 +1,11 @@ + 'library/{$name}/', + 'extra' => 'extras/library/{$name}/', + 'module' => 'module/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php new file mode 100644 index 0000000..56cdf5d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php @@ -0,0 +1,10 @@ + 'modules/{$vendor}-{$name}/', + 'theme' => 'themes/{$vendor}-{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/bootstrap.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/bootstrap.php new file mode 100644 index 0000000..0de276e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/installers/src/bootstrap.php @@ -0,0 +1,13 @@ + array( + 'version' => '2.5.0.0', + 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadGenerator.php' + ), +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/jetpack_autoload_psr4.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/jetpack_autoload_psr4.php new file mode 100644 index 0000000..d9f9f64 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/composer/jetpack_autoload_psr4.php @@ -0,0 +1,21 @@ + array( + 'version' => '1.9.0.0', + 'path' => array( $vendorDir . '/composer/installers/src/Composer/Installers' ) + ), + 'Automattic\\WooCommerce\\Blocks\\' => array( + 'version' => '3.8.1.0', + 'path' => array( $baseDir . '/src' ) + ), + 'Automattic\\Jetpack\\Autoloader\\' => array( + 'version' => '2.5.0.0', + 'path' => array( $vendorDir . '/automattic/jetpack-autoloader/src' ) + ), +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/autoload_functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/autoload_functions.php new file mode 100644 index 0000000..c7d9e2b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/autoload_functions.php @@ -0,0 +1,74 @@ +find_class_file( $class_name ); + if ( ! isset( $file ) ) { + return false; + } + + require_once $file; + return true; +} + +/** + * Finds the latest installed autoloader. If this is the latest autoloader, sets + * up the classmap and filemap. + */ +function set_up_autoloader() { + global $jetpack_autoloader_latest_version; + global $jetpack_autoloader_loader; + + require_once __DIR__ . '/class-plugins-handler.php'; + require_once __DIR__ . '/class-version-selector.php'; + require_once __DIR__ . '/class-autoloader-locator.php'; + require_once __DIR__ . '/class-autoloader-handler.php'; + + $plugins_handler = new Plugins_Handler(); + $version_selector = new Version_Selector(); + $autoloader_handler = new Autoloader_Handler( + $plugins_handler->get_current_plugin_path(), + $plugins_handler->get_all_active_plugins_paths(), + new Autoloader_Locator( $version_selector ), + $version_selector + ); + + // The autoloader must be reset when a plugin that was previously unknown is detected. + if ( $autoloader_handler->should_autoloader_reset() ) { + $jetpack_autoloader_latest_version = null; + $jetpack_autoloader_loader = null; + } + + if ( ! $autoloader_handler->is_latest_autoloader() || isset( $jetpack_autoloader_loader ) ) { + return; + } + + require_once __DIR__ . '/class-manifest-handler.php'; + require_once __DIR__ . '/class-version-loader.php'; + + $jetpack_autoloader_loader = $autoloader_handler->build_autoloader(); + $autoloader_handler->update_autoloader_chain(); + + // Now that the autoloader is ready we can load the files in the filemap safely. + $jetpack_autoloader_loader->load_filemap(); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-autoloader-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-autoloader-handler.php new file mode 100644 index 0000000..cf7200b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-autoloader-handler.php @@ -0,0 +1,198 @@ +current_plugin_path = $current_plugin_path; + $this->active_plugin_paths = $active_plugin_paths; + $this->autoloader_locator = $autoloader_locator; + $this->version_selector = $version_selector; + } + + /** + * Finds the latest installed autoloader. + * + * @return bool True if this autoloader is the latest, false otherwise. + */ + public function is_latest_autoloader() { + global $jetpack_autoloader_latest_version; + + if ( isset( $jetpack_autoloader_latest_version ) ) { + return $jetpack_autoloader_latest_version === $this->autoloader_locator->get_autoloader_version( $this->current_plugin_path ); + } + + $latest_plugin = $this->autoloader_locator->find_latest_autoloader( $this->active_plugin_paths, $jetpack_autoloader_latest_version ); + if ( ! isset( $latest_plugin ) ) { + return true; + } + + if ( $latest_plugin !== $this->current_plugin_path ) { + require $this->autoloader_locator->get_autoloader_path( $latest_plugin ); + return false; + } + + return true; + } + + /** + * Checks whether the autoloader should be reset. The autoloader should be reset: + * + * - When a plugin is activated via a method other than a request, for example using WP-CLI. + * - When the active plugins list changes between autoloader checks, for example when filtered by a plugin. + * + * We perform this reset because the manifest files for the plugin will have been initially unknown when + * selecting versions for classes and files. + * + * If the current plugin is not already known, this method will add it to the + * $jetpack_autoloader_activating_plugins_paths global. + * The $jetpack_autoloader_cached_plugin_paths global will store a cache of the + * active plugin paths when last changed. + * + * @return boolean True if the autoloader must be reset, else false. + */ + public function should_autoloader_reset() { + global $jetpack_autoloader_activating_plugins_paths; + global $jetpack_autoloader_cached_plugin_paths; + + $plugin_unknown = ! in_array( $this->current_plugin_path, $this->active_plugin_paths, true ); + if ( $plugin_unknown ) { + if ( ! isset( $jetpack_autoloader_activating_plugins_paths ) ) { + $jetpack_autoloader_activating_plugins_paths = array(); + } + + // If the current plugin isn't known, add it to the activating plugins list. + $jetpack_autoloader_activating_plugins_paths[] = $this->current_plugin_path; + $this->active_plugin_paths[] = $this->current_plugin_path; + } + + $cache_invalidated = $jetpack_autoloader_cached_plugin_paths !== $this->active_plugin_paths; + if ( $cache_invalidated ) { + $jetpack_autoloader_cached_plugin_paths = $this->active_plugin_paths; + } + + return $plugin_unknown || $cache_invalidated; + } + + /** + * Builds the Version_Autoloader class that is used for autoloading. + * + * @return Version_Loader + */ + public function build_autoloader() { + $manifest_handler = new Manifest_Handler( $this->active_plugin_paths, $this->version_selector ); + + global $jetpack_packages_psr4; + $jetpack_packages_psr4 = array(); + $manifest_handler->register_plugin_manifests( 'vendor/composer/jetpack_autoload_psr4.php', $jetpack_packages_psr4 ); + + global $jetpack_packages_classmap; + $jetpack_packages_classmap = array(); + $manifest_handler->register_plugin_manifests( 'vendor/composer/jetpack_autoload_classmap.php', $jetpack_packages_classmap ); + + global $jetpack_packages_filemap; + $jetpack_packages_filemap = array(); + $manifest_handler->register_plugin_manifests( 'vendor/composer/jetpack_autoload_filemap.php', $jetpack_packages_filemap ); + + // Store the generated autoloader data in the loader so we can use it. + return new Version_Loader( + $this->version_selector, + $jetpack_packages_classmap, + $jetpack_packages_psr4, + $jetpack_packages_filemap + ); + } + + /** + * Updates the spl autoloader chain: + * - Registers this namespace's autoloader function. + * - If a v1 autoloader function is registered, moves it to the end of the chain. + * - Removes any other v2 autoloader functions that have already been registered. This + * can occur when the autoloader is being reset by an activating plugin. + */ + public function update_autoloader_chain() { + spl_autoload_register( __NAMESPACE__ . '\autoloader' ); + + $autoload_chain = spl_autoload_functions(); + + foreach ( $autoload_chain as $autoloader ) { + if ( ! is_string( $autoloader ) ) { + /* + * The Jetpack Autoloader functions are registered as strings, so + * just continue if $autoloader isn't a string. + */ + continue; + } + + if ( self::V1_AUTOLOADER_NAME === $autoloader ) { + // Move the v1.* autoloader function to the end of the spl autoloader chain. + spl_autoload_unregister( $autoloader ); + spl_autoload_register( $autoloader ); + + } elseif ( + self::V2_AUTOLOADER_BASE === substr( $autoloader, 0, strlen( self::V2_AUTOLOADER_BASE ) ) + && __NAMESPACE__ !== substr( $autoloader, 0, strlen( __NAMESPACE__ ) ) + ) { + // Unregister any other v2.* autoloader functions if they're in the chain. + spl_autoload_unregister( $autoloader ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-autoloader-locator.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-autoloader-locator.php new file mode 100644 index 0000000..2aaa93d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-autoloader-locator.php @@ -0,0 +1,90 @@ +version_selector = $version_selector; + } + + /** + * Finds the path to the plugin with the latest autoloader. + * + * @param array $plugin_paths An array of plugin paths. + * @param string $latest_version The latest version reference. + * + * @return string|null + */ + public function find_latest_autoloader( $plugin_paths, &$latest_version ) { + $latest_plugin = null; + + foreach ( $plugin_paths as $plugin_path ) { + $version = $this->get_autoloader_version( $plugin_path ); + if ( ! $this->version_selector->is_version_update_required( $latest_version, $version ) ) { + continue; + } + + $latest_version = $version; + $latest_plugin = $plugin_path; + } + + return $latest_plugin; + } + + /** + * Gets the path to the autoloader. + * + * @param string $plugin_path The path to the plugin. + * + * @return string + */ + public function get_autoloader_path( $plugin_path ) { + return trailingslashit( $plugin_path ) . 'vendor/autoload_packages.php'; + } + + /** + * Gets the version for the autoloader. + * + * @param string $plugin_path The path to the plugin. + * + * @return string|null + */ + public function get_autoloader_version( $plugin_path ) { + $classmap = trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; + if ( ! file_exists( $classmap ) ) { + return null; + } + + $classmap = require $classmap; + if ( isset( $classmap[ AutoloadGenerator::class ] ) ) { + return $classmap[ AutoloadGenerator::class ]['version']; + } + + return null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-manifest-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-manifest-handler.php new file mode 100644 index 0000000..5d30237 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-manifest-handler.php @@ -0,0 +1,107 @@ +active_plugin_paths = $active_plugin_paths; + $this->version_selector = $version_selector; + } + + /** + * Registers all of the paths in a given manifest. + * + * @param string $manifest_path The path that we're loading the manifest from in each plugin. + * @param array $path_map The path map to add the contents of the manifests to. + * + * @return array $path_map The path map we've built using the manifests in each plugin. + */ + public function register_plugin_manifests( $manifest_path, &$path_map ) { + $file_paths = array_map( + function ( $path ) use ( $manifest_path ) { + return trailingslashit( $path ) . $manifest_path; + }, + $this->active_plugin_paths + ); + + foreach ( $file_paths as $path ) { + $this->register_manifest( $path, $path_map ); + } + + return $path_map; + } + + /** + * Registers a plugin's manifest file with the path map. + * + * @param string $manifest_path The absolute path to the manifest that we're loading. + * @param array $path_map The path map to add the contents of the manifest to. + */ + protected function register_manifest( $manifest_path, &$path_map ) { + if ( ! is_readable( $manifest_path ) ) { + return; + } + + $manifest = require $manifest_path; + if ( ! is_array( $manifest ) ) { + return; + } + + foreach ( $manifest as $key => $data ) { + $this->register_record( $key, $data, $path_map ); + } + } + + /** + * Registers an entry from the manifest in the path map. + * + * @param string $key The identifier for the entry we're registering. + * @param array $data The data for the entry we're registering. + * @param array $path_map The path map to add the contents of the manifest to. + */ + protected function register_record( $key, $data, &$path_map ) { + if ( isset( $path_map[ $key ]['version'] ) ) { + $selected_version = $path_map[ $key ]['version']; + } else { + $selected_version = null; + } + + if ( $this->version_selector->is_version_update_required( $selected_version, $data['version'] ) ) { + $path_map[ $key ] = array( + 'version' => $data['version'], + 'path' => $data['path'], + ); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-plugins-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-plugins-handler.php new file mode 100644 index 0000000..41e03cf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-plugins-handler.php @@ -0,0 +1,137 @@ +get_active_plugins_paths(); + $multisite_plugins_paths = $this->get_multisite_plugins_paths(); + $activating_plugins_paths = $this->get_plugins_activating_via_request(); + + return array_unique( + array_merge( + $active_plugins_paths, + $activating_plugins_paths, + $multisite_plugins_paths, + (array) $jetpack_autoloader_activating_plugins_paths + ) + ); + } + + /** + * Returns an array containing the paths of the active sitewide plugins in a multisite environment. + * + * @return array The paths of the active sitewide plugins or an empty array. + */ + protected function get_multisite_plugins_paths() { + $plugin_slugs = is_multisite() + ? array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) + : array(); + + $plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + /** + * Returns an array containing the paths of the currently active plugins. + * + * @return array The active plugins' paths or an empty array. + */ + protected function get_active_plugins_paths() { + $plugin_slugs = (array) get_option( 'active_plugins', array() ); + $plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + /** + * Adds the plugin directory from the WP_PLUGIN_DIR constant to the plugin slug. + * + * @param string $plugin_slug The plugin slug. + */ + private function create_plugin_path( $plugin_slug ) { + $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR ); + return trailingslashit( $plugin_dir ) . substr( $plugin_slug, 0, strrpos( $plugin_slug, '/' ) ); + } + + /** + * Ensure the plugin has its own directory and not a single-file plugin. + * + * @param string $plugin Plugin name, may be prefixed with "/". + * + * @return bool + */ + public function is_directory_plugin( $plugin ) { + return strlen( $plugin ) > 1 && false !== strpos( $plugin, '/', 1 ); + } + + /** + * Returns an array containing the names of plugins that are activating via a request. + * + * @return array An array of names of the activating plugins or an empty array. + */ + private function get_plugins_activating_via_request() { + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + // phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash + // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + + $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : false; + $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : false; + $nonce = isset( $_REQUEST['_wpnonce'] ) ? $_REQUEST['_wpnonce'] : false; + + /** + * Note: we're not actually checking the nonce here becase it's too early + * in the execution. The pluggable functions are not yet loaded to give + * plugins a chance to plug their versions. Therefore we're doing the bare + * minimum: checking whether the nonce exists and it's in the right place. + * The request will fail later if the nonce doesn't pass the check. + */ + + // In case of a single plugin activation there will be a plugin slug. + if ( 'activate' === $action && ! empty( $nonce ) ) { + return array( $this->create_plugin_path( wp_unslash( $plugin ) ) ); + } + + $plugins = isset( $_REQUEST['checked'] ) ? $_REQUEST['checked'] : array(); + + // In case of bulk activation there will be an array of plugins. + if ( 'activate-selected' === $action && ! empty( $nonce ) ) { + $plugin_slugs = array_map( 'wp_unslash', $plugins ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + // phpcs:enable WordPress.Security.NonceVerification.Recommended + // phpcs:enable WordPress.Security.ValidatedSanitizedInput.MissingUnslash + // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + return array(); + } + + /** + * Returns the path of the current plugin. + * + * @return string The path of the current plugin. + */ + public function get_current_plugin_path() { + $vendor_path = str_replace( '\\', '/', dirname( dirname( __FILE__ ) ) ); + // Path to the plugin's folder (the parent of the vendor/jetpack-autoloader folder). + return substr( $vendor_path, 0, strrpos( $vendor_path, '/' ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-version-loader.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-version-loader.php new file mode 100644 index 0000000..3e71b9c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-version-loader.php @@ -0,0 +1,164 @@ +version_selector = $version_selector; + $this->classmap = $classmap; + $this->psr4_map = $psr4_map; + $this->filemap = $filemap; + } + + /** + * Finds the file path for the given class. + * + * @param string $class_name The class to find. + * + * @return string|null $file_path The path to the file if found, null if no class was found. + */ + public function find_class_file( $class_name ) { + $data = $this->select_newest_file( + isset( $this->classmap[ $class_name ] ) ? $this->classmap[ $class_name ] : null, + $this->find_psr4_file( $class_name ) + ); + if ( ! isset( $data ) ) { + return null; + } + + return $data['path']; + } + + /** + * Load all of the files in the filemap. + */ + public function load_filemap() { + if ( empty( $this->filemap ) ) { + return; + } + + foreach ( $this->filemap as $file_identifier => $file_data ) { + if ( empty( $GLOBALS['__composer_autoload_files'][ $file_identifier ] ) ) { + require_once $file_data['path']; + + $GLOBALS['__composer_autoload_files'][ $file_identifier ] = true; + } + } + } + + /** + * Compares different class sources and returns the newest. + * + * @param array|null $classmap_data The classmap class data. + * @param array|null $psr4_data The PSR-4 class data. + * + * @return array|null $data + */ + private function select_newest_file( $classmap_data, $psr4_data ) { + if ( ! isset( $classmap_data ) ) { + return $psr4_data; + } elseif ( ! isset( $psr4_data ) ) { + return $classmap_data; + } + + if ( $this->version_selector->is_version_update_required( $classmap_data['version'], $psr4_data['version'] ) ) { + return $psr4_data; + } + + return $classmap_data; + } + + /** + * Finds the file for a given class in a PSR-4 namespace. + * + * @param string $class_name The class to find. + * + * @return array|null $data The version and path path to the file if found, null otherwise. + */ + private function find_psr4_file( $class_name ) { + if ( ! isset( $this->psr4_map ) ) { + return null; + } + + // Don't bother with classes that have no namespace. + $class_index = strrpos( $class_name, '\\' ); + if ( ! $class_index ) { + return null; + } + $class_for_path = str_replace( '\\', '/', $class_name ); + + // Search for the namespace by iteratively cutting off the last segment until + // we find a match. This allows us to check the most-specific namespaces + // first as well as minimize the amount of time spent looking. + for ( + $class_namespace = substr( $class_name, 0, $class_index ); + ! empty( $class_namespace ); + $class_namespace = substr( $class_namespace, 0, strrpos( $class_namespace, '\\' ) ) + ) { + $namespace = $class_namespace . '\\'; + if ( ! isset( $this->psr4_map[ $namespace ] ) ) { + continue; + } + $data = $this->psr4_map[ $namespace ]; + + foreach ( $data['path'] as $path ) { + $path .= '/' . substr( $class_for_path, strlen( $namespace ) ) . '.php'; + if ( file_exists( $path ) ) { + return array( + 'version' => $data['version'], + 'path' => $path, + ); + } + } + } + + return null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-version-selector.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-version-selector.php new file mode 100644 index 0000000..55c64c7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/vendor/jetpack-autoloader/class-version-selector.php @@ -0,0 +1,69 @@ +is_package_version_dev( $selected_version ) ) { + return false; + } + + if ( $this->is_package_version_dev( $compare_version ) ) { + if ( $use_dev_versions ) { + return true; + } else { + return false; + } + } + + if ( version_compare( $selected_version, $compare_version, '<' ) ) { + return true; + } + + return false; + } + + /** + * Checks whether the given package version is a development version. + * + * @param String $version The package version. + * + * @return Boolean True if the version is a dev version, else false. + */ + private function is_package_version_dev( $version ) { + if ( 'dev-' === substr( $version, 0, 4 ) || '9999999-dev' === $version ) { + return true; + } + + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/woocommerce-gutenberg-products-block.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/woocommerce-gutenberg-products-block.php new file mode 100644 index 0000000..2a6e582 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/packages/woocommerce-blocks/woocommerce-gutenberg-products-block.php @@ -0,0 +1,247 @@ +id; + $is_woocommerce_page = + property_exists( $current_screen, 'parent_base' ) && + 'woocommerce' === $current_screen->parent_base; + + return $is_plugins_page || $is_woocommerce_page; +} + +if ( version_compare( $GLOBALS['wp_version'], $minimum_wp_version, '<' ) ) { + /** + * Outputs for an admin notice about running WooCommerce Blocks on outdated WordPress. + * + * @since 2.5.0 + */ + function woocommerce_blocks_admin_unsupported_wp_notice() { + if ( should_display_compatibility_notices() ) { + ?> +
    +

    +
    +

    '; + printf( + /* Translators: %1$s is referring to a php constant name, %2$s is referring to the wp-config.php file. */ + esc_html__( 'WooCommerce Blocks development mode requires the %1$s constant to be defined and true in your %2$s file. Otherwise you are loading the blocks package from WooCommerce core.', 'woocommerce' ), + 'JETPACK_AUTOLOAD_DEV', + 'wp-config.php' + ); + echo '

    '; + } + ); +} + + +/** + * Autoload packages. + * + * The package autoloader includes version information which prevents classes in this feature plugin + * conflicting with WooCommerce core. + * + * We want to fail gracefully if `composer install` has not been executed yet, so we are checking for the autoloader. + * If the autoloader is not present, let's log the failure and display a nice admin notice. + */ +$autoloader = __DIR__ . '/vendor/autoload_packages.php'; +if ( is_readable( $autoloader ) ) { + require $autoloader; +} else { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + error_log( // phpcs:ignore + sprintf( + /* translators: 1: composer command. 2: plugin directory */ + esc_html__( 'Your installation of the WooCommerce Blocks feature plugin is incomplete. Please run %1$s within the %2$s directory.', 'woocommerce' ), + '`composer install`', + '`' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '`' + ) + ); + } + /** + * Outputs an admin notice if composer install has not been ran. + */ + add_action( + 'admin_notices', + function() { + ?> +
    +

    + composer install', + '' . esc_html( str_replace( ABSPATH, '', __DIR__ ) ) . '' + ); + ?> +

    +
    + registered[ $handle ], $wp_scripts->registered[ $handle ]->src ) ) { + return $translations; + } + + $handle_filename = basename( $wp_scripts->registered[ $handle ]->src ); + $locale = determine_locale(); + $lang_dir = WP_LANG_DIR . '/plugins'; + + // Translations are always based on the unminified filename. + if ( substr( $handle_filename, -7 ) === '.min.js' ) { + $handle_filename = substr( $handle_filename, 0, -7 ) . '.js'; + } + + // WordPress 5.0 uses md5 hashes of file paths to associate translation + // JSON files with the file they should be included for. This is an md5 + // of 'packages/woocommerce-blocks/build/FILENAME.js'. + $core_path_md5 = md5( 'packages/woocommerce-blocks/build/' . $handle_filename ); + $core_json_file = $lang_dir . '/woocommerce-' . $locale . '-' . $core_path_md5 . '.json'; + $json_translations = is_file( $core_json_file ) && is_readable( $core_json_file ) ? file_get_contents( $core_json_file ) : false; // phpcs:ignore + + if ( ! $json_translations ) { + return $translations; + } + + // Rather than short circuit pre_load_script_translations, we will output + // core translations using an inline script. This will allow us to continue + // to load feature-plugin translations which may exist as well. + $output = <<\n%s\n\n", $output ); // phpcs:ignore + + // Finally, short circuit the pre_load_script_translations hook by returning + // the translation JSON from the feature plugin, if it exists so this hook + // does not run again for the current handle. + $path_md5 = md5( 'build/' . $handle_filename ); + $json_file = $lang_dir . '/' . $domain . '-' . $locale . '-' . $path_md5 . '.json'; + $translations = is_file( $json_file ) && is_readable( $json_file ) ? file_get_contents( $json_file ) : false; // phpcs:ignore + + if ( $translations ) { + return $translations; + } + + // Return valid empty Jed locale. + return '{ "locale_data": { "messages": { "": {} } } }'; +} + +add_filter( 'pre_load_script_translations', 'woocommerce_blocks_get_i18n_data_json', 10, 4 ); + +/** + * Filter translations so we can retrieve translations from Core when the original and the translated + * texts are the same (which happens when translations are missing). + * + * @param string $translation Translated text based on WC Blocks translations. + * @param string $text Text to translate. + * @param string $domain The text domain. + * @return string WC Blocks translation. In case it's the same as $text, Core translation. + */ +function woocommerce_blocks_get_php_translation_from_core( $translation, $text, $domain ) { + if ( 'woo-gutenberg-products-block' !== $domain ) { + return $translation; + } + + // When translation is the same, that could mean the string is not translated. + // In that case, load it from core. + if ( $translation === $text ) { + return translate( $text, 'woocommerce' ); // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction, WordPress.WP.I18n.NonSingularStringLiteralText, WordPress.WP.I18n.TextDomainMismatch + } + return $translation; +} + +add_filter( 'gettext', 'woocommerce_blocks_get_php_translation_from_core', 10, 3 ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/readme.txt b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/readme.txt new file mode 100644 index 0000000..a47c1a4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/readme.txt @@ -0,0 +1,281 @@ +=== WooCommerce === +Contributors: automattic, mikejolley, jameskoster, claudiosanches, rodrigosprimo, peterfabian1000, vedjain, jamosova, obliviousharmony, konamiman, sadowski, wpmuguru, royho +Tags: e-commerce, store, sales, sell, woo, shop, cart, checkout, downloadable, downloads, payments, paypal, storefront, stripe, woo commerce +Requires at least: 5.3 +Tested up to: 5.6 +Requires PHP: 7.0 +Stable tag: 4.8.0 +License: GPLv3 +License URI: https://www.gnu.org/licenses/gpl-3.0.html + +WooCommerce is the world’s most popular open-source eCommerce solution. + +== Description == + +WooCommerce is [the world’s most popular](https://trends.builtwith.com/shop) open-source eCommerce solution. + +Our core platform is free, flexible, and amplified by a global community. The freedom of open-source means you retain full ownership of your store’s content and data forever. + +Whether you’re launching a business, taking brick-and-mortar retail online, or developing sites for clients, use WooCommerce for a store that powerfully blends content and commerce. + +- **Create beautiful, enticing storefronts** with [themes](https://woocommerce.com/product-category/themes/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) suited to your brand and industry. +- **Customize pages in minutes** using modular [product blocks](https://docs.woocommerce.com/document/woocommerce-blocks/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). +- Showcase physical and digital goods, product variations, custom configurations, instant downloads, and affiliate items. [Bookings](https://woocommerce.com/products/woocommerce-bookings/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), [memberships](https://woocommerce.com/products/woocommerce-memberships/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), [subscriptions](https://woocommerce.com/products/woocommerce-subscriptions/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), and [dynamic pricing](https://woocommerce.com/products/dynamic-pricing/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) rules are only an extension away. +- **Rise to the top of search results** by leveraging [WordPress’ SEO advantage](https://www.searchenginejournal.com/wordpress-best-cms-seo/). + +Built-in tools and popular integrations help you efficiently manage your business operations. Many services are free to add with a single click via the optional [Setup Wizard](https://docs.woocommerce.com/document/woocommerce-setup-wizard/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + +- **Choose how you want to get paid**. Conveniently manage payments from the comfort of your store with [WooCommerce Payments](https://woocommerce.com/payments/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) (U.S.-only). Securely accept cards, mobile wallets, bank transfers, and cash thanks to [100+ payment gateways](https://woocommerce.com/product-category/woocommerce-extensions/payment-gateways/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) – including [Stripe](https://woocommerce.com/products/stripe/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), [PayPal](https://woocommerce.com/products/woocommerce-gateway-paypal-checkout/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), and [Square](https://woocommerce.com/products/square/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). +- **Configure your shipping options**. Print USPS labels right from your dashboard and even schedule a pickup with [WooCommerce Shipping](https://woocommerce.com/products/shipping/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) (U.S.-only). Connect with [well-known carriers](https://woocommerce.com/product-category/woocommerce-extensions/shipping-methods/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) such as UPS, FedEx, and ShipStation – plus a wide variety of delivery, inventory, and fulfillment solutions for your locale. +- **Simplify sales tax**. Add [WooCommerce Tax](https://woocommerce.com/products/tax/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) or [similar integrated services](https://woocommerce.com/product-category/woocommerce-extensions/tax?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) to make automated calculations a reality. + += Grow your business, add features, and monitor your store on the go = + +WooCommerce means business. Keep tabs on the performance metrics most important to you with [WooCommerce Admin](https://wordpress.org/plugins/woocommerce-admin/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) – a powerful, customizable central dashboard for your store. + +Expand your audience across marketing and social channels with [Google Ads](https://woocommerce.com/products/google-ads/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), [HubSpot](https://woocommerce.com/products/hubspot-for-woocommerce/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), [Mailchimp](https://woocommerce.com/products/mailchimp-for-woocommerce/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), and [Facebook](https://woocommerce.com/products/facebook/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) integrations. You can always check out the in-dashboard [Marketing Hub](https://docs.woocommerce.com/document/marketing-hub/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) for fresh ideas and tips to help you succeed. + +Enhance store functionality with hundreds of free and paid extensions from the [official WooCommerce Marketplace](https://woocommerce.com/products/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). Our developers [vet each new extension](https://docs.woocommerce.com/document/marketplace-overview/#section-6?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) and regularly review existing inventory to maintain Marketplace quality standards. We are actively [looking for products that help store builders create successful stores](https://docs.woocommerce.com/document/marketplace-overview/#section-2?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + +Manage your store from anywhere with the free WooCommerce [mobile app](https://woocommerce.com/mobile/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) (Android and iOS). Spoiler alert: Keep an ear out for the slightly addictive "cha-ching" notification sound each time you make a new sale! + += Own and control your store data – forever = + +With WooCommerce, your data belongs to you. Always. + +If you opt to share [usage data](https://woocommerce.com/usage-tracking/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) with us, you can feel confident knowing that it’s anonymized and kept secure. Choose to opt-out at any time without impacting your store. + +Unlike hosted eCommerce solutions, WooCommerce store data is future-proof; should you wish to migrate to a different platform, you’re free to export all your content and take your site wherever you choose. No restrictions. + += Why developers choose (and love) WooCommerce = + +Developers can use WooCommerce to create, customize, and scale a store to meet a client’s exact specifications, making enhancements through extensions or custom solutions. + +- Leverage [hooks and filters](https://docs.woocommerce.com/document/introduction-to-hooks-actions-and-filters/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) to modify or create functionality. +- Integrate virtually any service using a robust [REST API](https://docs.woocommerce.com/document/woocommerce-rest-api/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) and webhooks. +- Design and build custom content blocks with React. +- [Inspect and modify](https://docs.woocommerce.com/documentation/plugins/woocommerce/woocommerce-codex/extending/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) any aspect of the core plugin code. +- Speed up development with a lightning-fast [CLI](https://woocommerce.github.io/code-reference/classes/wc-cli-rest-command.html?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + +The core platform is tested rigorously and often, supported by a dedicated development team working across time zones. Comprehensive documentation is updated with each release, empowering you to build exactly the store required. + += Be part of our growing international community = + +WooCommerce has a large, passionate community dedicated to helping merchants succeed, and it’s growing fast. + +There are [WooCommerce Meetups](https://woocommerce.com/meetups/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) in locations around the world that you can attend for free and even get involved in running. These events are a great way to learn from others, share your expertise, and connect with like-minded folks. + +WooCommerce also has a regular presence at WordCamps across the globe – we’d love to meet you. + += Contribute and translate = + +WooCommerce is developed and supported by Automattic, the creators of WordPress.com and Jetpack. We also have hundreds of independent contributors, and there’s always room for more. Head to the [WooCommerce GitHub Repository](https://github.com/woocommerce/woocommerce?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) to find out how you can pitch in. + +WooCommerce is translated into multiple languages, including Danish, Ukrainian, and Persian. Help localize WooCommerce even further by adding your locale – visit [translate.wordpress.org](https://translate.wordpress.org/projects/wp-plugins/woocommerce/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + +== Frequently Asked Questions == + += Where can I find WooCommerce documentation and user guides? = + +For help setting up and configuring WooCommerce, please refer to [Getting Started](https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) and the [New WooCommerce Store Owner Guide](https://woocommerce.com/guides/new-store/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + +For extending or theming WooCommerce, see our [codex](https://docs.woocommerce.com/documentation/plugins/woocommerce/woocommerce-codex/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), as well as the [Plugin Developer Handbook](https://docs.woocommerce.com/document/create-a-plugin/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + += Where can I get help or talk to other users about WooCommerce Core? = + +If you get stuck, you can ask for help in the [WooCommerce Support Forum](https://wordpress.org/support/plugin/woocommerce/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) by following [these guidelines](https://wordpress.org/support/topic/guide-to-the-woocommerce-forum/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), reach out via the [WooCommerce Community Slack](https://woocommerce.com/community-slack/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing), or post in the [WooCommerce Community group](https://www.facebook.com/groups/advanced.woocommerce?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) on Facebook. + += Where can I get help for extensions I have purchased on WooCommerce.com? = + +For assistance with paid extensions from the WooCommerce.com Marketplace: first, review our [self-service troubleshooting guide](https://docs.woocommerce.com/document/woocommerce-self-service-guide/). If the problem persists, kindly log a support ticket via [our helpdesk](https://woocommerce.com/my-account/create-a-ticket/). Our dedicated Happiness Engineers aim to respond within 24 hours. + += I’m having trouble logging in to WooCommerce.com – what now? = + +First, troubleshoot common login issues using this helpful [step-by-step guide](https://docs.woocommerce.com/document/log-into-woocommerce-com-with-wordpress-com/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). Still not working? [Get in touch with us](https://woocommerce.com/contact-us/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + += Will WooCommerce work with my theme? = + +Yes! WooCommerce will work with any theme but may require some additional styling. If you’re looking for a theme featuring deep WooCommerce integration, we recommend [Storefront](https://woocommerce.com/storefront/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + += How do I update WooCommerce? = + +We have a detailed guide on [How To Update WooCommerce](https://docs.woocommerce.com/document/how-to-update-woocommerce/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + += My site broke – what do I do? = + +Start by diagnosing the issue using our helpful [troubleshooting guide](https://docs.woocommerce.com/documentation/get-help/troubleshooting-get-help/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + +If you noticed the error after updating a theme or plugin, there might be compatibility issues between it and WooCommerce. If the issue appeared after updating WooCommerce, there could be a conflict between WooCommerce and an outdated theme or plugin. + +In both instances, we recommend running a conflict test using [Health Check](https://docs.woocommerce.com/document/troubleshooting-using-health-check/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) (which allows you to disable themes and plugins without affecting your visitors) or troubleshooting the issue using a [staging site](https://docs.woocommerce.com/document/how-to-test-for-conflicts/#section-3?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). + += Where can I report bugs? = + +Report bugs on the [WooCommerce GitHub repository](https://github.com/woocommerce/woocommerce/issues?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). You can also notify us via our support forum – be sure to search the forums to confirm that the error has not already been reported. + += Where can I request new features, themes, and extensions? = + +Request new features and extensions and vote on existing suggestions on our official [ideas board](https://ideas.woocommerce.com/forums/133476-woocommerce?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing). Our Product teams regularly review requests and consider them valuable for product planning. + += WooCommerce is awesome! Can I contribute? = + +Yes, you can! Join in on our [GitHub repository](https://github.com/woocommerce/woocommerce/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) and follow the [development blog](https://woocommerce.wordpress.com/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) to stay up-to-date with everything happening in the project. + += Where can I find REST API documentation? = + +Extensive [WooCommerce REST API Documentation](https://woocommerce.github.io/woocommerce-rest-api-docs/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) is available on GitHub. + += My question is not listed here. Where can I find more answers? = + +Check out [Frequently Asked Questions](https://docs.woocommerce.com/document/frequently-asked-questions/?utm_medium=referral&utm_source=wordpress.org&utm_campaign=wp_org_repo_listing) for more. + +== Installation == + += Minimum Requirements = + +* PHP 7.2 or greater is recommended +* MySQL 5.6 or greater is recommended + +Visit the [WooCommerce server requirements documentation](https://docs.woocommerce.com/document/server-requirements/?utm_source=wp%20org%20repo%20listing&utm_content=3.6) for a detailed list of server requirements. + += Automatic installation = + +Automatic installation is the easiest option -- WordPress will handles the file transfer, and you won’t need to leave your web browser. To do an automatic install of WooCommerce, log in to your WordPress dashboard, navigate to the Plugins menu, and click “Add New.” + +In the search field type “WooCommerce,” then click “Search Plugins.” Once you’ve found us, you can view details about it such as the point release, rating, and description. Most importantly of course, you can install it by! Click “Install Now,” and WordPress will take it from there. + += Manual installation = + +Manual installation method requires downloading the WooCommerce plugin and uploading it to your web server via your favorite FTP application. The WordPress codex contains [instructions on how to do this here](https://wordpress.org/support/article/managing-plugins/#manual-plugin-installation). + += Updating = + +Automatic updates should work smoothly, but we still recommend you back up your site. + +If you encounter issues with the shop/category pages after an update, flush the permalinks by going to WordPress > Settings > Permalinks and hitting “Save.” That should return things to normal. + += Sample data = + +WooCommerce comes with some sample data you can use to see how products look; import sample_products.xml via the [WordPress importer](https://wordpress.org/plugins/wordpress-importer/). You can also use the core [CSV importer](https://docs.woocommerce.com/document/product-csv-importer-exporter/?utm_source=wp%20org%20repo%20listing&utm_content=3.6) or our [CSV Import Suite extension](https://woocommerce.com/products/product-csv-import-suite/?utm_source=wp%20org%20repo%20listing&utm_content=3.6) to import sample_products.csv + +== Changelog == + += 4.8.0 - 2020-12-08 = + +**WooCommerce** + +* Enhancement - Limited the system status report's "not tested with version" warning to major versions. #28114 +* Enhancement - Add shipping, tax, and fee lines to refund REST API response. #28241 +* Enhancement - Added support for Twenty Twenty-One theme. #28134 +* Tweak - Reduced the memory usage of AJAX product searches. #28177 +* Tweak - Replaced deprecated jQuery functionality. #28005, #28058 +* Tweak - Hid "Add to cart" button for out of stock grouped products. #28169 +* Tweak - Made product date deserialization more explicit. #28052 +* Fix - Stock adjustment when deleting a refunded order item. #28069 +* Fix - Avatar display for recent reviews widget in admin area. #28067 +* Fix - Incorrect product sorting user capability. #28062 +* Fix - PayPal response emptying uninitialized cart. #28027 +* Fix - Display of visual feedback after pressing "Place Order" in `Twenty Twenty` and `Twenty Nineteen` themes #27997 +* Fix - Category and tag bulk deletion message. #27856 +* Fix - Corrected Puerto Rico address validation. #28465 +* Dev - Filter: `woocommerce_product_has_options` to products. #27514 +* Dev - Added error message to `checkout_error` JS event. #28101 +* Dev - Replaced usage of deprecated `woocommerce_reset_loop()` in product category shortcodes. #28242 +* Dev - Set "Tested up to" header to WordPress 5.6. #28388 +* Localization - Jamaican currency, states, and address structure. #27723 +* Localization - Better display of inclusive taxes during checkout. #28064 +* Localization - Validation for Belgium postcodes. #28145 + +**WooCommerce Admin - 1.7.0 & 1.7.1 & 1.7.2 & 1.7.3** + +* Enhancement - Variations report. #5167 +* Enhancement - Add ability to toggle homescreen layouts. #5429 +* Enhancement - Accordion component #5474 +* Enhancement - Badge component #5520 +* Tweak - Remove customer analytics data upon order deletion #5171 +* Tweak - Updating Stripe key field validation to support test keys #5201 +* Tweak - Wrap search control selected items in list #5231 +* Tweak - Update store setup link to redirect to setup wizard #5200 +* Tweak - Removing breadcrumbs from wc-admin header #5232 +* Tweak - Use consistent markdown headers in navigation readme #5417 +* Tweak - Remove Store Setup Alert #5499 +* Tweak - Customers: Update column heading for date registered #5542 +* Tweak - alter homescreen layout. #5465 +* Fix - Added support for custom actionable statuses. #5550 +* Fix - wrong casing used on the PayPal brand name #5514 🎉 @rtpHarry +* Fix - Import @wordpress/base-styles/default-custom-properties #5491 +* Fix - downloads report #5441 +* Fix - missing custom autocompleter attribute in Search component of Advanced Filter #5448 +* Fix - empty no posts state on Marketing page. #5411 +* Fix - visual issues in the Search component. #5199 +* Fix - Inconsistent line endings in readme.txt. #5281 +* Fix - popover menu to expand menu item width to 100% #5519 +* Fix - Wrong class name for querying Categories Report #5522 🎉 @zzap +* Fix - Remove label printing mention for non us countries #5527 +* Fix - First product script navigation dependency #5584 +* Fix - Added support for custom actionable statuses #5550 +* Fix - Display the store management links last on the homescreen #5579 +* Fix - Ensure the "Set up additional payment providers" inbox notification is shown when relevant after completing the OBW. #5547 +* Fix - Load wc-tracks in the homepage notice admin script. #5638 +* Fix - Link component prop caused a React warning. #5653 +* Fix - Flickering of order panel while loading. #5655 +* Fix - Tax code duplicated when clicking the button to remove. #5638 +* Fix - Restore Autoloading of WooCommerce Classes in PHP Tests. #5650 +* Fix - Skip WC Payment plugin note if plugin not added through the onboarding process. #5619 +* Fix - Use error_log() to log the deprecated class calls instead of `_deprecated_function()`. #5802 +* Fix - Don't show the Orders panel on the homescreen with the Task List. #5552 +* Fix - Home Screen: Do not show store setup activity panel. #5801 +* Dev - Home Screen - migrate orders panel. #5455 +* Dev - Store Profiler - include Creative Mail as a free extension #5543 +* Dev - Add undefined check in intervals data util #5546 +* Dev - Fix wakeup visibility for PHP 8 compatibility #5211 +* Dev - Fix header height and positioning for wc nav #5173 +* Dev - Add remote inbox notification rule processors for country and state #5203 +* Dev - Rename admin notes classes and file names to fit conventions #514 +* Dev - remove checks of store registration that are no longer needed. #5170 +* Dev - Fix version update script for composer.json #5165 +* Dev - Remove getAdminLink from data package #5158 +* Dev - Bump @woocommerce/components dependencies. #5153 +* Dev - Add note status remote inbox notifications rule processor #5207 +* Dev - Make code chunk filenames more stable. #5229 +* Dev - Inbox Panel component moved #5252 +* Dev - Added animation to Inbox note deletion #5263 +* Dev - Update starter pack dependencies #5254 +* Dev - Ensure test zips have latest packages from npm and composer. #5313 +* Dev - Add remote inbox notifications rule allowing access to any option #5206 +* Dev - Add manage orders on the go admin note #5159 +* Dev - Add WooCommerceDependencyExtractionWebpackPlugin package #5198 +* Dev - Migrate devdocs examples to Storybook stories #5271 +* Dev - Remove Enzyme in favor of React Testing Library #5299 +* Dev - Add exclusion rule to PHPCS config for TODO comments #5388 +* Dev - Remove no longer used isPanelEmpty logic. #5423 +* Dev - Use new @wordpress/components Card on Marketing page. #5428 +* Dev - Add PSR-4 naming checks to PHP linting. #5512 +* Dev - Rearrange the store management links under categories add filter woocommerce_admin_homescreen_quicklinks. #5476 +* Dev - Restyle the setup task list header to display incomplete tasks #5520 + +**WooCommerce Blocks - 3.7.0 & 3.7.1 & 3.8.0 & 3.8.1** + +* Enhancement - Allow shoppers to sign-up for an account from the Checkout block. #3331 +* Enhancement - Standardise & refactor colors scss to align with Gutenberg colors and WooCommerce brand. #3300 +* Tweak - Show the phone number field in the billing section when shipping is disabled in settings. #3376 +* Tweak - Add new doc referencing feature flags and experimental interfaces. #3348 +* Tweak - Add __experimental_woocommerce_blocks_checkout_order_processed action. #3238 +* Fix - Fix PHP 8 error when argument is not invocable in AssetsDataRegistry::Add_data. #3315 +* Fix - Improve layout of Cart block line item quantity selector & price on smaller screens. #3299 +* Fix - Correctly process orders with $0 total (e.g. via coupon) in Checkout block. #3298 +* Fix - Respect Enable Taxes setting for checkout block taxes display. #3291 +* Fix - Fix 3D secure payment errors. #3272 +* Fix - Show current selected attributes when re-edit Products by Attribute block. #3185 +* Fix - Ensure that accounts are not created via checkout block request if account registration is disabled for WooCommerce. #3371 +* Fix - radio controls and checkboxes in Twenty Twenty One dark theme. #3446 +* Fix - Twenty Twenty One Price filter, Active filters and radio control styling. #3444 +* Fix - Twenty Twenty One Button and Placeholder Styling. #3443 +* Fix - checkbox and textarea styles in Twenty Twenty One when it has dark controls active. #3450 + +[See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce/master/changelog.txt). + +== Upgrade Notice == + += 4.0 = +4.0 is a major update. Make a full site backup, update your theme and extensions, and [review update best practices](https://docs.woocommerce.com/document/how-to-update-your-site) before upgrading. diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/sample-data/sample_products.csv b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/sample-data/sample_products.csv new file mode 100644 index 0000000..dfb25e8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/sample-data/sample_products.csv @@ -0,0 +1,26 @@ +ID,Type,SKU,Name,Published,"Is featured?","Visibility in catalog","Short description",Description,"Date sale price starts","Date sale price ends","Tax status","Tax class","In stock?",Stock,"Backorders allowed?","Sold individually?","Weight (lbs)","Length (in)","Width (in)","Height (in)","Allow customer reviews?","Purchase note","Sale price","Regular price",Categories,Tags,"Shipping class",Images,"Download limit","Download expiry days",Parent,"Grouped products",Upsells,Cross-sells,"External URL","Button text",Position,"Attribute 1 name","Attribute 1 value(s)","Attribute 1 visible","Attribute 1 global","Attribute 2 name","Attribute 2 value(s)","Attribute 2 visible","Attribute 2 global","Meta: _wpcom_is_markdown","Download 1 name","Download 1 URL","Download 2 name","Download 2 URL" +44,variable,woo-vneck-tee,"V-Neck T-Shirt",1,1,visible,"This is a variable product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,.5,24,1,2,1,,,,"Clothing > Tshirts",,,"https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vneck-tee-2.jpg, https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-green-1.jpg, https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-blue-1.jpg",,,,,,,,,0,Color,"Blue, Green, Red",1,1,Size,"Large, Medium, Small",1,1,1,,,, +45,variable,woo-hoodie,Hoodie,1,0,visible,"This is a variable product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,1.5,10,8,3,1,,,,"Clothing > Hoodies",,,"https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-2.jpg, https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-blue-1.jpg, https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-green-1.jpg, https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-logo-2.jpg",,,,,,,,,0,Color,"Blue, Green, Red",1,1,Logo,"Yes, No",1,0,1,,,, +46,simple,woo-hoodie-with-logo,"Hoodie with Logo",1,0,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,2,10,6,3,1,,,45,"Clothing > Hoodies",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-logo-2.jpg,,,,,,,,,0,Color,Blue,1,1,,,,,1,,,, +47,simple,woo-tshirt,T-Shirt,1,0,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,.8,8,6,1,1,,,18,"Clothing > Tshirts",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/tshirt-2.jpg,,,,,,,,,0,Color,Gray,1,1,,,,,1,,,, +48,simple,woo-beanie,Beanie,1,0,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,.2,4,5,.5,1,,18,20,"Clothing > Accessories",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-2.jpg,,,,,,,,,0,Color,Red,1,1,,,,,1,,,, +58,simple,woo-belt,Belt,1,0,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,1.2,12,2,1.5,1,,55,65,"Clothing > Accessories",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/belt-2.jpg,,,,,,,,,0,,,,,,,,,1,,,, +60,simple,woo-cap,Cap,1,1,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,0.6,8,6.5,4,1,,16,18,"Clothing > Accessories",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/cap-2.jpg,,,,,,,,,0,Color,Yellow,1,1,,,,,1,,,, +62,simple,woo-sunglasses,Sunglasses,1,1,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,.2,4,1.4,1,1,,,90,"Clothing > Accessories",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/sunglasses-2.jpg,,,,,,,,,0,,,,,,,,,1,,,, +64,simple,woo-hoodie-with-pocket,"Hoodie with Pocket",1,1,hidden,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,3,10,8,2,1,,35,45,"Clothing > Hoodies",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-pocket-2.jpg,,,,,,,,,0,Color,Gray,1,1,,,,,1,,,, +66,simple,woo-hoodie-with-zipper,"Hoodie with Zipper",1,1,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,2,8,6,2,1,,,45,"Clothing > Hoodies",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-zipper-2.jpg,,,,,,,,,0,,,,,,,,,1,,,, +68,simple,woo-long-sleeve-tee,"Long Sleeve Tee",1,0,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,1,7,5,1,1,,,25,"Clothing > Tshirts",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/long-sleeve-tee-2.jpg,,,,,,,,,0,Color,Green,1,1,,,,,1,,,, +70,simple,woo-polo,Polo,1,0,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,.8,6,5,1,1,,,20,"Clothing > Tshirts",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/polo-2.jpg,,,,,,,,,0,Color,Blue,1,1,,,,,1,,,, +73,"simple, downloadable, virtual",woo-album,Album,1,0,visible,"This is a simple, virtual product.","Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,1,,,15,Music,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/album-1.jpg,1,1,,,,,,,0,,,,,,,,,1,"Single 1",https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg,"Single 2",https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg +75,"simple, downloadable, virtual",woo-single,Single,1,0,visible,"This is a simple, virtual product.","Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,1,,2,3,Music,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/single-1.jpg,1,1,,,,,,,0,,,,,,,,,1,Single,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg,, +76,variation,woo-vneck-tee-red,"V-Neck T-Shirt - Red",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,20,,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vneck-tee-2.jpg,,,woo-vneck-tee,,,,,,0,Color,Red,,1,Size,,,1,,,,, +77,variation,woo-vneck-tee-green,"V-Neck T-Shirt - Green",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,20,,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-green-1.jpg,,,woo-vneck-tee,,,,,,0,Color,Green,,1,Size,,,1,,,,, +78,variation,woo-vneck-tee-blue,"V-Neck T-Shirt - Blue",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,15,,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-blue-1.jpg,,,woo-vneck-tee,,,,,,0,Color,Blue,,1,Size,,,1,,,,, +79,variation,woo-hoodie-red,"Hoodie - Red, No",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,42,45,,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-2.jpg,,,woo-hoodie,,,,,,1,Color,Red,,1,Logo,No,,0,,,,, +80,variation,woo-hoodie-green,"Hoodie - Green, No",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,45,,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-green-1.jpg,,,woo-hoodie,,,,,,2,Color,Green,,1,Logo,No,,0,,,,, +81,variation,woo-hoodie-blue,"Hoodie - Blue, No",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,45,,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-blue-1.jpg,,,woo-hoodie,,,,,,3,Color,Blue,,1,Logo,No,,0,,,,, +83,simple,Woo-tshirt-logo,"T-Shirt with Logo",1,0,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,.5,10,12,.5,1,,,18,"Clothing > Tshirts",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/t-shirt-with-logo-1.jpg,,,,,,,,,0,Color,Gray,1,1,,,,,1,,,, +85,simple,Woo-beanie-logo,"Beanie with Logo",1,0,visible,"This is a simple product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,.2,6,4,1,1,,18,20,"Clothing > Accessories",,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-with-logo-1.jpg,,,,,,,,,0,Color,Red,1,1,,,,,1,,,, +87,grouped,logo-collection,"Logo Collection",1,0,visible,"This is a grouped product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,,Clothing,,,"https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/logo-1.jpg, https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-with-logo-1.jpg, https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/t-shirt-with-logo-1.jpg, https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-logo-2.jpg",,,,"woo-hoodie-with-logo, woo-tshirt, woo-beanie",,,,,0,,,,,,,,,1,,,, +89,external,wp-pennant,"WordPress Pennant",1,0,visible,"This is an external product.","Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,11.05,Decor,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/pennant-1.jpg,,,,,,,https://mercantile.wordpress.org/product/wordpress-pennant/,"Buy on the WordPress swag store!",0,,,,,,,,,1,,,, +90,variation,woo-hoodie-blue-logo,"Hoodie - Blue, Yes",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,45,,,,https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-logo-2.jpg,,,woo-hoodie,,,,,,0,Color,Blue,,1,Logo,Yes,,0,,,,, diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/sample-data/sample_products.xml b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/sample-data/sample_products.xml new file mode 100644 index 0000000..a5e3382 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/sample-data/sample_products.xml @@ -0,0 +1,4854 @@ + + + + + +WooCommerce Demo Store +http: +Just another WooCommerce store +Wed, 16 Jan 2019 13:09:24 +0000 +en-US +1.2 +http: +http: + + 1 + shopmanager + info@woocommerce.com + + + + +https://wordpress.org/?v=5.0.3 + + V-Neck T-Shirt + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/ + + + + 6 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + v-neck-t-shirt + publish + 0 + 0 + product + + 0 + + + + + + + + + + + _sku + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _thumbnail_id + + + + _price + + + + _price + + + + _regular_price + + + + _sale_price + + + + + Hoodie + https://woocommercecore.mystagingwebsite.com/product/hoodie/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie/ + + + + 7 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + hoodie + publish + 0 + 0 + product + + 0 + + + + + + + _sku + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _thumbnail_id + + + + _price + + + + _price + + + + _regular_price + + + + _sale_price + + + + + Hoodie with Logo + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-logo/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-logo/ + + + + 8 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + hoodie-with-logo + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + T-Shirt + https://woocommercecore.mystagingwebsite.com/product/t-shirt/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/t-shirt/ + + + + 9 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + t-shirt + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Beanie + https://woocommercecore.mystagingwebsite.com/product/beanie/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/beanie/ + + + + 10 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + beanie + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Belt + https://woocommercecore.mystagingwebsite.com/product/belt/ + Wed, 16 Jan 2019 13:01:52 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/belt/ + + + + 11 + 2019-01-16 13:01:52 + 2019-01-16 13:01:52 + open + closed + belt + publish + 0 + 0 + product + + 0 + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Cap + https://woocommercecore.mystagingwebsite.com/product/cap/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/cap/ + + + + 12 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + cap + publish + 0 + 0 + product + + 0 + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Sunglasses + https://woocommercecore.mystagingwebsite.com/product/sunglasses/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/sunglasses/ + + + + 13 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + sunglasses + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Hoodie with Pocket + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-pocket/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-pocket/ + + + + 14 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + hoodie-with-pocket + publish + 0 + 0 + product + + 0 + + + + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Hoodie with Zipper + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-zipper/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-with-zipper/ + + + + 15 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + hoodie-with-zipper + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Long Sleeve Tee + https://woocommercecore.mystagingwebsite.com/product/long-sleeve-tee/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/long-sleeve-tee/ + + + + 16 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + long-sleeve-tee + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Polo + https://woocommercecore.mystagingwebsite.com/product/polo/ + Wed, 16 Jan 2019 13:01:53 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/polo/ + + + + 17 + 2019-01-16 13:01:53 + 2019-01-16 13:01:53 + open + closed + polo + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Album + https://woocommercecore.mystagingwebsite.com/product/album/ + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/album/ + + + + 18 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + open + closed + album + publish + 0 + 0 + product + + 0 + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Single + https://woocommercecore.mystagingwebsite.com/product/single/ + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/single/ + + + + 19 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + open + closed + single + publish + 0 + 0 + product + + 0 + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + V-Neck T-Shirt - Red + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/?attribute_pa_color=red + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt-red/ + + + + 20 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + v-neck-t-shirt-red + publish + 6 + 0 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_pa_size + + + + + V-Neck T-Shirt - Green + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/?attribute_pa_color=green + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt-green/ + + + + 21 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + v-neck-t-shirt-green + publish + 6 + 0 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_pa_size + + + + + V-Neck T-Shirt - Blue + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt/?attribute_pa_color=blue + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/v-neck-t-shirt-blue/ + + + + 22 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + v-neck-t-shirt-blue + publish + 6 + 0 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _wpcom_is_markdown + + + + _wp_old_slug + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_pa_size + + + + + Hoodie - Red, No + https://woocommercecore.mystagingwebsite.com/product/hoodie/?attribute_pa_color=red&attribute_logo=no + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-red-no + + + + 23 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + hoodie-red-no + publish + 7 + 1 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_logo + + + + + Hoodie - Green, No + https://woocommercecore.mystagingwebsite.com/product/hoodie/?attribute_pa_color=green&attribute_logo=No + Wed, 16 Jan 2019 13:01:54 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-green-no/ + + + + 24 + 2019-01-16 13:01:54 + 2019-01-16 13:01:54 + closed + closed + hoodie-green-no + publish + 7 + 2 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_logo + + + + + Hoodie - Blue, No + https://woocommercecore.mystagingwebsite.com/product/hoodie/?attribute_pa_color=blue&attribute_logo=No + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-blue-no + + + + 25 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + closed + closed + hoodie-blue-no + publish + 7 + 3 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_logo + + + + + T-Shirt with Logo + https://woocommercecore.mystagingwebsite.com/product/t-shirt-with-logo/ + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/t-shirt-with-logo/ + + + + 26 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + open + closed + t-shirt-with-logo + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Beanie with Logo + https://woocommercecore.mystagingwebsite.com/product/beanie-with-logo/ + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/beanie-with-logo/ + + + + 27 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + open + closed + beanie-with-logo + publish + 0 + 0 + product + + 0 + + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + + Logo Collection + https://woocommercecore.mystagingwebsite.com/product/logo-collection/ + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/logo-collection/ + + + + 28 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + open + closed + logo-collection + publish + 0 + 0 + product + + 0 + + + + _sku + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _children + + + + _thumbnail_id + + + + _price + + + + _price + + + + + WordPress Pennant + https://woocommercecore.mystagingwebsite.com/product/wordpress-pennant/ + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/wordpress-pennant/ + + + + 29 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + open + closed + wordpress-pennant + publish + 0 + 0 + product + + 0 + + + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _thumbnail_id + + + + _product_url + + + + _button_text + + + + + Hoodie - Blue, Yes + https://woocommercecore.mystagingwebsite.com/product/hoodie/?attribute_pa_color=blue&attribute_logo=Yes + Wed, 16 Jan 2019 13:01:55 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/product/hoodie-blue-yes/ + + + + 30 + 2019-01-16 13:01:55 + 2019-01-16 13:01:55 + closed + closed + hoodie-blue-yes + publish + 7 + 0 + product_variation + + 0 + + _sku + + + + _regular_price + + + + _sale_price + + + + _sale_price_dates_from + + + + _sale_price_dates_to + + + + total_sales + + + + _tax_status + + + + _tax_class + + + + _manage_stock + + + + _backorders + + + + _low_stock_amount + + + + _sold_individually + + + + _weight + + + + _length + + + + _width + + + + _height + + + + _upsell_ids + + + + _crosssell_ids + + + + _purchase_note + + + + _default_attributes + + + + _virtual + + + + _downloadable + + + + _product_image_gallery + + + + _download_limit + + + + _download_expiry + + + + _stock + + + + _stock_status + + + + _wc_average_rating + + + + _wc_rating_count + + + + _wc_review_count + + + + _downloadable_files + + + + _product_attributes + + + + _product_version + + + + _price + + + + _variation_description + + + + _thumbnail_id + + + + attribute_pa_color + + + + attribute_logo + + + + + vneck-tee-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=31 + Wed, 16 Jan 2019 13:01:56 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vneck-tee-2.jpg + + + + 31 + 2019-01-16 13:01:56 + 2019-01-16 13:01:56 + open + closed + vneck-tee-2-jpg + inherit + 6 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vneck-tee-2.jpg + + _wc_attachment_source + + + + + vnech-tee-green-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=32 + Wed, 16 Jan 2019 13:01:57 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-green-1.jpg + + + + 32 + 2019-01-16 13:01:57 + 2019-01-16 13:01:57 + open + closed + vnech-tee-green-1-jpg + inherit + 6 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-green-1.jpg + + _wc_attachment_source + + + + + vnech-tee-blue-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=33 + Wed, 16 Jan 2019 13:01:58 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-blue-1.jpg + + + + 33 + 2019-01-16 13:01:58 + 2019-01-16 13:01:58 + open + closed + vnech-tee-blue-1-jpg + inherit + 6 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/vnech-tee-blue-1.jpg + + _wc_attachment_source + + + + + hoodie-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=34 + Wed, 16 Jan 2019 13:01:58 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-2.jpg + + + + 34 + 2019-01-16 13:01:58 + 2019-01-16 13:01:58 + open + closed + hoodie-2-jpg + inherit + 7 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-2.jpg + + _wc_attachment_source + + + + + hoodie-blue-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=35 + Wed, 16 Jan 2019 13:01:59 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-blue-1.jpg + + + + 35 + 2019-01-16 13:01:59 + 2019-01-16 13:01:59 + open + closed + hoodie-blue-1-jpg + inherit + 7 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-blue-1.jpg + + _wc_attachment_source + + + + + hoodie-green-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=36 + Wed, 16 Jan 2019 13:02:00 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-green-1.jpg + + + + 36 + 2019-01-16 13:02:00 + 2019-01-16 13:02:00 + open + closed + hoodie-green-1-jpg + inherit + 7 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-green-1.jpg + + _wc_attachment_source + + + + + hoodie-with-logo-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=37 + Wed, 16 Jan 2019 13:02:01 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-logo-2.jpg + + + + 37 + 2019-01-16 13:02:01 + 2019-01-16 13:02:01 + open + closed + hoodie-with-logo-2-jpg + inherit + 7 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-logo-2.jpg + + _wc_attachment_source + + + + + tshirt-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=38 + Wed, 16 Jan 2019 13:02:02 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/tshirt-2.jpg + + + + 38 + 2019-01-16 13:02:02 + 2019-01-16 13:02:02 + open + closed + tshirt-2-jpg + inherit + 9 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/tshirt-2.jpg + + _wc_attachment_source + + + + + beanie-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=39 + Wed, 16 Jan 2019 13:02:02 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-2.jpg + + + + 39 + 2019-01-16 13:02:02 + 2019-01-16 13:02:02 + open + closed + beanie-2-jpg + inherit + 10 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-2.jpg + + _wc_attachment_source + + + + + belt-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=40 + Wed, 16 Jan 2019 13:02:03 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/belt-2.jpg + + + + 40 + 2019-01-16 13:02:03 + 2019-01-16 13:02:03 + open + closed + belt-2-jpg + inherit + 11 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/belt-2.jpg + + _wc_attachment_source + + + + + cap-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=41 + Wed, 16 Jan 2019 13:02:04 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/cap-2.jpg + + + + 41 + 2019-01-16 13:02:04 + 2019-01-16 13:02:04 + open + closed + cap-2-jpg + inherit + 12 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/cap-2.jpg + + _wc_attachment_source + + + + + sunglasses-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=42 + Wed, 16 Jan 2019 13:02:05 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/sunglasses-2.jpg + + + + 42 + 2019-01-16 13:02:05 + 2019-01-16 13:02:05 + open + closed + sunglasses-2-jpg + inherit + 13 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/sunglasses-2.jpg + + _wc_attachment_source + + + + + hoodie-with-pocket-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=43 + Wed, 16 Jan 2019 13:02:06 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-pocket-2.jpg + + + + 43 + 2019-01-16 13:02:06 + 2019-01-16 13:02:06 + open + closed + hoodie-with-pocket-2-jpg + inherit + 14 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-pocket-2.jpg + + _wc_attachment_source + + + + + hoodie-with-zipper-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=44 + Wed, 16 Jan 2019 13:02:06 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-zipper-2.jpg + + + + 44 + 2019-01-16 13:02:06 + 2019-01-16 13:02:06 + open + closed + hoodie-with-zipper-2-jpg + inherit + 15 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/hoodie-with-zipper-2.jpg + + _wc_attachment_source + + + + + long-sleeve-tee-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=45 + Wed, 16 Jan 2019 13:02:07 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/long-sleeve-tee-2.jpg + + + + 45 + 2019-01-16 13:02:07 + 2019-01-16 13:02:07 + open + closed + long-sleeve-tee-2-jpg + inherit + 16 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/long-sleeve-tee-2.jpg + + _wc_attachment_source + + + + + polo-2.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=46 + Wed, 16 Jan 2019 13:02:08 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/polo-2.jpg + + + + 46 + 2019-01-16 13:02:08 + 2019-01-16 13:02:08 + open + closed + polo-2-jpg + inherit + 17 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/polo-2.jpg + + _wc_attachment_source + + + + + album-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=47 + Wed, 16 Jan 2019 13:02:09 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/album-1.jpg + + + + 47 + 2019-01-16 13:02:09 + 2019-01-16 13:02:09 + open + closed + album-1-jpg + inherit + 18 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/album-1.jpg + + _wc_attachment_source + + + + + single-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=48 + Wed, 16 Jan 2019 13:02:10 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/single-1.jpg + + + + 48 + 2019-01-16 13:02:10 + 2019-01-16 13:02:10 + open + closed + single-1-jpg + inherit + 19 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/single-1.jpg + + _wc_attachment_source + + + + + t-shirt-with-logo-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=49 + Wed, 16 Jan 2019 13:02:11 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/t-shirt-with-logo-1.jpg + + + + 49 + 2019-01-16 13:02:11 + 2019-01-16 13:02:11 + open + closed + t-shirt-with-logo-1-jpg + inherit + 26 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/t-shirt-with-logo-1.jpg + + _wc_attachment_source + + + + + beanie-with-logo-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=50 + Wed, 16 Jan 2019 13:02:12 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-with-logo-1.jpg + + + + 50 + 2019-01-16 13:02:12 + 2019-01-16 13:02:12 + open + closed + beanie-with-logo-1-jpg + inherit + 27 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/beanie-with-logo-1.jpg + + _wc_attachment_source + + + + + logo-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=51 + Wed, 16 Jan 2019 13:02:13 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/logo-1.jpg + + + + 51 + 2019-01-16 13:02:13 + 2019-01-16 13:02:13 + open + closed + logo-1-jpg + inherit + 28 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/logo-1.jpg + + _wc_attachment_source + + + + + pennant-1.jpg + https://woocommercecore.mystagingwebsite.com/?attachment_id=52 + Wed, 16 Jan 2019 13:02:13 +0000 + shopmanager + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/pennant-1.jpg + + + + 52 + 2019-01-16 13:02:13 + 2019-01-16 13:02:13 + open + closed + pennant-1-jpg + inherit + 29 + 0 + attachment + + 0 + https://woocommercecore.mystagingwebsite.com/wp-content/uploads/2017/12/pennant-1.jpg + + _wc_attachment_source + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/sample-data/sample_tax_rates.csv b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/sample-data/sample_tax_rates.csv new file mode 100644 index 0000000..02038b5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/sample-data/sample_tax_rates.csv @@ -0,0 +1,6 @@ +Country Code,State Code,ZIP/Postcode,City,Rate %,Tax Name,Priority,Compound,Shipping,Tax Class +GB,*,*,*,20.0000,VAT,1,1,1, +GB,*,*,*,5.0000,VAT,1,1,1,reduced-rate +GB,*,*,*,0.0000,VAT,1,1,1,zero-rate +US,*,*,*,10.0000,US,1,1,1, +US,AL,12345; 123456,*,2.0000,US AL,2,1,1, \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Autoloader.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Autoloader.php new file mode 100644 index 0000000..53f802e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Autoloader.php @@ -0,0 +1,74 @@ + +
    +

    + ', + '' + ); + ?> +

    +
    + enabled = get_option( 'woocommerce_schema_version', 0 ) >= 430; + } + + /** + * Is stock reservation enabled? + * + * @return boolean + */ + protected function is_enabled() { + return $this->enabled; + } + + /** + * Query for any existing holds on stock for this item. + * + * @param \WC_Product $product Product to get reserved stock for. + * @param integer $exclude_order_id Optional order to exclude from the results. + * + * @return integer Amount of stock already reserved. + */ + public function get_reserved_stock( $product, $exclude_order_id = 0 ) { + global $wpdb; + + if ( ! $this->is_enabled() ) { + return 0; + } + + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared + return (int) $wpdb->get_var( $this->get_query_for_reserved_stock( $product->get_stock_managed_by_id(), $exclude_order_id ) ); + } + + /** + * Put a temporary hold on stock for an order if enough is available. + * + * @throws ReserveStockException If stock cannot be reserved. + * + * @param \WC_Order $order Order object. + * @param int $minutes How long to reserve stock in minutes. Defaults to woocommerce_hold_stock_minutes. + */ + public function reserve_stock_for_order( $order, $minutes = 0 ) { + $minutes = $minutes ? $minutes : (int) get_option( 'woocommerce_hold_stock_minutes', 60 ); + + if ( ! $minutes || ! $this->is_enabled() ) { + return; + } + + try { + $items = array_filter( + $order->get_items(), + function( $item ) { + return $item->is_type( 'line_item' ) && $item->get_product() instanceof \WC_Product && $item->get_quantity() > 0; + } + ); + $rows = array(); + + foreach ( $items as $item ) { + $product = $item->get_product(); + + if ( ! $product->is_in_stock() ) { + throw new ReserveStockException( + 'woocommerce_product_out_of_stock', + sprintf( + /* translators: %s: product name */ + __( '"%s" is out of stock and cannot be purchased.', 'woocommerce' ), + $product->get_name() + ), + 403 + ); + } + + // If stock management is off, no need to reserve any stock here. + if ( ! $product->managing_stock() || $product->backorders_allowed() ) { + continue; + } + + $managed_by_id = $product->get_stock_managed_by_id(); + + /** + * Filter order item quantity. + * + * @param int|float $quantity Quantity. + * @param WC_Order $order Order data. + * @param WC_Order_Item_Product $item Order item data. + */ + $item_quantity = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item ); + + $rows[ $managed_by_id ] = isset( $rows[ $managed_by_id ] ) ? $rows[ $managed_by_id ] + $item_quantity : $item_quantity; + } + + if ( ! empty( $rows ) ) { + foreach ( $rows as $product_id => $quantity ) { + $this->reserve_stock_for_product( $product_id, $quantity, $order, $minutes ); + } + } + } catch ( ReserveStockException $e ) { + $this->release_stock_for_order( $order ); + throw $e; + } + } + + /** + * Release a temporary hold on stock for an order. + * + * @param \WC_Order $order Order object. + */ + public function release_stock_for_order( $order ) { + global $wpdb; + + if ( ! $this->is_enabled() ) { + return; + } + + $wpdb->delete( + $wpdb->wc_reserved_stock, + array( + 'order_id' => $order->get_id(), + ) + ); + } + + /** + * Reserve stock for a product by inserting rows into the DB. + * + * @throws ReserveStockException If a row cannot be inserted. + * + * @param int $product_id Product ID which is having stock reserved. + * @param int $stock_quantity Stock amount to reserve. + * @param \WC_Order $order Order object which contains the product. + * @param int $minutes How long to reserve stock in minutes. + */ + private function reserve_stock_for_product( $product_id, $stock_quantity, $order, $minutes ) { + global $wpdb; + + $product_data_store = \WC_Data_Store::load( 'product' ); + $query_for_stock = $product_data_store->get_query_for_stock( $product_id ); + $query_for_reserved_stock = $this->get_query_for_reserved_stock( $product_id, $order->get_id() ); + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared + $result = $wpdb->query( + $wpdb->prepare( + " + INSERT INTO {$wpdb->wc_reserved_stock} ( `order_id`, `product_id`, `stock_quantity`, `timestamp`, `expires` ) + SELECT %d, %d, %d, NOW(), ( NOW() + INTERVAL %d MINUTE ) FROM DUAL + WHERE ( $query_for_stock FOR UPDATE ) - ( $query_for_reserved_stock FOR UPDATE ) >= %d + ON DUPLICATE KEY UPDATE `expires` = VALUES( `expires` ), `stock_quantity` = VALUES( `stock_quantity` ) + ", + $order->get_id(), + $product_id, + $stock_quantity, + $minutes, + $stock_quantity + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared + + if ( ! $result ) { + $product = wc_get_product( $product_id ); + throw new ReserveStockException( + 'woocommerce_product_not_enough_stock', + sprintf( + /* translators: %s: product name */ + __( 'Not enough units of %s are available in stock to fulfil this order.', 'woocommerce' ), + $product ? $product->get_name() : '#' . $product_id + ), + 403 + ); + } + } + + /** + * Returns query statement for getting reserved stock of a product. + * + * @param int $product_id Product ID. + * @param integer $exclude_order_id Optional order to exclude from the results. + * @return string|void Query statement. + */ + private function get_query_for_reserved_stock( $product_id, $exclude_order_id = 0 ) { + global $wpdb; + $query = $wpdb->prepare( + " + SELECT COALESCE( SUM( stock_table.`stock_quantity` ), 0 ) FROM $wpdb->wc_reserved_stock stock_table + LEFT JOIN $wpdb->posts posts ON stock_table.`order_id` = posts.ID + WHERE posts.post_status IN ( 'wc-checkout-draft', 'wc-pending' ) + AND stock_table.`expires` > NOW() + AND stock_table.`product_id` = %d + AND stock_table.`order_id` != %d + ", + $product_id, + $exclude_order_id + ); + + /** + * Filter: woocommerce_query_for_reserved_stock + * Allows to filter the query for getting reserved stock of a product. + * + * @since 4.5.0 + * @param string $query The query for getting reserved stock of a product. + * @param int $product_id Product ID. + * @param int $exclude_order_id Order to exclude from the results. + */ + return apply_filters( 'woocommerce_query_for_reserved_stock', $query, $product_id, $exclude_order_id ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Checkout/Helpers/ReserveStockException.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Checkout/Helpers/ReserveStockException.php new file mode 100644 index 0000000..0122ff9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Checkout/Helpers/ReserveStockException.php @@ -0,0 +1,60 @@ +error_code = $code; + $this->error_data = $data; + + parent::__construct( $message, $http_status_code ); + } + + /** + * Returns the error code. + * + * @return string + */ + public function getErrorCode() { + return $this->error_code; + } + + /** + * Returns error data. + * + * @return array + */ + public function getErrorData() { + return $this->error_data; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Container.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Container.php new file mode 100644 index 0000000..4291867 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Container.php @@ -0,0 +1,89 @@ +container = new ExtendedContainer(); + + // Add ourselves as the shared instance of ContainerInterface, + // register everything else using service providers. + + $this->container->share( \Psr\Container\ContainerInterface::class, $this ); + + foreach ( $this->service_providers as $service_provider_class ) { + $this->container->addServiceProvider( $service_provider_class ); + } + } + + /** + * Finds an entry of the container by its identifier and returns it. + * + * @param string $id Identifier of the entry to look for. + * + * @throws NotFoundExceptionInterface No entry was found for **this** identifier. + * @throws Psr\Container\ContainerExceptionInterface Error while retrieving the entry. + * + * @return mixed Entry. + */ + public function get( $id ) { + return $this->container->get( $id ); + } + + /** + * Returns true if the container can return an entry for the given identifier. + * Returns false otherwise. + * + * `has($id)` returning true does not mean that `get($id)` will not throw an exception. + * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`. + * + * @param string $id Identifier of the entry to look for. + * + * @return bool + */ + public function has( $id ) { + return $this->container->has( $id ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/AbstractServiceProvider.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/AbstractServiceProvider.php new file mode 100644 index 0000000..bd1409e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/AbstractServiceProvider.php @@ -0,0 +1,171 @@ +getContainer()`. + */ +abstract class AbstractServiceProvider extends \Automattic\WooCommerce\Vendor\League\Container\ServiceProvider\AbstractServiceProvider { + + /** + * Register a class in the container and use reflection to guess the injection method arguments. + * + * WARNING: this method uses reflection, so please have performance in mind when using it. + * + * @param string $class_name Class name to register. + * @param mixed $concrete The concrete to register. Can be a shared instance, a factory callback, or a class name. + * @param bool $shared Whether to register the class as shared (`get` always returns the same instance) or not. + * + * @return DefinitionInterface The generated container definition. + * + * @throws ContainerException Error when reflecting the class, or class injection method is not public, or an argument has no valid type hint. + */ + protected function add_with_auto_arguments( string $class_name, $concrete = null, bool $shared = false ) : DefinitionInterface { + $definition = new Definition( $class_name, $concrete ); + + $function = $this->reflect_class_or_callable( $class_name, $concrete ); + + if ( ! is_null( $function ) ) { + $arguments = $function->getParameters(); + foreach ( $arguments as $argument ) { + if ( $argument->isDefaultValueAvailable() ) { + $default_value = $argument->getDefaultValue(); + $definition->addArgument( new RawArgument( $default_value ) ); + } else { + $argument_class = $this->get_class( $argument ); + if ( is_null( $argument_class ) ) { + throw new ContainerException( "Argument '{$argument->getName()}' of class '$class_name' doesn't have a type hint or has one that doesn't specify a class." ); + } + + $definition->addArgument( $argument_class->name ); + } + } + } + + // Register the definition only after being sure that no exception will be thrown. + $this->getContainer()->add( $definition->getAlias(), $definition, $shared ); + + return $definition; + } + + /** + * Gets the class of a parameter. + * + * This method is a replacement for ReflectionParameter::getClass, + * which is deprecated as of PHP 8. + * + * @param \ReflectionParameter $parameter The parameter to get the class for. + * + * @return \ReflectionClass|null The class of the parameter, or null if it hasn't any. + */ + private function get_class( \ReflectionParameter $parameter ) { + // TODO: Remove this 'if' block once minimum PHP version for WooCommerce is bumped to at least 7.1. + if ( version_compare( PHP_VERSION, '7.1', '<' ) ) { + return $parameter->getClass(); + } + + return $parameter->getType() && ! $parameter->getType()->isBuiltin() + ? new \ReflectionClass( $parameter->getType()->getName() ) + : null; + } + + /** + * Check if a combination of class name and concrete is valid for registration. + * Also return the class injection method if the concrete is either a class name or null (then use the supplied class name). + * + * @param string $class_name The class name to check. + * @param mixed $concrete The concrete to check. + * + * @return \ReflectionFunctionAbstract|null A reflection instance for the $class_name injection method or $concrete injection method or callable; null otherwise. + * @throws ContainerException Class has a private injection method, can't reflect class, or the concrete is invalid. + */ + private function reflect_class_or_callable( string $class_name, $concrete ) { + if ( ! isset( $concrete ) || is_string( $concrete ) && class_exists( $concrete ) ) { + try { + $class = $concrete ?? $class_name; + $method = new \ReflectionMethod( $class, Definition::INJECTION_METHOD ); + if ( ! isset( $method ) ) { + return null; + } + + $missing_modifiers = array(); + if ( ! $method->isFinal() ) { + $missing_modifiers[] = 'final'; + } + if ( ! $method->isPublic() ) { + $missing_modifiers[] = 'public'; + } + if ( ! empty( $missing_modifiers ) ) { + throw new ContainerException( "Method '" . Definition::INJECTION_METHOD . "' of class '$class' isn't '" . implode( ' ', $missing_modifiers ) . "', instances can't be created." ); + } + + return $method; + } catch ( \ReflectionException $ex ) { + return null; + } + } elseif ( is_callable( $concrete ) ) { + try { + return new \ReflectionFunction( $concrete ); + } catch ( \ReflectionException $ex ) { + throw new ContainerException( "Error when reflecting callable: {$ex->getMessage()}" ); + } + } + + return null; + } + + /** + * Register a class in the container and use reflection to guess the injection method arguments. + * The class is registered as shared, so `get` on the container always returns the same instance. + * + * WARNING: this method uses reflection, so please have performance in mind when using it. + * + * @param string $class_name Class name to register. + * @param mixed $concrete The concrete to register. Can be a shared instance, a factory callback, or a class name. + * + * @return DefinitionInterface The generated container definition. + * + * @throws ContainerException Error when reflecting the class, or class injection method is not public, or an argument has no valid type hint. + */ + protected function share_with_auto_arguments( string $class_name, $concrete = null ) : DefinitionInterface { + return $this->add_with_auto_arguments( $class_name, $concrete, true ); + } + + /** + * Register an entry in the container. + * + * @param string $id Entry id (typically a class or interface name). + * @param mixed|null $concrete Concrete entity to register under that id, null for automatic creation. + * @param bool|null $shared Whether to register the class as shared (`get` always returns the same instance) or not. + * + * @return DefinitionInterface The generated container definition. + */ + protected function add( string $id, $concrete = null, bool $shared = null ) : DefinitionInterface { + return $this->getContainer()->add( $id, $concrete, $shared ); + } + + /** + * Register a shared entry in the container (`get` always returns the same instance). + * + * @param string $id Entry id (typically a class or interface name). + * @param mixed|null $concrete Concrete entity to register under that id, null for automatic creation. + * + * @return DefinitionInterface The generated container definition. + */ + protected function share( string $id, $concrete = null ) : DefinitionInterface { + return $this->add( $id, $concrete, true ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ContainerException.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ContainerException.php new file mode 100644 index 0000000..de8499e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ContainerException.php @@ -0,0 +1,23 @@ +resolveArguments( $this->arguments ); + $concrete = new $concrete(); + + // Constructor injection causes backwards compatibility problems + // so we will rely on method injection via an internal method. + if ( method_exists( $concrete, static::INJECTION_METHOD ) ) { + call_user_func_array( array( $concrete, static::INJECTION_METHOD ), $resolved ); + } + + return $concrete; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ExtendedContainer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ExtendedContainer.php new file mode 100644 index 0000000..a4e084c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ExtendedContainer.php @@ -0,0 +1,152 @@ +is_class_allowed( $class_name ) ) { + throw new ContainerException( "You cannot add '$class_name', only classes in the {$this->woocommerce_namespace} namespace are allowed." ); + } + + $concrete_class = $this->get_class_from_concrete( $concrete ); + if ( isset( $concrete_class ) && ! $this->is_class_allowed( $concrete_class ) ) { + throw new ContainerException( "You cannot add concrete '$concrete_class', only classes in the {$this->woocommerce_namespace} namespace are allowed." ); + } + + // We want to use a definition class that does not support constructor injection to avoid accidental usage. + if ( ! $concrete instanceof DefinitionInterface ) { + $concrete = new Definition( $class_name, $concrete ); + } + + return parent::add( $class_name, $concrete, $shared ); + } + + /** + * Replace an existing registration with a different concrete. + * + * @param string $class_name The class name whose definition will be replaced. + * @param mixed $concrete The new concrete (same as "add"). + * + * @return DefinitionInterface The modified definition. + * @throws ContainerException Invalid parameters. + */ + public function replace( string $class_name, $concrete ) : DefinitionInterface { + if ( ! $this->has( $class_name ) ) { + throw new ContainerException( "The container doesn't have '$class_name' registered, please use 'add' instead of 'replace'." ); + } + + $concrete_class = $this->get_class_from_concrete( $concrete ); + if ( isset( $concrete_class ) && ! $this->is_class_allowed( $concrete_class ) ) { + throw new ContainerException( "You cannot use concrete '$concrete_class', only classes in the {$this->woocommerce_namespace} namespace are allowed." ); + } + + return $this->extend( $class_name )->setConcrete( $concrete ); + } + + /** + * Reset all the cached resolutions, so any further "get" for shared definitions will generate the instance again. + */ + public function reset_all_resolved() { + foreach ( $this->definitions->getIterator() as $definition ) { + // setConcrete causes the cached resolved value to be forgotten. + $concrete = $definition->getConcrete(); + $definition->setConcrete( $concrete ); + } + } + + /** + * Get an instance of a registered class. + * + * @param string $id The class name. + * @param bool $new True to generate a new instance even if the class was registered as shared. + * + * @return object An instance of the requested class. + * @throws ContainerException Attempt to get an instance of a non-namespaced class. + */ + public function get( $id, bool $new = false ) { + if ( false === strpos( $id, '\\' ) ) { + throw new ContainerException( "Attempt to get an instance of the non-namespaced class '$id' from the container, did you forget to add a namespace import?" ); + } + + return parent::get( $id, $new ); + } + + /** + * Gets the class from the concrete regardless of type. + * + * @param mixed $concrete The concrete that we want the class from.. + * + * @return string|null The class from the concrete if one is available, null otherwise. + */ + protected function get_class_from_concrete( $concrete ) { + if ( is_object( $concrete ) && ! is_callable( $concrete ) ) { + if ( $concrete instanceof DefinitionInterface ) { + return $this->get_class_from_concrete( $concrete->getConcrete() ); + } + + return get_class( $concrete ); + } + + if ( is_string( $concrete ) && class_exists( $concrete ) ) { + return $concrete; + } + + return null; + } + + /** + * Checks to see whether or not a class is allowed to be registered. + * + * @param string $class_name The class to check. + * + * @return bool True if the class is allowed to be registered, false otherwise. + */ + protected function is_class_allowed( string $class_name ): bool { + return StringUtil::starts_with( $class_name, $this->woocommerce_namespace, false ) || in_array( $class_name, $this->registration_whitelist, true ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ServiceProviders/ProxiesServiceProvider.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ServiceProviders/ProxiesServiceProvider.php new file mode 100644 index 0000000..b790397 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ServiceProviders/ProxiesServiceProvider.php @@ -0,0 +1,34 @@ +share( ActionsProxy::class ); + $this->share_with_auto_arguments( LegacyProxy::class ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/WCCom/ConnectionHelper.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/WCCom/ConnectionHelper.php new file mode 100644 index 0000000..d3c771d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Internal/WCCom/ConnectionHelper.php @@ -0,0 +1,29 @@ + '\\Automattic\\WooCommerce\\Blocks\\Package', + 'woocommerce-admin' => '\\Automattic\\WooCommerce\\Admin\\Composer\\Package', + ); + + /** + * Init the package loader. + * + * @since 3.7.0 + */ + public static function init() { + add_action( 'plugins_loaded', array( __CLASS__, 'on_init' ) ); + } + + /** + * Callback for WordPress init hook. + */ + public static function on_init() { + self::load_packages(); + } + + /** + * Checks a package exists by looking for it's directory. + * + * @param string $package Package name. + * @return boolean + */ + public static function package_exists( $package ) { + return file_exists( dirname( __DIR__ ) . '/packages/' . $package ); + } + + /** + * Loads packages after plugins_loaded hook. + * + * Each package should include an init file which loads the package so it can be used by core. + */ + protected static function load_packages() { + foreach ( self::$packages as $package_name => $package_class ) { + if ( ! self::package_exists( $package_name ) ) { + self::missing_package( $package_name ); + continue; + } + call_user_func( array( $package_class, 'init' ) ); + } + } + + /** + * If a package is missing, add an admin notice. + * + * @param string $package Package name. + */ + protected static function missing_package( $package ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + error_log( // phpcs:ignore + sprintf( + /* Translators: %s package name. */ + esc_html__( 'Missing the WooCommerce %s package', 'woocommerce' ), + '' . esc_html( $package ) . '' + ) . ' - ' . esc_html__( 'Your installation of WooCommerce is incomplete. If you installed WooCommerce from GitHub, please refer to this document to set up your development environment: https://github.com/woocommerce/woocommerce/wiki/How-to-set-up-WooCommerce-development-environment', 'woocommerce' ) + ); + } + add_action( + 'admin_notices', + function() use ( $package ) { + ?> +
    +

    + + ' . esc_html( $package ) . '' + ); + ?> + +
    + ', + '' + ); + ?> +

    +
    + $method( ...$args ); + } + + // If the class is a singleton, use the "instance" method. + if ( method_exists( $class_name, 'instance' ) ) { + return $class_name::instance( ...$args ); + } + + // Fallback to simply creating a new instance of the class. + return new $class_name( ...$args ); + } + + /** + * Get an instance of a class implementing WC_Queue_Interface. + * + * @return \WC_Queue_Interface The instance. + */ + private function get_instance_of_wc_queue_interface() { + return \WC_Queue::instance(); + } + + /** + * Call a user function. This should be used to execute any non-idempotent function, especially + * those in the `includes` directory or provided by WordPress. + * + * @param string $function_name The function to execute. + * @param mixed ...$parameters The parameters to pass to the function. + * + * @return mixed The result from the function. + */ + public function call_function( $function_name, ...$parameters ) { + return call_user_func_array( $function_name, $parameters ); + } + + /** + * Call a static method in a class. This should be used to execute any non-idempotent method in classes + * from the `includes` directory. + * + * @param string $class_name The name of the class containing the method. + * @param string $method_name The name of the method. + * @param mixed ...$parameters The parameters to pass to the method. + * + * @return mixed The result from the method. + */ + public function call_static( $class_name, $method_name, ...$parameters ) { + return call_user_func_array( "$class_name::$method_name", $parameters ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Utilities/NumberUtil.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Utilities/NumberUtil.php new file mode 100644 index 0000000..8e1a417 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/src/Utilities/NumberUtil.php @@ -0,0 +1,34 @@ + strlen( $string ) ) { + return false; + } + + $string = substr( $string, 0, $len ); + + if ( $case_sensitive ) { + return strcmp( $string, $starts_with ) === 0; + } + + return strcasecmp( $string, $starts_with ) === 0; + } + + /** + * Checks to see whether or not a string ends with another. + * + * @param string $string The string we want to check. + * @param string $ends_with The string we're looking for at the end of $string. + * @param bool $case_sensitive Indicates whether the comparison should be case-sensitive. + * + * @return bool True if the $string ends with $ends_with, false otherwise. + */ + public static function ends_with( string $string, string $ends_with, bool $case_sensitive = true ): bool { + $len = strlen( $ends_with ); + if ( $len > strlen( $string ) ) { + return false; + } + + $string = substr( $string, -$len ); + + if ( $case_sensitive ) { + return strcmp( $string, $ends_with ) === 0; + } + + return strcasecmp( $string, $ends_with ) === 0; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/archive-product.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/archive-product.php new file mode 100644 index 0000000..998cd5c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/archive-product.php @@ -0,0 +1,105 @@ + +
    + +

    + + + +
    + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/auth/form-grant-access.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/auth/form-grant-access.php new file mode 100644 index 0000000..0b67e7a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/auth/form-grant-access.php @@ -0,0 +1,61 @@ + + + + +

    + +

    + + + +

    + ' . esc_html( $app_name ) . '', '' . esc_html( $scope ) . '' ); + ?> +

    + +
      + +
    • + +
    + +
    + ID, 70 ); ?> +

    + display_name ) ); + ?> + +

    +
    + +

    + + +

    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/auth/form-login.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/auth/form-login.php new file mode 100644 index 0000000..3606ca0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/auth/form-login.php @@ -0,0 +1,54 @@ + + +

    + +

    + + + +

    + cancel and return to %1$s', 'woocommerce' ), esc_html( wc_clean( $app_name ) ), esc_url( $return_url ) ) ); + ?> +

    + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/auth/header.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/auth/header.php new file mode 100644 index 0000000..e05ccc9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/auth/header.php @@ -0,0 +1,33 @@ + +> + + + + + <?php esc_html_e( 'Application authentication request', 'woocommerce' ); ?> + + + + +

    <?php esc_attr_e( 'WooCommerce', 'woocommerce' ); ?>

    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-empty.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-empty.php new file mode 100644 index 0000000..0a463e9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-empty.php @@ -0,0 +1,39 @@ + 0 ) : ?> +

    + + + +

    + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-item-data.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-item-data.php new file mode 100644 index 0000000..d930009 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-item-data.php @@ -0,0 +1,26 @@ + +
    + +
    :
    +
    + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-shipping.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-shipping.php new file mode 100644 index 0000000..134b05b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-shipping.php @@ -0,0 +1,83 @@ +countries->get_formatted_address( $package['destination'], ', ' ); +$has_calculated_shipping = ! empty( $has_calculated_shipping ); +$show_shipping_calculator = ! empty( $show_shipping_calculator ); +$calculator_text = ''; +?> + + + + +
      + +
    • + ', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ), checked( $method->id, $chosen_method, false ) ); // WPCS: XSS ok. + } else { + printf( '', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ) ); // WPCS: XSS ok. + } + printf( '', $index, esc_attr( sanitize_title( $method->id ) ), wc_cart_totals_shipping_method_label( $method ) ); // WPCS: XSS ok. + do_action( 'woocommerce_after_shipping_rate', $method, $index ); + ?> +
    • + +
    + +

    + ' . esc_html( $formatted_destination ) . '' ); + $calculator_text = esc_html__( 'Change address', 'woocommerce' ); + } else { + echo wp_kses_post( apply_filters( 'woocommerce_shipping_estimate_html', __( 'Shipping options will be updated during checkout.', 'woocommerce' ) ) ); + } + ?> +

    + + ' . esc_html( $formatted_destination ) . '' ) ) ); + $calculator_text = esc_html__( 'Enter a different address', 'woocommerce' ); + endif; + ?> + + + ' . esc_html( $package_details ) . '

    '; ?> + + + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-totals.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-totals.php new file mode 100644 index 0000000..f5af332 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart-totals.php @@ -0,0 +1,112 @@ + +
    + + + +

    + + + + + + + + + cart->get_coupons() as $code => $coupon ) : ?> + + + + + + + cart->needs_shipping() && WC()->cart->show_shipping() ) : ?> + + + + + + + + cart->needs_shipping() && 'yes' === get_option( 'woocommerce_enable_shipping_calc' ) ) : ?> + + + + + + + + + cart->get_fees() as $fee ) : ?> + + + + + + + cart->display_prices_including_tax() ) { + $taxable_address = WC()->customer->get_taxable_address(); + $estimated_text = ''; + + if ( WC()->customer->is_customer_outside_base() && ! WC()->customer->has_calculated_shipping() ) { + /* translators: %s location. */ + $estimated_text = sprintf( ' ' . esc_html__( '(estimated for %s)', 'woocommerce' ) . '', WC()->countries->estimated_for_prefix( $taxable_address[0] ) . WC()->countries->countries[ $taxable_address[0] ] ); + } + + if ( 'itemized' === get_option( 'woocommerce_tax_total_display' ) ) { + foreach ( WC()->cart->get_tax_totals() as $code => $tax ) { // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + ?> + + + + + + + + + + + + + + + + + + + + +
    name ); ?>
    label ) . $estimated_text; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>formatted_amount ); ?>
    countries->tax_or_vat() ) . $estimated_text; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
    + +
    + +
    + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart.php new file mode 100644 index 0000000..adf15ed --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cart.php @@ -0,0 +1,176 @@ + + +
    + + + + + + + + + + + + + + + + + cart->get_cart() as $cart_item_key => $cart_item ) { + $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); + $product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key ); + + if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) { + $product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key ); + ?> + + + + + + + + + + + + + + + + + + + + + + + + +
      
    + ×', + esc_url( wc_get_cart_remove_url( $cart_item_key ) ), + esc_html__( 'Remove this item', 'woocommerce' ), + esc_attr( $product_id ), + esc_attr( $_product->get_sku() ) + ), + $cart_item_key + ); + ?> + + get_image(), $cart_item, $cart_item_key ); + + if ( ! $product_permalink ) { + echo $thumbnail; // PHPCS: XSS ok. + } else { + printf( '%s', esc_url( $product_permalink ), $thumbnail ); // PHPCS: XSS ok. + } + ?> + + get_name(), $cart_item, $cart_item_key ) . ' ' ); + } else { + echo wp_kses_post( apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', esc_url( $product_permalink ), $_product->get_name() ), $cart_item, $cart_item_key ) ); + } + + do_action( 'woocommerce_after_cart_item_name', $cart_item, $cart_item_key ); + + // Meta data. + echo wc_get_formatted_cart_item_data( $cart_item ); // PHPCS: XSS ok. + + // Backorder notification. + if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) { + echo wp_kses_post( apply_filters( 'woocommerce_cart_item_backorder_notification', '

    ' . esc_html__( 'Available on backorder', 'woocommerce' ) . '

    ', $product_id ) ); + } + ?> +
    + cart->get_product_price( $_product ), $cart_item, $cart_item_key ); // PHPCS: XSS ok. + ?> + + is_sold_individually() ) { + $product_quantity = sprintf( '1 ', $cart_item_key ); + } else { + $product_quantity = woocommerce_quantity_input( + array( + 'input_name' => "cart[{$cart_item_key}][qty]", + 'input_value' => $cart_item['quantity'], + 'max_value' => $_product->get_max_purchase_quantity(), + 'min_value' => '0', + 'product_name' => $_product->get_name(), + ), + $_product, + false + ); + } + + echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item ); // PHPCS: XSS ok. + ?> + + cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); // PHPCS: XSS ok. + ?> +
    + + +
    + + +
    + + + + + + + +
    + +
    + + + +
    + +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cross-sells.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cross-sells.php new file mode 100644 index 0000000..2f9a478 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/cross-sells.php @@ -0,0 +1,51 @@ + + +
    + +

    + + + + + + + get_id() ); + + setup_postdata( $GLOBALS['post'] =& $post_object ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited, Squiz.PHP.DisallowMultipleAssignments.Found + + wc_get_template_part( 'content', 'product' ); + ?> + + + + + +
    + + +cart->is_empty() ) : ?> + +
      + cart->get_cart() as $cart_item_key => $cart_item ) { + $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); + $product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key ); + + if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) ) { + $product_name = apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ); + $thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key ); + $product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key ); + $product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key ); + ?> +
    • + ×', + esc_url( wc_get_cart_remove_url( $cart_item_key ) ), + esc_attr__( 'Remove this item', 'woocommerce' ), + esc_attr( $product_id ), + esc_attr( $cart_item_key ), + esc_attr( $_product->get_sku() ) + ), + $cart_item_key + ); + ?> + + + + + + + + + ' . sprintf( '%s × %s', $cart_item['quantity'], $product_price ) . '', $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
    • + +
    + +

    + +

    + + + +

    + + + + + +

    + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/proceed-to-checkout-button.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/proceed-to-checkout-button.php new file mode 100644 index 0000000..d678926 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/proceed-to-checkout-button.php @@ -0,0 +1,27 @@ + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/shipping-calculator.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/shipping-calculator.php new file mode 100644 index 0000000..3cd4402 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/cart/shipping-calculator.php @@ -0,0 +1,91 @@ + + +
    + + %s', esc_html( ! empty( $button_text ) ? $button_text : __( 'Calculate shipping', 'woocommerce' ) ) ); ?> + + +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/cart-errors.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/cart-errors.php new file mode 100644 index 0000000..85a280e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/cart-errors.php @@ -0,0 +1,25 @@ + + +

    + + + +

    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-billing.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-billing.php new file mode 100644 index 0000000..9889929 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-billing.php @@ -0,0 +1,74 @@ + +
    + cart->needs_shipping() ) : ?> + +

    + + + +

    + + + + + +
    + get_checkout_fields( 'billing' ); + + foreach ( $fields as $key => $field ) { + woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); + } + ?> +
    + + +
    + +is_registration_enabled() ) : ?> + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-checkout.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-checkout.php new file mode 100644 index 0000000..00d5459 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-checkout.php @@ -0,0 +1,66 @@ +is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in() ) { + echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'You must be logged in to checkout.', 'woocommerce' ) ) ); + return; +} + +?> + +
    + + get_checkout_fields() ) : ?> + + + +
    +
    + +
    + +
    + +
    +
    + + + + + + + +

    + + + +
    + +
    + + + +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-coupon.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-coupon.php new file mode 100644 index 0000000..bca0336 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-coupon.php @@ -0,0 +1,42 @@ + +
    + ' . esc_html__( 'Click here to enter your code', 'woocommerce' ) . '' ), 'notice' ); ?> +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-login.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-login.php new file mode 100644 index 0000000..c9da081 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-login.php @@ -0,0 +1,36 @@ + + + esc_html__( 'If you have shopped with us before, please enter your details below. If you are a new customer, please proceed to the Billing section.', 'woocommerce' ), + 'redirect' => wc_get_checkout_url(), + 'hidden' => true, + ) +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-pay.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-pay.php new file mode 100644 index 0000000..b9244b6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-pay.php @@ -0,0 +1,98 @@ +get_order_item_totals(); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited +?> +
    + + + + + + + + + + + get_items() ) > 0 ) : ?> + get_items() as $item_id => $item ) : ?> + + + + + + + + + + + + + + + + + + + +
    + get_name() ), $item, false ); // @codingStandardsIgnoreLine + + do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order, false ); + + wc_display_item_meta( $item ); + + do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order, false ); + ?> + ' . sprintf( '× %s', esc_html( $item->get_quantity() ) ) . '', $item ); ?>get_formatted_line_subtotal( $item ); ?>
    + +
    + needs_payment() ) : ?> +
      + $gateway ) ); + } + } else { + echo '
    • ' . apply_filters( 'woocommerce_no_available_payment_methods_message', esc_html__( 'Sorry, it seems that there are no available payment methods for your location. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce' ) ) . '
    • '; // @codingStandardsIgnoreLine + } + ?> +
    + +
    + + + + + + + ' . esc_html( $order_button_text ) . '' ); // @codingStandardsIgnoreLine ?> + + + + +
    +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-shipping.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-shipping.php new file mode 100644 index 0000000..f395ba2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/form-shipping.php @@ -0,0 +1,70 @@ + +
    + cart->needs_shipping_address() ) : ?> + +

    + +

    + +
    + + + +
    + get_checkout_fields( 'shipping' ); + + foreach ( $fields as $key => $field ) { + woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); + } + ?> +
    + + + +
    + + +
    +
    + + + + + cart->needs_shipping() || wc_ship_to_billing_address_only() ) : ?> + +

    + + + +
    + get_checkout_fields( 'order' ) as $key => $field ) : ?> + get_value( $key ) ); ?> + +
    + + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/order-receipt.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/order-receipt.php new file mode 100644 index 0000000..bd8ca6f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/order-receipt.php @@ -0,0 +1,46 @@ + + +
      +
    • + + get_order_number() ); ?> +
    • +
    • + + get_date_created() ) ); ?> +
    • +
    • + + get_formatted_order_total() ); ?> +
    • + get_payment_method_title() ) : ?> +
    • + + get_payment_method_title() ); ?> +
    • + +
    + +get_payment_method(), $order->get_id() ); ?> + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/payment-method.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/payment-method.php new file mode 100644 index 0000000..a3d4dbd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/payment-method.php @@ -0,0 +1,33 @@ + +
  • + chosen, true ); ?> data-order_button_text="order_button_text ); ?>" /> + + + has_fields() || $gateway->get_description() ) : ?> +
    chosen ) : /* phpcs:ignore Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace */ ?>style="display:none;"> + payment_fields(); ?> +
    + +
  • diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/payment.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/payment.php new file mode 100644 index 0000000..a5467a7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/payment.php @@ -0,0 +1,61 @@ + +
    + cart->needs_payment() ) : ?> +
      + $gateway ) ); + } + } else { + echo '
    • ' . apply_filters( 'woocommerce_no_available_payment_methods_message', WC()->customer->get_billing_country() ? esc_html__( 'Sorry, it seems that there are no available payment methods for your state. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce' ) : esc_html__( 'Please fill in your details above to see available payment methods.', 'woocommerce' ) ) . '
    • '; // @codingStandardsIgnoreLine + } + ?> +
    + +
    + + + + + + + ' . esc_html( $order_button_text ) . '' ); // @codingStandardsIgnoreLine ?> + + + + +
    +
    + + + + + + + + + + cart->get_cart() as $cart_item_key => $cart_item ) { + $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); + + if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_checkout_cart_item_visible', true, $cart_item, $cart_item_key ) ) { + ?> + + + + + + + + + + + + + + cart->get_coupons() as $code => $coupon ) : ?> + + + + + + + cart->needs_shipping() && WC()->cart->show_shipping() ) : ?> + + + + + + + + + + cart->get_fees() as $fee ) : ?> + + + + + + + cart->display_prices_including_tax() ) : ?> + + cart->get_tax_totals() as $code => $tax ) : // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited ?> + + + + + + + + + + + + + + + + + + + + + + + +
    + get_name(), $cart_item, $cart_item_key ) . ' '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> + ' . sprintf( '× %s', $cart_item['quantity'] ) . '', $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> + + + cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
    name ); ?>
    label ); ?>formatted_amount ); ?>
    countries->tax_or_vat() ); ?>
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/terms.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/terms.php new file mode 100644 index 0000000..21ade90 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/checkout/terms.php @@ -0,0 +1,40 @@ + +
    + + + +

    + + +

    + +
    + + +
    + + get_id() ); + ?> + + has_status( 'failed' ) ) : ?> + +

    + +

    + + + + +

    + + + +

    + +
      + +
    • + + get_order_number(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
    • + +
    • + + get_date_created() ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
    • + + get_user_id() === get_current_user_id() && $order->get_billing_email() ) : ?> + + + +
    • + + get_formatted_order_total(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
    • + + get_payment_method_title() ) : ?> +
    • + + get_payment_method_title() ); ?> +
    • + + +
    + + + + get_payment_method(), $order->get_id() ); ?> + get_id() ); ?> + + + +

    + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-product-cat.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-product-cat.php new file mode 100644 index 0000000..e212f98 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-product-cat.php @@ -0,0 +1,57 @@ + +
  • > + +
  • diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-product.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-product.php new file mode 100644 index 0000000..e354ae2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-product.php @@ -0,0 +1,67 @@ +is_visible() ) { + return; +} +?> +
  • > + +
  • diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-single-product.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-single-product.php new file mode 100644 index 0000000..37a2c06 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-single-product.php @@ -0,0 +1,76 @@ + +
    > + + + +
    + +
    + + +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-widget-price-filter.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-widget-price-filter.php new file mode 100644 index 0000000..a491d34 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-widget-price-filter.php @@ -0,0 +1,40 @@ + + + +
    +
    + +
    + + + + + + +
    +
    +
    +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-widget-product.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-widget-product.php new file mode 100644 index 0000000..a64ff1e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-widget-product.php @@ -0,0 +1,43 @@ + +
  • + + + + get_image(); // PHPCS:Ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> + get_name() ); ?> + + + + get_average_rating() ); // PHPCS:Ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> + + + get_price_html(); // PHPCS:Ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> + + +
  • diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-widget-reviews.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-widget-reviews.php new file mode 100644 index 0000000..d46cbd5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/content-widget-reviews.php @@ -0,0 +1,34 @@ + +
  • + + + + get_image(); ?> + get_name(); ?> + + + comment_ID, 'rating', true ) ) ); ?> + + comment_ID ) ); ?> + + +
  • diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/admin-cancelled-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/admin-cancelled-order.php new file mode 100644 index 0000000..af11740 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/admin-cancelled-order.php @@ -0,0 +1,60 @@ + + + +

    get_order_number() ), esc_html( $order->get_formatted_billing_full_name() ) ); ?>

    + + + + +

    get_order_number() ), esc_html( $order->get_formatted_billing_full_name() ) ); ?>

    + + + + +

    get_formatted_billing_full_name() ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>

    + + + +

    get_billing_first_name() ) ); ?>

    +

    + + + +

    get_billing_first_name() ) ); ?>

    + +has_status( 'pending' ) ) { ?> +

    + array( + 'href' => array(), + ), + ) + ), + esc_html( get_bloginfo( 'name', 'display' ) ), + '' . esc_html__( 'Pay for this order', 'woocommerce' ) . '' + ); + ?> +

    + + +

    + get_date_created() ) ) ); + ?> +

    + + + +

    + +

    ' . esc_html( $user_login ) . '', make_clickable( esc_url( wc_get_page_permalink( 'myaccount' ) ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>

    + + +

    ' . esc_html( $user_pass ) . '' ); ?>

    + + + + + +

    get_billing_first_name() ) ); ?>

    +

    + +
    + +

    + + + + +

    get_billing_first_name() ) ); ?>

    +

    + + + + +

    get_billing_first_name() ) ); ?>

    + +

    get_order_number() ) ); ?>

    + + + + +

    get_billing_first_name() ) ); ?>

    + +

    + +

    + + + + + +

    + +

    + +

    +

    +

    + + + +

    + +get_formatted_billing_address(); +$shipping = $order->get_formatted_shipping_address(); + +?> + + + needs_shipping_address() && $shipping ) : ?> + + + +
    +

    + +
    + + get_billing_phone() ) : ?> +
    get_billing_phone() ); ?> + + get_billing_email() ) : ?> +
    get_billing_email() ); ?> + +
    +
    +

    + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-customer-details.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-customer-details.php new file mode 100644 index 0000000..70c42c2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-customer-details.php @@ -0,0 +1,31 @@ + + +
    +

    +
      + +
    • :
    • + +
    +
    + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-downloads.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-downloads.php new file mode 100644 index 0000000..6fce472 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-downloads.php @@ -0,0 +1,68 @@ +

    + + + + + $column_name ) : ?> + + + + + + + + $column_name ) : ?> + + + + +
    + + + + + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-footer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-footer.php new file mode 100644 index 0000000..4579924 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-footer.php @@ -0,0 +1,56 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-header.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-header.php new file mode 100644 index 0000000..23793c0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-header.php @@ -0,0 +1,65 @@ + + +> + + + <?php echo get_bloginfo( 'name', 'display' ); ?> + + ="0" marginwidth="0" topmargin="0" marginheight="0" offset="0"> +
    + + +
    +
    + ' . get_bloginfo( 'name', 'display' ) . '

    '; + } + ?> +
    + + + + + +
    + + + + + +
    +

    +
    + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-details.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-details.php new file mode 100644 index 0000000..d5b5966 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-details.php @@ -0,0 +1,114 @@ +get_items( apply_filters( 'woocommerce_purchase_order_item_types', 'line_item' ) ); +$show_purchase_note = $order->has_status( apply_filters( 'woocommerce_purchase_note_order_statuses', array( 'completed', 'processing' ) ) ); +$show_customer_details = is_user_logged_in() && $order->get_user_id() === get_current_user_id(); +$downloads = $order->get_downloadable_items(); +$show_downloads = $order->has_downloadable_item() && $order->is_download_permitted(); + +if ( $show_downloads ) { + wc_get_template( + 'order/order-downloads.php', + array( + 'downloads' => $downloads, + 'show_title' => true, + ) + ); +} +?> +
    + + +

    + +
    + + + + + + + + + + + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-styles.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-styles.php new file mode 100644 index 0000000..89c6aa4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-styles.php @@ -0,0 +1,229 @@ + +body { + padding: 0; +} + +#wrapper { + background-color: ; + margin: 0; + padding: 70px 0; + -webkit-text-size-adjust: none !important; + width: 100%; +} + +#template_container { + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1) !important; + background-color: ; + border: 1px solid ; + border-radius: 3px !important; +} + +#template_header { + background-color: ; + border-radius: 3px 3px 0 0 !important; + color: ; + border-bottom: 0; + font-weight: bold; + line-height: 100%; + vertical-align: middle; + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; +} + +#template_header h1, +#template_header h1 a { + color: ; + background-color: inherit; +} + +#template_header_image img { + margin-left: 0; + margin-right: 0; +} + +#template_footer td { + padding: 0; + border-radius: 6px; +} + +#template_footer #credit { + border: 0; + color: ; + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; + font-size: 12px; + line-height: 150%; + text-align: center; + padding: 24px 0; +} + +#template_footer #credit p { + margin: 0 0 16px; +} + +#body_content { + background-color: ; +} + +#body_content table td { + padding: 48px 48px 32px; +} + +#body_content table td td { + padding: 12px; +} + +#body_content table td th { + padding: 12px; +} + +#body_content td ul.wc-item-meta { + font-size: small; + margin: 1em 0 0; + padding: 0; + list-style: none; +} + +#body_content td ul.wc-item-meta li { + margin: 0.5em 0 0; + padding: 0; +} + +#body_content td ul.wc-item-meta li p { + margin: 0; +} + +#body_content p { + margin: 0 0 16px; +} + +#body_content_inner { + color: ; + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; + font-size: 14px; + line-height: 150%; + text-align: ; +} + +.td { + color: ; + border: 1px solid ; + vertical-align: middle; +} + +.address { + padding: 12px; + color: ; + border: 1px solid ; +} + +.text { + color: ; + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; +} + +.link { + color: ; +} + +#header_wrapper { + padding: 36px 48px; + display: block; +} + +h1 { + color: ; + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; + font-size: 30px; + font-weight: 300; + line-height: 150%; + margin: 0; + text-align: ; + text-shadow: 0 1px 0 ; +} + +h2 { + color: ; + display: block; + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; + font-size: 18px; + font-weight: bold; + line-height: 130%; + margin: 0 0 18px; + text-align: ; +} + +h3 { + color: ; + display: block; + font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; + font-size: 16px; + font-weight: bold; + line-height: 130%; + margin: 16px 0 8px; + text-align: ; +} + +a { + color: ; + font-weight: normal; + text-decoration: underline; +} + +img { + border: none; + display: inline-block; + font-size: 14px; + font-weight: bold; + height: auto; + outline: none; + text-decoration: none; + text-transform: capitalize; + vertical-align: middle; + margin-: 10px; + max-width: 100%; + height: auto; +} +get_order_number() ), esc_html( $order->get_formatted_billing_full_name() ) ) . "\n\n"; + +/* + * @hooked WC_Emails::order_details() Shows the order details table. + * @hooked WC_Structured_Data::generate_order_data() Generates structured data. + * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. + * @since 2.5.0 + */ +do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n----------------------------------------\n\n"; + +/* + * @hooked WC_Emails::order_meta() Shows order meta data. + */ +do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); + +/* + * @hooked WC_Emails::customer_details() Shows customer details + * @hooked WC_Emails::email_address() Shows email address + */ +do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/admin-failed-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/admin-failed-order.php new file mode 100644 index 0000000..90148e6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/admin-failed-order.php @@ -0,0 +1,58 @@ +get_order_number() ), esc_html( $order->get_formatted_billing_full_name() ) ) . "\n\n"; + +/* + * @hooked WC_Emails::order_details() Shows the order details table. + * @hooked WC_Structured_Data::generate_order_data() Generates structured data. + * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. + * @since 2.5.0 + */ +do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n----------------------------------------\n\n"; + +/* + * @hooked WC_Emails::order_meta() Shows order meta data. + */ +do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); + +/* + * @hooked WC_Emails::customer_details() Shows customer details + * @hooked WC_Emails::email_address() Shows email address + */ +do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/admin-new-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/admin-new-order.php new file mode 100644 index 0000000..97931f6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/admin-new-order.php @@ -0,0 +1,58 @@ +get_formatted_billing_full_name() ) ) . "\n\n"; + +/* + * @hooked WC_Emails::order_details() Shows the order details table. + * @hooked WC_Structured_Data::generate_order_data() Generates structured data. + * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. + * @since 2.5.0 + */ +do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n----------------------------------------\n\n"; + +/* + * @hooked WC_Emails::order_meta() Shows order meta data. + */ +do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); + +/* + * @hooked WC_Emails::customer_details() Shows customer details + * @hooked WC_Emails::email_address() Shows email address + */ +do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-completed-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-completed-order.php new file mode 100644 index 0000000..56f0071 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-completed-order.php @@ -0,0 +1,60 @@ +get_billing_first_name() ) ) . "\n\n"; +/* translators: %s: Site title */ +echo esc_html__( 'We have finished processing your order.', 'woocommerce' ) . "\n\n"; + +/* + * @hooked WC_Emails::order_details() Shows the order details table. + * @hooked WC_Structured_Data::generate_order_data() Generates structured data. + * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. + * @since 2.5.0 + */ +do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n----------------------------------------\n\n"; + +/* + * @hooked WC_Emails::order_meta() Shows order meta data. + */ +do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); + +/* + * @hooked WC_Emails::customer_details() Shows customer details + * @hooked WC_Emails::email_address() Shows email address + */ +do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-invoice.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-invoice.php new file mode 100644 index 0000000..a70e610 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-invoice.php @@ -0,0 +1,79 @@ +get_billing_first_name() ) ) . "\n\n"; + +if ( $order->has_status( 'pending' ) ) { + echo wp_kses_post( + sprintf( + /* translators: %1$s: Site title, %2$s: Order pay link */ + __( 'An order has been created for you on %1$s. Your invoice is below, with a link to make payment when you’re ready: %2$s', 'woocommerce' ), + esc_html( get_bloginfo( 'name', 'display' ) ), + esc_url( $order->get_checkout_payment_url() ) + ) + ) . "\n\n"; + +} else { + /* translators: %s: Order date */ + echo sprintf( esc_html__( 'Here are the details of your order placed on %s:', 'woocommerce' ), esc_html( wc_format_datetime( $order->get_date_created() ) ) ) . "\n\n"; +} + +/** + * Hook for the woocommerce_email_order_details. + * + * @hooked WC_Emails::order_details() Shows the order details table. + * @hooked WC_Structured_Data::generate_order_data() Generates structured data. + * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. + * @since 2.5.0 + */ +do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n----------------------------------------\n\n"; + +/** + * Hook for the woocommerce_email_order_meta. + * + * @hooked WC_Emails::order_meta() Shows order meta data. + */ +do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); + +/** + * Hook for woocommerce_email_customer_details + * + * @hooked WC_Emails::customer_details() Shows customer details + * @hooked WC_Emails::email_address() Shows email address + */ +do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-new-account.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-new-account.php new file mode 100644 index 0000000..56204d2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-new-account.php @@ -0,0 +1,44 @@ +get_billing_first_name() ) ) . "\n\n"; +echo esc_html__( 'The following note has been added to your order:', 'woocommerce' ) . "\n\n"; + +echo "----------\n\n"; + +echo wptexturize( $customer_note ) . "\n\n"; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped + +echo "----------\n\n"; + +echo esc_html__( 'As a reminder, here are your order details:', 'woocommerce' ) . "\n\n"; + +/* + * @hooked WC_Emails::order_details() Shows the order details table. + * @hooked WC_Structured_Data::generate_order_data() Generates structured data. + * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. + * @since 2.5.0 + */ +do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n----------------------------------------\n\n"; + +/* + * @hooked WC_Emails::order_meta() Shows order meta data. + */ +do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); + +/* + * @hooked WC_Emails::customer_details() Shows customer details + * @hooked WC_Emails::email_address() Shows email address + */ +do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-on-hold-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-on-hold-order.php new file mode 100644 index 0000000..b5dec0a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-on-hold-order.php @@ -0,0 +1,59 @@ +get_billing_first_name() ) ) . "\n\n"; +echo esc_html__( 'Thanks for your order. It’s on-hold until we confirm that payment has been received. In the meantime, here’s a reminder of what you ordered:', 'woocommerce' ) . "\n\n"; + +/* + * @hooked WC_Emails::order_details() Shows the order details table. + * @hooked WC_Structured_Data::generate_order_data() Generates structured data. + * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. + * @since 2.5.0 + */ +do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n----------------------------------------\n\n"; + +/* + * @hooked WC_Emails::order_meta() Shows order meta data. + */ +do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); + +/* + * @hooked WC_Emails::customer_details() Shows customer details + * @hooked WC_Emails::email_address() Shows email address + */ +do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-processing-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-processing-order.php new file mode 100644 index 0000000..fead3d7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-processing-order.php @@ -0,0 +1,60 @@ +get_billing_first_name() ) ) . "\n\n"; +/* translators: %s: Order number */ +echo sprintf( esc_html__( 'Just to let you know — we\'ve received your order #%s, and it is now being processed:', 'woocommerce' ), esc_html( $order->get_order_number() ) ) . "\n\n"; + +/* + * @hooked WC_Emails::order_details() Shows the order details table. + * @hooked WC_Structured_Data::generate_order_data() Generates structured data. + * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. + * @since 2.5.0 + */ +do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n----------------------------------------\n\n"; + +/* + * @hooked WC_Emails::order_meta() Shows order meta data. + */ +do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); + +/* + * @hooked WC_Emails::customer_details() Shows customer details + * @hooked WC_Emails::email_address() Shows email address + */ +do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-refunded-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-refunded-order.php new file mode 100644 index 0000000..a6626d3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-refunded-order.php @@ -0,0 +1,65 @@ +get_billing_first_name() ) . "\n\n"; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped +if ( $partial_refund ) { + /* translators: %s: Site title */ + echo sprintf( esc_html__( 'Your order on %s has been partially refunded. There are more details below for your reference:', 'woocommerce' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ) . "\n\n"; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped +} else { + /* translators: %s: Site title */ + echo sprintf( esc_html__( 'Your order on %s has been refunded. There are more details below for your reference:', 'woocommerce' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ) . "\n\n"; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped +} + +/* + * @hooked WC_Emails::order_details() Shows the order details table. + * @hooked WC_Structured_Data::generate_order_data() Generates structured data. + * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. + * @since 2.5.0 + */ +do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n----------------------------------------\n\n"; + +/* + * @hooked WC_Emails::order_meta() Shows order meta data. + */ +do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); + +/* + * @hooked WC_Emails::customer_details() Shows customer details + * @hooked WC_Emails::email_address() Shows email address + */ +do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-reset-password.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-reset-password.php new file mode 100644 index 0000000..efc4e5b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/customer-reset-password.php @@ -0,0 +1,43 @@ + $reset_key, 'id' => $user_id ), wc_get_endpoint_url( 'lost-password', '', wc_get_page_permalink( 'myaccount' ) ) ) ) . "\n\n"; // phpcs:ignore + +echo "\n\n----------------------------------------\n\n"; + +/** + * Show user-defined additional content - this is set in each email's settings. + */ +if ( $additional_content ) { + echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); + echo "\n\n----------------------------------------\n\n"; +} + +echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-addresses.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-addresses.php new file mode 100644 index 0000000..92ec35e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-addresses.php @@ -0,0 +1,38 @@ +#i', "\n", $order->get_formatted_billing_address() ) . "\n"; // WPCS: XSS ok. + +if ( $order->get_billing_phone() ) { + echo $order->get_billing_phone() . "\n"; // WPCS: XSS ok. +} + +if ( $order->get_billing_email() ) { + echo $order->get_billing_email() . "\n"; // WPCS: XSS ok. +} + +if ( ! wc_ship_to_billing_address_only() && $order->needs_shipping_address() ) { + $shipping = $order->get_formatted_shipping_address(); + + if ( $shipping ) { + echo "\n" . esc_html( wc_strtoupper( esc_html__( 'Shipping address', 'woocommerce' ) ) ) . "\n\n"; + echo preg_replace( '##i', "\n", $shipping ) . "\n"; // WPCS: XSS ok. + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-customer-details.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-customer-details.php new file mode 100644 index 0000000..e86c24a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-customer-details.php @@ -0,0 +1,26 @@ + $column_name ) { + echo wp_kses_post( $column_name ) . ': '; + + if ( has_action( 'woocommerce_email_downloads_column_' . $column_id ) ) { + do_action( 'woocommerce_email_downloads_column_' . $column_id, $download, $plain_text ); + } else { + switch ( $column_id ) { + case 'download-product': + echo esc_html( $download['product_name'] ); + break; + case 'download-file': + echo esc_html( $download['download_name'] ) . ' - ' . esc_url( $download['download_url'] ); + break; + case 'download-expires': + if ( ! empty( $download['access_expires'] ) ) { + echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $download['access_expires'] ) ) ); + } else { + esc_html_e( 'Never', 'woocommerce' ); + } + break; + } + } + echo "\n"; + } + echo "\n"; +} +echo '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-='; +echo "\n\n"; diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-order-details.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-order-details.php new file mode 100644 index 0000000..3a292aa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-order-details.php @@ -0,0 +1,54 @@ +get_order_number(), wc_format_datetime( $order->get_date_created() ) ) ) ) . "\n"; +echo "\n" . wc_get_email_order_items( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + $order, + array( + 'show_sku' => $sent_to_admin, + 'show_image' => false, + 'image_size' => array( 32, 32 ), + 'plain_text' => true, + 'sent_to_admin' => $sent_to_admin, + ) +); + +echo "==========\n\n"; + +$item_totals = $order->get_order_item_totals(); + +if ( $item_totals ) { + foreach ( $item_totals as $total ) { + echo wp_kses_post( $total['label'] . "\t " . $total['value'] ) . "\n"; + } +} + +if ( $order->get_customer_note() ) { + echo esc_html__( 'Note:', 'woocommerce' ) . "\t " . wp_kses_post( wptexturize( $order->get_customer_note() ) ) . "\n"; +} + +if ( $sent_to_admin ) { + /* translators: %s: Order link. */ + echo "\n" . sprintf( esc_html__( 'View order: %s', 'woocommerce' ), esc_url( $order->get_edit_order_url() ) ) . "\n"; +} + +do_action( 'woocommerce_email_after_order_table', $order, $sent_to_admin, $plain_text, $email ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-order-items.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-order-items.php new file mode 100644 index 0000000..bcd4466 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/plain/email-order-items.php @@ -0,0 +1,63 @@ + $item ) : + if ( apply_filters( 'woocommerce_order_item_visible', true, $item ) ) { + $product = $item->get_product(); + $sku = ''; + $purchase_note = ''; + + if ( is_object( $product ) ) { + $sku = $product->get_sku(); + $purchase_note = $product->get_purchase_note(); + } + + echo apply_filters( 'woocommerce_order_item_name', $item->get_name(), $item, false ); + if ( $show_sku && $sku ) { + echo ' (#' . $sku . ')'; + } + echo ' X ' . apply_filters( 'woocommerce_email_order_item_quantity', $item->get_quantity(), $item ); + echo ' = ' . $order->get_formatted_line_subtotal( $item ) . "\n"; + + // allow other plugins to add additional product information here + do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order, $plain_text ); + echo strip_tags( + wc_display_item_meta( + $item, + array( + 'before' => "\n- ", + 'separator' => "\n- ", + 'after' => '', + 'echo' => false, + 'autop' => false, + ) + ) + ); + + // allow other plugins to add additional product information here + do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order, $plain_text ); + } + // Note + if ( $show_purchase_note && $purchase_note ) { + echo "\n" . do_shortcode( wp_kses_post( $purchase_note ) ); + } + echo "\n\n"; +endforeach; diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/breadcrumb.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/breadcrumb.php new file mode 100644 index 0000000..3d6bc21 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/breadcrumb.php @@ -0,0 +1,46 @@ + $crumb ) { + + echo $before; + + if ( ! empty( $crumb[1] ) && sizeof( $breadcrumb ) !== $key + 1 ) { + echo '' . esc_html( $crumb[0] ) . ''; + } else { + echo esc_html( $crumb[0] ); + } + + echo $after; + + if ( sizeof( $breadcrumb ) !== $key + 1 ) { + echo $delimiter; + } + } + + echo $wrap_after; + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/form-login.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/form-login.php new file mode 100644 index 0000000..1c64a44 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/form-login.php @@ -0,0 +1,61 @@ + +> + + + + + +

    + + +

    +

    + + +

    +
    + + + +

    + + + + +

    +

    + +

    + +
    + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/quantity-input.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/quantity-input.php new file mode 100644 index 0000000..172fc85 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/quantity-input.php @@ -0,0 +1,49 @@ + + + +
    + + + + +
    + '; + break; + case 'twentyeleven': + echo ''; + get_sidebar( 'shop' ); + echo ''; + break; + case 'twentytwelve': + echo ''; + break; + case 'twentythirteen': + echo ''; + break; + case 'twentyfourteen': + echo ''; + get_sidebar( 'content' ); + break; + case 'twentyfifteen': + echo ''; + break; + case 'twentysixteen': + echo ''; + break; + default: + echo ''; + break; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/wrapper-start.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/wrapper-start.php new file mode 100644 index 0000000..aceb891 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/global/wrapper-start.php @@ -0,0 +1,49 @@ +
    '; + break; + case 'twentyeleven': + echo '
    '; + break; + case 'twentytwelve': + echo '
    '; + break; + case 'twentythirteen': + echo '
    '; + break; + case 'twentyfourteen': + echo '
    '; + break; + case 'twentyfifteen': + echo '
    '; + break; + case 'twentysixteen': + echo '
    '; + break; + default: + echo '
    '; + break; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/add-to-cart.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/add-to-cart.php new file mode 100644 index 0000000..9e4dda0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/add-to-cart.php @@ -0,0 +1,36 @@ +%s', + esc_url( $product->add_to_cart_url() ), + esc_attr( isset( $args['quantity'] ) ? $args['quantity'] : 1 ), + esc_attr( isset( $args['class'] ) ? $args['class'] : 'button' ), + isset( $args['attributes'] ) ? wc_implode_html_attributes( $args['attributes'] ) : '', + esc_html( $product->add_to_cart_text() ) + ), + $product, + $args +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/loop-end.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/loop-end.php new file mode 100644 index 0000000..802acb9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/loop-end.php @@ -0,0 +1,22 @@ + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/loop-start.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/loop-start.php new file mode 100644 index 0000000..b2d4960 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/loop-start.php @@ -0,0 +1,22 @@ + +
      diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/no-products-found.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/no-products-found.php new file mode 100644 index 0000000..906edb3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/no-products-found.php @@ -0,0 +1,21 @@ + +

      diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/orderby.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/orderby.php new file mode 100644 index 0000000..5b2c1f8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/orderby.php @@ -0,0 +1,31 @@ + +
      + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/pagination.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/pagination.php new file mode 100644 index 0000000..9d61f87 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/pagination.php @@ -0,0 +1,51 @@ + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/price.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/price.php new file mode 100644 index 0000000..951ca17 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/price.php @@ -0,0 +1,27 @@ + + +get_price_html() ) : ?> + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/rating.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/rating.php new file mode 100644 index 0000000..9b29aca --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/rating.php @@ -0,0 +1,28 @@ +get_average_rating() ); // WordPress.XSS.EscapeOutput.OutputNotEscaped. diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/result-count.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/result-count.php new file mode 100644 index 0000000..faec643 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/result-count.php @@ -0,0 +1,40 @@ + +

      + +

      diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/sale-flash.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/sale-flash.php new file mode 100644 index 0000000..2b35f76 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/loop/sale-flash.php @@ -0,0 +1,32 @@ + +is_on_sale() ) : ?> + + ' . esc_html__( 'Sale!', 'woocommerce' ) . '', $post, $product ); ?> + + array( + 'href' => array(), + ), +); +?> + +

      + Log out)', 'woocommerce' ), $allowed_html ), + '' . esc_html( $current_user->display_name ) . '', + esc_url( wc_logout_url() ) + ); + ?> +

      + +

      + recent orders, manage your billing address, and edit your password and account details.', 'woocommerce' ); + if ( wc_shipping_enabled() ) { + /* translators: 1: Orders URL 2: Addresses URL 3: Account URL. */ + $dashboard_desc = __( 'From your account dashboard you can view your recent orders, manage your shipping and billing addresses, and edit your password and account details.', 'woocommerce' ); + } + printf( + wp_kses( $dashboard_desc, $allowed_html ), + esc_url( wc_get_endpoint_url( 'orders' ) ), + esc_url( wc_get_endpoint_url( 'edit-address' ) ), + esc_url( wc_get_endpoint_url( 'edit-account' ) ) + ); + ?> +

      + +customer->get_downloadable_products(); +$has_downloads = (bool) $downloads; + +do_action( 'woocommerce_before_account_downloads', $has_downloads ); ?> + + + + + + + + + + +
      + + + + +
      + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-add-payment-method.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-add-payment-method.php new file mode 100644 index 0000000..71b859a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-add-payment-method.php @@ -0,0 +1,61 @@ +payment_gateways->get_available_payment_gateways(); + +if ( $available_gateways ) : ?> +
      +
      +
        + set_current(); + } + + foreach ( $available_gateways as $gateway ) { + ?> +
      • + chosen, true ); ?> /> + + has_fields() || $gateway->get_description() ) { + echo ''; + } + ?> +
      • + +
      + + + +
      + + + +
      +
      + + +

      + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-edit-account.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-edit-account.php new file mode 100644 index 0000000..eb5dfd1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-edit-account.php @@ -0,0 +1,76 @@ + + + > + + + +

      + + +

      +

      + + +

      +
      + +

      + + +

      +
      + +

      + + +

      + +
      + + +

      + + +

      +

      + + +

      +

      + + +

      +
      +
      + + + +

      + + + +

      + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-edit-address.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-edit-address.php new file mode 100644 index 0000000..6916bef --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-edit-address.php @@ -0,0 +1,56 @@ + + + + + + +
      + +

      + +
      + + +
      + $field ) { + woocommerce_form_field( $key, $field, wc_get_post_data_by_key( $key, $field['value'] ) ); + } + ?> +
      + + + +

      + + + +

      +
      + + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-login.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-login.php new file mode 100644 index 0000000..6680179 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-login.php @@ -0,0 +1,119 @@ + + + + +
      + +
      + + + +

      + + + + + +

      + + +

      +

      + + +

      + + + +

      + + + +

      +

      + +

      + + + + + + + +
      + +
      + +

      + +
      > + + + + + +

      + + +

      + + + +

      + + +

      + + + +

      + + +

      + + + +

      + + + + + +

      + + +

      + + + + + +
      + +
      + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-lost-password.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-lost-password.php new file mode 100644 index 0000000..15fc984 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/form-lost-password.php @@ -0,0 +1,45 @@ + + +
      + +

      + +

      + + +

      + +
      + + + +

      + + +

      + + + + + + +
      + +

      + +

      + + +

      +

      + + +

      + + + + +
      + + + +

      + + +

      + + + + + + + + +

      + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/my-account.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/my-account.php new file mode 100644 index 0000000..9a4f85f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/my-account.php @@ -0,0 +1,36 @@ + + +
      + +
      diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/my-address.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/my-address.php new file mode 100644 index 0000000..5cd3161 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/my-address.php @@ -0,0 +1,77 @@ + __( 'Billing address', 'woocommerce' ), + 'shipping' => __( 'Shipping address', 'woocommerce' ), + ), + $customer_id + ); +} else { + $get_addresses = apply_filters( + 'woocommerce_my_account_get_addresses', + array( + 'billing' => __( 'Billing address', 'woocommerce' ), + ), + $customer_id + ); +} + +$oldcol = 1; +$col = 1; +?> + +

      + +

      + + +
      + + + $address_title ) : ?> + + +
      +
      +

      + +
      +
      + +
      +
      + + + + +
      + customer->get_downloadable_products(); + +if ( $downloads ) : ?> + + + +

      + +
        + +
      • + ' . sprintf( _n( '%s download remaining', '%s downloads remaining', $download['downloads_remaining'], 'woocommerce' ), $download['downloads_remaining'] ) . ' ', $download ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } + + echo apply_filters( 'woocommerce_available_download_link', '' . $download['download_name'] . '', $download ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + do_action( 'woocommerce_available_download_end', $download ); + ?> +
      • + +
      + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/my-orders.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/my-orders.php new file mode 100644 index 0000000..77761e0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/my-orders.php @@ -0,0 +1,95 @@ + esc_html__( 'Order', 'woocommerce' ), + 'order-date' => esc_html__( 'Date', 'woocommerce' ), + 'order-status' => esc_html__( 'Status', 'woocommerce' ), + 'order-total' => esc_html__( 'Total', 'woocommerce' ), + 'order-actions' => ' ', + ) +); + +$customer_orders = get_posts( + apply_filters( + 'woocommerce_my_account_my_orders_query', + array( + 'numberposts' => $order_count, + 'meta_key' => '_customer_user', + 'meta_value' => get_current_user_id(), + 'post_type' => wc_get_order_types( 'view-orders' ), + 'post_status' => array_keys( wc_get_order_statuses() ), + ) + ) +); + +if ( $customer_orders ) : ?> + +

      + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-order-details.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-order-details.php new file mode 100644 index 0000000..2184d69 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-order-details.php @@ -0,0 +1,90 @@ + + +

    + get_edit_order_url() ) . '">'; + $after = ''; + } else { + $before = ''; + $after = ''; + } + /* translators: %s: Order ID. */ + echo wp_kses_post( $before . sprintf( __( '[Order #%s]', 'woocommerce' ) . $after . ' ()', $order->get_order_number(), $order->get_date_created()->format( 'c' ), wc_format_datetime( $order->get_date_created() ) ) ); + ?> +

    + +
    + + + + + + + + + + $sent_to_admin, + 'show_image' => false, + 'image_size' => array( 32, 32 ), + 'plain_text' => $plain_text, + 'sent_to_admin' => $sent_to_admin, + ) + ); + ?> + + + get_order_item_totals(); + + if ( $item_totals ) { + $i = 0; + foreach ( $item_totals as $total ) { + $i++; + ?> + + + + + get_customer_note() ) { + ?> + + + + + + +
    get_customer_note() ) ) ); ?>
    +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-order-items.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-order-items.php new file mode 100644 index 0000000..74bc9c1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/emails/email-order-items.php @@ -0,0 +1,104 @@ + $item ) : + $product = $item->get_product(); + $sku = ''; + $purchase_note = ''; + $image = ''; + + if ( ! apply_filters( 'woocommerce_order_item_visible', true, $item ) ) { + continue; + } + + if ( is_object( $product ) ) { + $sku = $product->get_sku(); + $purchase_note = $product->get_purchase_note(); + $image = $product->get_image( $image_size ); + } + + ?> +
    + get_name(), $item, false ) ); + + // SKU. + if ( $show_sku && $sku ) { + echo wp_kses_post( ' (#' . $sku . ')' ); + } + + // allow other plugins to add additional product information here. + do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order, $plain_text ); + + wc_display_item_meta( + $item, + array( + 'label_before' => '', + ) + ); + + // allow other plugins to add additional product information here. + do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order, $plain_text ); + + ?> + + get_quantity(); + $refunded_qty = $order->get_qty_refunded_for_item( $item_id ); + + if ( $refunded_qty ) { + $qty_display = '' . esc_html( $qty ) . ' ' . esc_html( $qty - ( $refunded_qty * -1 ) ) . ''; + } else { + $qty_display = esc_html( $qty ); + } + echo wp_kses_post( apply_filters( 'woocommerce_email_order_item_quantity', $qty_display, $item ) ); + ?> + + get_formatted_line_subtotal( $item ) ); ?> +
    + +
    + + + + $column_name ) : ?> + + + + + + + get_item_count(); + ?> + + $column_name ) : ?> + + + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/navigation.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/navigation.php new file mode 100644 index 0000000..8fc0db0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/navigation.php @@ -0,0 +1,35 @@ + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/orders.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/orders.php new file mode 100644 index 0000000..10fcadc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/orders.php @@ -0,0 +1,105 @@ + + + + + + + + $column_name ) : ?> + + + + + + + orders as $customer_order ) { + $order = wc_get_order( $customer_order ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + $item_count = $order->get_item_count() - $order->get_item_count_refunded(); + ?> + + $column_name ) : ?> + + + + + + + + + + max_num_pages ) : ?> +
    + + + + + max_num_pages ) !== $current_page ) : ?> + + +
    + + + +
    + + +
    + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/payment-methods.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/payment-methods.php new file mode 100644 index 0000000..8c6ad65 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/payment-methods.php @@ -0,0 +1,78 @@ + + + + + + + + $column_name ) : ?> + + + + + $methods ) : // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited ?> + + + $column_name ) : ?> + + + + + + + + + +

    + + + + + +payment_gateways->get_available_payment_gateways() ) : ?> + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/view-order.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/view-order.php new file mode 100644 index 0000000..2691e3d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/myaccount/view-order.php @@ -0,0 +1,56 @@ +get_customer_order_notes(); +?> +

    +' . $order->get_order_number() . '', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + '' . wc_format_datetime( $order->get_date_created() ) . '', // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + '' . wc_get_order_status_name( $order->get_status() ) . '' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +); +?> +

    + + +

    +
      + +
    1. +
      +
      +

      comment_date ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>

      +
      + comment_content ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
      +
      +
      +
      +
      +
    2. + +
    + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/notices/error.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/notices/error.php new file mode 100644 index 0000000..fe4af62 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/notices/error.php @@ -0,0 +1,33 @@ + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/notices/notice.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/notices/notice.php new file mode 100644 index 0000000..4e611df --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/notices/notice.php @@ -0,0 +1,32 @@ + + + +
    > + +
    + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/notices/success.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/notices/success.php new file mode 100644 index 0000000..e8643e5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/notices/success.php @@ -0,0 +1,32 @@ + + + +
    role="alert"> + +
    + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/form-tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/form-tracking.php new file mode 100644 index 0000000..d26f1a0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/form-tracking.php @@ -0,0 +1,34 @@ + + +
    + +

    + +

    +

    +
    + +

    + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-again.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-again.php new file mode 100644 index 0000000..f7bc224 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-again.php @@ -0,0 +1,23 @@ + + +

    + +

    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-details-customer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-details-customer.php new file mode 100644 index 0000000..62db640 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-details-customer.php @@ -0,0 +1,62 @@ +needs_shipping_address(); +?> +
    + + + +
    +
    + + + +

    + +
    + get_formatted_billing_address( esc_html__( 'N/A', 'woocommerce' ) ) ); ?> + + get_billing_phone() ) : ?> +

    get_billing_phone() ); ?>

    + + + get_billing_email() ) : ?> + + +
    + + + +
    + +
    +

    +
    + get_formatted_shipping_address( esc_html__( 'N/A', 'woocommerce' ) ) ); ?> +
    +
    + +
    + + + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-details-item.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-details-item.php new file mode 100644 index 0000000..7894d37 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-details-item.php @@ -0,0 +1,68 @@ + +
    + is_visible(); + $product_permalink = apply_filters( 'woocommerce_order_item_permalink', $is_visible ? $product->get_permalink( $item ) : '', $item, $order ); + + echo apply_filters( 'woocommerce_order_item_name', $product_permalink ? sprintf( '%s', $product_permalink, $item->get_name() ) : $item->get_name(), $item, $is_visible ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + $qty = $item->get_quantity(); + $refunded_qty = $order->get_qty_refunded_for_item( $item_id ); + + if ( $refunded_qty ) { + $qty_display = '' . esc_html( $qty ) . ' ' . esc_html( $qty - ( $refunded_qty * -1 ) ) . ''; + } else { + $qty_display = esc_html( $qty ); + } + + echo apply_filters( 'woocommerce_order_item_quantity_html', ' ' . sprintf( '× %s', $qty_display ) . '', $item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order, false ); + + wc_display_item_meta( $item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order, false ); + ?> + + get_formatted_line_subtotal( $item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
    + + + + + + + + + + $item ) { + $product = $item->get_product(); + + wc_get_template( + 'order/order-details-item.php', + array( + 'order' => $order, + 'item_id' => $item_id, + 'item' => $item, + 'show_purchase_note' => $show_purchase_note, + 'purchase_note' => $product ? $product->get_purchase_note() : '', + 'product' => $product, + ) + ); + } + + do_action( 'woocommerce_order_details_after_order_table_items', $order ); + ?> + + + + get_order_item_totals() as $key => $total ) { + ?> + + + + + + get_customer_note() ) : ?> + + + + + + +
    get_customer_note() ) ) ); ?>
    + + + + + $order ) ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-downloads.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-downloads.php new file mode 100644 index 0000000..9566cd3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/order-downloads.php @@ -0,0 +1,73 @@ + +
    + +

    + + + + + + $column_name ) : ?> + + + + + + + + $column_name ) : ?> + + + + +
    + ' . esc_html( $download['product_name'] ) . ''; + } else { + echo esc_html( $download['product_name'] ); + } + break; + case 'download-file': + echo '' . esc_html( $download['download_name'] ) . ''; + break; + case 'download-remaining': + echo is_numeric( $download['downloads_remaining'] ) ? esc_html( $download['downloads_remaining'] ) : esc_html__( '∞', 'woocommerce' ); + break; + case 'download-expires': + if ( ! empty( $download['access_expires'] ) ) { + echo ''; + } else { + esc_html_e( 'Never', 'woocommerce' ); + } + break; + } + } + ?> +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/tracking.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/tracking.php new file mode 100644 index 0000000..7e9d554 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/order/tracking.php @@ -0,0 +1,60 @@ +get_customer_order_notes(); +?> + +

    + ' . $order->get_order_number() . '', + '' . wc_format_datetime( $order->get_date_created() ) . '', + '' . wc_get_order_status_name( $order->get_status() ) . '' + ) + ) + ); + ?> +

    + + +

    +
      + +
    1. +
      +
      +

      comment_date ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>

      +
      + comment_content ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> +
      +
      +
      +
      +
      +
    2. + +
    + + +get_id() ); ?> diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/product-searchform.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/product-searchform.php new file mode 100644 index 0000000..c6c92bd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/product-searchform.php @@ -0,0 +1,28 @@ + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product-reviews.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product-reviews.php new file mode 100644 index 0000000..995a11e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product-reviews.php @@ -0,0 +1,145 @@ + +
    +
    +

    + get_review_count(); + if ( $count && wc_review_ratings_enabled() ) { + /* translators: 1: reviews count 2: product name */ + $reviews_title = sprintf( esc_html( _n( '%1$s review for %2$s', '%1$s reviews for %2$s', $count, 'woocommerce' ) ), esc_html( $count ), '' . get_the_title() . '' ); + echo apply_filters( 'woocommerce_reviews_title', $reviews_title, $count, $product ); // WPCS: XSS ok. + } else { + esc_html_e( 'Reviews', 'woocommerce' ); + } + ?> +

    + + +
      + 'woocommerce_comments' ) ) ); ?> +
    + + 1 && get_option( 'page_comments' ) ) : + echo ''; + endif; + ?> + +

    + +
    + + get_id() ) ) : ?> +
    +
    + have_comments() ? esc_html__( 'Add a review', 'woocommerce' ) : sprintf( esc_html__( 'Be the first to review “%s”', 'woocommerce' ), get_the_title() ), + /* translators: %s is product title */ + 'title_reply_to' => esc_html__( 'Leave a Reply to %s', 'woocommerce' ), + 'title_reply_before' => '', + 'title_reply_after' => '', + 'comment_notes_after' => '', + 'label_submit' => esc_html__( 'Submit', 'woocommerce' ), + 'logged_in_as' => '', + 'comment_field' => '', + ); + + $name_email_required = (bool) get_option( 'require_name_email', 1 ); + $fields = array( + 'author' => array( + 'label' => __( 'Name', 'woocommerce' ), + 'type' => 'text', + 'value' => $commenter['comment_author'], + 'required' => $name_email_required, + ), + 'email' => array( + 'label' => __( 'Email', 'woocommerce' ), + 'type' => 'email', + 'value' => $commenter['comment_author_email'], + 'required' => $name_email_required, + ), + ); + + $comment_form['fields'] = array(); + + foreach ( $fields as $key => $field ) { + $field_html = '

    '; + $field_html .= '

    '; + + $comment_form['fields'][ $key ] = $field_html; + } + + $account_page_url = wc_get_page_permalink( 'myaccount' ); + if ( $account_page_url ) { + /* translators: %s opening and closing link tags respectively */ + $comment_form['must_log_in'] = ''; + } + + if ( wc_review_ratings_enabled() ) { + $comment_form['comment_field'] = '
    '; + } + + $comment_form['comment_field'] .= '

    '; + + comment_form( apply_filters( 'woocommerce_product_review_comment_form_args', $comment_form ) ); + ?> +
    +
    + +

    + + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product.php new file mode 100644 index 0000000..39eeb1d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product.php @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + +
    + + + + + + + +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/grouped.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/grouped.php new file mode 100644 index 0000000..39df2ce --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/grouped.php @@ -0,0 +1,126 @@ + + +
    + + + get_id() ); + $quantites_required = $quantites_required || ( $grouped_product_child->is_purchasable() && ! $grouped_product_child->has_options() ); + $post = $post_object; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + setup_postdata( $post ); + + if ( $grouped_product_child->is_in_stock() ) { + $show_add_to_cart_button = true; + } + + echo ''; + + // Output columns for each product. + foreach ( $grouped_product_columns as $column_id ) { + do_action( 'woocommerce_grouped_product_list_before_' . $column_id, $grouped_product_child ); + + switch ( $column_id ) { + case 'quantity': + ob_start(); + + if ( ! $grouped_product_child->is_purchasable() || $grouped_product_child->has_options() || ! $grouped_product_child->is_in_stock() ) { + woocommerce_template_loop_add_to_cart(); + } elseif ( $grouped_product_child->is_sold_individually() ) { + echo ''; + } else { + do_action( 'woocommerce_before_add_to_cart_quantity' ); + + woocommerce_quantity_input( + array( + 'input_name' => 'quantity[' . $grouped_product_child->get_id() . ']', + 'input_value' => isset( $_POST['quantity'][ $grouped_product_child->get_id() ] ) ? wc_stock_amount( wc_clean( wp_unslash( $_POST['quantity'][ $grouped_product_child->get_id() ] ) ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Missing + 'min_value' => apply_filters( 'woocommerce_quantity_input_min', 0, $grouped_product_child ), + 'max_value' => apply_filters( 'woocommerce_quantity_input_max', $grouped_product_child->get_max_purchase_quantity(), $grouped_product_child ), + 'placeholder' => '0', + ) + ); + + do_action( 'woocommerce_after_add_to_cart_quantity' ); + } + + $value = ob_get_clean(); + break; + case 'label': + $value = ''; + break; + case 'price': + $value = $grouped_product_child->get_price_html() . wc_get_stock_html( $grouped_product_child ); + break; + default: + $value = ''; + break; + } + + echo ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + do_action( 'woocommerce_grouped_product_list_after_' . $column_id, $grouped_product_child ); + } + + echo ''; + } + $post = $previous_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + setup_postdata( $post ); + + do_action( 'woocommerce_grouped_product_list_after', $grouped_product_columns, $quantites_required, $product ); + ?> + +
    ' . apply_filters( 'woocommerce_grouped_product_list_column_' . $column_id, $value, $grouped_product_child ) . '
    + + + + + + + + + + + + +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/simple.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/simple.php new file mode 100644 index 0000000..494ece1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/simple.php @@ -0,0 +1,56 @@ +is_purchasable() ) { + return; +} + +echo wc_get_stock_html( $product ); // WPCS: XSS ok. + +if ( $product->is_in_stock() ) : ?> + + + +
    + + + apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $product ), + 'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ), + 'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( wp_unslash( $_POST['quantity'] ) ) : $product->get_min_purchase_quantity(), // WPCS: CSRF ok, input var ok. + ) + ); + + do_action( 'woocommerce_after_add_to_cart_quantity' ); + ?> + + + + +
    + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/variable.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/variable.php new file mode 100644 index 0000000..4d14248 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/variable.php @@ -0,0 +1,84 @@ + + +
    + + + +

    + + + + $options ) : ?> + + + + + + +
    + $options, + 'attribute' => $attribute_name, + 'product' => $product, + ) + ); + echo end( $attribute_keys ) === $attribute_name ? wp_kses_post( apply_filters( 'woocommerce_reset_variations_link', '' . esc_html__( 'Clear', 'woocommerce' ) . '' ) ) : ''; + ?> +
    + +
    + +
    + + + +
    + + +
    + + + apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $product ), + 'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ), + 'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( wp_unslash( $_POST['quantity'] ) ) : $product->get_min_purchase_quantity(), // WPCS: CSRF ok, input var ok. + ) + ); + + do_action( 'woocommerce_after_add_to_cart_quantity' ); + ?> + + + + + + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/variation.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/variation.php new file mode 100644 index 0000000..af3dde3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/add-to-cart/variation.php @@ -0,0 +1,23 @@ + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/meta.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/meta.php new file mode 100644 index 0000000..68a7e0f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/meta.php @@ -0,0 +1,40 @@ + +
    + + + + get_sku() || $product->is_type( 'variable' ) ) ) : ?> + + get_sku() ) ? $sku : esc_html__( 'N/A', 'woocommerce' ); ?> + + + + get_id(), ', ', '' . _n( 'Category:', 'Categories:', count( $product->get_category_ids() ), 'woocommerce' ) . ' ', '' ); ?> + + get_id(), ', ', '' . _n( 'Tag:', 'Tags:', count( $product->get_tag_ids() ), 'woocommerce' ) . ' ', '' ); ?> + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/photoswipe.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/photoswipe.php new file mode 100644 index 0000000..761b0b1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/photoswipe.php @@ -0,0 +1,56 @@ + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/price.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/price.php new file mode 100644 index 0000000..38e6d4d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/price.php @@ -0,0 +1,25 @@ + +

    get_price_html(); ?>

    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/product-attributes.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/product-attributes.php new file mode 100644 index 0000000..86faf52 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/product-attributes.php @@ -0,0 +1,33 @@ + + + $product_attribute ) : ?> + + + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/product-image.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/product-image.php new file mode 100644 index 0000000..0399028 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/product-image.php @@ -0,0 +1,55 @@ +get_image_id(); +$wrapper_classes = apply_filters( + 'woocommerce_single_product_image_gallery_classes', + array( + 'woocommerce-product-gallery', + 'woocommerce-product-gallery--' . ( $product->get_image_id() ? 'with-images' : 'without-images' ), + 'woocommerce-product-gallery--columns-' . absint( $columns ), + 'images', + ) +); +?> +
    + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/product-thumbnails.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/product-thumbnails.php new file mode 100644 index 0000000..cec3f34 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/product-thumbnails.php @@ -0,0 +1,33 @@ +get_gallery_image_ids(); + +if ( $attachment_ids && $product->get_image_id() ) { + foreach ( $attachment_ids as $attachment_id ) { + echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', wc_get_gallery_image_html( $attachment_id ), $attachment_id ); // phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/rating.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/rating.php new file mode 100644 index 0000000..a758f8b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/rating.php @@ -0,0 +1,43 @@ +get_rating_count(); +$review_count = $product->get_review_count(); +$average = $product->get_average_rating(); + +if ( $rating_count > 0 ) : ?> + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/related.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/related.php new file mode 100644 index 0000000..a7d3a3e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/related.php @@ -0,0 +1,54 @@ + + + + comment_ID ); + +if ( '0' === $comment->comment_approved ) { ?> + +

    + + + +

    + + + +

    + + (' . esc_attr__( 'verified owner', 'woocommerce' ) . ') '; + } + + ?> + +

    + + comment_ID, 'rating', true ) ); + +if ( $rating && wc_review_ratings_enabled() ) { + echo wc_get_rating_html( $rating ); // WPCS: XSS ok. +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/review.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/review.php new file mode 100644 index 0000000..cc22770 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/review.php @@ -0,0 +1,67 @@ + +
  • id="li-comment-"> + +
    + + + +
    + + + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/sale-flash.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/sale-flash.php new file mode 100644 index 0000000..d3ce965 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/sale-flash.php @@ -0,0 +1,32 @@ + +is_on_sale() ) : ?> + + ' . esc_html__( 'Sale!', 'woocommerce' ) . '', $post, $product ); ?> + + post_excerpt ); + +if ( ! $short_description ) { + return; +} + +?> +
    + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/stock.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/stock.php new file mode 100644 index 0000000..d8b1477 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/stock.php @@ -0,0 +1,23 @@ + +

    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/tabs/additional-information.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/tabs/additional-information.php new file mode 100644 index 0000000..f857b0c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/tabs/additional-information.php @@ -0,0 +1,30 @@ + + + +

    + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/tabs/description.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/tabs/description.php new file mode 100644 index 0000000..e7018a7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/tabs/description.php @@ -0,0 +1,30 @@ + + + +

    + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/tabs/tabs.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/tabs/tabs.php new file mode 100644 index 0000000..819943c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/tabs/tabs.php @@ -0,0 +1,56 @@ + + +
    +
      + $product_tab ) : ?> + + +
    + $product_tab ) : ?> +
    + +
    + + + +
    + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/title.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/title.php new file mode 100644 index 0000000..6fd646f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/title.php @@ -0,0 +1,22 @@ +', '' ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/up-sells.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/up-sells.php new file mode 100644 index 0000000..36e5ed4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/templates/single-product/up-sells.php @@ -0,0 +1,54 @@ + + +
    + +

    + + + + + + + get_id() ); + + setup_postdata( $GLOBALS['post'] =& $post_object ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited, Squiz.PHP.DisallowMultipleAssignments.Found + + wc_get_template_part( 'content', 'product' ); + ?> + + + + + +
    + + get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_attribute_taxonomies';" ) ) { + $wc_attributes = array_filter( (array) $wpdb->get_col( "SELECT attribute_name FROM {$wpdb->prefix}woocommerce_attribute_taxonomies;" ) ); + } else { + $wc_attributes = array(); + } + + // Tables. + WC_Install::drop_tables(); + + // Delete options. + $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'woocommerce\_%';" ); + $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'widget\_woocommerce\_%';" ); + + // Delete usermeta. + $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key LIKE 'woocommerce\_%';" ); + + // Delete posts + data. + $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE post_type IN ( 'product', 'product_variation', 'shop_coupon', 'shop_order', 'shop_order_refund' );" ); + $wpdb->query( "DELETE meta FROM {$wpdb->postmeta} meta LEFT JOIN {$wpdb->posts} posts ON posts.ID = meta.post_id WHERE posts.ID IS NULL;" ); + + $wpdb->query( "DELETE FROM {$wpdb->comments} WHERE comment_type IN ( 'order_note' );" ); + $wpdb->query( "DELETE meta FROM {$wpdb->commentmeta} meta LEFT JOIN {$wpdb->comments} comments ON comments.comment_ID = meta.comment_id WHERE comments.comment_ID IS NULL;" ); + + $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_order_items" ); + $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_order_itemmeta" ); + + // Delete terms if > WP 4.2 (term splitting was added in 4.2). + if ( version_compare( $wp_version, '4.2', '>=' ) ) { + // Delete term taxonomies. + foreach ( array( 'product_cat', 'product_tag', 'product_shipping_class', 'product_type' ) as $_taxonomy ) { + $wpdb->delete( + $wpdb->term_taxonomy, + array( + 'taxonomy' => $_taxonomy, + ) + ); + } + + // Delete term attributes. + foreach ( $wc_attributes as $_taxonomy ) { + $wpdb->delete( + $wpdb->term_taxonomy, + array( + 'taxonomy' => 'pa_' . $_taxonomy, + ) + ); + } + + // Delete orphan relationships. + $wpdb->query( "DELETE tr FROM {$wpdb->term_relationships} tr LEFT JOIN {$wpdb->posts} posts ON posts.ID = tr.object_id WHERE posts.ID IS NULL;" ); + + // Delete orphan terms. + $wpdb->query( "DELETE t FROM {$wpdb->terms} t LEFT JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id WHERE tt.term_id IS NULL;" ); + + // Delete orphan term meta. + if ( ! empty( $wpdb->termmeta ) ) { + $wpdb->query( "DELETE tm FROM {$wpdb->termmeta} tm LEFT JOIN {$wpdb->term_taxonomy} tt ON tm.term_id = tt.term_id WHERE tt.term_id IS NULL;" ); + } + } + + // Clear any cached data that has been removed. + wp_cache_flush(); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/autoload.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/autoload.php new file mode 100644 index 0000000..6ec5465 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/autoload.php @@ -0,0 +1,7 @@ +io = $io; + } + + /** + * Dump the autoloader. + * + * @param Config $config Config object. + * @param InstalledRepositoryInterface $localRepo Installed Reposetories object. + * @param PackageInterface $mainPackage Main Package object. + * @param InstallationManager $installationManager Manager for installing packages. + * @param string $targetDir Path to the current target directory. + * @param bool $scanPsr0Packages Whether to search for packages. Currently hard coded to always be false. + * @param string $suffix The autoloader suffix. + */ + public function dump( + Config $config, + InstalledRepositoryInterface $localRepo, + PackageInterface $mainPackage, + InstallationManager $installationManager, + $targetDir, + $scanPsr0Packages = null, // Not used we always optimize. + $suffix = null + ) { + + $filesystem = new Filesystem(); + $filesystem->ensureDirectoryExists( $config->get( 'vendor-dir' ) ); + + $basePath = $filesystem->normalizePath( realpath( getcwd() ) ); + $vendorPath = $filesystem->normalizePath( realpath( $config->get( 'vendor-dir' ) ) ); + $targetDir = $vendorPath . '/' . $targetDir; + $filesystem->ensureDirectoryExists( $targetDir ); + + $packageMap = $this->buildPackageMap( $installationManager, $mainPackage, $localRepo->getCanonicalPackages() ); + $autoloads = $this->parseAutoloads( $packageMap, $mainPackage ); + + $classMap = $this->getClassMap( $autoloads, $filesystem, $vendorPath, $basePath ); + $fileMap = $this->getFileMap( $autoloads, $filesystem, $vendorPath, $basePath ); + + // Remove a file that was generated in versions 2.0.0 to 2.1.0. + $filesystem->remove( $vendorPath . '/autoload_functions.php' ); + + // Generate the files. + file_put_contents( $targetDir . '/jetpack_autoload_classmap.php', $this->getAutoloadClassmapPackagesFile( $classMap ) ); + $this->io->writeError( 'Generated ' . $targetDir . '/jetpack_autoload_classmap.php', true ); + + file_put_contents( $targetDir . '/jetpack_autoload_filemap.php', $this->getAutoloadFilesPackagesFile( $fileMap ) ); + $this->io->writeError( 'Generated ' . $targetDir . '/jetpack_autoload_filemap.php', true ); + + file_put_contents( $vendorPath . '/autoload_packages.php', $this->getAutoloadPackageFile( 'autoload.php', $suffix ) ); + $this->io->writeError( 'Generated ' . $vendorPath . '/autoload_packages.php', true ); + + $jetpackAutoloaderDir = $vendorPath . '/jetpack-autoloader'; + $filesystem->ensureDirectoryExists( $jetpackAutoloaderDir ); + file_put_contents( $jetpackAutoloaderDir . '/autoload_functions.php', $this->getAutoloadPackageFile( 'functions.php', $suffix ) ); + $this->io->writeError( 'Generated ' . $jetpackAutoloaderDir . '/jetpack-autoloader/autoload_functions.php', true ); + + file_put_contents( $vendorPath . '/class-autoloader-handler.php', $this->getAutoloadPackageFile( 'class-autoloader-handler.php', $suffix ) ); + $this->io->writeError( 'Generated ' . $vendorPath . '/class-autoloader-handler.php', true ); + + file_put_contents( $vendorPath . '/class-classes-handler.php', $this->getAutoloadPackageFile( 'class-classes-handler.php', $suffix ) ); + $this->io->writeError( 'Generated ' . $vendorPath . '/class-classes-handler.php', true ); + + file_put_contents( $vendorPath . '/class-files-handler.php', $this->getAutoloadPackageFile( 'class-files-handler.php', $suffix ) ); + $this->io->writeError( 'Generated ' . $vendorPath . '/class-files-handler.php', true ); + + file_put_contents( $vendorPath . '/class-plugins-handler.php', $this->getAutoloadPackageFile( 'class-plugins-handler.php', $suffix ) ); + $this->io->writeError( 'Generated ' . $vendorPath . '/class-plugins-handler.php', true ); + + file_put_contents( $vendorPath . '/class-version-selector.php', $this->getAutoloadPackageFile( 'class-version-selector.php', $suffix ) ); + $this->io->writeError( 'Generated ' . $vendorPath . '/class-version-selector.php', true ); + } + + /** + * This function differs from the composer parseAutoloadsType in that beside returning the path. + * It also return the path and the version of a package. + * + * Currently supports only psr-4 and clasmap parsing. + * + * @param array $packageMap Map of all the packages. + * @param string $type Type of autoloader to use, currently not used, since we only support psr-4. + * @param PackageInterface $mainPackage Instance of the Package Object. + * + * @return array + */ + protected function parseAutoloadsType( array $packageMap, $type, PackageInterface $mainPackage ) { + $autoloads = array(); + + if ( 'psr-4' !== $type && 'classmap' !== $type && 'files' !== $type ) { + return parent::parseAutoloadsType( $packageMap, $type, $mainPackage ); + } + + foreach ( $packageMap as $item ) { + list($package, $installPath) = $item; + $autoload = $package->getAutoload(); + + if ( $package === $mainPackage ) { + $autoload = array_merge_recursive( $autoload, $package->getDevAutoload() ); + } + + if ( null !== $package->getTargetDir() && $package !== $mainPackage ) { + $installPath = substr( $installPath, 0, -strlen( '/' . $package->getTargetDir() ) ); + } + + if ( 'psr-4' === $type && isset( $autoload['psr-4'] ) && is_array( $autoload['psr-4'] ) ) { + foreach ( $autoload['psr-4'] as $namespace => $paths ) { + $paths = is_array( $paths ) ? $paths : array( $paths ); + foreach ( $paths as $path ) { + $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path; + $autoloads[ $namespace ][] = array( + 'path' => $relativePath, + 'version' => $package->getVersion(), // Version of the class comes from the package - should we try to parse it? + ); + } + } + } + + if ( 'classmap' === $type && isset( $autoload['classmap'] ) && is_array( $autoload['classmap'] ) ) { + foreach ( $autoload['classmap'] as $paths ) { + $paths = is_array( $paths ) ? $paths : array( $paths ); + foreach ( $paths as $path ) { + $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path; + $autoloads[] = array( + 'path' => $relativePath, + 'version' => $package->getVersion(), // Version of the class comes from the package - should we try to parse it? + ); + } + } + } + if ( 'files' === $type && isset( $autoload['files'] ) && is_array( $autoload['files'] ) ) { + foreach ( $autoload['files'] as $file_id => $paths ) { + $paths = is_array( $paths ) ? $paths : array( $paths ); + foreach ( $paths as $path ) { + $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path; + $autoloads[ $this->getFileIdentifier( $package, $path ) ] = array( + 'path' => $relativePath, + 'version' => $package->getVersion(), // Version of the file comes from the package - should we try to parse it? + ); + } + } + } + } + + return $autoloads; + } + + /** + * Take the autoloads array and return the classMap that contains the path and the version for each namespace. + * + * @param array $autoloads Array of autoload settings defined defined by the packages. + * @param Filesystem $filesystem Filesystem class instance. + * @param string $vendorPath Path to the vendor directory. + * @param string $basePath Base Path. + * + * @return string $classMap + */ + private function getClassMap( array $autoloads, Filesystem $filesystem, $vendorPath, $basePath ) { + $blacklist = null; + + if ( ! empty( $autoloads['exclude-from-classmap'] ) ) { + $blacklist = '{(' . implode( '|', $autoloads['exclude-from-classmap'] ) . ')}'; + } + + $classmapString = ''; + + // Scan the PSR-4 and classmap directories for class files, and add them to the class map. + foreach ( $autoloads['psr-4'] as $namespace => $packages_info ) { + foreach ( $packages_info as $package ) { + $dir = $filesystem->normalizePath( + $filesystem->isAbsolutePath( $package['path'] ) + ? $package['path'] + : $basePath . '/' . $package['path'] + ); + $namespace = empty( $namespace ) ? null : $namespace; + $map = ClassMapGenerator::createMap( $dir, $blacklist, $this->io, $namespace ); + + foreach ( $map as $class => $path ) { + $classCode = var_export( $class, true ); + $pathCode = $this->getPathCode( $filesystem, $basePath, $vendorPath, $path ); + $versionCode = var_export( $package['version'], true ); + $classmapString .= << array( + 'version' => $versionCode, + 'path' => $pathCode + ), +CLASS_CODE; + $classmapString .= PHP_EOL; + } + } + } + + foreach ( $autoloads['classmap'] as $package ) { + $dir = $filesystem->normalizePath( + $filesystem->isAbsolutePath( $package['path'] ) + ? $package['path'] + : $basePath . '/' . $package['path'] + ); + $map = ClassMapGenerator::createMap( $dir, $blacklist, $this->io, null ); + + foreach ( $map as $class => $path ) { + $classCode = var_export( $class, true ); + $pathCode = $this->getPathCode( $filesystem, $basePath, $vendorPath, $path ); + $versionCode = var_export( $package['version'], true ); + $classmapString .= << array( + 'version' => $versionCode, + 'path' => $pathCode + ), +CLASS_CODE; + $classmapString .= PHP_EOL; + } + } + + return 'array( ' . PHP_EOL . $classmapString . ');' . PHP_EOL; + } + + /** + * Generate the PHP that will be used in the autoload_classmap_package.php files. + * + * @param string $classMap class map array string that is to be written out to the file. + * + * @return string + */ + private function getAutoloadClassmapPackagesFile( $classMap ) { + + return << $package ) { + $key = var_export( $file_id, true ); + $pathCode = $this->getPathCode( $filesystem, $basePath, $vendorPath, $package['path'] ); + $versionCode = var_export( $package['version'], true ); + $fileMapString .= << array( + 'version' => $versionCode, + 'path' => $pathCode + ), +FILE_CODE; + $fileMapString .= PHP_EOL; + } + + return 'array( ' . PHP_EOL . $fileMapString . ');' . PHP_EOL; + } + + /** + * Generate the PHP that will be used in the autoload_files_package.php files. + * + * @param string $filesMap files array as string that is to be written out to the file. + * + * @return string + */ + private function getAutoloadFilesPackagesFile( $filesMap ) { + + return <<composer = $composer; + $this->io = $io; + } + + /** + * Do nothing. + * phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + * + * @param Composer $composer Composer object. + * @param IOInterface $io IO object. + */ + public function deactivate( Composer $composer, IOInterface $io ) { + /* + * Intentionally left empty. This is a PluginInterface method. + * phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + */ + } + + /** + * Do nothing. + * phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + * + * @param Composer $composer Composer object. + * @param IOInterface $io IO object. + */ + public function uninstall( Composer $composer, IOInterface $io ) { + /* + * Intentionally left empty. This is a PluginInterface method. + * phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + */ + } + + + /** + * Tell composer to listen for events and do something with them. + * + * @return array List of subscribed events. + */ + public static function getSubscribedEvents() { + return array( + ScriptEvents::POST_AUTOLOAD_DUMP => 'postAutoloadDump', + ); + } + + /** + * Generate the custom autolaoder. + * + * @param Event $event Script event object. + */ + public function postAutoloadDump( Event $event ) { + + $config = $this->composer->getConfig(); + + if ( 'vendor' !== $config->raw()['config']['vendor-dir'] ) { + $this->io->writeError( "\nAn error occurred while generating the autoloader files:", true ); + $this->io->writeError( 'The project\'s composer.json or composer environment set a non-default vendor directory.', true ); + $this->io->writeError( 'The default composer vendor directory must be used.', true ); + exit(); + } + + $installationManager = $this->composer->getInstallationManager(); + $repoManager = $this->composer->getRepositoryManager(); + $localRepo = $repoManager->getLocalRepository(); + $package = $this->composer->getPackage(); + $optimize = true; + $suffix = $config->get( 'autoloader-suffix' ) + ? $config->get( 'autoloader-suffix' ) + : md5( uniqid( '', true ) ); + + $generator = new AutoloadGenerator( $this->io ); + + $generator->dump( $config, $localRepo, $package, $installationManager, 'composer', $optimize, $suffix ); + $this->generated = true; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/autoload.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/autoload.php new file mode 100644 index 0000000..993c8cc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/autoload.php @@ -0,0 +1,6 @@ +plugins_handler = $plugins_handler; + $this->version_selector = $version_selector; + } + + /** + * Finds the latest installed autoloader. + */ + public function find_latest_autoloader() { + global $jetpack_autoloader_latest_version; + + $current_autoloader_path = trailingslashit( dirname( __FILE__ ) ) . 'autoload_packages.php'; + $current_autoloader_path = str_replace( '\\', '/', $current_autoloader_path ); + + $selected_autoloader_version = null; + $selected_autoloader_path = null; + + $active_plugins_paths = $this->plugins_handler->get_all_active_plugins_paths(); + + foreach ( $active_plugins_paths as $plugin_path ) { + $classmap_path = trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; + + if ( file_exists( $classmap_path ) ) { + $packages = require $classmap_path; + + $compare_version = $packages[ self::AUTOLOAD_GENERATOR_CLASS_NAME ]['version']; + $compare_path = trailingslashit( $plugin_path ) . 'vendor/autoload_packages.php'; + + if ( $this->version_selector->is_version_update_required( $selected_autoloader_version, $compare_version ) ) { + $selected_autoloader_version = $compare_version; + $selected_autoloader_path = $compare_path; + } + } + } + + $jetpack_autoloader_latest_version = $selected_autoloader_version; + + // $current_autoloader_path is already loaded + if ( $current_autoloader_path !== $selected_autoloader_path ) { + require $selected_autoloader_path; + } + } + + /** + * Get this autoloader's package version. + * + * @return String The autoloader's package version. + */ + public function get_current_autoloader_version() { + $classmap_file = trailingslashit( dirname( __FILE__ ) ) . 'composer/jetpack_autoload_classmap.php'; + $autoloader_packages = require $classmap_file; + + return $autoloader_packages[ self::AUTOLOAD_GENERATOR_CLASS_NAME ]['version']; + } + + + /** + * Updates the spl autoloader chain: + * - Registers this namespace's autoloader function. + * - If a v1 autoloader function is registered, moves it to the end of the chain. + * - Removes any other v2 autoloader functions that have already been registered. This + * can occur when the autoloader is being reset by an activating plugin. + */ + public function update_autoloader_chain() { + spl_autoload_register( __NAMESPACE__ . '\autoloader' ); + + $autoload_chain = spl_autoload_functions(); + + foreach ( $autoload_chain as $autoloader ) { + if ( ! is_string( $autoloader ) ) { + /* + * The Jetpack Autoloader functions are registered as strings, so + * just continue if $autoloader isn't a string. + */ + continue; + } + + if ( self::V1_AUTOLOADER_NAME === $autoloader ) { + // Move the v1.* autoloader function to the end of the spl autoloader chain. + spl_autoload_unregister( $autoloader ); + spl_autoload_register( $autoloader ); + + } elseif ( + self::V2_AUTOLOADER_BASE === substr( $autoloader, 0, strlen( self::V2_AUTOLOADER_BASE ) ) + && __NAMESPACE__ !== substr( $autoloader, 0, strlen( __NAMESPACE__ ) ) + ) { + // Unregister any other v2.* autoloader functions if they're in the chain. + spl_autoload_unregister( $autoloader ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-classes-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-classes-handler.php new file mode 100644 index 0000000..ff3be04 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-classes-handler.php @@ -0,0 +1,90 @@ +plugins_handler = $plugins_handler; + $this->version_selector = $version_selector; + } + + /** + * Adds the version of a package to the $jetpack_packages_classmap global + * array so that the autoloader is able to find it. + * + * @param string $class_name Name of the class that you want to autoload. + * @param string $version Version of the class. + * @param string $path Absolute path to the class so that we can load it. + */ + public function enqueue_package_class( $class_name, $version, $path ) { + global $jetpack_packages_classmap; + + if ( isset( $jetpack_packages_classmap[ $class_name ]['version'] ) ) { + $selected_version = $jetpack_packages_classmap[ $class_name ]['version']; + } else { + $selected_version = null; + } + + if ( $this->version_selector->is_version_update_required( $selected_version, $version ) ) { + $jetpack_packages_classmap[ $class_name ] = array( + 'version' => $version, + 'path' => $path, + ); + } + } + + /** + * Creates the path to the plugin's classmap file. The classmap filename is the filename + * generated by Jetpack Autoloader version >= 2.0. + * + * @param String $plugin_path The plugin path. + * + * @return String the classmap path. + */ + public function create_classmap_path( $plugin_path ) { + return trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; + } + + /** + * Initializes the classmap. + */ + public function set_class_paths() { + $active_plugins_paths = $this->plugins_handler->get_all_active_plugins_paths(); + $classmap_paths = array_map( array( $this, 'create_classmap_path' ), $active_plugins_paths ); + + foreach ( $classmap_paths as $path ) { + if ( is_readable( $path ) ) { + $class_map = require $path; + + if ( is_array( $class_map ) ) { + foreach ( $class_map as $class_name => $class_info ) { + $this->enqueue_package_class( $class_name, $class_info['version'], $class_info['path'] ); + } + } + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-files-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-files-handler.php new file mode 100644 index 0000000..1e5c453 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-files-handler.php @@ -0,0 +1,104 @@ +plugins_handler = $plugins_handler; + $this->version_selector = $version_selector; + } + + /** + * Adds the version of a package file to the $jetpack_packages_filemap global + * array so that we can load the most recent version. + * + * @param string $file_identifier Unique id to file assigned by composer based on package name and filename. + * @param string $version Version of the file. + * @param string $path Absolute path to the file so that we can load it. + */ + public function enqueue_package_file( $file_identifier, $version, $path ) { + global $jetpack_packages_filemap; + + if ( isset( $jetpack_packages_filemap[ $file_identifier ]['version'] ) ) { + $selected_version = $jetpack_packages_filemap[ $file_identifier ]['version']; + } else { + $selected_version = null; + } + + if ( $this->version_selector->is_version_update_required( $selected_version, $version ) ) { + $jetpack_packages_filemap[ $file_identifier ] = array( + 'version' => $version, + 'path' => $path, + ); + } + } + + /** + * Creates a path to the plugin's filemap. The filemap filename is the filename + * generated by Jetpack Autoloader version >= 2.0. + * + * @param String $plugin_path The plugin path. + * + * @return String The filemap path + */ + public function create_filemap_path( $plugin_path ) { + return trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_filemap.php'; + } + + /** + * Initializes the filemap. + */ + public function set_file_paths() { + $active_plugin_paths = $this->plugins_handler->get_all_active_plugins_paths(); + $filemap_paths = array_map( array( $this, 'create_filemap_path' ), $active_plugin_paths ); + + foreach ( $filemap_paths as $path ) { + if ( is_readable( $path ) ) { + $file_map = require $path; + + if ( is_array( $file_map ) ) { + foreach ( $file_map as $file_identifier => $file_data ) { + $this->enqueue_package_file( $file_identifier, $file_data['version'], $file_data['path'] ); + } + } + } + } + } + + /** + * Include latest version of all enqueued files. + */ + public function file_loader() { + global $jetpack_packages_filemap; + foreach ( $jetpack_packages_filemap as $file_identifier => $file_data ) { + if ( empty( $GLOBALS['__composer_autoload_files'][ $file_identifier ] ) ) { + require_once $file_data['path']; + + $GLOBALS['__composer_autoload_files'][ $file_identifier ] = true; + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php new file mode 100644 index 0000000..945a724 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php @@ -0,0 +1,150 @@ +get_active_plugins_paths(); + $multisite_plugins_paths = $this->get_multisite_plugins_paths(); + $active_plugins_paths = array_merge( $multisite_plugins_paths, $active_plugins_paths ); + + $activating_plugins_paths = $this->get_plugins_activating_via_request(); + $activating_plugins_paths = array_unique( array_merge( $activating_plugins_paths, $jetpack_autoloader_activating_plugins_paths ) ); + + $plugins_paths = array_unique( array_merge( $active_plugins_paths, $activating_plugins_paths ) ); + + return $plugins_paths; + } + + /** + * Returns an array containing the paths of the active sitewide plugins in a multisite environment. + * + * @return array The paths of the active sitewide plugins or an empty array. + */ + protected function get_multisite_plugins_paths() { + $plugin_slugs = is_multisite() + ? array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) + : array(); + + $plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + /** + * Returns an array containing the paths of the currently active plugins. + * + * @return array The active plugins' paths or an empty array. + */ + protected function get_active_plugins_paths() { + $plugin_slugs = (array) get_option( 'active_plugins', array() ); + $plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + /** + * Adds the plugin directory from the WP_PLUGIN_DIR constant to the plugin slug. + * + * @param string $plugin_slug The plugin slug. + */ + private function create_plugin_path( $plugin_slug ) { + $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR ); + return trailingslashit( $plugin_dir ) . substr( $plugin_slug, 0, strrpos( $plugin_slug, '/' ) ); + } + + /** + * Ensure the plugin has its own directory and not a single-file plugin. + * + * @param string $plugin Plugin name, may be prefixed with "/". + * + * @return bool + */ + public function is_directory_plugin( $plugin ) { + return strlen( $plugin ) > 1 && false !== strpos( $plugin, '/', 1 ); + } + + /** + * Checks whether the autoloader should be reset. The autoloader should be reset + * when a plugin is activating via a method other than a request, for example + * using WP-CLI. When this occurs, the activating plugin was not known when + * the autoloader selected the package versions for the classmap and filemap + * globals, so the autoloader must reselect the versions. + * + * If the current plugin is not already known, this method will add it to the + * $jetpack_autoloader_activating_plugins_paths global. + * + * @return boolean True if the autoloder must be reset, else false. + */ + public function should_autoloader_reset() { + global $jetpack_autoloader_activating_plugins_paths; + + $plugins_paths = $this->get_all_active_plugins_paths(); + $current_plugin_path = $this->get_current_plugin_path(); + $plugin_unknown = ! in_array( $current_plugin_path, $plugins_paths, true ); + + if ( $plugin_unknown ) { + // If the current plugin isn't known, add it to the activating plugins list. + $jetpack_autoloader_activating_plugins_paths[] = $current_plugin_path; + } + + return $plugin_unknown; + } + + /** + * Returns an array containing the names of plugins that are activating via a request. + * + * @return array An array of names of the activating plugins or an empty array. + */ + private function get_plugins_activating_via_request() { + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + + $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : false; + $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : false; + $nonce = isset( $_REQUEST['_wpnonce'] ) ? $_REQUEST['_wpnonce'] : false; + + /** + * Note: we're not actually checking the nonce here becase it's too early + * in the execution. The pluggable functions are not yet loaded to give + * plugins a chance to plug their versions. Therefore we're doing the bare + * minimum: checking whether the nonce exists and it's in the right place. + * The request will fail later if the nonce doesn't pass the check. + */ + + // In case of a single plugin activation there will be a plugin slug. + if ( 'activate' === $action && ! empty( $nonce ) ) { + return array( $this->create_plugin_path( wp_unslash( $plugin ) ) ); + } + + $plugins = isset( $_REQUEST['checked'] ) ? $_REQUEST['checked'] : array(); + + // In case of bulk activation there will be an array of plugins. + if ( 'activate-selected' === $action && ! empty( $nonce ) ) { + $plugin_slugs = array_map( 'wp_unslash', $plugins ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + // phpcs:enable WordPress.Security.NonceVerification.Recommended + return array(); + } + + /** + * Returns the path of the current plugin. + * + * @return string The path of the current plugin. + */ + public function get_current_plugin_path() { + $vendor_path = str_replace( '\\', '/', dirname( __FILE__ ) ); + // Path to the plugin's folder (the parent of the vendor folder). + return substr( $vendor_path, 0, strrpos( $vendor_path, '/' ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-version-selector.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-version-selector.php new file mode 100644 index 0000000..02c002e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/class-version-selector.php @@ -0,0 +1,61 @@ +is_package_version_dev( $selected_version ) ) { + return false; + } + + if ( $this->is_package_version_dev( $compare_version ) ) { + if ( $use_dev_versions ) { + return true; + } else { + return false; + } + } + + if ( version_compare( $selected_version, $compare_version, '<' ) ) { + return true; + } + + return false; + } + + /** + * Checks whether the given package version is a development version. + * + * @param String $version The package version. + * + * @return Boolean True if the version is a dev version, else false. + */ + private function is_package_version_dev( $version ) { + if ( 'dev-' === substr( $version, 0, 4 ) || '9999999-dev' === $version ) { + return true; + } + + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/functions.php new file mode 100644 index 0000000..a146bfa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-autoloader/src/functions.php @@ -0,0 +1,141 @@ +set_class_paths(); + + $files_handler = new Files_Handler( $plugins_handler, $version_selector ); + $files_handler->set_file_paths(); + + $files_handler->file_loader(); +} + +/** + * Finds the latest installed autoloader. If this is the latest autoloader, sets + * up the classmap and filemap. + */ +function set_up_autoloader() { + global $jetpack_autoloader_latest_version; + global $jetpack_packages_classmap; + + require_once __DIR__ . '/../class-plugins-handler.php'; + require_once __DIR__ . '/../class-version-selector.php'; + require_once __DIR__ . '/../class-autoloader-handler.php'; + + $plugins_handler = new Plugins_Handler(); + $version_selector = new Version_Selector(); + $autoloader_handler = new Autoloader_Handler( $plugins_handler, $version_selector ); + + if ( $plugins_handler->should_autoloader_reset() ) { + /* + * The autoloader must be reset when an activating plugin that was + * previously unknown is detected. + */ + $jetpack_autoloader_latest_version = null; + $jetpack_packages_classmap = array(); + } + + // Find the latest autoloader. + if ( ! $jetpack_autoloader_latest_version ) { + $autoloader_handler->find_latest_autoloader(); + } + + $current_autoloader_version = $autoloader_handler->get_current_autoloader_version(); + + // This is the latest autoloader, so generate the classmap and filemap and register the autoloader function. + if ( empty( $jetpack_packages_classmap ) && $current_autoloader_version === $jetpack_autoloader_latest_version ) { + enqueue_files( $plugins_handler, $version_selector ); + $autoloader_handler->update_autoloader_chain(); + add_filter( 'upgrader_post_install', __NAMESPACE__ . '\reset_maps_after_update', 0, 3 ); + } +} + +/** + * Resets the autoloader after a plugin update. + * + * @param bool $response Installation response. + * @param array $hook_extra Extra arguments passed to hooked filters. + * @param array $result Installation result data. + * + * @return bool The passed in $response param. + */ +function reset_maps_after_update( $response, $hook_extra, $result ) { + global $jetpack_packages_classmap; + + if ( isset( $hook_extra['plugin'] ) ) { + /* + * $hook_extra['plugin'] is the path to the plugin file relative to the plugins directory: + * https://core.trac.wordpress.org/browser/tags/5.4/src/wp-admin/includes/class-wp-upgrader.php#L701 + */ + $plugin = $hook_extra['plugin']; + + if ( false === strpos( $plugin, '/', 1 ) ) { + // Single-file plugins don't use packages, so bail. + return $response; + } + + if ( ! is_plugin_active( $plugin ) ) { + // The updated plugin isn't active, so bail. + return $response; + } + + /* + * $plugin is the path to the plugin file relative to the plugins directory. + */ + $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR ); + $plugin_path = trailingslashit( $plugin_dir ) . trailingslashit( explode( '/', $plugin )[0] ); + + if ( is_readable( $plugin_path . 'vendor/jetpack-autoloader/autoload_functions.php' ) ) { + // The plugin has a >=v2.2 autoloader, so reset the classmap. + $jetpack_packages_classmap = array(); + + set_up_autoloader(); + } + } + + return $response; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-constants/src/class-constants.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-constants/src/class-constants.php new file mode 100644 index 0000000..d7bdbcb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/automattic/jetpack-constants/src/class-constants.php @@ -0,0 +1,124 @@ +plugins_handler = $plugins_handler; + $this->version_selector = $version_selector; + } + + /** + * Finds the latest installed autoloader. + */ + public function find_latest_autoloader() { + global $jetpack_autoloader_latest_version; + + $current_autoloader_path = trailingslashit( dirname( __FILE__ ) ) . 'autoload_packages.php'; + $current_autoloader_path = str_replace( '\\', '/', $current_autoloader_path ); + + $selected_autoloader_version = null; + $selected_autoloader_path = null; + + $active_plugins_paths = $this->plugins_handler->get_all_active_plugins_paths(); + + foreach ( $active_plugins_paths as $plugin_path ) { + $classmap_path = trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; + + if ( file_exists( $classmap_path ) ) { + $packages = require $classmap_path; + + $compare_version = $packages[ self::AUTOLOAD_GENERATOR_CLASS_NAME ]['version']; + $compare_path = trailingslashit( $plugin_path ) . 'vendor/autoload_packages.php'; + + if ( $this->version_selector->is_version_update_required( $selected_autoloader_version, $compare_version ) ) { + $selected_autoloader_version = $compare_version; + $selected_autoloader_path = $compare_path; + } + } + } + + $jetpack_autoloader_latest_version = $selected_autoloader_version; + + // $current_autoloader_path is already loaded + if ( $current_autoloader_path !== $selected_autoloader_path ) { + require $selected_autoloader_path; + } + } + + /** + * Get this autoloader's package version. + * + * @return String The autoloader's package version. + */ + public function get_current_autoloader_version() { + $classmap_file = trailingslashit( dirname( __FILE__ ) ) . 'composer/jetpack_autoload_classmap.php'; + $autoloader_packages = require $classmap_file; + + return $autoloader_packages[ self::AUTOLOAD_GENERATOR_CLASS_NAME ]['version']; + } + + + /** + * Updates the spl autoloader chain: + * - Registers this namespace's autoloader function. + * - If a v1 autoloader function is registered, moves it to the end of the chain. + * - Removes any other v2 autoloader functions that have already been registered. This + * can occur when the autoloader is being reset by an activating plugin. + */ + public function update_autoloader_chain() { + spl_autoload_register( __NAMESPACE__ . '\autoloader' ); + + $autoload_chain = spl_autoload_functions(); + + foreach ( $autoload_chain as $autoloader ) { + if ( ! is_string( $autoloader ) ) { + /* + * The Jetpack Autoloader functions are registered as strings, so + * just continue if $autoloader isn't a string. + */ + continue; + } + + if ( self::V1_AUTOLOADER_NAME === $autoloader ) { + // Move the v1.* autoloader function to the end of the spl autoloader chain. + spl_autoload_unregister( $autoloader ); + spl_autoload_register( $autoloader ); + + } elseif ( + self::V2_AUTOLOADER_BASE === substr( $autoloader, 0, strlen( self::V2_AUTOLOADER_BASE ) ) + && __NAMESPACE__ !== substr( $autoloader, 0, strlen( __NAMESPACE__ ) ) + ) { + // Unregister any other v2.* autoloader functions if they're in the chain. + spl_autoload_unregister( $autoloader ); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-classes-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-classes-handler.php new file mode 100644 index 0000000..5a5024d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-classes-handler.php @@ -0,0 +1,98 @@ +plugins_handler = $plugins_handler; + $this->version_selector = $version_selector; + } + + /** + * Adds the version of a package to the $jetpack_packages_classmap global + * array so that the autoloader is able to find it. + * + * @param string $class_name Name of the class that you want to autoload. + * @param string $version Version of the class. + * @param string $path Absolute path to the class so that we can load it. + */ + public function enqueue_package_class( $class_name, $version, $path ) { + global $jetpack_packages_classmap; + + if ( isset( $jetpack_packages_classmap[ $class_name ]['version'] ) ) { + $selected_version = $jetpack_packages_classmap[ $class_name ]['version']; + } else { + $selected_version = null; + } + + if ( $this->version_selector->is_version_update_required( $selected_version, $version ) ) { + $jetpack_packages_classmap[ $class_name ] = array( + 'version' => $version, + 'path' => $path, + ); + } + } + + /** + * Creates the path to the plugin's classmap file. The classmap filename is the filename + * generated by Jetpack Autoloader version >= 2.0. + * + * @param String $plugin_path The plugin path. + * + * @return String the classmap path. + */ + public function create_classmap_path( $plugin_path ) { + return trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; + } + + /** + * Initializes the classmap. + */ + public function set_class_paths() { + $active_plugins_paths = $this->plugins_handler->get_all_active_plugins_paths(); + $classmap_paths = array_map( array( $this, 'create_classmap_path' ), $active_plugins_paths ); + + foreach ( $classmap_paths as $path ) { + if ( is_readable( $path ) ) { + $class_map = require $path; + + if ( is_array( $class_map ) ) { + foreach ( $class_map as $class_name => $class_info ) { + $this->enqueue_package_class( $class_name, $class_info['version'], $class_info['path'] ); + } + } + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-files-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-files-handler.php new file mode 100644 index 0000000..78c73c8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-files-handler.php @@ -0,0 +1,112 @@ +plugins_handler = $plugins_handler; + $this->version_selector = $version_selector; + } + + /** + * Adds the version of a package file to the $jetpack_packages_filemap global + * array so that we can load the most recent version. + * + * @param string $file_identifier Unique id to file assigned by composer based on package name and filename. + * @param string $version Version of the file. + * @param string $path Absolute path to the file so that we can load it. + */ + public function enqueue_package_file( $file_identifier, $version, $path ) { + global $jetpack_packages_filemap; + + if ( isset( $jetpack_packages_filemap[ $file_identifier ]['version'] ) ) { + $selected_version = $jetpack_packages_filemap[ $file_identifier ]['version']; + } else { + $selected_version = null; + } + + if ( $this->version_selector->is_version_update_required( $selected_version, $version ) ) { + $jetpack_packages_filemap[ $file_identifier ] = array( + 'version' => $version, + 'path' => $path, + ); + } + } + + /** + * Creates a path to the plugin's filemap. The filemap filename is the filename + * generated by Jetpack Autoloader version >= 2.0. + * + * @param String $plugin_path The plugin path. + * + * @return String The filemap path + */ + public function create_filemap_path( $plugin_path ) { + return trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_filemap.php'; + } + + /** + * Initializes the filemap. + */ + public function set_file_paths() { + $active_plugin_paths = $this->plugins_handler->get_all_active_plugins_paths(); + $filemap_paths = array_map( array( $this, 'create_filemap_path' ), $active_plugin_paths ); + + foreach ( $filemap_paths as $path ) { + if ( is_readable( $path ) ) { + $file_map = require $path; + + if ( is_array( $file_map ) ) { + foreach ( $file_map as $file_identifier => $file_data ) { + $this->enqueue_package_file( $file_identifier, $file_data['version'], $file_data['path'] ); + } + } + } + } + } + + /** + * Include latest version of all enqueued files. + */ + public function file_loader() { + global $jetpack_packages_filemap; + foreach ( $jetpack_packages_filemap as $file_identifier => $file_data ) { + if ( empty( $GLOBALS['__composer_autoload_files'][ $file_identifier ] ) ) { + require_once $file_data['path']; + + $GLOBALS['__composer_autoload_files'][ $file_identifier ] = true; + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-plugins-handler.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-plugins-handler.php new file mode 100644 index 0000000..0706a22 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-plugins-handler.php @@ -0,0 +1,158 @@ +get_active_plugins_paths(); + $multisite_plugins_paths = $this->get_multisite_plugins_paths(); + $active_plugins_paths = array_merge( $multisite_plugins_paths, $active_plugins_paths ); + + $activating_plugins_paths = $this->get_plugins_activating_via_request(); + $activating_plugins_paths = array_unique( array_merge( $activating_plugins_paths, $jetpack_autoloader_activating_plugins_paths ) ); + + $plugins_paths = array_unique( array_merge( $active_plugins_paths, $activating_plugins_paths ) ); + + return $plugins_paths; + } + + /** + * Returns an array containing the paths of the active sitewide plugins in a multisite environment. + * + * @return array The paths of the active sitewide plugins or an empty array. + */ + protected function get_multisite_plugins_paths() { + $plugin_slugs = is_multisite() + ? array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) + : array(); + + $plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + /** + * Returns an array containing the paths of the currently active plugins. + * + * @return array The active plugins' paths or an empty array. + */ + protected function get_active_plugins_paths() { + $plugin_slugs = (array) get_option( 'active_plugins', array() ); + $plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + /** + * Adds the plugin directory from the WP_PLUGIN_DIR constant to the plugin slug. + * + * @param string $plugin_slug The plugin slug. + */ + private function create_plugin_path( $plugin_slug ) { + $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR ); + return trailingslashit( $plugin_dir ) . substr( $plugin_slug, 0, strrpos( $plugin_slug, '/' ) ); + } + + /** + * Ensure the plugin has its own directory and not a single-file plugin. + * + * @param string $plugin Plugin name, may be prefixed with "/". + * + * @return bool + */ + public function is_directory_plugin( $plugin ) { + return strlen( $plugin ) > 1 && false !== strpos( $plugin, '/', 1 ); + } + + /** + * Checks whether the autoloader should be reset. The autoloader should be reset + * when a plugin is activating via a method other than a request, for example + * using WP-CLI. When this occurs, the activating plugin was not known when + * the autoloader selected the package versions for the classmap and filemap + * globals, so the autoloader must reselect the versions. + * + * If the current plugin is not already known, this method will add it to the + * $jetpack_autoloader_activating_plugins_paths global. + * + * @return boolean True if the autoloder must be reset, else false. + */ + public function should_autoloader_reset() { + global $jetpack_autoloader_activating_plugins_paths; + + $plugins_paths = $this->get_all_active_plugins_paths(); + $current_plugin_path = $this->get_current_plugin_path(); + $plugin_unknown = ! in_array( $current_plugin_path, $plugins_paths, true ); + + if ( $plugin_unknown ) { + // If the current plugin isn't known, add it to the activating plugins list. + $jetpack_autoloader_activating_plugins_paths[] = $current_plugin_path; + } + + return $plugin_unknown; + } + + /** + * Returns an array containing the names of plugins that are activating via a request. + * + * @return array An array of names of the activating plugins or an empty array. + */ + private function get_plugins_activating_via_request() { + + // phpcs:disable WordPress.Security.NonceVerification.Recommended + + $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : false; + $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : false; + $nonce = isset( $_REQUEST['_wpnonce'] ) ? $_REQUEST['_wpnonce'] : false; + + /** + * Note: we're not actually checking the nonce here becase it's too early + * in the execution. The pluggable functions are not yet loaded to give + * plugins a chance to plug their versions. Therefore we're doing the bare + * minimum: checking whether the nonce exists and it's in the right place. + * The request will fail later if the nonce doesn't pass the check. + */ + + // In case of a single plugin activation there will be a plugin slug. + if ( 'activate' === $action && ! empty( $nonce ) ) { + return array( $this->create_plugin_path( wp_unslash( $plugin ) ) ); + } + + $plugins = isset( $_REQUEST['checked'] ) ? $_REQUEST['checked'] : array(); + + // In case of bulk activation there will be an array of plugins. + if ( 'activate-selected' === $action && ! empty( $nonce ) ) { + $plugin_slugs = array_map( 'wp_unslash', $plugins ); + return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs ); + } + + // phpcs:enable WordPress.Security.NonceVerification.Recommended + return array(); + } + + /** + * Returns the path of the current plugin. + * + * @return string The path of the current plugin. + */ + public function get_current_plugin_path() { + $vendor_path = str_replace( '\\', '/', dirname( __FILE__ ) ); + // Path to the plugin's folder (the parent of the vendor folder). + return substr( $vendor_path, 0, strrpos( $vendor_path, '/' ) ); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-version-selector.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-version-selector.php new file mode 100644 index 0000000..e44cb96 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/class-version-selector.php @@ -0,0 +1,69 @@ +is_package_version_dev( $selected_version ) ) { + return false; + } + + if ( $this->is_package_version_dev( $compare_version ) ) { + if ( $use_dev_versions ) { + return true; + } else { + return false; + } + } + + if ( version_compare( $selected_version, $compare_version, '<' ) ) { + return true; + } + + return false; + } + + /** + * Checks whether the given package version is a development version. + * + * @param String $version The package version. + * + * @return Boolean True if the version is a dev version, else false. + */ + private function is_package_version_dev( $version ) { + if ( 'dev-' === substr( $version, 0, 4 ) || '9999999-dev' === $version ) { + return true; + } + + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/ClassLoader.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/ClassLoader.php new file mode 100644 index 0000000..1a58957 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/ClassLoader.php @@ -0,0 +1,445 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/InstalledVersions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..0664da8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/InstalledVersions.php @@ -0,0 +1,336 @@ + + array ( + 'pretty_version' => 'dev-release/4.8', + 'version' => 'dev-release/4.8', + 'aliases' => + array ( + ), + 'reference' => 'c9a204b0c11d252a56c90ffd1fa947d5cadbb7b1', + 'name' => 'woocommerce/woocommerce', + ), + 'versions' => + array ( + 'automattic/jetpack-autoloader' => + array ( + 'pretty_version' => 'v2.2.0', + 'version' => '2.2.0.0', + 'aliases' => + array ( + ), + 'reference' => '66a5d150b3928be718d86696f85631a7f0b98a7b', + ), + 'automattic/jetpack-constants' => + array ( + 'pretty_version' => 'v1.5.0', + 'version' => '1.5.0.0', + 'aliases' => + array ( + ), + 'reference' => '9827a2f446b8c4faafaf1c740483031c073a381d', + ), + 'composer/installers' => + array ( + 'pretty_version' => 'v1.9.0', + 'version' => '1.9.0.0', + 'aliases' => + array ( + ), + 'reference' => 'b93bcf0fa1fccb0b7d176b0967d969691cd74cca', + ), + 'league/container' => + array ( + 'pretty_version' => '3.3.3', + 'version' => '3.3.3.0', + 'aliases' => + array ( + ), + 'reference' => '7dc67bdf89efc338e674863c0ea70a63efe4de05', + ), + 'maxmind-db/reader' => + array ( + 'pretty_version' => 'v1.6.0', + 'version' => '1.6.0.0', + 'aliases' => + array ( + ), + 'reference' => 'febd4920bf17c1da84cef58e56a8227dfb37fbe4', + ), + 'orno/di' => + array ( + 'replaced' => + array ( + 0 => '~2.0', + ), + ), + 'pelago/emogrifier' => + array ( + 'pretty_version' => 'v3.1.0', + 'version' => '3.1.0.0', + 'aliases' => + array ( + ), + 'reference' => 'f6a5c7d44612d86c3901c93f1592f5440e6b2cd8', + ), + 'psr/container' => + array ( + 'pretty_version' => '1.0.0', + 'version' => '1.0.0.0', + 'aliases' => + array ( + ), + 'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f', + ), + 'psr/container-implementation' => + array ( + 'provided' => + array ( + 0 => '^1.0', + ), + ), + 'roundcube/plugin-installer' => + array ( + 'replaced' => + array ( + 0 => '*', + ), + ), + 'shama/baton' => + array ( + 'replaced' => + array ( + 0 => '*', + ), + ), + 'symfony/css-selector' => + array ( + 'pretty_version' => 'v3.3.6', + 'version' => '3.3.6.0', + 'aliases' => + array ( + ), + 'reference' => '4d882dced7b995d5274293039370148e291808f2', + ), + 'woocommerce/action-scheduler' => + array ( + 'pretty_version' => '3.1.6', + 'version' => '3.1.6.0', + 'aliases' => + array ( + ), + 'reference' => '275d0ba54b1c263dfc62688de2fa9a25a373edf8', + ), + 'woocommerce/woocommerce' => + array ( + 'pretty_version' => 'dev-release/4.8', + 'version' => 'dev-release/4.8', + 'aliases' => + array ( + ), + 'reference' => 'c9a204b0c11d252a56c90ffd1fa947d5cadbb7b1', + ), + 'woocommerce/woocommerce-admin' => + array ( + 'pretty_version' => '1.7.3', + 'version' => '1.7.3.0', + 'aliases' => + array ( + ), + 'reference' => '16de972f319e5e6fc8dbebf5024dd263234f39e0', + ), + 'woocommerce/woocommerce-blocks' => + array ( + 'pretty_version' => 'v3.8.1', + 'version' => '3.8.1.0', + 'aliases' => + array ( + ), + 'reference' => 'e5aef9eddd13c5511ba673eb70ed8cb3e80d828c', + ), + ), +); + + + + + + + +public static function getInstalledPackages() +{ +return array_keys(self::$installed['versions']); +} + + + + + + + + + +public static function isInstalled($packageName) +{ +return isset(self::$installed['versions'][$packageName]); +} + + + + + + + + + + + + + + +public static function satisfies(VersionParser $parser, $packageName, $constraint) +{ +$constraint = $parser->parseConstraints($constraint); +$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + +return $provided->matches($constraint); +} + + + + + + + + + + +public static function getVersionRanges($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +$ranges = array(); +if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = self::$installed['versions'][$packageName]['pretty_version']; +} +if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); +} +if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); +} +if (array_key_exists('provided', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); +} + +return implode(' || ', $ranges); +} + + + + + +public static function getVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['version']; +} + + + + + +public static function getPrettyVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['pretty_version']; +} + + + + + +public static function getReference($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['reference'])) { +return null; +} + +return self::$installed['versions'][$packageName]['reference']; +} + + + + + +public static function getRootPackage() +{ +return self::$installed['root']; +} + + + + + + + +public static function getRawData() +{ +return self::$installed; +} + + + + + + + + + + + + + + + + + + + +public static function reload($data) +{ +self::$installed = $data; +} +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/LICENSE b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_classmap.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..7a761c0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_classmap.php @@ -0,0 +1,118 @@ + $vendorDir . '/automattic/jetpack-constants/src/class-constants.php', + 'Automattic\\WooCommerce\\RestApi\\Package' => $baseDir . '/includes/rest-api/Package.php', + 'Automattic\\WooCommerce\\RestApi\\Server' => $baseDir . '/includes/rest-api/Server.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\AdminNotesHelper' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/AdminNotesHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\CouponHelper' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/CouponHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\CustomerHelper' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/CustomerHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\OrderHelper' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/OrderHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\ProductHelper' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/ProductHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\QueueHelper' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/QueueHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\SettingsHelper' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/SettingsHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\ShippingHelper' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/ShippingHelper.php', + 'Automattic\\WooCommerce\\RestApi\\Utilities\\ImageAttachment' => $baseDir . '/includes/rest-api/Utilities/ImageAttachment.php', + 'Automattic\\WooCommerce\\RestApi\\Utilities\\SingletonTrait' => $baseDir . '/includes/rest-api/Utilities/SingletonTrait.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', + 'WC_REST_CRUD_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_namespaces.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..b7fc012 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/symfony/css-selector'), + 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), + 'Pelago\\' => array($vendorDir . '/pelago/emogrifier/src'), + 'MaxMind\\Db\\' => array($vendorDir . '/maxmind-db/reader/src/MaxMind/Db'), + 'League\\Container\\' => array($vendorDir . '/league/container/src'), + 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\' => array($vendorDir . '/league/container'), + 'Automattic\\WooCommerce\\Tests\\' => array($baseDir . '/tests/php/src'), + 'Automattic\\WooCommerce\\Testing\\Tools\\' => array($baseDir . '/tests/Tools'), + 'Automattic\\WooCommerce\\Blocks\\' => array($baseDir . '/packages/woocommerce-blocks/src'), + 'Automattic\\WooCommerce\\Admin\\' => array($baseDir . '/packages/woocommerce-admin/src'), + 'Automattic\\WooCommerce\\' => array($baseDir . '/src'), + 'Automattic\\Jetpack\\Autoloader\\' => array($vendorDir . '/automattic/jetpack-autoloader/src'), +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_real.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_real.php new file mode 100644 index 0000000..28bff23 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_real.php @@ -0,0 +1,57 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit08a6ad0ed5b58cf461fde712d9bcae99::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_static.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_static.php new file mode 100644 index 0000000..e8fd807 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/autoload_static.php @@ -0,0 +1,219 @@ + + array ( + 'Symfony\\Component\\CssSelector\\' => 30, + ), + 'P' => + array ( + 'Psr\\Container\\' => 14, + 'Pelago\\' => 7, + ), + 'M' => + array ( + 'MaxMind\\Db\\' => 11, + ), + 'L' => + array ( + 'League\\Container\\' => 17, + ), + 'C' => + array ( + 'Composer\\Installers\\' => 20, + ), + 'A' => + array ( + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\' => 47, + 'Automattic\\WooCommerce\\Tests\\' => 29, + 'Automattic\\WooCommerce\\Testing\\Tools\\' => 37, + 'Automattic\\WooCommerce\\Blocks\\' => 30, + 'Automattic\\WooCommerce\\Admin\\' => 29, + 'Automattic\\WooCommerce\\' => 23, + 'Automattic\\Jetpack\\Autoloader\\' => 30, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Symfony\\Component\\CssSelector\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/css-selector', + ), + 'Psr\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/container/src', + ), + 'Pelago\\' => + array ( + 0 => __DIR__ . '/..' . '/pelago/emogrifier/src', + ), + 'MaxMind\\Db\\' => + array ( + 0 => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db', + ), + 'League\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/league/container/src', + ), + 'Composer\\Installers\\' => + array ( + 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers', + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/league/container', + ), + 'Automattic\\WooCommerce\\Tests\\' => + array ( + 0 => __DIR__ . '/../..' . '/tests/php/src', + ), + 'Automattic\\WooCommerce\\Testing\\Tools\\' => + array ( + 0 => __DIR__ . '/../..' . '/tests/Tools', + ), + 'Automattic\\WooCommerce\\Blocks\\' => + array ( + 0 => __DIR__ . '/../..' . '/packages/woocommerce-blocks/src', + ), + 'Automattic\\WooCommerce\\Admin\\' => + array ( + 0 => __DIR__ . '/../..' . '/packages/woocommerce-admin/src', + ), + 'Automattic\\WooCommerce\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + 'Automattic\\Jetpack\\Autoloader\\' => + array ( + 0 => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src', + ), + ); + + public static $classMap = array ( + 'Automattic\\Jetpack\\Constants' => __DIR__ . '/..' . '/automattic/jetpack-constants/src/class-constants.php', + 'Automattic\\WooCommerce\\RestApi\\Package' => __DIR__ . '/../..' . '/includes/rest-api/Package.php', + 'Automattic\\WooCommerce\\RestApi\\Server' => __DIR__ . '/../..' . '/includes/rest-api/Server.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\AdminNotesHelper' => __DIR__ . '/../..' . '/tests/legacy/unit-tests/rest-api/Helpers/AdminNotesHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\CouponHelper' => __DIR__ . '/../..' . '/tests/legacy/unit-tests/rest-api/Helpers/CouponHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\CustomerHelper' => __DIR__ . '/../..' . '/tests/legacy/unit-tests/rest-api/Helpers/CustomerHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\OrderHelper' => __DIR__ . '/../..' . '/tests/legacy/unit-tests/rest-api/Helpers/OrderHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\ProductHelper' => __DIR__ . '/../..' . '/tests/legacy/unit-tests/rest-api/Helpers/ProductHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\QueueHelper' => __DIR__ . '/../..' . '/tests/legacy/unit-tests/rest-api/Helpers/QueueHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\SettingsHelper' => __DIR__ . '/../..' . '/tests/legacy/unit-tests/rest-api/Helpers/SettingsHelper.php', + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\ShippingHelper' => __DIR__ . '/../..' . '/tests/legacy/unit-tests/rest-api/Helpers/ShippingHelper.php', + 'Automattic\\WooCommerce\\RestApi\\Utilities\\ImageAttachment' => __DIR__ . '/../..' . '/includes/rest-api/Utilities/ImageAttachment.php', + 'Automattic\\WooCommerce\\RestApi\\Utilities\\SingletonTrait' => __DIR__ . '/../..' . '/includes/rest-api/Utilities/SingletonTrait.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'WC_REST_CRUD_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php', + 'WC_REST_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php', + 'WC_REST_Coupons_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-coupons-controller.php', + 'WC_REST_Coupons_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-coupons-v1-controller.php', + 'WC_REST_Coupons_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php', + 'WC_REST_Customer_Downloads_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-customer-downloads-controller.php', + 'WC_REST_Customer_Downloads_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php', + 'WC_REST_Customer_Downloads_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php', + 'WC_REST_Customers_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php', + 'WC_REST_Customers_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php', + 'WC_REST_Customers_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php', + 'WC_REST_Data_Continents_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php', + 'WC_REST_Data_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php', + 'WC_REST_Data_Countries_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php', + 'WC_REST_Data_Currencies_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php', + 'WC_REST_Network_Orders_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-network-orders-controller.php', + 'WC_REST_Network_Orders_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php', + 'WC_REST_Order_Notes_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-order-notes-controller.php', + 'WC_REST_Order_Notes_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php', + 'WC_REST_Order_Notes_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php', + 'WC_REST_Order_Refunds_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php', + 'WC_REST_Order_Refunds_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php', + 'WC_REST_Order_Refunds_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php', + 'WC_REST_Orders_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php', + 'WC_REST_Orders_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php', + 'WC_REST_Orders_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php', + 'WC_REST_Payment_Gateways_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php', + 'WC_REST_Payment_Gateways_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php', + 'WC_REST_Posts_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php', + 'WC_REST_Product_Attribute_Terms_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php', + 'WC_REST_Product_Attribute_Terms_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php', + 'WC_REST_Product_Attribute_Terms_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php', + 'WC_REST_Product_Attributes_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-attributes-controller.php', + 'WC_REST_Product_Attributes_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php', + 'WC_REST_Product_Attributes_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php', + 'WC_REST_Product_Categories_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php', + 'WC_REST_Product_Categories_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php', + 'WC_REST_Product_Categories_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php', + 'WC_REST_Product_Reviews_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php', + 'WC_REST_Product_Reviews_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php', + 'WC_REST_Product_Reviews_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php', + 'WC_REST_Product_Shipping_Classes_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php', + 'WC_REST_Product_Shipping_Classes_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php', + 'WC_REST_Product_Shipping_Classes_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php', + 'WC_REST_Product_Tags_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-tags-controller.php', + 'WC_REST_Product_Tags_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php', + 'WC_REST_Product_Tags_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php', + 'WC_REST_Product_Variations_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php', + 'WC_REST_Product_Variations_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php', + 'WC_REST_Products_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php', + 'WC_REST_Products_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php', + 'WC_REST_Products_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php', + 'WC_REST_Report_Coupons_Totals_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php', + 'WC_REST_Report_Customers_Totals_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php', + 'WC_REST_Report_Orders_Totals_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php', + 'WC_REST_Report_Products_Totals_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php', + 'WC_REST_Report_Reviews_Totals_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php', + 'WC_REST_Report_Sales_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-sales-controller.php', + 'WC_REST_Report_Sales_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php', + 'WC_REST_Report_Sales_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php', + 'WC_REST_Report_Top_Sellers_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php', + 'WC_REST_Report_Top_Sellers_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php', + 'WC_REST_Report_Top_Sellers_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php', + 'WC_REST_Reports_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php', + 'WC_REST_Reports_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php', + 'WC_REST_Reports_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-reports-v2-controller.php', + 'WC_REST_Setting_Options_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php', + 'WC_REST_Setting_Options_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php', + 'WC_REST_Settings_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php', + 'WC_REST_Settings_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php', + 'WC_REST_Shipping_Methods_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-methods-controller.php', + 'WC_REST_Shipping_Methods_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php', + 'WC_REST_Shipping_Zone_Locations_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php', + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php', + 'WC_REST_Shipping_Zone_Methods_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php', + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php', + 'WC_REST_Shipping_Zones_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller.php', + 'WC_REST_Shipping_Zones_Controller_Base' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php', + 'WC_REST_Shipping_Zones_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php', + 'WC_REST_System_Status_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-controller.php', + 'WC_REST_System_Status_Tools_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-tools-controller.php', + 'WC_REST_System_Status_Tools_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php', + 'WC_REST_System_Status_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php', + 'WC_REST_Tax_Classes_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-tax-classes-controller.php', + 'WC_REST_Tax_Classes_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php', + 'WC_REST_Tax_Classes_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php', + 'WC_REST_Taxes_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-taxes-controller.php', + 'WC_REST_Taxes_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php', + 'WC_REST_Taxes_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-taxes-v2-controller.php', + 'WC_REST_Terms_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php', + 'WC_REST_Webhook_Deliveries_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php', + 'WC_REST_Webhook_Deliveries_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php', + 'WC_REST_Webhooks_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version3/class-wc-rest-webhooks-controller.php', + 'WC_REST_Webhooks_V1_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php', + 'WC_REST_Webhooks_V2_Controller' => __DIR__ . '/../..' . '/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit08a6ad0ed5b58cf461fde712d9bcae99::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit08a6ad0ed5b58cf461fde712d9bcae99::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit08a6ad0ed5b58cf461fde712d9bcae99::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installed.json b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installed.json new file mode 100644 index 0000000..85fd90f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installed.json @@ -0,0 +1,719 @@ +{ + "packages": [ + { + "name": "automattic/jetpack-autoloader", + "version": "v2.2.0", + "version_normalized": "2.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/Automattic/jetpack-autoloader.git", + "reference": "66a5d150b3928be718d86696f85631a7f0b98a7b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/66a5d150b3928be718d86696f85631a7f0b98a7b", + "reference": "66a5d150b3928be718d86696f85631a7f0b98a7b", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1 || ^2.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5" + }, + "time": "2020-08-14T20:34:36+00:00", + "type": "composer-plugin", + "extra": { + "class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin" + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Automattic\\Jetpack\\Autoloader\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Creates a custom autoloader for a plugin or theme.", + "support": { + "source": "https://github.com/Automattic/jetpack-autoloader/tree/master" + }, + "install-path": "../automattic/jetpack-autoloader" + }, + { + "name": "automattic/jetpack-constants", + "version": "v1.5.0", + "version_normalized": "1.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/Automattic/jetpack-constants.git", + "reference": "9827a2f446b8c4faafaf1c740483031c073a381d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Automattic/jetpack-constants/zipball/9827a2f446b8c4faafaf1c740483031c073a381d", + "reference": "9827a2f446b8c4faafaf1c740483031c073a381d", + "shasum": "" + }, + "require-dev": { + "php-mock/php-mock": "^2.1", + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5" + }, + "time": "2020-08-13T14:33:09+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "A wrapper for defining constants in a more testable way.", + "support": { + "source": "https://github.com/Automattic/jetpack-constants/tree/master" + }, + "install-path": "../automattic/jetpack-constants" + }, + { + "name": "composer/installers", + "version": "v1.9.0", + "version_normalized": "1.9.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || 2.0.*@dev", + "composer/semver": "1.0.* || 2.0.*@dev", + "phpunit/phpunit": "^4.8.36", + "sebastian/comparator": "^1.2.4", + "symfony/process": "^2.3" + }, + "time": "2020-04-07T06:57:05+00:00", + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v1.9.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "install-path": "./installers" + }, + { + "name": "league/container", + "version": "3.3.3", + "version_normalized": "3.3.3.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/container.git", + "reference": "7dc67bdf89efc338e674863c0ea70a63efe4de05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/container/zipball/7dc67bdf89efc338e674863c0ea70a63efe4de05", + "reference": "7dc67bdf89efc338e674863c0ea70a63efe4de05", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/container": "^1.0" + }, + "provide": { + "psr/container-implementation": "^1.0" + }, + "replace": { + "orno/di": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0", + "squizlabs/php_codesniffer": "^3.3" + }, + "time": "2020-09-28T13:38:44+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Container\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Bennett", + "email": "philipobenito@gmail.com", + "homepage": "http://www.philipobenito.com", + "role": "Developer" + } + ], + "description": "A fast and intuitive dependency injection container.", + "homepage": "https://github.com/thephpleague/container", + "keywords": [ + "container", + "dependency", + "di", + "injection", + "league", + "provider", + "service" + ], + "support": { + "issues": "https://github.com/thephpleague/container/issues", + "source": "https://github.com/thephpleague/container/tree/3.3.3" + }, + "funding": [ + { + "url": "https://github.com/philipobenito", + "type": "github" + } + ], + "install-path": "../league/container" + }, + { + "name": "maxmind-db/reader", + "version": "v1.6.0", + "version_normalized": "1.6.0.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git", + "reference": "febd4920bf17c1da84cef58e56a8227dfb37fbe4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/febd4920bf17c1da84cef58e56a8227dfb37fbe4", + "reference": "febd4920bf17c1da84cef58e56a8227dfb37fbe4", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "conflict": { + "ext-maxminddb": "<1.6.0,>=2.0.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "2.*", + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpcov": "^3.0", + "phpunit/phpunit": "5.*", + "squizlabs/php_codesniffer": "3.*" + }, + "suggest": { + "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups" + }, + "time": "2019-12-19T22:59:03+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MaxMind\\Db\\": "src/MaxMind/Db" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "https://www.maxmind.com/" + } + ], + "description": "MaxMind DB Reader API", + "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php", + "keywords": [ + "database", + "geoip", + "geoip2", + "geolocation", + "maxmind" + ], + "support": { + "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues", + "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.6.0" + }, + "install-path": "../maxmind-db/reader" + }, + { + "name": "pelago/emogrifier", + "version": "v3.1.0", + "version_normalized": "3.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/MyIntervals/emogrifier.git", + "reference": "f6a5c7d44612d86c3901c93f1592f5440e6b2cd8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/f6a5c7d44612d86c3901c93f1592f5440e6b2cd8", + "reference": "f6a5c7d44612d86c3901c93f1592f5440e6b2cd8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.6 || ~7.0 || ~7.1 || ~7.2 || ~7.3 || ~7.4", + "symfony/css-selector": "^2.8 || ^3.0 || ^4.0 || ^5.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.15.3", + "phpmd/phpmd": "^2.7.0", + "phpunit/phpunit": "^5.7.27", + "squizlabs/php_codesniffer": "^3.5.0" + }, + "time": "2019-12-26T19:37:31+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Pelago\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Klee", + "email": "github@oliverklee.de" + }, + { + "name": "Zoli Szabó", + "email": "zoli.szabo+github@gmail.com" + }, + { + "name": "John Reeve", + "email": "jreeve@pelagodesign.com" + }, + { + "name": "Jake Hotson", + "email": "jake@qzdesign.co.uk" + }, + { + "name": "Cameron Brooks" + }, + { + "name": "Jaime Prado" + } + ], + "description": "Converts CSS styles into inline style attributes in your HTML code", + "homepage": "https://www.myintervals.com/emogrifier.php", + "keywords": [ + "css", + "email", + "pre-processing" + ], + "support": { + "issues": "https://github.com/MyIntervals/emogrifier/issues", + "source": "https://github.com/MyIntervals/emogrifier" + }, + "install-path": "../pelago/emogrifier" + }, + { + "name": "psr/container", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2017-02-14T16:28:37+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, + "install-path": "../psr/container" + }, + { + "name": "symfony/css-selector", + "version": "v3.3.6", + "version_normalized": "3.3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "4d882dced7b995d5274293039370148e291808f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/4d882dced7b995d5274293039370148e291808f2", + "reference": "4d882dced7b995d5274293039370148e291808f2", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "time": "2017-05-01T15:01:29+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/master" + }, + "install-path": "../symfony/css-selector" + }, + { + "name": "woocommerce/action-scheduler", + "version": "3.1.6", + "version_normalized": "3.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/woocommerce/action-scheduler.git", + "reference": "275d0ba54b1c263dfc62688de2fa9a25a373edf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/woocommerce/action-scheduler/zipball/275d0ba54b1c263dfc62688de2fa9a25a373edf8", + "reference": "275d0ba54b1c263dfc62688de2fa9a25a373edf8", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^5.6", + "woocommerce/woocommerce-sniffs": "0.0.8", + "wp-cli/wp-cli": "~1.5.1" + }, + "time": "2020-05-12T16:22:33+00:00", + "type": "wordpress-plugin", + "extra": { + "scripts-description": { + "test": "Run unit tests", + "phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer", + "phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier" + } + }, + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "description": "Action Scheduler for WordPress and WooCommerce", + "homepage": "https://actionscheduler.org/", + "support": { + "issues": "https://github.com/woocommerce/action-scheduler/issues", + "source": "https://github.com/woocommerce/action-scheduler/tree/master" + }, + "install-path": "../../packages/action-scheduler" + }, + { + "name": "woocommerce/woocommerce-admin", + "version": "1.7.3", + "version_normalized": "1.7.3.0", + "source": { + "type": "git", + "url": "https://github.com/woocommerce/woocommerce-admin.git", + "reference": "16de972f319e5e6fc8dbebf5024dd263234f39e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/16de972f319e5e6fc8dbebf5024dd263234f39e0", + "reference": "16de972f319e5e6fc8dbebf5024dd263234f39e0", + "shasum": "" + }, + "require": { + "automattic/jetpack-autoloader": "^2.2.0", + "composer/installers": "^1.9.0", + "php": ">=5.6|>=7.0" + }, + "require-dev": { + "phpunit/phpunit": "7.5.20", + "suin/phpcs-psr4-sniff": "^2.2", + "woocommerce/woocommerce-sniffs": "0.1.0" + }, + "time": "2020-12-03T21:12:01+00:00", + "type": "wordpress-plugin", + "extra": { + "scripts-description": { + "test": "Run unit tests", + "phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer", + "phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Automattic\\WooCommerce\\Admin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "description": "A modern, javascript-driven WooCommerce Admin experience.", + "homepage": "https://github.com/woocommerce/woocommerce-admin", + "support": { + "issues": "https://github.com/woocommerce/woocommerce-admin/issues", + "source": "https://github.com/woocommerce/woocommerce-admin/tree/v1.7.3" + }, + "install-path": "../../packages/woocommerce-admin" + }, + { + "name": "woocommerce/woocommerce-blocks", + "version": "v3.8.1", + "version_normalized": "3.8.1.0", + "source": { + "type": "git", + "url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git", + "reference": "e5aef9eddd13c5511ba673eb70ed8cb3e80d828c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/e5aef9eddd13c5511ba673eb70ed8cb3e80d828c", + "reference": "e5aef9eddd13c5511ba673eb70ed8cb3e80d828c", + "shasum": "" + }, + "require": { + "automattic/jetpack-autoloader": "^2.0.0", + "composer/installers": "^1.7.0" + }, + "require-dev": { + "phpunit/phpunit": "6.5.14", + "woocommerce/woocommerce-sniffs": "0.1.0" + }, + "time": "2020-11-23T20:48:39+00:00", + "type": "wordpress-plugin", + "extra": { + "scripts-description": { + "phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer", + "phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Automattic\\WooCommerce\\Blocks\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "description": "WooCommerce blocks for the Gutenberg editor.", + "homepage": "https://woocommerce.com/", + "keywords": [ + "blocks", + "gutenberg", + "woocommerce" + ], + "support": { + "issues": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues", + "source": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/tree/v3.8.1" + }, + "install-path": "../../packages/woocommerce-blocks" + } + ], + "dev": false, + "dev-package-names": [] +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installed.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installed.php new file mode 100644 index 0000000..0ac8857 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installed.php @@ -0,0 +1,151 @@ + + array ( + 'pretty_version' => 'dev-release/4.8', + 'version' => 'dev-release/4.8', + 'aliases' => + array ( + ), + 'reference' => 'c9a204b0c11d252a56c90ffd1fa947d5cadbb7b1', + 'name' => 'woocommerce/woocommerce', + ), + 'versions' => + array ( + 'automattic/jetpack-autoloader' => + array ( + 'pretty_version' => 'v2.2.0', + 'version' => '2.2.0.0', + 'aliases' => + array ( + ), + 'reference' => '66a5d150b3928be718d86696f85631a7f0b98a7b', + ), + 'automattic/jetpack-constants' => + array ( + 'pretty_version' => 'v1.5.0', + 'version' => '1.5.0.0', + 'aliases' => + array ( + ), + 'reference' => '9827a2f446b8c4faafaf1c740483031c073a381d', + ), + 'composer/installers' => + array ( + 'pretty_version' => 'v1.9.0', + 'version' => '1.9.0.0', + 'aliases' => + array ( + ), + 'reference' => 'b93bcf0fa1fccb0b7d176b0967d969691cd74cca', + ), + 'league/container' => + array ( + 'pretty_version' => '3.3.3', + 'version' => '3.3.3.0', + 'aliases' => + array ( + ), + 'reference' => '7dc67bdf89efc338e674863c0ea70a63efe4de05', + ), + 'maxmind-db/reader' => + array ( + 'pretty_version' => 'v1.6.0', + 'version' => '1.6.0.0', + 'aliases' => + array ( + ), + 'reference' => 'febd4920bf17c1da84cef58e56a8227dfb37fbe4', + ), + 'orno/di' => + array ( + 'replaced' => + array ( + 0 => '~2.0', + ), + ), + 'pelago/emogrifier' => + array ( + 'pretty_version' => 'v3.1.0', + 'version' => '3.1.0.0', + 'aliases' => + array ( + ), + 'reference' => 'f6a5c7d44612d86c3901c93f1592f5440e6b2cd8', + ), + 'psr/container' => + array ( + 'pretty_version' => '1.0.0', + 'version' => '1.0.0.0', + 'aliases' => + array ( + ), + 'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f', + ), + 'psr/container-implementation' => + array ( + 'provided' => + array ( + 0 => '^1.0', + ), + ), + 'roundcube/plugin-installer' => + array ( + 'replaced' => + array ( + 0 => '*', + ), + ), + 'shama/baton' => + array ( + 'replaced' => + array ( + 0 => '*', + ), + ), + 'symfony/css-selector' => + array ( + 'pretty_version' => 'v3.3.6', + 'version' => '3.3.6.0', + 'aliases' => + array ( + ), + 'reference' => '4d882dced7b995d5274293039370148e291808f2', + ), + 'woocommerce/action-scheduler' => + array ( + 'pretty_version' => '3.1.6', + 'version' => '3.1.6.0', + 'aliases' => + array ( + ), + 'reference' => '275d0ba54b1c263dfc62688de2fa9a25a373edf8', + ), + 'woocommerce/woocommerce' => + array ( + 'pretty_version' => 'dev-release/4.8', + 'version' => 'dev-release/4.8', + 'aliases' => + array ( + ), + 'reference' => 'c9a204b0c11d252a56c90ffd1fa947d5cadbb7b1', + ), + 'woocommerce/woocommerce-admin' => + array ( + 'pretty_version' => '1.7.3', + 'version' => '1.7.3.0', + 'aliases' => + array ( + ), + 'reference' => '16de972f319e5e6fc8dbebf5024dd263234f39e0', + ), + 'woocommerce/woocommerce-blocks' => + array ( + 'pretty_version' => 'v3.8.1', + 'version' => '3.8.1.0', + 'aliases' => + array ( + ), + 'reference' => 'e5aef9eddd13c5511ba673eb70ed8cb3e80d828c', + ), + ), +); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/LICENSE b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/LICENSE new file mode 100644 index 0000000..85f97fc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Kyle Robinson Young + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AglInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AglInstaller.php new file mode 100644 index 0000000..01b8a41 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AglInstaller.php @@ -0,0 +1,21 @@ + 'More/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) { + return strtoupper($matches[1]); + }, $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php new file mode 100644 index 0000000..79a0e95 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php @@ -0,0 +1,9 @@ + 'ext/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php new file mode 100644 index 0000000..89d7ad9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php @@ -0,0 +1,11 @@ + 'addons/modules/{$name}/', + 'component' => 'addons/components/{$name}/', + 'service' => 'addons/services/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php new file mode 100644 index 0000000..22dad1b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php @@ -0,0 +1,49 @@ + 'Modules/{$name}/', + 'theme' => 'Themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type asgard-module, cut off a trailing '-plugin' if present. + * + * For package type asgard-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'asgard-module') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'asgard-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php new file mode 100644 index 0000000..d62fd8f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php new file mode 100644 index 0000000..d9d6073 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php @@ -0,0 +1,137 @@ +composer = $composer; + $this->package = $package; + $this->io = $io; + } + + /** + * Return the install path based on package type. + * + * @param PackageInterface $package + * @param string $frameworkType + * @return string + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + $type = $this->package->getType(); + + $prettyName = $this->package->getPrettyName(); + if (strpos($prettyName, '/') !== false) { + list($vendor, $name) = explode('/', $prettyName); + } else { + $vendor = ''; + $name = $prettyName; + } + + $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type')); + + $extra = $package->getExtra(); + if (!empty($extra['installer-name'])) { + $availableVars['name'] = $extra['installer-name']; + } + + if ($this->composer->getPackage()) { + $extra = $this->composer->getPackage()->getExtra(); + if (!empty($extra['installer-paths'])) { + $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor); + if ($customPath !== false) { + return $this->templatePath($customPath, $availableVars); + } + } + } + + $packageType = substr($type, strlen($frameworkType) + 1); + $locations = $this->getLocations(); + if (!isset($locations[$packageType])) { + throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type)); + } + + return $this->templatePath($locations[$packageType], $availableVars); + } + + /** + * For an installer to override to modify the vars per installer. + * + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + return $vars; + } + + /** + * Gets the installer's locations + * + * @return array + */ + public function getLocations() + { + return $this->locations; + } + + /** + * Replace vars in a path + * + * @param string $path + * @param array $vars + * @return string + */ + protected function templatePath($path, array $vars = array()) + { + if (strpos($path, '{') !== false) { + extract($vars); + preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches); + if (!empty($matches[1])) { + foreach ($matches[1] as $var) { + $path = str_replace('{$' . $var . '}', $$var, $path); + } + } + } + + return $path; + } + + /** + * Search through a passed paths array for a custom install path. + * + * @param array $paths + * @param string $name + * @param string $type + * @param string $vendor = NULL + * @return string + */ + protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL) + { + foreach ($paths as $path => $names) { + $names = (array) $names; + if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) { + return $path; + } + } + + return false; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php new file mode 100644 index 0000000..e80cd1e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php @@ -0,0 +1,126 @@ +.`. + * - `bitrix-d7-component` — copy the component to directory `bitrix/components//`. + * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/_`. + * + * You can set custom path to directory with Bitrix kernel in `composer.json`: + * + * ```json + * { + * "extra": { + * "bitrix-dir": "s1/bitrix" + * } + * } + * ``` + * + * @author Nik Samokhvalov + * @author Denis Kulichkin + */ +class BitrixInstaller extends BaseInstaller +{ + protected $locations = array( + 'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/', + 'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/', + 'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/', + ); + + /** + * @var array Storage for informations about duplicates at all the time of installation packages. + */ + private static $checkedDuplicates = array(); + + /** + * {@inheritdoc} + */ + public function inflectPackageVars($vars) + { + if ($this->composer->getPackage()) { + $extra = $this->composer->getPackage()->getExtra(); + + if (isset($extra['bitrix-dir'])) { + $vars['bitrix_dir'] = $extra['bitrix-dir']; + } + } + + if (!isset($vars['bitrix_dir'])) { + $vars['bitrix_dir'] = 'bitrix'; + } + + return parent::inflectPackageVars($vars); + } + + /** + * {@inheritdoc} + */ + protected function templatePath($path, array $vars = array()) + { + $templatePath = parent::templatePath($path, $vars); + $this->checkDuplicates($templatePath, $vars); + + return $templatePath; + } + + /** + * Duplicates search packages. + * + * @param string $path + * @param array $vars + */ + protected function checkDuplicates($path, array $vars = array()) + { + $packageType = substr($vars['type'], strlen('bitrix') + 1); + $localDir = explode('/', $vars['bitrix_dir']); + array_pop($localDir); + $localDir[] = 'local'; + $localDir = implode('/', $localDir); + + $oldPath = str_replace( + array('{$bitrix_dir}', '{$name}'), + array($localDir, $vars['name']), + $this->locations[$packageType] + ); + + if (in_array($oldPath, static::$checkedDuplicates)) { + return; + } + + if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) { + + $this->io->writeError(' Duplication of packages:'); + $this->io->writeError(' Package ' . $oldPath . ' will be called instead package ' . $path . ''); + + while (true) { + switch ($this->io->ask(' Delete ' . $oldPath . ' [y,n,?]? ', '?')) { + case 'y': + $fs = new Filesystem(); + $fs->removeDirectory($oldPath); + break 2; + + case 'n': + break 2; + + case '?': + default: + $this->io->writeError(array( + ' y - delete package ' . $oldPath . ' and to continue with the installation', + ' n - don\'t delete and to continue with the installation', + )); + $this->io->writeError(' ? - print help'); + break; + } + } + } + + static::$checkedDuplicates[] = $oldPath; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php new file mode 100644 index 0000000..da3aad2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php @@ -0,0 +1,9 @@ + 'Packages/{$vendor}/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php new file mode 100644 index 0000000..71ee2ef --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php @@ -0,0 +1,72 @@ + 'Plugin/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + if ($this->matchesCakeVersion('>=', '3.0.0')) { + return $vars; + } + + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + + return $vars; + } + + /** + * Change the default plugin location when cakephp >= 3.0 + */ + public function getLocations() + { + if ($this->matchesCakeVersion('>=', '3.0.0')) { + $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/'; + } + return $this->locations; + } + + /** + * Check if CakePHP version matches against a version + * + * @param string $matcher + * @param string $version + * @return bool + */ + protected function matchesCakeVersion($matcher, $version) + { + if (class_exists('Composer\Semver\Constraint\MultiConstraint')) { + $multiClass = 'Composer\Semver\Constraint\MultiConstraint'; + $constraintClass = 'Composer\Semver\Constraint\Constraint'; + } else { + $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint'; + $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint'; + } + + $repositoryManager = $this->composer->getRepositoryManager(); + if (! $repositoryManager) { + return false; + } + + $repos = $repositoryManager->getLocalRepository(); + if (!$repos) { + return false; + } + + return $repos->findPackage('cakephp/cakephp', new $constraintClass($matcher, $version)) !== null; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php new file mode 100644 index 0000000..ab2f9aa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php @@ -0,0 +1,11 @@ + 'Chef/{$vendor}/{$name}/', + 'role' => 'Chef/roles/{$name}/', + ); +} + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php new file mode 100644 index 0000000..6673aea --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php @@ -0,0 +1,9 @@ + 'ext/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php new file mode 100644 index 0000000..c887815 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php @@ -0,0 +1,10 @@ + 'CCF/orbit/{$name}/', + 'theme' => 'CCF/app/themes/{$name}/', + ); +} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php new file mode 100644 index 0000000..c7816df --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php @@ -0,0 +1,34 @@ + 'cockpit/modules/addons/{$name}/', + ); + + /** + * Format module name. + * + * Strip `module-` prefix from package name. + * + * @param array @vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'cockpit-module') { + return $this->inflectModuleVars($vars); + } + + return $vars; + } + + public function inflectModuleVars($vars) + { + $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php new file mode 100644 index 0000000..3b4a4ec --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php @@ -0,0 +1,11 @@ + 'application/libraries/{$name}/', + 'third-party' => 'application/third_party/{$name}/', + 'module' => 'application/modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php new file mode 100644 index 0000000..5c01baf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php @@ -0,0 +1,13 @@ + 'concrete/', + 'block' => 'application/blocks/{$name}/', + 'package' => 'packages/{$name}/', + 'theme' => 'application/themes/{$name}/', + 'update' => 'updates/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php new file mode 100644 index 0000000..d37a77a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php @@ -0,0 +1,35 @@ + 'craft/plugins/{$name}/', + ); + + /** + * Strip `craft-` prefix and/or `-plugin` suffix from package names + * + * @param array $vars + * + * @return array + */ + final public function inflectPackageVars($vars) + { + return $this->inflectPluginVars($vars); + } + + private function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']); + $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php new file mode 100644 index 0000000..d94219d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php @@ -0,0 +1,21 @@ + 'Plugin/{$name}/', + 'theme' => 'View/Themed/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name'])); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php new file mode 100644 index 0000000..f4837a6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php @@ -0,0 +1,10 @@ + 'app/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php new file mode 100644 index 0000000..7078816 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php @@ -0,0 +1,10 @@ + 'modules/{$vendor}/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php new file mode 100644 index 0000000..cfd638d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php @@ -0,0 +1,50 @@ + 'lib/plugins/{$name}/', + 'template' => 'lib/tpl/{$name}/', + ); + + /** + * Format package name. + * + * For package type dokuwiki-plugin, cut off a trailing '-plugin', + * or leading dokuwiki_ if present. + * + * For package type dokuwiki-template, cut off a trailing '-template' if present. + * + */ + public function inflectPackageVars($vars) + { + + if ($vars['type'] === 'dokuwiki-plugin') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'dokuwiki-template') { + return $this->inflectTemplateVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']); + $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']); + + return $vars; + } + + protected function inflectTemplateVars($vars) + { + $vars['name'] = preg_replace('/-template$/', '', $vars['name']); + $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']); + + return $vars; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php new file mode 100644 index 0000000..21f7e8e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php @@ -0,0 +1,16 @@ + + */ +class DolibarrInstaller extends BaseInstaller +{ + //TODO: Add support for scripts and themes + protected $locations = array( + 'module' => 'htdocs/custom/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php new file mode 100644 index 0000000..7328239 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php @@ -0,0 +1,22 @@ + 'core/', + 'module' => 'modules/{$name}/', + 'theme' => 'themes/{$name}/', + 'library' => 'libraries/{$name}/', + 'profile' => 'profiles/{$name}/', + 'database-driver' => 'drivers/lib/Drupal/Driver/Database/{$name}/', + 'drush' => 'drush/{$name}/', + 'custom-theme' => 'themes/custom/{$name}/', + 'custom-module' => 'modules/custom/{$name}/', + 'custom-profile' => 'profiles/custom/{$name}/', + 'drupal-multisite' => 'sites/{$name}/', + 'console' => 'console/{$name}/', + 'console-language' => 'console/language/{$name}/', + 'config' => 'config/sync/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php new file mode 100644 index 0000000..c0bb609 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php @@ -0,0 +1,9 @@ + 'mod/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php new file mode 100644 index 0000000..6f3dc97 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php @@ -0,0 +1,12 @@ + 'components/{$name}/', + 'module' => 'modules/{$name}/', + 'plugin' => 'plugins/{$name}/', + 'template' => 'templates/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php new file mode 100644 index 0000000..d5321a8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php @@ -0,0 +1,29 @@ + 'system/expressionengine/third_party/{$name}/', + 'theme' => 'themes/third_party/{$name}/', + ); + + private $ee3Locations = array( + 'addon' => 'system/user/addons/{$name}/', + 'theme' => 'themes/user/{$name}/', + ); + + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + + $version = "{$frameworkType}Locations"; + $this->locations = $this->$version; + + return parent::getInstallPath($package, $frameworkType); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php new file mode 100644 index 0000000..f30ebcc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php @@ -0,0 +1,10 @@ + 'web/assets/ezplatform/', + 'assets' => 'web/assets/ezplatform/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php new file mode 100644 index 0000000..6eba2e3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php @@ -0,0 +1,11 @@ + 'fuel/app/modules/{$name}/', + 'package' => 'fuel/packages/{$name}/', + 'theme' => 'fuel/app/themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php new file mode 100644 index 0000000..29d980b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php @@ -0,0 +1,9 @@ + 'components/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/GravInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/GravInstaller.php new file mode 100644 index 0000000..dbe63e0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/GravInstaller.php @@ -0,0 +1,30 @@ + 'user/plugins/{$name}/', + 'theme' => 'user/themes/{$name}/', + ); + + /** + * Format package name + * + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $restrictedWords = implode('|', array_keys($this->locations)); + + $vars['name'] = strtolower($vars['name']); + $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui', + '$1', + $vars['name'] + ); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php new file mode 100644 index 0000000..8fe017f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php @@ -0,0 +1,25 @@ + 'plugins/{$name}/', + 'theme' => 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php new file mode 100644 index 0000000..5e2142e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php @@ -0,0 +1,11 @@ + 'templates/{$name}/', + 'module' => 'application/modules/{$name}/', + 'library' => 'application/libraries/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Installer.php new file mode 100644 index 0000000..d1d43b9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Installer.php @@ -0,0 +1,280 @@ + 'AimeosInstaller', + 'asgard' => 'AsgardInstaller', + 'attogram' => 'AttogramInstaller', + 'agl' => 'AglInstaller', + 'annotatecms' => 'AnnotateCmsInstaller', + 'bitrix' => 'BitrixInstaller', + 'bonefish' => 'BonefishInstaller', + 'cakephp' => 'CakePHPInstaller', + 'chef' => 'ChefInstaller', + 'civicrm' => 'CiviCrmInstaller', + 'ccframework' => 'ClanCatsFrameworkInstaller', + 'cockpit' => 'CockpitInstaller', + 'codeigniter' => 'CodeIgniterInstaller', + 'concrete5' => 'Concrete5Installer', + 'craft' => 'CraftInstaller', + 'croogo' => 'CroogoInstaller', + 'dframe' => 'DframeInstaller', + 'dokuwiki' => 'DokuWikiInstaller', + 'dolibarr' => 'DolibarrInstaller', + 'decibel' => 'DecibelInstaller', + 'drupal' => 'DrupalInstaller', + 'elgg' => 'ElggInstaller', + 'eliasis' => 'EliasisInstaller', + 'ee3' => 'ExpressionEngineInstaller', + 'ee2' => 'ExpressionEngineInstaller', + 'ezplatform' => 'EzPlatformInstaller', + 'fuel' => 'FuelInstaller', + 'fuelphp' => 'FuelphpInstaller', + 'grav' => 'GravInstaller', + 'hurad' => 'HuradInstaller', + 'imagecms' => 'ImageCMSInstaller', + 'itop' => 'ItopInstaller', + 'joomla' => 'JoomlaInstaller', + 'kanboard' => 'KanboardInstaller', + 'kirby' => 'KirbyInstaller', + 'known' => 'KnownInstaller', + 'kodicms' => 'KodiCMSInstaller', + 'kohana' => 'KohanaInstaller', + 'lms' => 'LanManagementSystemInstaller', + 'laravel' => 'LaravelInstaller', + 'lavalite' => 'LavaLiteInstaller', + 'lithium' => 'LithiumInstaller', + 'magento' => 'MagentoInstaller', + 'majima' => 'MajimaInstaller', + 'mantisbt' => 'MantisBTInstaller', + 'mako' => 'MakoInstaller', + 'maya' => 'MayaInstaller', + 'mautic' => 'MauticInstaller', + 'mediawiki' => 'MediaWikiInstaller', + 'microweber' => 'MicroweberInstaller', + 'modulework' => 'MODULEWorkInstaller', + 'modx' => 'ModxInstaller', + 'modxevo' => 'MODXEvoInstaller', + 'moodle' => 'MoodleInstaller', + 'october' => 'OctoberInstaller', + 'ontowiki' => 'OntoWikiInstaller', + 'oxid' => 'OxidInstaller', + 'osclass' => 'OsclassInstaller', + 'pxcms' => 'PxcmsInstaller', + 'phpbb' => 'PhpBBInstaller', + 'pimcore' => 'PimcoreInstaller', + 'piwik' => 'PiwikInstaller', + 'plentymarkets'=> 'PlentymarketsInstaller', + 'ppi' => 'PPIInstaller', + 'puppet' => 'PuppetInstaller', + 'radphp' => 'RadPHPInstaller', + 'phifty' => 'PhiftyInstaller', + 'porto' => 'PortoInstaller', + 'redaxo' => 'RedaxoInstaller', + 'redaxo5' => 'Redaxo5Installer', + 'reindex' => 'ReIndexInstaller', + 'roundcube' => 'RoundcubeInstaller', + 'shopware' => 'ShopwareInstaller', + 'sitedirect' => 'SiteDirectInstaller', + 'silverstripe' => 'SilverStripeInstaller', + 'smf' => 'SMFInstaller', + 'sydes' => 'SyDESInstaller', + 'sylius' => 'SyliusInstaller', + 'symfony1' => 'Symfony1Installer', + 'tao' => 'TaoInstaller', + 'thelia' => 'TheliaInstaller', + 'tusk' => 'TuskInstaller', + 'typo3-cms' => 'TYPO3CmsInstaller', + 'typo3-flow' => 'TYPO3FlowInstaller', + 'userfrosting' => 'UserFrostingInstaller', + 'vanilla' => 'VanillaInstaller', + 'whmcs' => 'WHMCSInstaller', + 'wolfcms' => 'WolfCMSInstaller', + 'wordpress' => 'WordPressInstaller', + 'yawik' => 'YawikInstaller', + 'zend' => 'ZendInstaller', + 'zikula' => 'ZikulaInstaller', + 'prestashop' => 'PrestashopInstaller' + ); + + /** + * Installer constructor. + * + * Disables installers specified in main composer extra installer-disable + * list + * + * @param IOInterface $io + * @param Composer $composer + * @param string $type + * @param Filesystem|null $filesystem + * @param BinaryInstaller|null $binaryInstaller + */ + public function __construct( + IOInterface $io, + Composer $composer, + $type = 'library', + Filesystem $filesystem = null, + BinaryInstaller $binaryInstaller = null + ) { + parent::__construct($io, $composer, $type, $filesystem, + $binaryInstaller); + $this->removeDisabledInstallers(); + } + + /** + * {@inheritDoc} + */ + public function getInstallPath(PackageInterface $package) + { + $type = $package->getType(); + $frameworkType = $this->findFrameworkType($type); + + if ($frameworkType === false) { + throw new \InvalidArgumentException( + 'Sorry the package type of this package is not yet supported.' + ); + } + + $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; + $installer = new $class($package, $this->composer, $this->getIO()); + + return $installer->getInstallPath($package, $frameworkType); + } + + public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package) + { + parent::uninstall($repo, $package); + $installPath = $this->getPackageBasePath($package); + $this->io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? 'deleted' : 'not deleted')); + } + + /** + * {@inheritDoc} + */ + public function supports($packageType) + { + $frameworkType = $this->findFrameworkType($packageType); + + if ($frameworkType === false) { + return false; + } + + $locationPattern = $this->getLocationPattern($frameworkType); + + return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1; + } + + /** + * Finds a supported framework type if it exists and returns it + * + * @param string $type + * @return string + */ + protected function findFrameworkType($type) + { + $frameworkType = false; + + krsort($this->supportedTypes); + + foreach ($this->supportedTypes as $key => $val) { + if ($key === substr($type, 0, strlen($key))) { + $frameworkType = substr($type, 0, strlen($key)); + break; + } + } + + return $frameworkType; + } + + /** + * Get the second part of the regular expression to check for support of a + * package type + * + * @param string $frameworkType + * @return string + */ + protected function getLocationPattern($frameworkType) + { + $pattern = false; + if (!empty($this->supportedTypes[$frameworkType])) { + $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; + /** @var BaseInstaller $framework */ + $framework = new $frameworkClass(null, $this->composer, $this->getIO()); + $locations = array_keys($framework->getLocations()); + $pattern = $locations ? '(' . implode('|', $locations) . ')' : false; + } + + return $pattern ? : '(\w+)'; + } + + /** + * Get I/O object + * + * @return IOInterface + */ + private function getIO() + { + return $this->io; + } + + /** + * Look for installers set to be disabled in composer's extra config and + * remove them from the list of supported installers. + * + * Globals: + * - true, "all", and "*" - disable all installers. + * - false - enable all installers (useful with + * wikimedia/composer-merge-plugin or similar) + * + * @return void + */ + protected function removeDisabledInstallers() + { + $extra = $this->composer->getPackage()->getExtra(); + + if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) { + // No installers are disabled + return; + } + + // Get installers to disable + $disable = $extra['installer-disable']; + + // Ensure $disabled is an array + if (!is_array($disable)) { + $disable = array($disable); + } + + // Check which installers should be disabled + $all = array(true, "all", "*"); + $intersect = array_intersect($all, $disable); + if (!empty($intersect)) { + // Disable all installers + $this->supportedTypes = array(); + } else { + // Disable specified installers + foreach ($disable as $key => $installer) { + if (is_string($installer) && key_exists($installer, $this->supportedTypes)) { + unset($this->supportedTypes[$installer]); + } + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php new file mode 100644 index 0000000..c6c1b33 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php @@ -0,0 +1,9 @@ + 'extensions/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php new file mode 100644 index 0000000..9ee7759 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php @@ -0,0 +1,15 @@ + 'components/{$name}/', + 'module' => 'modules/{$name}/', + 'template' => 'templates/{$name}/', + 'plugin' => 'plugins/{$name}/', + 'library' => 'libraries/{$name}/', + ); + + // TODO: Add inflector for mod_ and com_ names +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php new file mode 100644 index 0000000..9cb7b8c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php @@ -0,0 +1,18 @@ + 'plugins/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php new file mode 100644 index 0000000..36b2f84 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php @@ -0,0 +1,11 @@ + 'site/plugins/{$name}/', + 'field' => 'site/fields/{$name}/', + 'tag' => 'site/tags/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php new file mode 100644 index 0000000..c5d08c5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php @@ -0,0 +1,11 @@ + 'IdnoPlugins/{$name}/', + 'theme' => 'Themes/{$name}/', + 'console' => 'ConsolePlugins/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php new file mode 100644 index 0000000..7143e23 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php @@ -0,0 +1,10 @@ + 'cms/plugins/{$name}/', + 'media' => 'cms/media/vendor/{$name}/' + ); +} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php new file mode 100644 index 0000000..dcd6d26 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php new file mode 100644 index 0000000..903143a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php @@ -0,0 +1,27 @@ + 'plugins/{$name}/', + 'template' => 'templates/{$name}/', + 'document-template' => 'documents/templates/{$name}/', + 'userpanel-module' => 'userpanel/modules/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php new file mode 100644 index 0000000..be4d53a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php @@ -0,0 +1,9 @@ + 'libraries/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php new file mode 100644 index 0000000..412c0b5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php @@ -0,0 +1,10 @@ + 'packages/{$vendor}/{$name}/', + 'theme' => 'public/themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php new file mode 100644 index 0000000..47bbd4c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php @@ -0,0 +1,10 @@ + 'libraries/{$name}/', + 'source' => 'libraries/_source/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php new file mode 100644 index 0000000..9c2e9fb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php new file mode 100644 index 0000000..5a66460 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php @@ -0,0 +1,16 @@ + 'assets/snippets/{$name}/', + 'plugin' => 'assets/plugins/{$name}/', + 'module' => 'assets/modules/{$name}/', + 'template' => 'assets/templates/{$name}/', + 'lib' => 'assets/lib/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php new file mode 100644 index 0000000..cf18e94 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php @@ -0,0 +1,11 @@ + 'app/design/frontend/{$name}/', + 'skin' => 'skin/frontend/default/{$name}/', + 'library' => 'lib/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php new file mode 100644 index 0000000..e463756 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php @@ -0,0 +1,37 @@ + 'plugins/{$name}/', + ); + + /** + * Transforms the names + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + return $this->correctPluginName($vars); + } + + /** + * Change hyphenated names to camelcase + * @param array $vars + * @return array + */ + private function correctPluginName($vars) + { + $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, $vars['name']); + $vars['name'] = ucfirst($camelCasedName); + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php new file mode 100644 index 0000000..ca3cfac --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php @@ -0,0 +1,9 @@ + 'app/packages/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php new file mode 100644 index 0000000..dadb1db --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php @@ -0,0 +1,23 @@ + 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php new file mode 100644 index 0000000..3e1ce2b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php @@ -0,0 +1,25 @@ + 'plugins/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format package name of mautic-plugins to CamelCase + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'mautic-plugin') { + $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, ucfirst($vars['name'])); + } + + return $vars; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php new file mode 100644 index 0000000..30a9167 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php @@ -0,0 +1,33 @@ + 'modules/{$name}/', + ); + + /** + * Format package name. + * + * For package type maya-module, cut off a trailing '-module' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'maya-module') { + return $this->inflectModuleVars($vars); + } + + return $vars; + } + + protected function inflectModuleVars($vars) + { + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php new file mode 100644 index 0000000..f5a8957 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php @@ -0,0 +1,51 @@ + 'core/', + 'extension' => 'extensions/{$name}/', + 'skin' => 'skins/{$name}/', + ); + + /** + * Format package name. + * + * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform + * to CamelCase keeping existing uppercase chars. + * + * For package type mediawiki-skin, cut off a trailing '-skin' if present. + * + */ + public function inflectPackageVars($vars) + { + + if ($vars['type'] === 'mediawiki-extension') { + return $this->inflectExtensionVars($vars); + } + + if ($vars['type'] === 'mediawiki-skin') { + return $this->inflectSkinVars($vars); + } + + return $vars; + } + + protected function inflectExtensionVars($vars) + { + $vars['name'] = preg_replace('/-extension$/', '', $vars['name']); + $vars['name'] = str_replace('-', ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectSkinVars($vars) + { + $vars['name'] = preg_replace('/-skin$/', '', $vars['name']); + + return $vars; + } + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php new file mode 100644 index 0000000..b7d9703 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php @@ -0,0 +1,119 @@ + 'userfiles/modules/{$install_item_dir}/', + 'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/', + 'template' => 'userfiles/templates/{$install_item_dir}/', + 'element' => 'userfiles/elements/{$install_item_dir}/', + 'vendor' => 'vendor/{$install_item_dir}/', + 'components' => 'components/{$install_item_dir}/' + ); + + /** + * Format package name. + * + * For package type microweber-module, cut off a trailing '-module' if present + * + * For package type microweber-template, cut off a trailing '-template' if present. + * + */ + public function inflectPackageVars($vars) + { + + + if ($this->package->getTargetDir()) { + $vars['install_item_dir'] = $this->package->getTargetDir(); + } else { + $vars['install_item_dir'] = $vars['name']; + if ($vars['type'] === 'microweber-template') { + return $this->inflectTemplateVars($vars); + } + if ($vars['type'] === 'microweber-templates') { + return $this->inflectTemplatesVars($vars); + } + if ($vars['type'] === 'microweber-core') { + return $this->inflectCoreVars($vars); + } + if ($vars['type'] === 'microweber-adapter') { + return $this->inflectCoreVars($vars); + } + if ($vars['type'] === 'microweber-module') { + return $this->inflectModuleVars($vars); + } + if ($vars['type'] === 'microweber-modules') { + return $this->inflectModulesVars($vars); + } + if ($vars['type'] === 'microweber-skin') { + return $this->inflectSkinVars($vars); + } + if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') { + return $this->inflectElementVars($vars); + } + } + + + return $vars; + } + + protected function inflectTemplateVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-template$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/template-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectTemplatesVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-templates$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/templates-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectCoreVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-providers$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/-provider$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/-adapter$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectModuleVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-module$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/module-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectModulesVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-modules$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/modules-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectSkinVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-skin$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/skin-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectElementVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-elements$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/elements-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/-element$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/element-$/', '', $vars['install_item_dir']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php new file mode 100644 index 0000000..0ee140a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php @@ -0,0 +1,12 @@ + 'core/packages/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php new file mode 100644 index 0000000..75dbe71 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php @@ -0,0 +1,58 @@ + 'mod/{$name}/', + 'admin_report' => 'admin/report/{$name}/', + 'atto' => 'lib/editor/atto/plugins/{$name}/', + 'tool' => 'admin/tool/{$name}/', + 'assignment' => 'mod/assignment/type/{$name}/', + 'assignsubmission' => 'mod/assign/submission/{$name}/', + 'assignfeedback' => 'mod/assign/feedback/{$name}/', + 'auth' => 'auth/{$name}/', + 'availability' => 'availability/condition/{$name}/', + 'block' => 'blocks/{$name}/', + 'booktool' => 'mod/book/tool/{$name}/', + 'cachestore' => 'cache/stores/{$name}/', + 'cachelock' => 'cache/locks/{$name}/', + 'calendartype' => 'calendar/type/{$name}/', + 'format' => 'course/format/{$name}/', + 'coursereport' => 'course/report/{$name}/', + 'customcertelement' => 'mod/customcert/element/{$name}/', + 'datafield' => 'mod/data/field/{$name}/', + 'datapreset' => 'mod/data/preset/{$name}/', + 'editor' => 'lib/editor/{$name}/', + 'enrol' => 'enrol/{$name}/', + 'filter' => 'filter/{$name}/', + 'gradeexport' => 'grade/export/{$name}/', + 'gradeimport' => 'grade/import/{$name}/', + 'gradereport' => 'grade/report/{$name}/', + 'gradingform' => 'grade/grading/form/{$name}/', + 'local' => 'local/{$name}/', + 'logstore' => 'admin/tool/log/store/{$name}/', + 'ltisource' => 'mod/lti/source/{$name}/', + 'ltiservice' => 'mod/lti/service/{$name}/', + 'message' => 'message/output/{$name}/', + 'mnetservice' => 'mnet/service/{$name}/', + 'plagiarism' => 'plagiarism/{$name}/', + 'portfolio' => 'portfolio/{$name}/', + 'qbehaviour' => 'question/behaviour/{$name}/', + 'qformat' => 'question/format/{$name}/', + 'qtype' => 'question/type/{$name}/', + 'quizaccess' => 'mod/quiz/accessrule/{$name}/', + 'quiz' => 'mod/quiz/report/{$name}/', + 'report' => 'report/{$name}/', + 'repository' => 'repository/{$name}/', + 'scormreport' => 'mod/scorm/report/{$name}/', + 'search' => 'search/engine/{$name}/', + 'theme' => 'theme/{$name}/', + 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/', + 'profilefield' => 'user/profile/field/{$name}/', + 'webservice' => 'webservice/{$name}/', + 'workshopallocation' => 'mod/workshop/allocation/{$name}/', + 'workshopeval' => 'mod/workshop/eval/{$name}/', + 'workshopform' => 'mod/workshop/form/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php new file mode 100644 index 0000000..08d5dc4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php @@ -0,0 +1,47 @@ + 'modules/{$name}/', + 'plugin' => 'plugins/{$vendor}/{$name}/', + 'theme' => 'themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type october-plugin, cut off a trailing '-plugin' if present. + * + * For package type october-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'october-plugin') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'october-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']); + $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php new file mode 100644 index 0000000..5dd3438 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php @@ -0,0 +1,24 @@ + 'extensions/{$name}/', + 'theme' => 'extensions/themes/{$name}/', + 'translation' => 'extensions/translations/{$name}/', + ); + + /** + * Format package name to lower case and remove ".ontowiki" suffix + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower($vars['name']); + $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']); + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = preg_replace('/-translation$/', '', $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php new file mode 100644 index 0000000..3ca7954 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php @@ -0,0 +1,14 @@ + 'oc-content/plugins/{$name}/', + 'theme' => 'oc-content/themes/{$name}/', + 'language' => 'oc-content/languages/{$name}/', + ); + +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php new file mode 100644 index 0000000..49940ff --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php @@ -0,0 +1,59 @@ +.+)\/.+/'; + + protected $locations = array( + 'module' => 'modules/{$name}/', + 'theme' => 'application/views/{$name}/', + 'out' => 'out/{$name}/', + ); + + /** + * getInstallPath + * + * @param PackageInterface $package + * @param string $frameworkType + * @return void + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + $installPath = parent::getInstallPath($package, $frameworkType); + $type = $this->package->getType(); + if ($type === 'oxid-module') { + $this->prepareVendorDirectory($installPath); + } + return $installPath; + } + + /** + * prepareVendorDirectory + * + * Makes sure there is a vendormetadata.php file inside + * the vendor folder if there is a vendor folder. + * + * @param string $installPath + * @return void + */ + protected function prepareVendorDirectory($installPath) + { + $matches = ''; + $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches); + if (!$hasVendorDirectory) { + return; + } + + $vendorDirectory = $matches['vendor']; + $vendorPath = getcwd() . '/modules/' . $vendorDirectory; + if (!file_exists($vendorPath)) { + mkdir($vendorPath, 0755, true); + } + + $vendorMetaDataPath = $vendorPath . '/vendormetadata.php'; + touch($vendorMetaDataPath); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php new file mode 100644 index 0000000..170136f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php new file mode 100644 index 0000000..4e59a8a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php @@ -0,0 +1,11 @@ + 'bundles/{$name}/', + 'library' => 'libraries/{$name}/', + 'framework' => 'frameworks/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php new file mode 100644 index 0000000..deb2b77 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php @@ -0,0 +1,11 @@ + 'ext/{$vendor}/{$name}/', + 'language' => 'language/{$name}/', + 'style' => 'styles/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php new file mode 100644 index 0000000..4781fa6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php @@ -0,0 +1,21 @@ + 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php new file mode 100644 index 0000000..c17f457 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php @@ -0,0 +1,32 @@ + 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php new file mode 100644 index 0000000..903e55f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php @@ -0,0 +1,29 @@ + '{$name}/' + ); + + /** + * Remove hyphen, "plugin" and format to camelcase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = explode("-", $vars['name']); + foreach ($vars['name'] as $key => $name) { + $vars['name'][$key] = ucfirst($vars['name'][$key]); + if (strcasecmp($name, "Plugin") == 0) { + unset($vars['name'][$key]); + } + } + $vars['name'] = implode("",$vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Plugin.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Plugin.php new file mode 100644 index 0000000..e60da0e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Plugin.php @@ -0,0 +1,27 @@ +installer = new Installer($io, $composer); + $composer->getInstallationManager()->addInstaller($this->installer); + } + + public function deactivate(Composer $composer, IOInterface $io) + { + $composer->getInstallationManager()->removeInstaller($this->installer); + } + + public function uninstall(Composer $composer, IOInterface $io) + { + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php new file mode 100644 index 0000000..dbf85e6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php @@ -0,0 +1,9 @@ + 'app/Containers/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php new file mode 100644 index 0000000..4c8421e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php @@ -0,0 +1,10 @@ + 'modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php new file mode 100644 index 0000000..77cc3dd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php @@ -0,0 +1,11 @@ + 'modules/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php new file mode 100644 index 0000000..6551058 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php @@ -0,0 +1,63 @@ + 'app/Modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format package name. + * + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'pxcms-module') { + return $this->inflectModuleVars($vars); + } + + if ($vars['type'] === 'pxcms-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + /** + * For package type pxcms-module, cut off a trailing '-plugin' if present. + * + * return string + */ + protected function inflectModuleVars($vars) + { + $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) + $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module- + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module + $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s + $vars['name'] = ucwords($vars['name']); // make module name camelcased + + return $vars; + } + + + /** + * For package type pxcms-module, cut off a trailing '-plugin' if present. + * + * return string + */ + protected function inflectThemeVars($vars) + { + $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) + $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme- + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme + $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s + $vars['name'] = ucwords($vars['name']); // make module name camelcased + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php new file mode 100644 index 0000000..0f78b5c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php @@ -0,0 +1,24 @@ + 'src/{$name}/' + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php new file mode 100644 index 0000000..252c733 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php @@ -0,0 +1,10 @@ + 'themes/{$name}/', + 'plugin' => 'plugins/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php new file mode 100644 index 0000000..23a2034 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php @@ -0,0 +1,10 @@ + 'redaxo/src/addons/{$name}/', + 'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php new file mode 100644 index 0000000..0954457 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php @@ -0,0 +1,10 @@ + 'redaxo/include/addons/{$name}/', + 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php new file mode 100644 index 0000000..d8d795b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php @@ -0,0 +1,22 @@ + 'plugins/{$name}/', + ); + + /** + * Lowercase name and changes the name to a underscores + * + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(str_replace('-', '_', $vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php new file mode 100644 index 0000000..1acd3b1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php @@ -0,0 +1,10 @@ + 'Sources/{$name}/', + 'theme' => 'Themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php new file mode 100644 index 0000000..7d20d27 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php @@ -0,0 +1,60 @@ + 'engine/Shopware/Plugins/Local/Backend/{$name}/', + 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/', + 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/', + 'theme' => 'templates/{$name}/', + 'plugin' => 'custom/plugins/{$name}/', + 'frontend-theme' => 'themes/Frontend/{$name}/', + ); + + /** + * Transforms the names + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'shopware-theme') { + return $this->correctThemeName($vars); + } + + return $this->correctPluginName($vars); + } + + /** + * Changes the name to a camelcased combination of vendor and name + * @param array $vars + * @return array + */ + private function correctPluginName($vars) + { + $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, $vars['name']); + + $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName); + + return $vars; + } + + /** + * Changes the name to a underscore separated name + * @param array $vars + * @return array + */ + private function correctThemeName($vars) + { + $vars['name'] = str_replace('-', '_', $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php new file mode 100644 index 0000000..81910e9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php @@ -0,0 +1,35 @@ + '{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Return the install path based on package type. + * + * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework + * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0 + * + * @param PackageInterface $package + * @param string $frameworkType + * @return string + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + if ( + $package->getName() == 'silverstripe/framework' + && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion()) + && version_compare($package->getVersion(), '2.999.999') < 0 + ) { + return $this->templatePath($this->locations['module'], array('name' => 'sapphire')); + } + + return parent::getInstallPath($package, $frameworkType); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php new file mode 100644 index 0000000..762d94c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php @@ -0,0 +1,25 @@ + 'modules/{$vendor}/{$name}/', + 'plugin' => 'plugins/{$vendor}/{$name}/' + ); + + public function inflectPackageVars($vars) + { + return $this->parseVars($vars); + } + + protected function parseVars($vars) + { + $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor']; + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php new file mode 100644 index 0000000..83ef9d0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php @@ -0,0 +1,49 @@ + 'app/modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format module name. + * + * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present. + * + * @param array @vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'sydes-module') { + return $this->inflectModuleVars($vars); + } + + if ($vars['type'] === 'sydes-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + public function inflectModuleVars($vars) + { + $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']); + $vars['name'] = strtolower($vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php new file mode 100644 index 0000000..4357a35 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php @@ -0,0 +1,9 @@ + 'themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php new file mode 100644 index 0000000..1675c4f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php @@ -0,0 +1,26 @@ + + */ +class Symfony1Installer extends BaseInstaller +{ + protected $locations = array( + 'plugin' => 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, $vars['name']); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php new file mode 100644 index 0000000..b1663e8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php @@ -0,0 +1,16 @@ + + */ +class TYPO3CmsInstaller extends BaseInstaller +{ + protected $locations = array( + 'extension' => 'typo3conf/ext/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php new file mode 100644 index 0000000..42572f4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php @@ -0,0 +1,38 @@ + 'Packages/Application/{$name}/', + 'framework' => 'Packages/Framework/{$name}/', + 'plugin' => 'Packages/Plugins/{$name}/', + 'site' => 'Packages/Sites/{$name}/', + 'boilerplate' => 'Packages/Boilerplates/{$name}/', + 'build' => 'Build/{$name}/', + ); + + /** + * Modify the package name to be a TYPO3 Flow style key. + * + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + $autoload = $this->package->getAutoload(); + if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) { + $namespace = key($autoload['psr-0']); + $vars['name'] = str_replace('\\', '.', $namespace); + } + if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) { + $namespace = key($autoload['psr-4']); + $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.'); + } + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php new file mode 100644 index 0000000..108def1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php @@ -0,0 +1,12 @@ + '{$name}' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php new file mode 100644 index 0000000..158af52 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php @@ -0,0 +1,12 @@ + 'local/modules/{$name}/', + 'frontoffice-template' => 'templates/frontOffice/{$name}/', + 'backoffice-template' => 'templates/backOffice/{$name}/', + 'email-template' => 'templates/email/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php new file mode 100644 index 0000000..7c0113b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php @@ -0,0 +1,14 @@ + + */ + class TuskInstaller extends BaseInstaller + { + protected $locations = array( + 'task' => '.tusk/tasks/{$name}/', + 'command' => '.tusk/commands/{$name}/', + 'asset' => 'assets/tusk/{$name}/', + ); + } diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php new file mode 100644 index 0000000..fcb414a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php @@ -0,0 +1,9 @@ + 'app/sprinkles/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php new file mode 100644 index 0000000..24ca645 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php @@ -0,0 +1,10 @@ + 'plugins/{$name}/', + 'theme' => 'themes/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php new file mode 100644 index 0000000..7d90c5e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php @@ -0,0 +1,49 @@ + 'src/{$vendor}/{$name}/', + 'theme' => 'themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type vgmcp-bundle, cut off a trailing '-bundle' if present. + * + * For package type vgmcp-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'vgmcp-bundle') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'vgmcp-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php new file mode 100644 index 0000000..b65dbba --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php @@ -0,0 +1,21 @@ + 'modules/addons/{$vendor}_{$name}/', + 'fraud' => 'modules/fraud/{$vendor}_{$name}/', + 'gateways' => 'modules/gateways/{$vendor}_{$name}/', + 'notifications' => 'modules/notifications/{$vendor}_{$name}/', + 'registrars' => 'modules/registrars/{$vendor}_{$name}/', + 'reports' => 'modules/reports/{$vendor}_{$name}/', + 'security' => 'modules/security/{$vendor}_{$name}/', + 'servers' => 'modules/servers/{$vendor}_{$name}/', + 'social' => 'modules/social/{$vendor}_{$name}/', + 'support' => 'modules/support/{$vendor}_{$name}/', + 'templates' => 'templates/{$vendor}_{$name}/', + 'includes' => 'includes/{$vendor}_{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php new file mode 100644 index 0000000..cb38788 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php @@ -0,0 +1,9 @@ + 'wolf/plugins/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php new file mode 100644 index 0000000..91c46ad --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php @@ -0,0 +1,12 @@ + 'wp-content/plugins/{$name}/', + 'theme' => 'wp-content/themes/{$name}/', + 'muplugin' => 'wp-content/mu-plugins/{$name}/', + 'dropin' => 'wp-content/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php new file mode 100644 index 0000000..27f429f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php @@ -0,0 +1,32 @@ + 'module/{$name}/', + ); + + /** + * Format package name to CamelCase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php new file mode 100644 index 0000000..bde9bc8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php @@ -0,0 +1,11 @@ + 'library/{$name}/', + 'extra' => 'extras/library/{$name}/', + 'module' => 'module/{$name}/', + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php new file mode 100644 index 0000000..56cdf5d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php @@ -0,0 +1,10 @@ + 'modules/{$vendor}-{$name}/', + 'theme' => 'themes/{$vendor}-{$name}/' + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/bootstrap.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/bootstrap.php new file mode 100644 index 0000000..0de276e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/installers/src/bootstrap.php @@ -0,0 +1,13 @@ + array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/XPathExpr.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\TranslatorInterface' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/TranslatorInterface.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\FunctionExtension' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/Extension/FunctionExtension.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\CombinationExtension' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/Extension/CombinationExtension.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\PseudoClassExtension' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/Extension/PseudoClassExtension.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\NodeExtension' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/Extension/NodeExtension.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\ExtensionInterface' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/Extension/ExtensionInterface.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\AttributeMatchingExtension' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\HtmlExtension' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/Extension/HtmlExtension.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\AbstractExtension' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/Extension/AbstractExtension.php' + ), + 'Symfony\\Component\\CssSelector\\XPath\\Translator' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/XPath/Translator.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\CommentHandler' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Handler/CommentHandler.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\IdentifierHandler' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Handler/IdentifierHandler.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\WhitespaceHandler' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Handler/WhitespaceHandler.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\StringHandler' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Handler/StringHandler.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\HashHandler' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Handler/HashHandler.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\HandlerInterface' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Handler/HandlerInterface.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\NumberHandler' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Handler/NumberHandler.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ClassParser' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/ClassParser.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\EmptyStringParser' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ElementParser' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/ElementParser.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\HashParser' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/HashParser.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Token' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Token.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Parser' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Parser.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerEscaping' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\Tokenizer' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/Tokenizer.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerPatterns' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\Reader' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/Reader.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\ParserInterface' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/ParserInterface.php' + ), + 'Symfony\\Component\\CssSelector\\Parser\\TokenStream' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Parser/TokenStream.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\ClassNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/ClassNode.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\FunctionNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/FunctionNode.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\AbstractNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/AbstractNode.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\PseudoNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/PseudoNode.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\ElementNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/ElementNode.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\Specificity' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/Specificity.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\HashNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/HashNode.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\AttributeNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/AttributeNode.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\NegationNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/NegationNode.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\NodeInterface' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/NodeInterface.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\SelectorNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/SelectorNode.php' + ), + 'Symfony\\Component\\CssSelector\\Node\\CombinedSelectorNode' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Node/CombinedSelectorNode.php' + ), + 'Symfony\\Component\\CssSelector\\Exception\\InternalErrorException' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Exception/InternalErrorException.php' + ), + 'Symfony\\Component\\CssSelector\\Exception\\ExceptionInterface' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Exception/ExceptionInterface.php' + ), + 'Symfony\\Component\\CssSelector\\Exception\\SyntaxErrorException' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Exception/SyntaxErrorException.php' + ), + 'Symfony\\Component\\CssSelector\\Exception\\ParseException' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Exception/ParseException.php' + ), + 'Symfony\\Component\\CssSelector\\Exception\\ExpressionErrorException' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/Exception/ExpressionErrorException.php' + ), + 'Symfony\\Component\\CssSelector\\CssSelectorConverter' => array( + 'version' => '3.3.6.0', + 'path' => $vendorDir . '/symfony/css-selector/CssSelectorConverter.php' + ), + 'Psr\\Container\\NotFoundExceptionInterface' => array( + 'version' => '1.0.0.0', + 'path' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php' + ), + 'Psr\\Container\\ContainerInterface' => array( + 'version' => '1.0.0.0', + 'path' => $vendorDir . '/psr/container/src/ContainerInterface.php' + ), + 'Psr\\Container\\ContainerExceptionInterface' => array( + 'version' => '1.0.0.0', + 'path' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php' + ), + 'Pelago\\Emogrifier\\CssInliner' => array( + 'version' => '3.1.0.0', + 'path' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/CssInliner.php' + ), + 'Pelago\\Emogrifier\\Utilities\\CssConcatenator' => array( + 'version' => '3.1.0.0', + 'path' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/Utilities/CssConcatenator.php' + ), + 'Pelago\\Emogrifier\\Utilities\\ArrayIntersector' => array( + 'version' => '3.1.0.0', + 'path' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/Utilities/ArrayIntersector.php' + ), + 'Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer' => array( + 'version' => '3.1.0.0', + 'path' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/HtmlNormalizer.php' + ), + 'Pelago\\Emogrifier\\HtmlProcessor\\HtmlPruner' => array( + 'version' => '3.1.0.0', + 'path' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/HtmlPruner.php' + ), + 'Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter' => array( + 'version' => '3.1.0.0', + 'path' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/CssToAttributeConverter.php' + ), + 'Pelago\\Emogrifier\\HtmlProcessor\\AbstractHtmlProcessor' => array( + 'version' => '3.1.0.0', + 'path' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/AbstractHtmlProcessor.php' + ), + 'Pelago\\Emogrifier' => array( + 'version' => '3.1.0.0', + 'path' => $vendorDir . '/pelago/emogrifier/src/Emogrifier.php' + ), + 'MaxMind\\Db\\Reader\\Decoder' => array( + 'version' => '1.6.0.0', + 'path' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php' + ), + 'MaxMind\\Db\\Reader\\InvalidDatabaseException' => array( + 'version' => '1.6.0.0', + 'path' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php' + ), + 'MaxMind\\Db\\Reader\\Metadata' => array( + 'version' => '1.6.0.0', + 'path' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.php' + ), + 'MaxMind\\Db\\Reader\\Util' => array( + 'version' => '1.6.0.0', + 'path' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php' + ), + 'MaxMind\\Db\\Reader' => array( + 'version' => '1.6.0.0', + 'path' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader.php' + ), + 'Composer\\Installers\\GravInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/GravInstaller.php' + ), + 'Composer\\Installers\\AttogramInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AttogramInstaller.php' + ), + 'Composer\\Installers\\DrupalInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DrupalInstaller.php' + ), + 'Composer\\Installers\\CraftInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CraftInstaller.php' + ), + 'Composer\\Installers\\CiviCrmInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CiviCrmInstaller.php' + ), + 'Composer\\Installers\\ItopInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ItopInstaller.php' + ), + 'Composer\\Installers\\ReIndexInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ReIndexInstaller.php' + ), + 'Composer\\Installers\\TheliaInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php' + ), + 'Composer\\Installers\\SilverStripeInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php' + ), + 'Composer\\Installers\\ShopwareInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php' + ), + 'Composer\\Installers\\DokuWikiInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DokuWikiInstaller.php' + ), + 'Composer\\Installers\\SyliusInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SyliusInstaller.php' + ), + 'Composer\\Installers\\PPIInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PPIInstaller.php' + ), + 'Composer\\Installers\\KirbyInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/KirbyInstaller.php' + ), + 'Composer\\Installers\\LaravelInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/LaravelInstaller.php' + ), + 'Composer\\Installers\\ElggInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ElggInstaller.php' + ), + 'Composer\\Installers\\VanillaInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/VanillaInstaller.php' + ), + 'Composer\\Installers\\YawikInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/YawikInstaller.php' + ), + 'Composer\\Installers\\RoundcubeInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/RoundcubeInstaller.php' + ), + 'Composer\\Installers\\VgmcpInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/VgmcpInstaller.php' + ), + 'Composer\\Installers\\UserFrostingInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/UserFrostingInstaller.php' + ), + 'Composer\\Installers\\RadPHPInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php' + ), + 'Composer\\Installers\\KnownInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/KnownInstaller.php' + ), + 'Composer\\Installers\\SMFInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SMFInstaller.php' + ), + 'Composer\\Installers\\PhiftyInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php' + ), + 'Composer\\Installers\\MakoInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php' + ), + 'Composer\\Installers\\TYPO3CmsInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php' + ), + 'Composer\\Installers\\CockpitInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CockpitInstaller.php' + ), + 'Composer\\Installers\\CodeIgniterInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php' + ), + 'Composer\\Installers\\TaoInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/TaoInstaller.php' + ), + 'Composer\\Installers\\AimeosInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AimeosInstaller.php' + ), + 'Composer\\Installers\\KohanaInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php' + ), + 'Composer\\Installers\\Plugin' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php' + ), + 'Composer\\Installers\\ExpressionEngineInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php' + ), + 'Composer\\Installers\\OctoberInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/OctoberInstaller.php' + ), + 'Composer\\Installers\\WolfCMSInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php' + ), + 'Composer\\Installers\\LithiumInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/LithiumInstaller.php' + ), + 'Composer\\Installers\\ZendInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ZendInstaller.php' + ), + 'Composer\\Installers\\Symfony1Installer' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/Symfony1Installer.php' + ), + 'Composer\\Installers\\LavaLiteInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php' + ), + 'Composer\\Installers\\MoodleInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MoodleInstaller.php' + ), + 'Composer\\Installers\\HuradInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/HuradInstaller.php' + ), + 'Composer\\Installers\\BaseInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/BaseInstaller.php' + ), + 'Composer\\Installers\\CakePHPInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CakePHPInstaller.php' + ), + 'Composer\\Installers\\RedaxoInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/RedaxoInstaller.php' + ), + 'Composer\\Installers\\ModxInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ModxInstaller.php' + ), + 'Composer\\Installers\\MauticInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MauticInstaller.php' + ), + 'Composer\\Installers\\MagentoInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MagentoInstaller.php' + ), + 'Composer\\Installers\\Concrete5Installer' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/Concrete5Installer.php' + ), + 'Composer\\Installers\\FuelphpInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php' + ), + 'Composer\\Installers\\FuelInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelInstaller.php' + ), + 'Composer\\Installers\\PrestashopInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php' + ), + 'Composer\\Installers\\OxidInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/OxidInstaller.php' + ), + 'Composer\\Installers\\TuskInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/TuskInstaller.php' + ), + 'Composer\\Installers\\TYPO3FlowInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php' + ), + 'Composer\\Installers\\PiwikInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php' + ), + 'Composer\\Installers\\PuppetInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PuppetInstaller.php' + ), + 'Composer\\Installers\\AglInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AglInstaller.php' + ), + 'Composer\\Installers\\PimcoreInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php' + ), + 'Composer\\Installers\\EliasisInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/EliasisInstaller.php' + ), + 'Composer\\Installers\\Redaxo5Installer' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/Redaxo5Installer.php' + ), + 'Composer\\Installers\\BitrixInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/BitrixInstaller.php' + ), + 'Composer\\Installers\\AsgardInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AsgardInstaller.php' + ), + 'Composer\\Installers\\WHMCSInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php' + ), + 'Composer\\Installers\\KanboardInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/KanboardInstaller.php' + ), + 'Composer\\Installers\\WordPressInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/WordPressInstaller.php' + ), + 'Composer\\Installers\\MajimaInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MajimaInstaller.php' + ), + 'Composer\\Installers\\DframeInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DframeInstaller.php' + ), + 'Composer\\Installers\\PlentymarketsInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php' + ), + 'Composer\\Installers\\EzPlatformInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/EzPlatformInstaller.php' + ), + 'Composer\\Installers\\MODXEvoInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php' + ), + 'Composer\\Installers\\OntoWikiInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php' + ), + 'Composer\\Installers\\AnnotateCmsInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php' + ), + 'Composer\\Installers\\MODULEWorkInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php' + ), + 'Composer\\Installers\\OsclassInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/OsclassInstaller.php' + ), + 'Composer\\Installers\\ChefInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ChefInstaller.php' + ), + 'Composer\\Installers\\JoomlaInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php' + ), + 'Composer\\Installers\\Installer' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php' + ), + 'Composer\\Installers\\KodiCMSInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php' + ), + 'Composer\\Installers\\PhpBBInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php' + ), + 'Composer\\Installers\\MediaWikiInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php' + ), + 'Composer\\Installers\\ImageCMSInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php' + ), + 'Composer\\Installers\\PortoInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PortoInstaller.php' + ), + 'Composer\\Installers\\DolibarrInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php' + ), + 'Composer\\Installers\\BonefishInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/BonefishInstaller.php' + ), + 'Composer\\Installers\\MayaInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MayaInstaller.php' + ), + 'Composer\\Installers\\CroogoInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CroogoInstaller.php' + ), + 'Composer\\Installers\\PxcmsInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PxcmsInstaller.php' + ), + 'Composer\\Installers\\DecibelInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DecibelInstaller.php' + ), + 'Composer\\Installers\\SyDESInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SyDESInstaller.php' + ), + 'Composer\\Installers\\LanManagementSystemInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php' + ), + 'Composer\\Installers\\ClanCatsFrameworkInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php' + ), + 'Composer\\Installers\\ZikulaInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php' + ), + 'Composer\\Installers\\MantisBTInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php' + ), + 'Composer\\Installers\\SiteDirectInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SiteDirectInstaller.php' + ), + 'Composer\\Installers\\MicroweberInstaller' => array( + 'version' => '1.9.0.0', + 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\ContainerAwareTrait' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/ContainerAwareTrait.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Container' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Container.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Argument\\RawArgument' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Argument/RawArgument.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Argument\\ClassNameWithOptionalValue' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Argument/ClassNameWithOptionalValue.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Argument\\ClassName' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Argument/ClassName.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Argument\\ArgumentResolverTrait' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Argument/ArgumentResolverTrait.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Argument\\ArgumentResolverInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Argument/ArgumentResolverInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Argument\\RawArgumentInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Argument/RawArgumentInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Argument\\ClassNameInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Argument/ClassNameInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Inflector\\InflectorAggregate' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Inflector/InflectorAggregate.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Inflector\\InflectorAggregateInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Inflector/InflectorAggregateInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Inflector\\InflectorInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Inflector/InflectorInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Inflector\\Inflector' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Inflector/Inflector.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\ServiceProvider\\ServiceProviderAggregateInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/ServiceProvider/ServiceProviderAggregateInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\ServiceProvider\\AbstractServiceProvider' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/ServiceProvider/AbstractServiceProvider.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\ServiceProvider\\ServiceProviderAggregate' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/ServiceProvider/ServiceProviderAggregate.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\ServiceProvider\\BootableServiceProviderInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/ServiceProvider/BootableServiceProviderInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\ServiceProvider\\ServiceProviderInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/ServiceProvider/ServiceProviderInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Definition\\DefinitionAggregate' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Definition/DefinitionAggregate.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Definition\\Definition' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Definition/Definition.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Definition\\DefinitionAggregateInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Definition/DefinitionAggregateInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Definition\\DefinitionInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Definition/DefinitionInterface.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\ReflectionContainer' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/ReflectionContainer.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Exception\\ContainerException' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Exception/ContainerException.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\Exception\\NotFoundException' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/Exception/NotFoundException.php' + ), + 'Automattic\\WooCommerce\\Vendor\\League\\Container\\ContainerAwareInterface' => array( + 'version' => 'dev-release/4.8', + 'path' => $vendorDir . '/league/container/src/ContainerAwareInterface.php' + ), + 'Automattic\\WooCommerce\\Tests\\Internal\\WCCom\\ConnectionHelperTest' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Internal/WCCom/ConnectionHelperTest.php' + ), + 'Automattic\\WooCommerce\\Tests\\Internal\\DependencyManagement\\ExtendedContainerTest' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Internal/DependencyManagement/ExtendedContainerTest.php' + ), + 'Automattic\\WooCommerce\\Tests\\Internal\\DependencyManagement\\ExampleClasses\\ClassWithScalarInjectionMethodArgument' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithScalarInjectionMethodArgument.php' + ), + 'Automattic\\WooCommerce\\Tests\\Internal\\DependencyManagement\\ExampleClasses\\ClassWithDependencies' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithDependencies.php' + ), + 'Automattic\\WooCommerce\\Tests\\Internal\\DependencyManagement\\ExampleClasses\\DependencyClass' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Internal/DependencyManagement/ExampleClasses/DependencyClass.php' + ), + 'Automattic\\WooCommerce\\Tests\\Internal\\DependencyManagement\\ExampleClasses\\ClassWithPrivateInjectionMethod' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithPrivateInjectionMethod.php' + ), + 'Automattic\\WooCommerce\\Tests\\Internal\\DependencyManagement\\ExampleClasses\\ClassWithNonFinalInjectionMethod' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithNonFinalInjectionMethod.php' + ), + 'Automattic\\WooCommerce\\Tests\\Internal\\DependencyManagement\\ExampleClasses\\ClassWithInjectionMethodArgumentWithoutTypeHint' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Internal/DependencyManagement/ExampleClasses/ClassWithInjectionMethodArgumentWithoutTypeHint.php' + ), + 'Automattic\\WooCommerce\\Tests\\Internal\\DependencyManagement\\AbstractServiceProviderTest' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Internal/DependencyManagement/AbstractServiceProviderTest.php' + ), + 'Automattic\\WooCommerce\\Tests\\Utilities\\StringUtilTest' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Utilities/StringUtilTest.php' + ), + 'Automattic\\WooCommerce\\Tests\\Utilities\\NumberUtilTest' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Utilities/NumberUtilTest.php' + ), + 'Automattic\\WooCommerce\\Tests\\Proxies\\LegacyProxyTest' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Proxies/LegacyProxyTest.php' + ), + 'Automattic\\WooCommerce\\Tests\\Proxies\\ExampleClasses\\ClassThatDependsOnLegacyCode' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Proxies/ExampleClasses/ClassThatDependsOnLegacyCode.php' + ), + 'Automattic\\WooCommerce\\Tests\\Proxies\\MockableLegacyProxyTest' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Proxies/MockableLegacyProxyTest.php' + ), + 'Automattic\\WooCommerce\\Tests\\Proxies\\ClassThatDependsOnLegacyCodeTest' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/php/src/Proxies/ClassThatDependsOnLegacyCodeTest.php' + ), + 'Automattic\\WooCommerce\\Testing\\Tools\\CodeHacking\\CodeHackerTestHook' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/Tools/CodeHacking/CodeHackerTestHook.php' + ), + 'Automattic\\WooCommerce\\Testing\\Tools\\CodeHacking\\CodeHacker' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/Tools/CodeHacking/CodeHacker.php' + ), + 'Automattic\\WooCommerce\\Testing\\Tools\\CodeHacking\\Hacks\\BypassFinalsHack' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/Tools/CodeHacking/Hacks/BypassFinalsHack.php' + ), + 'Automattic\\WooCommerce\\Testing\\Tools\\CodeHacking\\Hacks\\StaticMockerHack' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/Tools/CodeHacking/Hacks/StaticMockerHack.php' + ), + 'Automattic\\WooCommerce\\Testing\\Tools\\CodeHacking\\Hacks\\FunctionsMockerHack' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/Tools/CodeHacking/Hacks/FunctionsMockerHack.php' + ), + 'Automattic\\WooCommerce\\Testing\\Tools\\CodeHacking\\Hacks\\CodeHack' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/Tools/CodeHacking/Hacks/CodeHack.php' + ), + 'Automattic\\WooCommerce\\Testing\\Tools\\DependencyManagement\\DependencyManagementTestHook' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/Tools/DependencyManagement/DependencyManagementTestHook.php' + ), + 'Automattic\\WooCommerce\\Testing\\Tools\\DependencyManagement\\MockableLegacyProxy' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/Tools/DependencyManagement/MockableLegacyProxy.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\PaymentResult' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/PaymentResult.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\PaymentMethodTypeInterface' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/PaymentMethodTypeInterface.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\PaymentMethodRegistry' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/PaymentMethodRegistry.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\Integrations\\AbstractPaymentMethodType' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/Integrations/AbstractPaymentMethodType.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\Integrations\\Cheque' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/Integrations/Cheque.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\Integrations\\BankTransfer' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/Integrations/BankTransfer.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\Integrations\\CashOnDelivery' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/Integrations/CashOnDelivery.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\Integrations\\Stripe' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/Integrations/Stripe.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\Integrations\\PayPal' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/Integrations/PayPal.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\PaymentContext' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/PaymentContext.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Payments\\Api' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Payments/Api.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Package' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Package.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Library' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Library.php' + ), + 'Automattic\\WooCommerce\\Blocks\\RestApi' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/RestApi.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Utils\\BlocksWpQuery' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Utils/BlocksWpQuery.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Registry\\Container' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Registry/Container.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Registry\\SharedType' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Registry/SharedType.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Registry\\FactoryType' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Registry/FactoryType.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Registry\\AbstractDependencyType' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Registry/AbstractDependencyType.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\FeaturedProduct' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/FeaturedProduct.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ActiveFilters' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ActiveFilters.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\HandpickedProducts' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/HandpickedProducts.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ReviewsByProduct' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ReviewsByProduct.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ProductSearch' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ProductSearch.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\Cart' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/Cart.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\AtomicBlock' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/AtomicBlock.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ProductOnSale' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ProductOnSale.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ProductTopRated' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ProductTopRated.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\SingleProduct' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/SingleProduct.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ProductNew' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ProductNew.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\Checkout' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/Checkout.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ProductCategories' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ProductCategories.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ProductTag' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ProductTag.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\AllReviews' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/AllReviews.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\AbstractProductGrid' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/AbstractProductGrid.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\AbstractBlock' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/AbstractBlock.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\AttributeFilter' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/AttributeFilter.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\AbstractDynamicBlock' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/AbstractDynamicBlock.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ReviewsByCategory' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ReviewsByCategory.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ProductsByAttribute' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ProductsByAttribute.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ProductBestSellers' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ProductBestSellers.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\ProductCategory' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/ProductCategory.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\FeaturedCategory' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/FeaturedCategory.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\PriceFilter' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/PriceFilter.php' + ), + 'Automattic\\WooCommerce\\Blocks\\BlockTypes\\AllProducts' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/BlockTypes/AllProducts.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Installer' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Installer.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\RoutesController' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/RoutesController.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\SchemaController' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/SchemaController.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\CartShippingRateSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/CartShippingRateSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\CartItemSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/CartItemSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\CartSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/CartSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\AbstractSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/AbstractSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\CartCouponSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/CartCouponSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\ProductAttributeSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductAttributeSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\ErrorSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/ErrorSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\BillingAddressSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/BillingAddressSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\TermSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/TermSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\ProductCategorySchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductCategorySchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\OrderCouponSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/OrderCouponSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\ProductCollectionDataSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductCollectionDataSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\ProductSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\ShippingAddressSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/ShippingAddressSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\CheckoutSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/CheckoutSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\ImageAttachmentSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/ImageAttachmentSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Schemas\\ProductReviewSchema' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Schemas/ProductReviewSchema.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Utilities\\NoticeHandler' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Utilities/NoticeHandler.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Utilities\\ProductQueryFilters' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Utilities/ProductQueryFilters.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Utilities\\Pagination' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Utilities/Pagination.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Utilities\\ProductQuery' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Utilities/ProductQuery.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Utilities\\OrderController' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Utilities/OrderController.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Utilities\\ReserveStock' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Utilities/ReserveStock.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Utilities\\ReserveStockException' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Utilities/ReserveStockException.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Utilities\\CartController' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Utilities/CartController.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\RouteException' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/RouteException.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\ProductReviews' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/ProductReviews.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartApplyCoupon' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartApplyCoupon.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartCouponsByCode' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartCouponsByCode.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\Cart' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/Cart.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartUpdateItem' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartUpdateItem.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\ProductCategoriesById' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCategoriesById.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\ProductCollectionData' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCollectionData.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartItemsByKey' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartItemsByKey.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\AbstractCartRoute' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractCartRoute.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\AbstractTermsRoute' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractTermsRoute.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\Checkout' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/Checkout.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\ProductCategories' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/ProductCategories.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\ProductAttributes' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributes.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartItems' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartItems.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartAddItem' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartAddItem.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartSelectShippingRate' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartSelectShippingRate.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\AbstractRoute' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/AbstractRoute.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartRemoveCoupon' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartRemoveCoupon.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\ProductAttributesById' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributesById.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\RouteInterface' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/RouteInterface.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\ProductsById' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/ProductsById.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\Products' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/Products.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartUpdateShipping' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartUpdateShipping.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartRemoveItem' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartRemoveItem.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\ProductTags' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/ProductTags.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\CartCoupons' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/CartCoupons.php' + ), + 'Automattic\\WooCommerce\\Blocks\\StoreApi\\Routes\\ProductAttributeTerms' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/StoreApi/Routes/ProductAttributeTerms.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Assets\\BackCompatAssetDataRegistry' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Assets/BackCompatAssetDataRegistry.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Assets\\AssetDataRegistry' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Assets/AssetDataRegistry.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Assets\\Api' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Assets/Api.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Domain\\Package' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Domain/Package.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Domain\\Bootstrap' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Domain/Bootstrap.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Domain\\Services\\CreateAccount' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Domain/Services/CreateAccount.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Domain\\Services\\DraftOrders' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Domain/Services/DraftOrders.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Domain\\Services\\Email\\CustomerNewAccount' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Domain/Services/Email/CustomerNewAccount.php' + ), + 'Automattic\\WooCommerce\\Blocks\\Assets' => array( + 'version' => '3.8.1.0', + 'path' => $baseDir . '/packages/woocommerce-blocks/src/Assets.php' + ), + 'Automattic\\WooCommerce\\Admin\\Overrides\\Order' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Overrides/Order.php' + ), + 'Automattic\\WooCommerce\\Admin\\Overrides\\ThemeUpgrader' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Overrides/ThemeUpgrader.php' + ), + 'Automattic\\WooCommerce\\Admin\\Overrides\\ThemeUpgraderSkin' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Overrides/ThemeUpgraderSkin.php' + ), + 'Automattic\\WooCommerce\\Admin\\Overrides\\OrderTraits' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Overrides/OrderTraits.php' + ), + 'Automattic\\WooCommerce\\Admin\\Overrides\\OrderRefund' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Overrides/OrderRefund.php' + ), + 'Automattic\\WooCommerce\\Admin\\Loader' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Loader.php' + ), + 'Automattic\\WooCommerce\\Admin\\ReportCSVEmail' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/ReportCSVEmail.php' + ), + 'Automattic\\WooCommerce\\Admin\\FeaturePlugin' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/FeaturePlugin.php' + ), + 'Automattic\\WooCommerce\\Admin\\ReportsSync' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/ReportsSync.php' + ), + 'Automattic\\WooCommerce\\Admin\\ReportCSVExporter' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/ReportCSVExporter.php' + ), + 'Automattic\\WooCommerce\\Admin\\Install' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Install.php' + ), + 'Automattic\\WooCommerce\\Admin\\PluginsHelper' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/PluginsHelper.php' + ), + 'Automattic\\WooCommerce\\Admin\\CategoryLookup' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/CategoryLookup.php' + ), + 'Automattic\\WooCommerce\\Admin\\DateTimeProvider\\CurrentDateTimeProvider' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/DateTimeProvider/CurrentDateTimeProvider.php' + ), + 'Automattic\\WooCommerce\\Admin\\DateTimeProvider\\DateTimeProviderInterface' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/DateTimeProvider/DateTimeProviderInterface.php' + ), + 'Automattic\\WooCommerce\\Admin\\ReportExporter' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/ReportExporter.php' + ), + 'Automattic\\WooCommerce\\Admin\\Composer\\Package' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Composer/Package.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\MobileAppBanner' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/MobileAppBanner.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\OnboardingTasks' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/OnboardingTasks.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\ShippingLabelBannerDisplayRules' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/ShippingLabelBannerDisplayRules.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\CouponsMovedTrait' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/CouponsMovedTrait.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\Navigation\\Init' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/Navigation/Init.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\Navigation\\CoreMenu' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/Navigation/CoreMenu.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\Navigation\\Screen' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/Navigation/Screen.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\Navigation\\Menu' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/Navigation/Menu.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\Coupons' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/Coupons.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\ShippingLabelBanner' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/ShippingLabelBanner.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\ActivityPanels' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/ActivityPanels.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\Onboarding' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/Onboarding.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\OnboardingSetUpShipping' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/OnboardingSetUpShipping.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\CustomerEffortScoreTracks' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/CustomerEffortScoreTracks.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\Marketing' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/Marketing.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\Analytics' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/Analytics.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\AnalyticsDashboard' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/AnalyticsDashboard.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\OnboardingAutomateTaxes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/OnboardingAutomateTaxes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Features\\Homescreen' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Features/Homescreen.php' + ), + 'Automattic\\WooCommerce\\Admin\\Events' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Events.php' + ), + 'Automattic\\WooCommerce\\Admin\\DeprecatedClassFacade' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/DeprecatedClassFacade.php' + ), + 'Automattic\\WooCommerce\\Admin\\PluginsProvider\\PluginsProviderInterface' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/PluginsProvider/PluginsProviderInterface.php' + ), + 'Automattic\\WooCommerce\\Admin\\PluginsProvider\\PluginsProvider' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/PluginsProvider/PluginsProvider.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\OnboardingPayments' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/OnboardingPayments.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\GivingFeedbackNotes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/GivingFeedbackNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\PerformanceOnMobile' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/PerformanceOnMobile.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\SellingOnlineCourses' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/SellingOnlineCourses.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\TestCheckout' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/TestCheckout.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\ManageOrdersOnTheGo' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/ManageOrdersOnTheGo.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\Note' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/Note.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\RealTimeOrderAlerts' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/RealTimeOrderAlerts.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\PersonalizeStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/PersonalizeStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\StartDropshippingBusiness' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/StartDropshippingBusiness.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\OnlineClothingStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/OnlineClothingStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WooCommercePayments' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/WooCommercePayments.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\FirstProduct' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/FirstProduct.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\GoogleAdsAndMarketing' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/GoogleAdsAndMarketing.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\NavigationFeedback' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/NavigationFeedback.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\MobileApp' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/MobileApp.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WooCommerceSubscriptions' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/WooCommerceSubscriptions.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\OrderMilestones' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/OrderMilestones.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\TrackingOptIn' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/TrackingOptIn.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\DrawAttention' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DrawAttention.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WooSubscriptionsNotes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/WooSubscriptionsNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\DeactivatePlugin' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeactivatePlugin.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\EditProductsOnTheMove' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/EditProductsOnTheMove.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\Notes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/Notes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\MigrateFromShopify' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/MigrateFromShopify.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\NoteTraits' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/NoteTraits.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\InsightFirstSale' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/InsightFirstSale.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\EUVATNumber' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/EUVATNumber.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\InstallJPAndWCSPlugins' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/InstallJPAndWCSPlugins.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Note' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Choose_Niche' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Coupon_Page_Moved' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Customize_Store_With_Blocks' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Deactivate_Plugin' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Draw_Attention' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Edit_Products_On_The_Move' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_EU_VAT_Number' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Facebook_Marketing_Expert' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_First_Product' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Giving_Feedback_Notes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Historical_Data' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Home_Screen_Feedback' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Insight_First_Sale' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Install_JP_And_WCS_Plugins' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Launch_Checklist' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Marketing' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Migrate_From_Shopify' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Mobile_App' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Need_Some_Inspiration' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_New_Sales_Record' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Onboarding_Email_Marketing' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Onboarding_Payments' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Online_Clothing_Store' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Order_Milestones' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Performance_On_Mobile' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Personalize_Store' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Real_Time_Order_Alerts' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Review_Shipping_Settings' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Selling_Online_Courses' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Set_Up_Additional_Payment_Types' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Start_Dropshipping_Business' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Test_Checkout' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Tracking_Opt_In' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_Woo_Subscriptions_Notes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_WooCommerce_Payments' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\WC_Admin_Notes_WooCommerce_Subscriptions' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/DeprecatedNotes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\ConfirmTaxSettings' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/ConfirmTaxSettings.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\NavigationFeedbackFollowUp' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/NavigationFeedbackFollowUp.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\Marketing' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/Marketing.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\LaunchChecklist' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/LaunchChecklist.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\NeedSomeInspiration' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/NeedSomeInspiration.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\SetUpAdditionalPaymentTypes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/SetUpAdditionalPaymentTypes.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\OnboardingEmailMarketing' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/OnboardingEmailMarketing.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\HistoricalData' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/HistoricalData.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\CustomizeStoreWithBlocks' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/CustomizeStoreWithBlocks.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\ReviewShippingSettings' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/ReviewShippingSettings.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\NewSalesRecord' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/NewSalesRecord.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\HomeScreenFeedback' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/HomeScreenFeedback.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\CouponPageMoved' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/CouponPageMoved.php' + ), + 'Automattic\\WooCommerce\\Admin\\Notes\\ChooseNiche' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Notes/ChooseNiche.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\IsEcommerceRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/IsEcommerceRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\EvaluateAndGetStatus' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/EvaluateAndGetStatus.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\RemoteInboxNotificationsEngine' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/RemoteInboxNotificationsEngine.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\OrRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/OrRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\OrdersProvider' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/OrdersProvider.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\SpecRunner' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/SpecRunner.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\PluginVersionRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/PluginVersionRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\StoredStateSetupForProducts' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/StoredStateSetupForProducts.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\NotRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/NotRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\ProductCountRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/ProductCountRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\StoredStateRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/StoredStateRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\GetRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/GetRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\RuleProcessorInterface' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/RuleProcessorInterface.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\PublishBeforeTimeRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/PublishBeforeTimeRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\RuleEvaluator' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/RuleEvaluator.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\WCAdminActiveForRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/WCAdminActiveForRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\PublishAfterTimeRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/PublishAfterTimeRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\NoteStatusRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/NoteStatusRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\ComparisonOperation' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/ComparisonOperation.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\WCAdminActiveForProvider' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/WCAdminActiveForProvider.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\OrderCountRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/OrderCountRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\OptionRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/OptionRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\BaseLocationCountryRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/BaseLocationCountryRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\FailRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/FailRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\PassRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/PassRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\BaseLocationStateRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/BaseLocationStateRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\OnboardingProfileRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/OnboardingProfileRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\DataSourcePoller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/DataSourcePoller.php' + ), + 'Automattic\\WooCommerce\\Admin\\RemoteInboxNotifications\\PluginsActivatedRuleProcessor' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/RemoteInboxNotifications/PluginsActivatedRuleProcessor.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Taxes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Taxes.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\ProductReviews' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/ProductReviews.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Init' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Init.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\OnboardingProfile' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/OnboardingProfile.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\OnboardingTasks' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/OnboardingTasks.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\DataDownloadIPs' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/DataDownloadIPs.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Themes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Themes.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\SettingOptions' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/SettingOptions.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\NoteActions' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/NoteActions.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Plugins' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Plugins.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Notes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Notes.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Coupons' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Coupons.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\ProductCategories' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/ProductCategories.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\ProductVariations' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/ProductVariations.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Leaderboards' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Leaderboards.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Data' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Data.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Marketing' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Marketing.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Options' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Options.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Products' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Products.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Customers' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Customers.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\OnboardingThemes' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/OnboardingThemes.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\DataCountries' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/DataCountries.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\MarketingOverview' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/MarketingOverview.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Orders' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Orders.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Customers\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Customers/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Customers\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Customers/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Customers\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Customers/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Customers\\Stats\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Customers/Stats/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Customers\\Stats\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Customers/Stats/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Customers\\Stats\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Customers/Stats/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\DataStoreInterface' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/DataStoreInterface.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Products\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Products/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Products\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Products/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Products\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Products/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Products\\Stats\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Products/Stats/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Products\\Stats\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Products/Stats/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Products\\Stats\\Segmenter' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Products/Stats/Segmenter.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Products\\Stats\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Products/Stats/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\TimeInterval' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/TimeInterval.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\ExportableInterface' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/ExportableInterface.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Cache' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Cache.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Variations\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Variations/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Variations\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Variations/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Variations\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Variations/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Variations\\Stats\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Variations/Stats/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Variations\\Stats\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Variations/Stats/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Variations\\Stats\\Segmenter' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Variations/Stats/Segmenter.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Variations\\Stats\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Variations/Stats/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\ExportableTraits' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/ExportableTraits.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Coupons\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Coupons/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Coupons\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Coupons/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Coupons\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Coupons/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Coupons\\Stats\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Coupons/Stats/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Coupons\\Stats\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Coupons/Stats/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Coupons\\Stats\\Segmenter' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Coupons/Stats/Segmenter.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Coupons\\Stats\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Coupons/Stats/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\ParameterException' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/ParameterException.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Segmenter' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Segmenter.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Taxes\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Taxes/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Taxes\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Taxes/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Taxes\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Taxes/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Taxes\\Stats\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Taxes/Stats/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Taxes\\Stats\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Taxes/Stats/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Taxes\\Stats\\Segmenter' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Taxes/Stats/Segmenter.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Taxes\\Stats\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Taxes/Stats/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\PerformanceIndicators\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/PerformanceIndicators/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Orders\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Orders/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Orders\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Orders/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Orders\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Orders/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Orders\\Stats\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Orders/Stats/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Orders\\Stats\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Orders/Stats/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Orders\\Stats\\Segmenter' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Orders/Stats/Segmenter.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Orders\\Stats\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Orders/Stats/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Export\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Export/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Stock\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Stock/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Stock\\Stats\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Stock/Stats/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Stock\\Stats\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Stock/Stats/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Stock\\Stats\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Stock/Stats/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Revenue\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Revenue/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Revenue\\Stats\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Revenue/Stats/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Import\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Import/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Downloads\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Downloads/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Downloads\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Downloads/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Downloads\\Files\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Downloads/Files/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Downloads\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Downloads/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Downloads\\Stats\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Downloads/Stats/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Downloads\\Stats\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Downloads/Stats/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Downloads\\Stats\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Downloads/Stats/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Categories\\Controller' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Categories/Controller.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Categories\\DataStore' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Categories/DataStore.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\Categories\\Query' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/Categories/Query.php' + ), + 'Automattic\\WooCommerce\\Admin\\API\\Reports\\SqlQuery' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/API/Reports/SqlQuery.php' + ), + 'Automattic\\WooCommerce\\Admin\\Marketing\\InstalledExtensions' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Marketing/InstalledExtensions.php' + ), + 'Automattic\\WooCommerce\\Admin\\PageController' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/PageController.php' + ), + 'Automattic\\WooCommerce\\Admin\\Schedulers\\ImportScheduler' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Schedulers/ImportScheduler.php' + ), + 'Automattic\\WooCommerce\\Admin\\Schedulers\\OrdersScheduler' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Schedulers/OrdersScheduler.php' + ), + 'Automattic\\WooCommerce\\Admin\\Schedulers\\SchedulerTraits' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Schedulers/SchedulerTraits.php' + ), + 'Automattic\\WooCommerce\\Admin\\Schedulers\\ImportInterface' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Schedulers/ImportInterface.php' + ), + 'Automattic\\WooCommerce\\Admin\\Schedulers\\CustomersScheduler' => array( + 'version' => '1.7.3.0', + 'path' => $baseDir . '/packages/woocommerce-admin/src/Schedulers/CustomersScheduler.php' + ), + 'Automattic\\WooCommerce\\Container' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Container.php' + ), + 'Automattic\\WooCommerce\\Internal\\WCCom\\ConnectionHelper' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Internal/WCCom/ConnectionHelper.php' + ), + 'Automattic\\WooCommerce\\Internal\\DependencyManagement\\ContainerException' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Internal/DependencyManagement/ContainerException.php' + ), + 'Automattic\\WooCommerce\\Internal\\DependencyManagement\\ExtendedContainer' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Internal/DependencyManagement/ExtendedContainer.php' + ), + 'Automattic\\WooCommerce\\Internal\\DependencyManagement\\AbstractServiceProvider' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Internal/DependencyManagement/AbstractServiceProvider.php' + ), + 'Automattic\\WooCommerce\\Internal\\DependencyManagement\\Definition' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Internal/DependencyManagement/Definition.php' + ), + 'Automattic\\WooCommerce\\Internal\\DependencyManagement\\ServiceProviders\\ProxiesServiceProvider' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Internal/DependencyManagement/ServiceProviders/ProxiesServiceProvider.php' + ), + 'Automattic\\WooCommerce\\Checkout\\Helpers\\ReserveStock' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Checkout/Helpers/ReserveStock.php' + ), + 'Automattic\\WooCommerce\\Checkout\\Helpers\\ReserveStockException' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Checkout/Helpers/ReserveStockException.php' + ), + 'Automattic\\WooCommerce\\Packages' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Packages.php' + ), + 'Automattic\\WooCommerce\\Utilities\\StringUtil' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Utilities/StringUtil.php' + ), + 'Automattic\\WooCommerce\\Utilities\\NumberUtil' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Utilities/NumberUtil.php' + ), + 'Automattic\\WooCommerce\\Proxies\\ActionsProxy' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Proxies/ActionsProxy.php' + ), + 'Automattic\\WooCommerce\\Proxies\\LegacyProxy' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Proxies/LegacyProxy.php' + ), + 'Automattic\\WooCommerce\\Autoloader' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/src/Autoloader.php' + ), + 'Automattic\\Jetpack\\Autoloader\\AutoloadGenerator' => array( + 'version' => '2.2.0.0', + 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadGenerator.php' + ), + 'Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin' => array( + 'version' => '2.2.0.0', + 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php' + ), + 'Automattic\\WooCommerce\\RestApi\\Server' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Server.php' + ), + 'Automattic\\WooCommerce\\RestApi\\Package' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Package.php' + ), + 'Automattic\\WooCommerce\\RestApi\\Utilities\\SingletonTrait' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Utilities/SingletonTrait.php' + ), + 'Automattic\\WooCommerce\\RestApi\\Utilities\\ImageAttachment' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Utilities/ImageAttachment.php' + ), + 'WC_REST_Tax_Classes_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-tax-classes-v1-controller.php' + ), + 'WC_REST_Webhook_Deliveries_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-webhook-deliveries-v1-controller.php' + ), + 'WC_REST_Order_Refunds_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php' + ), + 'WC_REST_Product_Tags_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-tags-v1-controller.php' + ), + 'WC_REST_Product_Categories_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-categories-v1-controller.php' + ), + 'WC_REST_Coupons_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-coupons-v1-controller.php' + ), + 'WC_REST_Taxes_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-taxes-v1-controller.php' + ), + 'WC_REST_Product_Attributes_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-attributes-v1-controller.php' + ), + 'WC_REST_Webhooks_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-webhooks-v1-controller.php' + ), + 'WC_REST_Orders_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php' + ), + 'WC_REST_Reports_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-reports-v1-controller.php' + ), + 'WC_REST_Report_Sales_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-report-sales-v1-controller.php' + ), + 'WC_REST_Order_Notes_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php' + ), + 'WC_REST_Customer_Downloads_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-customer-downloads-v1-controller.php' + ), + 'WC_REST_Product_Attribute_Terms_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php' + ), + 'WC_REST_Report_Top_Sellers_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-report-top-sellers-v1-controller.php' + ), + 'WC_REST_Product_Shipping_Classes_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-shipping-classes-v1-controller.php' + ), + 'WC_REST_Products_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-products-v1-controller.php' + ), + 'WC_REST_Product_Reviews_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php' + ), + 'WC_REST_Customers_V1_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version1/class-wc-rest-customers-v1-controller.php' + ), + 'WC_REST_Report_Products_Totals_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-products-totals-controller.php' + ), + 'WC_REST_Data_Countries_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-countries-controller.php' + ), + 'WC_REST_Product_Attributes_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-attributes-controller.php' + ), + 'WC_REST_Posts_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-posts-controller.php' + ), + 'WC_REST_Order_Refunds_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-order-refunds-controller.php' + ), + 'WC_REST_Product_Variations_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php' + ), + 'WC_REST_CRUD_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php' + ), + 'WC_REST_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-controller.php' + ), + 'WC_REST_Customer_Downloads_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-customer-downloads-controller.php' + ), + 'WC_REST_Data_Currencies_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-currencies-controller.php' + ), + 'WC_REST_Shipping_Methods_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-methods-controller.php' + ), + 'WC_REST_Products_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php' + ), + 'WC_REST_Reports_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-reports-controller.php' + ), + 'WC_REST_Settings_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-settings-controller.php' + ), + 'WC_REST_Report_Orders_Totals_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-orders-totals-controller.php' + ), + 'WC_REST_Product_Tags_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-tags-controller.php' + ), + 'WC_REST_System_Status_Tools_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-tools-controller.php' + ), + 'WC_REST_Product_Categories_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-categories-controller.php' + ), + 'WC_REST_Report_Reviews_Totals_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-reviews-totals-controller.php' + ), + 'WC_REST_Data_Continents_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-continents-controller.php' + ), + 'WC_REST_Orders_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller.php' + ), + 'WC_REST_Taxes_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-taxes-controller.php' + ), + 'WC_REST_Shipping_Zones_Controller_Base' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller-base.php' + ), + 'WC_REST_Data_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-data-controller.php' + ), + 'WC_REST_Shipping_Zone_Locations_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-locations-controller.php' + ), + 'WC_REST_Report_Sales_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-sales-controller.php' + ), + 'WC_REST_Tax_Classes_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-tax-classes-controller.php' + ), + 'WC_REST_Webhooks_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-webhooks-controller.php' + ), + 'WC_REST_Terms_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php' + ), + 'WC_REST_Network_Orders_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-network-orders-controller.php' + ), + 'WC_REST_Product_Attribute_Terms_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-attribute-terms-controller.php' + ), + 'WC_REST_Customers_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-customers-controller.php' + ), + 'WC_REST_Report_Top_Sellers_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-top-sellers-controller.php' + ), + 'WC_REST_Coupons_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-coupons-controller.php' + ), + 'WC_REST_Shipping_Zones_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zones-controller.php' + ), + 'WC_REST_Shipping_Zone_Methods_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php' + ), + 'WC_REST_System_Status_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-system-status-controller.php' + ), + 'WC_REST_Product_Reviews_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php' + ), + 'WC_REST_Product_Shipping_Classes_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-product-shipping-classes-controller.php' + ), + 'WC_REST_Setting_Options_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-setting-options-controller.php' + ), + 'WC_REST_Report_Coupons_Totals_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-coupons-totals-controller.php' + ), + 'WC_REST_Payment_Gateways_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-payment-gateways-controller.php' + ), + 'WC_REST_Order_Notes_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-order-notes-controller.php' + ), + 'WC_REST_Report_Customers_Totals_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version3/class-wc-rest-report-customers-totals-controller.php' + ), + 'WC_REST_Product_Categories_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-categories-v2-controller.php' + ), + 'WC_REST_Shipping_Zone_Locations_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-locations-v2-controller.php' + ), + 'WC_REST_Shipping_Zones_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zones-v2-controller.php' + ), + 'WC_REST_Coupons_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-coupons-v2-controller.php' + ), + 'WC_REST_Taxes_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-taxes-v2-controller.php' + ), + 'WC_REST_Product_Variations_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php' + ), + 'WC_REST_Tax_Classes_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-tax-classes-v2-controller.php' + ), + 'WC_REST_Order_Refunds_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-order-refunds-v2-controller.php' + ), + 'WC_REST_Webhook_Deliveries_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-webhook-deliveries-v2-controller.php' + ), + 'WC_REST_Product_Tags_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-tags-v2-controller.php' + ), + 'WC_REST_Product_Shipping_Classes_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-shipping-classes-v2-controller.php' + ), + 'WC_REST_Report_Top_Sellers_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-report-top-sellers-v2-controller.php' + ), + 'WC_REST_Products_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php' + ), + 'WC_REST_System_Status_Tools_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php' + ), + 'WC_REST_Shipping_Zone_Methods_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-zone-methods-v2-controller.php' + ), + 'WC_REST_Network_Orders_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-network-orders-v2-controller.php' + ), + 'WC_REST_Customers_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-customers-v2-controller.php' + ), + 'WC_REST_Setting_Options_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-setting-options-v2-controller.php' + ), + 'WC_REST_Product_Reviews_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller.php' + ), + 'WC_REST_System_Status_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-v2-controller.php' + ), + 'WC_REST_Webhooks_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-webhooks-v2-controller.php' + ), + 'WC_REST_Product_Attributes_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-attributes-v2-controller.php' + ), + 'WC_REST_Payment_Gateways_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-payment-gateways-v2-controller.php' + ), + 'WC_REST_Settings_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-settings-v2-controller.php' + ), + 'WC_REST_Shipping_Methods_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-shipping-methods-v2-controller.php' + ), + 'WC_REST_Reports_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-reports-v2-controller.php' + ), + 'WC_REST_Report_Sales_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-report-sales-v2-controller.php' + ), + 'WC_REST_Orders_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php' + ), + 'WC_REST_Product_Attribute_Terms_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-product-attribute-terms-v2-controller.php' + ), + 'WC_REST_Customer_Downloads_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-customer-downloads-v2-controller.php' + ), + 'WC_REST_Order_Notes_V2_Controller' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/includes/rest-api/Controllers/Version2/class-wc-rest-order-notes-v2-controller.php' + ), + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\QueueHelper' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/QueueHelper.php' + ), + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\CustomerHelper' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/CustomerHelper.php' + ), + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\OrderHelper' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/OrderHelper.php' + ), + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\CouponHelper' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/CouponHelper.php' + ), + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\SettingsHelper' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/SettingsHelper.php' + ), + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\ShippingHelper' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/ShippingHelper.php' + ), + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\AdminNotesHelper' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/AdminNotesHelper.php' + ), + 'Automattic\\WooCommerce\\RestApi\\UnitTests\\Helpers\\ProductHelper' => array( + 'version' => 'dev-release/4.8', + 'path' => $baseDir . '/tests/legacy/unit-tests/rest-api/Helpers/ProductHelper.php' + ), + 'Automattic\\Jetpack\\Constants' => array( + 'version' => '1.5.0.0', + 'path' => $vendorDir . '/automattic/jetpack-constants/src/class-constants.php' + ), +); + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/jetpack_autoload_filemap.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/jetpack_autoload_filemap.php new file mode 100644 index 0000000..8f008b4 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/composer/jetpack_autoload_filemap.php @@ -0,0 +1,10 @@ += 70000)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/jetpack-autoloader/autoload_functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/jetpack-autoloader/autoload_functions.php new file mode 100644 index 0000000..401032f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/jetpack-autoloader/autoload_functions.php @@ -0,0 +1,149 @@ +set_class_paths(); + + $files_handler = new Files_Handler( $plugins_handler, $version_selector ); + $files_handler->set_file_paths(); + + $files_handler->file_loader(); +} + +/** + * Finds the latest installed autoloader. If this is the latest autoloader, sets + * up the classmap and filemap. + */ +function set_up_autoloader() { + global $jetpack_autoloader_latest_version; + global $jetpack_packages_classmap; + + require_once __DIR__ . '/../class-plugins-handler.php'; + require_once __DIR__ . '/../class-version-selector.php'; + require_once __DIR__ . '/../class-autoloader-handler.php'; + + $plugins_handler = new Plugins_Handler(); + $version_selector = new Version_Selector(); + $autoloader_handler = new Autoloader_Handler( $plugins_handler, $version_selector ); + + if ( $plugins_handler->should_autoloader_reset() ) { + /* + * The autoloader must be reset when an activating plugin that was + * previously unknown is detected. + */ + $jetpack_autoloader_latest_version = null; + $jetpack_packages_classmap = array(); + } + + // Find the latest autoloader. + if ( ! $jetpack_autoloader_latest_version ) { + $autoloader_handler->find_latest_autoloader(); + } + + $current_autoloader_version = $autoloader_handler->get_current_autoloader_version(); + + // This is the latest autoloader, so generate the classmap and filemap and register the autoloader function. + if ( empty( $jetpack_packages_classmap ) && $current_autoloader_version === $jetpack_autoloader_latest_version ) { + enqueue_files( $plugins_handler, $version_selector ); + $autoloader_handler->update_autoloader_chain(); + add_filter( 'upgrader_post_install', __NAMESPACE__ . '\reset_maps_after_update', 0, 3 ); + } +} + +/** + * Resets the autoloader after a plugin update. + * + * @param bool $response Installation response. + * @param array $hook_extra Extra arguments passed to hooked filters. + * @param array $result Installation result data. + * + * @return bool The passed in $response param. + */ +function reset_maps_after_update( $response, $hook_extra, $result ) { + global $jetpack_packages_classmap; + + if ( isset( $hook_extra['plugin'] ) ) { + /* + * $hook_extra['plugin'] is the path to the plugin file relative to the plugins directory: + * https://core.trac.wordpress.org/browser/tags/5.4/src/wp-admin/includes/class-wp-upgrader.php#L701 + */ + $plugin = $hook_extra['plugin']; + + if ( false === strpos( $plugin, '/', 1 ) ) { + // Single-file plugins don't use packages, so bail. + return $response; + } + + if ( ! is_plugin_active( $plugin ) ) { + // The updated plugin isn't active, so bail. + return $response; + } + + /* + * $plugin is the path to the plugin file relative to the plugins directory. + */ + $plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR ); + $plugin_path = trailingslashit( $plugin_dir ) . trailingslashit( explode( '/', $plugin )[0] ); + + if ( is_readable( $plugin_path . 'vendor/jetpack-autoloader/autoload_functions.php' ) ) { + // The plugin has a >=v2.2 autoloader, so reset the classmap. + $jetpack_packages_classmap = array(); + + set_up_autoloader(); + } + } + + return $response; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/ArgumentResolverInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/ArgumentResolverInterface.php new file mode 100644 index 0000000..9c7393f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/ArgumentResolverInterface.php @@ -0,0 +1,28 @@ +getValue(); + } elseif ($argument instanceof ClassNameInterface) { + $id = $argument->getClassName(); + } elseif (!is_string($argument)) { + return $argument; + } else { + $justStringValue = true; + $id = $argument; + } + + $container = null; + + try { + $container = $this->getLeagueContainer(); + } catch (ContainerException $e) { + if ($this instanceof ReflectionContainer) { + $container = $this; + } + } + + if ($container !== null) { + try { + return $container->get($id); + } catch (NotFoundException $exception) { + if ($argument instanceof ClassNameWithOptionalValue) { + return $argument->getOptionalValue(); + } + + if ($justStringValue) { + return $id; + } + + throw $exception; + } + } + + if ($argument instanceof ClassNameWithOptionalValue) { + return $argument->getOptionalValue(); + } + + // Just a string value. + return $id; + }, $arguments); + } + + /** + * {@inheritdoc} + */ + public function reflectArguments(ReflectionFunctionAbstract $method, array $args = []) : array + { + $arguments = array_map(function (ReflectionParameter $param) use ($method, $args) { + $name = $param->getName(); + $type = $param->getType(); + + if (array_key_exists($name, $args)) { + return new RawArgument($args[$name]); + } + + if ($type) { + if (PHP_VERSION_ID >= 70200) { + $typeName = $type->getName(); + } else { + $typeName = (string) $type; + } + + $typeName = ltrim($typeName, '?'); + + if ($param->isDefaultValueAvailable()) { + return new ClassNameWithOptionalValue($typeName, $param->getDefaultValue()); + } + + return new ClassName($typeName); + } + + if ($param->isDefaultValueAvailable()) { + return new RawArgument($param->getDefaultValue()); + } + + throw new NotFoundException(sprintf( + 'Unable to resolve a value for parameter (%s) in the function/method (%s)', + $name, + $method->getName() + )); + }, $method->getParameters()); + + return $this->resolveArguments($arguments); + } + + /** + * @return ContainerInterface + */ + abstract public function getContainer() : ContainerInterface; + + /** + * @return Container + */ + abstract public function getLeagueContainer() : Container; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/ClassName.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/ClassName.php new file mode 100644 index 0000000..bab358f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/ClassName.php @@ -0,0 +1,29 @@ +value = $value; + } + + /** + * {@inheritdoc} + */ + public function getClassName() : string + { + return $this->value; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/ClassNameInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/ClassNameInterface.php new file mode 100644 index 0000000..ab2708e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/ClassNameInterface.php @@ -0,0 +1,13 @@ +className = $className; + $this->optionalValue = $optionalValue; + } + + /** + * @inheritDoc + */ + public function getClassName(): string + { + return $this->className; + } + + public function getOptionalValue() + { + return $this->optionalValue; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/RawArgument.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/RawArgument.php new file mode 100644 index 0000000..fe0ddd0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/RawArgument.php @@ -0,0 +1,29 @@ +value = $value; + } + + /** + * {@inheritdoc} + */ + public function getValue() + { + return $this->value; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/RawArgumentInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/RawArgumentInterface.php new file mode 100644 index 0000000..8730cac --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Argument/RawArgumentInterface.php @@ -0,0 +1,13 @@ +definitions = $definitions ?? new DefinitionAggregate; + $this->providers = $providers ?? new ServiceProviderAggregate; + $this->inflectors = $inflectors ?? new InflectorAggregate; + + if ($this->definitions instanceof ContainerAwareInterface) { + $this->definitions->setLeagueContainer($this); + } + + if ($this->providers instanceof ContainerAwareInterface) { + $this->providers->setLeagueContainer($this); + } + + if ($this->inflectors instanceof ContainerAwareInterface) { + $this->inflectors->setLeagueContainer($this); + } + } + + /** + * Add an item to the container. + * + * @param string $id + * @param mixed $concrete + * @param boolean $shared + * + * @return DefinitionInterface + */ + public function add(string $id, $concrete = null, bool $shared = null) : DefinitionInterface + { + $concrete = $concrete ?? $id; + $shared = $shared ?? $this->defaultToShared; + + return $this->definitions->add($id, $concrete, $shared); + } + + /** + * Proxy to add with shared as true. + * + * @param string $id + * @param mixed $concrete + * + * @return DefinitionInterface + */ + public function share(string $id, $concrete = null) : DefinitionInterface + { + return $this->add($id, $concrete, true); + } + + /** + * Whether the container should default to defining shared definitions. + * + * @param boolean $shared + * + * @return self + */ + public function defaultToShared(bool $shared = true) : ContainerInterface + { + $this->defaultToShared = $shared; + + return $this; + } + + /** + * Get a definition to extend. + * + * @param string $id [description] + * + * @return DefinitionInterface + */ + public function extend(string $id) : DefinitionInterface + { + if ($this->providers->provides($id)) { + $this->providers->register($id); + } + + if ($this->definitions->has($id)) { + return $this->definitions->getDefinition($id); + } + + throw new NotFoundException( + sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $id) + ); + } + + /** + * Add a service provider. + * + * @param ServiceProviderInterface|string $provider + * + * @return self + */ + public function addServiceProvider($provider) : self + { + $this->providers->add($provider); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function get($id, bool $new = false) + { + if ($this->definitions->has($id)) { + $resolved = $this->definitions->resolve($id, $new); + return $this->inflectors->inflect($resolved); + } + + if ($this->definitions->hasTag($id)) { + $arrayOf = $this->definitions->resolveTagged($id, $new); + + array_walk($arrayOf, function (&$resolved) { + $resolved = $this->inflectors->inflect($resolved); + }); + + return $arrayOf; + } + + if ($this->providers->provides($id)) { + $this->providers->register($id); + + if (!$this->definitions->has($id) && !$this->definitions->hasTag($id)) { + throw new ContainerException(sprintf('Service provider lied about providing (%s) service', $id)); + } + + return $this->get($id, $new); + } + + foreach ($this->delegates as $delegate) { + if ($delegate->has($id)) { + $resolved = $delegate->get($id); + return $this->inflectors->inflect($resolved); + } + } + + throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id)); + } + + /** + * {@inheritdoc} + */ + public function has($id) : bool + { + if ($this->definitions->has($id)) { + return true; + } + + if ($this->definitions->hasTag($id)) { + return true; + } + + if ($this->providers->provides($id)) { + return true; + } + + foreach ($this->delegates as $delegate) { + if ($delegate->has($id)) { + return true; + } + } + + return false; + } + + /** + * Allows for manipulation of specific types on resolution. + * + * @param string $type + * @param callable|null $callback + * + * @return InflectorInterface + */ + public function inflector(string $type, callable $callback = null) : InflectorInterface + { + return $this->inflectors->add($type, $callback); + } + + /** + * Delegate a backup container to be checked for services if it + * cannot be resolved via this container. + * + * @param ContainerInterface $container + * + * @return self + */ + public function delegate(ContainerInterface $container) : self + { + $this->delegates[] = $container; + + if ($container instanceof ContainerAwareInterface) { + $container->setLeagueContainer($this); + } + + return $this; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ContainerAwareInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ContainerAwareInterface.php new file mode 100644 index 0000000..b0a4f91 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ContainerAwareInterface.php @@ -0,0 +1,40 @@ +container = $container; + + return $this; + } + + /** + * Get the container. + * + * @return ContainerInterface + */ + public function getContainer() : ContainerInterface + { + if ($this->container instanceof ContainerInterface) { + return $this->container; + } + + throw new ContainerException('No container implementation has been set.'); + } + + /** + * Set a container. + * + * @param Container $container + * + * @return self + */ + public function setLeagueContainer(Container $container) : ContainerAwareInterface + { + $this->container = $container; + $this->leagueContainer = $container; + + return $this; + } + + /** + * Get the container. + * + * @return Container + */ + public function getLeagueContainer() : Container + { + if ($this->leagueContainer instanceof Container) { + return $this->leagueContainer; + } + + throw new ContainerException('No container implementation has been set.'); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Definition/Definition.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Definition/Definition.php new file mode 100644 index 0000000..c357080 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Definition/Definition.php @@ -0,0 +1,274 @@ +alias = $id; + $this->concrete = $concrete; + } + + /** + * {@inheritdoc} + */ + public function addTag(string $tag) : DefinitionInterface + { + $this->tags[$tag] = true; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function hasTag(string $tag) : bool + { + return isset($this->tags[$tag]); + } + + /** + * {@inheritdoc} + */ + public function setAlias(string $id) : DefinitionInterface + { + $this->alias = $id; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getAlias() : string + { + return $this->alias; + } + + /** + * {@inheritdoc} + */ + public function setShared(bool $shared = true) : DefinitionInterface + { + $this->shared = $shared; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function isShared() : bool + { + return $this->shared; + } + + /** + * {@inheritdoc} + */ + public function getConcrete() + { + return $this->concrete; + } + + /** + * {@inheritdoc} + */ + public function setConcrete($concrete) : DefinitionInterface + { + $this->concrete = $concrete; + $this->resolved = null; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addArgument($arg) : DefinitionInterface + { + $this->arguments[] = $arg; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addArguments(array $args) : DefinitionInterface + { + foreach ($args as $arg) { + $this->addArgument($arg); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addMethodCall(string $method, array $args = []) : DefinitionInterface + { + $this->methods[] = [ + 'method' => $method, + 'arguments' => $args + ]; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addMethodCalls(array $methods = []) : DefinitionInterface + { + foreach ($methods as $method => $args) { + $this->addMethodCall($method, $args); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function resolve(bool $new = false) + { + $concrete = $this->concrete; + + if ($this->isShared() && $this->resolved !== null && $new === false) { + return $this->resolved; + } + + if (is_callable($concrete)) { + $concrete = $this->resolveCallable($concrete); + } + + if ($concrete instanceof RawArgumentInterface) { + $this->resolved = $concrete->getValue(); + + return $concrete->getValue(); + } + + if ($concrete instanceof ClassNameInterface) { + $concrete = $concrete->getClassName(); + } + + if (is_string($concrete) && class_exists($concrete)) { + $concrete = $this->resolveClass($concrete); + } + + if (is_object($concrete)) { + $concrete = $this->invokeMethods($concrete); + } + + $this->resolved = $concrete; + + return $concrete; + } + + /** + * Resolve a callable. + * + * @param callable $concrete + * + * @return mixed + */ + protected function resolveCallable(callable $concrete) + { + $resolved = $this->resolveArguments($this->arguments); + + return call_user_func_array($concrete, $resolved); + } + + /** + * Resolve a class. + * + * @param string $concrete + * + * @return object + * + * @throws ReflectionException + */ + protected function resolveClass(string $concrete) + { + $resolved = $this->resolveArguments($this->arguments); + $reflection = new ReflectionClass($concrete); + + return $reflection->newInstanceArgs($resolved); + } + + /** + * Invoke methods on resolved instance. + * + * @param object $instance + * + * @return object + */ + protected function invokeMethods($instance) + { + foreach ($this->methods as $method) { + $args = $this->resolveArguments($method['arguments']); + + /** @var callable $callable */ + $callable = [$instance, $method['method']]; + call_user_func_array($callable, $args); + } + + return $instance; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Definition/DefinitionAggregate.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Definition/DefinitionAggregate.php new file mode 100644 index 0000000..3e39b2f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Definition/DefinitionAggregate.php @@ -0,0 +1,124 @@ +definitions = array_filter($definitions, function ($definition) { + return ($definition instanceof DefinitionInterface); + }); + } + + /** + * {@inheritdoc} + */ + public function add(string $id, $definition, bool $shared = false) : DefinitionInterface + { + if (!$definition instanceof DefinitionInterface) { + $definition = new Definition($id, $definition); + } + + $this->definitions[] = $definition + ->setAlias($id) + ->setShared($shared) + ; + + return $definition; + } + + /** + * {@inheritdoc} + */ + public function has(string $id) : bool + { + foreach ($this->getIterator() as $definition) { + if ($id === $definition->getAlias()) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function hasTag(string $tag) : bool + { + foreach ($this->getIterator() as $definition) { + if ($definition->hasTag($tag)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getDefinition(string $id) : DefinitionInterface + { + foreach ($this->getIterator() as $definition) { + if ($id === $definition->getAlias()) { + return $definition->setLeagueContainer($this->getLeagueContainer()); + } + } + + throw new NotFoundException(sprintf('Alias (%s) is not being handled as a definition.', $id)); + } + + /** + * {@inheritdoc} + */ + public function resolve(string $id, bool $new = false) + { + return $this->getDefinition($id)->resolve($new); + } + + /** + * {@inheritdoc} + */ + public function resolveTagged(string $tag, bool $new = false) : array + { + $arrayOf = []; + + foreach ($this->getIterator() as $definition) { + if ($definition->hasTag($tag)) { + $arrayOf[] = $definition->setLeagueContainer($this->getLeagueContainer())->resolve($new); + } + } + + return $arrayOf; + } + + /** + * {@inheritdoc} + */ + public function getIterator() : Generator + { + $count = count($this->definitions); + + for ($i = 0; $i < $count; $i++) { + yield $this->definitions[$i]; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Definition/DefinitionAggregateInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Definition/DefinitionAggregateInterface.php new file mode 100644 index 0000000..2d5842f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Definition/DefinitionAggregateInterface.php @@ -0,0 +1,67 @@ +type = $type; + $this->callback = $callback; + } + + /** + * {@inheritdoc} + */ + public function getType() : string + { + return $this->type; + } + + /** + * {@inheritdoc} + */ + public function invokeMethod(string $name, array $args) : InflectorInterface + { + $this->methods[$name] = $args; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function invokeMethods(array $methods) : InflectorInterface + { + foreach ($methods as $name => $args) { + $this->invokeMethod($name, $args); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function setProperty(string $property, $value) : InflectorInterface + { + $this->properties[$property] = $this->resolveArguments([$value])[0]; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function setProperties(array $properties) : InflectorInterface + { + foreach ($properties as $property => $value) { + $this->setProperty($property, $value); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function inflect($object) + { + $properties = $this->resolveArguments(array_values($this->properties)); + $properties = array_combine(array_keys($this->properties), $properties); + + // array_combine() can technically return false + foreach ($properties ?: [] as $property => $value) { + $object->{$property} = $value; + } + + foreach ($this->methods as $method => $args) { + $args = $this->resolveArguments($args); + + /** @var callable $callable */ + $callable = [$object, $method]; + call_user_func_array($callable, $args); + } + + if ($this->callback !== null) { + call_user_func($this->callback, $object); + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Inflector/InflectorAggregate.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Inflector/InflectorAggregate.php new file mode 100644 index 0000000..4db8471 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Inflector/InflectorAggregate.php @@ -0,0 +1,58 @@ +inflectors[] = $inflector; + + return $inflector; + } + + /** + * {@inheritdoc} + */ + public function getIterator() : Generator + { + $count = count($this->inflectors); + + for ($i = 0; $i < $count; $i++) { + yield $this->inflectors[$i]; + } + } + + /** + * {@inheritdoc} + */ + public function inflect($object) + { + foreach ($this->getIterator() as $inflector) { + $type = $inflector->getType(); + + if (! $object instanceof $type) { + continue; + } + + $inflector->setLeagueContainer($this->getLeagueContainer()); + $inflector->inflect($object); + } + + return $object; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Inflector/InflectorAggregateInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Inflector/InflectorAggregateInterface.php new file mode 100644 index 0000000..aac6455 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/Inflector/InflectorAggregateInterface.php @@ -0,0 +1,27 @@ +cacheResolutions === true && array_key_exists($id, $this->cache)) { + return $this->cache[$id]; + } + + if (! $this->has($id)) { + throw new NotFoundException( + sprintf('Alias (%s) is not an existing class and therefore cannot be resolved', $id) + ); + } + + $reflector = new ReflectionClass($id); + $construct = $reflector->getConstructor(); + + $resolution = $construct === null + ? new $id + : $resolution = $reflector->newInstanceArgs($this->reflectArguments($construct, $args)) + ; + + if ($this->cacheResolutions === true) { + $this->cache[$id] = $resolution; + } + + return $resolution; + } + + /** + * {@inheritdoc} + */ + public function has($id) : bool + { + return class_exists($id); + } + + /** + * Invoke a callable via the container. + * + * @param callable $callable + * @param array $args + * + * @return mixed + * + * @throws ReflectionException + */ + public function call(callable $callable, array $args = []) + { + if (is_string($callable) && strpos($callable, '::') !== false) { + $callable = explode('::', $callable); + } + + if (is_array($callable)) { + if (is_string($callable[0])) { + $callable[0] = $this->getContainer()->get($callable[0]); + } + + $reflection = new ReflectionMethod($callable[0], $callable[1]); + + if ($reflection->isStatic()) { + $callable[0] = null; + } + + return $reflection->invokeArgs($callable[0], $this->reflectArguments($reflection, $args)); + } + + if (is_object($callable)) { + $reflection = new ReflectionMethod($callable, '__invoke'); + + return $reflection->invokeArgs($callable, $this->reflectArguments($reflection, $args)); + } + + $reflection = new ReflectionFunction(\Closure::fromCallable($callable)); + + return $reflection->invokeArgs($this->reflectArguments($reflection, $args)); + } + + /** + * Whether the container should default to caching resolutions and returning + * the cache on following calls. + * + * @param boolean $option + * + * @return self + */ + public function cacheResolutions(bool $option = true) : ContainerInterface + { + $this->cacheResolutions = $option; + + return $this; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ServiceProvider/AbstractServiceProvider.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ServiceProvider/AbstractServiceProvider.php new file mode 100644 index 0000000..ed6af44 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ServiceProvider/AbstractServiceProvider.php @@ -0,0 +1,46 @@ +provides, true); + } + + /** + * {@inheritdoc} + */ + public function setIdentifier(string $id) : ServiceProviderInterface + { + $this->identifier = $id; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getIdentifier() : string + { + return $this->identifier ?? get_class($this); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ServiceProvider/BootableServiceProviderInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ServiceProvider/BootableServiceProviderInterface.php new file mode 100644 index 0000000..195b48a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ServiceProvider/BootableServiceProviderInterface.php @@ -0,0 +1,14 @@ +getContainer()->has($provider)) { + $provider = $this->getContainer()->get($provider); + } elseif (is_string($provider) && class_exists($provider)) { + $provider = new $provider; + } + + if (in_array($provider, $this->providers, true)) { + return $this; + } + + if ($provider instanceof ContainerAwareInterface) { + $provider->setLeagueContainer($this->getLeagueContainer()); + } + + if ($provider instanceof BootableServiceProviderInterface) { + $provider->boot(); + } + + if ($provider instanceof ServiceProviderInterface) { + $this->providers[] = $provider; + + return $this; + } + + throw new ContainerException( + 'A service provider must be a fully qualified class name or instance ' . + 'of (\League\Container\ServiceProvider\ServiceProviderInterface)' + ); + } + + /** + * {@inheritdoc} + */ + public function provides(string $service) : bool + { + foreach ($this->getIterator() as $provider) { + if ($provider->provides($service)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getIterator() : Generator + { + $count = count($this->providers); + + for ($i = 0; $i < $count; $i++) { + yield $this->providers[$i]; + } + } + + /** + * {@inheritdoc} + */ + public function register(string $service) + { + if (false === $this->provides($service)) { + throw new ContainerException( + sprintf('(%s) is not provided by a service provider', $service) + ); + } + + foreach ($this->getIterator() as $provider) { + if (in_array($provider->getIdentifier(), $this->registered, true)) { + continue; + } + + if ($provider->provides($service)) { + $provider->register(); + $this->registered[] = $provider->getIdentifier(); + } + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ServiceProvider/ServiceProviderAggregateInterface.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ServiceProvider/ServiceProviderAggregateInterface.php new file mode 100644 index 0000000..c2f61d6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/league/container/src/ServiceProvider/ServiceProviderAggregateInterface.php @@ -0,0 +1,36 @@ +leagueContainer property or the `getLeagueContainer` method + * from the ContainerAwareTrait. + * + * @return void + */ + public function register(); + + /** + * Set a custom id for the service provider. This enables + * registering the same service provider multiple times. + * + * @param string $id + * + * @return self + */ + public function setIdentifier(string $id) : ServiceProviderInterface; + + /** + * The id of the service provider uniquely identifies it, so + * that we can quickly determine if it has already been registered. + * Defaults to get_class($provider). + * + * @return string + */ + public function getIdentifier() : string; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/LICENSE b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/autoload.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/autoload.php new file mode 100644 index 0000000..1314b69 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/autoload.php @@ -0,0 +1,45 @@ +class. + * + * @param string $class + * the name of the class to load + */ +function mmdb_autoload($class) +{ + /* + * A project-specific mapping between the namespaces and where + * they're located. By convention, we include the trailing + * slashes. The one-element array here simply makes things easy + * to extend in the future if (for example) the test classes + * begin to use one another. + */ + $namespace_map = ['MaxMind\\Db\\' => __DIR__ . '/src/MaxMind/Db/']; + + foreach ($namespace_map as $prefix => $dir) { + /* First swap out the namespace prefix with a directory... */ + $path = str_replace($prefix, $dir, $class); + + /* replace the namespace separator with a directory separator... */ + $path = str_replace('\\', '/', $path); + + /* and finally, add the PHP file extension to the result. */ + $path = $path . '.php'; + + /* $path should now contain the path to a PHP file defining $class */ + if (file_exists($path)) { + include $path; + } + } +} + +spl_autoload_register('mmdb_autoload'); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/config.m4 b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/config.m4 new file mode 100644 index 0000000..675e00c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/config.m4 @@ -0,0 +1,40 @@ +PHP_ARG_WITH(maxminddb, + [Whether to enable the MaxMind DB Reader extension], + [ --with-maxminddb Enable MaxMind DB Reader extension support]) + +PHP_ARG_ENABLE(maxminddb-debug, for MaxMind DB debug support, + [ --enable-maxminddb-debug Enable enable MaxMind DB deubg support], no, no) + +if test $PHP_MAXMINDDB != "no"; then + + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + + AC_MSG_CHECKING(for libmaxminddb) + if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libmaxminddb; then + dnl retrieve build options from pkg-config + if $PKG_CONFIG libmaxminddb --atleast-version 1.0.0; then + LIBMAXMINDDB_INC=`$PKG_CONFIG libmaxminddb --cflags` + LIBMAXMINDDB_LIB=`$PKG_CONFIG libmaxminddb --libs` + LIBMAXMINDDB_VER=`$PKG_CONFIG libmaxminddb --modversion` + AC_MSG_RESULT(found version $LIBMAXMINDDB_VER) + else + AC_MSG_ERROR(system libmaxminddb must be upgraded to version >= 1.0.0) + fi + PHP_EVAL_LIBLINE($LIBMAXMINDDB_LIB, MAXMINDDB_SHARED_LIBADD) + PHP_EVAL_INCLINE($LIBMAXMINDDB_INC) + else + AC_MSG_RESULT(pkg-config information missing) + AC_MSG_WARN(will use libmaxmxinddb from compiler default path) + + PHP_CHECK_LIBRARY(maxminddb, MMDB_open) + PHP_ADD_LIBRARY(maxminddb, 1, MAXMINDDB_SHARED_LIBADD) + fi + + if test $PHP_MAXMINDDB_DEBUG != "no"; then + CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror" + fi + + PHP_SUBST(MAXMINDDB_SHARED_LIBADD) + + PHP_NEW_EXTENSION(maxminddb, maxminddb.c, $ext_shared) +fi diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/maxminddb.c b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/maxminddb.c new file mode 100644 index 0000000..a97a3d9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/maxminddb.c @@ -0,0 +1,704 @@ +/* MaxMind, Inc., licenses this file to you under the Apache License, Version + * 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#include "php_maxminddb.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "Zend/zend_exceptions.h" +#include "ext/standard/info.h" +#include + +#ifdef ZTS +#include +#endif + +#define __STDC_FORMAT_MACROS +#include + +#define PHP_MAXMINDDB_NS ZEND_NS_NAME("MaxMind", "Db") +#define PHP_MAXMINDDB_READER_NS ZEND_NS_NAME(PHP_MAXMINDDB_NS, "Reader") +#define PHP_MAXMINDDB_READER_EX_NS \ + ZEND_NS_NAME(PHP_MAXMINDDB_READER_NS, "InvalidDatabaseException") + +#ifdef ZEND_ENGINE_3 +#define Z_MAXMINDDB_P(zv) php_maxminddb_fetch_object(Z_OBJ_P(zv)) +#define _ZVAL_STRING ZVAL_STRING +#define _ZVAL_STRINGL ZVAL_STRINGL +typedef size_t strsize_t; +typedef zend_object free_obj_t; +#else +#define Z_MAXMINDDB_P(zv) \ + (maxminddb_obj *)zend_object_store_get_object(zv TSRMLS_CC) +#define _ZVAL_STRING(a, b) ZVAL_STRING(a, b, 1) +#define _ZVAL_STRINGL(a, b, c) ZVAL_STRINGL(a, b, c, 1) +typedef int strsize_t; +typedef void free_obj_t; +#endif + +/* For PHP 8 compatibility */ +#ifndef TSRMLS_C +#define TSRMLS_C +#endif +#ifndef TSRMLS_CC +#define TSRMLS_CC +#endif +#ifndef TSRMLS_DC +#define TSRMLS_DC +#endif +#ifndef ZEND_ACC_CTOR +#define ZEND_ACC_CTOR 0 +#endif + +#ifdef ZEND_ENGINE_3 +typedef struct _maxminddb_obj { + MMDB_s *mmdb; + zend_object std; +} maxminddb_obj; +#else +typedef struct _maxminddb_obj { + zend_object std; + MMDB_s *mmdb; +} maxminddb_obj; +#endif + +PHP_FUNCTION(maxminddb); + +static int +get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len); +static const MMDB_entry_data_list_s * +handle_entry_data_list(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC); +static const MMDB_entry_data_list_s * +handle_array(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC); +static const MMDB_entry_data_list_s * +handle_map(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC); +static void handle_uint128(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC); +static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC); +static void handle_uint32(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC); +static zend_class_entry *lookup_class(const char *name TSRMLS_DC); + +#define CHECK_ALLOCATED(val) \ + if (!val) { \ + zend_error(E_ERROR, "Out of memory"); \ + return; \ + } + +#define THROW_EXCEPTION(name, ...) \ + { \ + zend_class_entry *exception_ce = lookup_class(name TSRMLS_CC); \ + zend_throw_exception_ex(exception_ce, 0 TSRMLS_CC, __VA_ARGS__); \ + } + +#if PHP_VERSION_ID < 50399 +#define object_properties_init(zo, class_type) \ + { \ + zval *tmp; \ + zend_hash_copy((*zo).properties, \ + &class_type->default_properties, \ + (copy_ctor_func_t)zval_add_ref, \ + (void *)&tmp, \ + sizeof(zval *)); \ + } +#endif + +static zend_object_handlers maxminddb_obj_handlers; +static zend_class_entry *maxminddb_ce; + +static inline maxminddb_obj * +php_maxminddb_fetch_object(zend_object *obj TSRMLS_DC) { +#ifdef ZEND_ENGINE_3 + return (maxminddb_obj *)((char *)(obj)-XtOffsetOf(maxminddb_obj, std)); +#else + return (maxminddb_obj *)obj; +#endif +} + +ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_construct, 0, 0, 1) +ZEND_ARG_INFO(0, db_file) +ZEND_END_ARG_INFO() + +PHP_METHOD(MaxMind_Db_Reader, __construct) { + char *db_file = NULL; + strsize_t name_len; + zval *_this_zval = NULL; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + getThis(), + "Os", + &_this_zval, + maxminddb_ce, + &db_file, + &name_len) == FAILURE) { + THROW_EXCEPTION("InvalidArgumentException", + "The constructor takes exactly one argument."); + return; + } + + if (0 != php_check_open_basedir(db_file TSRMLS_CC) || + 0 != access(db_file, R_OK)) { + THROW_EXCEPTION("InvalidArgumentException", + "The file \"%s\" does not exist or is not readable.", + db_file); + return; + } + + MMDB_s *mmdb = (MMDB_s *)ecalloc(1, sizeof(MMDB_s)); + uint16_t status = MMDB_open(db_file, MMDB_MODE_MMAP, mmdb); + + if (MMDB_SUCCESS != status) { + THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS, + "Error opening database file (%s). Is this a valid " + "MaxMind DB file?", + db_file); + efree(mmdb); + return; + } + + maxminddb_obj *mmdb_obj = Z_MAXMINDDB_P(getThis()); + mmdb_obj->mmdb = mmdb; +} + +ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_get, 0, 0, 1) +ZEND_ARG_INFO(0, ip_address) +ZEND_END_ARG_INFO() + +PHP_METHOD(MaxMind_Db_Reader, get) { + int prefix_len = 0; + get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, return_value, &prefix_len); +} + +PHP_METHOD(MaxMind_Db_Reader, getWithPrefixLen) { + zval *record, *z_prefix_len; +#ifdef ZEND_ENGINE_3 + zval _record, _z_prefix_len; + record = &_record; + z_prefix_len = &_z_prefix_len; +#else + ALLOC_INIT_ZVAL(record); + ALLOC_INIT_ZVAL(z_prefix_len); +#endif + + int prefix_len = 0; + if (get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, record, &prefix_len)) { + return; + } + + array_init(return_value); + add_next_index_zval(return_value, record); + + ZVAL_LONG(z_prefix_len, prefix_len); + add_next_index_zval(return_value, z_prefix_len); +} + +static int +get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) { + char *ip_address = NULL; + strsize_t name_len; + zval *_this_zval = NULL; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + getThis(), + "Os", + &_this_zval, + maxminddb_ce, + &ip_address, + &name_len) == FAILURE) { + THROW_EXCEPTION("InvalidArgumentException", + "Method takes exactly one argument."); + return 1; + } + + const maxminddb_obj *mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(getThis()); + + MMDB_s *mmdb = mmdb_obj->mmdb; + + if (NULL == mmdb) { + THROW_EXCEPTION("BadMethodCallException", + "Attempt to read from a closed MaxMind DB."); + return 1; + } + + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_flags = AI_NUMERICHOST, + // We set ai_socktype so that we only get one result back + .ai_socktype = SOCK_STREAM}; + + struct addrinfo *addresses = NULL; + int gai_status = getaddrinfo(ip_address, NULL, &hints, &addresses); + if (gai_status) { + THROW_EXCEPTION("InvalidArgumentException", + "The value \"%s\" is not a valid IP address.", + ip_address); + return 1; + } + if (!addresses || !addresses->ai_addr) { + THROW_EXCEPTION( + "InvalidArgumentException", + "getaddrinfo was successful but failed to set the addrinfo"); + return 1; + } + + int sa_family = addresses->ai_addr->sa_family; + + int mmdb_error = MMDB_SUCCESS; + MMDB_lookup_result_s result = + MMDB_lookup_sockaddr(mmdb, addresses->ai_addr, &mmdb_error); + + freeaddrinfo(addresses); + + if (MMDB_SUCCESS != mmdb_error) { + char *exception_name; + if (MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR == mmdb_error) { + exception_name = "InvalidArgumentException"; + } else { + exception_name = PHP_MAXMINDDB_READER_EX_NS; + } + THROW_EXCEPTION(exception_name, + "Error looking up %s. %s", + ip_address, + MMDB_strerror(mmdb_error)); + return 1; + } + + *prefix_len = result.netmask; + + if (sa_family == AF_INET && mmdb->metadata.ip_version == 6) { + // We return the prefix length given the IPv4 address. If there is + // no IPv4 subtree, we return a prefix length of 0. + *prefix_len = *prefix_len >= 96 ? *prefix_len - 96 : 0; + } + + if (!result.found_entry) { + ZVAL_NULL(record); + return 0; + } + + MMDB_entry_data_list_s *entry_data_list = NULL; + int status = MMDB_get_entry_data_list(&result.entry, &entry_data_list); + + if (MMDB_SUCCESS != status) { + THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS, + "Error while looking up data for %s. %s", + ip_address, + MMDB_strerror(status)); + MMDB_free_entry_data_list(entry_data_list); + return 1; + } else if (NULL == entry_data_list) { + THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS, + "Error while looking up data for %s. Your database may " + "be corrupt or you have found a bug in libmaxminddb.", + ip_address); + return 1; + } + + handle_entry_data_list(entry_data_list, record TSRMLS_CC); + MMDB_free_entry_data_list(entry_data_list); + return 0; +} + +ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +PHP_METHOD(MaxMind_Db_Reader, metadata) { + if (ZEND_NUM_ARGS() != 0) { + THROW_EXCEPTION("InvalidArgumentException", + "Method takes no arguments."); + return; + } + + const maxminddb_obj *const mmdb_obj = + (maxminddb_obj *)Z_MAXMINDDB_P(getThis()); + + if (NULL == mmdb_obj->mmdb) { + THROW_EXCEPTION("BadMethodCallException", + "Attempt to read from a closed MaxMind DB."); + return; + } + + const char *const name = ZEND_NS_NAME(PHP_MAXMINDDB_READER_NS, "Metadata"); + zend_class_entry *metadata_ce = lookup_class(name TSRMLS_CC); + + object_init_ex(return_value, metadata_ce); + +#ifdef ZEND_ENGINE_3 + zval _metadata_array; + zval *metadata_array = &_metadata_array; + ZVAL_NULL(metadata_array); +#else + zval *metadata_array; + ALLOC_INIT_ZVAL(metadata_array); +#endif + + MMDB_entry_data_list_s *entry_data_list; + MMDB_get_metadata_as_entry_data_list(mmdb_obj->mmdb, &entry_data_list); + + handle_entry_data_list(entry_data_list, metadata_array TSRMLS_CC); + MMDB_free_entry_data_list(entry_data_list); +#if PHP_VERSION_ID >= 80000 + zend_call_method_with_1_params(Z_OBJ_P(return_value), + metadata_ce, + &metadata_ce->constructor, + ZEND_CONSTRUCTOR_FUNC_NAME, + NULL, + metadata_array); + zval_ptr_dtor(metadata_array); +#elif defined(ZEND_ENGINE_3) + zend_call_method_with_1_params(return_value, + metadata_ce, + &metadata_ce->constructor, + ZEND_CONSTRUCTOR_FUNC_NAME, + NULL, + metadata_array); + zval_ptr_dtor(metadata_array); +#else + zend_call_method_with_1_params(&return_value, + metadata_ce, + &metadata_ce->constructor, + ZEND_CONSTRUCTOR_FUNC_NAME, + NULL, + metadata_array); + zval_ptr_dtor(&metadata_array); +#endif +} + +PHP_METHOD(MaxMind_Db_Reader, close) { + if (ZEND_NUM_ARGS() != 0) { + THROW_EXCEPTION("InvalidArgumentException", + "Method takes no arguments."); + return; + } + + maxminddb_obj *mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(getThis()); + + if (NULL == mmdb_obj->mmdb) { + THROW_EXCEPTION("BadMethodCallException", + "Attempt to close a closed MaxMind DB."); + return; + } + MMDB_close(mmdb_obj->mmdb); + efree(mmdb_obj->mmdb); + mmdb_obj->mmdb = NULL; +} + +static const MMDB_entry_data_list_s * +handle_entry_data_list(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC) { + switch (entry_data_list->entry_data.type) { + case MMDB_DATA_TYPE_MAP: + return handle_map(entry_data_list, z_value TSRMLS_CC); + case MMDB_DATA_TYPE_ARRAY: + return handle_array(entry_data_list, z_value TSRMLS_CC); + case MMDB_DATA_TYPE_UTF8_STRING: + _ZVAL_STRINGL(z_value, + (char *)entry_data_list->entry_data.utf8_string, + entry_data_list->entry_data.data_size); + break; + case MMDB_DATA_TYPE_BYTES: + _ZVAL_STRINGL(z_value, + (char *)entry_data_list->entry_data.bytes, + entry_data_list->entry_data.data_size); + break; + case MMDB_DATA_TYPE_DOUBLE: + ZVAL_DOUBLE(z_value, entry_data_list->entry_data.double_value); + break; + case MMDB_DATA_TYPE_FLOAT: + ZVAL_DOUBLE(z_value, entry_data_list->entry_data.float_value); + break; + case MMDB_DATA_TYPE_UINT16: + ZVAL_LONG(z_value, entry_data_list->entry_data.uint16); + break; + case MMDB_DATA_TYPE_UINT32: + handle_uint32(entry_data_list, z_value TSRMLS_CC); + break; + case MMDB_DATA_TYPE_BOOLEAN: + ZVAL_BOOL(z_value, entry_data_list->entry_data.boolean); + break; + case MMDB_DATA_TYPE_UINT64: + handle_uint64(entry_data_list, z_value TSRMLS_CC); + break; + case MMDB_DATA_TYPE_UINT128: + handle_uint128(entry_data_list, z_value TSRMLS_CC); + break; + case MMDB_DATA_TYPE_INT32: + ZVAL_LONG(z_value, entry_data_list->entry_data.int32); + break; + default: + THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS, + "Invalid data type arguments: %d", + entry_data_list->entry_data.type); + return NULL; + } + return entry_data_list; +} + +static const MMDB_entry_data_list_s * +handle_map(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC) { + array_init(z_value); + const uint32_t map_size = entry_data_list->entry_data.data_size; + + uint i; + for (i = 0; i < map_size && entry_data_list; i++) { + entry_data_list = entry_data_list->next; + + char *key = estrndup((char *)entry_data_list->entry_data.utf8_string, + entry_data_list->entry_data.data_size); + if (NULL == key) { + THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS, + "Invalid data type arguments"); + return NULL; + } + + entry_data_list = entry_data_list->next; +#ifdef ZEND_ENGINE_3 + zval _new_value; + zval *new_value = &_new_value; + ZVAL_NULL(new_value); +#else + zval *new_value; + ALLOC_INIT_ZVAL(new_value); +#endif + entry_data_list = + handle_entry_data_list(entry_data_list, new_value TSRMLS_CC); + add_assoc_zval(z_value, key, new_value); + efree(key); + } + return entry_data_list; +} + +static const MMDB_entry_data_list_s * +handle_array(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC) { + const uint32_t size = entry_data_list->entry_data.data_size; + + array_init(z_value); + + uint i; + for (i = 0; i < size && entry_data_list; i++) { + entry_data_list = entry_data_list->next; +#ifdef ZEND_ENGINE_3 + zval _new_value; + zval *new_value = &_new_value; + ZVAL_NULL(new_value); +#else + zval *new_value; + ALLOC_INIT_ZVAL(new_value); +#endif + entry_data_list = + handle_entry_data_list(entry_data_list, new_value TSRMLS_CC); + add_next_index_zval(z_value, new_value); + } + return entry_data_list; +} + +static void handle_uint128(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC) { + uint64_t high = 0; + uint64_t low = 0; +#if MMDB_UINT128_IS_BYTE_ARRAY + int i; + for (i = 0; i < 8; i++) { + high = (high << 8) | entry_data_list->entry_data.uint128[i]; + } + + for (i = 8; i < 16; i++) { + low = (low << 8) | entry_data_list->entry_data.uint128[i]; + } +#else + high = entry_data_list->entry_data.uint128 >> 64; + low = (uint64_t)entry_data_list->entry_data.uint128; +#endif + + char *num_str; + spprintf(&num_str, 0, "0x%016" PRIX64 "%016" PRIX64, high, low); + CHECK_ALLOCATED(num_str); + + _ZVAL_STRING(z_value, num_str); + efree(num_str); +} + +static void handle_uint32(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC) { + uint32_t val = entry_data_list->entry_data.uint32; + +#if LONG_MAX >= UINT32_MAX + ZVAL_LONG(z_value, val); + return; +#else + if (val <= LONG_MAX) { + ZVAL_LONG(z_value, val); + return; + } + + char *int_str; + spprintf(&int_str, 0, "%" PRIu32, val); + CHECK_ALLOCATED(int_str); + + _ZVAL_STRING(z_value, int_str); + efree(int_str); +#endif +} + +static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list, + zval *z_value TSRMLS_DC) { + uint64_t val = entry_data_list->entry_data.uint64; + +#if LONG_MAX >= UINT64_MAX + ZVAL_LONG(z_value, val); + return; +#else + if (val <= LONG_MAX) { + ZVAL_LONG(z_value, val); + return; + } + + char *int_str; + spprintf(&int_str, 0, "%" PRIu64, val); + CHECK_ALLOCATED(int_str); + + _ZVAL_STRING(z_value, int_str); + efree(int_str); +#endif +} + +static zend_class_entry *lookup_class(const char *name TSRMLS_DC) { +#ifdef ZEND_ENGINE_3 + zend_string *n = zend_string_init(name, strlen(name), 0); + zend_class_entry *ce = zend_lookup_class(n); + zend_string_release(n); + if (NULL == ce) { + zend_error(E_ERROR, "Class %s not found", name); + } + return ce; +#else + zend_class_entry **ce; + if (FAILURE == zend_lookup_class(name, strlen(name), &ce TSRMLS_CC)) { + zend_error(E_ERROR, "Class %s not found", name); + } + return *ce; +#endif +} + +static void maxminddb_free_storage(free_obj_t *object TSRMLS_DC) { + maxminddb_obj *obj = + php_maxminddb_fetch_object((zend_object *)object TSRMLS_CC); + if (obj->mmdb != NULL) { + MMDB_close(obj->mmdb); + efree(obj->mmdb); + } + + zend_object_std_dtor(&obj->std TSRMLS_CC); +#ifndef ZEND_ENGINE_3 + efree(object); +#endif +} + +#ifdef ZEND_ENGINE_3 +static zend_object *maxminddb_create_handler(zend_class_entry *type TSRMLS_DC) { + maxminddb_obj *obj = (maxminddb_obj *)ecalloc(1, sizeof(maxminddb_obj)); + zend_object_std_init(&obj->std, type TSRMLS_CC); + object_properties_init(&(obj->std), type); + + obj->std.handlers = &maxminddb_obj_handlers; + + return &obj->std; +} +#else +static zend_object_value +maxminddb_create_handler(zend_class_entry *type TSRMLS_DC) { + zend_object_value retval; + + maxminddb_obj *obj = (maxminddb_obj *)ecalloc(1, sizeof(maxminddb_obj)); + zend_object_std_init(&obj->std, type TSRMLS_CC); + object_properties_init(&(obj->std), type); + + retval.handle = zend_objects_store_put( + obj, NULL, maxminddb_free_storage, NULL TSRMLS_CC); + retval.handlers = &maxminddb_obj_handlers; + + return retval; +} +#endif + +// clang-format off +static zend_function_entry maxminddb_methods[] = { + PHP_ME(MaxMind_Db_Reader, __construct, arginfo_maxmindbreader_construct, + ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(MaxMind_Db_Reader, close, arginfo_maxmindbreader_void, ZEND_ACC_PUBLIC) + PHP_ME(MaxMind_Db_Reader, get, arginfo_maxmindbreader_get, ZEND_ACC_PUBLIC) + PHP_ME(MaxMind_Db_Reader, getWithPrefixLen, arginfo_maxmindbreader_get, ZEND_ACC_PUBLIC) + PHP_ME(MaxMind_Db_Reader, metadata, arginfo_maxmindbreader_void, ZEND_ACC_PUBLIC) + { NULL, NULL, NULL } +}; +// clang-format on + +PHP_MINIT_FUNCTION(maxminddb) { + zend_class_entry ce; + + INIT_CLASS_ENTRY(ce, PHP_MAXMINDDB_READER_NS, maxminddb_methods); + maxminddb_ce = zend_register_internal_class(&ce TSRMLS_CC); + maxminddb_ce->create_object = maxminddb_create_handler; + memcpy(&maxminddb_obj_handlers, + zend_get_std_object_handlers(), + sizeof(zend_object_handlers)); + maxminddb_obj_handlers.clone_obj = NULL; +#ifdef ZEND_ENGINE_3 + maxminddb_obj_handlers.offset = XtOffsetOf(maxminddb_obj, std); + maxminddb_obj_handlers.free_obj = maxminddb_free_storage; +#endif + zend_declare_class_constant_string(maxminddb_ce, + "MMDB_LIB_VERSION", + sizeof("MMDB_LIB_VERSION") - 1, + MMDB_lib_version() TSRMLS_CC); + + return SUCCESS; +} + +static PHP_MINFO_FUNCTION(maxminddb) { + php_info_print_table_start(); + + php_info_print_table_row(2, "MaxMind DB Reader", "enabled"); + php_info_print_table_row( + 2, "maxminddb extension version", PHP_MAXMINDDB_VERSION); + php_info_print_table_row( + 2, "libmaxminddb library version", MMDB_lib_version()); + + php_info_print_table_end(); +} + +zend_module_entry maxminddb_module_entry = {STANDARD_MODULE_HEADER, + PHP_MAXMINDDB_EXTNAME, + NULL, + PHP_MINIT(maxminddb), + NULL, + NULL, + NULL, + PHP_MINFO(maxminddb), + PHP_MAXMINDDB_VERSION, + STANDARD_MODULE_PROPERTIES}; + +#ifdef COMPILE_DL_MAXMINDDB +ZEND_GET_MODULE(maxminddb) +#endif diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/php_maxminddb.h b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/php_maxminddb.h new file mode 100644 index 0000000..75c647b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/php_maxminddb.h @@ -0,0 +1,24 @@ +/* MaxMind, Inc., licenses this file to you under the Apache License, Version + * 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#include + +#ifndef PHP_MAXMINDDB_H +#define PHP_MAXMINDDB_H 1 +#define PHP_MAXMINDDB_VERSION "1.6.0" +#define PHP_MAXMINDDB_EXTNAME "maxminddb" + +extern zend_module_entry maxminddb_module_entry; +#define phpext_maxminddb_ptr &maxminddb_module_entry + +#endif diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/tests/001-load.phpt b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/tests/001-load.phpt new file mode 100644 index 0000000..09810ee --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/tests/001-load.phpt @@ -0,0 +1,12 @@ +--TEST-- +Check for maxminddb presence +--SKIPIF-- + +--FILE-- + +--EXPECT-- +maxminddb extension is available diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/tests/002-final.phpt b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/tests/002-final.phpt new file mode 100644 index 0000000..d91b7d0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/tests/002-final.phpt @@ -0,0 +1,13 @@ +--TEST-- +Check that Reader class is not final +--SKIPIF-- + +--FILE-- +isFinal()); +?> +--EXPECT-- +bool(false) diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/tests/003-open-basedir.phpt b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/tests/003-open-basedir.phpt new file mode 100644 index 0000000..26e9781 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/ext/tests/003-open-basedir.phpt @@ -0,0 +1,12 @@ +--TEST-- +openbase_dir is followed +--INI-- +open_basedir=/--dne-- +--FILE-- + +--EXPECTREGEX-- +.*open_basedir restriction in effect.* diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php new file mode 100644 index 0000000..3d5a829 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php @@ -0,0 +1,327 @@ +fileHandle = @fopen($database, 'rb'); + if ($this->fileHandle === false) { + throw new InvalidArgumentException( + "Error opening \"$database\"." + ); + } + $this->fileSize = @filesize($database); + if ($this->fileSize === false) { + throw new UnexpectedValueException( + "Error determining the size of \"$database\"." + ); + } + + $start = $this->findMetadataStart($database); + $metadataDecoder = new Decoder($this->fileHandle, $start); + list($metadataArray) = $metadataDecoder->decode($start); + $this->metadata = new Metadata($metadataArray); + $this->decoder = new Decoder( + $this->fileHandle, + $this->metadata->searchTreeSize + self::$DATA_SECTION_SEPARATOR_SIZE + ); + $this->ipV4Start = $this->ipV4StartNode(); + } + + /** + * Retrieves the record for the IP address. + * + * @param string $ipAddress + * the IP address to look up + * + * @throws BadMethodCallException if this method is called on a closed database + * @throws InvalidArgumentException if something other than a single IP address is passed to the method + * @throws InvalidDatabaseException + * if the database is invalid or there is an error reading + * from it + * + * @return mixed the record for the IP address + */ + public function get($ipAddress) + { + if (\func_num_args() !== 1) { + throw new InvalidArgumentException( + 'Method takes exactly one argument.' + ); + } + list($record) = $this->getWithPrefixLen($ipAddress); + + return $record; + } + + /** + * Retrieves the record for the IP address and its associated network prefix length. + * + * @param string $ipAddress + * the IP address to look up + * + * @throws BadMethodCallException if this method is called on a closed database + * @throws InvalidArgumentException if something other than a single IP address is passed to the method + * @throws InvalidDatabaseException + * if the database is invalid or there is an error reading + * from it + * + * @return array an array where the first element is the record and the + * second the network prefix length for the record + */ + public function getWithPrefixLen($ipAddress) + { + if (\func_num_args() !== 1) { + throw new InvalidArgumentException( + 'Method takes exactly one argument.' + ); + } + + if (!\is_resource($this->fileHandle)) { + throw new BadMethodCallException( + 'Attempt to read from a closed MaxMind DB.' + ); + } + + if (!filter_var($ipAddress, FILTER_VALIDATE_IP)) { + throw new InvalidArgumentException( + "The value \"$ipAddress\" is not a valid IP address." + ); + } + + list($pointer, $prefixLen) = $this->findAddressInTree($ipAddress); + if ($pointer === 0) { + return [null, $prefixLen]; + } + + return [$this->resolveDataPointer($pointer), $prefixLen]; + } + + private function findAddressInTree($ipAddress) + { + $rawAddress = unpack('C*', inet_pton($ipAddress)); + + $bitCount = \count($rawAddress) * 8; + + // The first node of the tree is always node 0, at the beginning of the + // value + $node = 0; + + $metadata = $this->metadata; + + // Check if we are looking up an IPv4 address in an IPv6 tree. If this + // is the case, we can skip over the first 96 nodes. + if ($metadata->ipVersion === 6) { + if ($bitCount === 32) { + $node = $this->ipV4Start; + } + } elseif ($metadata->ipVersion === 4 && $bitCount === 128) { + throw new InvalidArgumentException( + "Error looking up $ipAddress. You attempted to look up an" + . ' IPv6 address in an IPv4-only database.' + ); + } + + $nodeCount = $metadata->nodeCount; + + for ($i = 0; $i < $bitCount && $node < $nodeCount; ++$i) { + $tempBit = 0xFF & $rawAddress[($i >> 3) + 1]; + $bit = 1 & ($tempBit >> 7 - ($i % 8)); + + $node = $this->readNode($node, $bit); + } + if ($node === $nodeCount) { + // Record is empty + return [0, $i]; + } elseif ($node > $nodeCount) { + // Record is a data pointer + return [$node, $i]; + } + throw new InvalidDatabaseException('Something bad happened'); + } + + private function ipV4StartNode() + { + // If we have an IPv4 database, the start node is the first node + if ($this->metadata->ipVersion === 4) { + return 0; + } + + $node = 0; + + for ($i = 0; $i < 96 && $node < $this->metadata->nodeCount; ++$i) { + $node = $this->readNode($node, 0); + } + + return $node; + } + + private function readNode($nodeNumber, $index) + { + $baseOffset = $nodeNumber * $this->metadata->nodeByteSize; + + switch ($this->metadata->recordSize) { + case 24: + $bytes = Util::read($this->fileHandle, $baseOffset + $index * 3, 3); + list(, $node) = unpack('N', "\x00" . $bytes); + + return $node; + case 28: + $bytes = Util::read($this->fileHandle, $baseOffset + 3 * $index, 4); + if ($index === 0) { + $middle = (0xF0 & \ord($bytes[3])) >> 4; + } else { + $middle = 0x0F & \ord($bytes[0]); + } + list(, $node) = unpack('N', \chr($middle) . substr($bytes, $index, 3)); + + return $node; + case 32: + $bytes = Util::read($this->fileHandle, $baseOffset + $index * 4, 4); + list(, $node) = unpack('N', $bytes); + + return $node; + default: + throw new InvalidDatabaseException( + 'Unknown record size: ' + . $this->metadata->recordSize + ); + } + } + + private function resolveDataPointer($pointer) + { + $resolved = $pointer - $this->metadata->nodeCount + + $this->metadata->searchTreeSize; + if ($resolved >= $this->fileSize) { + throw new InvalidDatabaseException( + "The MaxMind DB file's search tree is corrupt" + ); + } + + list($data) = $this->decoder->decode($resolved); + + return $data; + } + + /* + * This is an extremely naive but reasonably readable implementation. There + * are much faster algorithms (e.g., Boyer-Moore) for this if speed is ever + * an issue, but I suspect it won't be. + */ + private function findMetadataStart($filename) + { + $handle = $this->fileHandle; + $fstat = fstat($handle); + $fileSize = $fstat['size']; + $marker = self::$METADATA_START_MARKER; + $markerLength = self::$METADATA_START_MARKER_LENGTH; + + $minStart = $fileSize - min(self::$METADATA_MAX_SIZE, $fileSize); + + for ($offset = $fileSize - $markerLength; $offset >= $minStart; --$offset) { + if (fseek($handle, $offset) !== 0) { + break; + } + + $value = fread($handle, $markerLength); + if ($value === $marker) { + return $offset + $markerLength; + } + } + throw new InvalidDatabaseException( + "Error opening database file ($filename). " . + 'Is this a valid MaxMind DB file?' + ); + } + + /** + * @throws InvalidArgumentException if arguments are passed to the method + * @throws BadMethodCallException if the database has been closed + * + * @return Metadata object for the database + */ + public function metadata() + { + if (\func_num_args()) { + throw new InvalidArgumentException( + 'Method takes no arguments.' + ); + } + + // Not technically required, but this makes it consistent with + // C extension and it allows us to change our implementation later. + if (!\is_resource($this->fileHandle)) { + throw new BadMethodCallException( + 'Attempt to read from a closed MaxMind DB.' + ); + } + + return $this->metadata; + } + + /** + * Closes the MaxMind DB and returns resources to the system. + * + * @throws Exception + * if an I/O error occurs + */ + public function close() + { + if (!\is_resource($this->fileHandle)) { + throw new BadMethodCallException( + 'Attempt to close a closed MaxMind DB.' + ); + } + fclose($this->fileHandle); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php new file mode 100644 index 0000000..132dae8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php @@ -0,0 +1,356 @@ +fileStream = $fileStream; + $this->pointerBase = $pointerBase; + + $this->pointerBaseByteSize = $pointerBase > 0 ? log($pointerBase, 2) / 8 : 0; + $this->pointerTestHack = $pointerTestHack; + + $this->switchByteOrder = $this->isPlatformLittleEndian(); + } + + public function decode($offset) + { + $ctrlByte = \ord(Util::read($this->fileStream, $offset, 1)); + ++$offset; + + $type = $ctrlByte >> 5; + + // Pointers are a special case, we don't read the next $size bytes, we + // use the size to determine the length of the pointer and then follow + // it. + if ($type === self::_POINTER) { + list($pointer, $offset) = $this->decodePointer($ctrlByte, $offset); + + // for unit testing + if ($this->pointerTestHack) { + return [$pointer]; + } + + list($result) = $this->decode($pointer); + + return [$result, $offset]; + } + + if ($type === self::_EXTENDED) { + $nextByte = \ord(Util::read($this->fileStream, $offset, 1)); + + $type = $nextByte + 7; + + if ($type < 8) { + throw new InvalidDatabaseException( + 'Something went horribly wrong in the decoder. An extended type ' + . 'resolved to a type number < 8 (' + . $type + . ')' + ); + } + + ++$offset; + } + + list($size, $offset) = $this->sizeFromCtrlByte($ctrlByte, $offset); + + return $this->decodeByType($type, $offset, $size); + } + + private function decodeByType($type, $offset, $size) + { + switch ($type) { + case self::_MAP: + return $this->decodeMap($size, $offset); + case self::_ARRAY: + return $this->decodeArray($size, $offset); + case self::_BOOLEAN: + return [$this->decodeBoolean($size), $offset]; + } + + $newOffset = $offset + $size; + $bytes = Util::read($this->fileStream, $offset, $size); + switch ($type) { + case self::_BYTES: + case self::_UTF8_STRING: + return [$bytes, $newOffset]; + case self::_DOUBLE: + $this->verifySize(8, $size); + + return [$this->decodeDouble($bytes), $newOffset]; + case self::_FLOAT: + $this->verifySize(4, $size); + + return [$this->decodeFloat($bytes), $newOffset]; + case self::_INT32: + return [$this->decodeInt32($bytes, $size), $newOffset]; + case self::_UINT16: + case self::_UINT32: + case self::_UINT64: + case self::_UINT128: + return [$this->decodeUint($bytes, $size), $newOffset]; + default: + throw new InvalidDatabaseException( + 'Unknown or unexpected type: ' . $type + ); + } + } + + private function verifySize($expected, $actual) + { + if ($expected !== $actual) { + throw new InvalidDatabaseException( + "The MaxMind DB file's data section contains bad data (unknown data type or corrupt data)" + ); + } + } + + private function decodeArray($size, $offset) + { + $array = []; + + for ($i = 0; $i < $size; ++$i) { + list($value, $offset) = $this->decode($offset); + array_push($array, $value); + } + + return [$array, $offset]; + } + + private function decodeBoolean($size) + { + return $size === 0 ? false : true; + } + + private function decodeDouble($bits) + { + // This assumes IEEE 754 doubles, but most (all?) modern platforms + // use them. + // + // We are not using the "E" format as that was only added in + // 7.0.15 and 7.1.1. As such, we must switch byte order on + // little endian machines. + list(, $double) = unpack('d', $this->maybeSwitchByteOrder($bits)); + + return $double; + } + + private function decodeFloat($bits) + { + // This assumes IEEE 754 floats, but most (all?) modern platforms + // use them. + // + // We are not using the "G" format as that was only added in + // 7.0.15 and 7.1.1. As such, we must switch byte order on + // little endian machines. + list(, $float) = unpack('f', $this->maybeSwitchByteOrder($bits)); + + return $float; + } + + private function decodeInt32($bytes, $size) + { + switch ($size) { + case 0: + return 0; + case 1: + case 2: + case 3: + $bytes = str_pad($bytes, 4, "\x00", STR_PAD_LEFT); + break; + case 4: + break; + default: + throw new InvalidDatabaseException( + "The MaxMind DB file's data section contains bad data (unknown data type or corrupt data)" + ); + } + + list(, $int) = unpack('l', $this->maybeSwitchByteOrder($bytes)); + + return $int; + } + + private function decodeMap($size, $offset) + { + $map = []; + + for ($i = 0; $i < $size; ++$i) { + list($key, $offset) = $this->decode($offset); + list($value, $offset) = $this->decode($offset); + $map[$key] = $value; + } + + return [$map, $offset]; + } + + private function decodePointer($ctrlByte, $offset) + { + $pointerSize = (($ctrlByte >> 3) & 0x3) + 1; + + $buffer = Util::read($this->fileStream, $offset, $pointerSize); + $offset = $offset + $pointerSize; + + switch ($pointerSize) { + case 1: + $packed = \chr($ctrlByte & 0x7) . $buffer; + list(, $pointer) = unpack('n', $packed); + $pointer += $this->pointerBase; + break; + case 2: + $packed = "\x00" . \chr($ctrlByte & 0x7) . $buffer; + list(, $pointer) = unpack('N', $packed); + $pointer += $this->pointerBase + 2048; + break; + case 3: + $packed = \chr($ctrlByte & 0x7) . $buffer; + + // It is safe to use 'N' here, even on 32 bit machines as the + // first bit is 0. + list(, $pointer) = unpack('N', $packed); + $pointer += $this->pointerBase + 526336; + break; + case 4: + // We cannot use unpack here as we might overflow on 32 bit + // machines + $pointerOffset = $this->decodeUint($buffer, $pointerSize); + + $byteLength = $pointerSize + $this->pointerBaseByteSize; + + if ($byteLength <= _MM_MAX_INT_BYTES) { + $pointer = $pointerOffset + $this->pointerBase; + } elseif (\extension_loaded('gmp')) { + $pointer = gmp_strval(gmp_add($pointerOffset, $this->pointerBase)); + } elseif (\extension_loaded('bcmath')) { + $pointer = bcadd($pointerOffset, $this->pointerBase); + } else { + throw new RuntimeException( + 'The gmp or bcmath extension must be installed to read this database.' + ); + } + } + + return [$pointer, $offset]; + } + + private function decodeUint($bytes, $byteLength) + { + if ($byteLength === 0) { + return 0; + } + + $integer = 0; + + for ($i = 0; $i < $byteLength; ++$i) { + $part = \ord($bytes[$i]); + + // We only use gmp or bcmath if the final value is too big + if ($byteLength <= _MM_MAX_INT_BYTES) { + $integer = ($integer << 8) + $part; + } elseif (\extension_loaded('gmp')) { + $integer = gmp_strval(gmp_add(gmp_mul($integer, 256), $part)); + } elseif (\extension_loaded('bcmath')) { + $integer = bcadd(bcmul($integer, 256), $part); + } else { + throw new RuntimeException( + 'The gmp or bcmath extension must be installed to read this database.' + ); + } + } + + return $integer; + } + + private function sizeFromCtrlByte($ctrlByte, $offset) + { + $size = $ctrlByte & 0x1f; + + if ($size < 29) { + return [$size, $offset]; + } + + $bytesToRead = $size - 28; + $bytes = Util::read($this->fileStream, $offset, $bytesToRead); + + if ($size === 29) { + $size = 29 + \ord($bytes); + } elseif ($size === 30) { + list(, $adjust) = unpack('n', $bytes); + $size = 285 + $adjust; + } elseif ($size > 30) { + list(, $adjust) = unpack('N', "\x00" . $bytes); + $size = $adjust + 65821; + } + + return [$size, $offset + $bytesToRead]; + } + + private function maybeSwitchByteOrder($bytes) + { + return $this->switchByteOrder ? strrev($bytes) : $bytes; + } + + private function isPlatformLittleEndian() + { + $testint = 0x00FF; + $packed = pack('S', $testint); + + return $testint === current(unpack('v', $packed)); + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php new file mode 100644 index 0000000..478a22c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php @@ -0,0 +1,12 @@ +binaryFormatMajorVersion = + $metadata['binary_format_major_version']; + $this->binaryFormatMinorVersion = + $metadata['binary_format_minor_version']; + $this->buildEpoch = $metadata['build_epoch']; + $this->databaseType = $metadata['database_type']; + $this->languages = $metadata['languages']; + $this->description = $metadata['description']; + $this->ipVersion = $metadata['ip_version']; + $this->nodeCount = $metadata['node_count']; + $this->recordSize = $metadata['record_size']; + $this->nodeByteSize = $this->recordSize / 4; + $this->searchTreeSize = $this->nodeCount * $this->nodeByteSize; + } + + public function __get($var) + { + return $this->$var; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php new file mode 100644 index 0000000..87ebbf1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/plugins/woocommerce/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.php @@ -0,0 +1,26 @@ + + * @author Roman Ožana + * @author Sander Kruger + * @author Zoli Szabó + */ +class Emogrifier +{ + /** + * @var int + */ + const CACHE_KEY_CSS = 0; + + /** + * @var int + */ + const CACHE_KEY_SELECTOR = 1; + + /** + * @var int + */ + const CACHE_KEY_XPATH = 2; + + /** + * @var int + */ + const CACHE_KEY_CSS_DECLARATIONS_BLOCK = 3; + + /** + * @var int + */ + const CACHE_KEY_COMBINED_STYLES = 4; + + /** + * for calculating nth-of-type and nth-child selectors + * + * @var int + */ + const INDEX = 0; + + /** + * for calculating nth-of-type and nth-child selectors + * + * @var int + */ + const MULTIPLIER = 1; + + /** + * @var string + */ + const ID_ATTRIBUTE_MATCHER = '/(\\w+)?\\#([\\w\\-]+)/'; + + /** + * @var string + */ + const CLASS_ATTRIBUTE_MATCHER = '/(\\w+|[\\*\\]])?((\\.[\\w\\-]+)+)/'; + + /** + * Regular expression component matching a static pseudo class in a selector, without the preceding ":", + * for which the applicable elements can be determined (by converting the selector to an XPath expression). + * (Contains alternation without a group and is intended to be placed within a capturing, non-capturing or lookahead + * group, as appropriate for the usage context.) + * + * @var string + */ + const PSEUDO_CLASS_MATCHER = '(?:first|last|nth)-child|nth-of-type|not\\([[:ascii:]]*\\)'; + + /** + * @var string + */ + const CONTENT_TYPE_META_TAG = ''; + + /** + * @var string + */ + const DEFAULT_DOCUMENT_TYPE = ''; + + /** + * @var string Regular expression part to match tag names that PHP's DOMDocument implementation is not aware are + * self-closing. These are mostly HTML5 elements, but for completeness (obsolete) and + * (deprecated) are also included. + * + * @see https://bugs.php.net/bug.php?id=73175 + */ + const PHP_UNRECOGNIZED_VOID_TAGNAME_MATCHER = '(?:command|embed|keygen|source|track|wbr)'; + + /** + * @var \DOMDocument + */ + protected $domDocument = null; + + /** + * @var \DOMXPath + */ + protected $xPath = null; + + /** + * @var string + */ + private $css = ''; + + /** + * @var bool[] + */ + private $excludedSelectors = []; + + /** + * @var string[] + */ + private $unprocessableHtmlTags = ['wbr']; + + /** + * @var bool[] + */ + private $allowedMediaTypes = ['all' => true, 'screen' => true, 'print' => true]; + + /** + * @var mixed[] + */ + private $caches = [ + self::CACHE_KEY_CSS => [], + self::CACHE_KEY_SELECTOR => [], + self::CACHE_KEY_XPATH => [], + self::CACHE_KEY_CSS_DECLARATIONS_BLOCK => [], + self::CACHE_KEY_COMBINED_STYLES => [], + ]; + + /** + * the visited nodes with the XPath paths as array keys + * + * @var \DOMElement[] + */ + private $visitedNodes = []; + + /** + * the styles to apply to the nodes with the XPath paths as array keys for the outer array + * and the attribute names/values as key/value pairs for the inner array + * + * @var string[][] + */ + private $styleAttributesForNodes = []; + + /** + * Determines whether the "style" attributes of tags in the the HTML passed to this class should be preserved. + * If set to false, the value of the style attributes will be discarded. + * + * @var bool + */ + private $isInlineStyleAttributesParsingEnabled = true; + + /** + * Determines whether the \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/admin/welcome-screen/automattic.png b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/admin/welcome-screen/automattic.png new file mode 100644 index 0000000..28353e5 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/admin/welcome-screen/automattic.png differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/admin/welcome-screen/child-themes.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/admin/welcome-screen/child-themes.jpg new file mode 100644 index 0000000..6799104 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/admin/welcome-screen/child-themes.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/admin/welcome-screen/storefront-bundle-hero.png b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/admin/welcome-screen/storefront-bundle-hero.png new file mode 100644 index 0000000..a0a6c1f Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/admin/welcome-screen/storefront-bundle-hero.png differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/amex.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/amex.svg new file mode 100644 index 0000000..9fe3048 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/amex.svg @@ -0,0 +1,14 @@ + + + + Slice 1 + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/diners.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/diners.svg new file mode 100644 index 0000000..b0c78cd --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/diners.svg @@ -0,0 +1,15 @@ + + + + diners + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/discover.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/discover.svg new file mode 100644 index 0000000..b2e4636 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/discover.svg @@ -0,0 +1,14 @@ + + + + discover + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/jcb.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/jcb.svg new file mode 100644 index 0000000..b30f4c3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/jcb.svg @@ -0,0 +1,29 @@ + + + + Slice 1 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/laser.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/laser.svg new file mode 100644 index 0000000..9f4aa2c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/laser.svg @@ -0,0 +1,71 @@ + + + + +Slice 1 +Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/maestro.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/maestro.svg new file mode 100644 index 0000000..8f0494a --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/maestro.svg @@ -0,0 +1,29 @@ + + + + Slice 1 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/mastercard.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/mastercard.svg new file mode 100644 index 0000000..8ceb0d2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/mastercard.svg @@ -0,0 +1,31 @@ + + + + Slice 1 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/paypal.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/paypal.svg new file mode 100644 index 0000000..1ab8113 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/paypal.svg @@ -0,0 +1,52 @@ + + + + +amex-outline +Created with Sketch. + + + + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/unknown.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/unknown.svg new file mode 100644 index 0000000..b825070 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/unknown.svg @@ -0,0 +1,13 @@ + + + + +Slice 1 +Created with Sketch. + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/visa.svg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/visa.svg new file mode 100644 index 0000000..115f2bf --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/credit-cards/visa.svg @@ -0,0 +1,17 @@ + + + + Slice 1 + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/controls/2cl.png b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/controls/2cl.png new file mode 100644 index 0000000..0580991 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/controls/2cl.png differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/controls/2cr.png b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/controls/2cr.png new file mode 100644 index 0000000..d387435 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/controls/2cr.png differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/categories/accessories.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/categories/accessories.jpg new file mode 100644 index 0000000..f809c89 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/categories/accessories.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/categories/hoodies.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/categories/hoodies.jpg new file mode 100644 index 0000000..b5087d8 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/categories/hoodies.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/categories/tshirts.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/categories/tshirts.jpg new file mode 100644 index 0000000..d60dc4a Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/categories/tshirts.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/hero.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/hero.jpg new file mode 100644 index 0000000..ffbeba6 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/hero.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/beanie.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/beanie.jpg new file mode 100644 index 0000000..d81b01f Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/beanie.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/belt.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/belt.jpg new file mode 100644 index 0000000..1d89f43 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/belt.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/cap.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/cap.jpg new file mode 100644 index 0000000..fd29cdf Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/cap.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie-with-logo.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie-with-logo.jpg new file mode 100644 index 0000000..9609e3b Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie-with-logo.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie-with-pocket.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie-with-pocket.jpg new file mode 100644 index 0000000..72c3272 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie-with-pocket.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie-with-zipper.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie-with-zipper.jpg new file mode 100644 index 0000000..f9b27c9 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie-with-zipper.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie.jpg new file mode 100644 index 0000000..c772445 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/hoodie.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/long-sleeve-tee.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/long-sleeve-tee.jpg new file mode 100644 index 0000000..64c7d9d Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/long-sleeve-tee.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/polo.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/polo.jpg new file mode 100644 index 0000000..6766cc2 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/polo.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/sunglasses.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/sunglasses.jpg new file mode 100644 index 0000000..f5421e5 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/sunglasses.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/tshirt.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/tshirt.jpg new file mode 100644 index 0000000..d775d53 Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/tshirt.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/vneck-tee.jpg b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/vneck-tee.jpg new file mode 100644 index 0000000..4f581cd Binary files /dev/null and b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/images/customizer/starter-content/products/vneck-tee.jpg differ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/admin.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/admin.js new file mode 100644 index 0000000..34d8fb8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/admin.js @@ -0,0 +1,20 @@ +/* global ajaxurl, storefrontNUX */ +( function( wp, $ ) { + 'use strict'; + + if ( ! wp ) { + return; + } + + $( function() { + // Dismiss notice + $( document ).on( 'click', '.sf-notice-nux .notice-dismiss', function() { + $.ajax({ + type: 'POST', + url: ajaxurl, + data: { nonce: storefrontNUX.nonce, action: 'storefront_dismiss_notice' }, + dataType: 'json' + }); + }); + }); +})( window.wp, jQuery ); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/admin.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/admin.min.js new file mode 100644 index 0000000..5b856eb --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/admin.min.js @@ -0,0 +1 @@ +!function(n,o){"use strict";n&&o(function(){o(document).on("click",".sf-notice-nux .notice-dismiss",function(){o.ajax({type:"POST",url:ajaxurl,data:{nonce:storefrontNUX.nonce,action:"storefront_dismiss_notice"},dataType:"json"})})})}(window.wp,jQuery); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/customizer.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/customizer.js new file mode 100644 index 0000000..f8d137c --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/customizer.js @@ -0,0 +1,243 @@ +/* global _wpCustomizeSFGuidedTourSteps */ +( function( wp, $ ) { + 'use strict'; + + if ( ! wp || ! wp.customize ) { return; } + + // Set up our namespace. + var api = wp.customize; + + api.SFGuidedTourSteps = []; + + if ( 'undefined' !== typeof _wpCustomizeSFGuidedTourSteps ) { + $.extend( api.SFGuidedTourSteps, _wpCustomizeSFGuidedTourSteps ); + } + + /** + * wp.customize.SFGuidedTour + * + */ + api.SFGuidedTour = { + $container: null, + currentStep: -1, + + init: function() { + this._setupUI(); + }, + + _setupUI: function() { + var self = this, + $wpCustomize = $( 'body.wp-customizer .wp-full-overlay' ); + + this.$container = $( '
    ' ).addClass( 'sf-guided-tour' ); + + // Add guided tour div + $wpCustomize.prepend( this.$container ); + + // Add listeners + this._addListeners(); + + // Initial position + this.$container.css( ! $( 'body' ).hasClass( 'rtl' ) ? 'left' : 'right', ( $( '#customize-controls' ).width() + 10 ) + 'px' ).on( 'transitionend', function() { + self.$container.addClass( 'sf-loaded' ); + }); + + // Show first step + this._showNextStep(); + + $( document ).on( 'click', '.sf-guided-tour-step .sf-nux-button', function() { + self._showNextStep(); + return false; + }); + + $( document ).on( 'click', '.sf-guided-tour-step .sf-guided-tour-skip', function() { + if ( 0 === self.currentStep ) { + self._hideTour( true ); + } else { + self._showNextStep(); + } + + return false; + }); + }, + + _addListeners: function() { + var self = this; + + api.state( 'expandedSection' ).bind( function() { + self._adjustPosition(); + }); + + api.state( 'expandedPanel' ).bind( function() { + self._adjustPosition(); + }); + }, + + _adjustPosition: function() { + var step = this._getCurrentStep(), + expandedSection = api.state( 'expandedSection' ).get(), + expandedPanel = api.state( 'expandedPanel' ).get(); + + if ( ! step ) { + return; + } + + this.$container.removeClass( 'sf-inside-section' ); + + if ( expandedSection && step.section === expandedSection.id ) { + this._moveContainer( $( expandedSection.container[1] ).find( '.customize-section-title' ) ); + this.$container.addClass( 'sf-inside-section' ); + } else if ( false === expandedSection && false === expandedPanel ) { + if ( this._isTourHidden() ) { + this._revealTour(); + } else { + var selector = this._getSelector( step.section ); + this._moveContainer( selector ); + } + } else { + this._hideTour(); + } + }, + + _hideTour: function( remove ) { + var self = this; + + // Already hidden? + if ( this._isTourHidden() ) { + return; + } + + this.$container.css({ + transform: '', + top: this.$container.offset().top + }); + + $( 'body' ).addClass( 'sf-exiting' ).on( 'animationend.storefront webkitAnimationEnd.storefront', function() { + $( this ).removeClass( 'sf-exiting' ).off( 'animationend.storefront webkitAnimationEnd.storefront' ).addClass( 'sf-hidden' ); + self.$container.hide(); + + if ( ! _.isUndefined( remove ) && true === remove ) { + self._removeTour(); + } + }); + }, + + _revealTour: function() { + var self = this; + + $( 'body' ).removeClass( 'sf-hidden' ); + + self.$container.show(); + + $( 'body' ).addClass( 'sf-entering' ).on( 'animationend.storefront webkitAnimationEnd.storefront', function() { + $( this ).removeClass( 'sf-entering' ).off( 'animationend.storefront webkitAnimationEnd.storefront' ); + + self.$container.css({ + top: 'auto', + transform: 'translateY(' + parseInt( self.$container.offset().top, 10 ) + 'px)' + }); + }); + }, + + _removeTour: function() { + this.$container.remove(); + }, + + _closeAllSections: function() { + api.section.each( function ( section ) { + section.collapse( { duration: 0 } ); + }); + + api.panel.each( function ( panel ) { + panel.collapse( { duration: 0 } ); + }); + }, + + _showNextStep: function() { + var step, template; + + if ( this._isLastStep() ) { + this._hideTour( true ); + return; + } + + this._closeAllSections(); + + // Get next step + step = this._getNextStep(); + + // Convert line breaks to paragraphs + step.message = this._lineBreaksToParagraphs( step.message ); + + // Load template + template = wp.template( 'sf-guided-tour-step' ); + + this.$container.removeClass( 'sf-first-step' ); + + if ( 0 === this.currentStep ) { + step.first_step = true; + this.$container.addClass( 'sf-first-step' ); + } + + if ( this._isLastStep() ) { + step.last_step = true; + this.$container.addClass( 'sf-last-step' ); + } + + this._moveContainer( this._getSelector( step.section ) ); + + this.$container.html( template( step ) ); + }, + + _moveContainer: function( $selector ) { + var self = this, position; + + if ( ! $selector ) { + return; + } + + position = parseInt( $selector.offset().top, 10 ) + ( $selector.height() / 2 ) - 44; + + this.$container.addClass( 'sf-moving' ).css({ 'transform': 'translateY(' + parseInt( position, 10 ) + 'px)' }).on( 'transitionend.storefront', function() { + self.$container.removeClass( 'sf-moving' ); + self.$container.off( 'transitionend.storefront' ); + } ); + }, + + _getSelector: function( pointTo ) { + var sectionOrPanel = api.section( pointTo ) ? api.section( pointTo ) : api.panel( pointTo ); + + // Check whether this is a section, panel, or a regular selector + if ( ! _.isUndefined( sectionOrPanel ) ) { + return $( sectionOrPanel.container[0] ); + } + + return $( pointTo ); + }, + + _getCurrentStep: function() { + return api.SFGuidedTourSteps[ this.currentStep ]; + }, + + _getNextStep: function() { + this.currentStep = this.currentStep + 1; + return api.SFGuidedTourSteps[ this.currentStep ]; + }, + + _isTourHidden: function() { + return ( ( $( 'body' ).hasClass( 'sf-hidden' ) ) ? true : false ); + }, + + _isLastStep: function() { + return ( ( ( this.currentStep + 1 ) < api.SFGuidedTourSteps.length ) ? false : true ); + }, + + _lineBreaksToParagraphs: function( message ) { + return '

    ' + message.replace( '\n\n', '

    ' ) + '

    '; + } + }; + + $( document ).ready( function() { + api.SFGuidedTour.init(); + }); +} )( window.wp, jQuery ); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/customizer.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/customizer.min.js new file mode 100644 index 0000000..6ab9ea0 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/customizer.min.js @@ -0,0 +1 @@ +!function(n,i){"use strict";var s;n&&n.customize&&((s=n.customize).SFGuidedTourSteps=[],"undefined"!=typeof _wpCustomizeSFGuidedTourSteps&&i.extend(s.SFGuidedTourSteps,_wpCustomizeSFGuidedTourSteps),s.SFGuidedTour={$container:null,currentStep:-1,init:function(){this._setupUI()},_setupUI:function(){var t=this,e=i("body.wp-customizer .wp-full-overlay");this.$container=i("
    ").addClass("sf-guided-tour"),e.prepend(this.$container),this._addListeners(),this.$container.css(i("body").hasClass("rtl")?"right":"left",i("#customize-controls").width()+10+"px").on("transitionend",function(){t.$container.addClass("sf-loaded")}),this._showNextStep(),i(document).on("click",".sf-guided-tour-step .sf-nux-button",function(){return t._showNextStep(),!1}),i(document).on("click",".sf-guided-tour-step .sf-guided-tour-skip",function(){return 0===t.currentStep?t._hideTour(!0):t._showNextStep(),!1})},_addListeners:function(){var t=this;s.state("expandedSection").bind(function(){t._adjustPosition()}),s.state("expandedPanel").bind(function(){t._adjustPosition()})},_adjustPosition:function(){var t=this._getCurrentStep(),e=s.state("expandedSection").get(),n=s.state("expandedPanel").get();t&&(this.$container.removeClass("sf-inside-section"),e&&t.section===e.id?(this._moveContainer(i(e.container[1]).find(".customize-section-title")),this.$container.addClass("sf-inside-section")):!1===e&&!1===n?this._isTourHidden()?this._revealTour():(t=this._getSelector(t.section),this._moveContainer(t)):this._hideTour())},_hideTour:function(t){var e=this;this._isTourHidden()||(this.$container.css({transform:"",top:this.$container.offset().top}),i("body").addClass("sf-exiting").on("animationend.storefront webkitAnimationEnd.storefront",function(){i(this).removeClass("sf-exiting").off("animationend.storefront webkitAnimationEnd.storefront").addClass("sf-hidden"),e.$container.hide(),_.isUndefined(t)||!0!==t||e._removeTour()}))},_revealTour:function(){var t=this;i("body").removeClass("sf-hidden"),t.$container.show(),i("body").addClass("sf-entering").on("animationend.storefront webkitAnimationEnd.storefront",function(){i(this).removeClass("sf-entering").off("animationend.storefront webkitAnimationEnd.storefront"),t.$container.css({top:"auto",transform:"translateY("+parseInt(t.$container.offset().top,10)+"px)"})})},_removeTour:function(){this.$container.remove()},_closeAllSections:function(){s.section.each(function(t){t.collapse({duration:0})}),s.panel.each(function(t){t.collapse({duration:0})})},_showNextStep:function(){var t,e;this._isLastStep()?this._hideTour(!0):(this._closeAllSections(),(t=this._getNextStep()).message=this._lineBreaksToParagraphs(t.message),e=n.template("sf-guided-tour-step"),this.$container.removeClass("sf-first-step"),0===this.currentStep&&(t.first_step=!0,this.$container.addClass("sf-first-step")),this._isLastStep()&&(t.last_step=!0,this.$container.addClass("sf-last-step")),this._moveContainer(this._getSelector(t.section)),this.$container.html(e(t)))},_moveContainer:function(t){var e=this;t&&(t=parseInt(t.offset().top,10)+t.height()/2-44,this.$container.addClass("sf-moving").css({transform:"translateY("+parseInt(t,10)+"px)"}).on("transitionend.storefront",function(){e.$container.removeClass("sf-moving"),e.$container.off("transitionend.storefront")}))},_getSelector:function(t){var e=s.section(t)?s.section(t):s.panel(t);return _.isUndefined(e)?i(t):i(e.container[0])},_getCurrentStep:function(){return s.SFGuidedTourSteps[this.currentStep]},_getNextStep:function(){return this.currentStep=this.currentStep+1,s.SFGuidedTourSteps[this.currentStep]},_isTourHidden:function(){return!!i("body").hasClass("sf-hidden")},_isLastStep:function(){return!(this.currentStep+1"+t.replace("\n\n","

    ")+"

    "}},i(document).ready(function(){s.SFGuidedTour.init()}))}(window.wp,jQuery); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/plugin-install.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/plugin-install.js new file mode 100644 index 0000000..3d6c940 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/plugin-install.js @@ -0,0 +1,41 @@ +( function( wp, $ ) { + 'use strict'; + + if ( ! wp ) { + return; + } + + $( function() { + $( document ).on( 'click', '.sf-install-now', function( event ) { + var $button = $( event.target ); + + if ( $button.hasClass( 'activate-now' ) ) { + return true; + } + + event.preventDefault(); + + if ( $button.hasClass( 'updating-message' ) || $button.hasClass( 'button-disabled' ) ) { + return; + } + + if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.ajaxLocked ) { + wp.updates.requestFilesystemCredentials( event ); + + $( document ).on( 'credential-modal-cancel', function() { + var $message = $( '.sf-install-now.updating-message' ); + + $message + .removeClass( 'updating-message' ) + .text( wp.updates.l10n.installNow ); + + wp.a11y.speak( wp.updates.l10n.updateCancel, 'polite' ); + } ); + } + + wp.updates.installPlugin( { + slug: $button.data( 'slug' ) + } ); + }); + }); +})( window.wp, jQuery ); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/plugin-install.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/plugin-install.min.js new file mode 100644 index 0000000..6a7b330 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/admin/plugin-install.min.js @@ -0,0 +1 @@ +!function(a,t){"use strict";a&&t(function(){t(document).on("click",".sf-install-now",function(e){var s=t(e.target);if(s.hasClass("activate-now"))return!0;e.preventDefault(),s.hasClass("updating-message")||s.hasClass("button-disabled")||(a.updates.shouldRequestFilesystemCredentials&&!a.updates.ajaxLocked&&(a.updates.requestFilesystemCredentials(e),t(document).on("credential-modal-cancel",function(){t(".sf-install-now.updating-message").removeClass("updating-message").text(a.updates.l10n.installNow),a.a11y.speak(a.updates.l10n.updateCancel,"polite")})),a.updates.installPlugin({slug:s.data("slug")}))})})}(window.wp,jQuery); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/editor.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/editor.js new file mode 100644 index 0000000..733867f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/editor.js @@ -0,0 +1,154 @@ +/** + * Block editor enhancements. + * + * Contains functionality to dynamically update the block editor + * configuration and styling. + */ +(function () { + /** + * Check if the main sidebar is active (has widgets). + * + * This uses a custom property `mainSidebarActive` added via the + * `block_editor_settings` filter. + * + * @return {boolean} Whether sidebar is active. + */ + var sidebarIsActive = function sidebarIsActive() { + var settings = wp.data.select('core/editor').getEditorSettings(); + + if (settings.hasOwnProperty('mainSidebarActive') && !!settings.mainSidebarActive) { + return true; + } + + return false; + }; + /** + * Get current page template name. + * + * @return {string} The page template name. + */ + + + var getCurrentPageTemplate = function getCurrentPageTemplate() { + return wp.data.select('core/editor').getEditedPostAttribute('template'); + }; + /** + * Check if the active theme supports a wide layout. + * + * @return {boolean} Whether the theme supports wide layout. + */ + + + var themeSupportsWide = function themeSupportsWide() { + var settings = wp.data.select('core/editor').getEditorSettings(); + + if (settings.hasOwnProperty('alignWide') && !!settings.alignWide) { + return true; + } + + return false; + }; + /** + * Update editor wide support. + * + * @param {boolean} alignWide Whether the editor supports + * alignWide support. + * + * @return {void} + */ + + + var updateWideSupport = function updateWideSupport(alignWide) { + wp.data.dispatch('core/editor').updateEditorSettings({ + 'alignWide': !!alignWide + }); + }; + /** + * Update `data-align` attribute on each block. + * + * @param {boolean} alignWide Whether alignWide is supported. + * + * @return {void} + */ + + + var updateAlignAttribute = function updateAlignAttribute(alignWide) { + var blocks = wp.data.select('core/editor').getBlocks(); + blocks.forEach(function (block) { + if (block.attributes.hasOwnProperty('align')) { + var align = block.attributes.align; + + if (!['full', 'wide'].includes(align)) { + return; + } + + var blockWrapper = document.getElementById('block-' + block.clientId); + + if (blockWrapper) { + blockWrapper.setAttribute('data-align', alignWide ? align : ''); + } + } + }); + }; + /** + * Add custom class to editor wrapper if main sidebar is active. + * + * @param {boolean} showSidebar Whether to add custom class. + * + * @return {void} + */ + + + var toggleCustomSidebarClass = function toggleCustomSidebarClass(showSidebar) { + // First class for WP<=5.3 and second class for WP>=5.4. + var editorWrapper = document.querySelector('.editor-writing-flow, .block-editor-writing-flow'); + + if (!editorWrapper) { + return; + } + + if (!!showSidebar) { + editorWrapper.classList.add('storefront-has-sidebar'); + } else { + editorWrapper.classList.remove('storefront-has-sidebar'); + } + }; + /** + * Update editor and blocks when layout changes. + * + * @return {void} + */ + + + var maybeUpdateEditor = function maybeUpdateEditor() { + if ('template-fullwidth.php' === getCurrentPageTemplate()) { + updateWideSupport(true); + toggleCustomSidebarClass(false); + updateAlignAttribute(true); + } else if (sidebarIsActive()) { + updateWideSupport(false); + toggleCustomSidebarClass(true); + updateAlignAttribute(false); + } else { + updateWideSupport(true); + toggleCustomSidebarClass(false); + updateAlignAttribute(true); + } + }; + + wp.domReady(function () { + // Don't do anything if the theme doesn't declare support for `align-wide`. + if (!themeSupportsWide()) { + return; + } + + maybeUpdateEditor(); + var pageTemplate = getCurrentPageTemplate(); + wp.data.subscribe(function () { + if (getCurrentPageTemplate() !== pageTemplate) { + pageTemplate = getCurrentPageTemplate(); + maybeUpdateEditor(); + } + }); + }); +})(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/editor.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/editor.min.js new file mode 100644 index 0000000..39610be --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/editor.min.js @@ -0,0 +1 @@ +!function(){function i(){return wp.data.select("core/editor").getEditedPostAttribute("template")}function e(t){wp.data.dispatch("core/editor").updateEditorSettings({alignWide:!!t})}function a(i){wp.data.select("core/editor").getBlocks().forEach(function(t){var e;t.attributes.hasOwnProperty("align")&&(e=t.attributes.align,!["full","wide"].includes(e)||(t=document.getElementById("block-"+t.clientId))&&t.setAttribute("data-align",i?e:""))})}function r(t){var e=document.querySelector(".editor-writing-flow, .block-editor-writing-flow");e&&(t?e.classList.add("storefront-has-sidebar"):e.classList.remove("storefront-has-sidebar"))}function o(){var t;"template-fullwidth.php"!==i()&&(t=wp.data.select("core/editor").getEditorSettings()).hasOwnProperty("mainSidebarActive")&&t.mainSidebarActive?(e(!1),r(!0),a(!1)):(e(!0),r(!1),a(!0))}wp.domReady(function(){var t,e;(t=wp.data.select("core/editor").getEditorSettings()).hasOwnProperty("alignWide")&&t.alignWide&&(o(),e=i(),wp.data.subscribe(function(){i()!==e&&(e=i(),o())}))})}(); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/footer.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/footer.js new file mode 100644 index 0000000..61138be --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/footer.js @@ -0,0 +1,47 @@ +/** + * footer.js + * + * Adds a class required to reveal the search in the handheld footer bar. + * Also hides the handheld footer bar when an input is focused. + */ +( function() { + // Wait for DOM to be ready. + document.addEventListener( 'DOMContentLoaded', function() { + if ( 0 === document.getElementsByClassName( 'storefront-handheld-footer-bar' ).length ) { + return; + } + + // Add class to footer search when clicked. + [].forEach.call( document.querySelectorAll( '.storefront-handheld-footer-bar .search > a' ), function( anchor ) { + anchor.addEventListener( 'click', function( event ) { + anchor.parentElement.classList.toggle( 'active' ); + event.preventDefault(); + } ); + } ); + + // Add focus class to body when an input field is focused. + // This is used to hide the Handheld Footer Bar when an input is focused. + var footer_bar = document.getElementsByClassName( 'storefront-handheld-footer-bar' ); + var forms = document.forms; + var isFocused = function( focused ) { + return function( event ) { + if ( !! focused && event.target.tabIndex !== -1 ) { + document.body.classList.add( 'sf-input-focused' ); + } else { + document.body.classList.remove( 'sf-input-focused' ); + } + }; + }; + + if ( footer_bar.length && forms.length ) { + for ( var i = 0; i < forms.length; i++ ) { + if ( footer_bar[0].contains( forms[ i ] ) ) { + continue; + } + + forms[ i ].addEventListener( 'focus', isFocused( true ), true ); + forms[ i ].addEventListener( 'blur', isFocused( false ), true ); + } + } + } ); +} )(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/footer.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/footer.min.js new file mode 100644 index 0000000..c30a549 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/footer.min.js @@ -0,0 +1 @@ +document.addEventListener("DOMContentLoaded",function(){if(0!==document.getElementsByClassName("storefront-handheld-footer-bar").length){[].forEach.call(document.querySelectorAll(".storefront-handheld-footer-bar .search > a"),function(t){t.addEventListener("click",function(e){t.parentElement.classList.toggle("active"),e.preventDefault()})});function e(t){return function(e){t&&-1!==e.target.tabIndex?document.body.classList.add("sf-input-focused"):document.body.classList.remove("sf-input-focused")}}var t=document.getElementsByClassName("storefront-handheld-footer-bar"),n=document.forms;if(t.length&&n.length)for(var o=0;o 0 ) { + [].forEach.call( handheld[0].querySelectorAll( '.menu-item-has-children > a, .page_item_has_children > a' ), function( anchor ) { + + // Add dropdown toggle that displays child menu items + var btn = document.createElement( 'button' ); + btn.setAttribute( 'aria-expanded', 'false' ); + btn.classList.add( 'dropdown-toggle' ); + + var btnSpan = document.createElement( 'span' ); + btnSpan.classList.add( 'screen-reader-text' ); + btnSpan.appendChild( document.createTextNode( storefrontScreenReaderText.expand ) ); + + btn.appendChild( btnSpan ); + + anchor.parentNode.insertBefore( btn, anchor.nextSibling ); + + // Set the active submenu dropdown toggle button initial state + if ( anchor.parentNode.classList.contains( 'current-menu-ancestor' ) ) { + btn.setAttribute( 'aria-expanded', 'true' ); + btn.classList.add( 'toggled-on' ); + btn.nextElementSibling.classList.add( 'toggled-on' ); + } + + // Add event listener + btn.addEventListener( 'click', function() { + btn.classList.toggle( 'toggled-on' ); + + // Remove text inside span + while ( btnSpan.firstChild ) { + btnSpan.removeChild( btnSpan.firstChild ); + } + + var expanded = btn.classList.contains( 'toggled-on' ); + + btn.setAttribute( 'aria-expanded', expanded ); + btnSpan.appendChild( document.createTextNode( expanded ? storefrontScreenReaderText.collapse : storefrontScreenReaderText.expand ) ); + btn.nextElementSibling.classList.toggle( 'toggled-on' ); + } ); + } ); + } + + // Add focus class to parents of sub-menu anchors. + [].forEach.call( document.querySelectorAll( '.site-header .menu-item > a, .site-header .page_item > a, .site-header-cart a' ), function( anchor ) { + anchor.addEventListener( 'focus', function() { + + // Remove focus class from other sub-menus previously open. + var elems = document.querySelectorAll( '.focus' ); + + [].forEach.call( elems, function( el ) { + if ( ! el.contains( anchor ) ) { + el.classList.remove( 'focus' ); + + // Remove blocked class, if it exists. + if ( el.firstChild && el.firstChild.classList ) { + el.firstChild.classList.remove( 'blocked' ); + } + } + } ); + + // Add focus class. + var li = anchor.parentNode; + + li.classList.add( 'focus' ); + } ); + } ); + + // Add an identifying class to dropdowns when on a touch device + // This is required to switch the dropdown hiding method from a negative `left` value to `display: none`. + if ( ( 'ontouchstart' in window || navigator.maxTouchPoints ) && window.innerWidth > 767 ) { + [].forEach.call( document.querySelectorAll( '.site-header ul ul, .site-header-cart .widget_shopping_cart' ), function( element ) { + element.classList.add( 'sub-menu--is-touch-device' ); + } ); + + // Add blocked class to links that open sub-menus, and prevent from navigating away on first touch. + var acceptClick = false; + + [].forEach.call( document.querySelectorAll( '.site-header .menu-item > a, .site-header .page_item > a, .site-header-cart a' ), function( anchor ) { + anchor.addEventListener( 'click', function( event ) { + if ( anchor.classList.contains( 'blocked' ) && false === acceptClick ) { + event.preventDefault(); + } + + acceptClick = false; + } ); + + anchor.addEventListener( 'pointerup', function( event ) { + if ( anchor.classList.contains( 'blocked' ) || 'mouse' === event.pointerType ) { + acceptClick = true; + } else if ( ( 'cart-contents' === anchor.className && anchor.parentNode.nextElementSibling && '' !== anchor.parentNode.nextElementSibling.textContent.trim() ) || anchor.nextElementSibling ) { + anchor.classList.add( 'blocked' ); + } else { + acceptClick = true; + } + } ); + } ); + + // Ensure the dropdowns close when user taps outside the site header + [].forEach.call( document.querySelectorAll( 'body #page > :not( .site-header )' ), function( element ) { + element.addEventListener( 'click', function() { + [].forEach.call( document.querySelectorAll( '.focus, .blocked' ), function( el ) { + el.classList.remove( 'focus' ); + el.classList.remove( 'blocked' ); + } ); + } ); + } ); + } + } ); +} )(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/navigation.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/navigation.min.js new file mode 100644 index 0000000..d890ad2 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/navigation.min.js @@ -0,0 +1 @@ +document.addEventListener("DOMContentLoaded",function(){var t,n,e,a,s=document.getElementById("site-navigation");!s||(t=s.querySelector("button"))&&((n=s.querySelector("ul"))?(t.setAttribute("aria-expanded","false"),n.setAttribute("aria-expanded","false"),n.classList.add("nav-menu"),t.addEventListener("click",function(){s.classList.toggle("toggled");var e=s.classList.contains("toggled")?"true":"false";t.setAttribute("aria-expanded",e),n.setAttribute("aria-expanded",e)}),0<(e=document.getElementsByClassName("handheld-navigation")).length&&[].forEach.call(e[0].querySelectorAll(".menu-item-has-children > a, .page_item_has_children > a"),function(e){var t=document.createElement("button");t.setAttribute("aria-expanded","false"),t.classList.add("dropdown-toggle");var n=document.createElement("span");n.classList.add("screen-reader-text"),n.appendChild(document.createTextNode(storefrontScreenReaderText.expand)),t.appendChild(n),e.parentNode.insertBefore(t,e.nextSibling),e.parentNode.classList.contains("current-menu-ancestor")&&(t.setAttribute("aria-expanded","true"),t.classList.add("toggled-on"),t.nextElementSibling.classList.add("toggled-on")),t.addEventListener("click",function(){for(t.classList.toggle("toggled-on");n.firstChild;)n.removeChild(n.firstChild);var e=t.classList.contains("toggled-on");t.setAttribute("aria-expanded",e),n.appendChild(document.createTextNode(e?storefrontScreenReaderText.collapse:storefrontScreenReaderText.expand)),t.nextElementSibling.classList.toggle("toggled-on")})}),[].forEach.call(document.querySelectorAll(".site-header .menu-item > a, .site-header .page_item > a, .site-header-cart a"),function(t){t.addEventListener("focus",function(){var e=document.querySelectorAll(".focus");[].forEach.call(e,function(e){e.contains(t)||(e.classList.remove("focus"),e.firstChild&&e.firstChild.classList&&e.firstChild.classList.remove("blocked"))}),t.parentNode.classList.add("focus")})}),("ontouchstart"in window||navigator.maxTouchPoints)&&767 a, .site-header .page_item > a, .site-header-cart a"),function(t){t.addEventListener("click",function(e){t.classList.contains("blocked")&&!1===a&&e.preventDefault(),a=!1}),t.addEventListener("pointerup",function(e){!t.classList.contains("blocked")&&"mouse"!==e.pointerType&&("cart-contents"===t.className&&t.parentNode.nextElementSibling&&""!==t.parentNode.nextElementSibling.textContent.trim()||t.nextElementSibling)?t.classList.add("blocked"):a=!0})}),[].forEach.call(document.querySelectorAll("body #page > :not( .site-header )"),function(e){e.addEventListener("click",function(){[].forEach.call(document.querySelectorAll(".focus, .blocked"),function(e){e.classList.remove("focus"),e.classList.remove("blocked")})})}))):t.style.display="none")}); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/skip-link-focus-fix.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/skip-link-focus-fix.js new file mode 100644 index 0000000..1581349 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/skip-link-focus-fix.js @@ -0,0 +1,19 @@ +( function() { + var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1, + is_opera = navigator.userAgent.toLowerCase().indexOf( 'opera' ) > -1, + is_ie = navigator.userAgent.toLowerCase().indexOf( 'msie' ) > -1; + + if ( ( is_webkit || is_opera || is_ie ) && document.getElementById && window.addEventListener ) { + window.addEventListener( 'hashchange', function() { + var element = document.getElementById( location.hash.substring( 1 ) ); + + if ( element ) { + if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) { + element.tabIndex = -1; + } + + element.focus(); + } + }, false ); + } +})(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/skip-link-focus-fix.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/skip-link-focus-fix.min.js new file mode 100644 index 0000000..2a8ccfa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/skip-link-focus-fix.min.js @@ -0,0 +1 @@ +!function(){var e=-1 0 ) { + var stickyAddToCartToggle = function() { + if ( ( trigger[0].getBoundingClientRect().top + trigger[0].scrollHeight ) < 0 ) { + stickyAddToCart[0].classList.add( 'storefront-sticky-add-to-cart--slideInDown' ); + stickyAddToCart[0].classList.remove( 'storefront-sticky-add-to-cart--slideOutUp' ); + } else if ( stickyAddToCart[0].classList.contains( 'storefront-sticky-add-to-cart--slideInDown' ) ) { + stickyAddToCart[0].classList.add( 'storefront-sticky-add-to-cart--slideOutUp' ); + stickyAddToCart[0].classList.remove( 'storefront-sticky-add-to-cart--slideInDown' ); + } + }; + + stickyAddToCartToggle(); + + window.addEventListener( 'scroll', function() { + stickyAddToCartToggle(); + } ); + + // Get product id + var product_id = null; + + document.body.classList.forEach( function( item ){ + if ( 'postid-' === item.substring( 0, 7 ) ) { + product_id = item.replace( /[^0-9]/g, '' ); + } + } ); + + if ( product_id ) { + var product = document.getElementById( 'product-' + product_id ); + + if ( product ) { + if ( ! product.classList.contains( 'product-type-simple' ) && ! product.classList.contains( 'product-type-external' ) ) { + var selectOptions = document.getElementsByClassName( 'storefront-sticky-add-to-cart__content-button' ); + + selectOptions[0].addEventListener( 'click', function( event ) { + event.preventDefault(); + document.getElementById( 'product-' + product_id ).scrollIntoView(); + } ); + } + } + } + } + } ); +} )(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/sticky-add-to-cart.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/sticky-add-to-cart.min.js new file mode 100644 index 0000000..3eff5ec --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/sticky-add-to-cart.min.js @@ -0,0 +1 @@ +document.addEventListener("DOMContentLoaded",function(){var t,e,s,n,o=document.getElementsByClassName("storefront-sticky-add-to-cart");o.length&&("undefined"==typeof storefront_sticky_add_to_cart_params||0<(t=document.getElementsByClassName(storefront_sticky_add_to_cart_params.trigger_class)).length&&((e=function(){t[0].getBoundingClientRect().top+t[0].scrollHeight<0?(o[0].classList.add("storefront-sticky-add-to-cart--slideInDown"),o[0].classList.remove("storefront-sticky-add-to-cart--slideOutUp")):o[0].classList.contains("storefront-sticky-add-to-cart--slideInDown")&&(o[0].classList.add("storefront-sticky-add-to-cart--slideOutUp"),o[0].classList.remove("storefront-sticky-add-to-cart--slideInDown"))})(),window.addEventListener("scroll",function(){e()}),s=null,document.body.classList.forEach(function(t){"postid-"===t.substring(0,7)&&(s=t.replace(/[^0-9]/g,""))}),!s||(n=document.getElementById("product-"+s))&&(n.classList.contains("product-type-simple")||n.classList.contains("product-type-external")||document.getElementsByClassName("storefront-sticky-add-to-cart__content-button")[0].addEventListener("click",function(t){t.preventDefault(),document.getElementById("product-"+s).scrollIntoView()}))))}); \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/vendor/pep.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/vendor/pep.min.js new file mode 100644 index 0000000..a976ae8 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/vendor/pep.min.js @@ -0,0 +1,5 @@ +/*! + * PEP v0.4.3 | https://github.com/jquery/PEP + * Copyright jQuery Foundation and other contributors | http://jquery.org/license + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.PointerEventsPolyfill=e()}(this,function(){"use strict";function r(t,e){e=e||Object.create(null);var n=document.createEvent("Event");n.initEvent(t,e.bubbles||!1,e.cancelable||!1);for(var i,r=2;r=i.length){var r=[];k.forEach(function(t,e){if(1!==e&&!this.findTouch(i,e-2)){var n=t.out;r.push(n)}},this),r.forEach(this.cancelOut,this)}},touchstart:function(t){this.vacuumTouches(t),this.setPrimaryTouch(t.changedTouches[0]),this.dedupSynthMouse(t),this.scrolling||(this.clickCount++,this.processTouches(t,this.overDown))},overDown:function(t){k.set(t.pointerId,{target:t.target,out:t,outTarget:t.target}),m.enterOver(t),m.down(t)},touchmove:function(t){this.scrolling||(this.shouldScroll(t)?(this.scrolling=!0,this.touchcancel(t)):(t.preventDefault(),this.processTouches(t,this.moveOverOut)))},moveOverOut:function(t){var e=t,n=k.get(e.pointerId);if(n){var i=n.out,r=n.outTarget;m.move(e),i&&r!==e.target&&(i.relatedTarget=e.target,e.relatedTarget=r,i.target=r,e.target?(m.leaveOut(i),m.enterOver(e)):(e.target=r,e.relatedTarget=null,this.cancelOut(e))),n.out=e,n.outTarget=e.target}},touchend:function(t){this.dedupSynthMouse(t),this.processTouches(t,this.upOut)},upOut:function(t){this.scrolling||(m.up(t),m.leaveOut(t)),this.cleanUpPointer(t)},touchcancel:function(t){this.processTouches(t,this.cancelOut)},cancelOut:function(t){m.cancel(t),m.leaveOut(t),this.cleanUpPointer(t)},cleanUpPointer:function(t){k.delete(t.pointerId),this.removePrimaryPointer(t)},dedupSynthMouse:function(t){var e=_.lastTouches,n=t.changedTouches[0];if(this.isPrimaryTouch(n)){var i={x:n.clientX,y:n.clientY};e.push(i);var r=function(t,e){var n=t.indexOf(e);-1 768 && brandsAZ[0].getBoundingClientRect().top < 0 ) { + brandsAZ[0].style.paddingTop = Math.min( ( Math.abs( brandsAZ[0].getBoundingClientRect().top ) + 20 + adminBar ), brandsContainerHeight - brandsAZHeight ) + 'px'; + } else { + brandsAZ[0].style.paddingTop = 0; + } + }; + + stickyBrandsAZ(); + + window.addEventListener( 'scroll', function() { + stickyBrandsAZ(); + } ); + } ); +} )(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/woocommerce/extensions/brands.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/woocommerce/extensions/brands.min.js new file mode 100644 index 0000000..21feb33 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/woocommerce/extensions/brands.min.js @@ -0,0 +1 @@ +document.addEventListener("DOMContentLoaded",function(){var n,t,e,d,i=document.getElementsByClassName("brands_index");i.length&&(n=document.body.classList.contains("admin-bar")?32:0,t=document.getElementById("brands_a_z").scrollHeight,e=i[0].scrollHeight+40,(d=function(){768 windowHeight ) { + cartList.style.maxHeight = '15em'; + cartList.style.overflowY = 'auto'; + } + } ); + } ); +} )(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/woocommerce/header-cart.min.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/woocommerce/header-cart.min.js new file mode 100644 index 0000000..367a2e7 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/assets/js/woocommerce/header-cart.min.js @@ -0,0 +1 @@ +document.body.classList.contains("woocommerce-cart")||document.body.classList.contains("woocommerce-checkout")||window.innerWidth<768||!document.getElementById("site-header-cart")||window.addEventListener("load",function(){document.querySelector(".site-header-cart").addEventListener("mouseover",function(){var e=window.outerHeight,t=this.querySelector(".widget_shopping_cart_content").getBoundingClientRect().bottom+this.offsetHeight,o=this.querySelector(".cart_list");e + +
    + + +

    + ' . get_the_title() . '' + ); + // phpcs:enable + ?> +

    + + 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through. ?> + + + +
      + 'ol', + 'short_ping' => true, + 'callback' => 'storefront_comment', + ) + ); + ?> +
    + + 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through. ?> + + +

    + '', + 'title_reply_after' => '', + ) + ); + + comment_form( $args ); + ?> + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-homepage.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-homepage.php new file mode 100644 index 0000000..a220c0d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-homepage.php @@ -0,0 +1,25 @@ + + + +
    style="" data-featured-image=""> +
    + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-none.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-none.php new file mode 100644 index 0000000..d495a43 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-none.php @@ -0,0 +1,39 @@ + + +
    + + +
    + + +

    + Get started here.', 'storefront' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( admin_url( 'post-new.php' ) ) ); + ?> +

    + + + +

    + + + + +

    + + + +
    +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-page.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-page.php new file mode 100644 index 0000000..e7c4bcc --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-page.php @@ -0,0 +1,20 @@ + + +
    > + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-single.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-single.php new file mode 100644 index 0000000..4426446 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content-single.php @@ -0,0 +1,32 @@ + + +
    > + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content.php new file mode 100644 index 0000000..863e974 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/content.php @@ -0,0 +1,22 @@ + + +
    > + + + +
    diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/docs/releases.md b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/docs/releases.md new file mode 100644 index 0000000..7dd04b6 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/docs/releases.md @@ -0,0 +1,103 @@ +# Releasing Storefront + +This document outlines the process for releasing new versions of the Storefront theme. + +Note that Storefront bumps the minor version (2.x.0) between releases and the next version after 2.9.0 would be 3.0.0, [similar to WordPress core version numbering](https://make.wordpress.org/core/handbook/about/release-cycle/version-numbering/). Patch versions are used for fix releases that are deployed outside the usual release schedule (this is rare). + +## Steps + +The release process has three main phases: + +- Building and testing a release candidate (RC) - steps 1-3 below. +- Fixing any issues that arise during RC testing. +- Building and releasing the final release - steps 1 & 4-6. + +Depending on the release, releasing and testing an RC may not be necessary (i.e. skip step 2); for larger releases, multiple RCs may be worthwhile (i.e. repeat steps 1-3). + +### 1 – Prepare code & build zip file + +- Confirm all work intended for release (fixes, features) is completed and merged to release branch. + - Typically we release Storefront from default branch (`trunk`). + - A release branch (e.g. `release/2.7`) is used as needed, e.g. patch releases (rare). + - Ensure testing instructions for all enhancements are [available on the wiki](https://github.com/woocommerce/storefront/wiki/Release-Testing-Instructions). +- Review any [dependency updates since the last release](https://github.com/woocommerce/storefront/pulls?q=is%3Apr+author%3Aapp%2Frenovate+is%3Aclosed). + - Is extra testing needed? + - Add release notes as appropriate (e.g. major versions or risky/impactful updates). +- Ensure your local checkout is on release branch and up to date! +- Update version numbers and release date (if you're building an RC version make sure you use the correct version strategy - eg. 2.6.1-rc1): + - `readme.txt` + - `style.scss` + - `package.json` and `package-lock.json` +- Confirm/update metadata in `readme.txt`, e.g. “tested up to” version. +- Review if any [user documentation](https://docs.woocommerce.com/documentation/themes/storefront/) updates are needed, for example: new features or changed minimum requirements. +- Finalise changelog and add to `readme.txt`. +- Clean install of dependencies: `npm ci`. +- Run a production build: `npm run build`. +- Ensure all changes above are committed and pushed (you should not have uncommitted changes): + - Version numbers, dates, metadata + - Changelog + - Translation (`.pot`) file. Note this file is generated by production build. + +__*Outcome*: You know what changes are in the release, what might be impacted, and what testing is required.__ + +__*Outcome*: A `storefront.zip` file that you can test with.__ + +__*Outcome*: All release changes including versions and POT file are committed and pushed to release branch.__ + +### 2 – Publish RC build (optional) + +- Publish release on [GitHub](https://github.com/woocommerce/storefront/releases). + - Upload release zip. + - Use this format for tag: `version/1.2.3-rc.1`. + - Paste changelog into “release details” field. + - Check `This is a pre-release` tickbox. + +__*Outcome*: A `storefront.zip` file is available to the community and other stakeholders for testing and feedback.__ + +### 3 – Test & QA + +Note: all new code should have been fully tested during development. This test pass is to confirm that there are no major regressions or bugs, aka [“happy path”](https://en.wikipedia.org/wiki/Happy_path) or [smoke testing](http://softwaretestingfundamentals.com/smoke-testing/). + +Testing documentation is available in the [wiki](https://github.com/woocommerce/storefront/wiki/): + +- [Checklist of main flows and features](https://github.com/woocommerce/storefront/wiki/Testing-Storefront:-flows-and-features). +- [Testing instructions for each release (2.5.7 and newer)](https://github.com/woocommerce/storefront/wiki/Release-Testing-Instructions). + +- __Recommended__: Test in a clean environment, similar to a typical hosting environment. Avoid testing in your development environment. +- __Recommended__: Test with a snapshot of data from a real store, with customers, products and reviews. + +Perform testing as appropriate for the release. Use your judgement to ensure effective efficient testing – e.g. for small releases, 1 tester (you) x ~1 hour. For larger releases, allow more time and request assistance from team, testing guild as necessary. + +At a minimum, test the following: + +- Spot-check a cross-section of key flows - e.g. timeboxed exploratory testing. +- Confirm recent fixes and features (this release, previous release) are working correctly and haven’t regressed. + +__If there are blocking issues or major regressions, the process stops here!__ (So they can be fixed.) + +__*Outcome*: You (release lead) are confident that the product is ready for release, and a safe & worthwhile upgrade for merchants.__ + +### 4 – Launch release + +Now we get to release! + +- If necessary, build final `storefront.zip` with correct (non-RC) version number (repeat step 1, and appropriate testing - step 3). +- Publish release on [GitHub](https://github.com/woocommerce/storefront/releases). + - Upload release zip. + - Use this format for tag: `version/1.2.3`. + - Paste changelog into “release details” field. +- Upload to [WordPress.org](https://wordpress.org/themes/upload/). (You'll need access to the `Automattic` user account.) +- Publish any [user documentation](https://docs.woocommerce.com/documentation/themes/storefront/) updates. +- Post an announcement on the [dev blog](https://woocommerce.wordpress.com/category/storefront/). + +__*Outcome*: Merchants are using the new Storefront, your new features are live, stores are working better, customers are happier!__ + +### 5 – Post-release checks + +- Confirm WordPress.org version is correct, sites can auto-update. +- Update [demo site](https://themes.woocommerce.com/storefront/): + - Clone/update [demo.woothemes.com](https://github.com/automattic/demo.woothemes.com) repository master branch. + - Update storefront – i.e. unzip and replace `themes/storefront`. + - Commit & push. + - Site should automatically build & deploy. +- Confirm demo site is running correct version and nothing is broken. diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/e2e/specs/browser.test.js b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/e2e/specs/browser.test.js new file mode 100644 index 0000000..9e08d07 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/e2e/specs/browser.test.js @@ -0,0 +1,9 @@ +describe( 'Storefront', () => { + beforeAll( async () => { + await page.goto( STORE_URL ); + } ); + + it( 'should have "built with Storefront" footer', async () => { + await expect( page ).toMatch( 'Built with Storefront & WooCommerce.' ); + } ); +}); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/footer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/footer.php new file mode 100644 index 0000000..398242b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/footer.php @@ -0,0 +1,40 @@ + + +
    +
    + + + +
    +
    + + + +
    +
    + + + + + + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/functions.php new file mode 100644 index 0000000..4a1925e --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/functions.php @@ -0,0 +1,74 @@ + $storefront_version, + + /** + * Initialize all the things. + */ + 'main' => require 'inc/class-storefront.php', + 'customizer' => require 'inc/customizer/class-storefront-customizer.php', +); + +require 'inc/storefront-functions.php'; +require 'inc/storefront-template-hooks.php'; +require 'inc/storefront-template-functions.php'; +require 'inc/wordpress-shims.php'; + +if ( class_exists( 'Jetpack' ) ) { + $storefront->jetpack = require 'inc/jetpack/class-storefront-jetpack.php'; +} + +if ( storefront_is_woocommerce_activated() ) { + $storefront->woocommerce = require 'inc/woocommerce/class-storefront-woocommerce.php'; + $storefront->woocommerce_customizer = require 'inc/woocommerce/class-storefront-woocommerce-customizer.php'; + + require 'inc/woocommerce/class-storefront-woocommerce-adjacent-products.php'; + + require 'inc/woocommerce/storefront-woocommerce-template-hooks.php'; + require 'inc/woocommerce/storefront-woocommerce-template-functions.php'; + require 'inc/woocommerce/storefront-woocommerce-functions.php'; +} + +if ( is_admin() ) { + $storefront->admin = require 'inc/admin/class-storefront-admin.php'; + + require 'inc/admin/class-storefront-plugin-install.php'; +} + +/** + * NUX + * Only load if wp version is 4.7.3 or above because of this issue; + * https://core.trac.wordpress.org/ticket/39610?cversion=1&cnum_hist=2 + */ +if ( version_compare( get_bloginfo( 'version' ), '4.7.3', '>=' ) && ( is_admin() || is_customize_preview() ) ) { + require 'inc/nux/class-storefront-nux-admin.php'; + require 'inc/nux/class-storefront-nux-guided-tour.php'; + + if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '3.0.0', '>=' ) ) { + require 'inc/nux/class-storefront-nux-starter-content.php'; + } +} + +/** + * Note: Do not add any custom code here. Please use a custom plugin so that your customizations aren't lost during updates. + * https://github.com/woocommerce/theme-customisations + */ diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/header.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/header.php new file mode 100644 index 0000000..7fcaad3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/header.php @@ -0,0 +1,67 @@ + section and everything up till
    + * + * @package storefront + */ + +?> +> + + + + + + + + + +> + + + + + +
    + + + + + + +
    +
    + + + +
    +
    + Storefront +
      +
    • +
    • +
    • +
    +
    + + + +
    + ' . sprintf( esc_attr__( 'Setup complete %1$sYour Storefront adventure begins now 🚀%2$s ', 'storefront' ), '', '' ) . ''; + echo '

    ' . esc_attr__( 'One more thing... You might be interested in the following Storefront extensions and designs.', 'storefront' ) . '

    '; + } else { + echo '

    ' . esc_attr__( 'Hello! You might be interested in the following Storefront extensions and designs.', 'storefront' ) . '

    '; + } + ?> +
    + +
    +
    +

    + + Storefront Extensions Hero + + +

    + +

    + +

    + +

    + + +

    + +

    +
    +
    +

    + Storefront Powerpack + +

    + +

    + +

    + +

    + +

    + +

    + +

    + +

    +
    +
    + +
    +

    + Automattic' ); + ?> +

    +
    +
    + esc_attr__( 'Activated', 'storefront' ), + 'url' => '#', + 'classes' => 'disabled', + ); + } elseif ( $this->_is_plugin_installed( $plugin_slug ) ) { + $url = $this->_is_plugin_installed( $plugin_slug ); + + // The plugin exists but isn't activated yet. + $button = array( + 'message' => esc_attr__( 'Activate', 'storefront' ), + 'url' => $url, + 'classes' => 'activate-now', + ); + } else { + // The plugin doesn't exist. + $url = wp_nonce_url( + add_query_arg( + array( + 'action' => 'install-plugin', + 'plugin' => $plugin_slug, + ), + self_admin_url( 'update.php' ) + ), + 'install-plugin_' . $plugin_slug + ); + $button = array( + 'message' => esc_attr__( 'Install now', 'storefront' ), + 'url' => $url, + 'classes' => ' install-now install-' . $plugin_slug, + ); + } + ?> + + + 'activate', + 'plugin' => $plugin_file, + ), + admin_url( 'plugins.php' ) + ), + 'activate-plugin_' . $plugin_file + ); + return $url; + } + } + return false; + } + /** + * Welcome screen enhance section + * + * @since 1.5.2 + */ + public function welcome_enhance() { + require_once get_template_directory() . '/inc/admin/welcome-screen/component-enhance.php'; + } + + /** + * Welcome screen contribute section + * + * @since 1.5.2 + */ + public function welcome_contribute() { + require_once get_template_directory() . '/inc/admin/welcome-screen/component-contribute.php'; + } + + /** + * Get product data from json + * + * @param string $url URL to the json file. + * @param string $transient Name the transient. + * @return [type] [description] + */ + public function get_storefront_product_data( $url, $transient ) { + $raw_products = wp_safe_remote_get( $url ); + $products = json_decode( wp_remote_retrieve_body( $raw_products ) ); + + if ( ! empty( $products ) ) { + set_transient( $transient, $products, DAY_IN_SECONDS ); + } + + return $products; + } + } + +endif; + +return new Storefront_Admin(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/admin/class-storefront-plugin-install.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/admin/class-storefront-plugin-install.php new file mode 100644 index 0000000..aa3d04f --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/admin/class-storefront-plugin-install.php @@ -0,0 +1,151 @@ + esc_attr__( 'Activated', 'storefront' ), + 'url' => '#', + 'classes' => array( 'storefront-button', 'disabled' ), + ); + + if ( '' !== $activated ) { + $button['message'] = esc_attr( $activated ); + } + } elseif ( self::_is_plugin_installed( $plugin_slug ) ) { + $url = self::_is_plugin_installed( $plugin_slug ); + + // The plugin exists but isn't activated yet. + $button = array( + 'message' => esc_attr__( 'Activate', 'storefront' ), + 'url' => $url, + 'classes' => array( 'activate-now' ), + ); + + if ( '' !== $activate ) { + $button['message'] = esc_attr( $activate ); + } + } else { + // The plugin doesn't exist. + $url = wp_nonce_url( + add_query_arg( + array( + 'action' => 'install-plugin', + 'plugin' => $plugin_slug, + ), + self_admin_url( 'update.php' ) + ), + 'install-plugin_' . $plugin_slug + ); + $button = array( + 'message' => esc_attr__( 'Install now', 'storefront' ), + 'url' => $url, + 'classes' => array( 'sf-install-now', 'install-now', 'install-' . $plugin_slug ), + ); + + if ( '' !== $install ) { + $button['message'] = esc_attr( $install ); + } + } + + if ( ! empty( $classes ) ) { + $button['classes'] = array_merge( $button['classes'], $classes ); + } + + $button['classes'] = implode( ' ', $button['classes'] ); + + ?> + + + + + 'activate', + 'plugin' => $plugin_file, + ), + admin_url( 'plugins.php' ) + ), + 'activate-plugin_' . $plugin_file + ); + return $url; + } + } + return false; + } + } + +endif; + +return new Storefront_Plugin_Install(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/class-storefront.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/class-storefront.php new file mode 100644 index 0000000..0e0828b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/class-storefront.php @@ -0,0 +1,580 @@ + 110, + 'width' => 470, + 'flex-width' => true, + 'flex-height' => true, + ) + ) + ); + + /** + * Register menu locations. + */ + register_nav_menus( + apply_filters( + 'storefront_register_nav_menus', + array( + 'primary' => __( 'Primary Menu', 'storefront' ), + 'secondary' => __( 'Secondary Menu', 'storefront' ), + 'handheld' => __( 'Handheld Menu', 'storefront' ), + ) + ) + ); + + /* + * Switch default core markup for search form, comment form, comments, galleries, captions and widgets + * to output valid HTML5. + */ + add_theme_support( + 'html5', + apply_filters( + 'storefront_html5_args', + array( + 'search-form', + 'comment-form', + 'comment-list', + 'gallery', + 'caption', + 'widgets', + 'style', + 'script', + ) + ) + ); + + /** + * Setup the WordPress core custom background feature. + */ + add_theme_support( + 'custom-background', + apply_filters( + 'storefront_custom_background_args', + array( + 'default-color' => apply_filters( 'storefront_default_background_color', 'ffffff' ), + 'default-image' => '', + ) + ) + ); + + /** + * Setup the WordPress core custom header feature. + */ + add_theme_support( + 'custom-header', + apply_filters( + 'storefront_custom_header_args', + array( + 'default-image' => '', + 'header-text' => false, + 'width' => 1950, + 'height' => 500, + 'flex-width' => true, + 'flex-height' => true, + ) + ) + ); + + /** + * Add support for the Site Logo plugin and the site logo functionality in JetPack + * https://github.com/automattic/site-logo + * http://jetpack.me/ + */ + add_theme_support( + 'site-logo', + apply_filters( + 'storefront_site_logo_args', + array( + 'size' => 'full', + ) + ) + ); + + /** + * Declare support for title theme feature. + */ + add_theme_support( 'title-tag' ); + + /** + * Declare support for selective refreshing of widgets. + */ + add_theme_support( 'customize-selective-refresh-widgets' ); + + /** + * Add support for Block Styles. + */ + add_theme_support( 'wp-block-styles' ); + + /** + * Add support for full and wide align images. + */ + add_theme_support( 'align-wide' ); + + /** + * Add support for editor styles. + */ + add_theme_support( 'editor-styles' ); + + /** + * Add support for editor font sizes. + */ + add_theme_support( + 'editor-font-sizes', + array( + array( + 'name' => __( 'Small', 'storefront' ), + 'size' => 14, + 'slug' => 'small', + ), + array( + 'name' => __( 'Normal', 'storefront' ), + 'size' => 16, + 'slug' => 'normal', + ), + array( + 'name' => __( 'Medium', 'storefront' ), + 'size' => 23, + 'slug' => 'medium', + ), + array( + 'name' => __( 'Large', 'storefront' ), + 'size' => 26, + 'slug' => 'large', + ), + array( + 'name' => __( 'Huge', 'storefront' ), + 'size' => 37, + 'slug' => 'huge', + ), + ) + ); + + /** + * Enqueue editor styles. + */ + add_editor_style( array( 'assets/css/base/gutenberg-editor.css', $this->google_fonts() ) ); + + /** + * Add support for responsive embedded content. + */ + add_theme_support( 'responsive-embeds' ); + } + + /** + * Register widget area. + * + * @link https://codex.wordpress.org/Function_Reference/register_sidebar + */ + public function widgets_init() { + $sidebar_args['sidebar'] = array( + 'name' => __( 'Sidebar', 'storefront' ), + 'id' => 'sidebar-1', + 'description' => '', + ); + + $sidebar_args['header'] = array( + 'name' => __( 'Below Header', 'storefront' ), + 'id' => 'header-1', + 'description' => __( 'Widgets added to this region will appear beneath the header and above the main content.', 'storefront' ), + ); + + $rows = intval( apply_filters( 'storefront_footer_widget_rows', 1 ) ); + $regions = intval( apply_filters( 'storefront_footer_widget_columns', 4 ) ); + + for ( $row = 1; $row <= $rows; $row++ ) { + for ( $region = 1; $region <= $regions; $region++ ) { + $footer_n = $region + $regions * ( $row - 1 ); // Defines footer sidebar ID. + $footer = sprintf( 'footer_%d', $footer_n ); + + if ( 1 === $rows ) { + /* translators: 1: column number */ + $footer_region_name = sprintf( __( 'Footer Column %1$d', 'storefront' ), $region ); + + /* translators: 1: column number */ + $footer_region_description = sprintf( __( 'Widgets added here will appear in column %1$d of the footer.', 'storefront' ), $region ); + } else { + /* translators: 1: row number, 2: column number */ + $footer_region_name = sprintf( __( 'Footer Row %1$d - Column %2$d', 'storefront' ), $row, $region ); + + /* translators: 1: column number, 2: row number */ + $footer_region_description = sprintf( __( 'Widgets added here will appear in column %1$d of footer row %2$d.', 'storefront' ), $region, $row ); + } + + $sidebar_args[ $footer ] = array( + 'name' => $footer_region_name, + 'id' => sprintf( 'footer-%d', $footer_n ), + 'description' => $footer_region_description, + ); + } + } + + $sidebar_args = apply_filters( 'storefront_sidebar_args', $sidebar_args ); + + foreach ( $sidebar_args as $sidebar => $args ) { + $widget_tags = array( + 'before_widget' => '
    ', + 'after_widget' => '
    ', + 'before_title' => '', + 'after_title' => '', + ); + + /** + * Dynamically generated filter hooks. Allow changing widget wrapper and title tags. See the list below. + * + * 'storefront_header_widget_tags' + * 'storefront_sidebar_widget_tags' + * + * 'storefront_footer_1_widget_tags' + * 'storefront_footer_2_widget_tags' + * 'storefront_footer_3_widget_tags' + * 'storefront_footer_4_widget_tags' + */ + $filter_hook = sprintf( 'storefront_%s_widget_tags', $sidebar ); + $widget_tags = apply_filters( $filter_hook, $widget_tags ); + + if ( is_array( $widget_tags ) ) { + register_sidebar( $args + $widget_tags ); + } + } + } + + /** + * Enqueue scripts and styles. + * + * @since 1.0.0 + */ + public function scripts() { + global $storefront_version; + + /** + * Styles + */ + wp_enqueue_style( 'storefront-style', get_template_directory_uri() . '/style.css', '', $storefront_version ); + wp_style_add_data( 'storefront-style', 'rtl', 'replace' ); + + wp_enqueue_style( 'storefront-icons', get_template_directory_uri() . '/assets/css/base/icons.css', '', $storefront_version ); + wp_style_add_data( 'storefront-icons', 'rtl', 'replace' ); + + /** + * Fonts + */ + wp_enqueue_style( 'storefront-fonts', $this->google_fonts(), array(), $storefront_version ); + + /** + * Scripts + */ + $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; + + wp_enqueue_script( 'storefront-navigation', get_template_directory_uri() . '/assets/js/navigation' . $suffix . '.js', array(), $storefront_version, true ); + wp_enqueue_script( 'storefront-skip-link-focus-fix', get_template_directory_uri() . '/assets/js/skip-link-focus-fix' . $suffix . '.js', array(), '20130115', true ); + + if ( has_nav_menu( 'handheld' ) ) { + $storefront_l10n = array( + 'expand' => __( 'Expand child menu', 'storefront' ), + 'collapse' => __( 'Collapse child menu', 'storefront' ), + ); + + wp_localize_script( 'storefront-navigation', 'storefrontScreenReaderText', $storefront_l10n ); + } + + if ( is_page_template( 'template-homepage.php' ) && has_post_thumbnail() ) { + wp_enqueue_script( 'storefront-homepage', get_template_directory_uri() . '/assets/js/homepage' . $suffix . '.js', array(), $storefront_version, true ); + } + + if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) { + wp_enqueue_script( 'comment-reply' ); + } + + wp_enqueue_script( 'jquery-pep', get_template_directory_uri() . '/assets/js/vendor/pep.min.js', array(), '0.4.3', true ); + } + + /** + * Register Google fonts. + * + * @since 2.4.0 + * @return string Google fonts URL for the theme. + */ + public function google_fonts() { + $google_fonts = apply_filters( + 'storefront_google_font_families', + array( + 'source-sans-pro' => 'Source+Sans+Pro:400,300,300italic,400italic,600,700,900', + ) + ); + + $query_args = array( + 'family' => implode( '|', $google_fonts ), + 'subset' => rawurlencode( 'latin,latin-ext' ), + ); + + $fonts_url = add_query_arg( $query_args, 'https://fonts.googleapis.com/css' ); + + return $fonts_url; + } + + /** + * Enqueue block assets. + * + * @since 2.5.0 + */ + public function block_assets() { + global $storefront_version; + + // Styles. + wp_enqueue_style( 'storefront-gutenberg-blocks', get_template_directory_uri() . '/assets/css/base/gutenberg-blocks.css', '', $storefront_version ); + wp_style_add_data( 'storefront-gutenberg-blocks', 'rtl', 'replace' ); + } + + /** + * Enqueue supplemental block editor assets. + * + * @since 2.4.0 + */ + public function block_editor_assets() { + global $storefront_version; + + // JS. + $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; + wp_enqueue_script( 'storefront-editor', get_template_directory_uri() . '/assets/js/editor' . $suffix . '.js', array( 'wp-data', 'wp-dom-ready', 'wp-edit-post' ), $storefront_version, true ); + } + + /** + * Enqueue child theme stylesheet. + * A separate function is required as the child theme css needs to be enqueued _after_ the parent theme + * primary css and the separate WooCommerce css. + * + * @since 1.5.3 + */ + public function child_scripts() { + if ( is_child_theme() ) { + $child_theme = wp_get_theme( get_stylesheet() ); + wp_enqueue_style( 'storefront-child-style', get_stylesheet_uri(), array(), $child_theme->get( 'Version' ) ); + } + } + + /** + * Get our wp_nav_menu() fallback, wp_page_menu(), to show a home link. + * + * @param array $args Configuration arguments. + * @return array + */ + public function page_menu_args( $args ) { + $args['show_home'] = true; + return $args; + } + + /** + * Adds custom classes to the array of body classes. + * + * @param array $classes Classes for the body element. + * @return array + */ + public function body_classes( $classes ) { + // Adds a class to blogs with more than 1 published author. + if ( is_multi_author() ) { + $classes[] = 'group-blog'; + } + + /** + * Adds a class when WooCommerce is not active. + * + * @todo Refactor child themes to remove dependency on this class. + */ + $classes[] = 'no-wc-breadcrumb'; + + /** + * What is this?! + * Take the blue pill, close this file and forget you saw the following code. + * Or take the red pill, filter storefront_make_me_cute and see how deep the rabbit hole goes... + */ + $cute = apply_filters( 'storefront_make_me_cute', false ); + + if ( true === $cute ) { + $classes[] = 'storefront-cute'; + } + + // If our main sidebar doesn't contain widgets, adjust the layout to be full-width. + if ( ! is_active_sidebar( 'sidebar-1' ) ) { + $classes[] = 'storefront-full-width-content'; + } + + // Add class when using homepage template + featured image. + if ( is_page_template( 'template-homepage.php' ) && has_post_thumbnail() ) { + $classes[] = 'has-post-thumbnail'; + } + + // Add class when Secondary Navigation is in use. + if ( has_nav_menu( 'secondary' ) ) { + $classes[] = 'storefront-secondary-navigation'; + } + + // Add class if align-wide is supported. + if ( current_theme_supports( 'align-wide' ) ) { + $classes[] = 'storefront-align-wide'; + } + + return $classes; + } + + /** + * Adds a custom parameter to the editor settings that is used + * to track whether the main sidebar has widgets. + * + * @since 2.4.3 + * @param array $settings Default editor settings. + * @param WP_Post $post Post being edited. + * + * @return array Filtered block editor settings. + */ + public function custom_editor_settings( $settings, $post ) { + $settings['mainSidebarActive'] = false; + + if ( is_active_sidebar( 'sidebar-1' ) ) { + $settings['mainSidebarActive'] = true; + } + + return $settings; + } + + /** + * Custom navigation markup template hooked into `navigation_markup_template` filter hook. + */ + public function navigation_markup_template() { + $template = ''; + + return apply_filters( 'storefront_navigation_markup_template', $template ); + } + + /** + * Add styles for embeds + */ + public function print_embed_styles() { + global $storefront_version; + + wp_enqueue_style( 'source-sans-pro', '//fonts.googleapis.com/css?family=Source+Sans+Pro:400,300,300italic,400italic,700,900', array(), $storefront_version ); + $accent_color = get_theme_mod( 'storefront_accent_color' ); + $background_color = storefront_get_content_background_color(); + ?> + + type ) { + default: + case 'text': + echo '

    ' . wp_kses_post( $this->description ) . '

    '; + break; + + case 'heading': + echo '' . esc_html( $this->label ) . ''; + break; + + case 'divider': + echo '
    '; + break; + } + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/customizer/class-storefront-customizer-control-more.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/customizer/class-storefront-customizer-control-more.php new file mode 100644 index 0000000..64bc9da --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/customizer/class-storefront-customizer-control-more.php @@ -0,0 +1,50 @@ + + + choices ) ) { + return; + } + + $name = '_customize-radio-' . $this->id; ?> + + + label ); ?> + + + description ) ) : ?> + description ); ?> + + +
    + choices as $value => $label ) : ?> + link(); + checked( $this->value(), $value ); + ?> + > + + + +
    + + + '#333333', + 'storefront_text_color' => '#6d6d6d', + 'storefront_accent_color' => '#96588a', + 'storefront_hero_heading_color' => '#000000', + 'storefront_hero_text_color' => '#000000', + 'storefront_header_background_color' => '#ffffff', + 'storefront_header_text_color' => '#404040', + 'storefront_header_link_color' => '#333333', + 'storefront_footer_background_color' => '#f0f0f0', + 'storefront_footer_heading_color' => '#333333', + 'storefront_footer_text_color' => '#6d6d6d', + 'storefront_footer_link_color' => '#333333', + 'storefront_button_background_color' => '#eeeeee', + 'storefront_button_text_color' => '#333333', + 'storefront_button_alt_background_color' => '#333333', + 'storefront_button_alt_text_color' => '#ffffff', + 'storefront_layout' => 'right', + 'background_color' => 'ffffff', + ) + ); + } + + /** + * Adds a value to each Storefront setting if one isn't already present. + * + * @uses get_storefront_default_setting_values() + */ + public function default_theme_mod_values() { + foreach ( $this->get_storefront_default_setting_values() as $mod => $val ) { + add_filter( 'theme_mod_' . $mod, array( $this, 'get_theme_mod_value' ), 10 ); + } + } + + /** + * Get theme mod value. + * + * @param string $value Theme modification value. + * @return string + */ + public function get_theme_mod_value( $value ) { + $key = substr( current_filter(), 10 ); + + $set_theme_mods = get_theme_mods(); + + if ( isset( $set_theme_mods[ $key ] ) ) { + return $value; + } + + $values = $this->get_storefront_default_setting_values(); + + return isset( $values[ $key ] ) ? $values[ $key ] : $value; + } + + /** + * Set Customizer setting defaults. + * These defaults need to be applied separately as child themes can filter storefront_setting_default_values + * + * @param array $wp_customize the Customizer object. + * @uses get_storefront_default_setting_values() + */ + public function edit_default_customizer_settings( $wp_customize ) { + foreach ( $this->get_storefront_default_setting_values() as $mod => $val ) { + $wp_customize->get_setting( $mod )->default = $val; + } + } + + /** + * Add postMessage support for site title and description for the Theme Customizer along with several other settings. + * + * @param WP_Customize_Manager $wp_customize Theme Customizer object. + * @since 1.0.0 + */ + public function customize_register( $wp_customize ) { + + // Move background color setting alongside background image. + $wp_customize->get_control( 'background_color' )->section = 'background_image'; + $wp_customize->get_control( 'background_color' )->priority = 20; + + // Change background image section title & priority. + $wp_customize->get_section( 'background_image' )->title = __( 'Background', 'storefront' ); + $wp_customize->get_section( 'background_image' )->priority = 30; + + // Change header image section title & priority. + $wp_customize->get_section( 'header_image' )->title = __( 'Header', 'storefront' ); + $wp_customize->get_section( 'header_image' )->priority = 25; + + // Selective refresh. + if ( function_exists( 'add_partial' ) ) { + $wp_customize->get_setting( 'blogname' )->transport = 'postMessage'; + $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage'; + + $wp_customize->selective_refresh->add_partial( + 'custom_logo', + array( + 'selector' => '.site-branding', + 'render_callback' => array( $this, 'get_site_logo' ), + ) + ); + + $wp_customize->selective_refresh->add_partial( + 'blogname', + array( + 'selector' => '.site-title.beta a', + 'render_callback' => array( $this, 'get_site_name' ), + ) + ); + + $wp_customize->selective_refresh->add_partial( + 'blogdescription', + array( + 'selector' => '.site-description', + 'render_callback' => array( $this, 'get_site_description' ), + ) + ); + } + + /** + * Custom controls + */ + require_once dirname( __FILE__ ) . '/class-storefront-customizer-control-radio-image.php'; + require_once dirname( __FILE__ ) . '/class-storefront-customizer-control-arbitrary.php'; + + if ( apply_filters( 'storefront_customizer_more', true ) ) { + require_once dirname( __FILE__ ) . '/class-storefront-customizer-control-more.php'; + } + + /** + * Add the typography section + */ + $wp_customize->add_section( + 'storefront_typography', + array( + 'title' => __( 'Typography', 'storefront' ), + 'priority' => 45, + ) + ); + + /** + * Heading color + */ + $wp_customize->add_setting( + 'storefront_heading_color', + array( + 'default' => apply_filters( 'storefront_default_heading_color', '#484c51' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_heading_color', + array( + 'label' => __( 'Heading color', 'storefront' ), + 'section' => 'storefront_typography', + 'settings' => 'storefront_heading_color', + 'priority' => 20, + ) + ) + ); + + /** + * Text Color + */ + $wp_customize->add_setting( + 'storefront_text_color', + array( + 'default' => apply_filters( 'storefront_default_text_color', '#43454b' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_text_color', + array( + 'label' => __( 'Text color', 'storefront' ), + 'section' => 'storefront_typography', + 'settings' => 'storefront_text_color', + 'priority' => 30, + ) + ) + ); + + /** + * Accent Color + */ + $wp_customize->add_setting( + 'storefront_accent_color', + array( + 'default' => apply_filters( 'storefront_default_accent_color', '#96588a' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_accent_color', + array( + 'label' => __( 'Link / accent color', 'storefront' ), + 'section' => 'storefront_typography', + 'settings' => 'storefront_accent_color', + 'priority' => 40, + ) + ) + ); + + /** + * Hero Heading Color + */ + $wp_customize->add_setting( + 'storefront_hero_heading_color', + array( + 'default' => apply_filters( 'storefront_default_hero_heading_color', '#000000' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_hero_heading_color', + array( + 'label' => __( 'Hero heading color', 'storefront' ), + 'section' => 'storefront_typography', + 'settings' => 'storefront_hero_heading_color', + 'priority' => 50, + ) + ) + ); + + /** + * Hero Text Color + */ + $wp_customize->add_setting( + 'storefront_hero_text_color', + array( + 'default' => apply_filters( 'storefront_default_hero_text_color', '#000000' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_hero_text_color', + array( + 'label' => __( 'Hero text color', 'storefront' ), + 'section' => 'storefront_typography', + 'settings' => 'storefront_hero_text_color', + 'priority' => 60, + ) + ) + ); + + $wp_customize->add_control( + new Arbitrary_Storefront_Control( + $wp_customize, + 'storefront_header_image_heading', + array( + 'section' => 'header_image', + 'type' => 'heading', + 'label' => __( 'Header background image', 'storefront' ), + 'priority' => 6, + ) + ) + ); + + /** + * Header Background + */ + $wp_customize->add_setting( + 'storefront_header_background_color', + array( + 'default' => apply_filters( 'storefront_default_header_background_color', '#2c2d33' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_header_background_color', + array( + 'label' => __( 'Background color', 'storefront' ), + 'section' => 'header_image', + 'settings' => 'storefront_header_background_color', + 'priority' => 15, + ) + ) + ); + + /** + * Header text color + */ + $wp_customize->add_setting( + 'storefront_header_text_color', + array( + 'default' => apply_filters( 'storefront_default_header_text_color', '#9aa0a7' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_header_text_color', + array( + 'label' => __( 'Text color', 'storefront' ), + 'section' => 'header_image', + 'settings' => 'storefront_header_text_color', + 'priority' => 20, + ) + ) + ); + + /** + * Header link color + */ + $wp_customize->add_setting( + 'storefront_header_link_color', + array( + 'default' => apply_filters( 'storefront_default_header_link_color', '#d5d9db' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_header_link_color', + array( + 'label' => __( 'Link color', 'storefront' ), + 'section' => 'header_image', + 'settings' => 'storefront_header_link_color', + 'priority' => 30, + ) + ) + ); + + /** + * Footer section + */ + $wp_customize->add_section( + 'storefront_footer', + array( + 'title' => __( 'Footer', 'storefront' ), + 'priority' => 28, + 'description' => __( 'Customize the look & feel of your website footer.', 'storefront' ), + ) + ); + + /** + * Footer Background + */ + $wp_customize->add_setting( + 'storefront_footer_background_color', + array( + 'default' => apply_filters( 'storefront_default_footer_background_color', '#f0f0f0' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_footer_background_color', + array( + 'label' => __( 'Background color', 'storefront' ), + 'section' => 'storefront_footer', + 'settings' => 'storefront_footer_background_color', + 'priority' => 10, + ) + ) + ); + + /** + * Footer heading color + */ + $wp_customize->add_setting( + 'storefront_footer_heading_color', + array( + 'default' => apply_filters( 'storefront_default_footer_heading_color', '#494c50' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_footer_heading_color', + array( + 'label' => __( 'Heading color', 'storefront' ), + 'section' => 'storefront_footer', + 'settings' => 'storefront_footer_heading_color', + 'priority' => 20, + ) + ) + ); + + /** + * Footer text color + */ + $wp_customize->add_setting( + 'storefront_footer_text_color', + array( + 'default' => apply_filters( 'storefront_default_footer_text_color', '#61656b' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_footer_text_color', + array( + 'label' => __( 'Text color', 'storefront' ), + 'section' => 'storefront_footer', + 'settings' => 'storefront_footer_text_color', + 'priority' => 30, + ) + ) + ); + + /** + * Footer link color + */ + $wp_customize->add_setting( + 'storefront_footer_link_color', + array( + 'default' => apply_filters( 'storefront_default_footer_link_color', '#2c2d33' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_footer_link_color', + array( + 'label' => __( 'Link color', 'storefront' ), + 'section' => 'storefront_footer', + 'settings' => 'storefront_footer_link_color', + 'priority' => 40, + ) + ) + ); + + /** + * Buttons section + */ + $wp_customize->add_section( + 'storefront_buttons', + array( + 'title' => __( 'Buttons', 'storefront' ), + 'priority' => 45, + 'description' => __( 'Customize the look & feel of your website buttons.', 'storefront' ), + ) + ); + + /** + * Button background color + */ + $wp_customize->add_setting( + 'storefront_button_background_color', + array( + 'default' => apply_filters( 'storefront_default_button_background_color', '#96588a' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_button_background_color', + array( + 'label' => __( 'Background color', 'storefront' ), + 'section' => 'storefront_buttons', + 'settings' => 'storefront_button_background_color', + 'priority' => 10, + ) + ) + ); + + /** + * Button text color + */ + $wp_customize->add_setting( + 'storefront_button_text_color', + array( + 'default' => apply_filters( 'storefront_default_button_text_color', '#ffffff' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_button_text_color', + array( + 'label' => __( 'Text color', 'storefront' ), + 'section' => 'storefront_buttons', + 'settings' => 'storefront_button_text_color', + 'priority' => 20, + ) + ) + ); + + /** + * Button alt background color + */ + $wp_customize->add_setting( + 'storefront_button_alt_background_color', + array( + 'default' => apply_filters( 'storefront_default_button_alt_background_color', '#2c2d33' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_button_alt_background_color', + array( + 'label' => __( 'Alternate button background color', 'storefront' ), + 'section' => 'storefront_buttons', + 'settings' => 'storefront_button_alt_background_color', + 'priority' => 30, + ) + ) + ); + + /** + * Button alt text color + */ + $wp_customize->add_setting( + 'storefront_button_alt_text_color', + array( + 'default' => apply_filters( 'storefront_default_button_alt_text_color', '#ffffff' ), + 'sanitize_callback' => 'sanitize_hex_color', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Color_Control( + $wp_customize, + 'storefront_button_alt_text_color', + array( + 'label' => __( 'Alternate button text color', 'storefront' ), + 'section' => 'storefront_buttons', + 'settings' => 'storefront_button_alt_text_color', + 'priority' => 40, + ) + ) + ); + + /** + * Layout + */ + $wp_customize->add_section( + 'storefront_layout', + array( + 'title' => __( 'Layout', 'storefront' ), + 'priority' => 50, + ) + ); + + $wp_customize->add_setting( + 'storefront_layout', + array( + 'default' => apply_filters( 'storefront_default_layout', $layout = is_rtl() ? 'left' : 'right' ), + 'sanitize_callback' => 'storefront_sanitize_choices', + ) + ); + + $wp_customize->add_control( + new Storefront_Custom_Radio_Image_Control( + $wp_customize, + 'storefront_layout', + array( + 'settings' => 'storefront_layout', + 'section' => 'storefront_layout', + 'label' => __( 'General Layout', 'storefront' ), + 'priority' => 1, + 'choices' => array( + 'right' => get_template_directory_uri() . '/assets/images/customizer/controls/2cr.png', + 'left' => get_template_directory_uri() . '/assets/images/customizer/controls/2cl.png', + ), + ) + ) + ); + + /** + * More + */ + if ( apply_filters( 'storefront_customizer_more', true ) ) { + $wp_customize->add_section( + 'storefront_more', + array( + 'title' => __( 'More', 'storefront' ), + 'priority' => 999, + ) + ); + + $wp_customize->add_setting( + 'storefront_more', + array( + 'default' => null, + 'sanitize_callback' => 'sanitize_text_field', + ) + ); + + $wp_customize->add_control( + new More_Storefront_Control( + $wp_customize, + 'storefront_more', + array( + 'label' => __( 'Looking for more options?', 'storefront' ), + 'section' => 'storefront_more', + 'settings' => 'storefront_more', + 'priority' => 1, + ) + ) + ); + } + } + + /** + * Get all of the Storefront theme mods. + * + * @return array $storefront_theme_mods The Storefront Theme Mods. + */ + public function get_storefront_theme_mods() { + $storefront_theme_mods = array( + 'background_color' => storefront_get_content_background_color(), + 'accent_color' => get_theme_mod( 'storefront_accent_color' ), + 'hero_heading_color' => get_theme_mod( 'storefront_hero_heading_color' ), + 'hero_text_color' => get_theme_mod( 'storefront_hero_text_color' ), + 'header_background_color' => get_theme_mod( 'storefront_header_background_color' ), + 'header_link_color' => get_theme_mod( 'storefront_header_link_color' ), + 'header_text_color' => get_theme_mod( 'storefront_header_text_color' ), + 'footer_background_color' => get_theme_mod( 'storefront_footer_background_color' ), + 'footer_link_color' => get_theme_mod( 'storefront_footer_link_color' ), + 'footer_heading_color' => get_theme_mod( 'storefront_footer_heading_color' ), + 'footer_text_color' => get_theme_mod( 'storefront_footer_text_color' ), + 'text_color' => get_theme_mod( 'storefront_text_color' ), + 'heading_color' => get_theme_mod( 'storefront_heading_color' ), + 'button_background_color' => get_theme_mod( 'storefront_button_background_color' ), + 'button_text_color' => get_theme_mod( 'storefront_button_text_color' ), + 'button_alt_background_color' => get_theme_mod( 'storefront_button_alt_background_color' ), + 'button_alt_text_color' => get_theme_mod( 'storefront_button_alt_text_color' ), + ); + + return apply_filters( 'storefront_theme_mods', $storefront_theme_mods ); + } + + /** + * Get Customizer css. + * + * @see get_storefront_theme_mods() + * @return array $styles the css + */ + public function get_css() { + $storefront_theme_mods = $this->get_storefront_theme_mods(); + $brighten_factor = apply_filters( 'storefront_brighten_factor', 25 ); + $darken_factor = apply_filters( 'storefront_darken_factor', -25 ); + + $styles = ' + .main-navigation ul li a, + .site-title a, + ul.menu li a, + .site-branding h1 a, + button.menu-toggle, + button.menu-toggle:hover, + .handheld-navigation .dropdown-toggle { + color: ' . $storefront_theme_mods['header_link_color'] . '; + } + + button.menu-toggle, + button.menu-toggle:hover { + border-color: ' . $storefront_theme_mods['header_link_color'] . '; + } + + .main-navigation ul li a:hover, + .main-navigation ul li:hover > a, + .site-title a:hover, + .site-header ul.menu li.current-menu-item > a { + color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['header_link_color'], 65 ) . '; + } + + table:not( .has-background ) th { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -7 ) . '; + } + + table:not( .has-background ) tbody td { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -2 ) . '; + } + + table:not( .has-background ) tbody tr:nth-child(2n) td, + fieldset, + fieldset legend { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -4 ) . '; + } + + .site-header, + .secondary-navigation ul ul, + .main-navigation ul.menu > li.menu-item-has-children:after, + .secondary-navigation ul.menu ul, + .storefront-handheld-footer-bar, + .storefront-handheld-footer-bar ul li > a, + .storefront-handheld-footer-bar ul li.search .site-search, + button.menu-toggle, + button.menu-toggle:hover { + background-color: ' . $storefront_theme_mods['header_background_color'] . '; + } + + p.site-description, + .site-header, + .storefront-handheld-footer-bar { + color: ' . $storefront_theme_mods['header_text_color'] . '; + } + + button.menu-toggle:after, + button.menu-toggle:before, + button.menu-toggle span:before { + background-color: ' . $storefront_theme_mods['header_link_color'] . '; + } + + h1, h2, h3, h4, h5, h6, .wc-block-grid__product-title { + color: ' . $storefront_theme_mods['heading_color'] . '; + } + + .widget h1 { + border-bottom-color: ' . $storefront_theme_mods['heading_color'] . '; + } + + body, + .secondary-navigation a { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + .widget-area .widget a, + .hentry .entry-header .posted-on a, + .hentry .entry-header .post-author a, + .hentry .entry-header .post-comments a, + .hentry .entry-header .byline a { + color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['text_color'], 5 ) . '; + } + + a { + color: ' . $storefront_theme_mods['accent_color'] . '; + } + + a:focus, + button:focus, + .button.alt:focus, + input:focus, + textarea:focus, + input[type="button"]:focus, + input[type="reset"]:focus, + input[type="submit"]:focus, + input[type="email"]:focus, + input[type="tel"]:focus, + input[type="url"]:focus, + input[type="password"]:focus, + input[type="search"]:focus { + outline-color: ' . $storefront_theme_mods['accent_color'] . '; + } + + button, input[type="button"], input[type="reset"], input[type="submit"], .button, .widget a.button { + background-color: ' . $storefront_theme_mods['button_background_color'] . '; + border-color: ' . $storefront_theme_mods['button_background_color'] . '; + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + button:hover, input[type="button"]:hover, input[type="reset"]:hover, input[type="submit"]:hover, .button:hover, .widget a.button:hover { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_background_color'], $darken_factor ) . '; + border-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_background_color'], $darken_factor ) . '; + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + button.alt, input[type="button"].alt, input[type="reset"].alt, input[type="submit"].alt, .button.alt, .widget-area .widget a.button.alt { + background-color: ' . $storefront_theme_mods['button_alt_background_color'] . '; + border-color: ' . $storefront_theme_mods['button_alt_background_color'] . '; + color: ' . $storefront_theme_mods['button_alt_text_color'] . '; + } + + button.alt:hover, input[type="button"].alt:hover, input[type="reset"].alt:hover, input[type="submit"].alt:hover, .button.alt:hover, .widget-area .widget a.button.alt:hover { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_alt_background_color'], $darken_factor ) . '; + border-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_alt_background_color'], $darken_factor ) . '; + color: ' . $storefront_theme_mods['button_alt_text_color'] . '; + } + + .pagination .page-numbers li .page-numbers.current { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], $darken_factor ) . '; + color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['text_color'], -10 ) . '; + } + + #comments .comment-list .comment-content .comment-text { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -7 ) . '; + } + + .site-footer { + background-color: ' . $storefront_theme_mods['footer_background_color'] . '; + color: ' . $storefront_theme_mods['footer_text_color'] . '; + } + + .site-footer a:not(.button):not(.components-button) { + color: ' . $storefront_theme_mods['footer_link_color'] . '; + } + + .site-footer .storefront-handheld-footer-bar a:not(.button):not(.components-button) { + color: ' . $storefront_theme_mods['header_link_color'] . '; + } + + .site-footer h1, .site-footer h2, .site-footer h3, .site-footer h4, .site-footer h5, .site-footer h6, .site-footer .widget .widget-title, .site-footer .widget .widgettitle { + color: ' . $storefront_theme_mods['footer_heading_color'] . '; + } + + .page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-title { + color: ' . $storefront_theme_mods['hero_heading_color'] . '; + } + + .page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-content { + color: ' . $storefront_theme_mods['hero_text_color'] . '; + } + + @media screen and ( min-width: 768px ) { + .secondary-navigation ul.menu a:hover { + color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['header_text_color'], $brighten_factor ) . '; + } + + .secondary-navigation ul.menu a { + color: ' . $storefront_theme_mods['header_text_color'] . '; + } + + .main-navigation ul.menu ul.sub-menu, + .main-navigation ul.nav-menu ul.children { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['header_background_color'], -15 ) . '; + } + + .site-header { + border-bottom-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['header_background_color'], -15 ) . '; + } + }'; + + return apply_filters( 'storefront_customizer_css', $styles ); + } + + /** + * Get Gutenberg Customizer css. + * + * @see get_storefront_theme_mods() + * @return array $styles the css + */ + public function gutenberg_get_css() { + $storefront_theme_mods = $this->get_storefront_theme_mods(); + $darken_factor = apply_filters( 'storefront_darken_factor', -25 ); + + // Gutenberg. + $styles = ' + .wp-block-button__link:not(.has-text-color) { + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + .wp-block-button__link:not(.has-text-color):hover, + .wp-block-button__link:not(.has-text-color):focus, + .wp-block-button__link:not(.has-text-color):active { + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + .wp-block-button__link:not(.has-background) { + background-color: ' . $storefront_theme_mods['button_background_color'] . '; + } + + .wp-block-button__link:not(.has-background):hover, + .wp-block-button__link:not(.has-background):focus, + .wp-block-button__link:not(.has-background):active { + border-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_background_color'], $darken_factor ) . '; + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_background_color'], $darken_factor ) . '; + } + + .wp-block-quote footer, + .wp-block-quote cite, + .wp-block-quote__citation { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + .wp-block-pullquote cite, + .wp-block-pullquote footer, + .wp-block-pullquote__citation { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + .wp-block-image figcaption { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + .wp-block-separator.is-style-dots::before { + color: ' . $storefront_theme_mods['heading_color'] . '; + } + + .wp-block-file a.wp-block-file__button { + color: ' . $storefront_theme_mods['button_text_color'] . '; + background-color: ' . $storefront_theme_mods['button_background_color'] . '; + border-color: ' . $storefront_theme_mods['button_background_color'] . '; + } + + .wp-block-file a.wp-block-file__button:hover, + .wp-block-file a.wp-block-file__button:focus, + .wp-block-file a.wp-block-file__button:active { + color: ' . $storefront_theme_mods['button_text_color'] . '; + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_background_color'], $darken_factor ) . '; + } + + .wp-block-code, + .wp-block-preformatted pre { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + .wp-block-table:not( .has-background ):not( .is-style-stripes ) tbody tr:nth-child(2n) td { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -2 ) . '; + } + + .wp-block-cover .wp-block-cover__inner-container h1:not(.has-text-color), + .wp-block-cover .wp-block-cover__inner-container h2:not(.has-text-color), + .wp-block-cover .wp-block-cover__inner-container h3:not(.has-text-color), + .wp-block-cover .wp-block-cover__inner-container h4:not(.has-text-color), + .wp-block-cover .wp-block-cover__inner-container h5:not(.has-text-color), + .wp-block-cover .wp-block-cover__inner-container h6:not(.has-text-color) { + color: ' . $storefront_theme_mods['hero_heading_color'] . '; + } + + .wc-block-components-price-slider__range-input-progress, + .rtl .wc-block-components-price-slider__range-input-progress { + --range-color: ' . $storefront_theme_mods['accent_color'] . '; + } + + /* Target only IE11 */ + @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { + .wc-block-components-price-slider__range-input-progress { + background: ' . $storefront_theme_mods['accent_color'] . '; + } + } + + .wc-block-components-button:not(.is-link) { + background-color: ' . $storefront_theme_mods['button_alt_background_color'] . '; + color: ' . $storefront_theme_mods['button_alt_text_color'] . '; + } + + .wc-block-components-button:not(.is-link):hover, + .wc-block-components-button:not(.is-link):focus, + .wc-block-components-button:not(.is-link):active { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_alt_background_color'], $darken_factor ) . '; + color: ' . $storefront_theme_mods['button_alt_text_color'] . '; + } + + .wc-block-components-button:not(.is-link):disabled { + background-color: ' . $storefront_theme_mods['button_alt_background_color'] . '; + color: ' . $storefront_theme_mods['button_alt_text_color'] . '; + } + + .wc-block-cart__submit-container { + background-color: ' . $storefront_theme_mods['background_color'] . '; + } + + .wc-block-cart__submit-container::before { + color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], is_color_light( $storefront_theme_mods['background_color'] ) ? -35 : 70, 0.5 ) . '; + } + + .wc-block-components-order-summary-item__quantity { + background-color: ' . $storefront_theme_mods['background_color'] . '; + border-color: ' . $storefront_theme_mods['text_color'] . '; + box-shadow: 0 0 0 2px ' . $storefront_theme_mods['background_color'] . '; + color: ' . $storefront_theme_mods['text_color'] . '; + } + '; + + return apply_filters( 'storefront_gutenberg_customizer_css', $styles ); + } + + /** + * Enqueue dynamic colors to use editor blocks. + * + * @since 2.4.0 + */ + public function block_editor_customizer_css() { + $storefront_theme_mods = $this->get_storefront_theme_mods(); + + $styles = ''; + + if ( is_admin() ) { + $styles .= ' + .editor-styles-wrapper { + background-color: ' . $storefront_theme_mods['background_color'] . '; + } + + .editor-styles-wrapper table:not( .has-background ) th { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -7 ) . '; + } + + .editor-styles-wrapper table:not( .has-background ) tbody td { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -2 ) . '; + } + + .editor-styles-wrapper table:not( .has-background ) tbody tr:nth-child(2n) td, + .editor-styles-wrapper fieldset, + .editor-styles-wrapper fieldset legend { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -4 ) . '; + } + + .editor-post-title__block .editor-post-title__input, + .editor-styles-wrapper h1, + .editor-styles-wrapper h2, + .editor-styles-wrapper h3, + .editor-styles-wrapper h4, + .editor-styles-wrapper h5, + .editor-styles-wrapper h6 { + color: ' . $storefront_theme_mods['heading_color'] . '; + } + + /* WP <=5.3 */ + .editor-styles-wrapper .editor-block-list__block, + /* WP >=5.4 */ + .editor-styles-wrapper .block-editor-block-list__block { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + .editor-styles-wrapper a, + .wp-block-freeform.block-library-rich-text__tinymce a { + color: ' . $storefront_theme_mods['accent_color'] . '; + } + + .editor-styles-wrapper a:focus, + .wp-block-freeform.block-library-rich-text__tinymce a:focus { + outline-color: ' . $storefront_theme_mods['accent_color'] . '; + } + + body.post-type-post .editor-post-title__block::after { + content: ""; + }'; + } + + $styles .= $this->gutenberg_get_css(); + + wp_add_inline_style( 'storefront-gutenberg-blocks', apply_filters( 'storefront_gutenberg_block_editor_customizer_css', $styles ) ); + } + + /** + * Add CSS in for styles handled by the theme customizer + * + * @since 1.0.0 + * @return void + */ + public function add_customizer_css() { + wp_add_inline_style( 'storefront-style', $this->get_css() ); + } + + /** + * Layout classes + * Adds 'right-sidebar' and 'left-sidebar' classes to the body tag + * + * @param array $classes current body classes. + * @return string[] modified body classes + * @since 1.0.0 + */ + public function layout_class( $classes ) { + $left_or_right = get_theme_mod( 'storefront_layout' ); + + $classes[] = $left_or_right . '-sidebar'; + + return $classes; + } + + /** + * Add CSS for custom controls + * + * This function incorporates CSS from the Kirki Customizer Framework + * + * The Kirki Customizer Framework, Copyright Aristeides Stathopoulos (@aristath), + * is licensed under the terms of the GNU GPL, Version 2 (or later) + * + * @link https://github.com/reduxframework/kirki/ + * @since 1.5.0 + */ + public function customizer_custom_control_css() { + ?> + + 'main', + 'footer' => 'page', + 'render' => array( $this, 'jetpack_infinite_scroll_loop' ), + 'footer_widgets' => array( + 'footer-1', + 'footer-2', + 'footer-3', + 'footer-4', + ), + ) + ) + ); + } + + /** + * A loop used to display content appended using Jetpack infinite scroll + * + * @return void + */ + public function jetpack_infinite_scroll_loop() { + do_action( 'storefront_jetpack_infinite_scroll_before' ); + + if ( function_exists( 'storefront_is_product_archive' ) && storefront_is_product_archive() ) { + do_action( 'storefront_jetpack_product_infinite_scroll_before' ); + woocommerce_product_loop_start(); + } + + while ( have_posts() ) : + the_post(); + if ( function_exists( 'storefront_is_product_archive' ) && storefront_is_product_archive() ) { + wc_get_template_part( 'content', 'product' ); + } else { + get_template_part( 'content', get_post_format() ); + } + endwhile; // end of the loop. + + if ( function_exists( 'storefront_is_product_archive' ) && storefront_is_product_archive() ) { + woocommerce_product_loop_end(); + do_action( 'storefront_jetpack_product_infinite_scroll_after' ); + } + + do_action( 'storefront_jetpack_infinite_scroll_after' ); + } + + /** + * Adds columns wrapper to content appended by Jetpack infinite scroll + * + * @return void + */ + public function jetpack_infinite_scroll_wrapper_columns() { + add_action( 'storefront_jetpack_product_infinite_scroll_before', 'storefront_product_columns_wrapper' ); + add_action( 'storefront_jetpack_product_infinite_scroll_after', 'storefront_product_columns_wrapper_close' ); + } + + /** + * Enqueue jetpack styles. + * + * @since 1.6.1 + */ + public function jetpack_scripts() { + global $storefront_version; + + if ( wp_style_is( 'the-neverending-homepage', 'enqueued' ) ) { + wp_enqueue_style( 'storefront-jetpack-infinite-scroll', get_template_directory_uri() . '/assets/css/jetpack/infinite-scroll.css', array( 'the-neverending-homepage' ), $storefront_version ); + wp_style_add_data( 'storefront-jetpack-infinite-scroll', 'rtl', 'replace' ); + } + + wp_enqueue_style( 'storefront-jetpack-widgets', get_template_directory_uri() . '/assets/css/jetpack/widgets.css', array(), $storefront_version ); + wp_style_add_data( 'storefront-jetpack-widgets', 'rtl', 'replace' ); + } + } + +endif; + +return new Storefront_Jetpack(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/nux/class-storefront-nux-admin.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/nux/class-storefront-nux-admin.php new file mode 100644 index 0000000..a614b7b --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/nux/class-storefront-nux-admin.php @@ -0,0 +1,315 @@ + wp_create_nonce( 'storefront_notice_dismiss' ), + ); + + wp_localize_script( 'storefront-admin-nux', 'storefrontNUX', $storefront_nux ); + } + + /** + * Output admin notices. + * + * @since 2.2.0 + */ + public function admin_notices() { + global $pagenow; + + if ( true === (bool) get_option( 'storefront_nux_dismissed' ) ) { + return; + } + + // Coming from the WooCommerce Wizard? + if ( wp_get_referer() && 0 === strpos( basename( wp_get_referer() ), 'index.php?page=wc-setup' ) && 'post-new.php' === $pagenow ) { + return; + } + ?> + +
    + + '; ?> + + +
    + +

    +

    +

    + + + +

    +

    + +

    +
    + + + + + + + + _is_woocommerce_empty() ) : ?> + + + + + + + _is_woocommerce_empty() ) : ?> + + + + + +
    + +
    +
    + '1' ); + + $tasks = array(); + + if ( ! empty( $_REQUEST['homepage'] ) && 'on' === sanitize_text_field( wp_unslash( $_REQUEST['homepage'] ) ) ) { // WPCS: input var ok. + if ( current_user_can( 'edit_pages' ) && 'page' === get_option( 'show_on_front' ) ) { + $this->_assign_page_template( get_option( 'page_on_front' ), 'template-homepage.php' ); + } else { + $tasks[] = 'homepage'; + } + } + + if ( ! empty( $_REQUEST['products'] ) && 'on' === sanitize_text_field( wp_unslash( $_REQUEST['products'] ) ) ) { // WPCS: input var ok. + $tasks[] = 'products'; + } + + if ( ! empty( $tasks ) ) { + $args['sf_tasks'] = implode( ',', $tasks ); + + if ( current_user_can( 'manage_options' ) ) { + + // Make sure the fresh_site flag is set to true. + update_option( 'fresh_site', true ); + + if ( current_user_can( 'edit_pages' ) && true === (bool) get_option( 'storefront_nux_fresh_site' ) ) { + $this->_set_woocommerce_pages_full_width(); + } + } + } + + // Redirect to the Storefront Welcome screen when exiting the Customizer. + $args['return'] = rawurlencode( admin_url( 'themes.php?page=storefront-welcome' ) ); + + wp_safe_redirect( add_query_arg( $args, admin_url( 'customize.php' ) ) ); + + die(); + } + + /** + * Get WooCommerce page ids. + * + * @since 2.2.0 + */ + public static function get_woocommerce_pages() { + $woocommerce_pages = array(); + + $wc_pages_options = apply_filters( + 'storefront_page_option_names', + array( + 'woocommerce_cart_page_id', + 'woocommerce_checkout_page_id', + 'woocommerce_myaccount_page_id', + 'woocommerce_shop_page_id', + 'woocommerce_terms_page_id', + ) + ); + + foreach ( $wc_pages_options as $option ) { + $page_id = get_option( $option ); + + if ( ! empty( $page_id ) ) { + $page_id = intval( $page_id ); + + if ( null !== get_post( $page_id ) ) { + $woocommerce_pages[ $option ] = $page_id; + } + } + } + + return $woocommerce_pages; + } + + /** + * Update Storefront fresh site flag. + * + * @since 2.2.0 + */ + public function log_fresh_site_state() { + if ( null === get_option( 'storefront_nux_fresh_site', null ) ) { + update_option( 'storefront_nux_fresh_site', get_option( 'fresh_site' ) ); + } + } + + /** + * Add custom classes to the list of admin body classes. + * + * @since 2.2.0 + * @param string $classes Classes for the admin body element. + * @return string + */ + public function admin_body_class( $classes ) { + if ( true === (bool) get_option( 'storefront_nux_dismissed' ) ) { + return $classes; + } + + $classes .= ' sf-nux '; + + return $classes; + } + + /** + * Set WooCommerce pages to use the full width template. + * + * @since 2.2.0 + */ + private function _set_woocommerce_pages_full_width() { + $wc_pages = $this->get_woocommerce_pages(); + + foreach ( $wc_pages as $option => $page_id ) { + $this->_assign_page_template( $page_id, 'template-fullwidth.php' ); + } + } + + /** + * Given a page id assign a given page template to it. + * + * @since 2.2.0 + * @param int $page_id Page id. + * @param string $template Template file name. + * @return void|bool Returns false if $page_id or $template is empty. + */ + private function _assign_page_template( $page_id, $template ) { + if ( empty( $page_id ) || empty( $template ) || '' === locate_template( $template ) ) { + return false; + } + + update_post_meta( $page_id, '_wp_page_template', $template ); + } + + /** + * Check if WooCommerce is empty. + * + * @since 2.2.0 + * @return bool + */ + private function _is_woocommerce_empty() { + $products = wp_count_posts( 'product' ); + + if ( 0 < $products->publish ) { + return false; + } + + return true; + } + } + +endif; + +return new Storefront_NUX_Admin(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/nux/class-storefront-nux-guided-tour.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/nux/class-storefront-nux-guided-tour.php new file mode 100644 index 0000000..75313c1 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/nux/class-storefront-nux-guided-tour.php @@ -0,0 +1,156 @@ +guided_tour_steps() ); + } + + /** + * Template for steps. + * + * @since 2.2.0 + */ + public function print_templates() { + ?> + + __( 'Welcome to the Customizer', 'storefront' ), + /* translators: %s: 'End Of Line' symbol */ + 'message' => sprintf( __( 'Here you can control the overall look and feel of your store.%sTo get started, let\'s add your logo', 'storefront' ), PHP_EOL . PHP_EOL ), + 'button_text' => __( 'Let\'s go!', 'storefront' ), + 'section' => '#customize-info', + ); + + if ( ! has_custom_logo() ) { + $steps[] = array( + 'title' => __( 'Add your logo', 'storefront' ), + 'message' => __( 'Open the Site Identity Panel, then click the \'Select Logo\' button to upload your logo.', 'storefront' ), + 'section' => 'title_tagline', + ); + } + + $steps[] = array( + 'title' => __( 'Customize your navigation menus', 'storefront' ), + 'message' => __( 'Organize your menus by adding Pages, Categories, Tags, and Custom Links.', 'storefront' ), + 'section' => 'nav_menus', + ); + + $steps[] = array( + 'title' => __( 'Choose your accent color', 'storefront' ), + 'message' => __( 'In the typography panel you can specify an accent color which will be applied to things like links and star ratings. We recommend using your brand color for this setting.', 'storefront' ), + 'section' => 'storefront_typography', + ); + + $steps[] = array( + 'title' => __( 'Color your buttons', 'storefront' ), + 'message' => __( 'Choose colors for your button backgrounds and text. Once again, brand colors are good choices here.', 'storefront' ), + 'section' => 'storefront_buttons', + ); + + $steps[] = array( + 'title' => '', + /* translators: 1: open tag, 2: close tag, 3: 'End Of Line' symbol */ + 'message' => sprintf( __( 'All set! Remember to %1$ssave & publish%2$s your changes when you\'re done.%3$sYou can return to your dashboard by clicking the X in the top left corner.', 'storefront' ), '', '', PHP_EOL . PHP_EOL ), + 'section' => '#customize-header-actions .save', + 'button_text' => __( 'Done', 'storefront' ), + ); + + return $steps; + } + } + +endif; + +return new Storefront_NUX_Guided_Tour(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/nux/class-storefront-nux-starter-content.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/nux/class-storefront-nux-starter-content.php new file mode 100644 index 0000000..5d8a4fa --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/nux/class-storefront-nux-starter-content.php @@ -0,0 +1,1276 @@ +=' ) && + ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '3.6.0', '>=' ) ) ) { + add_action( 'customize_preview_init', array( $this, 'update_homepage_content' ), 10 ); + } + + if ( ! isset( $_GET['sf_starter_content'] ) || 1 !== absint( $_GET['sf_starter_content'] ) ) { // WPCS: input var ok. + add_filter( 'storefront_starter_content', '__return_empty_array' ); + } + } + + /** + * Remove default widgets on activation + * Set an option so that this is only done the first time the user activates Storefront. + * + * @since 2.2.0 + * @return void + */ + public function remove_default_widgets() { + if ( false === (bool) get_option( 'storefront_cleared_widgets' ) && true === (bool) get_option( 'storefront_nux_fresh_site' ) ) { + update_option( 'sidebars_widgets', array( 'wp_inactive_widgets' => array() ) ); + update_option( 'storefront_cleared_widgets', true ); + } + } + + /** + * Starter content. + * + * @since 2.2.0 + */ + public function starter_content() { + $starter_content = array( + 'posts' => array( + 'about' => array( + 'post_type' => 'page', + 'post_title' => __( 'About', 'storefront' ), + 'post_content' => __( 'You might be an artist who would like to introduce yourself and your work here or maybe you’re a business with a mission to describe.', 'storefront' ), + ), + 'contact' => array( + 'post_type' => 'page', + 'post_title' => __( 'Contact', 'storefront' ), + 'post_content' => __( 'This is a page with some basic contact information, such as an address and phone number. You might also try a plugin to add a contact form.', 'storefront' ), + ), + 'blog', + ), + 'attachments' => array( + 'beanie-image' => array( + 'post_title' => 'Beanie', + 'file' => 'assets/images/customizer/starter-content/products/beanie.jpg', + ), + 'belt-image' => array( + 'post_title' => 'Belt', + 'file' => 'assets/images/customizer/starter-content/products/belt.jpg', + ), + 'cap-image' => array( + 'post_title' => 'Cap', + 'file' => 'assets/images/customizer/starter-content/products/cap.jpg', + ), + 'hoodie-with-logo-image' => array( + 'post_title' => 'Hoodie with Logo', + 'file' => 'assets/images/customizer/starter-content/products/hoodie-with-logo.jpg', + ), + 'hoodie-with-pocket-image' => array( + 'post_title' => 'Hoodie with Pocket', + 'file' => 'assets/images/customizer/starter-content/products/hoodie-with-pocket.jpg', + ), + 'hoodie-with-zipper-image' => array( + 'post_title' => 'Hoodie with Zipper', + 'file' => 'assets/images/customizer/starter-content/products/hoodie-with-zipper.jpg', + ), + 'hoodie-image' => array( + 'post_title' => 'Hoodie', + 'file' => 'assets/images/customizer/starter-content/products/hoodie.jpg', + ), + 'long-sleeve-tee-image' => array( + 'post_title' => 'Long Sleeve Tee', + 'file' => 'assets/images/customizer/starter-content/products/long-sleeve-tee.jpg', + ), + 'polo-image' => array( + 'post_title' => 'Polo', + 'file' => 'assets/images/customizer/starter-content/products/polo.jpg', + ), + 'sunglasses-image' => array( + 'post_title' => 'Sunglasses', + 'file' => 'assets/images/customizer/starter-content/products/sunglasses.jpg', + ), + 'tshirt-image' => array( + 'post_title' => 'Tshirt', + 'file' => 'assets/images/customizer/starter-content/products/tshirt.jpg', + ), + 'vneck-tee-image' => array( + 'post_title' => 'Vneck Tshirt', + 'file' => 'assets/images/customizer/starter-content/products/vneck-tee.jpg', + ), + 'hero-image' => array( + 'post_title' => 'Hero', + 'file' => 'assets/images/customizer/starter-content/hero.jpg', + ), + 'accessories-image' => array( + 'post_title' => 'Accessories', + 'file' => 'assets/images/customizer/starter-content/categories/accessories.jpg', + ), + 'tshirts-image' => array( + 'post_title' => 'T-shirts', + 'file' => 'assets/images/customizer/starter-content/categories/tshirts.jpg', + ), + 'hoodies-image' => array( + 'post_title' => 'Hoodies', + 'file' => 'assets/images/customizer/starter-content/categories/hoodies.jpg', + ), + ), + 'options' => array( + 'show_on_front' => 'page', + 'page_on_front' => '{{home}}', + 'page_for_posts' => '{{blog}}', + ), + 'widgets' => array( + 'footer-1' => array( + 'text_about', + ), + 'footer-2' => array( + 'text_business_info', + ), + ), + 'nav_menus' => array( + 'primary' => array( + 'name' => __( 'Primary Menu', 'storefront' ), + 'items' => array( + 'shop' => array( + 'type' => 'post_type', + 'object' => 'page', + 'object_id' => '{{sf_shop}}', + ), + 'page_about' => array( + 'type' => 'post_type', + 'object' => 'page', + 'object_id' => '{{about}}', + ), + 'page_contact' => array( + 'type' => 'post_type', + 'object' => 'page', + 'object_id' => '{{contact}}', + ), + ), + ), + 'secondary' => array( + 'name' => __( 'Secondary Menu', 'storefront' ), + 'items' => array( + 'my_account' => array( + 'type' => 'post_type', + 'object' => 'page', + 'object_id' => '{{sf_my-account}}', + ), + ), + ), + 'handheld' => array( + 'name' => __( 'Handheld Menu', 'storefront' ), + 'items' => array( + 'shop' => array( + 'type' => 'post_type', + 'object' => 'page', + 'object_id' => '{{sf_shop}}', + ), + ), + ), + ), + ); + + // Add homepage. + if ( version_compare( get_bloginfo( 'version' ), '5.2', '>=' ) && + ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '3.6.0', '>=' ) ) ) { + $homepage_content = array( + 'post_title' => esc_attr__( 'Homepage', 'storefront' ), + 'template' => 'template-fullwidth.php', + ); + } else { + $homepage_content = array( + 'post_title' => esc_attr__( 'Welcome', 'storefront' ), + /* translators: %s: 'End Of Line' symbol */ + 'post_content' => sprintf( esc_attr__( 'This is your homepage which is what most visitors will see when they first visit your shop.%sYou can change this text by editing the "Welcome" page via the "Pages" menu in your dashboard.', 'storefront' ), PHP_EOL . PHP_EOL ), + 'template' => 'template-homepage.php', + 'thumbnail' => '{{hero-image}}', + ); + } + + $homepage = array( + 'home' => $homepage_content, + ); + + $starter_content['posts'] = array_merge( $starter_content['posts'], $homepage ); + + // Add products. + $starter_content_wc_products = $this->_starter_content_products(); + + if ( ! empty( $starter_content_wc_products ) ) { + $starter_content['posts'] = array_merge( $starter_content['posts'], $starter_content_wc_products ); + } + + // Use symbols as post name for attachments. + foreach ( $starter_content['attachments'] as $symbol => $attachment ) { + $starter_content['attachments'][ $symbol ]['post_name'] = $symbol; + } + + // Add WooCommerce pages. + $starter_content_wc_pages = array(); + $woocommerce_pages = Storefront_NUX_Admin::get_woocommerce_pages(); + + foreach ( $woocommerce_pages as $option => $page_id ) { + $page = get_post( $page_id ); + + if ( null !== $page ) { + $starter_content_wc_pages[ 'sf_' . $page->post_name ] = array( + 'post_title' => $page->post_title, + 'post_name' => $page->post_name, + 'post_type' => 'page', + ); + } + } + + if ( ! empty( $starter_content_wc_pages ) ) { + $starter_content['posts'] = array_merge( $starter_content['posts'], $starter_content_wc_pages ); + } + + // Register support for starter content. + add_theme_support( 'starter-content', apply_filters( 'storefront_starter_content', $starter_content ) ); + } + + /** + * Filters starter content and remove some of the content if necessary. + * + * @since 2.2.0 + * @param array $content Starter content. + * @param array $config Config. + * @return array $content + */ + public function filter_start_content( $content, $config ) { + if ( ! isset( $_GET['sf_starter_content'] ) || 1 !== absint( $_GET['sf_starter_content'] ) ) { // WPCS: input var ok. + return $content; + } + + // Get hero image and save for later. + $hero_image = false; + + if ( array_key_exists( 'attachments', $content ) && array_key_exists( 'hero-image', $content['attachments'] ) ) { + $hero_image = $content['attachments']['hero-image']; + } + + // Remove some of the content if necessary. + $tasks = array(); + + if ( isset( $_GET['sf_tasks'] ) && '' !== sanitize_text_field( wp_unslash( $_GET['sf_tasks'] ) ) ) { // WPCS: input var ok. + $tasks = explode( ',', sanitize_text_field( wp_unslash( $_GET['sf_tasks'] ) ) ); // WPCS: input var ok. + } + + $tasks = $this->_validate_tasks( $tasks ); + + foreach ( $tasks as $task ) { + switch ( $task ) { + case 'homepage': + unset( $content['options'] ); + unset( $content['posts']['home'] ); + unset( $content['posts']['blog'] ); + + break; + + case 'products': + if ( isset( $content['posts'] ) ) { + foreach ( $content['posts'] as $post_id => $post ) { + if ( isset( $post['post_type'] ) && 'product' === $post['post_type'] ) { + unset( $content['posts'][ $post_id ] ); + } + } + } + + unset( $content['posts']['about'] ); + unset( $content['posts']['contact'] ); + unset( $content['attachments'] ); + unset( $content['nav_menus'] ); + unset( $content['widgets'] ); + + break; + } + } + + // Existing site: remove custom pages, navigation menus and widgets from starter content. + if ( true !== (bool) get_option( 'storefront_nux_fresh_site' ) ) { + unset( $content['posts']['about'] ); + unset( $content['posts']['contact'] ); + unset( $content['nav_menus'] ); + unset( $content['widgets'] ); + } + + // Add homepage attachment image, if necessary for blocks. + if ( $hero_image && + array_key_exists( 'posts', $content ) && + array_key_exists( 'home', $content['posts'] ) && + ! array_key_exists( 'attachments', $content ) + ) { + $content['attachments'] = array( + 'hero-image' => $hero_image, + ); + } + + return $content; + } + + /** + * Filter WooCommerce main query to include starter content products. + * + * @since 2.2.0 + * @param object $query The Query. + * @return void + */ + public function wc_query( $query ) { + if ( ! is_customize_preview() || true !== (bool) get_option( 'fresh_site' ) ) { + return; + } + + $post__in = array(); + + // Add existing products. + $existing_products = $this->_get_existing_wc_products(); + + if ( ! empty( $existing_products ) ) { + $post__in = array_merge( $post__in, $existing_products ); + } + + // Add starter content. + $created_products = $this->_get_created_starter_content_products(); + + if ( false !== $created_products ) { + + // Merge starter content products. + $post__in = array_merge( $post__in, $created_products ); + + // Allow for multiple status. + $query->set( 'post_status', get_post_stati() ); + } + + // Add products to query. + $query->set( 'post__in', $post__in ); + } + + /** + * Filter shortcode products loop in WooCommerce. + * + * @since 2.2.0 + * @param array $query_args Query args. + * @param array $atts Shortcode attributes. + * @param string $loop_name Loop name. + * @return array $args + */ + public function shortcode_loop_products( $query_args, $atts, $loop_name = null ) { + if ( ! is_customize_preview() || true !== (bool) get_option( 'fresh_site' ) ) { + return $query_args; + } + + // When a list of ids is already present in the query, return. + if ( array_key_exists( 'post__in', $query_args ) ) { + $query_args['post_status'] = get_post_stati(); + return $query_args; + } + + $query_args['post__in'] = array(); + + // Add existing products to query. + $existing_products = $this->_get_existing_wc_products(); + + if ( ! empty( $existing_products ) ) { + $query_args['post__in'] = array_merge( $query_args['post__in'], $existing_products ); + } + + // Add starter content to query. + $created_products = $this->_get_created_starter_content_products(); + + if ( false !== $created_products ) { + + // Add created products to query. + $query_args['post__in'] = array_merge( $query_args['post__in'], $created_products ); + + // Allow for multiple status. + $query_args['post_status'] = get_post_stati(); + } + + return $query_args; + } + + /** + * Filter shortcode products loop in WooCommerce. + * + * @since 2.5.0 + * @param array $query_args Query args. + * @param array $atts Shortcode attributes. + * @param string $type Loop type. + * @return array $query_args + */ + public function filter_on_sale_products( $query_args, $atts, $type ) { + if ( ! is_customize_preview() || true !== (bool) get_option( 'fresh_site' ) ) { + return $query_args; + } + + if ( 'sale_products' === $type ) { + $onsale = array( + 'beanie', + 'belt', + 'cap', + 'hoodie-with-pocket', + ); + + $products = $this->_query_starter_content( 'product', $onsale, true ); + + if ( ! empty( $products ) ) { + $query_args['post__in'] = $products; + } + } + + return $query_args; + } + + /** + * Override product categories when displaying starter content. + * + * @since 2.5.0 + * @param array $categories Product categories. + * @return array $categories Modified product categories. + */ + public function filter_product_categories_shortcode( $categories ) { + if ( ! is_customize_preview() || true !== (bool) get_option( 'fresh_site' ) ) { + return $categories; + } + + // Get empty categories. + $categories = get_terms( + 'product_cat', + array( + 'hide_empty' => false, + ) + ); + + foreach ( $categories as $key => $cat ) { + + // Fake number of products in category. + $categories[ $key ]->count = 1; + } + + return $categories; + } + + /** + * Add product taxonomies to starter content. + * + * @since 2.2.0 + */ + public function add_product_tax() { + if ( ! is_customize_preview() || true !== (bool) get_option( 'fresh_site' ) ) { + return; + } + + $created_products = $this->_get_created_starter_content_products(); + + if ( false === $created_products ) { + return; + } + + $starter_products = $this->_starter_content_products(); + + if ( is_array( $created_products ) ) { + foreach ( $created_products as $product ) { + $product = get_post( $product ); + + if ( ! $product ) { + continue; + } + + $post_name = get_post_meta( $product->ID, '_customize_draft_post_name', true ); + + if ( ! $post_name || ! array_key_exists( $post_name, $starter_products ) ) { + continue; + } + + $taxonomies = array( 'product_cat', 'product_tag' ); + + foreach ( $taxonomies as $taxonomy ) { + if ( array_key_exists( $taxonomy, $starter_products[ $post_name ]['taxonomy'] ) ) { + $categories = $starter_products[ $post_name ]['taxonomy'][ $taxonomy ]; + + if ( ! empty( $categories ) ) { + $category_ids = array(); + + foreach ( $categories as $category ) { + // Check if the term already exists. + $category_exists = term_exists( $category['term'], $taxonomy ); + + if ( $category_exists ) { + $category_ids[] = (int) $category_exists['term_id']; + + continue; + } + + // Create new category. + $created_category = wp_insert_term( + $category['term'], + $taxonomy, + array( + 'description' => $category['description'], + 'slug' => $category['slug'], + ) + ); + + if ( ! is_wp_error( $created_category ) ) { + $category_ids[] = $created_category['term_id']; + + $category_image = $this->_get_category_image_attachment_id( $category['slug'] ); + + if ( $category_image ) { + update_term_meta( (int) $created_category['term_id'], 'thumbnail_id', $category_image ); + } + } + } + + wp_set_object_terms( $product->ID, $category_ids, $taxonomy ); + } + } + } + } + } + + add_filter( 'storefront_product_categories_shortcode_args', array( $this, 'filter_sf_categories' ) ); + } + + /** + * Add product data to starter products. + * + * @since 2.2.0 + * @return void + */ + public function set_product_data() { + if ( ! is_customize_preview() || true !== (bool) get_option( 'fresh_site' ) ) { + return; + } + + $created_products = $this->_get_created_starter_content_products(); + + if ( false === $created_products ) { + return; + } + + $starter_products = $this->_starter_content_products(); + + if ( is_array( $created_products ) ) { + foreach ( $created_products as $product ) { + $product = wc_get_product( $product ); + + if ( ! $product ) { + continue; + } + + $post_name = get_post_meta( $product->get_id(), '_customize_draft_post_name', true ); + + if ( ! $post_name || ! array_key_exists( $post_name, $starter_products ) ) { + continue; + } + + if ( ! array_key_exists( 'product_data', $starter_products[ $post_name ] ) ) { + continue; + } + + $product_data = $starter_products[ $post_name ]['product_data']; + + // Set visibility. + $product->set_catalog_visibility( 'visible' ); + + // Set regular price. + if ( ! empty( $product_data['regular_price'] ) ) { + $product->set_regular_price( floatval( $product_data['regular_price'] ) ); + } + + // Set price. + if ( ! empty( $product_data['price'] ) ) { + $product->set_price( floatval( $product_data['price'] ) ); + } + + // Set sale price. + if ( ! empty( $product_data['sale_price'] ) ) { + $product->set_sale_price( floatval( $product_data['sale_price'] ) ); + } + + // Set featured. + if ( ! empty( $product_data['featured'] ) ) { + $product->set_featured( true ); + } else { + $product->set_featured( false ); + } + + // Save. + $product->save(); + } + } + } + + /** + * Filter Storefront Product Categories shortcode. + * + * @since 2.2.0 + * @param array $args Shortcode args. + * @return array $args + */ + public function filter_sf_categories( $args ) { + // Get Categories. + $product_cats = get_terms( + 'product_cat', + array( + 'fields' => 'ids', + 'hide_empty' => false, + ) + ); + + if ( ! empty( $product_cats ) ) { + + // Needs to be set for categories to show up. + $args['hide_empty'] = false; + + // List of categories to display. + $args['ids'] = implode( $product_cats, ',' ); + } + + return $args; + } + + /** + * WooCommerce 3.0.0 changes the title of all auto-draft products to "AUTO-DRAFT". + * Here we change the title back when the post status changes. + * + * @since 2.2.0 + * @param string $new_status New status. + * @param string $old_status Old status. + * @param WP_Post $post Post data. + */ + public function transition_post_status( $new_status, $old_status, $post ) { + if ( 'publish' === $new_status && 'auto-draft' === $old_status && in_array( $post->post_type, array( 'product' ), true ) ) { + $post_name = get_post_meta( $post->ID, '_customize_draft_post_name', true ); + + $starter_products = $this->_starter_content_products(); + + if ( $post_name && array_key_exists( $post_name, $starter_products ) ) { + $update_product = array( + 'ID' => $post->ID, + 'post_title' => $starter_products[ $post_name ]['post_title'], + ); + + wp_update_post( $update_product ); + } + } + } + + /** + * WooCommerce 3.0.0 changes the title of all auto-draft products to "AUTO-DRAFT". + * Here we filter the title and display the correct one instead. + * + * @since 2.2.0 + * @param string $title Post title. + * @param int $post_id Post id. + */ + public function filter_auto_draft_title( $title, $post_id = null ) { + if ( ! $post_id ) { + return $title; + } + + $post = get_post( $post_id ); + + if ( $post && 'auto-draft' === $post->post_status && in_array( $post->post_type, array( 'product' ), true ) && 'AUTO-DRAFT' === $post->post_title ) { + $post_name = get_post_meta( $post->ID, '_customize_draft_post_name', true ); + + $starter_products = $this->_starter_content_products(); + + if ( $post_name && array_key_exists( $post_name, $starter_products ) ) { + return $starter_products[ $post_name ]['post_title']; + } + } + + return $title; + } + + /** + * Starter content products. + * + * @since 2.2.0 + */ + private function _starter_content_products() { + $accessories_name = esc_attr__( 'Accessories', 'storefront' ); + $accessories_description = esc_attr__( 'A short category description', 'storefront' ); + + $hoodies_name = esc_attr__( 'Hoodies', 'storefront' ); + $hoodies_description = esc_attr__( 'A short category description', 'storefront' ); + + $tshirts_name = esc_attr__( 'Tshirts', 'storefront' ); + $tshirts_description = esc_attr__( 'A short category description', 'storefront' ); + + $products = array( + // Accessories. + 'beanie' => array( + 'post_title' => esc_attr__( 'Beanie', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{beanie-image}}', + 'product_data' => array( + 'regular_price' => '20', + 'price' => '18', + 'sale_price' => '18', + 'featured' => false, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $accessories_name, + 'slug' => 'accessories', + 'description' => $accessories_description, + ), + ), + ), + ), + 'belt' => array( + 'post_title' => esc_attr__( 'Belt', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{belt-image}}', + 'product_data' => array( + 'regular_price' => '65', + 'price' => '55', + 'sale_price' => '55', + 'featured' => false, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $accessories_name, + 'slug' => 'accessories', + 'description' => $accessories_description, + ), + ), + ), + ), + 'cap' => array( + 'post_title' => esc_attr__( 'Cap', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{cap-image}}', + 'product_data' => array( + 'regular_price' => '18', + 'price' => '16', + 'sale_price' => '16', + 'featured' => false, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $accessories_name, + 'slug' => 'accessories', + 'description' => $accessories_description, + ), + ), + ), + ), + 'sunglasses' => array( + 'post_title' => esc_attr__( 'Sunglasses', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{sunglasses-image}}', + 'product_data' => array( + 'regular_price' => '90', + 'price' => '90', + 'featured' => true, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $accessories_name, + 'slug' => 'accessories', + 'description' => $accessories_description, + ), + ), + ), + ), + 'hoodie-with-logo' => array( + 'post_title' => esc_attr__( 'Hoodie with Logo', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{hoodie-with-logo-image}}', + 'product_data' => array( + 'regular_price' => '45', + 'price' => '45', + 'featured' => false, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $hoodies_name, + 'slug' => 'hoodies', + 'description' => $hoodies_description, + ), + ), + ), + ), + 'hoodie-with-pocket' => array( + 'post_title' => esc_attr__( 'Hoodie with Pocket', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{hoodie-with-pocket-image}}', + 'product_data' => array( + 'regular_price' => '45', + 'price' => '35', + 'sale_price' => '35', + 'featured' => true, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $hoodies_name, + 'slug' => 'hoodies', + 'description' => $hoodies_description, + ), + ), + ), + ), + 'hoodie-with-zipper' => array( + 'post_title' => esc_attr__( 'Hoodie with Zipper', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{hoodie-with-zipper-image}}', + 'product_data' => array( + 'regular_price' => '45', + 'price' => '45', + 'featured' => true, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $hoodies_name, + 'slug' => 'hoodies', + 'description' => $hoodies_description, + ), + ), + ), + ), + 'hoodie' => array( + 'post_title' => esc_attr__( 'Hoodie', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{hoodie-image}}', + 'product_data' => array( + 'regular_price' => '45', + 'price' => '42', + 'sale_price' => '42', + 'featured' => true, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $hoodies_name, + 'slug' => 'hoodies', + 'description' => $hoodies_description, + ), + ), + ), + ), + 'long-sleeve-tee' => array( + 'post_title' => esc_attr__( 'Long Sleeve Tee', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{long-sleeve-tee-image}}', + 'product_data' => array( + 'regular_price' => '25', + 'price' => '25', + 'featured' => false, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $tshirts_name, + 'slug' => 'tshirts', + 'description' => $tshirts_description, + ), + ), + ), + ), + 'polo' => array( + 'post_title' => esc_attr__( 'Polo', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{polo-image}}', + 'product_data' => array( + 'regular_price' => '20', + 'price' => '20', + 'featured' => false, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $tshirts_name, + 'slug' => 'tshirts', + 'description' => $tshirts_description, + ), + ), + ), + ), + 'tshirt' => array( + 'post_title' => esc_attr__( 'Tshirt', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{tshirt-image}}', + 'product_data' => array( + 'regular_price' => '18', + 'price' => '18', + 'featured' => false, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $tshirts_name, + 'slug' => 'tshirts', + 'description' => $tshirts_description, + ), + ), + ), + ), + 'vneck-tee' => array( + 'post_title' => esc_attr__( 'Vneck Tshirt', 'storefront' ), + 'post_content' => 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.', + 'post_type' => 'product', + 'comment_status' => 'open', + 'thumbnail' => '{{vneck-tee-image}}', + 'product_data' => array( + 'regular_price' => '18', + 'price' => '18', + 'featured' => false, + ), + 'taxonomy' => array( + 'product_cat' => array( + array( + 'term' => $tshirts_name, + 'slug' => 'tshirts', + 'description' => $tshirts_description, + ), + ), + ), + ), + ); + + // Use symbols as post name. + foreach ( $products as $symbol => $product ) { + $products[ $symbol ]['post_name'] = $symbol; + } + + return apply_filters( 'storefront_starter_content_products', $products ); + } + + /** + * Adds blocks to homepage content. + * + * @since 2.5.0 + */ + public function update_homepage_content() { + $homepage = $this->_query_starter_content( 'page', 'homepage', true ); + + if ( empty( $homepage ) ) { + return; + } + + $homepage = $homepage[0]; + + $content = $this->_replace_homepage_blocks_symbols(); + + if ( ! empty( $content ) ) { + + // Update homepage content. + $update_homepage = array( + 'ID' => $homepage, + 'post_content' => $content, + ); + + wp_update_post( $update_homepage ); + } + } + + /** + * Homepage blocks content. + * + * @since 2.5.0 + * @return string $content Homepage content. + */ + private function _homepage_blocks_content() { + $content = ' + {{cover}} + + +

    ' . __( 'Shop by Category', 'storefront' ) . '

    + + + + [product_categories limit="3" columns="3" orderby="menu_order"] + + + +

    ' . __( 'New In', 'storefront' ) . '

    + + + + + {{handpicked-products}} + + +

    ' . __( 'Fan Favorites', 'storefront' ) . '

    + + + + + +

    ' . __( 'On Sale', 'storefront' ) . '

    + + + + + +

    ' . __( 'Best Sellers', 'storefront' ) . '

    + + + + '; + + return trim( $content ); + } + + /** + * Replaces placeholder symbols with content. + * + * @since 2.5.0 + * @return string $content Homepage content. + */ + private function _replace_homepage_blocks_symbols() { + $content = $this->_homepage_blocks_content(); + + // Replace hero placeholders. + $hero = $this->_query_starter_content( 'attachment', 'hero-image', true ); + + if ( ! empty( $hero ) ) { + $cover = ' + +
    +

    ' . __( 'Welcome', 'storefront' ) . '

    + + + +

    ' . __( 'This is your homepage which is what most visitors will see when they first visit your shop.', 'storefront' ) . '

    + + + +

    ' . __( 'You can change this text by editing the "Welcome" page via the "Pages" menu in your dashboard.', 'storefront' ) . '

    +
    + + '; + + $attachment = $hero[0]; + $cover = str_replace( '{{hero-image-id}}', $attachment, $cover ); + $cover = str_replace( '{{hero-image-url}}', wp_get_attachment_url( $attachment ), $cover ); + $content = str_replace( '{{cover}}', $cover, $content ); + } else { + $content = str_replace( '{{cover}}', '', $content ); + } + + // Replace handpicked products placeholders. + $featured = array( + 'sunglasses', + 'hoodie-with-pocket', + 'hoodie-with-zipper', + 'hoodie', + ); + + $products = $this->_query_starter_content( 'product', $featured, true ); + + if ( ! empty( $products ) ) { + $handpicked = ' + +

    ' . __( 'We Recommend', 'storefront' ) . '

    + + + + '; + + $handpicked = str_replace( '{{handpicked-products}}', implode( ',', $products ), $handpicked ); + $content = str_replace( '{{handpicked-products}}', $handpicked, $content ); + } else { + $content = str_replace( '{{handpicked-products}}', '', $content ); + } + + return $content; + } + + /** + * Get a list of posts created by starter content. + * + * @since 2.2.1 + * @return mixed false|array $query Array of post ids. + */ + private function _get_created_starter_content_products() { + global $wp_customize; + + $setting = $wp_customize->get_setting( 'nav_menus_created_posts' ); + + if ( is_object( $setting ) ) { + $created_products_ids = $setting->value(); + + if ( ! empty( $created_products_ids ) ) { + return (array) $created_products_ids; + } + } + + return false; + } + + /** + * Get a list of existing products in the store. + * + * @since 2.2.0 + * @return array $query Array of product ids. + */ + private function _get_existing_wc_products() { + $query_args = array( + 'post_type' => 'product', + 'post_status' => 'publish', + 'fields' => 'ids', + 'posts_per_page' => -1, + ); + + $products = get_posts( $query_args ); + + if ( $products && ! empty( $products ) ) { + return $products; + } + + return array(); + } + + /** + * Query start content imported by the Customizer. + * + * @since 2.5.0 + * @param string $post_type Post Type. + * @param mixed string|array $draft_slugs Slug or array of draft slugs. + * @param bool $ids Whether to return just the ids or the whole post object. + * @return mixed false|int $query Query results. + */ + private function _query_starter_content( $post_type, $draft_slugs, $ids = false ) { + $query_args = array( + 'post_type' => $post_type, + 'post_status' => 'auto-draft', + 'posts_per_page' => -1, + 'meta_query' => array( + array( + 'key' => '_customize_draft_post_name', + 'value' => $draft_slugs, + 'compare' => is_array( $draft_slugs ) ? 'IN' : '=', + ), + ), + ); + + $created_products = $this->_get_created_starter_content_products(); + + if ( false !== $created_products ) { + $query_args['post__in'] = $created_products; + } + + if ( $ids ) { + $query_args['fields'] = 'ids'; + } + + $query = get_posts( $query_args ); + + if ( ! empty( $query ) ) { + return $query; + } + + return false; + } + + /** + * Given a category slug, find the related image attachment. + * + * @since 2.2.0 + * @param string $category Category. + * @return mixed false|int $query first attachment found. + */ + private function _get_category_image_attachment_id( $category ) { + $attachment = $this->_query_starter_content( 'attachment', $category . '-image', true ); + + if ( ! empty( $attachment ) ) { + return $attachment[0]; + } + + return false; + } + + /** + * Validates and sanitizes a given tasks list. + * + * @since 2.2.0 + * @param string $tasks The tasks. + * @return mixed false|array $validated_tasks if tasks list is not empty. + */ + private function _validate_tasks( $tasks ) { + $valid_tasks = apply_filters( 'storefront_valid_tour_tasks', array( 'homepage', 'products' ) ); + + $validated_tasks = array(); + + foreach ( $tasks as $task ) { + $task = sanitize_key( $task ); + + if ( in_array( $task, $valid_tasks, true ) ) { + $validated_tasks[] = $task; + } + } + + $validated_tasks = array_diff( $valid_tasks, $validated_tasks ); + + return $validated_tasks; + } + } + +endif; + +return new Storefront_NUX_Starter_Content(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/storefront-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/storefront-functions.php new file mode 100644 index 0000000..a46e982 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/storefront-functions.php @@ -0,0 +1,247 @@ + $value ) { + echo esc_attr( $style . ': ' . $value . '; ' ); + } +} + +/** + * Apply inline style to the Storefront homepage content. + * + * @uses get_the_post_thumbnail_url() + * @since 2.2.0 + */ +function storefront_homepage_content_styles() { + $featured_image = get_the_post_thumbnail_url( get_the_ID() ); + $background_image = ''; + + if ( $featured_image ) { + $background_image = 'url(' . esc_url( $featured_image ) . ')'; + } + + $styles = array(); + + if ( '' !== $background_image ) { + $styles['background-image'] = $background_image; + } + + $styles = apply_filters( 'storefront_homepage_content_styles', $styles ); + + foreach ( $styles as $style => $value ) { + echo esc_attr( $style . ': ' . $value . '; ' ); + } +} + +/** + * Given an hex colors, returns an array with the colors components. + * + * @param strong $hex Hex color e.g. #111111. + * @return bool Array with color components (r, g, b). + * @since 2.5.8 + */ +function get_rgb_values_from_hex( $hex ) { + // Format the hex color string. + $hex = str_replace( '#', '', $hex ); + + if ( 3 === strlen( $hex ) ) { + $hex = str_repeat( substr( $hex, 0, 1 ), 2 ) . str_repeat( substr( $hex, 1, 1 ), 2 ) . str_repeat( substr( $hex, 2, 1 ), 2 ); + } + + // Get decimal values. + $r = hexdec( substr( $hex, 0, 2 ) ); + $g = hexdec( substr( $hex, 2, 2 ) ); + $b = hexdec( substr( $hex, 4, 2 ) ); + + return array( + 'r' => $r, + 'g' => $g, + 'b' => $b, + ); +} + +/** + * Returns true for light colors and false for dark colors. + * + * @param strong $hex Hex color e.g. #111111. + * @return bool True if the average lightness of the three components of the color is higher or equal than 127.5. + * @since 2.5.8 + */ +function is_color_light( $hex ) { + $rgb_values = get_rgb_values_from_hex( $hex ); + $average_lightness = ( $rgb_values['r'] + $rgb_values['g'] + $rgb_values['b'] ) / 3; + return $average_lightness >= 127.5; +} + +/** + * Adjust a hex color brightness + * Allows us to create hover styles for custom link colors + * + * @since 2.5.8 Added $opacity argument. + * + * @param strong $hex Hex color e.g. #111111. + * @param integer $steps Factor by which to brighten/darken ranging from -255 (darken) to 255 (brighten). + * @param float $opacity Opacity factor between 0 and 1. + * @return string Brightened/darkened color (hex by default, rgba if opacity is set to a valid value below 1). + * @since 1.0.0 + */ +function storefront_adjust_color_brightness( $hex, $steps, $opacity = 1 ) { + // Steps should be between -255 and 255. Negative = darker, positive = lighter. + $steps = max( -255, min( 255, $steps ) ); + + $rgb_values = get_rgb_values_from_hex( $hex ); + + // Adjust number of steps and keep it inside 0 to 255. + $r = max( 0, min( 255, $rgb_values['r'] + $steps ) ); + $g = max( 0, min( 255, $rgb_values['g'] + $steps ) ); + $b = max( 0, min( 255, $rgb_values['b'] + $steps ) ); + + if ( $opacity >= 0 && $opacity < 1 ) { + return 'rgba(' . $r . ',' . $g . ',' . $b . ',' . $opacity . ')'; + } + + $r_hex = str_pad( dechex( $r ), 2, '0', STR_PAD_LEFT ); + $g_hex = str_pad( dechex( $g ), 2, '0', STR_PAD_LEFT ); + $b_hex = str_pad( dechex( $b ), 2, '0', STR_PAD_LEFT ); + + return '#' . $r_hex . $g_hex . $b_hex; +} + +/** + * Sanitizes choices (selects / radios) + * Checks that the input matches one of the available choices + * + * @param array $input the available choices. + * @param array $setting the setting object. + * @since 1.3.0 + */ +function storefront_sanitize_choices( $input, $setting ) { + // Ensure input is a slug. + $input = sanitize_key( $input ); + + // Get list of choices from the control associated with the setting. + $choices = $setting->manager->get_control( $setting->id )->choices; + + // If the input is a valid key, return it; otherwise, return the default. + return ( array_key_exists( $input, $choices ) ? $input : $setting->default ); +} + +/** + * Checkbox sanitization callback. + * + * Sanitization callback for 'checkbox' type controls. This callback sanitizes `$checked` + * as a boolean value, either TRUE or FALSE. + * + * @param bool $checked Whether the checkbox is checked. + * @return bool Whether the checkbox is checked. + * @since 1.5.0 + */ +function storefront_sanitize_checkbox( $checked ) { + return ( ( isset( $checked ) && true === $checked ) ? true : false ); +} + +/** + * Storefront Sanitize Hex Color + * + * @param string $color The color as a hex. + * @todo remove in 2.1. + */ +function storefront_sanitize_hex_color( $color ) { + _deprecated_function( 'storefront_sanitize_hex_color', '2.0', 'sanitize_hex_color' ); + + if ( '' === $color ) { + return ''; + } + + // 3 or 6 hex digits, or the empty string. + if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) { + return $color; + } + + return null; +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/storefront-template-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/storefront-template-functions.php new file mode 100644 index 0000000..801052d --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/storefront-template-functions.php @@ -0,0 +1,709 @@ + + < id="comment-"> +
    + + +
    + +
    + +
    +
    + $add_below, + 'depth' => $depth, + 'max_depth' => $args['max_depth'], + ) + ) + ); + ?> + +
    +
    + +
    + + +
    > + + + +
    + ' . esc_html__( 'Built with Storefront & WooCommerce', 'storefront' ) . '.'; + } else { + $links_output .= '' . esc_html__( 'Built with Storefront', 'storefront' ) . '.'; + } + } + + if ( apply_filters( 'storefront_privacy_policy_link', true ) && function_exists( 'the_privacy_policy_link' ) ) { + $separator = ''; + $links_output = get_the_privacy_policy_link( '', ( ! empty( $links_output ) ? $separator : '' ) ) . $links_output; + } + + $links_output = apply_filters( 'storefront_credit_links_output', $links_output ); + ?> +
    + + + +
    + + +
    + + + +
    + +
    + ' . $logo . '' : $logo; + } else { + $tag = is_home() ? 'h1' : 'div'; + + $html = '<' . esc_attr( $tag ) . ' class="beta site-title">' . esc_html( get_bloginfo( 'name' ) ) . ''; + + if ( '' !== get_bloginfo( 'description' ) ) { + $html .= '

    ' . esc_html( get_bloginfo( 'description', 'display' ) ) . '

    '; + } + } + + if ( ! $echo ) { + return $html; + } + + echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } +} + +if ( ! function_exists( 'storefront_primary_navigation' ) ) { + /** + * Display Primary Navigation + * + * @since 1.0.0 + * @return void + */ + function storefront_primary_navigation() { + ?> + + + + + + + +
    + ', '' ); + ?> +
    + +
    + ', '' ); + ?> +
    + +
    + + '', + ) + ); + ?> +
    + +
    + ', '' ); + } else { + the_title( sprintf( '

    ', esc_url( get_permalink() ) ), '

    ' ); + } + + do_action( 'storefront_post_header_after' ); + ?> +
    + +
    + ' . get_the_title() . '' + ) + ); + + do_action( 'storefront_post_content_after' ); + + wp_link_pages( + array( + 'before' => '', + ) + ); + ?> +
    + %2$s'; + + if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) { + $time_string = ''; + } + + $time_string = sprintf( + $time_string, + esc_attr( get_the_date( 'c' ) ), + esc_html( get_the_date() ), + esc_attr( get_the_modified_date( 'c' ) ), + esc_html( get_the_modified_date() ) + ); + + $output_time_string = sprintf( '%2$s', esc_url( get_permalink() ), $time_string ); + + $posted_on = ' + ' . + /* translators: %s: post date */ + sprintf( __( 'Posted on %s', 'storefront' ), $output_time_string ) . + ''; + + // Author. + $author = sprintf( + '', + __( 'by', 'storefront' ), + esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ), + esc_html( get_the_author() ) + ); + + // Comments. + $comments = ''; + + if ( ! post_password_required() && ( comments_open() || 0 !== intval( get_comments_number() ) ) ) { + $comments_number = get_comments_number_text( __( 'Leave a comment', 'storefront' ), __( '1 Comment', 'storefront' ), __( '% Comments', 'storefront' ) ); + + $comments = sprintf( + '%2$s', + esc_url( get_comments_link() ), + $comments_number + ); + } + + echo wp_kses( + sprintf( '%1$s %2$s %3$s', $posted_on, $author, $comments ), + array( + 'span' => array( + 'class' => array(), + ), + 'a' => array( + 'href' => array(), + 'title' => array(), + 'rel' => array(), + ), + 'time' => array( + 'datetime' => array(), + 'class' => array(), + ), + ) + ); + } +} + +if ( ! function_exists( 'storefront_edit_post_link' ) ) { + /** + * Display the edit link + * + * @since 2.5.0 + */ + function storefront_edit_post_link() { + edit_post_link( + sprintf( + wp_kses( + /* translators: %s: Name of current post. Only visible to screen readers */ + __( 'Edit %s', 'storefront' ), + array( + 'span' => array( + 'class' => array(), + ), + ) + ), + get_the_title() + ), + '' + ); + } +} + +if ( ! function_exists( 'storefront_post_taxonomy' ) ) { + /** + * Display the post taxonomies + * + * @since 2.4.0 + */ + function storefront_post_taxonomy() { + /* translators: used between list items, there is a space after the comma */ + $categories_list = get_the_category_list( __( ', ', 'storefront' ) ); + + /* translators: used between list items, there is a space after the comma */ + $tags_list = get_the_tag_list( '', __( ', ', 'storefront' ) ); + ?> + + + + 'list', + 'next_text' => _x( 'Next', 'Next post', 'storefront' ), + 'prev_text' => _x( 'Previous', 'Previous post', 'storefront' ), + ); + + the_posts_pagination( $args ); + } +} + +if ( ! function_exists( 'storefront_post_nav' ) ) { + /** + * Display navigation to next/previous post when applicable. + */ + function storefront_post_nav() { + $args = array( + 'next_text' => '' . esc_html__( 'Next post:', 'storefront' ) . ' %title', + 'prev_text' => '' . esc_html__( 'Previous post:', 'storefront' ) . ' %title', + ); + the_post_navigation( $args ); + } +} + +if ( ! function_exists( 'storefront_posted_on' ) ) { + /** + * Prints HTML with meta information for the current post-date/time and author. + * + * @deprecated 2.4.0 + */ + function storefront_posted_on() { + _deprecated_function( 'storefront_posted_on', '2.4.0' ); + } +} + +if ( ! function_exists( 'storefront_homepage_content' ) ) { + /** + * Display homepage content + * Hooked into the `homepage` action in the homepage template + * + * @since 1.0.0 + * @return void + */ + function storefront_homepage_content() { + while ( have_posts() ) { + the_post(); + + get_template_part( 'content', 'homepage' ); + + } // end of the loop. + } +} + +if ( ! function_exists( 'storefront_social_icons' ) ) { + /** + * Display social icons + * If the subscribe and connect plugin is active, display the icons. + * + * @link http://wordpress.org/plugins/subscribe-and-connect/ + * @since 1.0.0 + */ + function storefront_social_icons() { + if ( class_exists( 'Subscribe_And_Connect' ) ) { + echo ''; + } + } +} + +if ( ! function_exists( 'storefront_get_sidebar' ) ) { + /** + * Display storefront sidebar + * + * @uses get_sidebar() + * @since 1.0.0 + */ + function storefront_get_sidebar() { + get_sidebar(); + } +} + +if ( ! function_exists( 'storefront_post_thumbnail' ) ) { + /** + * Display post thumbnail + * + * @var $size thumbnail size. thumbnail|medium|large|full|$custom + * @uses has_post_thumbnail() + * @uses the_post_thumbnail + * @param string $size the post thumbnail size. + * @since 1.5.0 + */ + function storefront_post_thumbnail( $size = 'full' ) { + if ( has_post_thumbnail() ) { + the_post_thumbnail( $size ); + } + } +} + +if ( ! function_exists( 'storefront_primary_navigation_wrapper' ) ) { + /** + * The primary navigation wrapper + */ + function storefront_primary_navigation_wrapper() { + echo '
    '; + } +} + +if ( ! function_exists( 'storefront_primary_navigation_wrapper_close' ) ) { + /** + * The primary navigation wrapper close + */ + function storefront_primary_navigation_wrapper_close() { + echo '
    '; + } +} + +if ( ! function_exists( 'storefront_header_container' ) ) { + /** + * The header container + */ + function storefront_header_container() { + echo '
    '; + } +} + +if ( ! function_exists( 'storefront_header_container_close' ) ) { + /** + * The header container close + */ + function storefront_header_container_close() { + echo '
    '; + } +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/storefront-template-hooks.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/storefront-template-hooks.php new file mode 100644 index 0000000..b3628be --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/storefront-template-hooks.php @@ -0,0 +1,93 @@ +in_same_term = $in_same_term; + $this->excluded_terms = $excluded_terms; + $this->taxonomy = $taxonomy; + $this->previous = $previous; + } + + /** + * Get adjacent product or circle back to the first/last valid product. + * + * @since 2.4.3 + * + * @return WC_Product|false Product object if successful. False if no valid product is found. + */ + public function get_product() { + global $post; + + $product = false; + $this->current_product = $post->ID; + + // Try to get a valid product via `get_adjacent_post()`. + while ( $adjacent = $this->get_adjacent() ) { + $product = wc_get_product( $adjacent->ID ); + + if ( $product && $product->is_visible() ) { + break; + } + + $product = false; + $this->current_product = $adjacent->ID; + } + + if ( $product ) { + return $product; + } + + // No valid product found; Query WC for first/last product. + $product = $this->query_wc(); + + if ( $product ) { + return $product; + } + + return false; + } + + /** + * Get adjacent post. + * + * @since 2.4.3 + * + * @return WP_POST|false Post object if successful. False if no valid post is found. + */ + private function get_adjacent() { + global $post; + + $direction = $this->previous ? 'previous' : 'next'; + + add_filter( 'get_' . $direction . '_post_where', array( $this, 'filter_post_where' ) ); + + $adjacent = get_adjacent_post( $this->in_same_term, $this->excluded_terms, $this->previous, $this->taxonomy ); + + remove_filter( 'get_' . $direction . '_post_where', array( $this, 'filter_post_where' ) ); + + return $adjacent; + } + + /** + * Filters the WHERE clause in the SQL for an adjacent post query, replacing the + * date with date of the next post to consider. + * + * @since 2.4.3 + * + * @param string $where The `WHERE` clause in the SQL. + * @return WP_POST|false Post object if successful. False if no valid post is found. + */ + public function filter_post_where( $where ) { + global $post; + + $new = get_post( $this->current_product ); + + $where = str_replace( $post->post_date, $new->post_date, $where ); + + return $where; + } + + /** + * Query WooCommerce for either the first or last products. + * + * @since 2.4.3 + * + * @return WC_Product|false Post object if successful. False if no valid post is found. + */ + private function query_wc() { + global $post; + + $args = array( + 'limit' => 2, + 'visibility' => 'catalog', + 'exclude' => array( $post->ID ), + 'orderby' => 'date', + 'status' => 'publish', + ); + + if ( ! $this->previous ) { + $args['order'] = 'ASC'; + } + + if ( $this->in_same_term ) { + $terms = get_the_terms( $post->ID, $this->taxonomy ); + + if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { + $args['category'] = wp_list_pluck( $terms, 'slug' ); + } + } + + $products = wc_get_products( apply_filters( 'storefront_woocommerce_adjacent_query_args', $args ) ); + + // At least 2 results are required, otherwise previous/next will be the same. + if ( ! empty( $products ) && count( $products ) >= 2 ) { + return $products[0]; + } + + return false; + } + } + +endif; diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/class-storefront-woocommerce-customizer.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/class-storefront-woocommerce-customizer.php new file mode 100644 index 0000000..868f8af --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/class-storefront-woocommerce-customizer.php @@ -0,0 +1,337 @@ +add_section( + 'storefront_single_product_page', + array( + 'title' => __( 'Product Page', 'storefront' ), + 'priority' => 10, + 'panel' => 'woocommerce', + ) + ); + + $wp_customize->add_setting( + 'storefront_product_pagination', + array( + 'default' => apply_filters( 'storefront_default_product_pagination', true ), + 'sanitize_callback' => 'wp_validate_boolean', + ) + ); + + $wp_customize->add_setting( + 'storefront_sticky_add_to_cart', + array( + 'default' => apply_filters( 'storefront_default_sticky_add_to_cart', true ), + 'sanitize_callback' => 'wp_validate_boolean', + ) + ); + + $wp_customize->add_control( + 'storefront_sticky_add_to_cart', + array( + 'type' => 'checkbox', + 'section' => 'storefront_single_product_page', + 'label' => __( 'Sticky Add-To-Cart', 'storefront' ), + 'description' => __( 'A small content bar at the top of the browser window which includes relevant product information and an add-to-cart button. It slides into view once the standard add-to-cart button has scrolled out of view.', 'storefront' ), + 'priority' => 10, + ) + ); + + $wp_customize->add_control( + 'storefront_product_pagination', + array( + 'type' => 'checkbox', + 'section' => 'storefront_single_product_page', + 'label' => __( 'Product Pagination', 'storefront' ), + 'description' => __( 'Displays next and previous links on product pages. A product thumbnail is displayed with the title revealed on hover.', 'storefront' ), + 'priority' => 20, + ) + ); + } + + /** + * Get Customizer css. + * + * @see get_storefront_theme_mods() + * @since 2.4.0 + * @return string $styles the css + */ + public function get_css() { + $storefront_theme_mods = $this->get_storefront_theme_mods(); + $brighten_factor = apply_filters( 'storefront_brighten_factor', 25 ); + $darken_factor = apply_filters( 'storefront_darken_factor', -25 ); + + $styles = ' + a.cart-contents, + .site-header-cart .widget_shopping_cart a { + color: ' . $storefront_theme_mods['header_link_color'] . '; + } + + a.cart-contents:hover, + .site-header-cart .widget_shopping_cart a:hover, + .site-header-cart:hover > li > a { + color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['header_link_color'], 65 ) . '; + } + + table.cart td.product-remove, + table.cart td.actions { + border-top-color: ' . $storefront_theme_mods['background_color'] . '; + } + + .storefront-handheld-footer-bar ul li.cart .count { + background-color: ' . $storefront_theme_mods['header_link_color'] . '; + color: ' . $storefront_theme_mods['header_background_color'] . '; + border-color: ' . $storefront_theme_mods['header_background_color'] . '; + } + + .woocommerce-tabs ul.tabs li.active a, + ul.products li.product .price, + .onsale, + .wc-block-grid__product-onsale, + .widget_search form:before, + .widget_product_search form:before { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + .woocommerce-breadcrumb a, + a.woocommerce-review-link, + .product_meta a { + color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['text_color'], 5 ) . '; + } + + .wc-block-grid__product-onsale, + .onsale { + border-color: ' . $storefront_theme_mods['text_color'] . '; + } + + .star-rating span:before, + .quantity .plus, .quantity .minus, + p.stars a:hover:after, + p.stars a:after, + .star-rating span:before, + #payment .payment_methods li input[type=radio]:first-child:checked+label:before { + color: ' . $storefront_theme_mods['accent_color'] . '; + } + + .widget_price_filter .ui-slider .ui-slider-range, + .widget_price_filter .ui-slider .ui-slider-handle { + background-color: ' . $storefront_theme_mods['accent_color'] . '; + } + + .order_details { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -7 ) . '; + } + + .order_details > li { + border-bottom: 1px dotted ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -28 ) . '; + } + + .order_details:before, + .order_details:after { + background: -webkit-linear-gradient(transparent 0,transparent 0),-webkit-linear-gradient(135deg,' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -7 ) . ' 33.33%,transparent 33.33%),-webkit-linear-gradient(45deg,' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -7 ) . ' 33.33%,transparent 33.33%) + } + + #order_review { + background-color: ' . $storefront_theme_mods['background_color'] . '; + } + + #payment .payment_methods > li .payment_box, + #payment .place-order { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -5 ) . '; + } + + #payment .payment_methods > li:not(.woocommerce-notice) { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -10 ) . '; + } + + #payment .payment_methods > li:not(.woocommerce-notice):hover { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], -15 ) . '; + } + + .woocommerce-pagination .page-numbers li .page-numbers.current { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['background_color'], $darken_factor ) . '; + color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['text_color'], -10 ) . '; + } + + .wc-block-grid__product-onsale, + .onsale, + .woocommerce-pagination .page-numbers li .page-numbers:not(.current) { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + p.stars a:before, + p.stars a:hover~a:before, + p.stars.selected a.active~a:before { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + p.stars.selected a.active:before, + p.stars:hover a:before, + p.stars.selected a:not(.active):before, + p.stars.selected a.active:before { + color: ' . $storefront_theme_mods['accent_color'] . '; + } + + .single-product div.product .woocommerce-product-gallery .woocommerce-product-gallery__trigger { + background-color: ' . $storefront_theme_mods['button_background_color'] . '; + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + .single-product div.product .woocommerce-product-gallery .woocommerce-product-gallery__trigger:hover { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_background_color'], $darken_factor ) . '; + border-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_background_color'], $darken_factor ) . '; + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + .button.added_to_cart:focus, + .button.wc-forward:focus { + outline-color: ' . $storefront_theme_mods['accent_color'] . '; + } + + .added_to_cart, + .site-header-cart .widget_shopping_cart a.button, + .wc-block-grid__products .wc-block-grid__product .wp-block-button__link { + background-color: ' . $storefront_theme_mods['button_background_color'] . '; + border-color: ' . $storefront_theme_mods['button_background_color'] . '; + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + .added_to_cart:hover, + .site-header-cart .widget_shopping_cart a.button:hover, + .wc-block-grid__products .wc-block-grid__product .wp-block-button__link:hover { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_background_color'], $darken_factor ) . '; + border-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_background_color'], $darken_factor ) . '; + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + .added_to_cart.alt, .added_to_cart, .widget a.button.checkout { + background-color: ' . $storefront_theme_mods['button_alt_background_color'] . '; + border-color: ' . $storefront_theme_mods['button_alt_background_color'] . '; + color: ' . $storefront_theme_mods['button_alt_text_color'] . '; + } + + .added_to_cart.alt:hover, .added_to_cart:hover, .widget a.button.checkout:hover { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_alt_background_color'], $darken_factor ) . '; + border-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['button_alt_background_color'], $darken_factor ) . '; + color: ' . $storefront_theme_mods['button_alt_text_color'] . '; + } + + .button.loading { + color: ' . $storefront_theme_mods['button_background_color'] . '; + } + + .button.loading:hover { + background-color: ' . $storefront_theme_mods['button_background_color'] . '; + } + + .button.loading:after { + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + @media screen and ( min-width: 768px ) { + .site-header-cart .widget_shopping_cart, + .site-header .product_list_widget li .quantity { + color: ' . $storefront_theme_mods['header_text_color'] . '; + } + + .site-header-cart .widget_shopping_cart .buttons, + .site-header-cart .widget_shopping_cart .total { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['header_background_color'], -10 ) . '; + } + + .site-header-cart .widget_shopping_cart { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['header_background_color'], -15 ) . '; + } + }'; + + if ( ! class_exists( 'Storefront_Product_Pagination' ) ) { + $styles .= ' + .storefront-product-pagination a { + color: ' . $storefront_theme_mods['text_color'] . '; + background-color: ' . $storefront_theme_mods['background_color'] . '; + }'; + } + + if ( ! class_exists( 'Storefront_Sticky_Add_to_Cart' ) ) { + $styles .= ' + .storefront-sticky-add-to-cart { + color: ' . $storefront_theme_mods['text_color'] . '; + background-color: ' . $storefront_theme_mods['background_color'] . '; + } + + .storefront-sticky-add-to-cart a:not(.button) { + color: ' . $storefront_theme_mods['header_link_color'] . '; + }'; + } + + return apply_filters( 'storefront_customizer_woocommerce_css', $styles ); + } + + /** + * Add CSS in for styles handled by the theme customizer + * + * @since 2.4.0 + * @return void + */ + public function add_customizer_css() { + wp_add_inline_style( 'storefront-woocommerce-style', $this->get_css() ); + } + + } + +endif; + +return new Storefront_WooCommerce_Customizer(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/class-storefront-woocommerce.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/class-storefront-woocommerce.php new file mode 100644 index 0000000..f8dcde5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/class-storefront-woocommerce.php @@ -0,0 +1,530 @@ + 416, + 'thumbnail_image_width' => 324, + 'product_grid' => array( + 'default_columns' => 3, + 'default_rows' => 4, + 'min_columns' => 1, + 'max_columns' => 6, + 'min_rows' => 1, + ), + ) + ) + ); + + add_theme_support( 'wc-product-gallery-zoom' ); + add_theme_support( 'wc-product-gallery-lightbox' ); + add_theme_support( 'wc-product-gallery-slider' ); + + /** + * Add 'storefront_woocommerce_setup' action. + * + * @since 2.4.0 + */ + do_action( 'storefront_woocommerce_setup' ); + } + + /** + * Add CSS in for styles handled by the theme customizer + * If the Customizer is active pull in the raw css. Otherwise pull in the prepared theme_mods if they exist. + * + * @since 2.1.0 + * @return void + */ + public function add_customizer_css() { + wp_add_inline_style( 'storefront-woocommerce-style', $this->get_woocommerce_extension_css() ); + } + + /** + * Assign styles to individual theme mod. + * + * @deprecated 2.3.1 + * @since 2.1.0 + * @return void + */ + public function set_storefront_style_theme_mods() { + if ( function_exists( 'wc_deprecated_function' ) ) { + wc_deprecated_function( __FUNCTION__, '2.3.1' ); + } else { + _deprecated_function( __FUNCTION__, '2.3.1' ); + } + } + + /** + * Add WooCommerce specific classes to the body tag + * + * @param array $classes css classes applied to the body tag. + * @return array $classes modified to include 'woocommerce-active' class + */ + public function woocommerce_body_class( $classes ) { + $classes[] = 'woocommerce-active'; + + // Remove `no-wc-breadcrumb` body class. + $key = array_search( 'no-wc-breadcrumb', $classes, true ); + + if ( false !== $key ) { + unset( $classes[ $key ] ); + } + + return $classes; + } + + /** + * WooCommerce specific scripts & stylesheets + * + * @since 1.0.0 + */ + public function woocommerce_scripts() { + global $storefront_version; + + $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; + + wp_enqueue_style( 'storefront-woocommerce-style', get_template_directory_uri() . '/assets/css/woocommerce/woocommerce.css', array( 'storefront-style', 'storefront-icons' ), $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-style', 'rtl', 'replace' ); + + wp_register_script( 'storefront-header-cart', get_template_directory_uri() . '/assets/js/woocommerce/header-cart' . $suffix . '.js', array(), $storefront_version, true ); + wp_enqueue_script( 'storefront-header-cart' ); + + wp_enqueue_script( 'storefront-handheld-footer-bar', get_template_directory_uri() . '/assets/js/footer' . $suffix . '.js', array(), $storefront_version, true ); + + if ( ! class_exists( 'Storefront_Sticky_Add_to_Cart' ) && is_product() ) { + wp_register_script( 'storefront-sticky-add-to-cart', get_template_directory_uri() . '/assets/js/sticky-add-to-cart' . $suffix . '.js', array(), $storefront_version, true ); + } + } + + /** + * Star rating backwards compatibility script (WooCommerce <2.5). + * + * @since 1.6.0 + */ + public function star_rating_script() { + if ( is_product() ) { + ?> + + 3, + 'columns' => 3, + ) + ); + + return $args; + } + + /** + * Product gallery thumbnail columns + * + * @return integer number of columns + * @since 1.0.0 + */ + public function thumbnail_columns() { + $columns = 4; + + if ( ! is_active_sidebar( 'sidebar-1' ) ) { + $columns = 5; + } + + return intval( apply_filters( 'storefront_product_thumbnail_columns', $columns ) ); + } + + /** + * Products per page + * + * @return integer number of products + * @since 1.0.0 + */ + public function products_per_page() { + return intval( apply_filters( 'storefront_products_per_page', 12 ) ); + } + + /** + * Query WooCommerce Extension Activation. + * + * @param string $extension Extension class name. + * @return boolean + */ + public function is_woocommerce_extension_activated( $extension = 'WC_Bookings' ) { + return class_exists( $extension ) ? true : false; + } + + /** + * Remove the breadcrumb delimiter + * + * @param array $defaults The breadcrumb defaults. + * @return array The breadcrumb defaults. + * @since 2.2.0 + */ + public function change_breadcrumb_delimiter( $defaults ) { + $defaults['delimiter'] = ' / '; + $defaults['wrap_before'] = '
    '; + return $defaults; + } + + /** + * Integration Styles & Scripts + * + * @return void + */ + public function woocommerce_integrations_scripts() { + global $storefront_version; + + $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; + + /** + * Bookings + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Bookings' ) ) { + wp_enqueue_style( 'storefront-woocommerce-bookings-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/bookings.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-bookings-style', 'rtl', 'replace' ); + } + + /** + * Brands + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Brands' ) ) { + wp_enqueue_style( 'storefront-woocommerce-brands-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/brands.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-brands-style', 'rtl', 'replace' ); + + wp_enqueue_script( 'storefront-woocommerce-brands', get_template_directory_uri() . '/assets/js/woocommerce/extensions/brands' . $suffix . '.js', array(), $storefront_version, true ); + } + + /** + * Wishlists + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Wishlists_Wishlist' ) ) { + wp_enqueue_style( 'storefront-woocommerce-wishlists-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/wishlists.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-wishlists-style', 'rtl', 'replace' ); + } + + /** + * AJAX Layered Nav + */ + if ( $this->is_woocommerce_extension_activated( 'SOD_Widget_Ajax_Layered_Nav' ) ) { + wp_enqueue_style( 'storefront-woocommerce-ajax-layered-nav-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/ajax-layered-nav.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-ajax-layered-nav-style', 'rtl', 'replace' ); + } + + /** + * Variation Swatches + */ + if ( $this->is_woocommerce_extension_activated( 'WC_SwatchesPlugin' ) ) { + wp_enqueue_style( 'storefront-woocommerce-variation-swatches-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/variation-swatches.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-variation-swatches-style', 'rtl', 'replace' ); + } + + /** + * Composite Products + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Composite_Products' ) ) { + wp_enqueue_style( 'storefront-woocommerce-composite-products-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/composite-products.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-composite-products-style', 'rtl', 'replace' ); + } + + /** + * WooCommerce Photography + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Photography' ) ) { + wp_enqueue_style( 'storefront-woocommerce-photography-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/photography.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-photography-style', 'rtl', 'replace' ); + } + + /** + * Product Reviews Pro + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Product_Reviews_Pro' ) ) { + wp_enqueue_style( 'storefront-woocommerce-product-reviews-pro-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/product-reviews-pro.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-product-reviews-pro-style', 'rtl', 'replace' ); + } + + /** + * WooCommerce Smart Coupons + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Smart_Coupons' ) ) { + wp_enqueue_style( 'storefront-woocommerce-smart-coupons-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/smart-coupons.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-smart-coupons-style', 'rtl', 'replace' ); + } + + /** + * WooCommerce Deposits + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Deposits' ) ) { + wp_enqueue_style( 'storefront-woocommerce-deposits-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/deposits.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-deposits-style', 'rtl', 'replace' ); + } + + /** + * WooCommerce Product Bundles + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Bundles' ) ) { + wp_enqueue_style( 'storefront-woocommerce-bundles-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/bundles.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-bundles-style', 'rtl', 'replace' ); + } + + /** + * WooCommerce Multiple Shipping Addresses + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Ship_Multiple' ) ) { + wp_enqueue_style( 'storefront-woocommerce-sma-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/ship-multiple-addresses.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-sma-style', 'rtl', 'replace' ); + } + + /** + * WooCommerce Advanced Product Labels + */ + if ( $this->is_woocommerce_extension_activated( 'Woocommerce_Advanced_Product_Labels' ) ) { + wp_enqueue_style( 'storefront-woocommerce-apl-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/advanced-product-labels.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-apl-style', 'rtl', 'replace' ); + } + + /** + * WooCommerce Mix and Match + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Mix_and_Match' ) ) { + wp_enqueue_style( 'storefront-woocommerce-mix-and-match-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/mix-and-match.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-mix-and-match-style', 'rtl', 'replace' ); + } + + /** + * WooCommerce Memberships + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Memberships' ) ) { + wp_enqueue_style( 'storefront-woocommerce-memberships-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/memberships.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-memberships-style', 'rtl', 'replace' ); + } + + /** + * WooCommerce Quick View + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Quick_View' ) ) { + wp_enqueue_style( 'storefront-woocommerce-quick-view-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/quick-view.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-quick-view-style', 'rtl', 'replace' ); + } + + /** + * Checkout Add Ons + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Checkout_Add_Ons' ) ) { + add_filter( 'storefront_sticky_order_review', '__return_false' ); + } + + /** + * WooCommerce Product Recommendations + */ + if ( $this->is_woocommerce_extension_activated( 'WC_Product_Recommendations' ) ) { + wp_enqueue_style( 'storefront-woocommerce-product-recommendations-style', get_template_directory_uri() . '/assets/css/woocommerce/extensions/product-recommendations.css', 'storefront-woocommerce-style', $storefront_version ); + wp_style_add_data( 'storefront-woocommerce-product-recommendations-style', 'rtl', 'replace' ); + } + } + + /** + * Get extension css. + * + * @see get_storefront_theme_mods() + * @return array $styles the css + */ + public function get_woocommerce_extension_css() { + global $storefront; + + if ( ! is_object( $storefront ) || + ! property_exists( $storefront, 'customizer' ) || + ! is_a( $storefront->customizer, 'Storefront_Customizer' ) || + ! method_exists( $storefront->customizer, 'get_storefront_theme_mods' ) ) { + return apply_filters( 'storefront_customizer_woocommerce_extension_css', '' ); + } + + $storefront_theme_mods = $storefront->customizer->get_storefront_theme_mods(); + + $woocommerce_extension_style = ''; + + if ( $this->is_woocommerce_extension_activated( 'WC_Bookings' ) ) { + $woocommerce_extension_style .= ' + .wc-bookings-date-picker .ui-datepicker td.bookable a { + background-color: ' . $storefront_theme_mods['accent_color'] . ' !important; + } + + .wc-bookings-date-picker .ui-datepicker td.bookable a.ui-state-default { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['accent_color'], -10 ) . ' !important; + } + + .wc-bookings-date-picker .ui-datepicker td.bookable a.ui-state-active { + background-color: ' . storefront_adjust_color_brightness( $storefront_theme_mods['accent_color'], -50 ) . ' !important; + } + '; + } + + if ( $this->is_woocommerce_extension_activated( 'WC_Product_Reviews_Pro' ) ) { + $woocommerce_extension_style .= ' + .woocommerce #reviews .product-rating .product-rating-details table td.rating-graph .bar, + .woocommerce-page #reviews .product-rating .product-rating-details table td.rating-graph .bar { + background-color: ' . $storefront_theme_mods['text_color'] . ' !important; + } + + .woocommerce #reviews .contribution-actions .feedback, + .woocommerce-page #reviews .contribution-actions .feedback, + .star-rating-selector:not(:checked) label.checkbox { + color: ' . $storefront_theme_mods['text_color'] . '; + } + + .woocommerce #reviews #comments ol.commentlist li .contribution-actions a, + .woocommerce-page #reviews #comments ol.commentlist li .contribution-actions a, + .star-rating-selector:not(:checked) input:checked ~ label.checkbox, + .star-rating-selector:not(:checked) label.checkbox:hover ~ label.checkbox, + .star-rating-selector:not(:checked) label.checkbox:hover, + .woocommerce #reviews #comments ol.commentlist li .contribution-actions a, + .woocommerce-page #reviews #comments ol.commentlist li .contribution-actions a, + .woocommerce #reviews .form-contribution .attachment-type:not(:checked) label.checkbox:before, + .woocommerce-page #reviews .form-contribution .attachment-type:not(:checked) label.checkbox:before { + color: ' . $storefront_theme_mods['accent_color'] . ' !important; + }'; + } + + if ( $this->is_woocommerce_extension_activated( 'WC_Smart_Coupons' ) ) { + $woocommerce_extension_style .= ' + .coupon-container { + background-color: ' . $storefront_theme_mods['button_background_color'] . ' !important; + } + + .coupon-content { + border-color: ' . $storefront_theme_mods['button_text_color'] . ' !important; + color: ' . $storefront_theme_mods['button_text_color'] . '; + } + + .sd-buttons-transparent.woocommerce .coupon-content, + .sd-buttons-transparent.woocommerce-page .coupon-content { + border-color: ' . $storefront_theme_mods['button_background_color'] . ' !important; + }'; + } + + return apply_filters( 'storefront_customizer_woocommerce_extension_css', $woocommerce_extension_style ); + } + + /* + |-------------------------------------------------------------------------- + | Integrations. + |-------------------------------------------------------------------------- + */ + + /** + * Sets up integrations. + * + * @since 2.3.4 + * + * @return void + */ + public function setup_integrations() { + + if ( $this->is_woocommerce_extension_activated( 'WC_Bundles' ) ) { + add_filter( 'woocommerce_bundled_table_item_js_enqueued', '__return_true' ); + add_filter( 'woocommerce_bundles_group_mode_options_data', array( $this, 'bundles_group_mode_options_data' ) ); + } + + if ( $this->is_woocommerce_extension_activated( 'WC_Composite_Products' ) ) { + add_filter( 'woocommerce_composited_table_item_js_enqueued', '__return_true' ); + add_filter( 'woocommerce_display_composite_container_cart_item_data', '__return_true' ); + } + } + + /** + * Add "Includes" meta to parent cart items. + * Displayed only on handheld/mobile screens. + * + * @since 2.3.4 + * + * @param array $group_mode_data Group mode data. + * @return array + */ + public function bundles_group_mode_options_data( $group_mode_data ) { + $group_mode_data['parent']['features'][] = 'parent_cart_item_meta'; + + return $group_mode_data; + } + } + +endif; + +return new Storefront_WooCommerce(); diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/storefront-woocommerce-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/storefront-woocommerce-functions.php new file mode 100644 index 0000000..40f7dd3 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/storefront-woocommerce-functions.php @@ -0,0 +1,49 @@ +get_product(); +} + +/** + * Retrieves the next product. + * + * @since 2.4.3 + * + * @param bool $in_same_term Optional. Whether post should be in a same taxonomy term. Default false. + * @param array|string $excluded_terms Optional. Comma-separated list of excluded term IDs. Default empty. + * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'product_cat'. + * @return WC_Product|false Product object if successful. False if no valid product is found. + */ +function storefront_get_next_product( $in_same_term = false, $excluded_terms = '', $taxonomy = 'product_cat' ) { + $product = new Storefront_WooCommerce_Adjacent_Products( $in_same_term, $excluded_terms, $taxonomy ); + return $product->get_product(); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/storefront-woocommerce-template-functions.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/storefront-woocommerce-template-functions.php new file mode 100644 index 0000000..72be768 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/woocommerce/storefront-woocommerce-template-functions.php @@ -0,0 +1,956 @@ +cart instanceof \WC_Cart; + } +} + +if ( ! function_exists( 'storefront_before_content' ) ) { + /** + * Before Content + * Wraps all WooCommerce content in wrappers which match the theme markup + * + * @since 1.0.0 + * @return void + */ + function storefront_before_content() { + ?> +
    +
    + +
    +
    + + + + + cart->get_cart_subtotal() ); ?> cart->get_cart_contents_count(), 'storefront' ), WC()->cart->get_cart_contents_count() ) ); ?> + + + + + + '; + } +} + +if ( ! function_exists( 'storefront_sorting_wrapper_close' ) ) { + /** + * Sorting wrapper close + * + * @since 1.4.3 + * @return void + */ + function storefront_sorting_wrapper_close() { + echo '
    '; + } +} + +if ( ! function_exists( 'storefront_product_columns_wrapper' ) ) { + /** + * Product columns wrapper + * + * @since 2.2.0 + * @return void + */ + function storefront_product_columns_wrapper() { + $columns = storefront_loop_columns(); + echo '
    '; + } +} + +if ( ! function_exists( 'storefront_loop_columns' ) ) { + /** + * Default loop columns on product archives + * + * @return integer products per row + * @since 1.0.0 + */ + function storefront_loop_columns() { + $columns = 3; // 3 products per row + + if ( function_exists( 'wc_get_default_products_per_row' ) ) { + $columns = wc_get_default_products_per_row(); + } + + return apply_filters( 'storefront_loop_columns', $columns ); + } +} + +if ( ! function_exists( 'storefront_product_columns_wrapper_close' ) ) { + /** + * Product columns wrapper close + * + * @since 2.2.0 + * @return void + */ + function storefront_product_columns_wrapper_close() { + echo '
    '; + } +} + +if ( ! function_exists( 'storefront_shop_messages' ) ) { + /** + * Storefront shop messages + * + * @since 1.4.4 + * @uses storefront_do_shortcode + */ + function storefront_shop_messages() { + if ( ! is_checkout() ) { + echo wp_kses_post( storefront_do_shortcode( 'woocommerce_messages' ) ); + } + } +} + +if ( ! function_exists( 'storefront_woocommerce_pagination' ) ) { + /** + * Storefront WooCommerce Pagination + * WooCommerce disables the product pagination inside the woocommerce_product_subcategories() function + * but since Storefront adds pagination before that function is excuted we need a separate function to + * determine whether or not to display the pagination. + * + * @since 1.4.4 + */ + function storefront_woocommerce_pagination() { + if ( woocommerce_products_will_display() ) { + woocommerce_pagination(); + } + } +} + +if ( ! function_exists( 'storefront_product_categories' ) ) { + /** + * Display Product Categories + * Hooked into the `homepage` action in the homepage template + * + * @since 1.0.0 + * @param array $args the product section args. + * @return void + */ + function storefront_product_categories( $args ) { + $args = apply_filters( + 'storefront_product_categories_args', + array( + 'limit' => 3, + 'columns' => 3, + 'child_categories' => 0, + 'orderby' => 'menu_order', + 'title' => __( 'Shop by Category', 'storefront' ), + ) + ); + + $shortcode_content = storefront_do_shortcode( + 'product_categories', + apply_filters( + 'storefront_product_categories_shortcode_args', + array( + 'number' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + 'orderby' => esc_attr( $args['orderby'] ), + 'parent' => esc_attr( $args['child_categories'] ), + ) + ) + ); + + /** + * Only display the section if the shortcode returns product categories + */ + if ( false !== strpos( $shortcode_content, 'product-category' ) ) { + echo '
    '; + + do_action( 'storefront_homepage_before_product_categories' ); + + echo '

    ' . wp_kses_post( $args['title'] ) . '

    '; + + do_action( 'storefront_homepage_after_product_categories_title' ); + + echo $shortcode_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + do_action( 'storefront_homepage_after_product_categories' ); + + echo '
    '; + } + } +} + +if ( ! function_exists( 'storefront_recent_products' ) ) { + /** + * Display Recent Products + * Hooked into the `homepage` action in the homepage template + * + * @since 1.0.0 + * @param array $args the product section args. + * @return void + */ + function storefront_recent_products( $args ) { + $args = apply_filters( + 'storefront_recent_products_args', + array( + 'limit' => 4, + 'columns' => 4, + 'orderby' => 'date', + 'order' => 'desc', + 'title' => __( 'New In', 'storefront' ), + ) + ); + + $shortcode_content = storefront_do_shortcode( + 'products', + apply_filters( + 'storefront_recent_products_shortcode_args', + array( + 'orderby' => esc_attr( $args['orderby'] ), + 'order' => esc_attr( $args['order'] ), + 'per_page' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + ) + ) + ); + + /** + * Only display the section if the shortcode returns products + */ + if ( false !== strpos( $shortcode_content, 'product' ) ) { + echo '
    '; + + do_action( 'storefront_homepage_before_recent_products' ); + + echo '

    ' . wp_kses_post( $args['title'] ) . '

    '; + + do_action( 'storefront_homepage_after_recent_products_title' ); + + echo $shortcode_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + do_action( 'storefront_homepage_after_recent_products' ); + + echo '
    '; + } + } +} + +if ( ! function_exists( 'storefront_featured_products' ) ) { + /** + * Display Featured Products + * Hooked into the `homepage` action in the homepage template + * + * @since 1.0.0 + * @param array $args the product section args. + * @return void + */ + function storefront_featured_products( $args ) { + $args = apply_filters( + 'storefront_featured_products_args', + array( + 'limit' => 4, + 'columns' => 4, + 'orderby' => 'date', + 'order' => 'desc', + 'visibility' => 'featured', + 'title' => __( 'We Recommend', 'storefront' ), + ) + ); + + $shortcode_content = storefront_do_shortcode( + 'products', + apply_filters( + 'storefront_featured_products_shortcode_args', + array( + 'per_page' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + 'orderby' => esc_attr( $args['orderby'] ), + 'order' => esc_attr( $args['order'] ), + 'visibility' => esc_attr( $args['visibility'] ), + ) + ) + ); + + /** + * Only display the section if the shortcode returns products + */ + if ( false !== strpos( $shortcode_content, 'product' ) ) { + echo ''; + } + } +} + +if ( ! function_exists( 'storefront_popular_products' ) ) { + /** + * Display Popular Products + * Hooked into the `homepage` action in the homepage template + * + * @since 1.0.0 + * @param array $args the product section args. + * @return void + */ + function storefront_popular_products( $args ) { + $args = apply_filters( + 'storefront_popular_products_args', + array( + 'limit' => 4, + 'columns' => 4, + 'orderby' => 'rating', + 'order' => 'desc', + 'title' => __( 'Fan Favorites', 'storefront' ), + ) + ); + + $shortcode_content = storefront_do_shortcode( + 'products', + apply_filters( + 'storefront_popular_products_shortcode_args', + array( + 'per_page' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + 'orderby' => esc_attr( $args['orderby'] ), + 'order' => esc_attr( $args['order'] ), + ) + ) + ); + + /** + * Only display the section if the shortcode returns products + */ + if ( false !== strpos( $shortcode_content, 'product' ) ) { + echo ''; + } + } +} + +if ( ! function_exists( 'storefront_on_sale_products' ) ) { + /** + * Display On Sale Products + * Hooked into the `homepage` action in the homepage template + * + * @param array $args the product section args. + * @since 1.0.0 + * @return void + */ + function storefront_on_sale_products( $args ) { + $args = apply_filters( + 'storefront_on_sale_products_args', + array( + 'limit' => 4, + 'columns' => 4, + 'orderby' => 'date', + 'order' => 'desc', + 'on_sale' => 'true', + 'title' => __( 'On Sale', 'storefront' ), + ) + ); + + $shortcode_content = storefront_do_shortcode( + 'products', + apply_filters( + 'storefront_on_sale_products_shortcode_args', + array( + 'per_page' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + 'orderby' => esc_attr( $args['orderby'] ), + 'order' => esc_attr( $args['order'] ), + 'on_sale' => esc_attr( $args['on_sale'] ), + ) + ) + ); + + /** + * Only display the section if the shortcode returns products + */ + if ( false !== strpos( $shortcode_content, 'product' ) ) { + echo '
    '; + + do_action( 'storefront_homepage_before_on_sale_products' ); + + echo '

    ' . wp_kses_post( $args['title'] ) . '

    '; + + do_action( 'storefront_homepage_after_on_sale_products_title' ); + + echo $shortcode_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + do_action( 'storefront_homepage_after_on_sale_products' ); + + echo '
    '; + } + } +} + +if ( ! function_exists( 'storefront_best_selling_products' ) ) { + /** + * Display Best Selling Products + * Hooked into the `homepage` action in the homepage template + * + * @since 2.0.0 + * @param array $args the product section args. + * @return void + */ + function storefront_best_selling_products( $args ) { + $args = apply_filters( + 'storefront_best_selling_products_args', + array( + 'limit' => 4, + 'columns' => 4, + 'orderby' => 'popularity', + 'order' => 'desc', + 'title' => esc_attr__( 'Best Sellers', 'storefront' ), + ) + ); + + $shortcode_content = storefront_do_shortcode( + 'products', + apply_filters( + 'storefront_best_selling_products_shortcode_args', + array( + 'per_page' => intval( $args['limit'] ), + 'columns' => intval( $args['columns'] ), + 'orderby' => esc_attr( $args['orderby'] ), + 'order' => esc_attr( $args['order'] ), + ) + ) + ); + + /** + * Only display the section if the shortcode returns products + */ + if ( false !== strpos( $shortcode_content, 'product' ) ) { + echo '
    '; + + do_action( 'storefront_homepage_before_best_selling_products' ); + + echo '

    ' . wp_kses_post( $args['title'] ) . '

    '; + + do_action( 'storefront_homepage_after_best_selling_products_title' ); + + echo $shortcode_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + do_action( 'storefront_homepage_after_best_selling_products' ); + + echo '
    '; + } + } +} + +if ( ! function_exists( 'storefront_promoted_products' ) ) { + /** + * Featured and On-Sale Products + * Check for featured products then on-sale products and use the appropiate shortcode. + * If neither exist, it can fallback to show recently added products. + * + * @since 1.5.1 + * @param integer $per_page total products to display. + * @param integer $columns columns to arrange products in to. + * @param boolean $recent_fallback Should the function display recent products as a fallback when there are no featured or on-sale products?. + * @uses storefront_is_woocommerce_activated() + * @uses wc_get_featured_product_ids() + * @uses wc_get_product_ids_on_sale() + * @uses storefront_do_shortcode() + * @return void + */ + function storefront_promoted_products( $per_page = '2', $columns = '2', $recent_fallback = true ) { + if ( storefront_is_woocommerce_activated() ) { + + if ( wc_get_featured_product_ids() ) { + + echo '

    ' . esc_html__( 'Featured Products', 'storefront' ) . '

    '; + + // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped + echo storefront_do_shortcode( + 'featured_products', + array( + 'per_page' => $per_page, + 'columns' => $columns, + ) + ); + // phpcs:enable + } elseif ( wc_get_product_ids_on_sale() ) { + + echo '

    ' . esc_html__( 'On Sale Now', 'storefront' ) . '

    '; + + // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped + echo storefront_do_shortcode( + 'sale_products', + array( + 'per_page' => $per_page, + 'columns' => $columns, + ) + ); + // phpcs:enable + } elseif ( $recent_fallback ) { + + echo '

    ' . esc_html__( 'New In Store', 'storefront' ) . '

    '; + + // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped + echo storefront_do_shortcode( + 'recent_products', + array( + 'per_page' => $per_page, + 'columns' => $columns, + ) + ); + // phpcs:enable + } + } + } +} + +if ( ! function_exists( 'storefront_handheld_footer_bar' ) ) { + /** + * Display a menu intended for use on handheld devices + * + * @since 2.0.0 + */ + function storefront_handheld_footer_bar() { + $links = array( + 'my-account' => array( + 'priority' => 10, + 'callback' => 'storefront_handheld_footer_bar_account_link', + ), + 'search' => array( + 'priority' => 20, + 'callback' => 'storefront_handheld_footer_bar_search', + ), + 'cart' => array( + 'priority' => 30, + 'callback' => 'storefront_handheld_footer_bar_cart_link', + ), + ); + + if ( did_action( 'woocommerce_blocks_enqueue_cart_block_scripts_after' ) || did_action( 'woocommerce_blocks_enqueue_checkout_block_scripts_after' ) ) { + return; + } + + if ( wc_get_page_id( 'myaccount' ) === -1 ) { + unset( $links['my-account'] ); + } + + if ( wc_get_page_id( 'cart' ) === -1 ) { + unset( $links['cart'] ); + } + + $links = apply_filters( 'storefront_handheld_footer_bar_links', $links ); + ?> + + ' . esc_attr__( 'Search', 'storefront' ) . ''; + storefront_product_search(); + } +} + +if ( ! function_exists( 'storefront_handheld_footer_bar_cart_link' ) ) { + /** + * The cart callback function for the handheld footer bar + * + * @since 2.0.0 + */ + function storefront_handheld_footer_bar_cart_link() { + if ( ! storefront_woo_cart_available() ) { + return; + } + ?> + + cart->get_cart_contents_count() ); ?> + + ' . esc_attr__( 'My Account', 'storefront' ) . ''; + } +} + +if ( ! function_exists( 'storefront_single_product_pagination' ) ) { + /** + * Single Product Pagination + * + * @since 2.3.0 + */ + function storefront_single_product_pagination() { + if ( class_exists( 'Storefront_Product_Pagination' ) || true !== get_theme_mod( 'storefront_product_pagination' ) ) { + return; + } + + // Show only products in the same category? + $in_same_term = apply_filters( 'storefront_single_product_pagination_same_category', true ); + $excluded_terms = apply_filters( 'storefront_single_product_pagination_excluded_terms', '' ); + $taxonomy = apply_filters( 'storefront_single_product_pagination_taxonomy', 'product_cat' ); + + $previous_product = storefront_get_previous_product( $in_same_term, $excluded_terms, $taxonomy ); + $next_product = storefront_get_next_product( $in_same_term, $excluded_terms, $taxonomy ); + + if ( ! $previous_product && ! $next_product ) { + return; + } + + ?> + + is_purchasable() && $product->is_in_stock() ) { + $show = true; + } elseif ( $product->is_type( 'external' ) ) { + $show = true; + } + + if ( ! $show ) { + return; + } + + $params = apply_filters( + 'storefront_sticky_add_to_cart_params', + array( + 'trigger_class' => 'entry-summary', + ) + ); + + wp_localize_script( 'storefront-sticky-add-to-cart', 'storefront_sticky_add_to_cart_params', $params ); + + wp_enqueue_script( 'storefront-sticky-add-to-cart' ); + ?> +
    +
    +
    + +
    + + get_price_html() ); ?> + get_average_rating() ) ); ?> +
    + + add_to_cart_text() ); ?> + +
    +
    +
    + 6, + 'columns' => 4, + 'orderby' => 'name', + 'show_empty' => false, + 'title' => __( 'Shop by Brand', 'storefront' ), + ) + ); + + $shortcode_content = storefront_do_shortcode( + 'product_brand_thumbnails', + apply_filters( + 'storefront_woocommerce_brands_shortcode_args', + array( + 'number' => absint( $args['number'] ), + 'columns' => absint( $args['columns'] ), + 'orderby' => esc_attr( $args['orderby'] ), + 'show_empty' => (bool) $args['show_empty'], + ) + ) + ); + + echo '
    '; + + do_action( 'storefront_homepage_before_woocommerce_brands' ); + + echo '

    ' . wp_kses_post( $args['title'] ) . '

    '; + + do_action( 'storefront_homepage_after_woocommerce_brands_title' ); + + echo $shortcode_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + do_action( 'storefront_homepage_after_woocommerce_brands' ); + + echo '
    '; + } +} + +if ( ! function_exists( 'storefront_woocommerce_brands_archive' ) ) { + /** + * Display brand image on brand archives + * Requires WooCommerce Brands. + * + * @since 2.3.0 + * @link https://woocommerce.com/products/brands/ + * @uses is_tax() + * @uses wp_kses_post() + * @uses get_brand_thumbnail_image() + * @uses get_queried_object() + * @return void + */ + function storefront_woocommerce_brands_archive() { + if ( is_tax( 'product_brand' ) ) { + echo wp_kses_post( get_brand_thumbnail_image( get_queried_object() ) ); + } + } +} + +if ( ! function_exists( 'storefront_woocommerce_brands_single' ) ) { + /** + * Output product brand image for use on single product pages + * Requires WooCommerce Brands. + * + * @since 2.3.0 + * @link https://woocommerce.com/products/brands/ + * @uses storefront_do_shortcode() + * @uses wp_kses_post() + * @return void + */ + function storefront_woocommerce_brands_single() { + $brand = storefront_do_shortcode( + 'product_brand', + array( + 'class' => '', + ) + ); + + if ( empty( $brand ) ) { + return; + } + + ?> +
    + +
    + =' ) ) { + add_filter( 'woocommerce_add_to_cart_fragments', 'storefront_cart_link_fragment' ); +} else { + add_filter( 'add_to_cart_fragments', 'storefront_cart_link_fragment' ); +} + +/** + * Integrations + * + * @see storefront_woocommerce_brands_archive() + * @see storefront_woocommerce_brands_single() + * @see storefront_woocommerce_brands_homepage_section() + */ +if ( class_exists( 'WC_Brands' ) ) { + add_action( 'woocommerce_archive_description', 'storefront_woocommerce_brands_archive', 5 ); + add_action( 'woocommerce_single_product_summary', 'storefront_woocommerce_brands_single', 4 ); + add_action( 'homepage', 'storefront_woocommerce_brands_homepage_section', 80 ); +} diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/wordpress-shims.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/wordpress-shims.php new file mode 100644 index 0000000..9a3e7b5 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/inc/wordpress-shims.php @@ -0,0 +1,19 @@ + + +
    +
    + + + +
    +
    + + +msgid "" +msgstr "" +"Project-Id-Version: Storefront 2.9.0\n" +"Report-Msgid-Bugs-To: https://github.com/woothemes/storefront/issues\n" +"POT-Creation-Date: 2020-11-10 10:08:33+00:00\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"X-Generator: grunt-wp-i18n 1.0.3\n" + +#: 404.php:19 +msgid "Oops! That page can’t be found." +msgstr "" + +#: 404.php:22 +msgid "" +"Nothing was found at this location. Try searching, or check out the links " +"below." +msgstr "" + +#: 404.php:25 inc/woocommerce/storefront-woocommerce-template-functions.php:716 +msgid "Search" +msgstr "" + +#: 404.php:39 +msgid "Promoted Products" +msgstr "" + +#: 404.php:45 404.php:47 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:297 +msgid "Product Categories" +msgstr "" + +#: 404.php:60 404.php:62 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:464 +msgid "Popular Products" +msgstr "" + +#: comments.php:21 +msgid "Post Comments" +msgstr "" + +#: comments.php:40 +msgid "Comment Navigation Above" +msgstr "" + +#: comments.php:41 comments.php:61 +msgid "Comment navigation" +msgstr "" + +#: comments.php:42 comments.php:62 +msgid "← Older Comments" +msgstr "" + +#: comments.php:43 comments.php:63 +msgid "Newer Comments →" +msgstr "" + +#: comments.php:60 +msgid "Comment Navigation Below" +msgstr "" + +#: comments.php:72 +msgid "Comments are closed." +msgstr "" + +#: content-none.php:14 +msgid "Nothing Found" +msgstr "" + +#: content-none.php:23 +#. translators: 1: URL +msgid "Ready to publish your first post? Get started here." +msgstr "" + +#: content-none.php:29 +msgid "" +"Sorry, but nothing matched your search terms. Please try again with some " +"different keywords." +msgstr "" + +#: content-none.php:34 +msgid "" +"It seems we can’t find what you’re looking for. Perhaps " +"searching can help." +msgstr "" + +#: inc/admin/class-storefront-admin.php:72 +msgid "Support" +msgstr "" + +#: inc/admin/class-storefront-admin.php:73 +msgid "Documentation" +msgstr "" + +#: inc/admin/class-storefront-admin.php:74 +msgid "Development blog" +msgstr "" + +#: inc/admin/class-storefront-admin.php:91 +#. translators: 1: HTML, 2: HTML +msgid "Setup complete %1$sYour Storefront adventure begins now 🚀%2$s " +msgstr "" + +#: inc/admin/class-storefront-admin.php:92 +msgid "" +"One more thing... You might be interested in the following Storefront " +"extensions and designs." +msgstr "" + +#: inc/admin/class-storefront-admin.php:94 +msgid "" +"Hello! You might be interested in the following Storefront extensions and " +"designs." +msgstr "" + +#: inc/admin/class-storefront-admin.php:101 +msgid "Storefront Extensions Bundle" +msgstr "" + +#: inc/admin/class-storefront-admin.php:107 +msgid "All the tools you'll need to define your style and customize Storefront." +msgstr "" + +#: inc/admin/class-storefront-admin.php:111 +msgid "" +"Make it yours without touching code with the Storefront Extensions bundle. " +"Express yourself, optimize conversions, delight customers." +msgstr "" + +#: inc/admin/class-storefront-admin.php:116 +msgid "Read more and purchase" +msgstr "" + +#: inc/admin/class-storefront-admin.php:120 +msgid "Alternate designs" +msgstr "" + +#: inc/admin/class-storefront-admin.php:124 +msgid "" +"Quickly and easily transform your shops appearance with Storefront child " +"themes." +msgstr "" + +#: inc/admin/class-storefront-admin.php:128 +msgid "Each has been designed to serve a different industry - from fashion to food." +msgstr "" + +#: inc/admin/class-storefront-admin.php:132 +msgid "Of course they are all fully compatible with each Storefront extension." +msgstr "" + +#: inc/admin/class-storefront-admin.php:136 +msgid "Check 'em out" +msgstr "" + +#: inc/admin/class-storefront-admin.php:145 +#. translators: %s: Automattic branding +msgid "An %s project" +msgstr "" + +#: inc/admin/class-storefront-admin.php:174 +#: inc/admin/class-storefront-plugin-install.php:62 +msgid "Activated" +msgstr "" + +#: inc/admin/class-storefront-admin.php:183 +#: inc/admin/class-storefront-plugin-install.php:75 +msgid "Activate" +msgstr "" + +#: inc/admin/class-storefront-admin.php:200 +#: inc/admin/class-storefront-plugin-install.php:96 +msgid "Install now" +msgstr "" + +#: inc/admin/class-storefront-admin.php:207 +msgid "Learn more" +msgstr "" + +#: inc/admin/class-storefront-plugin-install.php:115 +#. translators: conjunction of two alternative options user can choose (in +#. missing plugin admin notice). Example: "Activate WooCommerce or learn more" +msgid "or" +msgstr "" + +#: inc/admin/class-storefront-plugin-install.php:116 +msgid "learn more" +msgstr "" + +#: inc/class-storefront.php:97 +#: inc/nux/class-storefront-nux-starter-content.php:162 +msgid "Primary Menu" +msgstr "" + +#: inc/class-storefront.php:98 +#: inc/nux/class-storefront-nux-starter-content.php:182 +msgid "Secondary Menu" +msgstr "" + +#: inc/class-storefront.php:99 +#: inc/nux/class-storefront-nux-starter-content.php:192 +msgid "Handheld Menu" +msgstr "" + +#: inc/class-storefront.php:204 +msgid "Small" +msgstr "" + +#: inc/class-storefront.php:209 +msgid "Normal" +msgstr "" + +#: inc/class-storefront.php:214 +msgid "Medium" +msgstr "" + +#: inc/class-storefront.php:219 +msgid "Large" +msgstr "" + +#: inc/class-storefront.php:224 +msgid "Huge" +msgstr "" + +#: inc/class-storefront.php:249 +msgid "Sidebar" +msgstr "" + +#: inc/class-storefront.php:255 +msgid "Below Header" +msgstr "" + +#: inc/class-storefront.php:257 +msgid "" +"Widgets added to this region will appear beneath the header and above the " +"main content." +msgstr "" + +#: inc/class-storefront.php:270 +#. translators: 1: column number +msgid "Footer Column %1$d" +msgstr "" + +#: inc/class-storefront.php:273 +#. translators: 1: column number +msgid "Widgets added here will appear in column %1$d of the footer." +msgstr "" + +#: inc/class-storefront.php:276 +#. translators: 1: row number, 2: column number +msgid "Footer Row %1$d - Column %2$d" +msgstr "" + +#: inc/class-storefront.php:279 +#. translators: 1: column number, 2: row number +msgid "Widgets added here will appear in column %1$d of footer row %2$d." +msgstr "" + +#: inc/class-storefront.php:352 +msgid "Expand child menu" +msgstr "" + +#: inc/class-storefront.php:353 +msgid "Collapse child menu" +msgstr "" + +#: inc/class-storefront.php:522 +msgid "Post Navigation" +msgstr "" + +#: inc/customizer/class-storefront-customizer-control-more.php:29 +#. translators: 1: Storefront, 2: start tag, 3: Storefront, 4: end tag +msgid "" +"There's a range of %1$s extensions available to put additional power in " +"your hands. Check out the %2$s%3$s%4$s page in your dashboard for more " +"information." +msgstr "" + +#: inc/customizer/class-storefront-customizer-control-more.php:36 +#. translators: %s: Storefront +msgid "Enjoying %s?" +msgstr "" + +#: inc/customizer/class-storefront-customizer-control-more.php:43 +#. translators: 1: start tag, 2: end tag +msgid "" +"Why not leave us a review on %1$sWordPress.org%2$s? We'd really appreciate " +"it!" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:123 +msgid "Background" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:127 +msgid "Header" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:176 +msgid "Typography" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:197 +#: inc/customizer/class-storefront-customizer.php:438 +msgid "Heading color" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:221 +#: inc/customizer/class-storefront-customizer.php:354 +#: inc/customizer/class-storefront-customizer.php:462 +#: inc/customizer/class-storefront-customizer.php:546 +msgid "Text color" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:245 +msgid "Link / accent color" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:269 +msgid "Hero heading color" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:293 +msgid "Hero text color" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:308 +msgid "Header background image" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:330 +#: inc/customizer/class-storefront-customizer.php:414 +#: inc/customizer/class-storefront-customizer.php:522 +msgid "Background color" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:378 +#: inc/customizer/class-storefront-customizer.php:486 +msgid "Link color" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:392 +msgid "Footer" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:394 +msgid "Customize the look & feel of your website footer." +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:500 +msgid "Buttons" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:502 +msgid "Customize the look & feel of your website buttons." +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:570 +msgid "Alternate button background color" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:594 +msgid "Alternate button text color" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:608 +msgid "Layout" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:628 +msgid "General Layout" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:645 +msgid "More" +msgstr "" + +#: inc/customizer/class-storefront-customizer.php:663 +msgid "Looking for more options?" +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:84 +msgid "Thanks for installing Storefront, you rock! 🤘" +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:85 +msgid "To enable eCommerce features you need to install the WooCommerce plugin." +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:86 +msgid "WooCommerce activated" +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:86 +msgid "Activate WooCommerce" +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:86 +msgid "Install WooCommerce" +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:90 +msgid "Design your store 🎨" +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:94 +msgid "" +"Before you add your first product let's design your store. We'll add some " +"example products for you. When you're ready let's get started by adding " +"your logo." +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:96 +msgid "" +"You've set up WooCommerce, now it's time to give it some style! Let's get " +"started by entering the Customizer and adding your logo." +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:117 +msgid "Apply the Storefront homepage template" +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:119 +msgid "Create a homepage using Storefront's homepage template" +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:127 +msgid "Add example products" +msgstr "" + +#: inc/nux/class-storefront-nux-admin.php:132 +#: inc/nux/class-storefront-nux-guided-tour.php:112 +msgid "Let's go!" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:83 +msgid "Next" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:89 +msgid "No thanks, skip the tour" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:91 +msgid "Skip this step" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:109 +msgid "Welcome to the Customizer" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:111 +#. translators: %s: 'End Of Line' symbol +msgid "" +"Here you can control the overall look and feel of your store.%sTo get " +"started, let's add your logo" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:118 +msgid "Add your logo" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:119 +msgid "" +"Open the Site Identity Panel, then click the 'Select Logo' button to upload " +"your logo." +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:125 +msgid "Customize your navigation menus" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:126 +msgid "Organize your menus by adding Pages, Categories, Tags, and Custom Links." +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:131 +msgid "Choose your accent color" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:132 +msgid "" +"In the typography panel you can specify an accent color which will be " +"applied to things like links and star ratings. We recommend using your " +"brand color for this setting." +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:137 +msgid "Color your buttons" +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:138 +msgid "" +"Choose colors for your button backgrounds and text. Once again, brand " +"colors are good choices here." +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:145 +#. translators: 1: open tag, 2: close tag, 3: 'End Of Line' +#. symbol +msgid "" +"All set! Remember to %1$ssave & publish%2$s your changes when you're " +"done.%3$sYou can return to your dashboard by clicking the X in the top left " +"corner." +msgstr "" + +#: inc/nux/class-storefront-nux-guided-tour.php:147 +msgid "Done" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:71 +msgid "About" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:72 +msgid "" +"You might be an artist who would like to introduce yourself and your work " +"here or maybe you’re a business with a mission to describe." +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:76 +msgid "Contact" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:77 +msgid "" +"This is a page with some basic contact information, such as an address and " +"phone number. You might also try a plugin to add a contact form." +msgstr "" + +#. Template Name of the plugin/theme +msgid "Homepage" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:213 +#: inc/nux/class-storefront-nux-starter-content.php:1095 +msgid "Welcome" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:215 +#. translators: %s: 'End Of Line' symbol +msgid "" +"This is your homepage which is what most visitors will see when they first " +"visit your shop.%sYou can change this text by editing the \"Welcome\" page " +"via the \"Pages\" menu in your dashboard." +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:725 +msgid "Accessories" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:726 +#: inc/nux/class-storefront-nux-starter-content.php:729 +#: inc/nux/class-storefront-nux-starter-content.php:732 +msgid "A short category description" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:728 +msgid "Hoodies" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:731 +msgid "Tshirts" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:737 +msgid "Beanie" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:759 +msgid "Belt" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:781 +msgid "Cap" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:803 +msgid "Sunglasses" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:824 +msgid "Hoodie with Logo" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:845 +msgid "Hoodie with Pocket" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:867 +msgid "Hoodie with Zipper" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:888 +msgid "Hoodie" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:910 +msgid "Long Sleeve Tee" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:931 +msgid "Polo" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:952 +msgid "Tshirt" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:973 +msgid "Vneck Tshirt" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:1042 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:276 +msgid "Shop by Category" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:1050 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:331 +msgid "New In" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:1058 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:443 +msgid "Fan Favorites" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:1064 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:499 +msgid "On Sale" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:1070 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:555 +msgid "Best Sellers" +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:1099 +msgid "" +"This is your homepage which is what most visitors will see when they first " +"visit your shop." +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:1103 +msgid "" +"You can change this text by editing the \"Welcome\" page via the \"Pages\" " +"menu in your dashboard." +msgstr "" + +#: inc/nux/class-storefront-nux-starter-content.php:1129 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:387 +msgid "We Recommend" +msgstr "" + +#: inc/storefront-template-functions.php:48 +msgid "Your comment is awaiting moderation." +msgstr "" + +#: inc/storefront-template-functions.php:75 +msgid "Edit" +msgstr "" + +#: inc/storefront-template-functions.php:142 +msgid "WooCommerce - The Best eCommerce Platform for WordPress" +msgstr "" + +#: inc/storefront-template-functions.php:142 +msgid "Built with Storefront & WooCommerce" +msgstr "" + +#: inc/storefront-template-functions.php:144 +msgid "Storefront - The perfect platform for your next WooCommerce project." +msgstr "" + +#: inc/storefront-template-functions.php:144 +msgid "Built with Storefront" +msgstr "" + +#: inc/storefront-template-functions.php:241 +msgid "Primary Navigation" +msgstr "" + +#: inc/storefront-template-functions.php:242 +msgid "Menu" +msgstr "" + +#: inc/storefront-template-functions.php:273 +msgid "Secondary Navigation" +msgstr "" + +#: inc/storefront-template-functions.php:297 +msgid "Skip to navigation" +msgstr "" + +#: inc/storefront-template-functions.php:298 +msgid "Skip to content" +msgstr "" + +#: inc/storefront-template-functions.php:310 +msgid "Edit this section" +msgstr "" + +#: inc/storefront-template-functions.php:356 +#: inc/storefront-template-functions.php:427 +msgid "Pages:" +msgstr "" + +#: inc/storefront-template-functions.php:418 +#. translators: %s: post title +msgid "Continue reading %s" +msgstr "" + +#: inc/storefront-template-functions.php:468 +#. translators: %s: post date +msgid "Posted on %s" +msgstr "" + +#: inc/storefront-template-functions.php:474 +msgid "by" +msgstr "" + +#: inc/storefront-template-functions.php:483 +msgid "Leave a comment" +msgstr "" + +#: inc/storefront-template-functions.php:483 +msgid "1 Comment" +msgstr "" + +#: inc/storefront-template-functions.php:483 +msgid "% Comments" +msgstr "" + +#: inc/storefront-template-functions.php:523 +#. translators: %s: Name of current post. Only visible to screen readers +msgid "Edit %s" +msgstr "" + +#: inc/storefront-template-functions.php:546 +#: inc/storefront-template-functions.php:549 +#. translators: used between list items, there is a space after the comma +msgid ", " +msgstr "" + +#: inc/storefront-template-functions.php:555 +msgid "Category:" +msgid_plural "Categories:" +msgstr[0] "" +msgstr[1] "" + +#: inc/storefront-template-functions.php:561 +msgid "Tag:" +msgid_plural "Tags:" +msgstr[0] "" +msgstr[1] "" + +#: inc/storefront-template-functions.php:593 +msgid "Next post:" +msgstr "" + +#: inc/storefront-template-functions.php:594 +msgid "Previous post:" +msgstr "" + +#: inc/woocommerce/class-storefront-woocommerce-customizer.php:60 +msgid "Product Page" +msgstr "" + +#: inc/woocommerce/class-storefront-woocommerce-customizer.php:87 +msgid "Sticky Add-To-Cart" +msgstr "" + +#: inc/woocommerce/class-storefront-woocommerce-customizer.php:88 +msgid "" +"A small content bar at the top of the browser window which includes " +"relevant product information and an add-to-cart button. It slides into view " +"once the standard add-to-cart button has scrolled out of view." +msgstr "" + +#: inc/woocommerce/class-storefront-woocommerce-customizer.php:98 +msgid "Product Pagination" +msgstr "" + +#: inc/woocommerce/class-storefront-woocommerce-customizer.php:99 +msgid "" +"Displays next and previous links on product pages. A product thumbnail is " +"displayed with the title revealed on hover." +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:91 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:732 +msgid "View your shopping cart" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:93 +#. translators: %d: number of items in cart +msgid "%d item" +msgid_plural "%d items" +msgstr[0] "" +msgstr[1] "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:352 +msgid "Recent Products" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:409 +#: inc/woocommerce/storefront-woocommerce-template-functions.php:614 +msgid "Featured Products" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:521 +msgid "On Sale Products" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:576 +msgid "Best Selling Products" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:627 +msgid "On Sale Now" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:640 +msgid "New In Store" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:746 +msgid "My Account" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:774 +msgid "More products" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:838 +msgid "You're viewing:" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:874 +msgid "Shop by Brand" +msgstr "" + +#: inc/woocommerce/storefront-woocommerce-template-functions.php:891 +msgid "Product Brands" +msgstr "" + +#: search.php:19 +#. translators: %s: search term +msgid "Search Results for: %s" +msgstr "" + +#. Theme Name of the plugin/theme +msgid "Storefront" +msgstr "" + +#. Theme URI of the plugin/theme +msgid "https://woocommerce.com/storefront/" +msgstr "" + +#. Description of the plugin/theme +msgid "" +"Storefront is the perfect theme for your next WooCommerce project. Designed " +"and developed by WooCommerce Core developers, it features a bespoke " +"integration with WooCommerce itself plus many of the most popular customer " +"facing WooCommerce extensions. There are several layout & color options to " +"personalise your shop, multiple widget regions, a responsive design and " +"much more. Developers will love its lean and extensible codebase making it " +"a joy to customize and extend. Looking for a WooCommerce theme? Look no " +"further!" +msgstr "" + +#. Author of the plugin/theme +msgid "Automattic" +msgstr "" + +#. Author URI of the plugin/theme +msgid "https://woocommerce.com/" +msgstr "" + +#. Template Name of the plugin/theme +msgid "Full width" +msgstr "" + +#: comments.php:31 +#. translators: 1: number of comments, 2: post title +msgctxt "comments title" +msgid "%1$s thought on “%2$s”" +msgid_plural "%1$s thoughts on “%2$s”" +msgstr[0] "" +msgstr[1] "" + +#: inc/storefront-template-functions.php:579 +msgctxt "Next post" +msgid "Next" +msgstr "" + +#: inc/storefront-template-functions.php:580 +msgctxt "Previous post" +msgid "Previous" +msgstr "" \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/loop.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/loop.php new file mode 100644 index 0000000..536c2d9 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/loop.php @@ -0,0 +1,30 @@ + + +
    +
    + + + +
    +
    + + + +
    +
    + + + + + + + +
    +
    + + + + diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/single.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/single.php new file mode 100644 index 0000000..1af9988 --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/single.php @@ -0,0 +1,31 @@ + + +
    +
    + + + +
    +
    + +ol,li>ul{margin-bottom:0;margin-right:1em}dt{font-weight:600}dd{margin:0 0 1.618em}b,strong{font-weight:600}blockquote,cite,dfn,em,i{font-style:italic}blockquote{padding:0 1em;border-right:3px solid rgba(0,0,0,.05)}address{margin:0 0 1.41575em}pre{background:rgba(0,0,0,.1);font-family:Courier\ 10 Pitch,Courier,monospace;margin-bottom:1.618em;padding:1.618em;overflow:auto;max-width:100%}code,kbd,tt,var{font-family:Monaco,Consolas,Andale Mono,DejaVu Sans Mono,monospace;background-color:rgba(0,0,0,.05);padding:.202em .5407911001em}abbr,acronym{border-bottom:1px dotted #666;cursor:help}ins,mark{text-decoration:none;font-weight:600;background:rgba(0,0,0,0)}sub,sup{font-size:75%;height:0;line-height:0;position:relative;vertical-align:baseline}sup{bottom:1ex}sub{top:.5ex}small{font-size:75%}big{font-size:125%}figure{margin:0}img{height:auto;max-width:100%;display:block;border-radius:3px}a{color:#2c2d33;text-decoration:none}a:focus,button:focus,input:focus,textarea:focus{outline:2px solid #96588a}.storefront-cute *{font-family:Comic Sans MS,sans-serif}*{box-sizing:border-box}body{background-color:#fff}.site,body{overflow-x:hidden}.header-widget-region,.site-content{-webkit-tap-highlight-color:rgba(0,0,0,0)}.site-header{background-color:#2c2d33;padding-top:1.618em;padding-bottom:1.618em;color:#9aa0a7;background-position:50%;position:relative;z-index:999;border-bottom:1px solid rgba(0,0,0,0)}.site-header .custom-logo-link,.site-header .site-logo-anchor,.site-header .site-logo-link{display:block;margin-bottom:0}.site-header .custom-logo-link img,.site-header .site-logo-anchor img,.site-header .site-logo-link img{width:100%;max-width:210px}.site-header .widget{margin-bottom:0}.home.blog .site-header,.home.page:not(.page-template-template-homepage) .site-header,.home.post-type-archive-product .site-header{margin-bottom:4.235801032em}.no-wc-breadcrumb .site-header{margin-bottom:4.235801032em}.no-wc-breadcrumb.page-template-template-homepage .site-header{margin-bottom:0}.header-widget-region{position:relative;z-index:99}.header-widget-region:after,.header-widget-region:before{content:"";display:table}.header-widget-region:after{clear:both}.header-widget-region .widget{margin:0;padding:1em 0;font-size:.875em}.site-branding{float:right;margin-bottom:0;width:calc(100% - 120px)}.site-branding .site-title{font-size:2em;letter-spacing:-1px;margin:0}.site-branding .site-title a{font-weight:700}.site-branding .site-description{font-size:.875em;display:none}.site-branding .logo{margin:0}.site-main{margin-bottom:2.617924em}.site-content{outline:none}.page-template-template-homepage:not(.has-post-thumbnail) .site-main{padding-top:4.235801032em}.page-template-template-homepage .type-page{padding-top:2.617924em;padding-bottom:2.617924em;position:relative}.page-template-template-homepage .type-page .storefront-hero__button-edit{position:absolute;top:1em;left:1em;font-size:.875em}.page-template-template-homepage .entry-content{font-size:1.1em}.page-template-template-homepage .entry-content p:last-child{margin-bottom:0}.page-template-template-homepage .entry-header h1{font-size:3.706325903em;margin-bottom:.2360828548em}.page-template-template-homepage .entry-content,.page-template-template-homepage .entry-header{max-width:41.0994671405em;margin-right:auto;margin-left:auto;text-align:center}.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail{background-size:cover;background-position:50%;padding-top:6.8535260698em;padding-bottom:6.8535260698em}.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-content,.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-title{opacity:0;-webkit-transition:all,ease,.5s;transition:all,ease,.5s}.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-content.loaded,.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-title.loaded{opacity:1}.site-footer{background-color:#f3f3f3;color:#3b3c3f;padding:1.618em 0 3.706325903em}.site-footer h1,.site-footer h2,.site-footer h3,.site-footer h4,.site-footer h5,.site-footer h6{color:#333437}.site-footer a{color:#2c2d33;text-decoration:underline}.site-footer a:hover{text-decoration:none}.site-footer a.button,.site-footer a.components-button:not(.is-link),.site-footer a.wp-block-button__link{text-decoration:none}.site-info{padding:2.617924em 0}.site-info span[role=separator]{padding:0 .3342343017em 0 .2360828548em}.site-info span[role=separator]:before{content:"\007c"}.alignleft{display:inline;float:right;margin-left:1em}.alignright{display:inline;float:left;margin-right:1em}.aligncenter{clear:both;display:block;margin:0 auto}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#f1f1f1;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;display:block;font-weight:700;height:auto;right:0;line-height:normal;padding:1em 1.618em;text-decoration:none;top:0;width:auto;z-index:100000;outline:none}.screen-reader-text.skip-link:focus{-webkit-clip-path:none;clip-path:none}.clear:after,.clear:before,.comment-content:after,.comment-content:before,.entry-content:after,.entry-content:before,.site-content:after,.site-content:before,.site-footer:after,.site-footer:before,.site-header:after,.site-header:before{content:"";display:table}.clear:after,.comment-content:after,.entry-content:after,.site-content:after,.site-footer:after,.site-header:after{clear:both}table{border-spacing:0;width:100%;margin:0 0 1.41575em;border-collapse:separate}table caption{padding:1em 0;font-weight:600}table td,table th{padding:1em 1.41575em;text-align:right;vertical-align:top}table td p:last-child,table th p:last-child{margin-bottom:0}table th{font-weight:600}table thead th{padding:1.41575em;vertical-align:middle}table tbody h2{font-size:1em;letter-spacing:normal}table tbody h2,table tbody h2 a{font-weight:400}.error404 .site-content .widget_product_search{padding:1.618em;background-color:rgba(0,0,0,.025)}.error404 .site-content .widget_product_search form{margin:0}.error404.left-sidebar .content-area,.error404.right-sidebar .content-area{width:100%}.error404 .fourohfour-columns-2{padding:2.617924em 0;border:1px solid rgba(0,0,0,.05);border-width:1px 0;margin-bottom:2.617924em}.error404 .fourohfour-columns-2:after,.error404 .fourohfour-columns-2:before{content:"";display:table}.error404 .fourohfour-columns-2:after{clear:both}.error404 .fourohfour-columns-2 .widget,.error404 .fourohfour-columns-2 ul.products li.product{margin-bottom:0}.error404 .fourohfour-columns-2 .col-1 ul.products{margin-bottom:2.2906835em}.error404 .fourohfour-columns-2 .col-1 ul.products li.product{width:45.4545454545%;float:right;margin-left:9.0909090909%}.error404 .fourohfour-columns-2 .col-1 ul.products li.product:last-child{margin-left:0}.error404 .fourohfour-columns-2 .col-2{padding:1.618em;background-color:rgba(0,0,0,.025)}#comments{padding-top:2.617924em}#comments .comments-title{border-bottom:1px solid rgba(0,0,0,.05);padding-bottom:.5407911001em;margin-bottom:1.618em}#comments .comment-list{list-style:none;margin-right:0}#comments .comment-list .comment-body:after,#comments .comment-list .comment-body:before{content:"";display:table}#comments .comment-list .comment-body:after{clear:both}#comments .comment-list .comment-content{padding-bottom:1.618em;margin-bottom:1.618em}#comments .comment-list .comment-content .comment-text{padding:1.618em;border-radius:3px}#comments .comment-list .comment-content .comment-text p:last-child{margin-bottom:0}#comments .comment-list .comment-meta{margin-bottom:1em}#comments .comment-list .comment-meta .avatar{margin-bottom:1em;max-width:64px;height:auto}#comments .comment-list .comment-meta a.comment-date{font-size:.875em}#comments .comment-list .comment-meta cite{font-style:normal;clear:both;display:block}#comments .comment-list .reply{margin-bottom:1.618em;padding-top:.6180469716em}#comments .comment-list .reply:after,#comments .comment-list .reply:before{content:"";display:table}#comments .comment-list .reply:after{clear:both}#comments .comment-list .reply a{display:inline-block;margin-left:1em}#comments .comment-list .reply a:last-child{margin-left:0}#comments .comment-list .children{list-style:none}.comment-content a{word-wrap:break-word}#respond{clear:both;padding:1.618em;background-color:rgba(0,0,0,.0125);position:relative}#respond .comment-form-author input,#respond .comment-form-email input,#respond .comment-form-url input{width:100%}#respond .form-submit,#respond form{margin-bottom:0}#respond #cancel-comment-reply-link{position:absolute;top:.5407911001em;left:.5407911001em;display:block;height:1em;width:1em;overflow:hidden;line-height:1;font-size:1.41575em;text-align:center;-webkit-transition:ease,.3s,-webkit-transform;transition:ease,.3s,-webkit-transform;transition:transform,ease,.3s;transition:transform,ease,.3s,-webkit-transform}#respond #cancel-comment-reply-link:hover{-webkit-transform:scale(1.3);-ms-transform:scale(1.3);transform:scale(1.3)}.hentry{margin:0 0 4.235801032em}.hentry .wp-post-image{margin-bottom:1.618em;margin-right:auto;margin-left:auto}.hentry .entry-header{margin-bottom:1em;border-bottom:1px solid rgba(0,0,0,.05)}.hentry .entry-header .byline,.hentry .entry-header .post-author,.hentry .entry-header .post-comments,.hentry .entry-header .posted-on{font-size:.875em}.hentry .entry-header .byline a,.hentry .entry-header .post-author a,.hentry .entry-header .post-comments a,.hentry .entry-header .posted-on a{font-weight:600;text-decoration:underline}.hentry .entry-header .byline a:hover,.hentry .entry-header .post-author a:hover,.hentry .entry-header .post-comments a:hover,.hentry .entry-header .posted-on a:hover{text-decoration:none}.hentry .entry-content a{text-decoration:underline}.hentry .entry-content a:hover{text-decoration:none}.hentry .entry-content a.button,.hentry .entry-content a.components-button:not(.is-link),.hentry .entry-content a.wp-block-button__link{text-decoration:none}.hentry .entry-taxonomy{margin:1.41575em 0 0;padding-top:1em;border-top:1px solid rgba(0,0,0,.05)}.hentry.type-page .entry-header{border-bottom:0;margin-bottom:0}.cat-links,.tags-links{font-size:.875em}.cat-links a,.tags-links a{color:#727272;font-weight:600;text-decoration:underline}.byline,.updated:not(.published){display:none}.group-blog .byline,.single .byline{display:inline}.page-links{clear:both;margin:0 0 1em}form{margin-bottom:1.618em}button,input,select,textarea{font-size:100%;margin:0}.added_to_cart,.button,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link,button,input[type=button],input[type=reset],input[type=submit]{border:0;border-radius:0;background:none;background-color:#43454b;border-color:#43454b;color:#fff;cursor:pointer;padding:.6180469716em 1.41575em;text-decoration:none;font-weight:600;text-shadow:none;display:inline-block;-webkit-appearance:none}.added_to_cart:after,.button:after,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link:after,button:after,input[type=button]:after,input[type=reset]:after,input[type=submit]:after{display:none}.added_to_cart.alt,.added_to_cart.cta,.button.alt,.button.cta,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.alt,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.cta,button.alt,button.cta,input[type=button].alt,input[type=button].cta,input[type=reset].alt,input[type=reset].cta,input[type=submit].alt,input[type=submit].cta{background-color:#2c2d33;border-color:#2c2d33}.added_to_cart.alt:hover,.added_to_cart.cta:hover,.button.alt:hover,.button.cta:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.alt:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.cta:hover,button.alt:hover,button.cta:hover,input[type=button].alt:hover,input[type=button].cta:hover,input[type=reset].alt:hover,input[type=reset].cta:hover,input[type=submit].alt:hover,input[type=submit].cta:hover{background-color:#2c2d33}.added_to_cart:hover,.button:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link:hover,button:hover,input[type=button]:hover,input[type=reset]:hover,input[type=submit]:hover{color:#fff}.added_to_cart.loading,.button.loading,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.loading,button.loading,input[type=button].loading,input[type=reset].loading,input[type=submit].loading{opacity:.5}.added_to_cart.small,.button.small,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.small,button.small,input[type=button].small,input[type=reset].small,input[type=submit].small{padding:.5407911001em .875em;font-size:.875em}.added_to_cart.disabled,.added_to_cart:disabled,.button.disabled,.button:disabled,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.disabled,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link:disabled,button.disabled,button:disabled,input[type=button].disabled,input[type=button]:disabled,input[type=reset].disabled,input[type=reset]:disabled,input[type=submit].disabled,input[type=submit]:disabled{opacity:.5!important;cursor:not-allowed}.added_to_cart.disabled:hover,.added_to_cart:disabled:hover,.button.disabled:hover,.button:disabled:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.disabled:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link:disabled:hover,button.disabled:hover,button:disabled:hover,input[type=button].disabled:hover,input[type=button]:disabled:hover,input[type=reset].disabled:hover,input[type=reset]:disabled:hover,input[type=submit].disabled:hover,input[type=submit]:disabled:hover{opacity:.5!important}.wc-block-components-button:not(.is-link).disabled,.wc-block-components-button:not(.is-link):disabled{opacity:.5;cursor:not-allowed}.wc-block-components-button:not(.is-link).disabled:hover,.wc-block-components-button:not(.is-link):disabled:hover{opacity:.5}input[type=checkbox],input[type=radio]{padding:0}input[type=checkbox]+label,input[type=radio]+label{margin:0 .3819820591em 0 0}input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=search]{box-sizing:border-box}input[type=search]::-webkit-input-placeholder{color:#616161}input[type=search]:-ms-input-placeholder{color:#616161}input[type=search]::-ms-input-placeholder{color:#616161}input[type=search]::placeholder{color:#616161}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}.input-text,input[type=email],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=url],textarea{padding:.6180469716em;background-color:#f2f2f2;color:#43454b;border:0;-webkit-appearance:none;box-sizing:border-box;font-weight:400;box-shadow:inset 0 1px 1px rgba(0,0,0,.125)}.input-text:focus,input[type=email]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=url]:focus,textarea:focus{background-color:#ededed}textarea{overflow:auto;padding-right:.875em;vertical-align:top;width:100%}label{font-weight:400}label.inline input{width:auto}fieldset{padding:1em 1.618em 1.618em;border:0;margin:1.618em 0}fieldset legend{font-weight:600;padding:.6180469716em 1em;margin-right:-1em}[placeholder]:focus::-webkit-input-placeholder{-webkit-transition:opacity .5s ease .5s;transition:opacity .5s ease .5s;opacity:0}.comment-content img.wp-smiley,.entry-content img.wp-smiley,.page-content img.wp-smiley{border:none;margin-bottom:0;margin-top:0;padding:0;display:inline-block;border-radius:0}.wp-caption{margin-bottom:1em;max-width:100%}.wp-caption img[class*=wp-image-]{display:block;margin:0 auto}.wp-caption .wp-caption-text{text-align:right;font-style:italic;border-bottom:2px solid rgba(0,0,0,.05);padding:1em 0}.gallery{margin-bottom:1em}.gallery:after,.gallery:before{content:"";display:table}.gallery:after{clear:both}.gallery .gallery-item{float:right}.gallery .gallery-item .gallery-icon a{display:block}.gallery .gallery-item .gallery-icon img{border:none;height:auto;margin:0 auto}.gallery .gallery-item .gallery-caption{margin:0;text-align:center}.gallery.gallery-columns-1 .gallery-item{width:100%}.gallery.gallery-columns-2 .gallery-item{width:50%}.gallery.gallery-columns-3 .gallery-item{width:33.3%}.gallery.gallery-columns-4 .gallery-item{width:25%}.gallery.gallery-columns-5 .gallery-item{width:20%}.gallery.gallery-columns-6 .gallery-item{width:16.666666667%}.gallery.gallery-columns-7 .gallery-item{width:14.285714286%}.gallery.gallery-columns-8 .gallery-item{width:12.5%}.gallery.gallery-columns-9 .gallery-item{width:11.111111111%}embed,iframe,object,video{max-width:100%}.secondary-navigation{display:none}button.menu-toggle{cursor:pointer;text-align:right;float:left;position:relative;border:2px solid rgba(0,0,0,0);box-shadow:none;border-radius:2px;padding:.6180469716em 2.617924em .6180469716em .875em;font-size:.875em;max-width:120px}button.menu-toggle,button.menu-toggle:hover{background-image:none}button.menu-toggle span:before{-webkit-transition:all,ease,.2s;transition:all,ease,.2s}button.menu-toggle:after,button.menu-toggle:before,button.menu-toggle span:before{content:"";display:block;height:2px;width:14px;position:absolute;top:50%;right:1em;margin-top:-1px;-webkit-transition:all,ease,.2s;transition:all,ease,.2s;border-radius:3px}button.menu-toggle:before{-webkit-transform:translateY(-4px);-ms-transform:translateY(-4px);transform:translateY(-4px)}button.menu-toggle:after{-webkit-transform:translateY(4px);-ms-transform:translateY(4px);transform:translateY(4px)}.toggled button.menu-toggle:after,.toggled button.menu-toggle:before{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.toggled button.menu-toggle:after{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.toggled button.menu-toggle span:before{opacity:0}.primary-navigation{display:none}.main-navigation:after,.main-navigation:before{content:"";display:table}.main-navigation:after{clear:both}.main-navigation div.menu{display:none}.main-navigation div.menu:last-child{display:block}.main-navigation .menu{clear:both}.handheld-navigation,.main-navigation div.menu>ul:not(.nav-menu),.nav-menu{overflow:hidden;max-height:0;-webkit-transition:all,ease,.8s;transition:all,ease,.8s}.handheld-navigation{clear:both}.handheld-navigation ul{margin:0}.handheld-navigation ul.menu li{position:relative}.handheld-navigation ul.menu li button:after{-webkit-transition:all,ease,.9s;transition:all,ease,.9s}.handheld-navigation ul.menu li button.toggled-on:after{-webkit-transform:rotate(-180deg);-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.handheld-navigation ul.menu .sub-menu{visibility:hidden;opacity:0;max-height:0;-webkit-transition:all,ease,.9s;transition:all,ease,.9s}.handheld-navigation ul.menu .sub-menu.toggled-on{visibility:visible;max-height:9999px;opacity:1}.handheld-navigation .dropdown-toggle{background:rgba(0,0,0,0);position:absolute;top:0;left:0;display:block}.main-navigation.toggled .handheld-navigation,.main-navigation.toggled .menu>ul:not(.nav-menu),.main-navigation.toggled ul[aria-expanded=true]{max-height:9999px}.main-navigation ul{margin-right:0;list-style:none;margin-bottom:0}.main-navigation ul ul{display:block;margin-right:1.41575em}.main-navigation ul li a{padding:.875em 0;display:block}.main-navigation ul li a:hover{color:#e6e6e6}.site-main nav.navigation{clear:both;padding:2.617924em 0}.site-main nav.navigation:after,.site-main nav.navigation:before{content:"";display:table}.site-main nav.navigation:after{clear:both}.site-main nav.navigation .nav-next a,.site-main nav.navigation .nav-previous a{display:inline-block}.site-main nav.navigation .nav-previous{float:right;width:50%}.site-main nav.navigation .nav-next{float:left;text-align:left;width:50%}.pagination,.woocommerce-pagination{padding:1em 0;border:1px solid rgba(0,0,0,.05);border-width:1px 0;text-align:center;clear:both}.pagination ul.page-numbers:after,.pagination ul.page-numbers:before,.woocommerce-pagination ul.page-numbers:after,.woocommerce-pagination ul.page-numbers:before{content:"";display:table}.pagination ul.page-numbers:after,.woocommerce-pagination ul.page-numbers:after{clear:both}.pagination .page-numbers,.woocommerce-pagination .page-numbers{list-style:none;margin:0;vertical-align:middle}.pagination .page-numbers li,.woocommerce-pagination .page-numbers li{display:inline-block}.pagination .page-numbers li .page-numbers,.woocommerce-pagination .page-numbers li .page-numbers{border-right-width:0;display:inline-block;padding:.3342343017em .875em;background-color:rgba(0,0,0,.025);color:#43454b}.pagination .page-numbers li .page-numbers.current,.woocommerce-pagination .page-numbers li .page-numbers.current{background-color:#2c2d33;border-color:#2c2d33}.pagination .page-numbers li .page-numbers.dots,.woocommerce-pagination .page-numbers li .page-numbers.dots{background-color:rgba(0,0,0,0)}.pagination .page-numbers li .page-numbers.next,.pagination .page-numbers li .page-numbers.prev,.woocommerce-pagination .page-numbers li .page-numbers.next,.woocommerce-pagination .page-numbers li .page-numbers.prev{padding-right:1em;padding-left:1em}.pagination .page-numbers li a.page-numbers:hover,.woocommerce-pagination .page-numbers li a.page-numbers:hover{background-color:rgba(0,0,0,.05)}.rtl .pagination a.next,.rtl .pagination a.prev,.rtl .woocommerce-pagination a.next,.rtl .woocommerce-pagination a.prev{-webkit-transform:rotateY(-180deg);transform:rotateY(-180deg)}.widget{margin:0 0 3.706325903em}.widget select{max-width:100%}.widget .widget-search .search-submit{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.widget .widget-title,.widget .widgettitle{font-size:1.41575em;letter-spacing:0;border-bottom:1px solid rgba(0,0,0,.05);padding:0 0 1em;margin-bottom:1em;font-weight:300}.widget ul{margin-right:0;list-style:none}.widget ul ul{margin-right:1.618em}.widget-area .widget{font-size:.875em;font-weight:400}.widget-area .widget h1.widget-title{font-size:1.41575em}.widget-area .widget a{font-weight:600;text-decoration:underline}.widget-area .widget a:hover{text-decoration:none}.widget-area .widget a.button,.widget-area .widget a.components-button:not(.is-link),.widget-area .widget a.wp-block-button__link{text-decoration:none}.widget-area .widget a.button{font-weight:600!important}.widget_product_search form,.widget_search form{position:relative}.widget_product_search form input[type=search],.widget_product_search form input[type=text],.widget_search form input[type=search],.widget_search form input[type=text]{width:100%}.widget_product_search form button[type=submit],.widget_product_search form input[type=submit],.widget_search form button[type=submit],.widget_search form input[type=submit]{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important;top:0;right:0}.widget_archive ul,.widget_categories ul,.widget_layered_nav_filters ul,.widget_layered_nav ul,.widget_links ul,.widget_nav_menu ul,.widget_pages ul,.widget_product_categories ul,.widget_recent_comments ul,.widget_recent_entries ul{margin:0}.widget_archive ul li,.widget_categories ul li,.widget_layered_nav_filters ul li,.widget_layered_nav ul li,.widget_links ul li,.widget_nav_menu ul li,.widget_pages ul li,.widget_product_categories ul li,.widget_recent_comments ul li,.widget_recent_entries ul li{list-style:none;margin-bottom:1em;line-height:1.41575em}.widget_archive ul .children,.widget_categories ul .children,.widget_layered_nav_filters ul .children,.widget_layered_nav ul .children,.widget_links ul .children,.widget_nav_menu ul .children,.widget_pages ul .children,.widget_product_categories ul .children,.widget_recent_comments ul .children,.widget_recent_entries ul .children{margin-right:0;margin-top:1em}#wp-calendar td,#wp-calendar th,.wp-calendar-table td,.wp-calendar-table th{padding:.236em;text-align:center}.widget_pages ul ul.children,.widget_recent_entries ul ul.children{margin:.6180469716em 1.41575em 0 0}.widget_rating_filter .wc-layered-nav-rating{margin-bottom:.6180469716em}.widget_rating_filter .wc-layered-nav-rating a{text-decoration:none!important}.widget_rating_filter .wc-layered-nav-rating .star-rating{display:inline-block;height:1em;line-height:1}@media (min-width:768px){table.shop_table_responsive tbody tr td,table.shop_table_responsive tbody tr th{text-align:right}.site-header{padding-top:2.617924em;padding-bottom:0}.site-header .site-branding{display:block;width:100%;float:right;margin-right:0;margin-left:0;clear:both}.site-header .site-branding img{height:auto;max-width:230px;max-height:none}.woocommerce-active .site-header .site-branding{width:73.9130434783%;float:right;margin-left:4.347826087%}.woocommerce-active .site-header .site-search{width:21.7391304348%;float:left;margin-left:0;clear:none}.woocommerce-active .site-header .main-navigation{width:73.9130434783%;float:right;margin-left:4.347826087%;clear:both}.woocommerce-active .site-header .site-header-cart{width:21.7391304348%;float:left;margin-left:0;margin-bottom:0}.storefront-secondary-navigation .site-header .site-branding{width:39.1304347826%;float:right;margin-left:4.347826087%}.storefront-secondary-navigation .site-header .secondary-navigation{width:56.5217391304%;float:left;margin-left:0}.storefront-secondary-navigation.woocommerce-active .site-header .site-branding{width:21.7391304348%;float:right;margin-left:4.347826087%}.storefront-secondary-navigation.woocommerce-active .site-header .secondary-navigation{width:47.8260869565%;float:right;margin-left:4.347826087%}.site-branding .site-description{margin-bottom:0;display:block}.custom-logo-link,.site-branding,.site-header-cart,.site-logo-anchor,.site-logo-link,.site-search{margin-bottom:1.41575em}.site-header .subscribe-and-connect-connect{float:left;margin-bottom:1em}.site-header .subscribe-and-connect-connect .icons{list-style:none;margin:0}.site-header .subscribe-and-connect-connect .icons a{font-size:1em!important}.site-header .subscribe-and-connect-connect .icons li{margin:0 .5407911001em 0 0!important;display:inline-block}.col-full{max-width:66.4989378333em;margin-right:auto;margin-left:auto;padding:0 2.617924em;box-sizing:content-box}.col-full:after,.col-full:before{content:"";display:table}.col-full:after{content:" ";display:block;clear:both}.site-content:after,.site-content:before{content:"";display:table}.site-content:after{clear:both}.content-area{width:73.9130434783%;float:right;margin-left:4.347826087%}.widget-area{width:21.7391304348%;float:left;margin-left:0}.right-sidebar .content-area{width:73.9130434783%;float:right;margin-left:4.347826087%}.right-sidebar .widget-area{width:21.7391304348%;float:left;margin-left:0}.left-sidebar .content-area{width:73.9130434783%;float:left;margin-left:0}.left-sidebar .widget-area{width:21.7391304348%;float:right;margin-left:4.347826087%}.storefront-full-width-content .content-area{width:100%;float:right;margin-right:0;margin-left:0}.content-area,.widget-area{margin-bottom:2.617924em}.page-template-template-fullwidth-php .content-area,.page-template-template-homepage-php .content-area{width:100%;float:right;margin-right:0;margin-left:0}.footer-widgets{padding-top:4.235801032em;border-bottom:1px solid rgba(0,0,0,.05)}.footer-widgets:after,.footer-widgets:before{content:"";display:table}.footer-widgets:after{clear:both}.footer-widgets.col-2 .block{width:47.8260869565%;float:right;margin-left:4.347826087%}.footer-widgets.col-2 .block.footer-widget-2{float:left;margin-left:0}.footer-widgets.col-3 .block{width:30.4347826087%;float:right;margin-left:4.347826087%}.footer-widgets.col-3 .block.footer-widget-3{float:left;margin-left:0}.footer-widgets.col-4 .block{width:21.7391304348%;float:right;margin-left:4.347826087%}.footer-widgets.col-4 .block.footer-widget-4{float:left;margin-left:0}.comment-list:after,.comment-list:before{content:"";display:table}.comment-list:after{clear:both}.comment-list .comment{clear:both}.comment-list .comment-meta{width:17.6470588235%;float:right;margin-left:5.8823529412%;text-align:left}.comment-list .comment-meta .avatar{float:left}.comment-list .comment-content{padding-bottom:3.706325903em;margin-bottom:3.706325903em}.comment-list #respond,.comment-list .comment-content{width:76.4705882353%;float:left;margin-left:0}.comment-list #respond{float:left}.comment-list #respond .comment-form-author,.comment-list #respond .comment-form-email,.comment-list #respond .comment-form-url{width:100%;margin-left:0}.comment-list .comment-body #respond{box-shadow:0 6px 2em rgba(0,0,0,.2);margin-bottom:2.617924em;margin-top:-1.618em}.comment-list .reply{clear:both;text-align:left}.comment-list ol.children{width:88.2352941176%;float:left;margin-left:0;list-style:none}.comment-list ol.children .comment-meta{width:20%;float:right;margin-left:6.6666666667%}.comment-list ol.children #respond,.comment-list ol.children .comment-content{width:73.3333333333%;float:left;margin-left:0}.comment-list ol.children ol.children{width:86.6666666667%;float:left;margin-left:0}.comment-list ol.children ol.children .comment-meta{width:23.0769230769%;float:right;margin-left:7.6923076923%}.comment-list ol.children ol.children #respond,.comment-list ol.children ol.children .comment-content{width:69.2307692308%;float:left;margin-left:0}.comment-list ol.children ol.children ol.children{width:84.6153846154%;float:left;margin-left:0}.comment-list ol.children ol.children ol.children .comment-meta{width:27.2727272727%;float:right;margin-left:9.0909090909%}.comment-list ol.children ol.children ol.children #respond,.comment-list ol.children ol.children ol.children .comment-content{width:63.6363636364%;float:left;margin-left:0}.comment-list ol.children ol.children ol.children ol.children{width:81.8181818182%;float:left;margin-left:0}.comment-list ol.children ol.children ol.children ol.children .comment-meta{width:33.3333333333%;float:right;margin-left:11.1111111111%}.comment-list ol.children ol.children ol.children ol.children #respond,.comment-list ol.children ol.children ol.children ol.children .comment-content{width:55.5555555556%;float:left;margin-left:0}#respond{padding:2.617924em}#respond .comment-form-author,#respond .comment-form-email,#respond .comment-form-url{width:29.4117647059%;float:right;margin-left:5.8823529412%}#respond .comment-form-url{float:left;margin-left:0}#respond .comment-form-comment{clear:both}.hentry .entry-header{margin-bottom:2.617924em}.handheld-navigation,.main-navigation.toggled .handheld-navigation,.main-navigation.toggled div.menu,.menu-toggle{display:none}.primary-navigation{display:block}.main-navigation,.secondary-navigation{clear:both;display:block;width:100%}.main-navigation ul,.secondary-navigation ul{list-style:none;margin:0;padding-right:0;display:block}.main-navigation ul li,.secondary-navigation ul li{position:relative;display:inline-block;text-align:right}.main-navigation ul li a,.secondary-navigation ul li a{display:block}.main-navigation ul li a:before,.secondary-navigation ul li a:before{display:none}.main-navigation ul li.focus>ul,.main-navigation ul li:hover>ul,.secondary-navigation ul li.focus>ul,.secondary-navigation ul li:hover>ul{right:0;display:block}.main-navigation ul li.focus>ul li>ul,.main-navigation ul li:hover>ul li>ul,.secondary-navigation ul li.focus>ul li>ul,.secondary-navigation ul li:hover>ul li>ul{right:-9999px}.main-navigation ul li.focus>ul li>ul.sub-menu--is-touch-device,.main-navigation ul li:hover>ul li>ul.sub-menu--is-touch-device,.secondary-navigation ul li.focus>ul li>ul.sub-menu--is-touch-device,.secondary-navigation ul li:hover>ul li>ul.sub-menu--is-touch-device{display:none;right:0}.main-navigation ul li.focus>ul li.focus>ul,.main-navigation ul li.focus>ul li:hover>ul,.main-navigation ul li:hover>ul li.focus>ul,.main-navigation ul li:hover>ul li:hover>ul,.secondary-navigation ul li.focus>ul li.focus>ul,.secondary-navigation ul li.focus>ul li:hover>ul,.secondary-navigation ul li:hover>ul li.focus>ul,.secondary-navigation ul li:hover>ul li:hover>ul{right:100%;top:0;display:block}.main-navigation ul ul,.secondary-navigation ul ul{float:right;position:absolute;top:100%;z-index:99999;right:-9999px}.main-navigation ul ul.sub-menu--is-touch-device,.secondary-navigation ul ul.sub-menu--is-touch-device{display:none;right:0}.main-navigation ul ul li,.secondary-navigation ul ul li{display:block}.main-navigation ul ul li a,.secondary-navigation ul ul li a{width:200px}ul.menu li.current-menu-item>a{color:#43454b}.storefront-primary-navigation{clear:both}.storefront-primary-navigation:after,.storefront-primary-navigation:before{content:"";display:table}.storefront-primary-navigation:after{clear:both}.main-navigation div.menu{display:block}.main-navigation ul.menu,.main-navigation ul.nav-menu{max-height:none;overflow:visible;margin-right:-1em;-webkit-transition:none;transition:none}.main-navigation ul.menu>li>a,.main-navigation ul.nav-menu>li>a{padding:1.618em 1em}.main-navigation ul.menu>li.menu-item-has-children:hover:after,.main-navigation ul.menu>li.page_item_has_children:hover:after,.main-navigation ul.nav-menu>li.menu-item-has-children:hover:after,.main-navigation ul.nav-menu>li.page_item_has_children:hover:after{display:block}.main-navigation ul.menu ul,.main-navigation ul.nav-menu ul{margin-right:0}.main-navigation ul.menu ul li a,.main-navigation ul.nav-menu ul li a{padding:.875em 1.41575em;font-weight:400;font-size:.875em}.main-navigation ul.menu ul li:last-child,.main-navigation ul.nav-menu ul li:last-child{border-bottom:0}.main-navigation ul.menu ul ul,.main-navigation ul.nav-menu ul ul{margin-right:0;box-shadow:none}.main-navigation ul.menu ul a:hover,.main-navigation ul.menu ul li.focus,.main-navigation ul.menu ul li:hover>a,.main-navigation ul.nav-menu ul a:hover,.main-navigation ul.nav-menu ul li.focus,.main-navigation ul.nav-menu ul li:hover>a{background-color:rgba(0,0,0,.025)}.main-navigation a{padding:0 1em 2.2906835em}.secondary-navigation{margin:0 0 1.618em;width:auto;clear:none;line-height:1}.secondary-navigation .menu{font-size:.875em;width:auto;float:left}.secondary-navigation .menu>li:hover>a{text-decoration:none}.secondary-navigation .menu ul a{padding:.326em .875em;background:rgba(0,0,0,.05)}.secondary-navigation .menu ul li:first-child a{padding-top:1em}.secondary-navigation .menu ul li:last-child a{padding-bottom:1em}.secondary-navigation .menu ul ul{margin-top:-.6180469716em}.secondary-navigation .menu a{padding:1em .875em;color:#737781;font-weight:400}.secondary-navigation .menu a:hover{text-decoration:none}.error404 .fourohfour-columns-2 .col-1{width:47.8260869565%;float:right;margin-left:4.347826087%}.error404 .fourohfour-columns-2 .col-1 ul.products{margin-bottom:0}.error404 .fourohfour-columns-2 .col-2{width:47.8260869565%;float:left;margin-left:0}}@media (max-width:66.4989378333em){.col-full{margin-right:2.617924em;margin-left:2.617924em;padding:0}}@media (max-width:568px){.col-full{margin-right:1.41575em;margin-left:1.41575em;padding:0}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/style.css b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/style.css new file mode 100644 index 0000000..a328fff --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/style.css @@ -0,0 +1,32 @@ +/*! +Theme Name: Storefront +Theme URI: https://woocommerce.com/storefront/ +Author: Automattic +Author URI: https://woocommerce.com/ +Description: Storefront is the perfect theme for your next WooCommerce project. Designed and developed by WooCommerce Core developers, it features a bespoke integration with WooCommerce itself plus many of the most popular customer facing WooCommerce extensions. There are several layout & color options to personalise your shop, multiple widget regions, a responsive design and much more. Developers will love its lean and extensible codebase making it a joy to customize and extend. Looking for a WooCommerce theme? Look no further! +Version: 2.9.0 +Tested up to: 5.5.1 +Requires PHP: 5.6.0 +License: GNU General Public License v2 or later +License URI: https://www.gnu.org/licenses/gpl-2.0.html +Text Domain: storefront +Tags: e-commerce, two-columns, left-sidebar, right-sidebar, custom-background, custom-colors, custom-header, custom-menu, featured-images, full-width-template, threaded-comments, accessibility-ready, rtl-language-support, footer-widgets, sticky-post, theme-options, editor-style + +This theme, like WordPress, is licensed under the GPL. +Use it to make something cool, have fun, and share what you've learned with others. + +Storefront is based on Underscores https://underscores.me/, (C) 2012-2017 Automattic, Inc. + +Resetting and rebuilding styles have been helped along thanks to the fine work of +Eric Meyer https://meyerweb.com/eric/tools/css/reset/index.html +along with Nicolas Gallagher and Jonathan Neal http://necolas.github.com/normalize.css/ + +All sizing (typography, layout, padding/margins, etc) are inspired by a modular scale that uses 1em as a base size with a 1.618 ratio. +You can read more about the calculator we use in our Sass here: https://github.com/modularscale/modularscale-sass + +FontAwesome License: SIL Open Font License - http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL +Images License: GNU General Public License v2 or later +*/ +/*! + * normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css + */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:rgba(0,0,0,0)}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}optgroup{font-weight:700}table{border-collapse:collapse}td,th{padding:0}body{-ms-word-wrap:break-word;word-wrap:break-word}body,button,input,textarea{color:#43454b;line-height:1.618;text-rendering:optimizeLegibility;font-weight:400}body,button,input,select,textarea{font-family:Source Sans Pro,HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif}select{color:initial;max-width:100%}h1,h2,h3,h4,h5,h6{clear:both;font-weight:300;margin:0 0 .5407911001em;color:#131315}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:300}.alpha,h1{font-size:2.617924em;line-height:1.214;letter-spacing:-1px}.beta,h2{font-size:2em;line-height:1.214}.beta+h3,h2+h3{border-top:1px solid rgba(0,0,0,.05);padding-top:.5407911001em}.gamma,h3{font-size:1.618em}.delta,h4{font-size:1.41575em}.alpha,.beta,.delta,.gamma{display:block}blockquote+h2,blockquote+h3,blockquote+h4,blockquote+header h2,form+h2,form+h3,form+h4,form+header h2,ol+h2,ol+h3,ol+h4,ol+header h2,p+h2,p+h3,p+h4,p+header h2,table+h2,table+h3,table+h4,table+header h2,ul+h2,ul+h3,ul+h4,ul+header h2{margin-top:2.2906835em}hr{background-color:#ccc;border:0;height:1px}hr,p{margin:0 0 1.41575em}ol,ul{margin:0 0 1.41575em 3em;padding:0}ul{list-style:disc}ol{list-style:decimal}li>ol,li>ul{margin-bottom:0;margin-left:1em}dt{font-weight:600}dd{margin:0 0 1.618em}b,strong{font-weight:600}blockquote,cite,dfn,em,i{font-style:italic}blockquote{padding:0 1em;border-left:3px solid rgba(0,0,0,.05)}address{margin:0 0 1.41575em}pre{background:rgba(0,0,0,.1);font-family:Courier\ 10 Pitch,Courier,monospace;margin-bottom:1.618em;padding:1.618em;overflow:auto;max-width:100%}code,kbd,tt,var{font-family:Monaco,Consolas,Andale Mono,DejaVu Sans Mono,monospace;background-color:rgba(0,0,0,.05);padding:.202em .5407911001em}abbr,acronym{border-bottom:1px dotted #666;cursor:help}ins,mark{text-decoration:none;font-weight:600;background:rgba(0,0,0,0)}sub,sup{font-size:75%;height:0;line-height:0;position:relative;vertical-align:baseline}sup{bottom:1ex}sub{top:.5ex}small{font-size:75%}big{font-size:125%}figure{margin:0}img{height:auto;max-width:100%;display:block;border-radius:3px}a{color:#2c2d33;text-decoration:none}a:focus,button:focus,input:focus,textarea:focus{outline:2px solid #96588a}.storefront-cute *{font-family:Comic Sans MS,sans-serif}*{box-sizing:border-box}body{background-color:#fff}.site,body{overflow-x:hidden}.header-widget-region,.site-content{-webkit-tap-highlight-color:rgba(0,0,0,0)}.site-header{background-color:#2c2d33;padding-top:1.618em;padding-bottom:1.618em;color:#9aa0a7;background-position:50%;position:relative;z-index:999;border-bottom:1px solid rgba(0,0,0,0)}.site-header .custom-logo-link,.site-header .site-logo-anchor,.site-header .site-logo-link{display:block;margin-bottom:0}.site-header .custom-logo-link img,.site-header .site-logo-anchor img,.site-header .site-logo-link img{width:100%;max-width:210px}.site-header .widget{margin-bottom:0}.home.blog .site-header,.home.page:not(.page-template-template-homepage) .site-header,.home.post-type-archive-product .site-header{margin-bottom:4.235801032em}.no-wc-breadcrumb .site-header{margin-bottom:4.235801032em}.no-wc-breadcrumb.page-template-template-homepage .site-header{margin-bottom:0}.header-widget-region{position:relative;z-index:99}.header-widget-region:after,.header-widget-region:before{content:"";display:table}.header-widget-region:after{clear:both}.header-widget-region .widget{margin:0;padding:1em 0;font-size:.875em}.site-branding{float:left;margin-bottom:0;width:calc(100% - 120px)}.site-branding .site-title{font-size:2em;letter-spacing:-1px;margin:0}.site-branding .site-title a{font-weight:700}.site-branding .site-description{font-size:.875em;display:none}.site-branding .logo{margin:0}.site-main{margin-bottom:2.617924em}.site-content{outline:none}.page-template-template-homepage:not(.has-post-thumbnail) .site-main{padding-top:4.235801032em}.page-template-template-homepage .type-page{padding-top:2.617924em;padding-bottom:2.617924em;position:relative}.page-template-template-homepage .type-page .storefront-hero__button-edit{position:absolute;top:1em;right:1em;font-size:.875em}.page-template-template-homepage .entry-content{font-size:1.1em}.page-template-template-homepage .entry-content p:last-child{margin-bottom:0}.page-template-template-homepage .entry-header h1{font-size:3.706325903em;margin-bottom:.2360828548em}.page-template-template-homepage .entry-content,.page-template-template-homepage .entry-header{max-width:41.0994671405em;margin-left:auto;margin-right:auto;text-align:center}.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail{background-size:cover;background-position:50%;padding-top:6.8535260698em;padding-bottom:6.8535260698em}.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-content,.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-title{opacity:0;-webkit-transition:all,ease,.5s;transition:all,ease,.5s}.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-content.loaded,.page-template-template-homepage.has-post-thumbnail .type-page.has-post-thumbnail .entry-title.loaded{opacity:1}.site-footer{background-color:#f3f3f3;color:#3b3c3f;padding:1.618em 0 3.706325903em}.site-footer h1,.site-footer h2,.site-footer h3,.site-footer h4,.site-footer h5,.site-footer h6{color:#333437}.site-footer a{color:#2c2d33;text-decoration:underline}.site-footer a:hover{text-decoration:none}.site-footer a.button,.site-footer a.components-button:not(.is-link),.site-footer a.wp-block-button__link{text-decoration:none}.site-info{padding:2.617924em 0}.site-info span[role=separator]{padding:0 .2360828548em 0 .3342343017em}.site-info span[role=separator]:before{content:"\007c"}.alignleft{display:inline;float:left;margin-right:1em}.alignright{display:inline;float:right;margin-left:1em}.aligncenter{clear:both;display:block;margin:0 auto}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#f1f1f1;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;display:block;font-weight:700;height:auto;left:0;line-height:normal;padding:1em 1.618em;text-decoration:none;top:0;width:auto;z-index:100000;outline:none}.screen-reader-text.skip-link:focus{-webkit-clip-path:none;clip-path:none}.clear:after,.clear:before,.comment-content:after,.comment-content:before,.entry-content:after,.entry-content:before,.site-content:after,.site-content:before,.site-footer:after,.site-footer:before,.site-header:after,.site-header:before{content:"";display:table}.clear:after,.comment-content:after,.entry-content:after,.site-content:after,.site-footer:after,.site-header:after{clear:both}table{border-spacing:0;width:100%;margin:0 0 1.41575em;border-collapse:separate}table caption{padding:1em 0;font-weight:600}table td,table th{padding:1em 1.41575em;text-align:left;vertical-align:top}table td p:last-child,table th p:last-child{margin-bottom:0}table th{font-weight:600}table thead th{padding:1.41575em;vertical-align:middle}table tbody h2{font-size:1em;letter-spacing:normal}table tbody h2,table tbody h2 a{font-weight:400}.error404 .site-content .widget_product_search{padding:1.618em;background-color:rgba(0,0,0,.025)}.error404 .site-content .widget_product_search form{margin:0}.error404.left-sidebar .content-area,.error404.right-sidebar .content-area{width:100%}.error404 .fourohfour-columns-2{padding:2.617924em 0;border:1px solid rgba(0,0,0,.05);border-width:1px 0;margin-bottom:2.617924em}.error404 .fourohfour-columns-2:after,.error404 .fourohfour-columns-2:before{content:"";display:table}.error404 .fourohfour-columns-2:after{clear:both}.error404 .fourohfour-columns-2 .widget,.error404 .fourohfour-columns-2 ul.products li.product{margin-bottom:0}.error404 .fourohfour-columns-2 .col-1 ul.products{margin-bottom:2.2906835em}.error404 .fourohfour-columns-2 .col-1 ul.products li.product{width:45.4545454545%;float:left;margin-right:9.0909090909%}.error404 .fourohfour-columns-2 .col-1 ul.products li.product:last-child{margin-right:0}.error404 .fourohfour-columns-2 .col-2{padding:1.618em;background-color:rgba(0,0,0,.025)}#comments{padding-top:2.617924em}#comments .comments-title{border-bottom:1px solid rgba(0,0,0,.05);padding-bottom:.5407911001em;margin-bottom:1.618em}#comments .comment-list{list-style:none;margin-left:0}#comments .comment-list .comment-body:after,#comments .comment-list .comment-body:before{content:"";display:table}#comments .comment-list .comment-body:after{clear:both}#comments .comment-list .comment-content{padding-bottom:1.618em;margin-bottom:1.618em}#comments .comment-list .comment-content .comment-text{padding:1.618em;border-radius:3px}#comments .comment-list .comment-content .comment-text p:last-child{margin-bottom:0}#comments .comment-list .comment-meta{margin-bottom:1em}#comments .comment-list .comment-meta .avatar{margin-bottom:1em;max-width:64px;height:auto}#comments .comment-list .comment-meta a.comment-date{font-size:.875em}#comments .comment-list .comment-meta cite{font-style:normal;clear:both;display:block}#comments .comment-list .reply{margin-bottom:1.618em;padding-top:.6180469716em}#comments .comment-list .reply:after,#comments .comment-list .reply:before{content:"";display:table}#comments .comment-list .reply:after{clear:both}#comments .comment-list .reply a{display:inline-block;margin-right:1em}#comments .comment-list .reply a:last-child{margin-right:0}#comments .comment-list .children{list-style:none}.comment-content a{word-wrap:break-word}#respond{clear:both;padding:1.618em;background-color:rgba(0,0,0,.0125);position:relative}#respond .comment-form-author input,#respond .comment-form-email input,#respond .comment-form-url input{width:100%}#respond .form-submit,#respond form{margin-bottom:0}#respond #cancel-comment-reply-link{position:absolute;top:.5407911001em;right:.5407911001em;display:block;height:1em;width:1em;overflow:hidden;line-height:1;font-size:1.41575em;text-align:center;-webkit-transition:ease,.3s,-webkit-transform;transition:ease,.3s,-webkit-transform;transition:transform,ease,.3s;transition:transform,ease,.3s,-webkit-transform}#respond #cancel-comment-reply-link:hover{-webkit-transform:scale(1.3);-ms-transform:scale(1.3);transform:scale(1.3)}.hentry{margin:0 0 4.235801032em}.hentry .wp-post-image{margin-bottom:1.618em;margin-left:auto;margin-right:auto}.hentry .entry-header{margin-bottom:1em;border-bottom:1px solid rgba(0,0,0,.05)}.hentry .entry-header .byline,.hentry .entry-header .post-author,.hentry .entry-header .post-comments,.hentry .entry-header .posted-on{font-size:.875em}.hentry .entry-header .byline a,.hentry .entry-header .post-author a,.hentry .entry-header .post-comments a,.hentry .entry-header .posted-on a{font-weight:600;text-decoration:underline}.hentry .entry-header .byline a:hover,.hentry .entry-header .post-author a:hover,.hentry .entry-header .post-comments a:hover,.hentry .entry-header .posted-on a:hover{text-decoration:none}.hentry .entry-content a{text-decoration:underline}.hentry .entry-content a:hover{text-decoration:none}.hentry .entry-content a.button,.hentry .entry-content a.components-button:not(.is-link),.hentry .entry-content a.wp-block-button__link{text-decoration:none}.hentry .entry-taxonomy{margin:1.41575em 0 0;padding-top:1em;border-top:1px solid rgba(0,0,0,.05)}.hentry.type-page .entry-header{border-bottom:0;margin-bottom:0}.cat-links,.tags-links{font-size:.875em}.cat-links a,.tags-links a{color:#727272;font-weight:600;text-decoration:underline}.byline,.updated:not(.published){display:none}.group-blog .byline,.single .byline{display:inline}.page-links{clear:both;margin:0 0 1em}form{margin-bottom:1.618em}button,input,select,textarea{font-size:100%;margin:0}.added_to_cart,.button,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link,button,input[type=button],input[type=reset],input[type=submit]{border:0;border-radius:0;background:none;background-color:#43454b;border-color:#43454b;color:#fff;cursor:pointer;padding:.6180469716em 1.41575em;text-decoration:none;font-weight:600;text-shadow:none;display:inline-block;-webkit-appearance:none}.added_to_cart:after,.button:after,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link:after,button:after,input[type=button]:after,input[type=reset]:after,input[type=submit]:after{display:none}.added_to_cart.alt,.added_to_cart.cta,.button.alt,.button.cta,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.alt,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.cta,button.alt,button.cta,input[type=button].alt,input[type=button].cta,input[type=reset].alt,input[type=reset].cta,input[type=submit].alt,input[type=submit].cta{background-color:#2c2d33;border-color:#2c2d33}.added_to_cart.alt:hover,.added_to_cart.cta:hover,.button.alt:hover,.button.cta:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.alt:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.cta:hover,button.alt:hover,button.cta:hover,input[type=button].alt:hover,input[type=button].cta:hover,input[type=reset].alt:hover,input[type=reset].cta:hover,input[type=submit].alt:hover,input[type=submit].cta:hover{background-color:#2c2d33}.added_to_cart:hover,.button:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link:hover,button:hover,input[type=button]:hover,input[type=reset]:hover,input[type=submit]:hover{color:#fff}.added_to_cart.loading,.button.loading,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.loading,button.loading,input[type=button].loading,input[type=reset].loading,input[type=submit].loading{opacity:.5}.added_to_cart.small,.button.small,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.small,button.small,input[type=button].small,input[type=reset].small,input[type=submit].small{padding:.5407911001em .875em;font-size:.875em}.added_to_cart.disabled,.added_to_cart:disabled,.button.disabled,.button:disabled,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.disabled,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link:disabled,button.disabled,button:disabled,input[type=button].disabled,input[type=button]:disabled,input[type=reset].disabled,input[type=reset]:disabled,input[type=submit].disabled,input[type=submit]:disabled{opacity:.5!important;cursor:not-allowed}.added_to_cart.disabled:hover,.added_to_cart:disabled:hover,.button.disabled:hover,.button:disabled:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link.disabled:hover,.wc-block-grid__products .wc-block-grid__product .wp-block-button__link:disabled:hover,button.disabled:hover,button:disabled:hover,input[type=button].disabled:hover,input[type=button]:disabled:hover,input[type=reset].disabled:hover,input[type=reset]:disabled:hover,input[type=submit].disabled:hover,input[type=submit]:disabled:hover{opacity:.5!important}.wc-block-components-button:not(.is-link).disabled,.wc-block-components-button:not(.is-link):disabled{opacity:.5;cursor:not-allowed}.wc-block-components-button:not(.is-link).disabled:hover,.wc-block-components-button:not(.is-link):disabled:hover{opacity:.5}input[type=checkbox],input[type=radio]{padding:0}input[type=checkbox]+label,input[type=radio]+label{margin:0 0 0 .3819820591em}input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=search]{box-sizing:border-box}input[type=search]::-webkit-input-placeholder{color:#616161}input[type=search]:-ms-input-placeholder{color:#616161}input[type=search]::-ms-input-placeholder{color:#616161}input[type=search]::placeholder{color:#616161}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}.input-text,input[type=email],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=url],textarea{padding:.6180469716em;background-color:#f2f2f2;color:#43454b;border:0;-webkit-appearance:none;box-sizing:border-box;font-weight:400;box-shadow:inset 0 1px 1px rgba(0,0,0,.125)}.input-text:focus,input[type=email]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=url]:focus,textarea:focus{background-color:#ededed}textarea{overflow:auto;padding-left:.875em;vertical-align:top;width:100%}label{font-weight:400}label.inline input{width:auto}fieldset{padding:1em 1.618em 1.618em;border:0;margin:1.618em 0}fieldset legend{font-weight:600;padding:.6180469716em 1em;margin-left:-1em}[placeholder]:focus::-webkit-input-placeholder{-webkit-transition:opacity .5s ease .5s;transition:opacity .5s ease .5s;opacity:0}.comment-content img.wp-smiley,.entry-content img.wp-smiley,.page-content img.wp-smiley{border:none;margin-bottom:0;margin-top:0;padding:0;display:inline-block;border-radius:0}.wp-caption{margin-bottom:1em;max-width:100%}.wp-caption img[class*=wp-image-]{display:block;margin:0 auto}.wp-caption .wp-caption-text{text-align:left;font-style:italic;border-bottom:2px solid rgba(0,0,0,.05);padding:1em 0}.gallery{margin-bottom:1em}.gallery:after,.gallery:before{content:"";display:table}.gallery:after{clear:both}.gallery .gallery-item{float:left}.gallery .gallery-item .gallery-icon a{display:block}.gallery .gallery-item .gallery-icon img{border:none;height:auto;margin:0 auto}.gallery .gallery-item .gallery-caption{margin:0;text-align:center}.gallery.gallery-columns-1 .gallery-item{width:100%}.gallery.gallery-columns-2 .gallery-item{width:50%}.gallery.gallery-columns-3 .gallery-item{width:33.3%}.gallery.gallery-columns-4 .gallery-item{width:25%}.gallery.gallery-columns-5 .gallery-item{width:20%}.gallery.gallery-columns-6 .gallery-item{width:16.666666667%}.gallery.gallery-columns-7 .gallery-item{width:14.285714286%}.gallery.gallery-columns-8 .gallery-item{width:12.5%}.gallery.gallery-columns-9 .gallery-item{width:11.111111111%}embed,iframe,object,video{max-width:100%}.secondary-navigation{display:none}button.menu-toggle{cursor:pointer;text-align:left;float:right;position:relative;border:2px solid rgba(0,0,0,0);box-shadow:none;border-radius:2px;padding:.6180469716em .875em .6180469716em 2.617924em;font-size:.875em;max-width:120px}button.menu-toggle,button.menu-toggle:hover{background-image:none}button.menu-toggle span:before{-webkit-transition:all,ease,.2s;transition:all,ease,.2s}button.menu-toggle:after,button.menu-toggle:before,button.menu-toggle span:before{content:"";display:block;height:2px;width:14px;position:absolute;top:50%;left:1em;margin-top:-1px;-webkit-transition:all,ease,.2s;transition:all,ease,.2s;border-radius:3px}button.menu-toggle:before{-webkit-transform:translateY(-4px);-ms-transform:translateY(-4px);transform:translateY(-4px)}button.menu-toggle:after{-webkit-transform:translateY(4px);-ms-transform:translateY(4px);transform:translateY(4px)}.toggled button.menu-toggle:after,.toggled button.menu-toggle:before{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.toggled button.menu-toggle:after{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.toggled button.menu-toggle span:before{opacity:0}.primary-navigation{display:none}.main-navigation:after,.main-navigation:before{content:"";display:table}.main-navigation:after{clear:both}.main-navigation div.menu{display:none}.main-navigation div.menu:last-child{display:block}.main-navigation .menu{clear:both}.handheld-navigation,.main-navigation div.menu>ul:not(.nav-menu),.nav-menu{overflow:hidden;max-height:0;-webkit-transition:all,ease,.8s;transition:all,ease,.8s}.handheld-navigation{clear:both}.handheld-navigation ul{margin:0}.handheld-navigation ul.menu li{position:relative}.handheld-navigation ul.menu li button:after{-webkit-transition:all,ease,.9s;transition:all,ease,.9s}.handheld-navigation ul.menu li button.toggled-on:after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.handheld-navigation ul.menu .sub-menu{visibility:hidden;opacity:0;max-height:0;-webkit-transition:all,ease,.9s;transition:all,ease,.9s}.handheld-navigation ul.menu .sub-menu.toggled-on{visibility:visible;max-height:9999px;opacity:1}.handheld-navigation .dropdown-toggle{background:rgba(0,0,0,0);position:absolute;top:0;right:0;display:block}.main-navigation.toggled .handheld-navigation,.main-navigation.toggled .menu>ul:not(.nav-menu),.main-navigation.toggled ul[aria-expanded=true]{max-height:9999px}.main-navigation ul{margin-left:0;list-style:none;margin-bottom:0}.main-navigation ul ul{display:block;margin-left:1.41575em}.main-navigation ul li a{padding:.875em 0;display:block}.main-navigation ul li a:hover{color:#e6e6e6}.site-main nav.navigation{clear:both;padding:2.617924em 0}.site-main nav.navigation:after,.site-main nav.navigation:before{content:"";display:table}.site-main nav.navigation:after{clear:both}.site-main nav.navigation .nav-next a,.site-main nav.navigation .nav-previous a{display:inline-block}.site-main nav.navigation .nav-previous{float:left;width:50%}.site-main nav.navigation .nav-next{float:right;text-align:right;width:50%}.pagination,.woocommerce-pagination{padding:1em 0;border:1px solid rgba(0,0,0,.05);border-width:1px 0;text-align:center;clear:both}.pagination ul.page-numbers:after,.pagination ul.page-numbers:before,.woocommerce-pagination ul.page-numbers:after,.woocommerce-pagination ul.page-numbers:before{content:"";display:table}.pagination ul.page-numbers:after,.woocommerce-pagination ul.page-numbers:after{clear:both}.pagination .page-numbers,.woocommerce-pagination .page-numbers{list-style:none;margin:0;vertical-align:middle}.pagination .page-numbers li,.woocommerce-pagination .page-numbers li{display:inline-block}.pagination .page-numbers li .page-numbers,.woocommerce-pagination .page-numbers li .page-numbers{border-left-width:0;display:inline-block;padding:.3342343017em .875em;background-color:rgba(0,0,0,.025);color:#43454b}.pagination .page-numbers li .page-numbers.current,.woocommerce-pagination .page-numbers li .page-numbers.current{background-color:#2c2d33;border-color:#2c2d33}.pagination .page-numbers li .page-numbers.dots,.woocommerce-pagination .page-numbers li .page-numbers.dots{background-color:rgba(0,0,0,0)}.pagination .page-numbers li .page-numbers.next,.pagination .page-numbers li .page-numbers.prev,.woocommerce-pagination .page-numbers li .page-numbers.next,.woocommerce-pagination .page-numbers li .page-numbers.prev{padding-left:1em;padding-right:1em}.pagination .page-numbers li a.page-numbers:hover,.woocommerce-pagination .page-numbers li a.page-numbers:hover{background-color:rgba(0,0,0,.05)}.rtl .pagination a.next,.rtl .pagination a.prev,.rtl .woocommerce-pagination a.next,.rtl .woocommerce-pagination a.prev{-webkit-transform:rotateY(180deg);transform:rotateY(180deg)}.widget{margin:0 0 3.706325903em}.widget select{max-width:100%}.widget .widget-search .search-submit{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.widget .widget-title,.widget .widgettitle{font-size:1.41575em;letter-spacing:0;border-bottom:1px solid rgba(0,0,0,.05);padding:0 0 1em;margin-bottom:1em;font-weight:300}.widget ul{margin-left:0;list-style:none}.widget ul ul{margin-left:1.618em}.widget-area .widget{font-size:.875em;font-weight:400}.widget-area .widget h1.widget-title{font-size:1.41575em}.widget-area .widget a{font-weight:600;text-decoration:underline}.widget-area .widget a:hover{text-decoration:none}.widget-area .widget a.button,.widget-area .widget a.components-button:not(.is-link),.widget-area .widget a.wp-block-button__link{text-decoration:none}.widget-area .widget a.button{font-weight:600!important}.widget_product_search form,.widget_search form{position:relative}.widget_product_search form input[type=search],.widget_product_search form input[type=text],.widget_search form input[type=search],.widget_search form input[type=text]{width:100%}.widget_product_search form button[type=submit],.widget_product_search form input[type=submit],.widget_search form button[type=submit],.widget_search form input[type=submit]{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important;top:0;left:0}.widget_archive ul,.widget_categories ul,.widget_layered_nav_filters ul,.widget_layered_nav ul,.widget_links ul,.widget_nav_menu ul,.widget_pages ul,.widget_product_categories ul,.widget_recent_comments ul,.widget_recent_entries ul{margin:0}.widget_archive ul li,.widget_categories ul li,.widget_layered_nav_filters ul li,.widget_layered_nav ul li,.widget_links ul li,.widget_nav_menu ul li,.widget_pages ul li,.widget_product_categories ul li,.widget_recent_comments ul li,.widget_recent_entries ul li{list-style:none;margin-bottom:1em;line-height:1.41575em}.widget_archive ul .children,.widget_categories ul .children,.widget_layered_nav_filters ul .children,.widget_layered_nav ul .children,.widget_links ul .children,.widget_nav_menu ul .children,.widget_pages ul .children,.widget_product_categories ul .children,.widget_recent_comments ul .children,.widget_recent_entries ul .children{margin-left:0;margin-top:1em}#wp-calendar td,#wp-calendar th,.wp-calendar-table td,.wp-calendar-table th{padding:.236em;text-align:center}.widget_pages ul ul.children,.widget_recent_entries ul ul.children{margin:.6180469716em 0 0 1.41575em}.widget_rating_filter .wc-layered-nav-rating{margin-bottom:.6180469716em}.widget_rating_filter .wc-layered-nav-rating a{text-decoration:none!important}.widget_rating_filter .wc-layered-nav-rating .star-rating{display:inline-block;height:1em;line-height:1}@media (min-width:768px){table.shop_table_responsive tbody tr td,table.shop_table_responsive tbody tr th{text-align:left}.site-header{padding-top:2.617924em;padding-bottom:0}.site-header .site-branding{display:block;width:100%;float:left;margin-left:0;margin-right:0;clear:both}.site-header .site-branding img{height:auto;max-width:230px;max-height:none}.woocommerce-active .site-header .site-branding{width:73.9130434783%;float:left;margin-right:4.347826087%}.woocommerce-active .site-header .site-search{width:21.7391304348%;float:right;margin-right:0;clear:none}.woocommerce-active .site-header .main-navigation{width:73.9130434783%;float:left;margin-right:4.347826087%;clear:both}.woocommerce-active .site-header .site-header-cart{width:21.7391304348%;float:right;margin-right:0;margin-bottom:0}.storefront-secondary-navigation .site-header .site-branding{width:39.1304347826%;float:left;margin-right:4.347826087%}.storefront-secondary-navigation .site-header .secondary-navigation{width:56.5217391304%;float:right;margin-right:0}.storefront-secondary-navigation.woocommerce-active .site-header .site-branding{width:21.7391304348%;float:left;margin-right:4.347826087%}.storefront-secondary-navigation.woocommerce-active .site-header .secondary-navigation{width:47.8260869565%;float:left;margin-right:4.347826087%}.site-branding .site-description{margin-bottom:0;display:block}.custom-logo-link,.site-branding,.site-header-cart,.site-logo-anchor,.site-logo-link,.site-search{margin-bottom:1.41575em}.site-header .subscribe-and-connect-connect{float:right;margin-bottom:1em}.site-header .subscribe-and-connect-connect .icons{list-style:none;margin:0}.site-header .subscribe-and-connect-connect .icons a{font-size:1em!important}.site-header .subscribe-and-connect-connect .icons li{margin:0 0 0 .5407911001em!important;display:inline-block}.col-full{max-width:66.4989378333em;margin-left:auto;margin-right:auto;padding:0 2.617924em;box-sizing:content-box}.col-full:after,.col-full:before{content:"";display:table}.col-full:after{content:" ";display:block;clear:both}.site-content:after,.site-content:before{content:"";display:table}.site-content:after{clear:both}.content-area{width:73.9130434783%;float:left;margin-right:4.347826087%}.widget-area{width:21.7391304348%;float:right;margin-right:0}.right-sidebar .content-area{width:73.9130434783%;float:left;margin-right:4.347826087%}.right-sidebar .widget-area{width:21.7391304348%;float:right;margin-right:0}.left-sidebar .content-area{width:73.9130434783%;float:right;margin-right:0}.left-sidebar .widget-area{width:21.7391304348%;float:left;margin-right:4.347826087%}.storefront-full-width-content .content-area{width:100%;float:left;margin-left:0;margin-right:0}.content-area,.widget-area{margin-bottom:2.617924em}.page-template-template-fullwidth-php .content-area,.page-template-template-homepage-php .content-area{width:100%;float:left;margin-left:0;margin-right:0}.footer-widgets{padding-top:4.235801032em;border-bottom:1px solid rgba(0,0,0,.05)}.footer-widgets:after,.footer-widgets:before{content:"";display:table}.footer-widgets:after{clear:both}.footer-widgets.col-2 .block{width:47.8260869565%;float:left;margin-right:4.347826087%}.footer-widgets.col-2 .block.footer-widget-2{float:right;margin-right:0}.footer-widgets.col-3 .block{width:30.4347826087%;float:left;margin-right:4.347826087%}.footer-widgets.col-3 .block.footer-widget-3{float:right;margin-right:0}.footer-widgets.col-4 .block{width:21.7391304348%;float:left;margin-right:4.347826087%}.footer-widgets.col-4 .block.footer-widget-4{float:right;margin-right:0}.comment-list:after,.comment-list:before{content:"";display:table}.comment-list:after{clear:both}.comment-list .comment{clear:both}.comment-list .comment-meta{width:17.6470588235%;float:left;margin-right:5.8823529412%;text-align:right}.comment-list .comment-meta .avatar{float:right}.comment-list .comment-content{padding-bottom:3.706325903em;margin-bottom:3.706325903em}.comment-list #respond,.comment-list .comment-content{width:76.4705882353%;float:right;margin-right:0}.comment-list #respond{float:right}.comment-list #respond .comment-form-author,.comment-list #respond .comment-form-email,.comment-list #respond .comment-form-url{width:100%;margin-right:0}.comment-list .comment-body #respond{box-shadow:0 6px 2em rgba(0,0,0,.2);margin-bottom:2.617924em;margin-top:-1.618em}.comment-list .reply{clear:both;text-align:right}.comment-list ol.children{width:88.2352941176%;float:right;margin-right:0;list-style:none}.comment-list ol.children .comment-meta{width:20%;float:left;margin-right:6.6666666667%}.comment-list ol.children #respond,.comment-list ol.children .comment-content{width:73.3333333333%;float:right;margin-right:0}.comment-list ol.children ol.children{width:86.6666666667%;float:right;margin-right:0}.comment-list ol.children ol.children .comment-meta{width:23.0769230769%;float:left;margin-right:7.6923076923%}.comment-list ol.children ol.children #respond,.comment-list ol.children ol.children .comment-content{width:69.2307692308%;float:right;margin-right:0}.comment-list ol.children ol.children ol.children{width:84.6153846154%;float:right;margin-right:0}.comment-list ol.children ol.children ol.children .comment-meta{width:27.2727272727%;float:left;margin-right:9.0909090909%}.comment-list ol.children ol.children ol.children #respond,.comment-list ol.children ol.children ol.children .comment-content{width:63.6363636364%;float:right;margin-right:0}.comment-list ol.children ol.children ol.children ol.children{width:81.8181818182%;float:right;margin-right:0}.comment-list ol.children ol.children ol.children ol.children .comment-meta{width:33.3333333333%;float:left;margin-right:11.1111111111%}.comment-list ol.children ol.children ol.children ol.children #respond,.comment-list ol.children ol.children ol.children ol.children .comment-content{width:55.5555555556%;float:right;margin-right:0}#respond{padding:2.617924em}#respond .comment-form-author,#respond .comment-form-email,#respond .comment-form-url{width:29.4117647059%;float:left;margin-right:5.8823529412%}#respond .comment-form-url{float:right;margin-right:0}#respond .comment-form-comment{clear:both}.hentry .entry-header{margin-bottom:2.617924em}.handheld-navigation,.main-navigation.toggled .handheld-navigation,.main-navigation.toggled div.menu,.menu-toggle{display:none}.primary-navigation{display:block}.main-navigation,.secondary-navigation{clear:both;display:block;width:100%}.main-navigation ul,.secondary-navigation ul{list-style:none;margin:0;padding-left:0;display:block}.main-navigation ul li,.secondary-navigation ul li{position:relative;display:inline-block;text-align:left}.main-navigation ul li a,.secondary-navigation ul li a{display:block}.main-navigation ul li a:before,.secondary-navigation ul li a:before{display:none}.main-navigation ul li.focus>ul,.main-navigation ul li:hover>ul,.secondary-navigation ul li.focus>ul,.secondary-navigation ul li:hover>ul{left:0;display:block}.main-navigation ul li.focus>ul li>ul,.main-navigation ul li:hover>ul li>ul,.secondary-navigation ul li.focus>ul li>ul,.secondary-navigation ul li:hover>ul li>ul{left:-9999px}.main-navigation ul li.focus>ul li>ul.sub-menu--is-touch-device,.main-navigation ul li:hover>ul li>ul.sub-menu--is-touch-device,.secondary-navigation ul li.focus>ul li>ul.sub-menu--is-touch-device,.secondary-navigation ul li:hover>ul li>ul.sub-menu--is-touch-device{display:none;left:0}.main-navigation ul li.focus>ul li.focus>ul,.main-navigation ul li.focus>ul li:hover>ul,.main-navigation ul li:hover>ul li.focus>ul,.main-navigation ul li:hover>ul li:hover>ul,.secondary-navigation ul li.focus>ul li.focus>ul,.secondary-navigation ul li.focus>ul li:hover>ul,.secondary-navigation ul li:hover>ul li.focus>ul,.secondary-navigation ul li:hover>ul li:hover>ul{left:100%;top:0;display:block}.main-navigation ul ul,.secondary-navigation ul ul{float:left;position:absolute;top:100%;z-index:99999;left:-9999px}.main-navigation ul ul.sub-menu--is-touch-device,.secondary-navigation ul ul.sub-menu--is-touch-device{display:none;left:0}.main-navigation ul ul li,.secondary-navigation ul ul li{display:block}.main-navigation ul ul li a,.secondary-navigation ul ul li a{width:200px}ul.menu li.current-menu-item>a{color:#43454b}.storefront-primary-navigation{clear:both}.storefront-primary-navigation:after,.storefront-primary-navigation:before{content:"";display:table}.storefront-primary-navigation:after{clear:both}.main-navigation div.menu{display:block}.main-navigation ul.menu,.main-navigation ul.nav-menu{max-height:none;overflow:visible;margin-left:-1em;-webkit-transition:none;transition:none}.main-navigation ul.menu>li>a,.main-navigation ul.nav-menu>li>a{padding:1.618em 1em}.main-navigation ul.menu>li.menu-item-has-children:hover:after,.main-navigation ul.menu>li.page_item_has_children:hover:after,.main-navigation ul.nav-menu>li.menu-item-has-children:hover:after,.main-navigation ul.nav-menu>li.page_item_has_children:hover:after{display:block}.main-navigation ul.menu ul,.main-navigation ul.nav-menu ul{margin-left:0}.main-navigation ul.menu ul li a,.main-navigation ul.nav-menu ul li a{padding:.875em 1.41575em;font-weight:400;font-size:.875em}.main-navigation ul.menu ul li:last-child,.main-navigation ul.nav-menu ul li:last-child{border-bottom:0}.main-navigation ul.menu ul ul,.main-navigation ul.nav-menu ul ul{margin-left:0;box-shadow:none}.main-navigation ul.menu ul a:hover,.main-navigation ul.menu ul li.focus,.main-navigation ul.menu ul li:hover>a,.main-navigation ul.nav-menu ul a:hover,.main-navigation ul.nav-menu ul li.focus,.main-navigation ul.nav-menu ul li:hover>a{background-color:rgba(0,0,0,.025)}.main-navigation a{padding:0 1em 2.2906835em}.secondary-navigation{margin:0 0 1.618em;width:auto;clear:none;line-height:1}.secondary-navigation .menu{font-size:.875em;width:auto;float:right}.secondary-navigation .menu>li:hover>a{text-decoration:none}.secondary-navigation .menu ul a{padding:.326em .875em;background:rgba(0,0,0,.05)}.secondary-navigation .menu ul li:first-child a{padding-top:1em}.secondary-navigation .menu ul li:last-child a{padding-bottom:1em}.secondary-navigation .menu ul ul{margin-top:-.6180469716em}.secondary-navigation .menu a{padding:1em .875em;color:#737781;font-weight:400}.secondary-navigation .menu a:hover{text-decoration:none}.error404 .fourohfour-columns-2 .col-1{width:47.8260869565%;float:left;margin-right:4.347826087%}.error404 .fourohfour-columns-2 .col-1 ul.products{margin-bottom:0}.error404 .fourohfour-columns-2 .col-2{width:47.8260869565%;float:right;margin-right:0}}@media (max-width:66.4989378333em){.col-full{margin-left:2.617924em;margin-right:2.617924em;padding:0}}@media (max-width:568px){.col-full{margin-left:1.41575em;margin-right:1.41575em;padding:0}} \ No newline at end of file diff --git a/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/template-fullwidth.php b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/template-fullwidth.php new file mode 100644 index 0000000..ed031de --- /dev/null +++ b/TE2/Proyecto Teknovate/htdocs/wordpress/wp-content/themes/storefront/template-fullwidth.php @@ -0,0 +1,37 @@ + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    +