#!/usr/bin/perl

# --------------------------------------------------------------
# Prontus CMS
# http://www.prontus.cl
# by Altavoz.net
#
# licensed under LGPL license.
# http://www.prontus.cl/license.html
# --------------------------------------------------------------

package lib_artic;
use utf8;
use strict;
use warnings;
no warnings 'uninitialized';

use JSON;
use DBI;

use lib_prontus;
use lib_waitlock;
use glib_fildir_03;
use lib_tax;
use lib_helper;

# debe setearse antes de usar la funcion maestra save_artic_with_object()
our $ARTIC_OBJ = undef;

# ---------------------------------------------------------------
# Esta funcion asume que ya esta cargado el cfg de prontus
# Realiza todo lo necesario para crear o updatear un articulo.
# Incluye semaforo.
# To-Do: Incluir hash de conf para indicar si tal operacion se realiza o no.
sub save_artic_with_object {
    my $is_new = $_[0]; # 1 | 0

    # Conectar a BD
    my ($base, $msg_err_bd) = &lib_prontus::conectar_prontus_bd();
    if (! ref($base)) {
        return $msg_err_bd;
    }

    # se asegura el xml mientras se guarda
    my $lock = "$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_LOCKS'}/$ARTIC_OBJ->{ts}.mutex";
    my $fh = &lib_waitlock::lock_file($lock);

    my $pag_articulo;
    my $autoinc = 0;
    my $post_proceso_lista;

    my %tabla_secc = &lib_tax::carga_hash_seccion($base);
    my %tabla_temas = &lib_tax::carga_hash_temas($base);
    my %tabla_subtemas = &lib_tax::carga_hash_subtemas($base);

    # se completan los nombres de la taxonomía
    for (my $i = 1; $i < 4; $i++) {
        if ($ARTIC_OBJ->{campos}{'_seccion' . $i} ne '') {
            $ARTIC_OBJ->{campos}{'_nom_seccion' . $i} = $tabla_secc{$ARTIC_OBJ->{campos}{'_seccion' . $i}}{'nombre'};
            if ($ARTIC_OBJ->{campos}{'_tema' . $i} ne '') {
                $ARTIC_OBJ->{campos}{'_nom_tema' . $i} = $tabla_temas{$ARTIC_OBJ->{campos}{'_tema' . $i}}{'nombre'};
                if ($ARTIC_OBJ->{campos}{'_subtema' . $i} ne '') {
                    $ARTIC_OBJ->{campos}{'_nom_subtema' . $i} = $tabla_subtemas{$ARTIC_OBJ->{campos}{'_subtema' . $i}}{'nombre'};
                }
            }
        }
    }

    # regenera los <tag>.txt para los tags q tenía el artículo antes de ser modificado
    my %campos_xml_old;
    my $tags_old;
    if (!$is_new) {
        %campos_xml_old = $ARTIC_OBJ->get_xml_content();
        $tags_old = $campos_xml_old{'_tags'};
    }

    # Generar y guardar xml. Se guardan los recursos subidos a traves del fid
    # Esto es comun para nuevo y actualizar
    if (!$ARTIC_OBJ->generar_xml_artic()) {
        &lib_waitlock::unlock_file($lock, $fh);
        return $Artic::ERR;
    }

    # Loguear modificacion
    my $label_action = 'Actualizar';
    $label_action = 'Ingresar' if ($is_new);

    # chequeamos cambio de alta para log.
    my $cambio_estado = '';
    my $estado_articulo = $ARTIC_OBJ->{campos}->{'_alta'} ? 'SI' : 'NO';
    if (!$is_new) {
        my $estado_previo = $campos_xml_old{'_alta'} ? 'SI' : 'NO';
        if ($estado_articulo ne $estado_previo) {
            $cambio_estado = " (Cambia Alta: $estado_previo -> $estado_articulo)";
        }
    } else {
        $cambio_estado = " (Alta: $estado_articulo)";
    }

    # Guardar articulo en base de datos
    my $msg_err_save = &do_save($base, $is_new);
    if ($msg_err_save) {
        if ($ARTIC_OBJ->{saved}) {
            &lib_prontus::write_log($label_action, 'Articulo'. $cambio_estado, 'ID: '.$ARTIC_OBJ->{ts}. ', '.$Artic::ERR);
        }
        &lib_waitlock::unlock_file($lock, $fh);
        return $msg_err_save;
    }

    # se actualiza metadata antes de parsear las vistas si aplica
    foreach my $key (keys %{$ARTIC_OBJ->{'xml_content'}}) {
        # hay un campo video en el artículo y no es multimedia_video1.width o similar
        if (lc(substr($key, 0, 16)) eq 'multimedia_video' && index($key, '.') < 0 && $ARTIC_OBJ->{xml_content}->{$key} ne '') {
            my $video = $key;
            my %data;
            my $update = 0;
            # el campos es foto de video, comparamos si es igual a la antigua, si es diferente hay que actualizar el json para el parseo posterior
            if ($campos_xml_old{"fotofija_$video"} ne $ARTIC_OBJ->{xml_content}->{"fotofija_$video"}) {
                my $path_foto = $ARTIC_OBJ->{campos}->{"fotofija_$video"};
                $path_foto =~ s/(foto_\d+)\_(.*)$/$1\/$2/si;
                $data{'poster'} = $path_foto;
                $data{'custom_imag'} = $path_foto;
                $update = 1;
                $ARTIC_OBJ->{xml_content}->{"$video.poster"} = $path_foto;
                $ARTIC_OBJ->{xml_content}->{"$video.custom_imag"} = $path_foto;
                $ARTIC_OBJ->{media_metadata}->{$video}->{"poster"} = $path_foto;
                $ARTIC_OBJ->{media_metadata}->{$video}->{"custom_imag"} = $path_foto;
            }

            if ($campos_xml_old{"chk_ad_disable_$video"} ne $ARTIC_OBJ->{xml_content}->{"chk_ad_disable_$video"}) {
                $data{"chk_ad_disable"} = defined($ARTIC_OBJ->{xml_content}->{"chk_ad_disable_$video"})?1:0;
                $update = 1;
                $ARTIC_OBJ->{xml_content}->{"$video.chk_ad_disable"} = $data{"chk_ad_disable"};
                $ARTIC_OBJ->{media_metadata}->{$video}->{"chk_ad_disable"} = $data{"chk_ad_disable"};
            }

            if (defined($ARTIC_OBJ->{xml_content}->{"ad_tag_$video"}) && $campos_xml_old{"ad_tag_$video"} ne $ARTIC_OBJ->{xml_content}->{"ad_tag_$video"}) {
                $data{"ad_tag"} = $ARTIC_OBJ->{xml_content}->{"ad_tag_$video"};
                $data{"ad_tag"} =~ s/^ +$//;
                $update = 1;
                $ARTIC_OBJ->{xml_content}->{"$video.ad_tag"} = $data{"ad_tag"};
                $ARTIC_OBJ->{media_metadata}->{$video}->{"ad_tag"} = $data{"ad_tag"};
            }

            if ($update) {
                my $fullpath_json = "$ARTIC_OBJ->{dst_multimedia}/$video$ARTIC_OBJ->{ts}.json";
                my $buffer_json = &glib_fildir_03::read_file_bin($fullpath_json);
                if ($buffer_json ne '' && $buffer_json =~ /^\{.*\}$/) {
                    my $hashref = decode_json($buffer_json);
                    foreach my $item (keys %data){
                        $hashref->{$item} = $data{$item};
                    }
                    my $json_str = encode_json($hashref);
                    utf8::decode($json_str);
                    &glib_fildir_03::write_file($fullpath_json, $json_str);
                }
            }
        }
    }

    $lib_prontus::ARTICS{$prontus_varglb::PRONTUS_ID}{$ARTIC_OBJ->{ts}} = $ARTIC_OBJ;

    # actualiza las vistas de los artículos
    &update_views($ARTIC_OBJ->{campos}->{'_fid'});

    &lib_prontus::write_log($label_action, 'Articulo'. $cambio_estado, 'ID: '.$ARTIC_OBJ->{ts});

    # Full path del artic (de la vista default)
    my $fullpath_artic = $ARTIC_OBJ->get_fullpath_artic('', $ARTIC_OBJ->{campos}->{'_plt'});

    # Lee de vuelta del XML
    my %campos_xml = $ARTIC_OBJ->get_xml_content();

    # Regen ports que correspondan, articulo nuevo no esta publicado en ninguna portada aún
    &regen_ports($fullpath_artic) if (!$is_new);

    # print STDERR "dir_cont[$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_SITE'}]\n";
    lib_tax::set_vars($prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_SITE'}, $prontus_varglb::DIR_ARTIC, $prontus_varglb::DIR_PAG, $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_TEMPLATES'}, $prontus_varglb::DIR_TAXONOMIA, $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'NUM_RELAC_DEFAULT'});

    # Se agregan los relacionados manuales antiguos para tambien regenerarlos.
    my $tax = $campos_xml{'_tax'};
    $tax .= "," . $campos_xml_old{'_tax'} if ($campos_xml_old{'_tax'});

    # Genera taxonomia manual.
    if ($tax ne '') {
        lib_tax::generar_relacionados_manualtax($tax, $ARTIC_OBJ->{dst_pags}, $ARTIC_OBJ->{ts}, $base, '');

        # Ahora parsea art relacionados para MVs
        foreach my $mv (keys %{$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'MULTIVISTAS'}}) {
            lib_tax::generar_relacionados_manualtax($tax, $ARTIC_OBJ->{dst_pags}, $ARTIC_OBJ->{ts}, $base, $mv);
        }
    } else {
        # Si no hay manual borra el generado
        lib_tax::borrar_relacionados_manualtax($ARTIC_OBJ->{dst_pags}, $ARTIC_OBJ->{ts});
    }

    # Regen relacionados por tax
    if ($prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'TAXONOMIA_NIVELES'} =~ /^[1-3]$/) {
        my $nivel_tax = $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'TAXONOMIA_NIVELES'};
        for (my $i = 1; $i <= $nivel_tax; $i++) {
            my ($s, $t, $st) = ($campos_xml{"_seccion$i"}, $campos_xml{"_tema$i"}, $campos_xml{"_subtema$i"});
            my ($old_s, $old_t, $old_st) = ($campos_xml_old{"_seccion$i"}, $campos_xml_old{"_tema$i"}, $campos_xml_old{"_subtema$i"});

            &generar_relacionados_tax($base, $s, $t, $st);

            # Si el articulo tenía s/t/st hay que regenerar los relacionados para que no aparezca.
            if ($s ne $old_s || $t ne $old_t || $st ne $old_st) {
                &generar_relacionados_tax($base, $old_s, $old_t, $old_st);
            }
        }
    }


    #regenerar relacionados por tags
    my $tags = $campos_xml{'_tags'};
    &generar_relacionados_tags($tags, $ARTIC_OBJ->{ts}, $base, $ARTIC_OBJ->{dst_pags});

    $ARTIC_OBJ->exec_post_proceso_art($fullpath_artic, $is_new);

    &lib_waitlock::unlock_file($lock, $fh);

    # Borra cache de no publicados
    &glib_fildir_03::borra_dir("$prontus_varglb::DIR_SERVER$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_CPAN'}/data/cache");
    return '';
}

# ---------------------------------------------------------------
# gatilla la generación de relacionados por taxonomía
sub generar_relacionados_tax {
    my ($base, $s, $t, $st) = @_;

    if ($s) {
        lib_tax::generar_relacionados($s, $t, $st, $base, '');

        # Ahora parsea art relacionados para MVs
        foreach my $mv (keys %{$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'MULTIVISTAS'}}) {
            lib_tax::generar_relacionados($s, $t, $st, $base, $mv);
        }
    }

}

# gatilla la generación de relacionados por tags
sub generar_relacionados_tags {
    my ($tags, $ts, $base, $dst_pags) = @_;

    # print STDERR "dir_cont[$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_SITE'}]\n";
    &lib_tags::set_vars($prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_SITE'},$prontus_varglb::DIR_ARTIC,$prontus_varglb::DIR_PAG,$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_TEMPLATES'},$prontus_varglb::DIR_TAGS,$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'NUM_RELAC_DEFAULT'});

    if ($tags ne '') {
        &lib_tags::generar_relacionados_tags($tags, $dst_pags, $ts, $base, '');

        # Ahora parsea art relacionados para MVs
        foreach my $mv (keys %{$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'MULTIVISTAS'}}) {
            &lib_tags::generar_relacionados_tags($tags, $dst_pags, $ts, $base, $mv);
        }
    }
}

# ---------------------------------------------------------------
# Actualiza registro de bd en base a info que carga del xml
# gestiona demás acciones de guardado de archivo (crear vistas, eliminarlas si se quita el)
sub do_save {
    my $base = shift;
    my $is_new = shift; # 1 | 0

    # recarga datos del articulo desde el xml
    $ARTIC_OBJ->get_xml_content();

    my $autoinc = 0;
    if ($is_new) {
        # articulo nuevo
        $autoinc = $ARTIC_OBJ->art_insert_bd($base);
        unlink $ARTIC_OBJ->{fullpath_xml} if (!$autoinc);

        return $Artic::ERR if (!$autoinc);

        # Nuevo autoinc se agrega al XML del artic
        $ARTIC_OBJ->setear_autoinc($autoinc);
    } else {
        # articulo existe, hay que actualizar
        $autoinc = $ARTIC_OBJ->art_update_bd($base);
        # si autoinc es 0, el articulo no es nuevo pero no se encontro en db y no se pudo actualizar
        if (!$autoinc) {
            # si no viene el autoinc en la info de articulo no se puede hacer nada, retorna error
            if (!defined($ARTIC_OBJ->{xml_content}->{'_art_autoinc'}) or $ARTIC_OBJ->{xml_content}->{'_art_autoinc'} eq '') {
                return $Artic::ERR if (!$autoinc);
            }
            # se revisa si el autoinc esta asignado a otro artículo
            my $sql = "select ART_ID from ART where ART_AUTOINC = ?";
            my $art_ts = &lib_prontus::existe_registro($sql, $base, $ARTIC_OBJ->{xml_content}->{'_art_autoinc'});
            # si ts = 0, el autoinc no esta asignado a ningun articulo
            if ($art_ts == 0) {
                # se inserta como si fuera regeneracion, el xml ya se guardo previamente
                $autoinc = $ARTIC_OBJ->art_insert_bd($base, 1);

                return $Artic::ERR if (!$autoinc);
            } else {
                # el autoinc ya tiene un ts asignado por lo tanto se inserta
                # como si fuera art nuevo para obtener un nuevo autoinc
                $autoinc = $ARTIC_OBJ->art_insert_bd($base);
                return $Artic::ERR if (!$autoinc);

                # Nuevo autoinc se agrega al XML del artic
                $ARTIC_OBJ->setear_autoinc($autoinc);
            }
        }
    }

    # El artículo y los datos ingresados ya fueron guardados
    # pueden ocurrir errores posteriores, pero los datos originales ya están guardados
    $ARTIC_OBJ->{saved} = 1;

    $ARTIC_OBJ->tags2bd($base, $is_new) || return $Artic::ERR;

    # guardamos los campos de multitag en la db
    $ARTIC_OBJ->multitags2bd($base, $is_new) || return $Artic::ERR;

    # se guarda para publicar/despublicar solo si esta activado el control fecha
    # si el articulo tiene alta
    if ($prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'CONTROL_FECHA'} eq 'SI' && $ARTIC_OBJ->{xml_content}->{'_alta'}) {
        # guardamos datos de publicación futura
        $ARTIC_OBJ->guardar_pub_exp_artic($base, 'pub') || return $Artic::ERR;

        # guardamos datos de expiración futura si "Sólo despublicar de portadas" no está marcado
        if (!$ARTIC_OBJ->{xml_content}->{'_soloportadas'}) {
            $ARTIC_OBJ->guardar_pub_exp_artic($base, 'exp') || return $Artic::ERR;
        }
    }

    # guardamos el titular friendly v4 en la base de datos
    $ARTIC_OBJ->genera_friendly_v4($base) || return $Artic::ERR;

    $ARTIC_OBJ->genera_friendly_v5($base) || return $Artic::ERR;
    return '';
}

# Actualiza las vistas del artículo (vista default, multivistas, paralelas)
# @param void
# @return false
sub update_views {
    # Solo se generan los archivos si el articulo tiene alta.
    my $fid = $_[0];

    # Generar/borrar vista principal (a partir del xml)
    $ARTIC_OBJ->generar_vista_art('') || return $Artic::ERR;

    # Generar/borrar vistas secundarias (a partir del xml)
    foreach my $mv (keys %{$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'MULTIVISTAS'}}) {
        $ARTIC_OBJ->generar_vista_art($mv) || return $Artic::ERR;
    }

    if ($ARTIC_OBJ->{'xml_content'}{'_alta'} ne '1') {
        # si no tiene alta llamamos de a los postprocesos.
        my $fullpath_plt       = "$ARTIC_OBJ->{pathdir_plt_pags}/$ARTIC_OBJ->{campos}->{'_plt'}";
        my $pathdir_plt_macros = $ARTIC_OBJ->{pathdir_plt_macros};
        # invocamos a los postprocesos del artículo.
        $ARTIC_OBJ->generar_vista_art('', undef, 0, 1) || return $Artic::ERR;
    }
    return '';
}

# ---------------------------------------------------------------
# Sea nuevo o modificar, y si hay control de alta, se reconstruyen las portadas de la
# edicion base, vigente y ultima que tengan ese articulo publicado.
# Las portadas que no tengan el articulo publicado no se tocan.
# @param string $artic el timestamp del artículo.
# @return void
sub regen_ports {
    my $artic = shift;

    if ($prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'ARTIC_ACTUALIZA_PORTS'} eq 'SI') {
        # cargamos la ruta de nice
        my $pathnice = &lib_prontus::get_path_nice();
        $pathnice = "$pathnice -n19 " if ($pathnice);
        $artic =~ s/[#;&<>|~]+//g;
        my $cmd = "$pathnice $prontus_varglb::DIR_SERVER/$prontus_varglb::DIR_CGI_CPAN/prontus_port_update_by_art.pl $artic >/dev/null 2>&1 &";
        print STDERR "[" . &glib_hrfec_03::get_dtime_pack4() . "]$cmd\n";
        system $cmd;
    }
}

# ---------------------------------------------------------------
# funcion para publicacion directa de 1 artic en alguna port.
# @param string $full_path_port path a la portada
# @param string $edic id de la edición
# @param string $nom_port nombre de la portada
# @param string $prontus_id
# @param string $ts_new_artic
# @param string $fid_artic
# @param int $area el área donde publicar
# @param int $orden la posición que debe tener.
# @return void
sub publica_art_in_port {
    my ($full_path_port, $edic, $nom_port, $prontus_id, $ts_new_artic, $fid_artic, $area, $orden, $vb) = @_;
    #  print STDERR "full_path_port[$full_path_port]\n";
    #  print STDERR "nom_port[$nom_port]\n";
    #  print STDERR "prontus_id[$prontus_id]\n";
    #  print STDERR "nom_artic[$nom_artic]\n";
    #  print STDERR "area[$area]\n";

    my ($pathdir_pags, $pathdir_seccs, @entries, $entry, $text_seccion,  $id);
    %lib_prontus::AREA = ();
    %lib_prontus::PRIO = ();
    %lib_prontus::DIR_FECHA = ();
    %lib_prontus::VB = ();

    my $full_path_xmlport = $full_path_port;
    $full_path_xmlport =~ s/\/port\/(\w+)(\.\w+)?$/\/xml\/$1\.xml/;

    # Rescatar la info de c/artic de la portada
    # print STDERR "full_path_xmlport[$full_path_xmlport]\n";
    my %rowartics = &lib_prontus::get_rowartics($full_path_xmlport);
    my $port_pub = &lib_prontus::get_port_pub($full_path_xmlport);
    my $no_write = 0;
    # Si la portada no esta publicada se activa el no_write.
    $no_write = 1 if ($port_pub eq '0');

    my $orden_art_new;
    my $is_first = 1;

    # art publicados en la portada, ordenados por area/orden
    foreach my $art (sort{$rowartics{$a}{'area'} <=> $rowartics{$b}{'area'} || $rowartics{$a}{'ord'} <=> $rowartics{$b}{'ord'}}(keys %rowartics)) {
        # art es de la forma <ts>
        $lib_prontus::AREA{$prontus_id}{$nom_port}{$art} = $rowartics{$art}{'area'};
        $lib_prontus::PRIO{$prontus_id}{$nom_port}{$art} = $rowartics{$art}{'ord'};
        $lib_prontus::DIR_FECHA{$prontus_id}{$nom_port}{$art} = $rowartics{$art}{'dir'};
        $lib_prontus::VB{$prontus_id}{$nom_port}{$art} = $rowartics{$art}{'vb'};

        # Rescata FIDs de cada articulo, a fin de poder publicar el nuevo artic encima del primero de su tipo.
        my $artic_obj = Artic->new(
                        'prontus_id'         => $prontus_id,
                        'public_server_name' => $prontus_varglb::CONFIG{$prontus_id}{'PUBLIC_SERVER_NAME'},
                        'cpan_server_name'   => $prontus_varglb::CONFIG{$prontus_id}{'CPAN_SERVER_NAME'},
                        'document_root'      => $prontus_varglb::DIR_SERVER,
                        'ts'                 => $art,
                        'no_check_dirs'      => 1)
                    || die "Error inicializando objeto articulo: $Artic::ERR\n";
        my %campos_xml = $artic_obj->get_xml_content();

        if (($campos_xml{'_fid'} eq $fid_artic) && ($is_first)) {
            $orden_art_new = $rowartics{$art}{'ord'} - 1;
            $is_first = 0;
        }
    }

    $orden_art_new = 1 if ($orden_art_new < 1);  # en caso de que no se haya detectado ninguno de este tipo

    # Agrega art. a publicar
    $lib_prontus::DIR_FECHA{$prontus_id}{$nom_port}{$ts_new_artic} = &glib_hrfec_03::get_date_pack4();
    # Asocia area al articulo.
    $lib_prontus::AREA{$prontus_id}{$nom_port}{$ts_new_artic} = $area;

    # si pasaron un orden específico, por ej. desde prontus_art_posting.cgi, lo uso. Si no, uso $orden_art_new.
    my $orden_def;
    if ($orden) {
        $orden_def = $orden;
    } else {
        $orden_def = $orden_art_new;
    }

    # Asocia prioridad correspondiente. nos aseguramos que sea un número para futuras comparaciones.
    $lib_prontus::PRIO{$prontus_id}{$nom_port}{$ts_new_artic} = $orden_def + 0;

    # reordenamos los demás items de esa área.
    foreach my $ts_order (keys %lib_prontus::PRIO) {
        if (($lib_prontus::AREA{$prontus_id}{$nom_port}{$ts_order} == $area) &&
            ($lib_prontus::PRIO{$prontus_id}{$nom_port}{$ts_order} >= $orden_def) &&
            ($ts_order ne $ts_new_artic)) {
            $lib_prontus::PRIO{$prontus_id}{$nom_port}{$ts_order} += 1;
        }
    }

    $lib_prontus::VB{$prontus_id}{$nom_port}{$ts_new_artic} = $vb;

    # Regenera la portada correspondiente
    my $mv = '';
    my $sin_regen_xml = 0;
    my $ts_preview = '';
    &lib_prontus::make_portada($full_path_port, "$prontus_varglb::DIR_SERVER/$prontus_id/plantillas/edic/nroedic/port/$nom_port", $prontus_varglb::DIR_SERVER, $prontus_id,$mv, $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'PUBLIC_SERVER_NAME'}, $prontus_varglb::PRONTUS_KEY, $prontus_varglb::STAMP_DEMO,$edic, $sin_regen_xml, $prontus_varglb::STAMP_DEMO_RSS, $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'CONTROL_FECHA'}, $ts_preview, $no_write);


    # Ahora proceso multivistas
    $sin_regen_xml = 1;
    foreach my $mv (keys %{$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'MULTIVISTAS'}}) {
        &lib_prontus::make_portada($full_path_port, "$prontus_varglb::DIR_SERVER/$prontus_id/plantillas/edic/nroedic/port/$nom_port", $prontus_varglb::DIR_SERVER, $prontus_id,$mv, $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'PUBLIC_SERVER_NAME'}, $prontus_varglb::PRONTUS_KEY, $prontus_varglb::STAMP_DEMO,'base', $sin_regen_xml, $prontus_varglb::STAMP_DEMO_RSS, $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'CONTROL_FECHA'}, $ts_preview, $no_write);
    }
}

# ---------------------------------------------------------------
sub get_articulos_pub_exp {
    # busca artículos en las tablas ART_PUBLICAR o ART_DESPUBLICAR, devuelve los registros con fecha de publicación o expiración menores o iguales a la fecha-hora actual.
    # param string $comando (pub|exp);
    # return array @articulos
    my $base = shift;
    my $comando = shift;
    my @articulos;
    my $msg_err_bd;

    # Conectar a BD
    ($base, $msg_err_bd) = &lib_prontus::conectar_prontus_bd();

    if (!ref($base)) {
        print STDERR $msg_err_bd;
        return @articulos;
    }

    my ($tabla, $colfechahora) = ('', '');
    if ($comando eq 'pub') {
        $tabla = 'ART_PUBLICAR';
        $colfechahora = 'ART_FECHAPHORAP';
    } elsif ($comando eq 'exp') {
        $tabla = 'ART_DESPUBLICAR';
        $colfechahora = 'ART_FECHAEHORAE';
    }

    my $sql = "SELECT $tabla.ART_ID, $tabla.$colfechahora, ART.ART_EXTENSION, ART.ART_TIPOFICHA, ART.ART_SOLOPORTADAS, ART_ALTA".
        " FROM $tabla INNER JOIN ART ON $tabla.ART_ID = ART.ART_ID WHERE $tabla.$colfechahora <= ? ORDER BY $colfechahora ASC";
    my @params = (&glib_hrfec_03::get_dtime_pack4());
    # print "$sql\n".join(';', @params)."\n";

    my ($art_id, $art_fechahora, $art_extension, $art_tipoficha, $art_soloportadas, $art_alta);
    my $salida = &glib_dbi_03::ejecutar_sql_bind_param($base, $sql, \@params, \($art_id, $art_fechahora, $art_extension, $art_tipoficha, $art_soloportadas, $art_alta));

    while ($salida->fetch) {
        push(@articulos, {'art_id'=>$art_id, 'art_fechahora'=>$art_fechahora, 'art_extension'=>$art_extension, 'art_tipoficha'=>$art_tipoficha, 'art_soloportadas'=>$art_soloportadas, 'art_alta' => $art_alta, 'comando'=>$comando});
    }
    $salida->finish;
    return @articulos;
}
# ---------------------------------------------------------------
sub delete_articulos_pub_exp_db {
    # elimina registros en las tablas ART_PUBLICAR o ART_DESPUBLICAR
    # param string $comando (pub|exp)
    # param array ['art_id', 'art_id', 'art_id'...]
    my $base = shift;
    my $comando = shift;
    my @articulos = @_;
    my $tabla;

    if ($comando eq 'pub') {
        $tabla = 'ART_PUBLICAR';
    } elsif ($comando eq 'exp') {
        $tabla = 'ART_DESPUBLICAR';
    }

    if (scalar @articulos <1)  {
        return 1;
    }

    my $placeholders = ', ?' x scalar @articulos;
    $placeholders = substr $placeholders, 2;
    my $sql = "DELETE FROM $tabla WHERE ART_ID IN ($placeholders) ";
    &glib_dbi_03::ejecutar_sql_param($base, $sql, \@articulos);

    return '';
}
# ---------------------------------------------------------------
sub genera_obj_artic {
    my $ts = shift;
    return Artic->new(
        'prontus_id'         => $prontus_varglb::PRONTUS_ID,
        'public_server_name' => $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'PUBLIC_SERVER_NAME'},
        'cpan_server_name'   => $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'CPAN_SERVER_NAME'},
        'document_root'      => $prontus_varglb::DIR_SERVER,
        'ts'                 =>  $ts
    ) || die "Error inicializando objeto articulo: $Artic::ERR\n";
}
# ---------------------------------------------------------------
sub carga_art_xml {
    my $fullpath_xml = $_[0];

    my $buff_xml_data   = &lib_prontus::get_xml_data($fullpath_xml);
    my %campos_from_xml = &lib_prontus::getCamposXml($buff_xml_data);

    return \%campos_from_xml;
}
# ---------------------------------------------------------------
# agrega campos necesarios para poder ejecutar
sub completar_campos_artic_guardar {
    my ($ts, $campos_xml) = @_;

    # ajustes de campos apra conservar fotos y adjuntos
    foreach my $campo (keys %{$campos_xml}) {
        if ($campo =~ /^multimedia_\w+$/) {
            $campos_xml->{'_hidd_'.$campo} = $campos_xml->{$campo};
            $campos_xml->{$campo} = '';
        }
        elsif ($campo =~ /^asocfile_\w+$/) {
            $campos_xml->{'_hidd_'.$campo} = $campos_xml->{$campo};
            $campos_xml->{$campo} = '';
        }
        elsif ($campo =~ /^foto_\w+$/) {
            $campos_xml->{$campo} = '';
        }
        elsif ($campo =~ /^_nom(foto_\w+)$/) {
            my $foto = $1;
            $campos_xml->{'_hidd_'.$foto} = $campos_xml->{$campo};
            my $relpath_foto = "$prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'DIR_SITE'}$prontus_varglb::DIR_ARTIC/".substr($ts, 0, 8). "$prontus_varglb::DIR_IMAG/" . $campos_xml->{$campo};
            $campos_xml->{'_path_'.$foto} = $relpath_foto;
        }
        elsif ($campo =~ /^fotofija_\w+$/) {
            $campos_xml->{$campo} =~ /\/site\/[^\/]+\/[0-9]{8}\/imag\/foto_([0-9]+)\d{14}\_*[a-zA-Z0-9\_\-\.]*?\.(\w+)$/;
            my $id = $1;
            # asigna tamaños maximos usando el tamaño actual de la foto, para mantenerlas igual
            $campos_xml->{'_maxw' . $campo} = $campos_xml->{'_wfoto_' . $id};
            $campos_xml->{'_maxh' . $campo} = $campos_xml->{'_hfoto_' . $id};
        }
    }

    # indexar solo puede valer 1 o 0, si no existía en xml, entonces debe ser 1
    if (!defined($campos_xml->{'_indexar'})) {
        $campos_xml->{'_indexar'} = 1;
    }
}

1;
