Giovanni Battista Lenoci / @gianiaz
PUG SONDRIO - 23 Gennaio 2019
Cerchiamo di capire se il tuo codice fa schifo e perchè.
$error = "";
$datetime_inizio = date('Y-m-d H:i', strtotime($_POST['datetime_inizio']));
$datetime_fine = date('Y-m-d H:i', strtotime($_POST['datetime_fine']));
if ($_POST['tipologia_incarico'] == 1) {
if ($_POST['nome'] != "") {
$nome = mysqli_real_escape_string(Connection::getConnection(), $_POST['nome']);
$sql = "SELECT COUNT(*) AS num FROM incarichi WHERE nome='" . $nome . "' AND id_commessa='" . intval($_POST['id_commessa']) . "' ";
if ($_POST['id'] != "") {
$sql .= " AND id!='" . intval($_POST['id']) . "' ";
}
$sql .= " LIMIT 1";
$res = mysqli_query(Connection::getConnection(), $sql);
if ($row = mysqli_fetch_array($res)) {
if ($row['num'] > 0) {
$error = 'inuso';
}
}
}
}
if ($datetime_fine <= $datetime_inizio) {
$error = "time";
}
echo $error;
Calisthenics è un termine inglese che identifica un insieme di esercizi fisici a corpo libero, generalmente eseguiti senza l'ausilio di attrezzi, alternativi a quelli classici della ginnastica. ... La parola calisthenics deriva da due termini greci, “kalos” che significa bellezza e “sthenos” ovvero forza.
Gli Object Calisthenics sono esercizi di programmazione, formalizzati in 9 regole, inventati da Jeff Bay nel suo libro "The ThoughtWorks Anthology"
Le regole non sono da prendere alla lettera, sono solo regole da tenere sempre presente, inoltre sono state pensate
function validaProdotti($prodotti)
{
$campiObbligatori = [
'prezzo',
'nome',
'descrizione',
'tipo'
];
$valido = true;
foreach ($prodotti as $prodotto) {
$campi = array_keys($prodotto);
foreach ($campiObbligatori as $campoObbligatorio) {
if(!in_array($campoObbligatorio, $campi)) {
$valido = false;
}
}
}
return $valido;
}
Togliamo il secondo livello di indentazione, collegandoci anche ai principi SOLID, ogni funzione/metodo deve svolgere un singolo compito.
function validaProdotti($prodotti)
{
$campiObbligatori = [
'prezzo',
'nome',
'descrizione',
'tipo'
];
$valido = true;
foreach ($prodotti as $prodotto) {
$prodottoValido = validaProdotto($prodotto, $campiObbligatori);
if(!$prodottoValido) {
$valido = false;
}
}
return $valido;
}
function validaProdotto($prodotto, $campiObbligatori)
{
$valido = true;
$campi = array_keys($prodotto);
foreach ($campiObbligatori as $campoObbligatorio) {
if (!in_array($campoObbligatorio, $campi)) {
$valido = false;
}
}
return $valido;
}
function validaProdotti($prodotti)
{
$campiObbligatori = [
'prezzo',
'nome',
'descrizione',
'tipo'
];
foreach ($prodotti as $prodotto) {
if(! validaProdotto($prodotto, $campiObbligatori)) {
return false;
}
}
return true;
}
function validaProdotto($prodotto, $campiObbligatori)
{
$campi = array_keys($prodotto);
$campiMancanti = array_diff($campiObbligatori, $campi);
return count($campiMancanti) === 0;
}
function validaListaProdotti($prodotti)
{
$prodottiValidi = array_filter($prodotti, 'isValid');
return count($prodottiValidi) === count($prodotti);
}
function isValid($prodotto)
{
$campiObbligatori = ['prezzo', 'nome', 'descrizione', 'tipo'];
$campi = array_keys($prodotto);
$campiMancanti = array_diff($campiObbligatori, $campi);
return count($campiMancanti) === 0;
}
private function handleInvoiceCreation(Request $request, AbstractInvoice $invoice)
{
$form = $this->formFactory->create(InvoiceType::class, $invoice);
$form->handleRequest($request);
if($this->user->canCreate()) {
if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($invoice);
$this->entityManager->flush();
$this->flashBag->addSuccessMessage('Fattura creata con successo');
$this->entityManager->refresh($invoice);
return new RedirectResponse(
$this->router->generate('panel_detail', ['invoice' => $invoice->getId()])
);
} else {
return [
'form' => $form->createView(),
'invoice' => $invoice,
];
}
} else {
// qualcos altro
}
}
private function handleInvoiceCreation(Request $request, AbstractInvoice $invoice)
{
$form = $this->formFactory->create(InvoiceType::class, $invoice);
$form->handleRequest($request);
if ($this->user->canCreate()) {
throw new Exception('Non puoi creare una invoice');
}
if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($invoice);
$this->entityManager->flush();
$this->entityManager->refresh($invoice);
$this->flashBag->addSuccessMessage('Fattura creata con successo');
return new RedirectResponse(
$this->router->generate('panel_detail', ['invoice' => $invoice->getId()])
);
}
return [
'form' => $form->createView(),
'invoice' => $invoice,
];
}
non si applica molto al PHP ¯\_(ツ)_/¯
$component->repaint(false);
class UiComponent {
public function repaint($animate = false)
}
class Animate {
public $animate = true;
public function __construct($animate = true){
$this->animate = $animate;
}
}
$component->repaint(new Animate(false));
$this->base_uri = $this->CI->config->site_url() . '/' . $this->CI->uri->segment('./') . $this->CI->uri->slash_segment(2, 'both');
$this->base_uri = $this->CI->config->iro->segment(1) . $this->CI->uri->slash_segment(2, 'leading');
La legge di Demetra afferma che un oggetto A può chiamare un metodo di un altro oggetto B ma l'oggetto A non può usare l'oggetto B per raggiungere un terzo oggetto C che possa soddisfare le sue richieste. Questo infatti implicherebbe una conoscenza dei dettagli interni di B (nello specifico, dei suoi componenti) da parte di A.
Anziché consentire ad A di interagire con un oggetto ottenuto da B (uno "sconosciuto"), il progettista dovrebbe modificare la classe B in modo da fornire direttamente nell'interfaccia di B il servizio di C che serve ad A.
Il vantaggio nel seguire la legge di Demetra consiste nel fatto che il software così creato tende ad essere più mantenibile ed adattabile. Visto che gli oggetti sono meno dipendenti dalla struttura interna degli altri oggetti, i contenitori di oggetti possono essere modificati senza dover ristrutturare i chiamanti.
Uno svantaggio della legge è che richiede la scrittura di una grande quantità di metodi wrapper per propagare le chiamate a metodo. Ciò può aumentare il tempo di sviluppo, almeno inizialmente, e sicuramente aumenta la quantità di codice necessario e peggiora le performance.
$pathMock->getExportFilename(Argument::type(InvoicePassive::class))
->shouldBeCalled()
->willReturn(self::FILE_NAME_INVOICE);
$user = $this->get('security.context')->getToken()->getUser();
$products = [
[
'nome' => 'Pippo',
'prezzo' => '10'
],
[
'nome' => 'Pluto',
'prezzo' => '5'
]
];
foreach ($products as $p) {
list($n, $prz) = $p;
echo 'Nome: ' . $n . ', prezzo' . $prz;
}
foreach ($products as $product) {
list($name, $price) = $product;
echo 'Nome: ' . $name . ', prezzo' . $price;
}
function processResponseHeaderAndDefineOutput($response) { ... }
function getPageData($data) { ... }
public function __construct(
BlameBot $blameBot,
SingleInvoiceChecker $singleInvoiceChecker,
ExportShutdownRepository $exportShutdownRepository,
InvoicePassiveRepository $invoicePassiveRepository,
EntityManager $entityManager,
PdfGenerator $pdfGenerator
LoggerInterface $logger,
Mailer $mailer
.....
) {
public function add($element);
public function clear();
public function contains($element);
public function isEmpty();
public function remove($key);
public function removeElement($element);
public function containsKey($key);
class User {
/** @var int $id */
private $id;
/** @var string $name */
private $name;
public function __construct(int $id, string $name) {
$this->id = $id;
$this->name = $name;
}
public function getId(): int {
return $this->id;
}
public function setId(int $id): void {
$this->id = $id;
}
public function getName(): string {
return $this->name;
}
public function setName(string $name): void {
$this->name = $name;
}
}
class User {
public int $id;
public string $name;
public function __construct(int $id, string $name) {
$this->id = $id;
$this->name = $name;
}
}