Categorias
Tropeçando

Tropeçando 32 – Republish

Blog do Márcio d'Ávila » HTML5 no horizonte

Depoimento da Caixa sobre o banco de dados PostgreSQL reforça sua importância. | 4Linux – Free Software Solutions

G1 - Sistema operacional para PCs vai se tornar irrelevante, diz criador do Linux - notícias em Tecnologia e Games

Introdução - Experimentando o Linux Mint Debian Edition

Caso dos boletos imitando Registro.br chegando ao fim?

welcome home : vim online

Vim - Portal brasileiro do editor de textos Vim (VI) :: aurelio.net

Categorias
Tropeçando

Tropeçando 20 – Republish

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

Mantis Bug Tracker

Gerenciamento de erros

TIOBE Software: Tiobe Index

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

RootSudo - Ubuntu Brasil

Ripando e Gerando DVDs no Linux de forma simples « jmmwrite – simples e direto

Categorias
Banco de dados PostGreSQL

Recover and replace win1252 content to utf-8 for a PostgreSQL database

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.

Categorias
Tropeçando

Tropeçando 16 – Republish

FTP mini-HOWTO (Linux)

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.

PHP: SQL Injection

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.

PHP: Relatando Erros - Manual

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

vivaotux: Afinando seu violão usando o bash - geek d+

[Dicas-L] Lista de servidores DNS abertos e rápidos

Categorias
Tropeçando

Tropeçando 14 – republish

GUI Database Design Tools - PostgreSQL Wiki

When Geeks Have Twins [PIC]

Lançado o Pl/PHP – iMasters

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

Categorias
Tropeçando

Tropeçando 8 – Republish

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

pdftk - the pdf toolkit

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.

yfrog - Share your images/videos on Twitter!

Vacation relaxation

Categorias
Tropeçando

Tropeçando 2 – Republish

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.

Ubuntu Basic Commands

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

Color Hunter

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.

Categorias
Linux Operational Systems Technology

Arch and my Thinkpad P14s

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.

Hardware

Software

Categorias
Tropeçando

Tropeçando 1 – Republish

Browsershots

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!

Reinstalando o GRUB

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

Filmow

"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/)
Categorias
PHP

Introducing value objects in PHP

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.

What does it mean?

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

Samples of Value Objects

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:

Validating a format:

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;
    }
}

Validating a set and its rules:

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;
    }
}

Enum-like validation:

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);
    }
}

When to use it

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.

Glossary

  1. Entity: An entity may be defined as a thing capable of an independent existence that can be uniquely identified. An entity is an abstraction from the complexities of a domain. When we speak of an entity, we normally speak of some aspect of the real world that can be distinguished from other aspects of the real world. [(from Wikipedia)]
  2. Business rule: A business rule defines or constrains some aspect of business and always resolves to either true or false. Business rules are intended to assert business structure or to control or influence the behavior of the business.
  3. Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code: data in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).