Commit e56773f8b646c287826982af5ebbd6ac0de11582

Authored by Edmar Moretti
1 parent e963a227

Inclusão de opção de download de dados nas interfaces de mapas interativos do sistema METAESTAT

admin/admin.db
No preview for this file type
admin/html/estat_uploaddados.html
... ... @@ -48,24 +48,27 @@ body {
48 48 <div id="i3GEOadminUploaddadosVariaveis" style="left: -5px;"></div>
49 49 <div id="i3GEOadminUploaddadosMedidas" style="left: -5px;"></div>
50 50 <br>
51   - <form id=i3GEOupload target="i3GEOuploadiframe" action="../php/metaestat_uploaddados_submit.php" onsubmit="i3GEOadmin.uploaddados.upload.submit();"
52   - method="post" ENCTYPE="multipart/form-data">
53   - <p class="paragrafo">
54   - <input class=digitar type="file" size=42 name="i3GEOuploadArquivo"
55   - style="top: 0px; left: 0px; cursor: pointer;">
56   - </p>
57   - <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
58   - <input type="submit" value="Enviar" >
59   - </form>
60   - <br>
61   - <div id="i3GEOadminEditorColunas" style="left: -5px;"></div>
62   - <iframe id="i3GEOuploadiframe" name="i3GEOuploadiframe" src="#" style="width:0;height:0;border:0px solid #fff;"></iframe>
  51 + <fieldset>
  52 + <legend>Upload de valores (arquivo CSV)</legend>
  53 + <form id=i3GEOupload target="i3GEOuploadiframe" action="../php/metaestat_uploaddados_submit.php" onsubmit="i3GEOadmin.uploaddados.upload.submit();"
  54 + method="post" ENCTYPE="multipart/form-data">
  55 + <p class="paragrafo">
  56 + <input class=digitar type="file" size=42 name="i3GEOuploadArquivo"
  57 + style="top: 0px; left: 0px; cursor: pointer;">
  58 + </p>
  59 + <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
  60 + <input type="submit" value="Enviar" >
  61 + </form>
  62 + <br>
  63 + <div id="i3GEOadminEditorColunas" style="left: -5px;"></div>
  64 + <iframe id="i3GEOuploadiframe" name="i3GEOuploadiframe" src="#" style="width:0;height:0;border:0px solid #fff;"></iframe>
  65 + </fieldset>
63 66 </div>
64 67 </div>
65 68 <div id=logajax style="display: block"></div>
66 69 <script>
67 70 /*
68   - Title: Upload de dados do sistema de metadados estat&iacute;sticos
  71 + Upload de dados do sistema de metadados estat&iacute;sticos
69 72  
70 73 Licenca:
71 74  
... ...
admin/index.html
... ... @@ -186,9 +186,13 @@
186 186 <td><div class=aplicar></div></td>
187 187 <td>Cadastro de fontes de informa&ccedil;&atilde;o</td>
188 188 </tr>
  189 + <tr onclick="abre('estat_uploaddados.html')">
  190 + <td><div class=aplicar></div></td>
  191 + <td>Upload e download de dados</td>
  192 + </tr>
189 193 <tr onclick="abre('html/estat_editor.html')">
190 194 <td><div class=aplicar></div></td>
191   - <td>Editor de tabelas de dados estat&iacute;cos</td>
  195 + <td>Gerenciador de tabelas de dados estat&iacute;cos</td>
192 196 </tr>
193 197 </table>
194 198 </div>
... ...
admin/js/estat_uploaddados.js
... ... @@ -163,8 +163,8 @@ i3GEOadmin.uploaddados = {
163 163 i3GEO.php.listaVariavel(i3GEOadmin.uploaddados.variaveis.combo,"i3geo_metaestat");
164 164 },
165 165 combo: function(dados){
166   - $i(i3GEOadmin.uploaddados.variaveis.onde).innerHTML = "<p>Escolha a vari&aacute;vel que receberá os dados</p>" +
167   - i3GEOF.metaestat.principal.comboVariaveis(dados,"i3GEOadminEditorVariaveis_combo","i3GEOadmin.uploaddados.medidas.lista()");
  166 + $i(i3GEOadmin.uploaddados.variaveis.onde).innerHTML = "<p>Escolha a vari&aacute;vel</p>" +
  167 + i3GEOF.metaestat.principal.comboVariaveis(dados,"i3GEOadminEditorVariaveis_combo","i3GEOadmin.uploaddados.medidas.lista()","","nao");
168 168 }
169 169 },
170 170 medidas:{
... ...
admin/php/classe_metaestat.php
... ... @@ -238,6 +238,11 @@ class Metaestat{
238 238 function sqlMedidaVariavel($id_medida_variavel,$todasascolunas,$agruparpor="",$tipolayer="polygon",$codigo_tipo_regiao = ""){
239 239 $filtro = false;
240 240 $dados = $this->listaMedidaVariavel("",$id_medida_variavel);
  241 + $pp = $this->listaParametro($id_medida_variavel,"",0);
  242 + foreach($pp as $p){
  243 + $parametrosMedida[] = $p["coluna"];
  244 + }
  245 + //var_dump($parametrosMedida);exit;
241 246 $titulo = $dados["nomemedida"];
242 247 $dadosgeo = $this->listaTipoRegiao($dados["codigo_tipo_regiao"]);
243 248 //indica se os dados sao agregados a uma regiao de nivel superior
... ... @@ -354,7 +359,13 @@ class Metaestat{
354 359 else{
355 360 $sqlgeo .= " FROM (SELECT ".$dados["colunavalor"].",".$dados["colunaidgeo"].",".$dados["colunaidunico"]." FROM ".$dados["esquemadb"].".".$dados["tabela"] ." __dadosfiltro__ ) as d, ".$dadosgeo["esquemadb"].".".$dadosgeo["tabela"]." as g";
356 361 }
357   - $sql .= " FROM (SELECT ".$dados["colunavalor"].",".$dados["colunaidgeo"]." FROM ".$dados["esquemadb"].".".$dados["tabela"] ." __dadosfiltro__ ) as d ";
  362 + if(count($parametrosMedida) > 0){
  363 + $parametrosMedida = implode(",",$parametrosMedida).",";
  364 + }
  365 + else{
  366 + $parametrosMedida = "";
  367 + }
  368 + $sql .= " FROM (SELECT $parametrosMedida".$dados["colunavalor"].",".$dados["colunaidgeo"]." FROM ".$dados["esquemadb"].".".$dados["tabela"] ." __dadosfiltro__ ) as d ";
358 369 }
359 370 }
360 371 else{
... ... @@ -679,7 +690,6 @@ class Metaestat{
679 690 elseif(!empty($filtro)){
680 691 $sqlf .= " WHERE ".$filtro;
681 692 }
682   - //echo $sqlf;exit;
683 693 $metaVariavel = $this->listaMedidaVariavel("",$id_medida_variavel);
684 694 if(!empty($metaVariavel["codigo_estat_conexao"])){
685 695 $c = $this->listaConexao($metaVariavel["codigo_estat_conexao"],true);
... ... @@ -1414,7 +1424,7 @@ class Metaestat{
1414 1424 /*
1415 1425 Function: listaParametro
1416 1426  
1417   - Lista as variaveis cadastradas ou uma unica variavel
  1427 + Lista os parametros cadastradas ou uma unica variavel
1418 1428  
1419 1429 Parametros:
1420 1430  
... ... @@ -1422,7 +1432,7 @@ class Metaestat{
1422 1432  
1423 1433 $id_parametro_variavel - opcional
1424 1434 */
1425   - function listaParametro($id_medida_variavel,$id_parametro_medida=""){
  1435 + function listaParametro($id_medida_variavel,$id_parametro_medida="",$id_pai=""){
1426 1436 $sql = "SELECT i3geoestat_parametro_medida.*,i3geoestat_medida_variavel.* ";
1427 1437 $sql .= "FROM ".$this->esquemaadmin."i3geoestat_parametro_medida ";
1428 1438 $sql .= "INNER JOIN ".$this->esquemaadmin."i3geoestat_medida_variavel ";
... ... @@ -1436,6 +1446,9 @@ class Metaestat{
1436 1446 else{
1437 1447 $sql .= "WHERE i3geoestat_parametro_medida.id_parametro_medida = $id_parametro_medida ";
1438 1448 }
  1449 + if($id_pai != ""){
  1450 + $sql .= " AND id_pai = $id_pai";
  1451 + }
1439 1452 //echo $sql;exit;
1440 1453 return $this->execSQL($sql,$id_parametro_medida);
1441 1454 }
... ...
admin/php/metaestat.php
... ... @@ -1072,6 +1072,12 @@ switch (strtoupper($funcao))
1072 1072 header("Content-type: application/xml");
1073 1073 echo($m->formataXML($dados));
1074 1074 }
  1075 + if($formato == "csv"){
  1076 + require_once(__DIR__."/../../pacotes/parsecsv/parsecsv.lib.php");
  1077 + $csv = new parseCSV();
  1078 + $csv->titles = array_keys($dados[0]);
  1079 + $csv->output(true, 'mvar'.$id_medida_variavel.'_'.date('dmY').'.csv', $dados);
  1080 + }
1075 1081 exit;
1076 1082 break;
1077 1083 /*
... ...
css/botoes2.css
... ... @@ -203,6 +203,14 @@
203 203 height: 15px;
204 204 width: 15px;
205 205 }
  206 +.ticDownload
  207 +{
  208 + background-image: url("../imagens/visual/default/sprite.png");
  209 + background-position: 0 -1124px;
  210 + background-repeat: no-repeat;
  211 + height: 15px;
  212 + width: 15px;
  213 +}
206 214 .carregarKml
207 215 {
208 216 background-image:URL('../imagens/visual/default/sprite2.png');
... ...
css/i3geo47.css
... ... @@ -478,6 +478,14 @@ background-position: -5px -603px;
478 478 height: 15px;
479 479 width: 15px;
480 480 }
  481 +.ticDownload
  482 +{
  483 +background-image: url("../imagens/visual/default/sprite.png");
  484 +background-position: 0 -1124px;
  485 +background-repeat: no-repeat;
  486 +height: 15px;
  487 +width: 15px;
  488 +}
481 489 .carregarKml
482 490 {
483 491 background-image:URL('../imagens/visual/default/sprite2.png');
... ...
css/i3geo47.css.php
... ... @@ -478,6 +478,14 @@ background-position: -5px -603px;
478 478 height: 15px;
479 479 width: 15px;
480 480 }
  481 +.ticDownload
  482 +{
  483 +background-image: url("../imagens/visual/default/sprite.png");
  484 +background-position: 0 -1124px;
  485 +background-repeat: no-repeat;
  486 +height: 15px;
  487 +width: 15px;
  488 +}
481 489 .carregarKml
482 490 {
483 491 background-image:URL('../imagens/visual/default/sprite2.png');
... ...
ferramentas/metaestat/editorlimites.js
... ... @@ -240,7 +240,8 @@ i3GEOF.editorlimites = {
240 240 lista.push(coordenadas);
241 241 }
242 242 }
243   - return {"tipo":tipo,"coordenadas":lista};
  243 + p = {"tipo":tipo,"coordenadas":lista};
  244 + return p;
244 245 },
245 246 toWKT: function(obj){
246 247 var wkt = new Wkt.Wkt();
... ...
ferramentas/metaestat/index.js
... ... @@ -1338,7 +1338,7 @@ i3GEOF.metaestat = {
1338 1338 }
1339 1339 var temp = function(dados){
1340 1340 var ins = "<p class='paragrafo' >" + $trad(1,i3GEOF.metaestat.dicionario) + "<br><br>" +
1341   - "<span>" + i3GEOF.metaestat.principal.comboVariaveis(dados,"i3geoCartoComboVariavelEditor","i3GEOF.metaestat.editor.comboVariaveisOnchange(this)","nao") + "</span>" +
  1341 + "<span>" + i3GEOF.metaestat.principal.comboVariaveis(dados,"i3geoCartoComboVariavelEditor","i3GEOF.metaestat.editor.comboVariaveisOnchange(this)","","nao") + "</span>" +
1342 1342 "<br><br><p><input id=i3GEOFmetaestatEditorBotao3 type='button' value='"+$trad(8,i3GEOF.metaestat.dicionario1)+"' />" +
1343 1343 "&nbsp;<input id=i3GEOFmetaestatEditorBotao3a type='button' value='"+$trad(5,i3GEOF.metaestat.dicionario1)+"' /><br>";
1344 1344 i3GEO.util.proximoAnterior("i3GEOF.metaestat.editor.t0()","i3GEOF.metaestat.editor.t2()",ins,"i3GEOF.metaestat.editor.t1","i3GEOFmetaestatEditor",true);
... ... @@ -1738,12 +1738,15 @@ i3GEOF.metaestat = {
1738 1738 i3GEO.php.relatorioVariavel(v.value,temp);
1739 1739 }
1740 1740 },
1741   - comboVariaveis: function(dados,idcombo,stronchange,mostraIconeinfo){
  1741 + comboVariaveis: function(dados,idcombo,stronchange,largura,mostraIconeinfo){
1742 1742 var ins,i,n = dados.length;
1743   - if(!mostraIconeinfo){
  1743 + if(!largura || largura === ""){
  1744 + largura = i3GEOF.metaestat.LARGURA - 40;
  1745 + }
  1746 + if(!mostraIconeinfo || mostraIconeinfo === ""){
1744 1747 mostraIconeinfo = "sim";
1745 1748 }
1746   - ins = "<select id='"+idcombo+"' style='box-shadow:0 1px 5px gray;width:"+(i3GEOF.metaestat.LARGURA - 40)+"px' onchange='"+stronchange+"'><option value=''>---</option>";
  1749 + ins = "<select id='"+idcombo+"' style='box-shadow:0 1px 5px gray;width:"+largura+"px' onchange='"+stronchange+"'><option value=''>---</option>";
1747 1750 for(i=0;i<n;i++){
1748 1751 ins += "<option title='"+dados[i].descricao+"' value='"+dados[i].codigo_variavel+"'>"+dados[i].nome+"</option>";
1749 1752 }
... ... @@ -1823,15 +1826,27 @@ i3GEOF.metaestat = {
1823 1826 $i("i3geoCartoParametrosMedidasVariavel").innerHTML = "";
1824 1827 i3GEOF.metaestat.classes.zeraParametros();
1825 1828 },
1826   - comboMedidasVariavel: function(dados,idcombo,stronchange,filtroesquema,mostraIconeprop){
  1829 + comboMedidasVariavel: function(dados,idcombo,stronchange,filtroesquema,largura,mostraIconeprop,mostraIconedown){
1827 1830 i3GEOF.metaestat.DADOSMEDIDASVARIAVEL = dados;
1828 1831 var n = dados.length,
1829 1832 ins = '',
1830 1833 i;
1831   - if(!mostraIconeprop){
  1834 + if(!largura || largura === ""){
  1835 + largura = i3GEOF.metaestat.LARGURA - 20;
  1836 + }
  1837 + if(!mostraIconeprop || mostraIconeprop === ""){
1832 1838 mostraIconeprop = "sim";
1833 1839 }
1834   - ins += "<select id='"+idcombo+"' style='width:"+(i3GEOF.metaestat.LARGURA - 40)+"px' onchange='"+stronchange+"'><option value=''>---</option>";
  1840 + if(!mostraIconedown || mostraIconedown === ""){
  1841 + mostraIconedown = "sim";
  1842 + }
  1843 + if(mostraIconeprop == "sim"){
  1844 + largura = largura - 19;
  1845 + }
  1846 + if(mostraIconedown == "sim"){
  1847 + largura = largura - 19;
  1848 + }
  1849 + ins += "<select id='"+idcombo+"' style='box-shadow:0 1px 5px gray;width:"+largura+"px' onchange='"+stronchange+"'><option value=''>---</option>";
1835 1850 for(i=0;i<n;i++){
1836 1851 if(!filtroesquema || (filtroesquema != "" && dados[i].esquemadb != filtroesquema)){
1837 1852 ins += "<option value='"+dados[i].id_medida_variavel+"'>"+dados[i].nomemedida+"</option>";
... ... @@ -1841,6 +1856,9 @@ i3GEOF.metaestat = {
1841 1856 if(mostraIconeprop == "sim"){
1842 1857 ins += "<img class='ticPropriedades2' src='"+i3GEO.configura.locaplic+"/imagens/visual/default/branco.gif' style='height:14px;position:relative;cursor:pointer;left:5px;top:4px;' onclick='i3GEOF.metaestat.classes.inicia()' title='"+$trad(18,i3GEOF.metaestat.dicionario)+"'/>";
1843 1858 }
  1859 + if(mostraIconedown == "sim"){
  1860 + ins += "<img class='ticDownload' src='"+i3GEO.configura.locaplic+"/imagens/visual/default/branco.gif' style='position:relative;cursor:pointer;left:8px;top:5px;' onclick='i3GEOF.metaestat.principal.downloadMedida()' title='"+$trad("a3")+"'/>";
  1861 + }
1844 1862 return ins;
1845 1863 },
1846 1864 opcoesMedidasVariavel: function(codigo_variavel){
... ... @@ -1878,6 +1896,17 @@ i3GEOF.metaestat = {
1878 1896 },
1879 1897 comboClassificacoesMedidaVariavelOnchange: function(combo){
1880 1898  
  1899 + },
  1900 + downloadMedida: function(){
  1901 + if(!$i("i3geoCartoComboMedidasVariavel")){
  1902 + i3GEO.janela.tempoMsg("erro: i3geoCartoComboMedidasVariavel???");
  1903 + return;
  1904 + }
  1905 + if(window.confirm("Confirma o download dos dados")){
  1906 + var p = i3GEO.configura.locaplic+"/admin/php/metaestat.php?funcao=dadosMedidaVariavel" +
  1907 + "&todasascolunas=1&formato=csv&id_medida_variavel="+$i("i3geoCartoComboMedidasVariavel").value;
  1908 + window.open(p);
  1909 + }
1881 1910 }
1882 1911 },
1883 1912 //funcoes utilizadas quando o mapa esta cadastrado e e utilizado um template para publicar o mapa
... ... @@ -1905,13 +1934,14 @@ i3GEOF.metaestat = {
1905 1934 ins = '',
1906 1935 i;
1907 1936  
1908   - ins = "<select style='width:"+(i3GEOF.metaestat.LARGURA - 40)+"px' onchange='i3GEOF.metaestat.publicador.comboMedidaVariavelOnchange(this)'><option value=''>---</option>";
  1937 + ins = "<select style='width:"+(i3GEOF.metaestat.LARGURA - 60)+"px' onchange='i3GEOF.metaestat.publicador.comboMedidaVariavelOnchange(this)'><option value=''>---</option>";
1909 1938 for(i=0;i<n;i++){
1910 1939 ins += "<option value='"+dados[i].id_mapa_tema+"'>"+dados[i].titulo+"</option>";
1911 1940 }
1912 1941 ins += "</select>";
1913 1942 ins += "<img class='ticPropriedades2' src='"+i3GEO.configura.locaplic+"/imagens/visual/default/branco.gif' style='height:14px;position:relative;cursor:pointer;left:5px;top:4px;' onclick='i3GEOF.metaestat.classes.inicia()' title='"+$trad(18,i3GEOF.metaestat.dicionario)+"'/>";
1914   - //ins += "<img src='"+i3GEO.configura.locaplic+"/imagens/ic_identifica.png' style='position:relative;cursor:pointer;left:5px;top:4px;' onclick='i3GEOF.metaestat.principal.maisInfo()' title='"+$trad(3,i3GEOF.metaestat.dicionario)+"'/>";
  1943 + ins += "<img class='ticDownload' src='"+i3GEO.configura.locaplic+"/imagens/visual/default/branco.gif' style='position:relative;cursor:pointer;left:8px;top:5px;' onclick='i3GEOF.metaestat.principal.downloadMedida()' title='"+$trad("a3")+"'/>";
  1944 +
1915 1945 $i(onde).innerHTML = ins;
1916 1946 };
1917 1947 i3GEO.php.listaTemasMapaMetaestat(temas,id_mapa_grupo);
... ...
pacotes/parsecsv/ChangeLog.txt 0 → 100755
... ... @@ -0,0 +1,166 @@
  1 +parseCSV 0.3.2
  2 +-----------------------------------
  3 +Date: 1-Apr-2008
  4 +
  5 +This is primarily a bug-fix release for a critical
  6 +bug which was brought to my attention.
  7 +
  8 +- Fixed a critical bug in conditions parsing which
  9 + would generate corrupt matching patterns causing
  10 + the condition(s) to not work at all in some
  11 + situations.
  12 +
  13 +- Fixed a small code error which would cause PHP to
  14 + generate a invalid offset notice when zero length
  15 + values were fed into the unparse() method to
  16 + generate CSV data from an array.
  17 +
  18 +Notice: If you have been using the "parsecsv-stable"
  19 +branch as an external in any of your projects,
  20 +please use the "stable/parsecsv" branch from this
  21 +point on as I will eventually remove the former due
  22 +to it's stupid naming.
  23 +
  24 +-----------------------------------
  25 +
  26 +
  27 +parseCSV 0.3.1
  28 +-----------------------------------
  29 +Date: 1-Sep-2007
  30 +
  31 +- Small change to default output settings to
  32 + conform with RFC 4180 (http://rfc.net/rfc4180.html).
  33 + Only the LF (line feed) character was used
  34 + by default to separate rows, rather than
  35 + CRLF (carriage return & line feed).
  36 +
  37 +-----------------------------------
  38 +
  39 +
  40 +parseCSV 0.3.0
  41 +-----------------------------------
  42 +Date: 9-Aug-2007
  43 +
  44 +- Changed to the MIT license.
  45 +
  46 +- Added offset and limit options.
  47 +
  48 +- Added SQL-like conditions for quickly
  49 + filtering out entries. Documentation on the
  50 + condition syntax is forthcoming.
  51 +
  52 +- Small parsing modification to comply
  53 + with some recent changes to the specifications
  54 + outlined on Wikipedia's Comma-separated values
  55 + article.
  56 +
  57 +- Minor changes and optimizations, and a few
  58 + spelling corrections. Oops :)
  59 +
  60 +- Included more complex code examples in the
  61 + parseCSV download.
  62 +
  63 +-----------------------------------
  64 +
  65 +
  66 +parseCSV 0.2.1
  67 +-----------------------------------
  68 +Date: 8-Aug-2007
  69 +
  70 +- Fixed stupid code which caused auto function
  71 + to not work in some situations.
  72 +
  73 +-----------------------------------
  74 +
  75 +
  76 +parseCSV 0.2.0 beta
  77 +-----------------------------------
  78 +Date: 2-Jan-2007
  79 +
  80 +- Added auto() function to automatically detect
  81 + delimiter character.
  82 + Useful for user upload incase delimiter is
  83 + comma (,), tab, or semi-colon (;). Some
  84 + versions of MS Excel for Windows use
  85 + semi-colons instead of commas when saving to
  86 + CSV files.
  87 + It uses a process of elimination to eliminate
  88 + characters that can not be the delimiter,
  89 + so it should work on all CSV-structured files
  90 + almost no matter what the delimiter is.
  91 +
  92 +- Generally updated some of the core workings
  93 + to increase performance, and offer better
  94 + support for large (1MB and up) files.
  95 +
  96 +- Added code examples to header comment.
  97 +
  98 +-----------------------------------
  99 +
  100 +
  101 +parseCSV 0.1.6 beta
  102 +-----------------------------------
  103 +Date: 22-Dec-2006
  104 +
  105 +- Updated output() function.
  106 +
  107 +-----------------------------------
  108 +
  109 +
  110 +parseCSV 0.1.5 beta
  111 +-----------------------------------
  112 +Date: 22-Dec-2006
  113 +
  114 +- Added output() function for easy output to
  115 + browser, for downloading features for example.
  116 +
  117 +-----------------------------------
  118 +
  119 +
  120 +parseCSV 0.1.4 beta
  121 +-----------------------------------
  122 +Date: 17-Dec-2006
  123 +
  124 +- Minor changes and fixes
  125 +
  126 +-----------------------------------
  127 +
  128 +
  129 +parseCSV 0.1.3 beta
  130 +-----------------------------------
  131 +Date: 17-Dec-2006
  132 +
  133 +- Added GPL v2.0 license.
  134 +
  135 +-----------------------------------
  136 +
  137 +
  138 +parseCSV 0.1.2 beta
  139 +-----------------------------------
  140 +Date: 17-Dec-2006
  141 +
  142 +- Added encoding() function for easier character
  143 + encoding configuration.
  144 +
  145 +-----------------------------------
  146 +
  147 +
  148 +parseCSV 0.1.1 beta
  149 +-----------------------------------
  150 +Date: 24-Nov-2006
  151 +
  152 +- Added support for a PHP die command on first
  153 + line of csv files if they have a .php extension
  154 + to protect secure data from being displayed
  155 + directly to the browser.
  156 +
  157 +-----------------------------------
  158 +
  159 +
  160 +parseCSV 0.1 beta
  161 +-----------------------------------
  162 +Date: 23-Nov-2006
  163 +
  164 +- Initial release
  165 +
  166 +-----------------------------------
... ...
pacotes/parsecsv/License.txt 0 → 100755
... ... @@ -0,0 +1,19 @@
  1 +Copyright (c) 2007 Jim Myhrberg (jim@zydev.info).
  2 +
  3 +Permission is hereby granted, free of charge, to any person obtaining a copy
  4 +of this software and associated documentation files (the "Software"), to deal
  5 +in the Software without restriction, including without limitation the rights
  6 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7 +copies of the Software, and to permit persons to whom the Software is
  8 +furnished to do so, subject to the following conditions:
  9 +
  10 +The above copyright notice and this permission notice shall be included in
  11 +all copies or substantial portions of the Software.
  12 +
  13 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19 +THE SOFTWARE.
0 20 \ No newline at end of file
... ...
pacotes/parsecsv/examples/_books.csv 0 → 100755
... ... @@ -0,0 +1,15 @@
  1 +rating,title,author,type,asin,tags,review
  2 +0,The Killing Kind,John Connolly,Book,0340771224,,i still haven't had time to read this one...
  3 +0,The Third Secret,Steve Berry,Book,0340899263,,need to find time to read this book
  4 +3,The Last Templar,Raymond Khoury,Book,0752880705,,
  5 +5,The Traveller,John Twelve Hawks,Book,059305430X,,
  6 +4,Crisis Four,Andy Mcnab,Book,0345428080,,
  7 +5,Prey,Michael Crichton,Book,0007154534,,
  8 +3,The Broker (Paperback),John Grisham,Book,0440241588,book johngrisham,"good book, but is slow in the middle"
  9 +3,Without Blood (Paperback),Alessandro Baricco,Book,1841955744,,
  10 +5,State of Fear (Paperback),Michael Crichton,Book,0061015733,,
  11 +4,The Rule of Four (Paperback),Ian Caldwell,Book,0099451956,book bestseller,
  12 +4,Deception Point (Paperback),Dan Brown,Book,0671027387,book danbrown bestseller,
  13 +5,Digital Fortress : A Thriller (Mass Market Paperback),Dan Brown,Book,0312995423,book danbrown bestseller,
  14 +5,Angels & Demons (Mass Market Paperback),Dan Brown,Book,0671027360,book danbrown bestseller,
  15 +4,The Da Vinci Code (Hardcover),Dan Brown," Book ",0385504209,book movie danbrown bestseller davinci,
0 16 \ No newline at end of file
... ...
pacotes/parsecsv/examples/basic.php 0 → 100755
... ... @@ -0,0 +1,48 @@
  1 +<pre>
  2 +<?php
  3 +
  4 +
  5 +# include parseCSV class.
  6 +require_once('../parsecsv.lib.php');
  7 +
  8 +
  9 +# create new parseCSV object.
  10 +$csv = new parseCSV();
  11 +
  12 +
  13 +# Parse '_books.csv' using automatic delimiter detection...
  14 +$csv->auto('_books.csv');
  15 +
  16 +# ...or if you know the delimiter, set the delimiter character
  17 +# if its not the default comma...
  18 +// $csv->delimiter = "\t"; # tab delimited
  19 +
  20 +# ...and then use the parse() function.
  21 +// $csv->parse('_books.csv');
  22 +
  23 +
  24 +# Output result.
  25 +// print_r($csv->data);
  26 +
  27 +
  28 +?>
  29 +</pre>
  30 +<style type="text/css" media="screen">
  31 + table { background-color: #BBB; }
  32 + th { background-color: #EEE; }
  33 + td { background-color: #FFF; }
  34 +</style>
  35 +<table border="0" cellspacing="1" cellpadding="3">
  36 + <tr>
  37 + <?php foreach ($csv->titles as $value): ?>
  38 + <th><?php echo $value; ?></th>
  39 + <?php endforeach; ?>
  40 + </tr>
  41 + <?php foreach ($csv->data as $key => $row): ?>
  42 + <tr>
  43 + <?php foreach ($row as $value): ?>
  44 + <td><?php echo $value; ?></td>
  45 + <?php endforeach; ?>
  46 + </tr>
  47 + <?php endforeach; ?>
  48 +</table>
... ...
pacotes/parsecsv/examples/conditions.php 0 → 100755
... ... @@ -0,0 +1,48 @@
  1 +<pre>
  2 +<?php
  3 +
  4 +
  5 +# include parseCSV class.
  6 +require_once('../parsecsv.lib.php');
  7 +
  8 +
  9 +# create new parseCSV object.
  10 +$csv = new parseCSV();
  11 +
  12 +
  13 +# Example conditions:
  14 +// $csv->conditions = 'title contains paperback OR title contains hardcover';
  15 +$csv->conditions = 'author does not contain dan brown';
  16 +// $csv->conditions = 'rating < 4 OR author is John Twelve Hawks';
  17 +// $csv->conditions = 'rating > 4 AND author is Dan Brown';
  18 +
  19 +
  20 +# Parse '_books.csv' using automatic delimiter detection.
  21 +$csv->auto('_books.csv');
  22 +
  23 +
  24 +# Output result.
  25 +// print_r($csv->data);
  26 +
  27 +
  28 +?>
  29 +</pre>
  30 +<style type="text/css" media="screen">
  31 + table { background-color: #BBB; }
  32 + th { background-color: #EEE; }
  33 + td { background-color: #FFF; }
  34 +</style>
  35 +<table border="0" cellspacing="1" cellpadding="3">
  36 + <tr>
  37 + <?php foreach ($csv->titles as $value): ?>
  38 + <th><?php echo $value; ?></th>
  39 + <?php endforeach; ?>
  40 + </tr>
  41 + <?php foreach ($csv->data as $key => $row): ?>
  42 + <tr>
  43 + <?php foreach ($row as $value): ?>
  44 + <td><?php echo $value; ?></td>
  45 + <?php endforeach; ?>
  46 + </tr>
  47 + <?php endforeach; ?>
  48 +</table>
0 49 \ No newline at end of file
... ...
pacotes/parsecsv/examples/limit.php 0 → 100755
... ... @@ -0,0 +1,61 @@
  1 +<pre>
  2 +<?php
  3 +
  4 +
  5 +# include parseCSV class.
  6 +require_once('../parsecsv.lib.php');
  7 +
  8 +
  9 +# create new parseCSV object.
  10 +$csv = new parseCSV();
  11 +
  12 +
  13 +# if sorting is enabled, the whole CSV file
  14 +# will be processed and sorted and then rows
  15 +# are extracted based on offset and limit.
  16 +#
  17 +# if sorting is not enabled, then the least
  18 +# amount of rows to satisfy offset and limit
  19 +# settings will be processed. this is useful
  20 +# with large files when you only need the
  21 +# first 20 rows for example.
  22 +$csv->sort_by = 'title';
  23 +
  24 +
  25 +# offset from the beginning of the file,
  26 +# ignoring the first X number of rows.
  27 +$csv->offset = 2;
  28 +
  29 +# limit the number of returned rows.
  30 +$csv->limit = 3;
  31 +
  32 +
  33 +# Parse '_books.csv' using automatic delimiter detection.
  34 +$csv->auto('_books.csv');
  35 +
  36 +
  37 +# Output result.
  38 +// print_r($csv->data);
  39 +
  40 +
  41 +?>
  42 +</pre>
  43 +<style type="text/css" media="screen">
  44 + table { background-color: #BBB; }
  45 + th { background-color: #EEE; }
  46 + td { background-color: #FFF; }
  47 +</style>
  48 +<table border="0" cellspacing="1" cellpadding="3">
  49 + <tr>
  50 + <?php foreach ($csv->titles as $value): ?>
  51 + <th><?php echo $value; ?></th>
  52 + <?php endforeach; ?>
  53 + </tr>
  54 + <?php foreach ($csv->data as $key => $row): ?>
  55 + <tr>
  56 + <?php foreach ($row as $value): ?>
  57 + <td><?php echo $value; ?></td>
  58 + <?php endforeach; ?>
  59 + </tr>
  60 + <?php endforeach; ?>
  61 +</table>
0 62 \ No newline at end of file
... ...
pacotes/parsecsv/parsecsv.lib.php 0 → 100755
... ... @@ -0,0 +1,697 @@
  1 +<?php
  2 +
  3 +class parseCSV {
  4 +
  5 +/*
  6 +
  7 + Class: parseCSV v0.3.2
  8 + http://code.google.com/p/parsecsv-for-php/
  9 +
  10 +
  11 + Fully conforms to the specifications lined out on wikipedia:
  12 + - http://en.wikipedia.org/wiki/Comma-separated_values
  13 +
  14 + Based on the concept of Ming Hong Ng's CsvFileParser class:
  15 + - http://minghong.blogspot.com/2006/07/csv-parser-for-php.html
  16 +
  17 +
  18 +
  19 + Copyright (c) 2007 Jim Myhrberg (jim@zydev.info).
  20 +
  21 + Permission is hereby granted, free of charge, to any person obtaining a copy
  22 + of this software and associated documentation files (the "Software"), to deal
  23 + in the Software without restriction, including without limitation the rights
  24 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  25 + copies of the Software, and to permit persons to whom the Software is
  26 + furnished to do so, subject to the following conditions:
  27 +
  28 + The above copyright notice and this permission notice shall be included in
  29 + all copies or substantial portions of the Software.
  30 +
  31 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  32 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  33 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  34 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  35 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  36 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  37 + THE SOFTWARE.
  38 +
  39 +
  40 +
  41 + Code Examples
  42 + ----------------
  43 + # general usage
  44 + $csv = new parseCSV('data.csv');
  45 + print_r($csv->data);
  46 + ----------------
  47 + # tab delimited, and encoding conversion
  48 + $csv = new parseCSV();
  49 + $csv->encoding('UTF-16', 'UTF-8');
  50 + $csv->delimiter = "\t";
  51 + $csv->parse('data.tsv');
  52 + print_r($csv->data);
  53 + ----------------
  54 + # auto-detect delimiter character
  55 + $csv = new parseCSV();
  56 + $csv->auto('data.csv');
  57 + print_r($csv->data);
  58 + ----------------
  59 + # modify data in a csv file
  60 + $csv = new parseCSV();
  61 + $csv->sort_by = 'id';
  62 + $csv->parse('data.csv');
  63 + # "4" is the value of the "id" column of the CSV row
  64 + $csv->data[4] = array('firstname' => 'John', 'lastname' => 'Doe', 'email' => 'john@doe.com');
  65 + $csv->save();
  66 + ----------------
  67 + # add row/entry to end of CSV file
  68 + # - only recommended when you know the extact sctructure of the file
  69 + $csv = new parseCSV();
  70 + $csv->save('data.csv', array('1986', 'Home', 'Nowhere', ''), true);
  71 + ----------------
  72 + # convert 2D array to csv data and send headers
  73 + # to browser to treat output as a file and download it
  74 + $csv = new parseCSV();
  75 + $csv->output (true, 'movies.csv', $array);
  76 + ----------------
  77 +
  78 +
  79 +*/
  80 +
  81 +
  82 + /**
  83 + * Configuration
  84 + * - set these options with $object->var_name = 'value';
  85 + */
  86 +
  87 + # use first line/entry as field names
  88 + var $heading = true;
  89 +
  90 + # override field names
  91 + var $fields = array();
  92 +
  93 + # sort entries by this field
  94 + var $sort_by = null;
  95 + var $sort_reverse = false;
  96 +
  97 + # delimiter (comma) and enclosure (double quote)
  98 + var $delimiter = ',';
  99 + var $enclosure = '"';
  100 +
  101 + # basic SQL-like conditions for row matching
  102 + var $conditions = null;
  103 +
  104 + # number of rows to ignore from beginning of data
  105 + var $offset = null;
  106 +
  107 + # limits the number of returned rows to specified amount
  108 + var $limit = null;
  109 +
  110 + # number of rows to analyze when attempting to auto-detect delimiter
  111 + var $auto_depth = 15;
  112 +
  113 + # characters to ignore when attempting to auto-detect delimiter
  114 + var $auto_non_chars = "a-zA-Z0-9\n\r";
  115 +
  116 + # preferred delimiter characters, only used when all filtering method
  117 + # returns multiple possible delimiters (happens very rarely)
  118 + var $auto_preferred = ",;\t.:|";
  119 +
  120 + # character encoding options
  121 + var $convert_encoding = false;
  122 + var $input_encoding = 'ISO-8859-1';
  123 + var $output_encoding = 'ISO-8859-1';
  124 +
  125 + # used by unparse(), save(), and output() functions
  126 + var $linefeed = "\r\n";
  127 +
  128 + # only used by output() function
  129 + var $output_delimiter = ',';
  130 + var $output_filename = 'data.csv';
  131 +
  132 +
  133 + /**
  134 + * Internal variables
  135 + */
  136 +
  137 + # current file
  138 + var $file;
  139 +
  140 + # loaded file contents
  141 + var $file_data;
  142 +
  143 + # array of field values in data parsed
  144 + var $titles = array();
  145 +
  146 + # two dimentional array of CSV data
  147 + var $data = array();
  148 +
  149 +
  150 + /**
  151 + * Constructor
  152 + * @param input CSV file or string
  153 + * @return nothing
  154 + */
  155 + function parseCSV ($input = null, $offset = null, $limit = null, $conditions = null) {
  156 + if ( $offset !== null ) $this->offset = $offset;
  157 + if ( $limit !== null ) $this->limit = $limit;
  158 + if ( count($conditions) > 0 ) $this->conditions = $conditions;
  159 + if ( !empty($input) ) $this->parse($input);
  160 + }
  161 +
  162 +
  163 + // ==============================================
  164 + // ----- [ Main Functions ] ---------------------
  165 + // ==============================================
  166 +
  167 + /**
  168 + * Parse CSV file or string
  169 + * @param input CSV file or string
  170 + * @return nothing
  171 + */
  172 + function parse ($input = null, $offset = null, $limit = null, $conditions = null) {
  173 + if ( !empty($input) ) {
  174 + if ( $offset !== null ) $this->offset = $offset;
  175 + if ( $limit !== null ) $this->limit = $limit;
  176 + if ( count($conditions) > 0 ) $this->conditions = $conditions;
  177 + if ( is_readable($input) ) {
  178 +
  179 + $this->data = $this->parse_file($input);
  180 + } else {
  181 + $this->file_data = &$input;
  182 + $this->data = $this->parse_string();
  183 +
  184 + }
  185 + if ( $this->data === false ) return false;
  186 + }
  187 + return true;
  188 + }
  189 +
  190 + /**
  191 + * Save changes, or new file and/or data
  192 + * @param file file to save to
  193 + * @param data 2D array with data
  194 + * @param append append current data to end of target CSV if exists
  195 + * @param fields field names
  196 + * @return true or false
  197 + */
  198 + function save ($file = null, $data = array(), $append = false, $fields = array()) {
  199 + if ( empty($file) ) $file = &$this->file;
  200 + $mode = ( $append ) ? 'at' : 'wt' ;
  201 + $is_php = ( preg_match('/\.php$/i', $file) ) ? true : false ;
  202 + return $this->_wfile($file, $this->unparse($data, $fields, $append, $is_php), $mode);
  203 + }
  204 +
  205 + /**
  206 + * Generate CSV based string for output
  207 + * @param output if true, prints headers and strings to browser
  208 + * @param filename filename sent to browser in headers if output is true
  209 + * @param data 2D array with data
  210 + * @param fields field names
  211 + * @param delimiter delimiter used to separate data
  212 + * @return CSV data using delimiter of choice, or default
  213 + */
  214 + function output ($output = true, $filename = null, $data = array(), $fields = array(), $delimiter = null) {
  215 + if ( empty($filename) ) $filename = $this->output_filename;
  216 + if ( $delimiter === null ) $delimiter = $this->output_delimiter;
  217 + $data = $this->unparse($data, $fields, null, null, $delimiter);
  218 + if ( $output ) {
  219 + header('Content-type: application/csv');
  220 + header('Content-Disposition: inline; filename="'.$filename.'"');
  221 + echo $data;
  222 + }
  223 + return $data;
  224 + }
  225 +
  226 + /**
  227 + * Convert character encoding
  228 + * @param input input character encoding, uses default if left blank
  229 + * @param output output character encoding, uses default if left blank
  230 + * @return nothing
  231 + */
  232 + function encoding ($input = null, $output = null) {
  233 + $this->convert_encoding = true;
  234 + if ( $input !== null ) $this->input_encoding = $input;
  235 + if ( $output !== null ) $this->output_encoding = $output;
  236 + }
  237 +
  238 + /**
  239 + * Auto-Detect Delimiter: Find delimiter by analyzing a specific number of
  240 + * rows to determine most probable delimiter character
  241 + * @param file local CSV file
  242 + * @param parse true/false parse file directly
  243 + * @param search_depth number of rows to analyze
  244 + * @param preferred preferred delimiter characters
  245 + * @param enclosure enclosure character, default is double quote (").
  246 + * @return delimiter character
  247 + */
  248 + function auto ($file = null, $parse = true, $search_depth = null, $preferred = null, $enclosure = null) {
  249 +
  250 + if ( $file === null ) $file = $this->file;
  251 + if ( empty($search_depth) ) $search_depth = $this->auto_depth;
  252 + if ( $enclosure === null ) $enclosure = $this->enclosure;
  253 +
  254 + if ( $preferred === null ) $preferred = $this->auto_preferred;
  255 +
  256 + if ( empty($this->file_data) ) {
  257 + if ( $this->_check_data($file) ) {
  258 + $data = &$this->file_data;
  259 + } else return false;
  260 + } else {
  261 + $data = &$this->file_data;
  262 + }
  263 +
  264 + $chars = array();
  265 + $strlen = strlen($data);
  266 + $enclosed = false;
  267 + $n = 1;
  268 + $to_end = true;
  269 +
  270 + // walk specific depth finding posssible delimiter characters
  271 + for ( $i=0; $i < $strlen; $i++ ) {
  272 + $ch = $data{$i};
  273 + $nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
  274 + $pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;
  275 +
  276 + // open and closing quotes
  277 + if ( $ch == $enclosure && (!$enclosed || $nch != $enclosure) ) {
  278 + $enclosed = ( $enclosed ) ? false : true ;
  279 +
  280 + // inline quotes
  281 + } elseif ( $ch == $enclosure && $enclosed ) {
  282 + $i++;
  283 +
  284 + // end of row
  285 + } elseif ( ($ch == "\n" && $pch != "\r" || $ch == "\r") && !$enclosed ) {
  286 + if ( $n >= $search_depth ) {
  287 + $strlen = 0;
  288 + $to_end = false;
  289 + } else {
  290 + $n++;
  291 + }
  292 +
  293 + // count character
  294 + } elseif (!$enclosed) {
  295 + if ( !preg_match('/['.preg_quote($this->auto_non_chars, '/').']/i', $ch) ) {
  296 + if ( !isset($chars[$ch][$n]) ) {
  297 + $chars[$ch][$n] = 1;
  298 + } else {
  299 + $chars[$ch][$n]++;
  300 + }
  301 + }
  302 + }
  303 + }
  304 +
  305 + // filtering
  306 + $depth = ( $to_end ) ? $n-1 : $n ;
  307 + $filtered = array();
  308 + foreach( $chars as $char => $value ) {
  309 + if ( $match = $this->_check_count($char, $value, $depth, $preferred) ) {
  310 + $filtered[$match] = $char;
  311 + }
  312 + }
  313 +
  314 + // capture most probable delimiter
  315 + ksort($filtered);
  316 + $delimiter = reset($filtered);
  317 + $this->delimiter = $delimiter;
  318 +
  319 + // parse data
  320 + if ( $parse ) $this->data = $this->parse_string();
  321 +
  322 + return $delimiter;
  323 +
  324 + }
  325 +
  326 +
  327 + // ==============================================
  328 + // ----- [ Core Functions ] ---------------------
  329 + // ==============================================
  330 +
  331 + /**
  332 + * Read file to string and call parse_string()
  333 + * @param file local CSV file
  334 + * @return 2D array with CSV data, or false on failure
  335 + */
  336 + function parse_file ($file = null) {
  337 + if ( $file === null ) $file = $this->file;
  338 + if ( empty($this->file_data) ) $this->load_data($file);
  339 + return ( !empty($this->file_data) ) ? $this->parse_string() : false ;
  340 + }
  341 +
  342 + /**
  343 + * Parse CSV strings to arrays
  344 + * @param data CSV string
  345 + * @return 2D array with CSV data, or false on failure
  346 + */
  347 + function parse_string ($data = null) {
  348 + if ( empty($data) ) {
  349 + if ( $this->_check_data() ) {
  350 + $data = &$this->file_data;
  351 + } else return false;
  352 + }
  353 +
  354 + $rows = array();
  355 + $row = array();
  356 + $row_count = 0;
  357 + $current = '';
  358 + $head = ( !empty($this->fields) ) ? $this->fields : array() ;
  359 + $col = 0;
  360 + $enclosed = false;
  361 + $was_enclosed = false;
  362 + $strlen = strlen($data);
  363 +
  364 + // walk through each character
  365 + for ( $i=0; $i < $strlen; $i++ ) {
  366 + $ch = $data{$i};
  367 + $nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
  368 + $pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;
  369 +
  370 + // open and closing quotes
  371 + if ( $ch == $this->enclosure && (!$enclosed || $nch != $this->enclosure) ) {
  372 + $enclosed = ( $enclosed ) ? false : true ;
  373 + if ( $enclosed ) $was_enclosed = true;
  374 +
  375 + // inline quotes
  376 + } elseif ( $ch == $this->enclosure && $enclosed ) {
  377 + $current .= $ch;
  378 + $i++;
  379 +
  380 + // end of field/row
  381 + } elseif ( ($ch == $this->delimiter || ($ch == "\n" && $pch != "\r") || $ch == "\r") && !$enclosed ) {
  382 + if ( !$was_enclosed ) $current = trim($current);
  383 + $key = ( !empty($head[$col]) ) ? $head[$col] : $col ;
  384 + $row[$key] = $current;
  385 + $current = '';
  386 + $col++;
  387 +
  388 + // end of row
  389 + if ( $ch == "\n" || $ch == "\r" ) {
  390 + if ( $this->_validate_offset($row_count) && $this->_validate_row_conditions($row, $this->conditions) ) {
  391 + if ( $this->heading && empty($head) ) {
  392 + $head = $row;
  393 + } elseif ( empty($this->fields) || (!empty($this->fields) && (($this->heading && $row_count > 0) || !$this->heading)) ) {
  394 + if ( !empty($this->sort_by) && !empty($row[$this->sort_by]) ) {
  395 + if ( isset($rows[$row[$this->sort_by]]) ) {
  396 + $rows[$row[$this->sort_by].'_0'] = &$rows[$row[$this->sort_by]];
  397 + unset($rows[$row[$this->sort_by]]);
  398 + for ( $sn=1; isset($rows[$row[$this->sort_by].'_'.$sn]); $sn++ ) {}
  399 + $rows[$row[$this->sort_by].'_'.$sn] = $row;
  400 + } else $rows[$row[$this->sort_by]] = $row;
  401 + } else $rows[] = $row;
  402 + }
  403 + }
  404 + $row = array();
  405 + $col = 0;
  406 + $row_count++;
  407 + if ( $this->sort_by === null && $this->limit !== null && count($rows) == $this->limit ) {
  408 + $i = $strlen;
  409 + }
  410 + }
  411 +
  412 + // append character to current field
  413 + } else {
  414 + $current .= $ch;
  415 + }
  416 + }
  417 + $this->titles = $head;
  418 + if ( !empty($this->sort_by) ) {
  419 + ( $this->sort_reverse ) ? krsort($rows) : ksort($rows) ;
  420 + if ( $this->offset !== null || $this->limit !== null ) {
  421 + $rows = array_slice($rows, ($this->offset === null ? 0 : $this->offset) , $this->limit, true);
  422 + }
  423 + }
  424 + return $rows;
  425 + }
  426 +
  427 + /**
  428 + * Create CSV data from array
  429 + * @param data 2D array with data
  430 + * @param fields field names
  431 + * @param append if true, field names will not be output
  432 + * @param is_php if a php die() call should be put on the first
  433 + * line of the file, this is later ignored when read.
  434 + * @param delimiter field delimiter to use
  435 + * @return CSV data (text string)
  436 + */
  437 + function unparse ( $data = array(), $fields = array(), $append = false , $is_php = false, $delimiter = null) {
  438 + if ( !is_array($data) || empty($data) ) $data = &$this->data;
  439 + if ( !is_array($fields) || empty($fields) ) $fields = &$this->titles;
  440 + if ( $delimiter === null ) $delimiter = $this->delimiter;
  441 +
  442 + $string = ( $is_php ) ? "<?php header('Status: 403'); die(' '); ?>".$this->linefeed : '' ;
  443 + $entry = array();
  444 +
  445 + // create heading
  446 + if ( $this->heading && !$append ) {
  447 + foreach( $fields as $key => $value ) {
  448 + $entry[] = $this->_enclose_value($value);
  449 + }
  450 + $string .= implode($delimiter, $entry).$this->linefeed;
  451 + $entry = array();
  452 + }
  453 +
  454 + // create data
  455 + foreach( $data as $key => $row ) {
  456 + foreach( $row as $field => $value ) {
  457 + $entry[] = $this->_enclose_value($value);
  458 + }
  459 + $string .= implode($delimiter, $entry).$this->linefeed;
  460 + $entry = array();
  461 + }
  462 +
  463 + return $string;
  464 + }
  465 +
  466 + /**
  467 + * Load local file or string
  468 + * @param input local CSV file
  469 + * @return true or false
  470 + */
  471 + function load_data ($input = null) {
  472 + $data = null;
  473 + $file = null;
  474 + if ( $input === null ) {
  475 + $file = $this->file;
  476 + } elseif ( file_exists($input) ) {
  477 + $file = $input;
  478 + } else {
  479 + $data = $input;
  480 + }
  481 + if ( !empty($data) || $data = $this->_rfile($file) ) {
  482 + if ( $this->file != $file ) $this->file = $file;
  483 + if ( preg_match('/\.php$/i', $file) && preg_match('/<\?.*?\?>(.*)/ims', $data, $strip) ) {
  484 + $data = ltrim($strip[1]);
  485 + }
  486 + if ( $this->convert_encoding ) $data = iconv($this->input_encoding, $this->output_encoding, $data);
  487 + if ( substr($data, -1) != "\n" ) $data .= "\n";
  488 + $this->file_data = &$data;
  489 + return true;
  490 + }
  491 + return false;
  492 + }
  493 +
  494 +
  495 + // ==============================================
  496 + // ----- [ Internal Functions ] -----------------
  497 + // ==============================================
  498 +
  499 + /**
  500 + * Validate a row against specified conditions
  501 + * @param row array with values from a row
  502 + * @param conditions specified conditions that the row must match
  503 + * @return true of false
  504 + */
  505 + function _validate_row_conditions ($row = array(), $conditions = null) {
  506 + if ( !empty($row) ) {
  507 + if ( !empty($conditions) ) {
  508 + $conditions = (strpos($conditions, ' OR ') !== false) ? explode(' OR ', $conditions) : array($conditions) ;
  509 + $or = '';
  510 + foreach( $conditions as $key => $value ) {
  511 + if ( strpos($value, ' AND ') !== false ) {
  512 + $value = explode(' AND ', $value);
  513 + $and = '';
  514 + foreach( $value as $k => $v ) {
  515 + $and .= $this->_validate_row_condition($row, $v);
  516 + }
  517 + $or .= (strpos($and, '0') !== false) ? '0' : '1' ;
  518 + } else {
  519 + $or .= $this->_validate_row_condition($row, $value);
  520 + }
  521 + }
  522 + return (strpos($or, '1') !== false) ? true : false ;
  523 + }
  524 + return true;
  525 + }
  526 + return false;
  527 + }
  528 +
  529 + /**
  530 + * Validate a row against a single condition
  531 + * @param row array with values from a row
  532 + * @param condition specified condition that the row must match
  533 + * @return true of false
  534 + */
  535 + function _validate_row_condition ($row, $condition) {
  536 + $operators = array(
  537 + '=', 'equals', 'is',
  538 + '!=', 'is not',
  539 + '<', 'is less than',
  540 + '>', 'is greater than',
  541 + '<=', 'is less than or equals',
  542 + '>=', 'is greater than or equals',
  543 + 'contains',
  544 + 'does not contain',
  545 + );
  546 + $operators_regex = array();
  547 + foreach( $operators as $value ) {
  548 + $operators_regex[] = preg_quote($value, '/');
  549 + }
  550 + $operators_regex = implode('|', $operators_regex);
  551 + if ( preg_match('/^(.+) ('.$operators_regex.') (.+)$/i', trim($condition), $capture) ) {
  552 + $field = $capture[1];
  553 + $op = $capture[2];
  554 + $value = $capture[3];
  555 + if ( preg_match('/^([\'\"]{1})(.*)([\'\"]{1})$/i', $value, $capture) ) {
  556 + if ( $capture[1] == $capture[3] ) {
  557 + $value = $capture[2];
  558 + $value = str_replace("\\n", "\n", $value);
  559 + $value = str_replace("\\r", "\r", $value);
  560 + $value = str_replace("\\t", "\t", $value);
  561 + $value = stripslashes($value);
  562 + }
  563 + }
  564 + if ( array_key_exists($field, $row) ) {
  565 + if ( ($op == '=' || $op == 'equals' || $op == 'is') && $row[$field] == $value ) {
  566 + return '1';
  567 + } elseif ( ($op == '!=' || $op == 'is not') && $row[$field] != $value ) {
  568 + return '1';
  569 + } elseif ( ($op == '<' || $op == 'is less than' ) && $row[$field] < $value ) {
  570 + return '1';
  571 + } elseif ( ($op == '>' || $op == 'is greater than') && $row[$field] > $value ) {
  572 + return '1';
  573 + } elseif ( ($op == '<=' || $op == 'is less than or equals' ) && $row[$field] <= $value ) {
  574 + return '1';
  575 + } elseif ( ($op == '>=' || $op == 'is greater than or equals') && $row[$field] >= $value ) {
  576 + return '1';
  577 + } elseif ( $op == 'contains' && preg_match('/'.preg_quote($value, '/').'/i', $row[$field]) ) {
  578 + return '1';
  579 + } elseif ( $op == 'does not contain' && !preg_match('/'.preg_quote($value, '/').'/i', $row[$field]) ) {
  580 + return '1';
  581 + } else {
  582 + return '0';
  583 + }
  584 + }
  585 + }
  586 + return '1';
  587 + }
  588 +
  589 + /**
  590 + * Validates if the row is within the offset or not if sorting is disabled
  591 + * @param current_row the current row number being processed
  592 + * @return true of false
  593 + */
  594 + function _validate_offset ($current_row) {
  595 + if ( $this->sort_by === null && $this->offset !== null && $current_row < $this->offset ) return false;
  596 + return true;
  597 + }
  598 +
  599 + /**
  600 + * Enclose values if needed
  601 + * - only used by unparse()
  602 + * @param value string to process
  603 + * @return Processed value
  604 + */
  605 + function _enclose_value ($value = null) {
  606 + if ( $value !== null && $value != '' ) {
  607 + $delimiter = preg_quote($this->delimiter, '/');
  608 + $enclosure = preg_quote($this->enclosure, '/');
  609 + if ( preg_match("/".$delimiter."|".$enclosure."|\n|\r/i", $value) || ($value{0} == ' ' || substr($value, -1) == ' ') ) {
  610 + $value = str_replace($this->enclosure, $this->enclosure.$this->enclosure, $value);
  611 + $value = $this->enclosure.$value.$this->enclosure;
  612 + }
  613 + }
  614 + return $value;
  615 + }
  616 +
  617 + /**
  618 + * Check file data
  619 + * @param file local filename
  620 + * @return true or false
  621 + */
  622 + function _check_data ($file = null) {
  623 + if ( empty($this->file_data) ) {
  624 + if ( $file === null ) $file = $this->file;
  625 + return $this->load_data($file);
  626 + }
  627 + return true;
  628 + }
  629 +
  630 +
  631 + /**
  632 + * Check if passed info might be delimiter
  633 + * - only used by find_delimiter()
  634 + * @return special string used for delimiter selection, or false
  635 + */
  636 + function _check_count ($char, $array, $depth, $preferred) {
  637 + if ( $depth == count($array) ) {
  638 + $first = null;
  639 + $equal = null;
  640 + $almost = false;
  641 + foreach( $array as $key => $value ) {
  642 + if ( $first == null ) {
  643 + $first = $value;
  644 + } elseif ( $value == $first && $equal !== false) {
  645 + $equal = true;
  646 + } elseif ( $value == $first+1 && $equal !== false ) {
  647 + $equal = true;
  648 + $almost = true;
  649 + } else {
  650 + $equal = false;
  651 + }
  652 + }
  653 + if ( $equal ) {
  654 + $match = ( $almost ) ? 2 : 1 ;
  655 + $pref = strpos($preferred, $char);
  656 + $pref = ( $pref !== false ) ? str_pad($pref, 3, '0', STR_PAD_LEFT) : '999' ;
  657 + return $pref.$match.'.'.(99999 - str_pad($first, 5, '0', STR_PAD_LEFT));
  658 + } else return false;
  659 + }
  660 + }
  661 +
  662 + /**
  663 + * Read local file
  664 + * @param file local filename
  665 + * @return Data from file, or false on failure
  666 + */
  667 + function _rfile ($file = null) {
  668 + if ( is_readable($file) ) {
  669 + if ( !($fh = fopen($file, 'r')) ) return false;
  670 + $data = fread($fh, filesize($file));
  671 + fclose($fh);
  672 + return $data;
  673 + }
  674 + return false;
  675 + }
  676 +
  677 + /**
  678 + * Write to local file
  679 + * @param file local filename
  680 + * @param string data to write to file
  681 + * @param mode fopen() mode
  682 + * @param lock flock() mode
  683 + * @return true or false
  684 + */
  685 + function _wfile ($file, $string = '', $mode = 'wb', $lock = 2) {
  686 + if ( $fp = fopen($file, $mode) ) {
  687 + flock($fp, $lock);
  688 + $re = fwrite($fp, $string);
  689 + $re2 = fclose($fp);
  690 + if ( $re != false && $re2 != false ) return true;
  691 + }
  692 + return false;
  693 + }
  694 +
  695 +}
  696 +
  697 +?>
0 698 \ No newline at end of file
... ...