<?php /** * Plugin Name: Agulló · Tienda en preparación * Description: WooCommerce sin precios ni compra, con área privada integrada en Agulló. * Version: 0.1.6 * Requires PHP: 8.0 * Author: Electricidad Agulló */ if(!defined('ABSPATH'))exit; function ags_message(){return 'Estamos preparando la compra online. Mientras tanto, puedes consultar productos y solicitar información a Agulló.';} // El bloqueo es deliberadamente incondicional: cargar tarifas no abre la venta. add_filter('woocommerce_is_purchasable','__return_false',PHP_INT_MAX); add_filter('woocommerce_variation_is_purchasable','__return_false',PHP_INT_MAX); add_filter('woocommerce_get_price_html','__return_empty_string',PHP_INT_MAX); add_filter('woocommerce_available_payment_gateways','__return_empty_array',PHP_INT_MAX); add_filter('woocommerce_add_to_cart_validation',function(){if(function_exists('wc_add_notice'))wc_add_notice(ags_message(),'error');return false;},PHP_INT_MAX); add_action('woocommerce_after_checkout_validation',function($data,$errors){$errors->add('agullo_sales_closed',ags_message());},PHP_INT_MAX,2); add_action('woocommerce_checkout_create_order',function(){throw new Exception(ags_message());},PHP_INT_MAX); add_filter('rest_pre_dispatch',function($result,$server,$request){if(preg_match('#^/wc/store(?:/v[0-9]+)?/(?:checkout|cart/(?:add-item|update-item))(?:/|$)#',$request->get_route()))return new WP_Error('agullo_sales_closed',ags_message(),array('status'=>403));return $result;},PHP_INT_MAX,3); add_filter('woocommerce_structured_data_product',function($data){unset($data['offers']);return $data;},PHP_INT_MAX); add_action('after_setup_theme',function(){add_theme_support('woocommerce');},20); add_action('init',function(){foreach(array('favoritos','facturas','ayuda')as $endpoint)add_rewrite_endpoint($endpoint,EP_ROOT|EP_PAGES);}); add_filter('woocommerce_account_menu_items',function($items){return array('dashboard'=>'Resumen','orders'=>'Mis pedidos','edit-address'=>'Direcciones','facturas'=>'Facturas','favoritos'=>'Favoritos','edit-account'=>'Datos personales','ayuda'=>'Ayuda','customer-logout'=>'Cerrar sesión');}); function ags_favorites($uid=0){return array_values((array)get_user_meta($uid?:get_current_user_id(),'ags_favorites',true));} add_action('wp_ajax_ags_favorites',function(){check_ajax_referer('ags_favorites','nonce');if(!is_user_logged_in())wp_send_json_error(null,403);if(isset($_POST['ids'])){$input=json_decode(wp_unslash($_POST['ids']),true);if(!is_array($input)||count($input)>100)wp_send_json_error(null,400);$ids=array_values(array_unique(array_filter(array_map('sanitize_key',$input))));$valid=array();if($ids){$posts=get_posts(array('post_type'=>'agullo_luminaire','post_status'=>'publish','posts_per_page'=>100,'meta_key'=>'_agullo_seed_id','meta_value'=>$ids,'meta_compare'=>'IN'));foreach($posts as $post)$valid[]=get_post_meta($post->ID,'_agullo_seed_id',true);}update_user_meta(get_current_user_id(),'ags_favorites',$valid);}wp_send_json_success(array('ids'=>ags_favorites()));}); add_action('wp_enqueue_scripts',function(){if(!class_exists('WooCommerce'))return;if(is_account_page()||is_cart()||is_checkout()){wp_enqueue_style('ags-account',plugins_url('assets/account.css',__FILE__),array(),'0.1.0');}if(is_user_logged_in()){wp_add_inline_script('agullo-ui','try{const k="agullo-product-favorites",owner="agullo-favorites-owner",uid="'.get_current_user_id().'",pk="ags-favorites-pending-"+uid;const l=JSON.parse(localStorage.getItem(k)||"[]"),r='.wp_json_encode(ags_favorites()).',p=localStorage.getItem(pk),o=localStorage.getItem(owner);let ids=p?JSON.parse(p):(!o?Array.from(new Set([...r,...(Array.isArray(l)?l:[])])):r);ids=Array.isArray(ids)?ids.slice(0,100):r;localStorage.setItem(k,JSON.stringify(ids));localStorage.setItem(owner,uid);if(JSON.stringify(ids)!==JSON.stringify(r))localStorage.setItem(pk,JSON.stringify(ids));}catch(e){}','before');wp_enqueue_script('ags-favorites',plugins_url('assets/favorites.js',__FILE__),array('agullo-ui'),'0.1.3',true);wp_localize_script('ags-favorites','agsFavorites',array('ajax'=>admin_url('admin-ajax.php'),'nonce'=>wp_create_nonce('ags_favorites'),'ids'=>ags_favorites(),'uid'=>get_current_user_id()));}},30); add_filter('template_include',function($template){if(function_exists('is_account_page')&&(is_account_page()||is_cart()||is_checkout()))return __DIR__.'/templates/account.php';return $template;},100); add_filter('woocommerce_locate_template',function($file,$name){return $name==='myaccount/dashboard.php'?__DIR__.'/templates/dashboard.php':$file;},30,2); add_action('woocommerce_account_facturas_endpoint',function(){echo '<h2>Tus facturas</h2><div class="ags-card"><p>Todavía no tienes facturas disponibles.</p><p>Cuando se active la compra online, podrás consultar aquí los documentos emitidos de tus pedidos.</p></div>';}); add_action('woocommerce_account_favoritos_endpoint',function(){echo '<h2>Una selección muy tuya.</h2><p>Las piezas que has guardado para tu próximo proyecto.</p>'; $ids=ags_favorites();if(!$ids){echo '<div class="ags-card"><p>Aún no has guardado piezas en tu cuenta.</p><a class="button" href="'.esc_url(home_url('/iluminacion/')).'">Explorar el catálogo</a></div>';return;}echo '<div class="ags-favorites-grid">';foreach($ids as $id){if(!function_exists('agullo_catalog_product_by_id'))continue;$p=agullo_catalog_product_by_id($id);if($p&&function_exists('agullo_card'))agullo_card($p);}echo '</div>';}); add_action('woocommerce_account_ayuda_endpoint',function(){echo '<h2>Te acompañamos.</h2><div class="ags-card"><p>Si necesitas ayuda con una pieza, una dirección o tu proyecto de iluminación, habla con nuestro equipo.</p><a class="button" href="'.esc_url(home_url('/contacto/')).'">Contactar con Agulló</a></div>';}); add_filter('woocommerce_billing_fields',function($fields){$fields['billing_company']=array('label'=>'Empresa / razón social','type'=>'text','required'=>false,'class'=>array('form-row-wide'),'priority'=>30);$fields['billing_nif']=array('label'=>'NIF / CIF para facturación','required'=>false,'class'=>array('form-row-wide'),'priority'=>35);return $fields;}); add_action('woocommerce_customer_save_address',function($uid,$type){if($type==='billing'&&isset($_POST['billing_nif']))update_user_meta($uid,'billing_nif',sanitize_text_field(wp_unslash($_POST['billing_nif'])));},10,2); add_filter('woocommerce_get_breadcrumb',function($crumbs){return $crumbs;}); add_action('admin_menu',function(){add_management_page('Agulló · Preparar tienda','Preparar tienda Agulló','manage_options','agullo-tienda','ags_admin');}); function ags_admin(){if(!current_user_can('manage_options'))return;echo '<div class="wrap"><h1>Agulló · Tienda en preparación</h1><p><strong>Venta online bloqueada.</strong> No se muestran precios, no se pueden añadir productos a la cesta y se rechazan los intentos de compra clásicos y mediante Store API.</p><p>El catálogo de iluminación actual conserva sus fichas y URLs. No se importan precios, productos de muestra ni pedidos ficticios.</p>';if(!class_exists('WooCommerce')){echo '<p>Instala y activa WooCommerce antes de preparar las páginas.</p>';}else{echo '<p>WooCommerce '.esc_html(WC_VERSION).' activo.</p><form method="post" action="'.esc_url(admin_url('admin-post.php')).'"><input type="hidden" name="action" value="ags_setup">';wp_nonce_field('ags_setup');submit_button('Preparar páginas de cuenta, cesta y compra');echo '</form><p><a href="'.esc_url(wc_get_page_permalink('myaccount')).'">Abrir Mi cuenta</a></p>';}echo '<p>La venta no se abrirá automáticamente al incorporar tarifas. Será necesario retirar expresamente este bloqueo cuando estén listos precios, pagos, fiscalidad y envíos.</p></div>';} add_action('admin_post_ags_setup',function(){if(!current_user_can('manage_options'))wp_die('Sin permisos',403);check_admin_referer('ags_setup');if(!class_exists('WooCommerce'))wp_die('WooCommerce no está activo.');foreach(array('myaccount'=>array('Mi cuenta','mi-cuenta','[woocommerce_my_account]'),'cart'=>array('Cesta','cesta','[woocommerce_cart]'),'checkout'=>array('Finalizar compra','finalizar-compra','[woocommerce_checkout]'))as $key=>$data){$current=absint(get_option('woocommerce_'.$key.'_page_id'));if($current&&get_post_status($current)==='publish')continue;$existing=get_page_by_path($data[1]);if($existing){if(!has_shortcode($existing->post_content,trim($data[2],'[]')))wp_die('Existe una página con la ruta '.$data[1].'. Revísala antes de continuar.');$id=$existing->ID;}else{$id=wp_insert_post(array('post_type'=>'page','post_title'=>$data[0],'post_name'=>$data[1],'post_content'=>$data[2],'post_status'=>'publish'),true);if(is_wp_error($id))wp_die(esc_html($id->get_error_message()));}update_option('woocommerce_'.$key.'_page_id',$id);update_post_meta($id,'_yoast_wpseo_meta-robots-noindex','1');}update_option('woocommerce_currency','EUR');update_option('woocommerce_currency_pos','right_space');update_option('woocommerce_price_decimal_sep',',');update_option('woocommerce_price_thousand_sep','.');update_option('woocommerce_enable_guest_checkout','no');update_option('woocommerce_enable_myaccount_registration','no');update_option('woocommerce_enable_checkout_login_reminder','yes');update_option('woocommerce_ship_to_destination','shipping');flush_rewrite_rules();wp_safe_redirect(admin_url('tools.php?page=agullo-tienda'));exit;}); register_activation_hook(__FILE__,function(){foreach(array('favoritos','facturas','ayuda')as $e)add_rewrite_endpoint($e,EP_ROOT|EP_PAGES);flush_rewrite_rules();}); register_deactivation_hook(__FILE__,'flush_rewrite_rules'); add_action('wp_enqueue_scripts',function(){if(!class_exists('WooCommerce'))return;wp_enqueue_script('ags-navigation',plugins_url('assets/navigation.js',__FILE__),array(),'0.1.1',true);wp_localize_script('ags-navigation','agsNavigation',array('account'=>wc_get_page_permalink('myaccount')));},35); require_once __DIR__.'/emails.php'; require_once __DIR__.'/sitemaps.php'; require_once __DIR__.'/idiomas.php'; /* AGML_ADMIN_BRIDGE_20261113 */ /** Temporary, capability- and nonce-guarded translation import/export UI. */ if (!defined('ABSPATH')) exit; add_action('admin_menu', function () { add_management_page('Traducciones Agulló', 'Traducciones Agulló', 'manage_options', 'agullo-traducciones', 'agml_bridge_page'); }); function agml_bridge_page() { if (!current_user_can('manage_options')) return; echo '<div class="wrap"><h1>Traducciones Agulló</h1><p>Importa traducciones revisadas como borradores vinculados mediante WPML. Conserva imágenes, referencias y originales.</p>'; $report = get_transient('agml_import_' . get_current_user_id()); if ($report) echo '<div class="notice notice-success"><p>' . esc_html($report) . '</p></div>'; echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '"><input type="hidden" name="action" value="agml_import">'; wp_nonce_field('agml_import'); echo '<label for="agml-batch">Lote JSON de traducciones</label><textarea id="agml-batch" name="batch" rows="12" class="large-text code" required></textarea>'; submit_button('Importar borradores traducidos'); echo '</form><hr><h2>Consultar originales publicados</h2><form method="get"><input type="hidden" name="page" value="agullo-traducciones"><label>IDs de originales (máximo 20) <input name="source_ids" value="' . esc_attr(sanitize_text_field(wp_unslash($_GET['source_ids'] ?? ''))) . '"></label>'; submit_button('Consultar', 'secondary'); echo '</form>'; $ids = array_slice(array_filter(array_map('absint', explode(',', sanitize_text_field(wp_unslash($_GET['source_ids'] ?? '')))))), 0, 20); $rows = array(); foreach ($ids as $id) { $p = get_post($id); if (!$p || $p->post_status !== 'publish' || !in_array($p->post_type, array('post','page','agullo_luminaire'), true)) continue; $row = array('source_id'=>$id, 'type'=>$p->post_type, 'title'=>$p->post_title, 'slug'=>$p->post_name, 'content'=>$p->post_content, 'excerpt'=>$p->post_excerpt); foreach (array('_agullo_record','_agullo_guide_record') as $key) { $value = get_post_meta($id, $key, true); if (is_array($value)) $row[$key] = array_intersect_key($value, array_flip(array('id','sku','brand','category','finish','material','size','light','bulb','ip','imageCaption','quick','credit','related_products','faq'))); } $row['seo_title'] = get_post_meta($id, '_yoast_wpseo_title', true); $row['seo_description'] = get_post_meta($id, '_yoast_wpseo_metadesc', true); $rows[] = $row; } if ($ids) echo '<textarea readonly rows="18" class="large-text code" id="agml-export">' . esc_textarea(wp_json_encode($rows, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)) . '</textarea>'; echo '</div>'; } add_action('admin_post_agml_import', function () { if (!current_user_can('manage_options')) wp_die('Sin permisos', '', array('response'=>403)); check_admin_referer('agml_import'); if (!defined('ICL_SITEPRESS_VERSION')) wp_die('WPML debe estar activo.'); $raw = wp_unslash($_POST['batch'] ?? ''); if (!is_string($raw) || strlen($raw) > 1500000) wp_die('Lote no válido.'); if (str_starts_with($raw, 'GZIP:')) { $packed = base64_decode(substr($raw, 5), true); $raw = $packed && function_exists('gzdecode') ? gzdecode($packed, 1500001) : false; if (!is_string($raw) || strlen($raw) > 1500000) wp_die('Lote comprimido no válido.'); } $rows = json_decode($raw, true); if (!is_array($rows) || !$rows || count($rows) > 60) wp_die('El lote debe contener entre 1 y 60 traducciones.'); $seen = array(); foreach ($rows as $r) { if (!is_array($r) || !in_array($r['language'] ?? '', array('en','fr','de'), true) || empty($r['source_id']) || empty($r['title']) || empty($r['slug']) || (!isset($r['segments']) && !isset($r['content']))) wp_die('Traducción incompleta.'); $p = get_post(absint($r['source_id'])); if (!$p || $p->post_status !== 'publish' || !in_array($p->post_type, array('post','page','agullo_luminaire'), true)) wp_die('Original no permitido.'); $key = $p->ID . ':' . $r['language']; if (isset($seen[$key])) wp_die('Traducción duplicada en el lote.'); $seen[$key] = true; $details = apply_filters('wpml_element_language_details', null, array('element_id'=>$p->ID, 'element_type'=>'post_' . $p->post_type)); if ($details && $details->language_code !== 'es') wp_die('El original no está en español.'); $existing = apply_filters('wpml_object_id', $p->ID, $p->post_type, false, $r['language']); // Never replace translations created by WPML or earlier imports implicitly. if ($existing && (int)$existing !== $p->ID) wp_die('Ya existe una traducción del original ' . $p->ID . ' en ' . esc_html($r['language']) . '. Revísala antes de sustituirla.'); if (isset($r['segments'])) { if (!is_array($r['segments']) || count($r['segments']) > 300) wp_die('Segmentos no válidos.'); foreach ($r['segments'] as $s) if (!is_array($s) || !isset($s['source'],$s['translation']) || !is_string($s['source']) || $s['source'] === '' || !is_string($s['translation']) || strpos($p->post_content, $s['source']) === false) wp_die('El contenido original ha cambiado. Revisa sus segmentos.'); } } $created = array(); foreach ($rows as $r) { $source = get_post(absint($r['source_id'])); $type = 'post_' . $source->post_type; $details = apply_filters('wpml_element_language_details', null, array('element_id'=>$source->ID, 'element_type'=>$type)); if (!$details) { do_action('wpml_set_element_language_details', array('element_id'=>$source->ID,'element_type'=>$type,'trid'=>false,'language_code'=>'es','source_language_code'=>null)); $details = apply_filters('wpml_element_language_details', null, array('element_id'=>$source->ID, 'element_type'=>$type)); } if (!$details || !$details->trid) wp_die('No se ha podido vincular el original mediante WPML.'); $content = $source->post_content; if (isset($r['segments'])) { $replace = array(); foreach ($r['segments'] as $s) $replace[$s['source']] = $s['translation']; $content = strtr($content, $replace); } else $content = $r['content']; $id = wp_insert_post(wp_slash(array('post_type'=>$source->post_type,'post_status'=>'draft','post_title'=>sanitize_text_field($r['title']),'post_name'=>sanitize_title($r['slug']),'post_content'=>wp_kses_post($content),'post_excerpt'=>sanitize_textarea_field($r['excerpt'] ?? ''),'menu_order'=>$source->menu_order)), true); if (is_wp_error($id)) wp_die(esc_html($id->get_error_message())); do_action('wpml_set_element_language_details', array('element_id'=>$id,'element_type'=>$type,'trid'=>$details->trid,'language_code'=>$r['language'],'source_language_code'=>'es')); foreach (array('_thumbnail_id','_agullo_seed_id','_agullo_guide','_agullo_record','_agullo_guide_record','_yoast_wpseo_meta-robots-noindex') as $key) { if (metadata_exists('post', $source->ID, $key)) update_post_meta($id, $key, get_post_meta($source->ID, $key, true)); } foreach (array('_agullo_record'=>array('finish','material','size','light','bulb','ip','imageCaption'), '_agullo_guide_record'=>array('quick','credit')) as $key=>$allowed) { $meta = get_post_meta($id, $key, true); if (is_array($meta) && !empty($r[$key]) && is_array($r[$key])) { foreach ($allowed as $field) if (isset($r[$key][$field]) && is_string($r[$key][$field])) $meta[$field] = sanitize_textarea_field($r[$key][$field]); update_post_meta($id, $key, $meta); } } foreach (array('seo_title'=>'_yoast_wpseo_title','seo_description'=>'_yoast_wpseo_metadesc') as $field=>$key) if (!empty($r[$field])) update_post_meta($id, $key, sanitize_text_field($r[$field])); foreach (get_object_taxonomies($source->post_type) as $taxonomy) { $terms = wp_get_object_terms($source->ID, $taxonomy, array('fields'=>'ids')); if (is_wp_error($terms)) continue; $mapped = array(); foreach ($terms as $term) $mapped[] = (int)apply_filters('wpml_object_id', $term, $taxonomy, true, $r['language']); wp_set_object_terms($id, $mapped, $taxonomy); } update_post_meta($id, '_agml_manual_source', $source->ID); $created[] = $source->ID . '→' . $id . ' (' . $r['language'] . ')'; } set_transient('agml_import_' . get_current_user_id(), 'Borradores creados: ' . implode(', ', $created), HOUR_IN_SECONDS); wp_safe_redirect(admin_url('tools.php?page=agullo-traducciones')); exit; }); Lucide: iluminación y catálogo de lámparas | Agulló
LUZ, DISEÑO Y ACOMPAÑAMIENTOVisítanos en Calpe
agullóELECTRICIDAD · ILUMINACIÓN
Hablemos

01 / CATÁLOGO DE ILUMINACIÓN

Iluminación Lucide

Piezas que acompañan. Luz que transforma. Explora el catálogo y consúltanos sobre los modelos, acabados y opciones para tu espacio.

Mostrando 1–24 de 32 piezas · Página 1 de 2Quitar filtros
Lucide NIGELLA · Café
LucideREF. 21450/40/96
NIGELLA

Café · GU10 · máx. 25 W

Lucide ROLLO · Terracota
LucideREF. 45591/01/55
ROLLO

Terracota · E27 · máx. 40 W

Lucide SIEMON · Azul
LucideREF. 45596/01/35
SIEMON

Azul · E14 · máx. 25 W

Lucide LESLEY · Negro
LucideREF. 03750/81/30
LESLEY

Negro · E27 · máx. 40 W

Lucide UNAR · Oro mate / latón
LucideREF. 79185/50/02
UNAR

Oro mate / latón · LED · 36 W · 2700 K

Lucide TRICIA · Negro / ópalo
LucideREF. 79187/01/30
TRICIA

Negro / ópalo · E27 · máx. 15 W

Lucide JANDERIN · Champán Color
LucideREF. 24405/34/05
JANDERIN

Champán Color · LED integrado · 2 x 16,5 W

Lucide MENGA · Ámbar / Negro
LucideREF. 25417/10/62
MENGA

Ámbar / Negro · LED integrado · 1 x 11 W

Lucide APPLAUSE · Hierro gris
LucideREF. 23400/80/15
APPLAUSE

Hierro gris · LED integrado · 1 x 50 W

Lucide SANTIAGO · Ámbar / Champán Color
LucideREF. 23401/12/62
SANTIAGO

Ámbar / Champán Color · LED integrado · 1 x 16 W

Lucide SIGMA · Negro
LucideREF. 23463/30/30
SIGMA

Negro · LED integrado · 1 x 30 W

Lucide RAFAL · Gris / Negro
LucideREF. 45592/01/36
RAFAL

Gris / Negro · E27 · 1 x 40 W

Lucide RAMZI · Marrón
LucideREF. 47506/81/43
RAMZI

Marrón · E14 · 1 x 40 W

Lucide TOMEO · Negro / Blanco
LucideREF. 47509/81/30
TOMEO

Negro / Blanco · E14 · 1 x 40 W

Lucide CELESTE · Blanco
LucideREF. 03745/24/31
CELESTE

Blanco · LED integrado · 1 x 21 W

Lucide GILLY · Negro
LucideREF. 36712/04/30
GILLY

Negro · LED integrado · 1 x 6 W

Lucide FOLD · Blanco
LucideREF. 21739/16/31
FOLD

Blanco · E27 · 3 x 40 W

Lucide ELLY · Ópalo / Negro
LucideREF. 07121/24/30
ELLY

Ópalo / Negro · LED integrado · 1 x 24 W

Lucide TYLER · Oro mate / Latón / Ahumado
LucideREF. 30164/01/02
TYLER

Oro mate / Latón / Ahumado · G9 · 1 x 33 W

Lucide SENTINO · Taupe / Oro mate / Latón
LucideREF. 10125/30/41
SENTINO

Taupe / Oro mate / Latón · G9 · 3 x 5 W

Lucide ARIANNE · Negro
LucideREF. 53102/24/30
ARIANNE

Negro · LED integrado · 1 x 23 W

Lucide JOLIJN · Oro mate / Latón
LucideREF. 77288/03/02
JOLIJN

Oro mate / Latón · LED integrado · 1 x 2 W

Lucide VINZ · Negro
LucideREF. 45299/02/30
VINZ

Negro · G9 · 2 x 28 W

Lucide MATIZ · Blanco / Ópalo
LucideREF. 77286/02/31
MATIZ

Blanco / Ópalo · LED integrado · 1 x 3,5 W

LA PIEZA ES SOLO EL PRINCIPIO

Elegir bien también es pensar la luz.

Te ayudamos con medidas, acabados, temperatura de color y ubicación.

Recibe asesoramiento
¿Te ayudamos?

TE AYUDAMOS A ELEGIR

Hablemos
de tu luz.

Cuéntanos qué necesitas. Te asesoramos sobre el modelo, los acabados y las opciones para tu espacio.

Tus datos se utilizarán para responder a esta consulta. Información sobre privacidad. Responsable: Electricidad Agulló. Finalidad: responder a tu consulta y facilitar información sobre los productos o servicios solicitados. Base jurídica: tu consentimiento. Puedes ejercer tus derechos en info@electricidadagullo.com. Consulta destinatarios, conservación y demás información en la política de privacidad.

Consultar por WhatsApp