Blog do Márcio d'Ávila » HTML5 no horizonte
Introdução - Experimentando o Linux Mint Debian Edition
Caso dos boletos imitando Registro.br chegando ao fim?
Vim - Portal brasileiro do editor de textos Vim (VI) :: aurelio.net
Activate Remote Desktop REMOTELY!!! | commandlinefu.com
PHP é à quinta-feira – 50 dicas sobre desempenho e segurança | Peopleware
Howto access ext3 partition from Windows | Ubuntu Geek
This tutorial will allow you to access your ext3 partition under Windows, using Sun VirtualBox and Ubuntu. The tutorial is pretty long due to the images, but they explain things easier sometimes (they are not just meaningless screenshots) (forgive me for your scroll button 😛 )
Upload Pie - The Simple Image Sharing Tool
Sharing files with expiration dates
Gerenciamento de erros
Index of languages being used around the world.
Busca de CEP em PHP, Ajax, PHP, ASP, Java, Python, Flash, XML, C#, Ruby
Color Fading Menu with jQuery | CSS-Tricks
Increase your internet speed with Namebench | Ubuntu Geek
Guia de referência de comando em PT-BR | Ubuntu Dicas
Uma lista com os comandos mais usados no linux em português brasileiro. É possível salvar os comandos em algum imagem para que fique como um papel de parede.
Blog do Márcio d’Ávila » Fraude Surpreendo - Proteja seus dados pessoais
Ripando e Gerando DVDs no Linux de forma simples « jmmwrite – simples e direto
I shouldn't be the first to need to export data from a PostgreSQL database installed on Windows with a win1252 code to a database with UTF-8 code (in my case, on a Linux server).
It is not enough to transform the transfer file to UTF-8, as the characters of win1252 (left double quote, right double quote, single quote and dash) will be there, with a weird value in your database.
In my experience, I had to import data as-is and afterwards perform an update using the function to rewrite data for UTF-8 characters correctly.
The following code examples are for: 1 - transform to HTML characters; 2 - transform to single characters.
HTML:
-- DROP FUNCTION substitui_win1252_html(texto);
CREATE OR REPLACE FUNCTION substitui_win1252_html(texto text)
RETURNS text AS
$$
BEGIN
texto := replace(replace(replace(replace(replace(texto, '', '’'), '', '“'), '', '”'), '','•'), '', '–')::text;
RETURN texto;
END;
$$
LANGUAGE plpgsql;
Simple:
-- DROP FUNCTION substitui_win1252(texto);
CREATE OR REPLACE FUNCTION substitui_win1252(texto text)
RETURNS text AS
$$
BEGIN
texto := replace(replace(replace(replace(replace(texto, '', ''''), '', '"'), '', '"'), '','•'), '', '-')::text;
RETURN texto;
END;
$$
LANGUAGE plpgsql;
Don't worry about the squares that you might see. If you copy it to a good text editor, you will their actual value.
Eficiência e segurança com SQL parametrizado
O uso de comandos SQL, na maioria das linguagens de programação e gerenciadores de bancos de dados que suportam esta linguagem de manipulação de dados, pode ser parametrizado com variáveis de ligação (bind variables). Este recurso que, para um programador desavisado e inexperiente, pode parecer uma burocracia desnecessária, na verdade é um mecanismo muito importante para trazer segurança e eficiência ao uso de SQL em programas. Veja porque e como.
Documentation for preventing SQL injection in PHP projects. Many web developers are unaware of how SQL queries can be handled and assume that an SQL query is a reliable command. It means that SQL queries are able to bypass access controls undetected, therefore bypassing standard authentication and authorization checks, and sometimes SQL queries can allow command access at the server operating system level.
Senhas armazenadas com segurança
Como Criar um Website :: Avi Alkalay
As 5 distribuições que mudaram o Linux
Segundo a chamada deste artigo da edição internacional da Linux Magazine, a história do Linux pode ser medida com base nas versões deste kernel, mas também pode ser medida pelas suas principais distribuições.
MySQL: Oracle assume um compromisso: GPL, documentado, sem contrato de suporte obrigatório, etc.
Scrum - Wikipédia, a enciclopédia livre
O Scrum é uma metodologia ágil para Gerenciamento de Projetos.
CentOS: Instalando mod_security
Spam: CGI.br determina bloqueio da porta 25 (smtp) a partir de janeiro
GUI Database Design Tools - PostgreSQL Wiki
You can run PHP code inside PostgreSQL database.
12 senhas que nunca devem ser usadas - Geek List
Como é o dia de um “gerente de mídias sociais”? » CrisDias weblog
Blog do Márcio d'Ávila » Relatórios de mercado de TI 2010/2011
Create your Google Sitemap Online - XML Sitemaps Generator
The 15 Most Detrimental Social Media Mistakes You're Making
Blog do Márcio d'Ávila » Corrida dos navegadores rumo a HTML5 e CSS3
Validar é importante?! | Tableless - Desenvolvimento com Padrões Web
Evitando frustrações com sessões no PHP | Igor Escobar // Blog
PHP web applications can complement state in your applications very easily. Why is an illusion of state maintained by transporting one page and other information between one page and another losing it along the way. you've already lost potential productivity due to bizarre bugs or even security breaches because of these beauties. Here are four tips to save you time and secure your site. (in portuguese)
Javascript: Onunload VS Onbeforeunload | Igor Escobar // Blog
Fico pensando em um caso mais familiar possível para ilustrar a utilidade das duas funções e a melhor que me vem a cabeça é o Gmail. Já pensou em fazer algo parecido com o Gmail? Quando o usuário fechar a janela e alguma requisição estiver em processamento ele da um aviso sobre ela para evitar perda sem necessídade. Muita gente pensa que o evento utilizado para fazer tal proeza é o evento “onunload” mas não é. Existe uma pequena diferença entre os 2 eventos.
8 Regular Expressions You Should Know - Nettuts+
8 expressões regulares que você deve conhecer
The Web Application Security Consortium / The Web Security Glossary
The Web Security Glossary is an alphabetical index of terms and terminology relating to web application security. The purpose of the Glossary is to clarify the language used within the community.
The Novel 100: The 100 Greatest Novels of All Time
Dividindo dados em colunas - Mauro Pichiliani - SQL Server
Olá, pessoal. Hoje veremos uma solução que utilizei para manipular um conjunto de linhas e colunas no SQL Server com o objetivo de separá-las em dois conjuntos de colunas e facilitar a visualização dos dados, uma operação que geralmente não é fácil de ser realizada nos bancos de dados relacionais. Apesar de utilizar o SQL Server como exemplo, a técnica apresentada nesta coluna pode ser adaptada para outros bancos de dados que suportem a linguagem SQL sem problemas.
dBpoweramp: CD Ripper & Audio Converter. Secure ripping to mp3, FLAC, m4a, Apple Lossless & WMA
CD extractor and multi converter from different audio and video codecs. Lots of advanced options for different formats.
A última de bluetooth - rede entre dois GNU/Linux
No trabalho você tem um pc ligado a internet via wifi, ethernet, ou similares. Você leva seu notebook que gostaria que estivesse conectado também, como fica? Você está no aeroporto com mais uma pessoa, os dois de notebook, só um modem 3G, como fica? E se vocês tiverem só um login da Vex, prestadora de acesso wifi, como fica? Você faz uma rede bluetooth entre os dois e compartilha a conexão, ora. (com exceção do primeiro, todos os comandos abaixo são como root)
Paje Online: Como Converter Vídeos no Linux?
Converter arquivos de vídeos e som no Linux, abrangendo os mais variados formatos e codecs, pode ser uma tarefa razoavelmente simples, bastando conhecer o programa certo. Nesta dica vamos apresentar o programa ffmpeg.
An extensive list of essential Linux commands that every Ubuntu user will find helpful in their Linux journey.
Instructables - Make, How To, and DIY
Aprenda a fazer tudo
PHP é à quinta-feira - Gerar uma password | Peopleware
Um conjunto de funções que os ajudarão a gerar uma password (ou qualquer outra string de caracteres aleatórios).
crie e encontre paleta de cores a partir de imagens
Sua Língua » Arquivo » Não compre o novo VOLP! — 1ª parte
Blank/erase a DVD-RW | commandlinefu.com
Apagando um DVD-RW na linha de comando
Se eu soubesse que web 2.0 era isso… » CrisDias weblog
nth-child | Boas práticas de Desenvolvimento com Padrões Web
9 Interesting Facts To Know About a Website | Tools
Os top cinco erros não técnicos cometidos por desenvolvedores | Pacote201.com.br
Blog do Márcio d’Ávila » Cuidado - A fraude evoluiu
Dicas para evitar fraudes da internet.
Here I will list some of the items I used to have Arch running with the minimum I needed for my ThinkPad P14s. I have experienced a seamless experience with my old ThinkPad Carbon x1.
I relate this to the Realtek 8852AE, an 802.11ax device used by P14s, that does not work out-the-box as the one used by x1, although faster.
What is Browsershots? Browsershots tests your website's compatability on different browsers by taking screenshots of your web pages rendered by real browsers on different operating systems. Free tier!
Alguém tentou reinstalar o outro Sistema Inoperacional e ele, genialmente, apagou a MBR e, conseqüentemente, a opção de escolha do GRUB? Agora dá para recuperar. Pelo Ubuntu (distribuição que uso e o do exemplo), é claro.
Ferramentas de segurança de rede
SecTools.Org: Top 125 Network Security Tools
O mundo de lunga: Conexão 3G - Solução para problema com DNS
Para resolver o problema de DNSs para conexões com modems Huawei, que sobrescreve o /etc/resolv.conf
50 exemplos de menu de navegação
Chartle.net - interactive charts online!
Ferramenta para montagem de gráfico para colocar em sites
Piwigo.org | Photo Gallery Software for the Web
Mais um exemplo de uma boa galeria de fotos
Resize your image online - It's easy, it's free!
Redimensionamento de imagens pela web
"O Filmow foi criado para pessoas viciadas e apaixonadas por filmes. A principal ideia do Filmow é que você mostre aos seus amigos os filmes que já assistiu, comente sobre eles e dê sua opinião, na página do filme. Mas, para os que apenas gostam de filmes, o Filmow também é uma rede social onde é possível encontrar pessoas e amigos. No Filmow você fica sabendo quais filmes são lançados, os que estão no cinema e aqueles que já estão em DVD, para você assistir em casa." (http://filmow.com/sobre-o-filmow/)
Domain-Driven Design (DDD) is a software design philosophy with one crucial concept: the structure and language of software code (class names, class methods, class variables) should match the business domain. To attend to this concept, DDD presents Value Objects, which, in practice, represents an object similar to a primitive type but should be modelled after the domain's business rules.
(Checkout code at https://github.com/rafaelbernard/blog-value-objects)
Value Objects are first described in Evans' Domain-Driven Design book, and further explained in Smith and Lerman's Domain-Driven Design Fundamentals course. It is an immutable type that is distinguishable only by the state of its properties. Unlike an Entity1, a class type with a unique identifier and remains distinct even if its properties are otherwise identical, two Value Objects with the same properties can be considered equal.
We would use Value Object classes to represent a type strictly and encapsulate the validation rules of that type. Think of age or a card from a poker deck. They can seem sufficiently represented by primitive types such as integer and string, but in reality, they are managed by strict business rules2. For example, you would like to ensure that a particular age value is a non-negative integer. Or a picked card has a value not greater than 10, not 1, i.e., there is a range of allowed numbers or unique letters combined within four allowed suits.
To translate it to code, you could think of a Person class as a guest application to map a person's name and age. Usually, we would say a name is a string and age is an int.
class Person
{
private string $name;
private int $age;
public function __constructor(string $name, int $age)
{
$this->name = $name;
$this->age = $age;
}
}
Although we can think that the specification above is good and we are just instantiating a Person object with all the required attributes, we may have some problems with the implementation because negative values are also int
and would be allowed:
$personOk = new Person('John Doe', 18);
$notARealPerson = new Person('Benjamin Button', -18); // -18 year? no way!
The code above will not fail and is very common that some business logic is performed to assert age will never be negative:
// if from a form
$age = (int) $_POST['age'];
if ($age < 0) {
throw new \Exception('Age could not be negative');
}
// but you need to copy the check everywhere a Person class is used. What if someone overlooks it?
$person = new Person('John Doe', $age);
When using Value Objects, you leverage your class with the exact type you need, correctly applying business logic. I will give more details later, but a hint of how the Person class would be with a Value Object:
use App\Domain;
class Person
{
private string $name;
private Age $age;
public function __construct(string $name, Age $age)
{
$this->name = $name;
$this->age = $age;
}
}
And now we are always sure that Person objects will have a valid age. Bear with me and understand how Age
Value Object class should look.
You may have already realized that we have many cases where we need similar things on every application. They are used to validate patterns to an expected format, a set of possible values to simulate an enum (only present on PHP 8) or to extend this set of values to be validated against some more rules.
I will be using PHP 7.4 compatible code in this blog. If you have applications using older versions, changing them should not be too complicated. Let me know in the comments if you need samples about how to write to an older version.
Some examples:
Our Age
class should be implemented as:
<?php
namespace App\Domain;
class Age
{
private int $value;
/**
* @param int $value
*/
public function __construct(int $value)
{
if (!$value < 0) {
throw new \UnexpectedValueException('Negative numbers are not a valid age.');
}
$this->value = $value;
}
public function value(): int
{
return $this->value;
}
}
Or a richer example with card suits:
<?php
namespace App\Domain;
class CardSuit
{
const HEARTS = 'H';
const DIAMONDS = 'D';
const CLUBS = 'C';
const SPADES = 'S';
const SUITS = [
self::HEARTS,
self::DIAMONDS,
self::CLUBS,
self::SPADES,
];
private string $value;
public function __construct(string $value)
{
if (!in_array($value, self::SUITS)) {
throw new \InvalidArgumentException("`$value` is not a valid card suit.");
}
$this->value = $value;
}
public function __toString()
{
return $this->value;
}
public function value(): string
{
return $this->value;
}
}
Observe rules when checking grade with isAlumni()
from a given ClassYear
. Ideally, we would have a Grade class, but I kept it more straightforward to simplify understanding the check, and I have a similar example with poker cards classes above.
<?php
namespace App\Domain;
class ClassYear
{
private int $value;
/**
* @param int $value
*/
public function __construct(int $value)
{
// For class year, our business rules is from 1901-2999
if (!preg_match('/^((19\d{2})|(2)\d{3})$/', $value)) {
throw new \InvalidArgumentException('Invalid year');
}
$this->value = $value;
}
public static function fromNow(): self
{
return new self(date('Y'));
}
public function value(): int
{
return $this->value;
}
public function isAlumni(): bool
{
return date('Y') - $this->value >= 13;
}
}
Observe that it encapsulates some Enum values, but also a simple rule (isGreaterThan
), and it enriches the type with a simple business rule support that the application can also use.
<?php
namespace App\Domain;
class CardRank
{
const ACE = 'A';
const KING = 'K';
const QUEEN = 'Q';
const JACK = 'J';
const TEN = 'X';
const NINE = '9';
const EIGHT = '8';
const SEVEN = '7';
const SIX = '6';
const FIVE = '5';
const FOUR = '4';
const THREE = '3';
const TWO = '2';
const RANKS = [
self::ACE,
self::KING,
self::QUEEN,
self::JACK,
self::TEN,
self::NINE,
self::EIGHT,
self::SEVEN,
self::SIX,
self::FIVE,
self::FOUR,
self::THREE,
self::TWO
];
const WEIGHTS = [
self::ACE => 20,
self::KING => 13,
self::QUEEN => 12,
self::JACK => 11,
self::TEN => 10,
self::NINE => 9,
self::EIGHT => 8,
self::SEVEN => 7,
self::SIX => 6,
self::FIVE => 5,
self::FOUR => 4,
self::THREE => 3,
self::TWO => 2
];
private string $value;
public function __construct(string $value)
{
if (!in_array($value, self::RANKS)) {
throw new \InvalidArgumentException("`$value` is not a valid card rank.");
}
$this->value = $value;
}
public function __toString()
{
return $this->value;
}
public function value(): string
{
return $this->value;
}
public function weight()
{
return self::WEIGHTS[$this->value];
}
public function isGreaterThan(CardRank $cardRank): bool
{
return $this->weight() > $cardRank->weight();
}
// Some static helper functions can be created to be more readable
public static function two(): CardRank
{
return new self(self::TWO);
}
public static function ace(): CardRank
{
return new self(self::ACE);
}
}
Create and use the Value Objects whenever you see that it fits "encapsulate the business rules for a given type" and "it represents an object similar to a primitive type". This will directly understand the expected type of code and instantly validate capabilities.
Some examples:
// a
$person = new Person('John Doe', new Age(20));
public function saveGuest(Person $person);
// b
$currentUserClassYear = ClassYear::fromNow();
if (!$currentUserClassYear->isAlumni()) {
// do something for a non-alumni user
}
// c
$pickedCard = new Card(new CardSuit(CardSuit::SPADES), new CardRank(CardRank::ACE));
// d
$aceSpade = new Card(CardSuit::spades(), CardRank::ace());
$twoSpade = new Card(CardSuit::spades(), CardRank::two());
if ($aceSpace->isGreaterThan($twoSpade)) {
// do something when greater, such as sum the weight to count points
}
A code-base that uses Value Objects avoids repetition code to validate a type that is not represented by native types, improves readability, and keeps consistency about business rules (no one could overlook or forget to "copy the validation code check"). Value Objects has a built-in validation, making it superior to validation classes and creating a relationship with your business domain rules. It then keeps the code clean and lean.
You can see all related code at https://github.com/rafaelbernard/blog-value-objects.