Ir para conteúdo
Jack Oliveira

DRAP AND DROP

Recommended Posts

Ola pessoal, boa noite a todos

 

Bom é o seguinte tenho um codigo html onde selecione um modelo de site para poder criar na base selecionada, ele criar ate então, mas ele esta pegando somente o index.html

Mas quero que ele salva junto ao novo projeto o css, js, img, images, assets e fonts, quando faço os ajuste para que pega tudo isso ele me da erro ao salvar 

Vou mostra parte do html onde faz a seleção dos modelos

 

<!-- new page modal-->
<div class="modal fade" id="new-page-modal" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">   
    <form id="newPageForm" method="POST" action="save.php">        
    <div class="modal-content">
      <div class="modal-header">
        <h6 class="modal-title text-primary fw-normal"><i class="la la-lg la-file"></i> Nova página</h6>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
        </button>
      </div>
      <div class="modal-body text">
        <div class="mb-3 row" data-key="type">      
            <label class="col-sm-3 col-form-label">
                Modelo 
                <abbr title="O conteúdo deste modelo será usado como ponto de partida para o novo modelo">
                    <i class="la la-lg la-question-circle text-primary"></i>
                </abbr>
                
            </label>      
            <div class="col-sm-9 input">
                <div>    
                    <select class="form-select" name="startTemplateUrl">        
                        <option value="themes/modelo-branco/branco-template.html">Modelo em branco</option>        
                        <option value="themes/modelo1/index.html">Modelo 1 de L2</option>       
                        <option value="themes/modelo2/index.html">Modelo 3 de L2</option>
                        <option value="themes/modelo3/index.html">Modelo 3 de L2 </option>                        
                    </select>    
                </div>
            </div>     
        </div>
        <div class="mb-3 row" data-key="href">     
             <label class="col-sm-3 col-form-label">Nome da página</label>      
            <div class="col-sm-9 input">
                <div>   
                    <input name="title" type="text" value="Minha página" class="form-control" placeholder="Minha página" required>  
                </div>
            </div>     
        </div>        
        <div class="mb-3 row" data-key="href">     
             <label class="col-sm-3 col-form-label">Nome do arquivo</label>      
            <div class="col-sm-9 input">
                <div>   
                    <input name="file" type="text" value="my-page.html" class="form-control" placeholder="index.html" required>  
                </div>
            </div>     
        </div>       
        <div class="mb-3 row" data-key="href">     
             <label class="col-sm-3 col-form-label">Salvar na pasta</label>      
            <div class="col-sm-9 input">
                <div>   
                    <input name="folder" type="text" value="my-pages" class="form-control" placeholder="/" required>  
                </div>
                
            </div>     
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-secondary btn-lg" type="reset" data-bs-dismiss="modal"><i class="la la-times"></i> Cancelar</button>
        <button class="btn btn-primary btn-lg" type="submit"><i class="la la-check"></i> Criar página</button>
      </div>
    </div>   
   </form>        
  </div>
</div>

A ideia aqui é salvar tudo que tiver depois do themes/demo1/

quando ele salva so salva 

my-pasta/index.html

e quando for salva ele salva dentro de um pasta Projetos/MeuSite1

Projetos/MeuSite2  e assim vai

Este é o save.php

 

<?php
define('MAX_FILE_LIMIT', 1024 * 1024 * 2);//Tamanho máximo de arquivo HTML de 2 megabytes
define('ALLOW_PHP', false);//verifique se o html salvo contém tag php e não salve se não for permitido
define('ALLOWED_OEMBED_DOMAINS', [
	'https://www.youtube.com/', 
	'https://www.vimeo.com/', 
	'https://www.twitter.com/'
]);//carregar URLs apenas de sites permitidos para oembed

function sanitizeFileName($file, $allowedExtension = 'html') {
	$basename = basename($file);
	$disallow = ['.htaccess', 'passwd'];
	if (in_array($basename, $disallow)) {
		showError('Nome de arquivo não permitido!');
		return '';
	}
	
	//sanitize, remova o ponto duplo .. e remova os parâmetros get, se houver
	$file = preg_replace('@\?.*$@' , '', preg_replace('@\.{2,}@' , '', preg_replace('@[^\/\\a-zA-Z0-9\-\._]@', '', $file)));
	
	if ($file) {
		$file = __DIR__ . DIRECTORY_SEPARATOR . $file;
	} else {
		return '';
	}
	
	//permitir apenas extensão .html
	if ($allowedExtension) {
		$file = preg_replace('/\.[^.]+$/', '', $file) . ".$allowedExtension";
	}
	return $file;
}

function showError($error) {
	header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
	die($error);
}

function validOembedUrl($url) {
	foreach (ALLOWED_OEMBED_DOMAINS as $domain) {
		if (strpos($url, $domain) === 0) {
			return true;
		}
	}
	
	return false;
}

$html   = '';
$file   = '';
$action = '';

if (isset($_POST['startTemplateUrl']) && !empty($_POST['startTemplateUrl'])) {
	$startTemplateUrl = sanitizeFileName($_POST['startTemplateUrl']);
	$html = '';
	if ($startTemplateUrl) {
		$html = file_get_contents($startTemplateUrl);
	}
} else if (isset($_POST['html'])){
	$html = substr($_POST['html'], 0, MAX_FILE_LIMIT);
	if (!ALLOW_PHP) {
		//if (strpos($html, '<?php') !== false) {
		if (preg_match('@<\?php|<\? |<\?=|<\s*script\s*language\s*=\s*"\s*php\s*"\s*>@', $html)) {
			showError('PHP não permitido!');
		}
	}
}

if (isset($_POST['file'])) {
	$file = sanitizeFileName($_POST['file']);
}

if (isset($_GET['action'])) {
	$action = htmlspecialchars(strip_tags($_GET['action']));
}

if ($action) {
	//ações do gerenciador de arquivos, excluir e renomear
	switch ($action) {
		case 'rename':
			$newfile = sanitizeFileName($_POST['newfile']);
			if ($file && $newfile) {
				if (rename($file, $newfile)) {
					echo "Arquivo '$file' renomeado para '$newfile'";
				} else {
					showError("Erro ao renomear arquivo '$file' renomeado para '$newfile'");
				}
			}
		break;
		case 'delete':
			if ($file) {
				if (unlink($file)) {
					echo "Arquivo '$file' excluído";
				} else {
					showError("Erro ao excluir arquivo '$file'");
				}
			}
		break;
		case 'saveReusable':
		    //bloco ou seção
			$type = $_POST['type'] ?? false;
			$name = $_POST['name'] ?? false;
			$html = $_POST['html'] ?? false;
			
			if ($type && $name && $html) {
				
				$file = sanitizeFileName("$type/$name");
				if ($file) {
					$dir = dirname($file);
					if (!is_dir($dir)) {
						echo "$dir pasta não existe\n";
						if (mkdir($dir, 0777, true)) {
							echo "$dir pasta foi criada\n";
						} else {
							showError("Erro ao criar pasta '$dir'\n");
						}				
					}
					
					if (file_put_contents($file, $html)) {
						echo "Arquivo salvo '$file'";
					} else {
						showError("Erro ao salvar arquivo '$file'\nAs possíveis causas são falta de permissão de gravação ou caminho de arquivo incorreto!");
					}
				} else {
					showError('Nome de arquivo inválido!');
				}
			} else {
				showError("Faltam dados de elementos reutilizáveis!\n");
			}
		break;
		case 'oembedProxy':
			$url = $_GET['url'] ?? '';
			if (validOembedUrl($url)) {
				header('Content-Type: application/json');
				echo file_get_contents($url);
			} else {
				showError('URL inválida!');
			}
		break;
		default:
			showError("Ação inválida '$action'!");
	}
} else {
	//salvar pagina
	if ($html) {
		if ($file) {
			$dir = dirname($file);
			if (!is_dir($dir)) {
				echo "$dir pasta não existe\n";
				if (mkdir($dir, 0777, true)) {
					echo "$dir pasta foi criada\n";
				} else {
					showError("Erro ao criar pasta '$dir'\n");
				}
			}

			if (file_put_contents($file, $html)) {
				echo "Arquivo salvo '$file'";
			} else {
				showError("Erro ao salvar arquivo '$file'\nAs possíveis causas são falta de permissão de gravação ou caminho de arquivo incorreto!");
			}	
		} else {
			showError('O nome do arquivo está vazio!');
		}
	} else {
		showError('O conteúdo HTML está vazio!');
	}
}

Espero que possam entender o que preciso aqui....  fico no aguardo!  quando eu tento mudar a forma de salva no php, ele me da erro de que não foi salvo, e volta ao orginal como esta ai acima ele salva, talvez eu esteja escapando alguma coisa que não estou vendo.... 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para salvar todos os arquivos e pastas relacionados ao template (CSS, JS, imagens, etc.), você pode modificar seu código PHP para copiar a estrutura de diretórios e os arquivos. Vou mostrar como você pode fazer isso:

HTML
 

O código HTML não precisa de muitas alterações, mas certifique-se de que os caminhos dos templates estejam corretos. Aqui está o trecho relevante do seu HTML para referência:  

<!-- new page modal-->
<div class="modal fade" id="new-page-modal" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <form id="newPageForm" method="POST" action="save.php">
      <div class="modal-content">
        <div class="modal-header">
          <h6 class="modal-title text-primary fw-normal"><i class="la la-lg la-file"></i> Nova página</h6>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body text">
          <div class="mb-3 row" data-key="type">
            <label class="col-sm-3 col-form-label">
              Modelo
              <abbr title="O conteúdo deste modelo será usado como ponto de partida para o novo modelo">
                <i class="la la-lg la-question-circle text-primary"></i>
              </abbr>
            </label>
            <div class="col-sm-9 input">
              <div>
                <select class="form-select" name="startTemplateUrl">
                  <option value="themes/modelo-branco/branco-template.html">Modelo em branco</option>
                  <option value="themes/modelo1/index.html">Modelo 1 de L2</option>
                  <option value="themes/modelo2/index.html">Modelo 2 de L2</option>
                  <option value="themes/modelo3/index.html">Modelo 3 de L2 </option>
                </select>
              </div>
            </div>
          </div>
          <div class="mb-3 row" data-key="href">
            <label class="col-sm-3 col-form-label">Nome da página</label>
            <div class="col-sm-9 input">
              <div>
                <input name="title" type="text" value="Minha página" class="form-control" placeholder="Minha página" required>
              </div>
            </div>
          </div>
          <div class="mb-3 row" data-key="href">
            <label class="col-sm-3 col-form-label">Nome do arquivo</label>
            <div class="col-sm-9 input">
              <div>
                <input name="file" type="text" value="my-page.html" class="form-control" placeholder="index.html" required>
              </div>
            </div>
          </div>
          <div class="mb-3 row" data-key="href">
            <label class="col-sm-3 col-form-label">Salvar na pasta</label>
            <div class="col-sm-9 input">
              <div>
                <input name="folder" type="text" value="my-pages" class="form-control" placeholder="/" required>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button class="btn btn-secondary btn-lg" type="reset" data-bs-dismiss="modal"><i class="la la-times"></i> Cancelar</button>
          <button class="btn btn-primary btn-lg" type="submit"><i class="la la-check"></i> Criar página</button>
        </div>
      </div>
    </form>
  </div>
</div>


PHP (save.php)

Modifique o seu save.php para copiar a estrutura completa do template selecionado. Adicionado função para copiar diretórios recursivamente e ajustar o script para usar essa função.
 

<?php
define('MAX_FILE_LIMIT', 1024 * 1024 * 2);//Tamanho máximo de arquivo HTML de 2 megabytes
define('ALLOW_PHP', false);//verifique se o html salvo contém tag php e não salve se não for permitido
define('ALLOWED_OEMBED_DOMAINS', [
	'https://www.youtube.com/', 
	'https://www.vimeo.com/', 
	'https://www.twitter.com/'
]);//carregar URLs apenas de sites permitidos para oembed

function sanitizeFileName($file, $allowedExtension = 'html') {
	$basename = basename($file);
	$disallow = ['.htaccess', 'passwd'];
	if (in_array($basename, $disallow)) {
		showError('Nome de arquivo não permitido!');
		return '';
	}
	
	$file = preg_replace('@\?.*$@' , '', preg_replace('@\.{2,}@' , '', preg_replace('@[^\/\\a-zA-Z0-9\-\._]@', '', $file)));
	
	if ($file) {
		$file = __DIR__ . DIRECTORY_SEPARATOR . $file;
	} else {
		return '';
	}
	
	if ($allowedExtension) {
		$file = preg_replace('/\.[^.]+$/', '', $file) . ".$allowedExtension";
	}
	return $file;
}

function showError($error) {
	header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
	die($error);
}

function validOembedUrl($url) {
	foreach (ALLOWED_OEMBED_DOMAINS as $domain) {
		if (strpos($url, $domain) === 0) {
			return true;
		}
	}
	return false;
}

function copyDirectory($src, $dst) {
	$dir = opendir($src);
	@mkdir($dst);
	while(false !== ( $file = readdir($dir)) ) {
		if (( $file != '.' ) && ( $file != '..' )) {
			if ( is_dir($src . '/' . $file) ) {
				copyDirectory($src . '/' . $file, $dst . '/' . $file);
			}
			else {
				copy($src . '/' . $file, $dst . '/' . $file);
			}
		}
	}
	closedir($dir);
}

$html   = '';
$file   = '';
$action = '';

if (isset($_POST['startTemplateUrl']) && !empty($_POST['startTemplateUrl'])) {
	$startTemplateUrl = sanitizeFileName($_POST['startTemplateUrl']);
	if ($startTemplateUrl) {
		$templateDir = dirname($startTemplateUrl);
		$targetDir = __DIR__ . '/Projetos/' . sanitizeFileName($_POST['folder']);
		copyDirectory($templateDir, $targetDir);
		$html = file_get_contents($startTemplateUrl);
	}
} else if (isset($_POST['html'])){
	$html = substr($_POST['html'], 0, MAX_FILE_LIMIT);
	if (!ALLOW_PHP) {
		if (preg_match('@<\?php|<\? |<\?=|<\s*script\s*language\s*=\s*"\s*php\s*"\s*>@', $html)) {
			showError('PHP não permitido!');
		}
	}
}

if (isset($_POST['file'])) {
	$file = sanitizeFileName($_POST['file']);
}

if (isset($_GET['action'])) {
	$action = htmlspecialchars(strip_tags($_GET['action']));
}

if ($action) {
	switch ($action) {
		case 'rename':
			$newfile = sanitizeFileName($_POST['newfile']);
			if ($file && $newfile) {
				if (rename($file, $newfile)) {
					echo "Arquivo '$file' renomeado para '$newfile'";
				} else {
					showError("Erro ao renomear arquivo '$file' renomeado para '$newfile'");
				}
			}
		break;
		case 'delete':
			if ($file) {
				if (unlink($file)) {
					echo "Arquivo '$file' excluído";
				} else {
					showError("Erro ao excluir arquivo '$file'");
				}
			}
		break;
		case 'saveReusable':
			$type = $_POST['type'] ?? false;
			$name = $_POST['name'] ?? false;
			$html = $_POST['html'] ?? false;
			
			if ($type && $name && $html) {
				$file = sanitizeFileName("$type/$name");
				if ($file) {
					$dir = dirname($file);
					if (!is_dir($dir)) {
						echo "$dir pasta não existe\n";
						if (mkdir($dir, 0777, true)) {
							echo "$dir pasta foi criada\n";
						} else {
							showError("Erro ao criar pasta '$dir'\n");
						}
					}
					if (file_put_contents($file, $html)) {
						echo "Arquivo salvo '$file'";
					} else {
						showError("Erro ao salvar arquivo '$file'\nAs possíveis causas são falta de permissão de gravação ou caminho de arquivo incorreto!");
					}
				} else {
					showError('Nome de arquivo inválido!');
				}
			} else {
				showError("Faltam dados de elementos reutilizáveis!\n");
			}
		break;
		case 'oembedProxy':
			$url = $_GET['url'] ?? '';
			if (validOembedUrl($url)) {
				header('Content-Type: application/json');
				echo file_get_contents($url);
			} else {
				showError('URL inválida!');
			}
		break;
		default:
			showError("Ação inválida '$action'!");
	}
} else {
	if ($html) {
		if ($file) {
			$dir = dirname($file);
			if (!is_dir($dir)) {
				echo "$dir pasta não existe\n";
				if (mkdir($dir, 0777, true)) {
					echo "$dir pasta foi criada\n";
				} else {
					showError("Erro ao criar pasta '$dir'\n");
				}
			}
			if (file_put_contents($file, $html)) {
				echo "Arquivo salvo '$file'";
			} else {
				showError("Erro ao salvar arquivo '$file'\nAs possíveis causas são falta de permissão de gravação ou caminho de arquivo incorreto!");
			}
		} else {
			showError('O nome do arquivo está vazio!');
		}
	} else {
		showError('O conteúdo HTML está vazio!');
	}
}
?>

 

Explicação

  1. Função copyDirectory: Essa função copia recursivamente todos os arquivos e subdiretórios de um diretório fonte para um diretório destino.
     
  2. Modificação do processamento do template: Adicionado o código para copiar a estrutura do diretório do template para o destino especificado.
     

Com essas alterações, quando você selecionar um template e criar uma nova página, todo o conteúdo do diretório do template (CSS, JS, imagens, etc.) será copiado para a nova localização.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Um adendo: tente programar códigos complexos, no mínimo, utilizando somente programação funcional e não misture com programação procedural.

https://www.alura.com.br/artigos/programacao-funcional-o-que-e

Exemplo:

<?php

define('MAX_FILE_LIMIT', 1024 * 1024 * 2); // Tamanho máximo de arquivo HTML de 2 megabytes
define('ALLOW_PHP', false); // Verifique se o html salvo contém tag php e não salve se não for permitido
define('ALLOWED_OEMBED_DOMAINS', [
    'https://www.youtube.com/', 
    'https://www.vimeo.com/', 
    'https://www.twitter.com/'
]); // Carregar URLs apenas de sites permitidos para oembed

// Função pura
function sanitizeFileName($file, $allowedExtension = 'html') {
    $basename = basename($file);
    $disallow = ['.htaccess', 'passwd'];
    if (in_array($basename, $disallow)) {
        showError('Nome de arquivo não permitido!');
        return '';
    }

    $file = preg_replace('@\?.*$@' , '', preg_replace('@\.{2,}@' , '', preg_replace('@[^\/\\a-zA-Z0-9\-\._]@', '', $file)));

    if ($file) {
        $file = __DIR__ . DIRECTORY_SEPARATOR . $file;
    } else {
        return '';
    }

    if ($allowedExtension) {
        $file = preg_replace('/\.[^.]+$/', '', $file) . ".$allowedExtension";
    }
    return $file;
}

// Função pura
function showError($error) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
    die($error);
}

// Função de alta ordem (recebe uma função como argumento)
function validOembedUrl($url) {
    return array_reduce(ALLOWED_OEMBED_DOMAINS, function($valid, $domain) use ($url) {
        return $valid || strpos($url, $domain) === 0;
    }, false);
}

// Função pura
function copyDirectory($src, $dst) {
    $dir = opendir($src);
    @mkdir($dst);
    while (false !== ($file = readdir($dir))) {
        if (($file != '.') && ($file != '..')) {
            if (is_dir($src . '/' . $file)) {
                copyDirectory($src . '/' . $file, $dst . '/' . $file);
            } else {
                copy($src . '/' . $file, $dst . '/' . $file);
            }
        }
    }
    closedir($dir);
}

// Função de alta ordem (recebe uma função como argumento)
function processAction($action, $data) {
    $actions = [
        'rename' => function($data) {
            $newfile = sanitizeFileName($data['newfile']);
            if ($data['file'] && $newfile) {
                if (rename($data['file'], $newfile)) {
                    echo "Arquivo '{$data['file']}' renomeado para '$newfile'";
                } else {
                    showError("Erro ao renomear arquivo '{$data['file']}' para '$newfile'");
                }
            }
        },
        'delete' => function($data) {
            if ($data['file']) {
                if (unlink($data['file'])) {
                    echo "Arquivo '{$data['file']}' excluído";
                } else {
                    showError("Erro ao excluir arquivo '{$data['file']}'");
                }
            }
        },
        'saveReusable' => function($data) {
            $type = $data['type'] ?? false;
            $name = $data['name'] ?? false;
            $html = $data['html'] ?? false;
            
            if ($type && $name && $html) {
                $file = sanitizeFileName("$type/$name");
                if ($file) {
                    $dir = dirname($file);
                    if (!is_dir($dir)) {
                        echo "$dir pasta não existe\n";
                        if (mkdir($dir, 0777, true)) {
                            echo "$dir pasta foi criada\n";
                        } else {
                            showError("Erro ao criar pasta '$dir'\n");
                        }
                    }
                    if (file_put_contents($file, $html)) {
                        echo "Arquivo salvo '$file'";
                    } else {
                        showError("Erro ao salvar arquivo '$file'\nAs possíveis causas são falta de permissão de gravação ou caminho de arquivo incorreto!");
                    }
                } else {
                    showError('Nome de arquivo inválido!');
                }
            } else {
                showError("Faltam dados de elementos reutilizáveis!\n");
            }
        },
        'oembedProxy' => function($data) {
            $url = $data['url'] ?? '';
            if (validOembedUrl($url)) {
                header('Content-Type: application/json');
                echo file_get_contents($url);
            } else {
                showError('URL inválida!');
            }
        }
    ];

    if (isset($actions[$action])) {
        $actions[$action]($data);
    } else {
        showError("Ação inválida '$action'!");
    }
}

$html = '';
$file = '';
$action = '';

if (isset($_POST['startTemplateUrl']) && !empty($_POST['startTemplateUrl'])) {
    $startTemplateUrl = sanitizeFileName($_POST['startTemplateUrl']);
    if ($startTemplateUrl) {
        $templateDir = dirname($startTemplateUrl);
        $targetDir = __DIR__ . '/Projetos/' . sanitizeFileName($_POST['folder']);
        copyDirectory($templateDir, $targetDir);
        $html = file_get_contents($startTemplateUrl);
    }
} else if (isset($_POST['html'])) {
    $html = substr($_POST['html'], 0, MAX_FILE_LIMIT);
    if (!ALLOW_PHP) {
        if (preg_match('@<\?php|<\? |<\?=|<\s*script\s*language\s*=\s*"\s*php\s*"\s*>@', $html)) {
            showError('PHP não permitido!');
        }
    }
}

if (isset($_POST['file'])) {
    $file = sanitizeFileName($_POST['file']);
}

if (isset($_GET['action'])) {
    $action = htmlspecialchars(strip_tags($_GET['action']));
}

if ($action) {
    processAction($action, ['file' => $file, 'newfile' => $_POST['newfile'] ?? '', 'type' => $_POST['type'] ?? '', 'name' => $_POST['name'] ?? '', 'html' => $_POST['html'] ?? '', 'url' => $_GET['url'] ?? '']);
} else {
    if ($html) {
        if ($file) {
            $dir = dirname($file);
            if (!is_dir($dir)) {
                echo "$dir pasta não existe\n";
                if (mkdir($dir, 0777, true)) {
                    echo "$dir pasta foi criada\n";
                } else {
                    showError("Erro ao criar pasta '$dir'\n");
                }
            }
            if (file_put_contents($file, $html)) {
                echo "Arquivo salvo '$file'";
            } else {
                showError("Erro ao salvar arquivo '$file'\nAs possíveis causas são falta de permissão de gravação ou caminho de arquivo incorreto!");
            }
        } else {
            showError('O nome do arquivo está vazio!');
        }
    } else {
        showError('O conteúdo HTML está vazio!');
    }
}
?>

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Abaixo um exemplo de funções mais microgerenciadas, com documentação indicando se cada função é uma função pura ou não:

 

<?php

define('MAX_FILE_LIMIT', 1024 * 1024 * 2); // Tamanho máximo de arquivo HTML de 2 megabytes
define('ALLOW_PHP', false); // Verifique se o html salvo contém tag php e não salve se não for permitido
define('ALLOWED_OEMBED_DOMAINS', [
    'https://www.youtube.com/', 
    'https://www.vimeo.com/', 
    'https://www.twitter.com/'
]); // Carregar URLs apenas de sites permitidos para oembed

/**
 * Sanitiza o nome do arquivo.
 * Função pura.
 */
function sanitizeFileName($file, $allowedExtension = 'html') {
    $basename = getBaseName($file);
    if (isDisallowedFile($basename)) {
        showError('Nome de arquivo não permitido!');
        return '';
    }

    $file = sanitizeFilePath($file);
    if ($file) {
        $file = __DIR__ . DIRECTORY_SEPARATOR . $file;
    } else {
        return '';
    }

    if ($allowedExtension) {
        $file = addAllowedExtension($file, $allowedExtension);
    }
    return $file;
}

/**
 * Retorna o nome base do arquivo.
 * Função pura.
 */
function getBaseName($file) {
    return basename($file);
}

/**
 * Verifica se o arquivo é um dos arquivos não permitidos.
 * Função pura.
 */
function isDisallowedFile($basename) {
    $disallow = ['.htaccess', 'passwd'];
    return in_array($basename, $disallow);
}

/**
 * Sanitiza o caminho do arquivo.
 * Função pura.
 */
function sanitizeFilePath($file) {
    return preg_replace('@\?.*$@', '', preg_replace('@\.{2,}@', '', preg_replace('@[^\/\\a-zA-Z0-9\-\._]@', '', $file)));
}

/**
 * Adiciona a extensão permitida ao arquivo.
 * Função pura.
 */
function addAllowedExtension($file, $allowedExtension) {
    return preg_replace('/\.[^.]+$/', '', $file) . ".$allowedExtension";
}

/**
 * Exibe uma mensagem de erro e encerra a execução.
 * Função pura.
 */
function showError($error) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
    die($error);
}

/**
 * Verifica se a URL é permitida para oEmbed.
 * Função de alta ordem.
 */
function validOembedUrl($url) {
    return array_reduce(ALLOWED_OEMBED_DOMAINS, fn($valid, $domain) => $valid || strpos($url, $domain) === 0, false);
}

/**
 * Copia o diretório fonte para o diretório de destino.
 * Função não pura (opera no sistema de arquivos).
 */
function copyDirectory($src, $dst) {
    $dir = openDirectory($src);
    createDirectory($dst);
    while (false !== ($file = readDirectory($dir))) {
        if (isNotSpecialDir($file)) {
            $srcFilePath = $src . '/' . $file;
            $dstFilePath = $dst . '/' . $file;
            if (isDirectory($srcFilePath)) {
                copyDirectory($srcFilePath, $dstFilePath);
            } else {
                copyFile($srcFilePath, $dstFilePath);
            }
        }
    }
    closeDirectory($dir);
}

/**
 * Abre um diretório.
 * Função não pura (opera no sistema de arquivos).
 */
function openDirectory($path) {
    return opendir($path);
}

/**
 * Cria um diretório.
 * Função não pura (opera no sistema de arquivos).
 */
function createDirectory($path) {
    return @mkdir($path);
}

/**
 * Lê um diretório.
 * Função não pura (opera no sistema de arquivos).
 */
function readDirectory($dir) {
    return readdir($dir);
}

/**
 * Verifica se o arquivo não é um diretório especial (. ou ..).
 * Função pura.
 */
function isNotSpecialDir($file) {
    return ($file != '.' && $file != '..');
}

/**
 * Verifica se o caminho é um diretório.
 * Função não pura (opera no sistema de arquivos).
 */
function isDirectory($path) {
    return is_dir($path);
}

/**
 * Copia um arquivo de origem para o destino.
 * Função não pura (opera no sistema de arquivos).
 */
function copyFile($src, $dst) {
    return copy($src, $dst);
}

/**
 * Fecha um diretório.
 * Função não pura (opera no sistema de arquivos).
 */
function closeDirectory($dir) {
    closedir($dir);
}

/**
 * Processa as ações com base no tipo de ação.
 * Função de alta ordem.
 */
function processAction($action, $data) {
    $actions = [
        'rename' => function($data) {
            $newfile = sanitizeFileName($data['newfile']);
            if ($data['file'] && $newfile) {
                if (rename($data['file'], $newfile)) {
                    echo "Arquivo '{$data['file']}' renomeado para '$newfile'";
                } else {
                    showError("Erro ao renomear arquivo '{$data['file']}' para '$newfile'");
                }
            }
        },
        'delete' => function($data) {
            if ($data['file']) {
                if (unlink($data['file'])) {
                    echo "Arquivo '{$data['file']}' excluído";
                } else {
                    showError("Erro ao excluir arquivo '{$data['file']}'");
                }
            }
        },
        'saveReusable' => function($data) {
            $type = $data['type'] ?? false;
            $name = $data['name'] ?? false;
            $html = $data['html'] ?? false;
            
            if ($type && $name && $html) {
                $file = sanitizeFileName("$type/$name");
                if ($file) {
                    $dir = dirname($file);
                    if (!is_dir($dir)) {
                        echo "$dir pasta não existe\n";
                        if (mkdir($dir, 0777, true)) {
                            echo "$dir pasta foi criada\n";
                        } else {
                            showError("Erro ao criar pasta '$dir'\n");
                        }
                    }
                    if (file_put_contents($file, $html)) {
                        echo "Arquivo salvo '$file'";
                    } else {
                        showError("Erro ao salvar arquivo '$file'\nAs possíveis causas são falta de permissão de gravação ou caminho de arquivo incorreto!");
                    }
                } else {
                    showError('Nome de arquivo inválido!');
                }
            } else {
                showError("Faltam dados de elementos reutilizáveis!\n");
            }
        },
        'oembedProxy' => function($data) {
            $url = $data['url'] ?? '';
            if (validOembedUrl($url)) {
                header('Content-Type: application/json');
                echo file_get_contents($url);
            } else {
                showError('URL inválida!');
            }
        }
    ];

    if (isset($actions[$action])) {
        $actions[$action]($data);
    } else {
        showError("Ação inválida '$action'!");
    }
}

$html = '';
$file = '';
$action = '';

if (isset($_POST['startTemplateUrl']) && !empty($_POST['startTemplateUrl'])) {
    $startTemplateUrl = sanitizeFileName($_POST['startTemplateUrl']);
    if ($startTemplateUrl) {
        $templateDir = dirname($startTemplateUrl);
        $targetDir = __DIR__ . '/Projetos/' . sanitizeFileName($_POST['folder']);
        copyDirectory($templateDir, $targetDir);
        $html = file_get_contents($startTemplateUrl);
    }
} else if (isset($_POST['html'])) {
    $html = substr($_POST['html'], 0, MAX_FILE_LIMIT);
    if (!ALLOW_PHP) {
        if (containsPHP($html)) {
            showError('PHP não permitido!');
        }
    }
}

if (isset($_POST['file'])) {
    $file = sanitizeFileName($_POST['file']);
}

if (isset($_GET['action'])) {
    $action = sanitizeAction($_GET['action']);
}

if ($action) {
    processAction($action, [
        'file' => $file,
        'newfile' => $_POST['newfile'] ?? '',
        'type' => $_POST['type'] ?? '',
        'name' => $_POST['name'] ?? '',
        'html' => $_POST['html'] ?? '',
        'url' => $_GET['url'] ?? ''
    ]);
} else {
    if ($html) {
        if ($file) {
            if (!is_dir($dir = dirname($file))) {
                echo "$dir pasta não existe\n";
                if (!mkdir($dir, 0777, true)) {
                    showError("Erro ao criar pasta '$dir'\n");
                }
            }
            if (file_put_contents($file, $html)) {
                echo "Arquivo salvo '$file'";
            } else {
                showError("Erro ao salvar arquivo '$file'\nAs possíveis causas são falta de permissão de gravação ou caminho de arquivo incorreto!");
            }
        } else {
            showError('O nome do arquivo está vazio!');
        }
    } else {
        showError('O conteúdo HTML está vazio!');
    }
}

/**
 * Verifica se o conteúdo contém PHP.
 * Função pura.
 */
function containsPHP($html) {
    return preg_match('@<\?php|<\? |<\?=|<\s*script\s*language\s*=\s*"\s*php\s*"\s*>@', $html);
}

/**
 * Sanitiza a ação recebida via GET.
 * Função pura.
 */
function sanitizeAction($action) {
    return htmlspecialchars(strip_tags($action));
}
?>

Explicações das Funções:

  1. sanitizeFileName: Sanitiza o nome do arquivo. Função pura.
  2. getBaseName: Retorna o nome base do arquivo. Função pura.
  3. isDisallowedFile: Verifica se o arquivo é um dos arquivos não permitidos. Função pura.
  4. sanitizeFilePath: Sanitiza o caminho do arquivo. Função pura.
  5. addAllowedExtension: Adiciona a extensão permitida ao arquivo. Função pura.
  6. showError: Exibe uma mensagem de erro e encerra a execução. Função pura.
  7. validOembedUrl: Verifica se a URL é permitida para oEmbed. Função de alta ordem.
  8. copyDirectory: Copia o diretório fonte para o diretório de destino. Função não pura.
  9. openDirectory: Abre um diretório. Função não pura.
  10. createDirectory: Cria um diretório. Função não pura.
  11. readDirectory: Lê um diretório. Função não pura.
  12. isNotSpecialDir: Verifica se o arquivo não é um diretório especial (. ou ..). Função pura.
  13. isDirectory: Verifica se o caminho é um diretório. Função não pura.
  14. copyFile: Copia um arquivo de origem para o destino. Função não pura.
  15. closeDirectory: Fecha um diretório. Função não pura.
  16. processAction: Processa as ações com base no tipo de ação. Função de alta ordem.
  17. containsPHP: Verifica se o conteúdo contém PHP. Função pura.
  18. sanitizeAction: Sanitiza a ação recebida via GET. Função pura.

Este código agora está mais modularizado com funções microgerenciadas, facilitando a leitura e manutenção, além de seguir princípios de programação funcional onde aplicável.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora

  • Conteúdo Similar

    • Por violin101
      Caros amigos, saudações.
       
      Estou com uma pequena dúvida.
       
      Estou escrevendo um Sistema que tem vários Módulos.
       
      O módulo principal tem:
      Estoque | Compras | Expedição | Vendas

      Minha dúvida:
      como faço após Acessar o Módulo Principal e Escolher o Módulo que quero trabalhar,
      eu possa fechar o Módulo aberto por exemplo: Estoque, sem alterar o Módulo principal e outros se estiver aberto ?


      Grato,
       
      Cesar
    • Por douglas79
      Bom dia,

      Há alguns dias que venho instalar o apache, o php, mysql e o phpmyadmin manualmente e sem obter sucesso. Até consegui rodar o php, porém, quando vou baixar a úitima versão do MYSQL, não tem todos os pacotes nele instalados, inclusive no completo, só encontro o Router.
      Alguém pode me dizer o porquê que isso está ocorrendo?
      Desde já agradeço a ajuda de vocês, que será bem vinda!
      No aguardo!

      Uso a versão 8.3.9 do PHP
      Meu SO é o Windows 10 32 bits
    • Por violin101
      Caros amigos, saudações.
       
      Por favor, me perdoa em postar mais uma dúvida minha.

      Através de ajuda e orientação dos membros do Grupo, tenho conseguido resolver muitos problemas que tenho encontrado.
       
      Gostaria de saber dos amigos do grupo, se tem algum vídeo aula, orientando a Instalação das Biblioteca para Emissão de Nota Fiscal Eletrônica.
       
      Tenho feito várias busca e tenho encontrado a maioria das vezes tudo em LARAVEL.

      Sei que para instalar as Biblioteca, precisa do Composer, até aqui tudo bem.

      Minha dúvida: 
      após fazer o download da  sped-nfe  e  sped-da, essas biblioteca devem ser gravada em qual pasta ?  ----   na C:\  ou dentro da pasta do Sistema ?
      quando dou o comando: COMPOSER INSTALL esse comando já instala todas as bibliotecas, ou 1 por 1 ?

      Grato,
       
      Cesar
       
    • Por violin101
      Caros amigos, saudações.

      Estou com uma dúvida e gostaria do auxílio dos amigos.
       
      Gostaria de após o usuário digitar o Número do Pedido/Orçamento o Sistema Importa todos os Dados para a Entrada/Venda de Produtos.
       
      Exemplo:
      Pedido n.102 com os itens:
        10 un Produto X - vr_unit: 5.00
        05 un Produto Y - vr_unit: 3.00
        03 un Produto Z - vr_unit: 1.50
       
      Importar para Entrada/Venda
      Venda n.1001
      |__> como importo os dados do Pedido n.102 de uma só vez ?
       
      Grato,
       
      Cesar
    • Por violin101
      Caros amigos, saudações.
       
      Tenho uma tabela em HTML, que me traz as informações de parcelamento corretamente.
       
      Preciso fazer uma validação, mas quando tento somar a coluna que traz valor, a soma faz errada.
       
      Como devo fazer para SOMAR a coluna mostrando as casas decimais ?

      a tabela está assim:
      success: function(parcelas) { const tbody = $("#tbparcs tbody"); tbody.empty(); // Limpa a tabela antes de adicionar novas linhas parcelas.forEach(function(parcela) { let html = "<tr>"; html += "<td width='20%' height='10'style='text-align:center;'><input type='date' name='dtaprc[]' class='form-control d-none' value='"+dateSQL(parcela.data_vencimento)+"'><span>"+parcela.data_vencimento+"</span></td>"; <!--Quero somar essa coluna --> html += "<td width='50%' height='10' style='text-align:center;'><input type='text' name='vlrprc[]' class='form-control d-none' value='"+parcela.valor_parcela+"' oninput='formatNumber(this)'><span>"+parcela.valor_parcela+"</span></td>"; html += "<td width='15%' height='10' style='text-align:center;'>"+ "<button onclick='editarCelulaParcelamento(this)' type='button' class='btn btn-primary btn-editar-parc' style='margin-right: 1%; padding: 1px 2px;' title='Editar'>"+ "<i class='fa fa-edit'></i></button>"+ "<button type='button' data-save class='btn btn-success btn-salvar-parc' style='margin-right: 1%; padding: 1px 5px;' title='Salvar'>"+ "<i class='fa fa-save'></i></button>"+ "</td>"; html += "</tr>"; tbody.append(html); somarparcelas(); }); }  
      a função para somar a coluna está assim:
       
      //Função somar Total da Tabela function somarparcelas(){ parcelastotal = 0; //Preenche o INPUT do parcelastotal $("#tbparcs tbody tr").each(function(){ parcelastotal = parcelastotal + parseFloat($(this).find("td:eq(1)").text()); }); $("input[name=parcelastotal]").val(parcelastotal.toFixed(2)); } //o problema que estou encontrando está no parseFloat. //o parseFloat traz: 12 e não 12.57  
       
      Grato,
       
      Cesar
       
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.