Jump to content

POWERED BY:

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.... 

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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!');
    }
}
?>

 

Share this post


Link to post
Share on other 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.

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

  • Similar Content

    • By violin101
      Caros amigos, saudações.
       
      Humildemente peço desculpa por postar uma dúvida que tenho.

      Preciso salvar no MySql, os seguinte Registro:

      1 - Principal
      ====> minha dúvida começa aqui
      ==========> como faço para o Sistema Contar Automaticamente o que estiver despois do 1.____?
      1.01 - Matriz
      1.01.0001 - Estoque
      1.01.0002 - Oficina
      etc

      2 - Secundário
      2.01 - Loja_1
      2.01.0001 - Caixa
      2.01.0002 - Recepção
      etc
       
      Resumindo seria como se fosse um Cadastro de PLANO de CONTAS CONTÁBEIL.

      Grato,


      Cesar









       
    • By violin101
      Caros amigos, saudações.

      Por favor, me perdoa em recorrer a orientação dos amigos.

      Preciso fazer um Relatório onde o usuário pode Gerar uma Lista com prazo para vencimento de: 15 / 20/ 30 dias da data atual.

      Tem como montar uma SQL para o sistema fazer uma busca no MySql por período ou dias próximo ao vencimento ?

      Tentei fazer assim, mas o SQL me traz tudo:
      $query = "SELECT faturamento.*, DATE_ADD(faturamento.dataVencimento, INTERVAL 30 DAY), fornecedor.* FROM faturamento INNER JOIN fornecedor ON fornecedor.idfornecedor = faturamento.id_fornecedor WHERE faturamento.statusFatur = 1 ORDER BY faturamento.idFaturamento $ordenar ";  
      Grato,
       
      Cesar
       
       
       
       
    • By violin101
      Caros amigos, saudações
       
      Por favor, me perdoa em recorrer a orientação dos amigos, tenho uma dúvida.
       
      Gostaria de uma rotina onde o Sistema possa acusar para o usuário antes dos 30 dias, grifar na Tabela o aviso de vencimento próximo, por exemplo:
       
      Data Atual: 15/11/2024
                                           Vencimento
      Fornecedor.....................Data.....................Valor
      Fornecedor_1...........01/12/2024..........R$ 120,00 <== grifar a linha de Laranja
      Fornecedor_1...........01/01/2025..........R$ 130,00
      Fornecedor_2...........15/12/2024..........R$ 200,00 <== grifar a linha de Amarelo
      Fornecedor_2...........15/01/2025..........R$ 230,00
      Fornecedor_3...........20/12/2024..........R$ 150,00
       
      Alguém tem alguma dica ou leitura sobre este assunto ?

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

      Por favor, me perdoa em recorrer a ajuda dos amigos, mas preciso entender uma processo que não estou conseguindo sucesso.

      Como mencionado no Título estou escrevendo um Sistema Web para Gerenciamento de Empresa.
       
      Minha dúvida, que preciso muito entender:
      - preciso agora escrever a Rotina para Emissão de NFe e essa parte não estou conseguindo.
       
      tenho assistido alguns vídeos e leituras, mas não estou conseguindo sucesso, já fiz toda as importações das LIB da NFePhp conforme orientação.

      Preciso de ajuda.

      Algum dos amigos tem conhecimento de algum passo-a-passo explicando a criação dessa rotina ?

      tenho visto alguns vídeos com LARAVEL, mas quando tento utilizar e converter para PHP+Codeiginter, dá uma fila de erros que não entendo, mesmo informando as lib necessárias.

      Alguns do amigo tem algum vídeo, leitura explicando essa parte ?

      Grato,

      Cesar.
    • By violin101
      Caros amigos, saudações.

      Por favor, me perdoa em recorrer ao auxílio dos amigos, mas preciso entender e resolver um problema.
       
      Tenho uma Rotina que o usuário seleciona os produtos que deseja para requerer ao setor responsável.
       
      O usuário escolhe um produto qualquer e Clicla em um button para incluir a lista.

      O problema que estou enfrentando é que após escolher o produto e teclar ENTER o Sistema já salva no BD.
       
      Gostaria de criar uma Tecla de Atalho, para quando incluir/escolher o produto na lista, o usuário tecla como exemplo:
      ALT+A  para agregar a lista
      ALT+S para salvar a lista de itens desejados.

      Assim, quando teclar enter, o sistema não dispara o GRAVAR na Base de Dados.

      Grato,

      Cesar
       
       
       
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.