Treinamento Drupal
Dia 1
Instalação
Biblioteca mínimas para instalação no debian 12:
sudo apt-get install php php-common php-cli php-gd php-curl php-xml php-mbstring php-zip php-sybase php-mysql php-sqlite3
sudo apt-get install mariadb-server sqlite3 git
Instalação do php 7.4 para subir drupal da FFLCH (temporário):
sudo apt install apt-transport-https lsb-release ca-certificates curl -y
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
sudo apt update
Instalação das dependências em php7.4:
sudo apt-get install php7.4 php7.4-common php7.4-cli php7.4-gd php7.4-curl php7.4-xml php7.4-mbstring php7.4-zip php7.4-sybase php7.4-sqlite3 php7.4-mysql
Trocar versão do php para 7.4:
sudo update-alternatives --set php /usr/bin/php7.4
sudo update-alternatives --set phar /usr/bin/phar7.4
sudo update-alternatives --set phar.phar /usr/bin/phar.phar7.4
Instalação do composer:
curl -s https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
Instalação da distribuição Drupal da FFLCH:
git clone git@github.com:SEU-USERNAME/drupal.git
cd drupal
composer install
Instalação do Drupal com sqlite e perfil padrão:
./vendor/bin/drush site-install standard \
--db-url=sqlite://sites/default/files/.ht.sqlite \
--site-name="fflch" \
--site-mail="fflch@localhost" \
--account-name="fflch" \
--account-pass="fflch" \
--account-mail="fflch@localhost" --yes
Subindo um server local:
cd drupal
./vendor/bin/drupal serve -vvv
# ou
./vendor/bin/drupal serve 0.0.0.0:8000 -vvv
Zerando banco de dados:
# sqlite
# mysql
./vendor/bin/drupal database:drop
# sqlite
rm web/sites/default/files/.ht.sqlite*
Criação de módulo:
Criação de um módulo chamado treinamento:
./vendor/bin/drupal generate:module \
--module="treinamento" \
--machine-name="treinamento" \
--module-path="modules" \
--description="Módulo Treinamento" \
--core="8.x" \
--no-interaction
Habilitando módulo treinamento:
./vendor/bin/drupal module:install treinamento
O comando a seguir vai gerar o controller TreinamentoController e a respectiva rota, no controller terá um método chamado index(), assim como uma rota /treinamento apontando para esse método:
./vendor/bin/drupal generate:controller \
--module="treinamento" \
--class="TreinamentoController" \
--routes='"title":"index", "name":"treinamento.index", "method":"index", "path":"/treinamento"' \
--no-interaction
Limpando cache:
./vendor/bin/drupal cc
Exercício 1
Mostrar no seu controller quantidade de linhas do seguinte arquivo csv do tipo rest, walking e running. Também mostar a média da coluna pulse nos três casos rest, walking e running:
https://raw.githubusercontent.com/mwaskom/seaborn-data/master/exercise.csv
Exemplo de saída:
exercise.csv | rest | walking | running |
---|---|---|---|
Qtde linhas | XX | XX | XXX |
Média Pulse | XX | XX | XXX |
rest
Dia 2
Rota com parâmetro, será injetada no método index do controller:
treinamento.index:
path: '/treinamento/{parametro}'
defaults:
_controller: '\Drupal\treinamento\Controller\TreinamentoController::index'
requirements:
_permission: 'access content'
Criação de um twig template, para tal, criar um arquivo treinamento.module com a definição do template:
/**
* Implements hook_theme().
*/
function treinamento_theme($existing, $type, $theme, $path) {
return [
'treinamento' => [
'variables' => ['parametro' => NULL],
],
];
}
Criação de um twig template em templates/treinamento.html.twig:
<p>Nosso primeiro twig template!</p>
<p>Olha só o que você digitou na rota: </p>
Retornando o template no controller:
return [
'#theme' => 'treinamento',
'#parametro' => $parametro,
];
Na interface vamos criar alguns tipos de conteúdos. Criando e deletando nodes de todos tipos para ambiente de desenvolvimento:
./vendor/bin/drupal create:nodes
./vendor/bin/drupal entity:delete node --all
Carregando id’s dos nodes:
$nids = \Drupal::entityQuery('node')->condition('type','page')->execute();
Desafio: Mostrar a quantidade de nodes do tipo selecionado
Dica: pode-se desligar o cache de variáveis:
return [
'#theme' => 'treinamento',
...
'#cache' => [
'max-age' => 0,
],
];
A partir dos nids pode-se carregar os objetos nodes:
$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);
Iterando sob a os objetos nodes no twig:
<ul>
</ul>
Desafio: mostrar os títulos dos nodes no twig
Criando um node do tipo page:
use \Drupal\node\Entity\Node;
$node = Node::create([
'type' => 'page',
'title' => 'Teste com estagiários',
'field_qualquer' => 123,
]);
$node->save();
Ou se preferir:
use \Drupal\node\Entity\Node;
$node = Node::create(['type' => 'page']);
$node->title = 'mais um node';
$node->field_qualquer= 'Teste com estagiários';
$node->save();
Pode-se manipular somente um node já existente:
$nid = 1;
$node = Node::load($nid);
$node->body->format = 'full_html';
$node->save();
Exercício 2
Neste exercício vamos continuar trabalhando com o seguinte arquivo:
https://raw.githubusercontent.com/mwaskom/seaborn-data/master/exercise.csv
- Criar um tipo de conteúdo com as colunas desse arquivo
- Criar uma rota e um controller que leia o arquivo csv e para cada linha crie um node correspondente no tipo de conteúdo criado anteriormente (se essa rota for clicada duas vezes, não duplicar registros, e sim atualizá-los)
- Criar uma rota, controller e template mostrando a tabela (a partir dos nodes e não do csv)
- Remontar a tabela do exercício 1, mas lendo os nodes: Mostrar no seu controller quantidade de linhas do seguinte arquivo csv do tipo rest, walking e running. Também mostar a média da coluna pulse nos três casos rest, walking e running:
Exemplo de saída:
exercise.csv | rest | walking | running |
---|---|---|---|
Qtde linhas | XX | XX | XXX |
Média Pulse | XX | XX | XXX |
Dia 3
Criação de usuário admin com senha admin e criação de uma banco chamado drupal:
sudo mariadb
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' IDENTIFIED BY 'admin' WITH GRANT OPTION;
create database drupal;
quit
Instalação com perfil da fflch, fflchprofile e banco de dados mysql:
./vendor/bin/drush site-install fflchprofile \
--db-url="mysql://admin:admin@localhost/drupal" \
--site-name="fflch" \
--site-mail="fflch@localhost" \
--account-name="fflch" \
--account-pass="fflch" \
--account-mail="fflch@localhost" --yes
Como chamar um script php usando linha de comando, útil, por exemplo, para criar nodes sistematicamente:
./vendor/bin/drush php-script ~/cria_nodes.php
Carregando arquivo ao criar um node:
use \Drupal\node\Entity\Node;
$data = file_get_contents('/home/thiago/arquivo.pdf');
$file = file_save_data($data, 'public://arquivo.pdf', FILE_EXISTS_REPLACE);
$node = Node::create([
'type' => 'page',
'title' => 'Teste com arquivo',
'field_arquivo' => [
'target_id' => $file->id(),
'alt' => 'Pdf exemplo',
'title' => 'Pdf exemplo'
],
]);
$node->save();
Outra forma de carregar um arquivo:
use \Drupal\node\Entity\Node;
use \Drupal\file\Entity\File;
$filepath = '/home/thiago/arquivo.pdf';
$file = File::create([
'filename' => basename($filepath),
'uri' => 'public://' . basename($filepath),
'status' => 1,
'uid' => 1,
]);
$file->save();
$node = Node::create([
'type' => 'page',
'title' => 'Teste com arquivo',
'field_arquivo' => [
'target_id' => $file->id(),
'alt' => 'Pdf exemplo',
'title' => 'Pdf exemplo'
],
]);
$node->save();
Se quiser especificar uma pasta em files, troque ‘public://’ por ‘public://MINHA-PASTA/’
Criação de uma submissão de um webform:
use Drupal\webform\Entity\Webform;
use Drupal\webform\Entity\WebformSubmission;
$webform_id = 'meu_webform';
$webform = Webform::load($webform_id);
$values = [
'webform_id' => $webform->id(),
'data' => [
'nome' => 'Thiago Gomes Verissimo',
'email' => 'thiago.verissimo@usp.br',
],
];
$webform_submission = WebformSubmission::create($values);
$webform_submission->save();
Exercício 3
Neste exercício vamos trabalhar com o seguinte arquivo:
https://github.com/zygmuntz/goodbooks-10k/blob/master/samples/books.csv
- Criar um webform com as colunas desse arquivo
- Criar um arquivo php que leia o arquivo csv completo (https://raw.githubusercontent.com/zygmuntz/goodbooks-10k/master/books.csv) e para cada linha crie um submissão correspondente no webform criado anteriormente (rodar seu script com drush)
Dia 4 (em construção)
Carregando todas submissões de um webform:
use Drupal\webform\Entity\Webform;
use Drupal\webform\Entity\WebformSubmission;
$webform_id = 'meu_webform';
$webform = Webform::load($webform_id);
if ($webform->hasSubmissions()) {
$query = \Drupal::entityQuery('webform_submission')->condition('webform_id', $webform_id );
$result = $query->execute();
$submission_data = [];
foreach ($result as $item) {
$submission = \Drupal\webform\Entity\WebformSubmission::load($item);
$data = $submission->getData();
...
}
Extras
trocar a url alternativa:
$node->path->alias = '/novo-caminho-do-node'
$node->path->pathauto = Drupal\pathauto\PathautoState::SKIP;