Objetivo
Criar custom directive para componentes
Plataforma
Quasar Framework e VueJs
Conhecimento
Quasar Framework e VueJs
Introdução
Alguns funções são necessárias em vários componentes no Quasar/VueJs. Uma alternativa à criação de componentes é utilizar directive.
Solução
Para implementar no Quasar é preciso criar um arquivo no diretório “boot”. No meu caso criei o arquivo “directive.js”.
export default ({ Vue }) => {
Vue.directive('uppercase', {
bind (el, _, vnode) {
el.addEventListener('input', (e) => {
e.target.value = e.target.value.toUpperCase()
vnode.componentInstance.$emit('input', e.target.value.toUpperCase())
})
}
})
}
No “quasar.conf.js” incluir no array de boot files o nome do seu arquivo.
boot: [
‘..’,
‘..’,
‘directives’
],
É preciso utiliza o prefixo “v-” para utilizar a directive. No componente ficará
<q-input
outlined
v-model="data.SeuModel"
v-uppercase
label="Código"
/>
Objetivo
Proteger o acesso a uma URL através do Nginx
Plataforma
Linux, Nginx
Conhecimento
Linux, NGinx, MD5 e PHP
Introdução
Há varias formas de implementar um controle de acesso, um controle é fazer direto no servidor de aplicação
Solução
Para implementar a segurança no servidor de aplicação Nginx uma solução é utilizar o secure link module para utilizar na instalação atráves do gerenciador do pacote ou no ./configure utilizar o --with-http_secure_link_module
No config o location protegido deve seguir o código abaixo
location /secureurl/ {
.
.
.
secure_token $args;
secure_link_md5 "$secure_link_expires$uri$remote_addr secret";
if ($secure_link = "") {
return 403;
}
if ($secure_link = 0) {
return 410;
}
.
.
.
}
Para gerar a URL válida segue o código
<?php
/**
* @param $baseUrl - non protected part of the URL including hostname, e.g. http://example.com
* @param $path - protected path to the file, e.g. /downloads/myfile.zip
* @param $secret - the shared secret with the nginx server. Keep this info secure!!!
* @param $ttl - the number of seconds until this link expires
* @param $userIp - ip of the user allowed to download
* @return string
*/
function buildSecureLink($baseUrl, $path, $secret, $ttl, $userIp)
{
$expires = time() + $ttl;
$md5 = md5("$expires$path$userIp $secret", true);
$md5 = base64_encode($md5);
$md5 = strtr($md5, '+/', '-_');
$md5 = str_replace('=', '', $md5);
return $baseUrl . $path . '?md5=' . $md5 . '&expires=' . $expires;
}
// example usage
$secret = 'secret';
$baseUrl = 'http://127.0.0.1';
$path ='/file/myfile';
$ttl = 1000;//no of seconds this link is active
$userIp = '127.0.0.1';//normally you would read this from something like $_SERVER['REMOTE_ADDR'];
echo buildSecureLink($baseUrl, $path, $secret, $ttl, $userIp);
Objetivo
Ativar certificado digital para múltiplos subdomínios no servidor Nginx
Plataforma
Let’s Encrypt, Linux e Nginx
Conhecimento
Linux e NGinx
Introdução
Muitas vezes ativamos certificado digital só para o domínio principal e para domínio principal com www. Quando a aplicação cresce precisamos de certificado digital para os subdomínios também.
Solução
A solução é o utilizar o Certbot para gerar as chaves para nosso domínio.
sudo certbot --server https://acme-v02.api.letsencrypt.org/directory -d *.YOUR_SITE_HERE.com.br -d YOUR_SITE_HERE.com.br --manual --preferred-challenges dns-01 certonly Saving debug log to /var/log/letsencrypt/letsencrypt.log Connection to _______ closed. Plugins selected: Authenticator manual, Installer None Obtaining a new certificate Performing the following challenges: dns-01 challenge for YOUR_SITE_HERE.com.br - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running certbot in manual mode on a machine that is not your server, please ensure you're okay with that. Are you OK with your IP being logged? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: y - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please deploy a DNS TXT record under the name _acme-challenge.YOUR_SITE_HERE.com.br with the following value: CODE_HASH HERE
Neste passo é preciso editar o seu DNS TXT com o domínio _acme-challenge.YOUR_SITE_HERE.com.br e o Hash gerado. Como a imagem abaixo. É preciso lembrar que é preciso propagar a informação do DNS para continuar.
Assim que passar o tempo da propagação pode continuar a execução.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/YOUR_SITE_HERE.com.br-0001/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/YOUR_SITE_HERE.com.br-0001/privkey.pem
Your cert will expire on 2018-10-22. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
rafael@Principal:~$
Então é preciso editar as configuração do servidor e substituir a linha onde tem o caminho do certificado
ssl_certificate /etc/letsencrypt/live/YOUR_SITE_HERE.com.br-0001/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/YOUR_SITE_HERE.com.br-0001/privkey.pem;
Após isso é preciso reiniciar o servidor
rafael@Principal:~$ sudo service nginx restart
Objetivo
Fazer usuários reiniciar serviço sem senha
Plataforma
Ubuntu
Conhecimento
Linux
Introdução
Para tarefas automatizadas algumas ações podem ser simplificadas ao ponto de serem executado sem qualquer proteção.
Solução
Para facilitar daremos a um usuário comum a permissão de executar o reinicio do serviço do NGinx.
sudo visudo #Ir até o final do arquivo e inserir a linha abaixo YOUR_USER_HERE ALL=NOPASSWD: /bin/systemctl restart nginx.service
Objetivo
Redirecionar URL HTTP para HTTPS com Nginx
Plataforma
Linux e Nginx
Conhecimento
Linux
Introdução
Redirecionar seu dominios em HTTP para domínio HTTPS
Solução
A solução é configurar sites-available para redirecionar o tráfego. O sites-enable tem o link simbólico do sites-available.
#redirecionando para https
server {
listen 80;
server_name www.yourdomain.com.br yourdomain.com.br;
return 301 https://yourdomain.com.br$request_uri;
}
#redirecionando para https com www para sem www
server {
listen 443 ssl http2;
access_log off;
error_log off;
server_name www.yourdomain.com.br;
return 301 https://yourdomain.com.br$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name yourdomain.com.br;
root /usr/share/nginx/html/yourdomain/public;
index index.html index.htm index.php;
ssl on;
#server config
.
.
.
}
Objetivo
Utilizar o partition by no Oracle
Plataforma
Oracle SQL Developer
Conhecimento
Oracle SQL Developer e SQL
Introdução
Em um relatório precisei extrair uma sequência de ocorrência. Deparei com o partition by que facilitou minha vida.
Solução
select EQP_COD, count(*) OVER (partition by PES_COD order by PES_COD) countpes , row_number() OVER (partition by PES_COD order by PES_COD ) seq from EQUIPE order by PES_COD
O resultado será para cada equipe da pessoa sua sequência e seu total.
EQP countpes seq TM02 3 1 TM03 3 2 MM02 3 3 MB03 2 1 TB03 2 2 MB05 2 1 TB05 2 2 CO01 1 1
Objetivo
Corrigir erro ao emular um dispositivo Android no Ubuntu 16
Plataforma
linux, android
Conhecimento
linux
Introdução
Emular android é um recurso válida para testar o app em desenvolvimento quanto por alguma razão não é possível utilizar um dispositivo físico.
Ao executar o comando:
~/Android/Sdk/tools$ ./emulator -avd Nexus_5X_API_25
O retorno será:
libGL error: unable to load driver: i965_dri.so libGL error: driver pointer missing libGL error: failed to load driver: i965 libGL error: unable to load driver: i965_dri.so libGL error: driver pointer missing libGL error: failed to load driver: i965 libGL error: unable to load driver: swrast_dri.so libGL error: failed to load driver: swrast X Error of failed request: GLXBadContext Major opcode of failed request: 155 (GLX) Minor opcode of failed request: 6 (X_GLXIsDirect) Serial number of failed request: 55 Current serial number in output stream: 54 ...
O que precisará ser feito é substituição de uma biblioteca.
$ cd ~/Android/Sdk/emulator/lib64/libstdc++ $ mv libstdc++.so.6 libstdc++.so.6.bak $ ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6 libstdc++.so.6
Boa codificação
Objetivo
Envio de email com template através do ZF2
Plataforma
Linux, ZF2
Conhecimento
ZF2, SMTP
Introdução
Em plataformas web é necessário envio email para seus usuários e clientes. A comunicação com seus usuários e clientes com identidade visual é importante.
Portanto o envio de email com template é essencial.
Solução
Eu criei uma classe como serviço no ZF2. Criei o método abaixo.
public function sendTemplatedGenericEmail() {
$view = new \Zend\View\Renderer\PhpRenderer();
$resolver = new \Zend\View\Resolver\TemplateMapResolver();
$resolver->setMap([
'mailTemplate' => __DIR__ . "/../../../../Application/view/layout/{$this->getTemplate()}.phtml"
]);
$view->setResolver($resolver);
$viewModel = new ViewModel();
$viewModel->setTemplate('mailTemplate')->setVariables([
'username' => $this->getUsername(),
'userid' => $this->getUserid(),
'subject' => $this->getSubject(),
]);
$bodyPart = new \Zend\Mime\Message();
$bodyMessage = new \Zend\Mime\Part($view->render($viewModel));
$bodyMessage->type = 'text/html';
$bodyPart->setParts(array($bodyMessage));
$message = new \Zend\Mail\Message();
$message->setBody($bodyPart);
$message->setFrom('***psipsi.com.br', 'PsiPsi Info');
$message->addTo($this->getToemail());
$message->addBcc('****gmail.com');
$message->setSubject($this->getSubject());
$smtpOptions = new \Zend\Mail\Transport\SmtpOptions();
$smtpOptions->setHost('******.com')
->setConnectionClass('login')
->setName('*******')
->setPort('999')
->setConnectionConfig([
'username' => '****psipsi.com.br',
'password' => '*******',
'ssl' => 'tls',
]);
$transport = new \Zend\Mail\Transport\Smtp($smtpOptions);
$transport->send($message);
}
Esse trecho seta o template a ser usado. O getter $this->getTemplate() pega o nome do meu template.
$view = new \Zend\View\Renderer\PhpRenderer();
$resolver = new \Zend\View\Resolver\TemplateMapResolver();
$resolver->setMap([
'mailTemplate' => __DIR__ . "/../../../../Application/view/layout/{$this->getTemplate()}.phtml"
]);
$view->setResolver($resolver);
Neste trecho é setado as variáveis, tais como o nome e o assunto do email.
$viewModel = new ViewModel();
$viewModel->setTemplate('mailTemplate')->setVariables([
'username' => $this->getUsername(),
'userid' => $this->getUserid(),
'subject' => $this->getSubject(),
]);
Passamos o nosso template para o corpo do email
$bodyPart = new \Zend\Mime\Message(); $bodyMessage = new \Zend\Mime\Part($view->render($viewModel)); $bodyMessage->type = 'text/html'; $bodyPart->setParts(array($bodyMessage));
É finalizado o email com as informações faltantes para o email. Os getter: $this->getToemail(), $this->getSubject() fazem o trabalho de preencher.
$message = new \Zend\Mail\Message();
$message->setBody($bodyPart);
$message->setFrom('***psipsi.com.br', 'PsiPsi Info');
$message->addTo($this->getToemail());
$message->addBcc('****gmail.com');
$message->setSubject($this->getSubject());
Configuração do SMTP e envio.
$smtpOptions = new \Zend\Mail\Transport\SmtpOptions();
$smtpOptions->setHost('******.com')
->setConnectionClass('login')
->setName('******.com')
->setPort('999')
->setConnectionConfig([
'username' => '****psipsi.com.br',
'password' => '*******',
'ssl' => 'tls',
]);
$transport = new \Zend\Mail\Transport\Smtp($smtpOptions);
$transport->send($message);
O suporte a classes anônimas foi adicionado utilizando new class. Isso pode ser utilizado no lugar de definições completas de classes para objetos descartáveis.
<?php interface Logger { public function log(string $msg); } class Application { private $logger; public function getLogger(): Logger { return $this->logger;
}
public function setLogger(Logger $logger) {
$this->logger = $logger;
}
}
$app = new Application;
$app->setLogger(new class implements Logger {
public function log(string $msg) {
echo $msg;
}
});
var_dump($app->getLogger());
?>
O exemplo acima irá imprimir:
object(class@anonymous)#2 (0) {
}
A documentação completa pode ser encontrada na referência de classes anônimas.
O PHP 7 adiciona o suporte a declarações de tipo de retorno. Similar as declarações de tipo de argumento, as declarações de tipo de retorno especificam o tipo do valor que será retornado por uma função. Os mesmos tipos estão disponíveis para declarações de tipo de retorno, assim como para declarações para tipo de argumentos.
<?php
function arraysSum(array ...$arrays): array
{
return array_map(function(array $array): int {
return array_sum($array);
}, $arrays);
}
print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));
O exemplo acima irá imprimir:
Array
(
[0] => 6
[1] => 15
[2] => 24
)
A documentação completa, assim como exemplos de declarações de tipo de retorno pode ser encontrada na referencia declarações de tipo de retorno.

