bez wyzwisk za kod proszę
Code Review ma pomóc Tobie (żebyś mógł pisać lepszy kod i się rozwijał) i ludziom z Twojego zespołu (żeby nie musieli pływać w szambie). Nikt Cie nie powinien wyzywać. Jak ktoś tak robi podczas CR'ki to możesz mu podziękować i znaleźć innego recenzenta. Idąc na code review powinieneś się cieszyć, a nie bać, że ktoś Cie zmiesza z błotem.
Nie bierz też tych uwag do siebie osobiście, bo to że ktoś ma uwagi do Twojego kodu to normalna sprawa. Wszyscy piszemy dupny kod, ale za to jesteśmy zarąbiści w krytykowaniu i znajdywaniu błędów w cudzym kodzie.
Ta książka Ci bardzo pomoże: https://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672
Wszędzie zakomentowany kod i gdzieniegdzie źle sformatowany (np. brakuje spacji przy przecinkach/nawiasach, nazwy zmiennych raz z wielkiej, raz z małej litery).
Czasami używasz type hintów, a czasami nie. Staraj się ich używać wszędzie (łącznie z wartościami skalarnymi, jak int, string, bool).
```php
@param $what {string}
```
Staraj się nie komentować bez sensu. Zamiast tego użyj typów i dobierz dobrą nazwę. Wtedy komentarz jest zbędny. Nazewnictwo, nazewnictwo, nazewnictwo...
Przy okazji zamiast stringa lepiej by było, żeby tu była tablica, albo coś... wtedy ktoś nie musi wiedzieć jaki format tych kolumn wymagasz.
W PHPStorm masz skrót (cmd + P lub alt + P) który przy wywołaniu metody pokazuje Ci jakie parametry musisz podać. Widząc tam $what
programista dokończy na głos: WHAT THE FUCK
i nie będzie miał zielonego pojęcia co ma tam wpisać, żeby Twoja metoda była zadowolona i zwróciła sensowny wynik.
W tym momencie musisz dać albo komentarz, że to kolumny oddzielone przecinkiem, albo zmienić nazwę parametru na commaSeparatedColumns
. Z resztą ja w ogóle nie jestem fanem takich super ogólnych funkcji, które sobie wszystko zwracają. Poza tym ->select('w.'.$what)
może być wrażliwe na sql injection.
Kopiuj
public function select(string $commaSeparatedColumns, $order = 'DESC'): array
```php
class TopicValidator
```
Z tego co widzę, to odpowiedzialnością tej klasy nie jest walidacja. Ona coś tam sobie mapuje i usuwa duplikaty, więc warto jej zmienić nazwę.
```php
function deleteObjDuplicateFromArray($array, $keep_key_assoc = false){
```
Cały ten kod można zastąpić:
```php
array_unique(
array_map(function($element) {
return is_object($element) ? (array) $element : $element;
}, $input),
SORT_REGULAR
);
```
```php
public function getAmmoData():array
{
$ammoArray = array(
```
To powinno być w bazie/pliku json/xml gdziekolwiek poza plikiem `*.php`.
```php
/**
* @param string|int $IDOrAllGunsData set 'all' for all arrays, int with gun ID
* @return array|mixed|string
* @throws PrepareData "there is no ID smaller than 0" if set number less then 0;
* @throws PrepareData "you can set only string "all" (or "not defined" but then ID is set from the constructor)"
* @throws PrepareData "in "getGunsData" method there is no array with ID:[set ID]"
* @throws PrepareData "in "getGunsData" method there is no array with ID:[set ID]"
* @return array array with guns data
*/
public function getGunsData($IDOrAllGunsData = 'not defined'):array
{
```
1. Masz return type array, a w dokumentacji `array|mixed|string`, to jak to jest? (prawidłowo powinien być jeden return type)
2. Nie potrzebujesz komentarzy w stylu `@param` lub `@return` jeżeli dobrze nazwiesz metodę i użyjesz dobrodziejstw PHP 7 (czyli scalar type hints).
3. `@throws` powinno zawierać exception, które może zostać wyrzucone, np. `@throws \Exception`. Lepiej jednak wyrzucać exception, którego nazwa już coś nam mówi `@throws InvalidArgumentException` `@throws GunDoesNotExistException`, wtedy nie będziesz musiał ich dodatkowo opisywać.
4. `$IDOrAllGunsData`. Jeżeli nazwa twojej zmiennej lub metody ma w sobie `or` albo `and` to wiedz, że coś się dzieje (czyt. prawie na pewno ukrywa ona wiele odpowiedzialności).
5. Wszelkie magiczne zmienne typu `'not defined'` powinieneś wydzielić do jakiejś stałej i nią się posługiwać. Jeszcze lepiej [gdyby to był enum](https://github.com/myclabs/php-enum).
```php
class ModsDataPrepare
```
Znowu nazewnictwo. Nazwa klas/zmiennych nie powinny używać czasowników. Lepszą nazwą może być `CośTamProvider` z metodą `getData/prepare/provide`, czy coś w tym stylu.
```php
$numberPagination = count($allTutorialsArticleID)/5;
```
Do tego jest specjalny bundle. Możesz użyć [tego](https://github.com/KnpLabs/KnpPaginatorBundle), albo jakiegoś innego. Jeżeli chcesz to zrobić sam, to ta logika nie powinna tu być, powinieneś ją wydzielić do osobnej klasy, chociaż by po to, żeby móc jej ponownie użyć.
```php
public function approvalTutorialArticle()
```
Dlaczego tutaj się tyle dzieje... Walidacja powinna wylądować w osobnym pliku. Poza tym [masz do tego gotowe komponenty](https://symfony.com/doc/current/validation.html).
```php
$author = $_POST['tutorial_author'];
```
GLOBALEEEEEEEE :( Możesz zrobić tak:
```php
public function approvalTutorialArticle(Request $request)
{
// ...
$request->request->get('tutorial_author');
```
Ogólnie odnośnie kodu w kontrolerze, to dzieje się tam mnóstwo rzeczy. **W kontrolerze powinny być tylko rzeczy specyficzne dla danego IO**.
Jeżeli Twoim IO jest przeglądarka web, to wtedy jakieś pobieranie parametrów z requesta, renderowanie widoku i dodawanie jakiś komunikatow o błędzie do sesji.
Jeżeli Twoim IO jest Symfony Command, to powinno tam być tylko wypychanie komuniaktów do OutputInterface i pobieranie argumentów z InputInterface. Ewentualnie renderowanie jakiegoś paska postępu. Cała reszta powinna być wydzielona do osobnego serwisu.
Jeżeli będziesz chciał dodać inny kontroler dla apki mobilnej, albo właśnie jakiś command to co wtedy? Będziesz musiał zduplikować logikę, która tworzy coś, co tam sobie tworzysz, bo nie będziesz mógł użyć kontrolera dedykowanego dla web'a dla apki mobilnej, a tym bardziej dla commanda.