Jump to content
Sign in to follow this  
Gose

Update dentro de um import PHP

Recommended Posts

Gose

Ola pessoal!
Bom, vou tentar ser breve. Ao fazer o import de um ficheiro txt, se houver um asterisco no campo 'modelo' então vai ter de fazer um update e colocar o que está depois desse asterisco, no campo etiq_col ou 'observacoes'.

Ex: 173150;FRED  *etiq. c/ bolso ;1;M;1;932;FRANCISCO JOSE SANTOS FARIA;CAMISA;(A);VIADUTTO
O 'FRED  *etiq. c/ bolso' é o campo modelo e o 'VIADUTTO' o campo etiq_col. o objectivo é ficar:
173150;FRED ;1;M;1;932;FRANCISCO JOSE SANTOS FARIA;CAMISA;(A); c/ bolso
Ou seja o que estava depois do asterisco desaparece e passa a ser a informação no campo etiq_col.
Se não tiver o asterisco então faz o add à bd normalmente.
Já tentei várias maneiras, mas não estou conseguindo resolver. alguém me poderia ajudar?
O ficheiro import.php:

if (isset($_FILES['arquivo'])) {
   $arquivo = $_FILES['arquivo'];
   // carrega o txt ignorando linhas vazias
   $file = file($arquivo['tmp_name'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
   // define os índices do .txt em ordem
   $indices = ['ref_reg', 'modelo', 'cor', 'tamanho', 'quant', 'num_cliente', 'cliente', 'tipo', 'tecido','etiq_col'];
   $size = sizeof($indices);
   // percorre as linhas do txt
   foreach ($file as $k => $v) {
      // remover tabs:
      $v = preg_replace('/\t/', '', $v);
      //tratar codificação de caracteres não utf-8
      $v = utf8_encode($v);
      // quebra a linha no ponto e vírgula e remove o 'enter' no final
      $v = explode(';', rtrim($v, '\n'));
      // comparar se a quantidade de dados é igual a quantidade de índices
      if (sizeof($v) == $size) {
         $ok[] = array_combine($indices, $v);
      } else {
         echo "<pre>Quantidade de dados inadequada na linha: $k<br>";
         print_r($file[$k]);
         echo '</pre>';
      }
   }
   // rotina para montar query para inserção:
   if (isset($ok)) {
      // preparar dados pra query sql
      foreach ($ok as $k => $v) {
         foreach ($v as $key => $value) {
            // se o valor for numérico não coloca aspas
            if (is_numeric($value) || is_bool($value)) {
               $d[$key] = $value;
            } else {
               // se for string, fica entre aspas e escapa os caracteres especiais
               $d[$key] = "'" . $sqli->real_escape_string($value) . "'";
            }
            // tratar o tamanho:
            if ($key == 'tamanho') {
               $d['t' . $value] = $v['quant'];
            }
         }
         // remove os índices tamanho e quant
         unset($d['tamanho'], $d['quant']);
         $inserts[] = $d;
         // reseta a variável $d
         $d = null;
      }
	
	  
	  //se tiver asterisco insere nos respectivos campos (.col / .etiq / .obs)
		
		foreach ($dados as $k => $v) {
	  
	 if(($dados[$k]['produto']== 'col.') || ($dados[$k]['produto'] == 'etiq.')){
		 $query1 = "UPDATE $table SET etiq_col = 'produto' WHERE cod_num = id";
		 $result1 = $sqli->query($query1);
		 $dados[$k]['id'] = "<a href='?registos/notafiscal/{$dados[$k]['id']}' title='Gerar Nota Produto'>{$dados[$k]['id']}</a>";
		 }
	 } 

	//	  
      foreach ($inserts as $v) {
         $keys = array_keys(array_change_key_case($v,  CASE_LOWER));
         $query = "INSERT INTO $table(" . implode(', ', $keys) . ") VALUES\n   (" . implode(',', $v) . ");";
         // executa a query de inserção:
         $sqli->query($query);
         // verificar se houve falha:
         if($sqli->error){
            die('<p class="error">Falha na inserção!<br>'.$sqli->error.'</p>'.$query);
         }
      }
   }
}

 

Share this post


Link to post
Share on other sites
HappyHippyHippo

poderia estar aqui a apresentar um código mais bonito e eficiente, no entanto, acho que bastaria que conseguisses responder a esta simples questão :

onde está declarada a variável $dados ?


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Gose

Ola HappyHippyHippo.
Obrigado pela atenção.
 

Realmente não postei a parte onde a variável está declarada, porque está num outro ficheiro que é de visualização dos registos. A minha intenção é passar para o ficheiro do import, por isso esqueci-me de postar, mas aqui vai.
 

if (isset($params[0])) {
   $id = intval($params[0]);
   $query = 'select *, ';
   foreach ($tamanhos as $v) {
      $sizes[] = "sum(t$v) as t$v";
   }
   
   $query.= implode(', ', $sizes);
   $query.=" from $table where cod_num = $id";
   $query .= ' group by cor ';
   $result = $sqli->query($query);
   if ($sqli->error) {
      echo '<p class="error">Falha ao executar query de busca<br>' . $sqli->error . '</p>';
   } elseif ($result->num_rows) {
      // pega todos os dados do banco
      $dados = $result->fetch_all(MYSQLI_ASSOC);
      // rotina para remover tamanhos vazios
      foreach ($tamanhos as $t) {
         $col = 't' . $t;
         $coluna = array_column($dados, $col);
         if (array_sum($coluna) > 0) {
            
         } else {
            $remove[$col] = 1;
         }

 

Share this post


Link to post
Share on other sites
HappyHippyHippo

o que apresentas está um bocado complicado de perceber, mas desconfio que o que pretendes seja algo deste género

function clearData($data) {
    if (!is_array($data))
        return utf8_encode(str_replace(array('\t'), array(''), trim($data)));

    foreach ($data as $key => $value)
        $data[$key] = clearData($value);
    return $data;
}

if (isset($_FILES['arquivo']) && $_FILES['arquivo']['error'] == 0) {
    $indices = ['ref_reg', 'modelo', 'cor', 'tamanho', 'quant', 'num_cliente', 'cliente', 'tipo', 'tecido','etiq_col'];

    $fd = fopen($_FILES['arquivo'], 'r');

    $idx = -1;
    $records = [];
    while ($csv = fgetcsv($fd)) {
        $idx++;
        clearData($csv);

        // validate
        if (count($csv) != count($indices)) {
            echo "<pre>Quantidade de dados inadequada na linha: $idx<br></pre>";
            continue;
        }

        // record processing
        $csv['t'. $csv[$indices['tamanho']]] = $csv[$indices['quant']];
        if (($pos = strpos($csv[$indices['modelo']], '*')) !== NULL) {
            $csv[$indices['etiq_col']] = substr($csv[$indices['modelo']], $pos);
            $csv[$indices['modelo']] = substr($csv[$indices['modelo']], 0, $pos);
        }

        $records[] = $csv;
    }

    fclose($fd)

    // prepared statement
    $stmt = $sqli->prepare('insert into `$table` (`' . implode('`,`', $indices) . '`)
                                          values (' . implode(', ', array_fill(0, count($indices), '?')) . ')';

    // records insert SQL command execution
    foreach ($records as $idx => $record) {
        $stmt->bind_param(implode('', array_fill(0, count($indices), 's')),
                          $records[$idx]);
        $stmt->execute();
    }
}

 

Edited by HappyHippyHippo
on the fly code correction

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Gose

Olá HappyHippyHippo!

Antes de mais obrigado pela ajuda. Estive ausente e como tal não me foi possivel responder antes.
Tentei implementar pelo código que deste, mas neste caso não é possivel, uma vez que tenho de fazer tratamento de tamanhos em relação com as quantidades fornecidas. Como tal tentei implementar algum do teu código no meu. Sem sucesso para ja =/
Não é possivel fazer?

 foreach ($inserts as $v) {
		  
		   if (($pos = strpos($v['modelo'], '*')) !== NULL) {
            $v['etiq_col'] = substr($v['modelo'], $pos);
            $v['modelo'] = substr($v['modelo'], 0, $pos);
			
		  
         $keys = array_keys(array_change_key_case($v,  CASE_LOWER));
         $query = "INSERT INTO $table(" . implode(', ', $keys) . ") VALUES\n   (" . implode(',', $v) . ");";
         // executa a query de inserção:
         $sqli->query($query);
         // verificar se houve falha:
         if($sqli->error){
            die('<p class="error">Falha na inserção!<br>'.$sqli->error.'</p>'.$query);
         }
		
	  }
   }


Assim implementaria no codigo que ja tinha ( que funcionava o import do txt ), sem ter de alterar muito.
Tentei isto, mas não faz a troca de informação.
Podes ajudar?

Abraço

Share this post


Link to post
Share on other sites
HappyHippyHippo

o código que apresentei faz esse dito tratamento (ou pelo menos o tratamento que consegui perceber no primeiro tópico)


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Gose

Pois, testando o codigo que me deste está a dar uma sequência de erros:

. Warning: fopen() expects parameter 1 to be a valid path, array given in C:\wamp\www\admin_upd\admin\Views\Registos\Import.php on line 15

. Warning: fgetcsv() expects parameter 1 to be resource, boolean given in C:\wamp\www\admin_upd\admin\Views\Registos\Import.php on line 19

. fclose() expects parameter 1 to be resource, boolean given in C:\wamp\www\admin_upd\admin\Views\Registos\Import.php on line 38

. Array to string conversion in C:\wamp\www\admin_upd\admin\Views\Registos\Import.php on line 41 ( $stmt = $sqli->prepare("insert into $table (' . implode(' , ', $indices) . ') values (' . implode(', ', array_fill(0, count($indices), '?')) . '"); )

Share this post


Link to post
Share on other sites
HappyHippyHippo

e naõ consegues ver que falta algo ao primeiro argumento fa funçao fopen ?

e não consegues ver que todos os outros erros é devido ao primeiro ?

e não consegues ver que o código foi feito de cabeça, logo não teve qualquer tipo de teste/validação ?


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.