| Current Path : /var/www/html/libraries/noboss/ |
| Current File : /var/www/html/libraries/noboss/script.library.php |
<?php
/**
* @package No Boss Extensions
* @subpackage No Boss Library
* @author No Boss Technology <contact@nobosstechnology.com>
* @copyright Copyright (C) 2026 No Boss Technology. All rights reserved.
* @license GNU Lesser General Public License version 3 or later; see <https://www.gnu.org/licenses/lgpl-3.0.en.html>
*/
use Joomla\Filesystem\Folder;
use Joomla\CMS\Factory;
use Joomla\Database\DatabaseInterface;
//use Joomla\CMS\Cache\CacheControllerFactoryInterface;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Script de instalação da library utilizada por todas extensoes da No Boss
* - Esse script normalmente é executado após o script de instalacao do pacote
*
* - Formatos para retornar mensagens de erro / warning:
* // Mensagem de erro (fundo vermelho), sem interromper a instalacao
* Factory::getApplication()->enqueueMessage(Text::_("Aqui mensagem"), 'Error');
*
* // Mensagem de warning (fundo amarelo), sem interromper a instalacao
* Factory::getApplication()->enqueueMessage(Text::_("Aqui mensagem"), 'Warning');
*
* // Mensagem de warning (fundo amarelo), interrompendo a instalacao (Joomla tb exibe mensagem de erro da instalacao)
* throw new \RuntimeException(Text::_("Aqui mensagem"));
* return false;
*
*
* - Exemplos de usos do $parent que é recebido como parametro nas funções:
* // Obter nova versao recem instalada
* $parent->get('manifest')->version;
*
* // Obter alias da extensao (Ex: 'mod_nobosscalendar)
* $parent->manifest->name;
*
* // Redirecionar usuario apos a instalacao (interessante usar no metodo install na instalacao de componentes nossos para redirecionar o usuario para a pagina principal do componente apos a instalacao)
* $parent->getParent()->setRedirectURL('index.php?option=com_helloworld');*
*
*
* - Sobre uso de constantes de tradução
* - Se você deseja que as KEYs desses idiomas sejam usadas na primeira instalação do componente, o arquivo de idioma .sys.ini deve ser armazenado na pasta do componente (admin/language/en-GB/en-GB.com_helloworld.sys.ini)
* - Quando ja temos a library instalada, podemos forcar o carregamento do idioma da library e usar as constantes dela
*/
// Necessario para nao dar erro 500 de redeclaracao da classe p/ qnd eh update
if (!class_exists('NobossLibraryInstallerScript')){
class NobossLibraryInstallerScript{
/**
* Metodo executado antes de qualquer outro no processo de instalacao / update
* - Esse é o momento que a instalacao / update pode ser cancelado
* - Antes dessa funcao, apenas o preflight do script de instalacao do pacote é executado
*
* SOBRE PROBLEMA DE REMOÇÃO DA LIBRARY:
* - Quando a library já existe no site, o Joomla remove ela antes de executar qualquer função deste arquivo.
* - Isso ocorre somente com extensões do tipo Library, com os demais tipos de extensao não ocorre.
* - O problema disso é que se não tiver permissões suficientes no site, o Joomla devolve erro na atualização sem explicar o motivo.
* - Em maio de 2021 contornamos esses problemas colocando a instalação da library em um pacote. Desta forma, conseguimos validar as permissões antes do Joomla jogar o erro. Neste caso, exibimos uma mensagem bem explicativa sobre o problema e como resolver.
*
* @param string $type Tipo de intalações (install, update, discover_install)
* @param JInstaller $parent Classe que chama esse metodo (pode acessar funcoes dela)
*
* @return boolean true caso deva ser instalada, false para cancelar a instalação
*/
function preflight($type, $parent){
if($type == 'uninstall'){
return;
}
}
/**
* Metodo executado após o término da instalação / update
*
* @param string $type Tipo de intalações (install, update, discover_install)
* @param JInstaller $parent Classe que chama esse metodo (pode acessar funcoes dela)
*/
// FIXME: nao esta caindo mais nessa funcao e por isso colocamos ela no script de instalacao do pacote
public function postflight($type, $parent){
if($type == 'uninstall'){
return;
}
// $dirLayout = JPATH_SITE.'/layouts/noboss/';
// if (!@is_dir($dirLayout)){
// if (!@mkdir($dirLayout, 0775))
// {
// Folder::create($dirLayout, 0775);
// }
// }
try{
// Move pasta 'layouts/noboss' para local correto
$this->installLayoutsFolder();
} catch (\Exception $e){
// Criado apenas para evitar que o Joomla jogue erro 500 que deixa a library removida caso tenha algum erro nao tratado
Factory::getApplication()->enqueueMessage($e->getMessage(), 'Warning');
}
}
/**
* Metodo executado apos a instalacao
* - Aqui podemos exibir textos fora de notices / warnings utilizanco 'echo' ou html direto
*
* @param JInstaller $parent Classe que chama esse metodo (pode acessar funcoes dela)
*/
function install($parent) {
}
/**
* Metodo executado apos a atualizacao
* - Aqui podemos exibir textos fora de notices / warnings utilizanco 'echo' ou html direto
* - Utilizar tambem para colocar atualizacoes especificas de versoes (Ex: migrar dado no banco de estrutura antiga para nova)
* - Para qual versao foi instalada (usar em alguma condicao), utilize $parent->get('manifest')->version
*
* @param JInstaller $parent Classe que chama esse metodo (pode acessar funcoes dela)
*/
function update($parent) {
}
/**
* Metodo executado apos a desinstalacao
* - Aqui podemos exibir textos fora de notices / warnings utilizanco 'echo' ou html direto
*
* @param JInstaller $parent Classe que chama esse metodo (pode acessar funcoes dela)
*/
public function uninstall($parent){
try{
// Remove a pasta layouts pertencente a library
if(file_exists(JPATH_SITE.'/layouts/noboss')){
Folder::delete(JPATH_SITE.'/layouts/noboss');
}
} catch (\Exception $e){
// Criado apenas para evitar que o Joomla jogue erro 500 que deixa a library removida caso tenha algum erro nao tratado
}
}
/**
* Metodo que verifica se library deve ser instalada
* - Retorna true se nao existe instalada ou se versao esta desatualizada
*
* @return Booelean True para fazer a instalação, false para não fazer
*/
private function isUpdate($parent){
// Diretorio da library nao existe no site
if (!is_dir(JPATH_LIBRARIES . '/noboss')){
return true;
}
// Obtem versao instalada da library no banco de dados
$oldRelease = $this->geManifestCacheDb('version');
// Library nao foi localizada no banco
if(empty($oldRelease)){
return true;
}
// Retorna true se versao existente esta desatualizada
return version_compare( $parent->manifest->version, $oldRelease, '>' );
}
/**
* Metodo que obtem no banco dados em cache da extensao
*
* @param string $name Nome da variável a ler do cache
* @param string $element Representa a extensao que vamos verificar
*
* @return mixed O valor da variavel requerida
*/
function geManifestCacheDb($name, $element='noboss') {
$db = Factory::getContainer()->get(DatabaseInterface::class);
$query = $db->getQuery(true);
$query->select("a.manifest_cache")
->from("#__extensions as a")
->where("element = '{$element}'");
$db->setQuery($query);
// Decoda o json
$manifest = json_decode( $db->loadResult(), true );
// Retorna a variável buscada
return $manifest[$name];
}
/**
* Metodo que move a pasta 'layouts/noboss' para o local correto no Joomla (na instalacao vem dentro da library)
*/
public function installLayoutsFolder(){
$dirLayoutLibrary = JPATH_ROOT.'/libraries/noboss/src/layouts/';
$dirLayout = JPATH_ROOT.'/layouts/noboss/';
// Confirma se a pasta layouts esta criada dentro da library
if(is_dir($dirLayoutLibrary)){
try{
// Copia pasta layouts da library da no boss para a pasta layouts correta
Folder::copy($dirLayoutLibrary, $dirLayout, '', true, true);
// Altera permissao da pasta layouts inserida no site do usuario
@chmod($dirLayout, 0775);
if(is_dir($dirLayoutLibrary)){
// Remove a pasta layouts da library com funcao recursiva robusta
$this->removeDirectory($dirLayoutLibrary);
}
} catch (\Exception $e){
// Seta Warning para exibir na tela
Factory::getApplication()->enqueueMessage('Could not manage layouts directory: ' . $e->getMessage(), 'Warning');
}
}
}
/**
* Remove um diretório e todo o seu conteúdo recursivamente
*
* @param string $dir Caminho absoluto para o diretório a ser removido
* @return bool Retorna true se removido com sucesso, false caso contrário
*/
private function removeDirectory($dir) {
if (!is_dir($dir)) {
return false;
}
$items = @scandir($dir);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item == '.' || $item == '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $item;
// Tenta alterar permissao antes de remover
@chmod($path, 0777);
if (is_dir($path)) {
$this->removeDirectory($path);
} else {
@unlink($path);
}
}
// Tenta alterar permissao do diretorio antes de remover
@chmod($dir, 0777);
return @rmdir($dir);
}
}
}