From 2a5ed5cc258d8a70e75bb5cb112fd3789ceb75ac Mon Sep 17 00:00:00 2001
From: "a.shamavov" <a.shamavov@iqdev.digital>
Date: Fri, 12 Apr 2024 17:30:48 +0500
Subject: [PATCH] refactoring

---
 .idea/sonarlint.xml                           |  10 +
 .../001fdc7418679b6419e44b1142ab051819764ece  |   0
 .../43dcb35f966f0fa054ba7993783bf64ca2be218c  |   0
 .../6037d4b4b463114752d4470f297faf20f6eb091f  |   0
 .../672311d2a7e203158feec05c65a1596673272747  |   0
 .../6e70b6a94de880e98216f758f5f903c70ccf92d9  |   0
 .../87042d1f46b57381244d70e7a42feeb7710727dc  |   0
 .../a5cc2925ca8258af241be7e5b0381edf30266302  |   0
 .../ad8b439416d1e02614f47c5b471c7c4e587dca82  |   2 -
 .../baef02989dedf0ec859f7bce087a69f29bef2b72  |   0
 .../c5d6e48c28c17a397cf53caa8389f831b393980f  |   0
 .../d355caa07ac4b7aa5002c909a2c1d4a6319cf7e9  |   0
 .../fdb03812440437b51cbe4b19e899bfc5f72972fc  |   0
 .idea/sonarlint/issuestore/index.pb           |   4 +-
 .../001fdc7418679b6419e44b1142ab051819764ece  |   0
 .../43dcb35f966f0fa054ba7993783bf64ca2be218c  |   0
 .../6037d4b4b463114752d4470f297faf20f6eb091f  |   0
 .../672311d2a7e203158feec05c65a1596673272747  |   0
 .../6e70b6a94de880e98216f758f5f903c70ccf92d9  |   0
 .../87042d1f46b57381244d70e7a42feeb7710727dc  |   0
 .../a5cc2925ca8258af241be7e5b0381edf30266302  |   0
 .../baef02989dedf0ec859f7bce087a69f29bef2b72  |   0
 .../c5d6e48c28c17a397cf53caa8389f831b393980f  |   0
 .../d355caa07ac4b7aa5002c909a2c1d4a6319cf7e9  |   0
 .../fdb03812440437b51cbe4b19e899bfc5f72972fc  |   0
 .idea/sonarlint/securityhotspotstore/index.pb |   4 +-
 src/Action/Functions.php                      | 239 ++++++++++++++++++
 src/Controller/HomeController.php             |  29 +--
 28 files changed, 267 insertions(+), 21 deletions(-)
 create mode 100644 .idea/sonarlint.xml
 create mode 100644 .idea/sonarlint/issuestore/0/0/001fdc7418679b6419e44b1142ab051819764ece
 create mode 100644 .idea/sonarlint/issuestore/4/3/43dcb35f966f0fa054ba7993783bf64ca2be218c
 create mode 100644 .idea/sonarlint/issuestore/6/0/6037d4b4b463114752d4470f297faf20f6eb091f
 create mode 100644 .idea/sonarlint/issuestore/6/7/672311d2a7e203158feec05c65a1596673272747
 create mode 100644 .idea/sonarlint/issuestore/6/e/6e70b6a94de880e98216f758f5f903c70ccf92d9
 create mode 100644 .idea/sonarlint/issuestore/8/7/87042d1f46b57381244d70e7a42feeb7710727dc
 create mode 100644 .idea/sonarlint/issuestore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302
 create mode 100644 .idea/sonarlint/issuestore/b/a/baef02989dedf0ec859f7bce087a69f29bef2b72
 create mode 100644 .idea/sonarlint/issuestore/c/5/c5d6e48c28c17a397cf53caa8389f831b393980f
 create mode 100644 .idea/sonarlint/issuestore/d/3/d355caa07ac4b7aa5002c909a2c1d4a6319cf7e9
 create mode 100644 .idea/sonarlint/issuestore/f/d/fdb03812440437b51cbe4b19e899bfc5f72972fc
 create mode 100644 .idea/sonarlint/securityhotspotstore/0/0/001fdc7418679b6419e44b1142ab051819764ece
 create mode 100644 .idea/sonarlint/securityhotspotstore/4/3/43dcb35f966f0fa054ba7993783bf64ca2be218c
 create mode 100644 .idea/sonarlint/securityhotspotstore/6/0/6037d4b4b463114752d4470f297faf20f6eb091f
 create mode 100644 .idea/sonarlint/securityhotspotstore/6/7/672311d2a7e203158feec05c65a1596673272747
 create mode 100644 .idea/sonarlint/securityhotspotstore/6/e/6e70b6a94de880e98216f758f5f903c70ccf92d9
 create mode 100644 .idea/sonarlint/securityhotspotstore/8/7/87042d1f46b57381244d70e7a42feeb7710727dc
 create mode 100644 .idea/sonarlint/securityhotspotstore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302
 create mode 100644 .idea/sonarlint/securityhotspotstore/b/a/baef02989dedf0ec859f7bce087a69f29bef2b72
 create mode 100644 .idea/sonarlint/securityhotspotstore/c/5/c5d6e48c28c17a397cf53caa8389f831b393980f
 create mode 100644 .idea/sonarlint/securityhotspotstore/d/3/d355caa07ac4b7aa5002c909a2c1d4a6319cf7e9
 create mode 100644 .idea/sonarlint/securityhotspotstore/f/d/fdb03812440437b51cbe4b19e899bfc5f72972fc
 create mode 100644 src/Action/Functions.php

diff --git a/.idea/sonarlint.xml b/.idea/sonarlint.xml
new file mode 100644
index 0000000..6817efe
--- /dev/null
+++ b/.idea/sonarlint.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="SonarLintProjectSettings">
+    <option name="moduleMapping">
+      <map>
+        <entry key="iqdevTranningProgram" value="iqdevtranningprogram" />
+      </map>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/0/0/001fdc7418679b6419e44b1142ab051819764ece b/.idea/sonarlint/issuestore/0/0/001fdc7418679b6419e44b1142ab051819764ece
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/4/3/43dcb35f966f0fa054ba7993783bf64ca2be218c b/.idea/sonarlint/issuestore/4/3/43dcb35f966f0fa054ba7993783bf64ca2be218c
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/6/0/6037d4b4b463114752d4470f297faf20f6eb091f b/.idea/sonarlint/issuestore/6/0/6037d4b4b463114752d4470f297faf20f6eb091f
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/6/7/672311d2a7e203158feec05c65a1596673272747 b/.idea/sonarlint/issuestore/6/7/672311d2a7e203158feec05c65a1596673272747
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/6/e/6e70b6a94de880e98216f758f5f903c70ccf92d9 b/.idea/sonarlint/issuestore/6/e/6e70b6a94de880e98216f758f5f903c70ccf92d9
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/8/7/87042d1f46b57381244d70e7a42feeb7710727dc b/.idea/sonarlint/issuestore/8/7/87042d1f46b57381244d70e7a42feeb7710727dc
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302 b/.idea/sonarlint/issuestore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/a/d/ad8b439416d1e02614f47c5b471c7c4e587dca82 b/.idea/sonarlint/issuestore/a/d/ad8b439416d1e02614f47c5b471c7c4e587dca82
index ea6a1d3..e69de29 100644
--- a/.idea/sonarlint/issuestore/a/d/ad8b439416d1e02614f47c5b471c7c4e587dca82
+++ b/.idea/sonarlint/issuestore/a/d/ad8b439416d1e02614f47c5b471c7c4e587dca82
@@ -1,2 +0,0 @@
-
-vphp:S121"0Add curly braces around the nested statement(s).(ïŠí±üÿÿÿÿ8ÌÆ‹ì1J$562771d0-0b91-4f4c-beaf-90c25c2ac224
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/b/a/baef02989dedf0ec859f7bce087a69f29bef2b72 b/.idea/sonarlint/issuestore/b/a/baef02989dedf0ec859f7bce087a69f29bef2b72
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/c/5/c5d6e48c28c17a397cf53caa8389f831b393980f b/.idea/sonarlint/issuestore/c/5/c5d6e48c28c17a397cf53caa8389f831b393980f
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/d/3/d355caa07ac4b7aa5002c909a2c1d4a6319cf7e9 b/.idea/sonarlint/issuestore/d/3/d355caa07ac4b7aa5002c909a2c1d4a6319cf7e9
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/f/d/fdb03812440437b51cbe4b19e899bfc5f72972fc b/.idea/sonarlint/issuestore/f/d/fdb03812440437b51cbe4b19e899bfc5f72972fc
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/issuestore/index.pb b/.idea/sonarlint/issuestore/index.pb
index dae00e9..ab15ef3 100644
--- a/.idea/sonarlint/issuestore/index.pb
+++ b/.idea/sonarlint/issuestore/index.pb
@@ -10,4 +10,6 @@ C
 E
 assets/styles/app.css,5\8\58d82e459ad700473925afc6a4d3ceb1cbdfdf19
 E
-public/files/text.txt,9\9\994b95f5d0e2f9641bf4e2c30422e6a0a6a105b5
\ No newline at end of file
+public/files/text.txt,9\9\994b95f5d0e2f9641bf4e2c30422e6a0a6a105b5
+H
+src/Action/Functions.php,4\3\43dcb35f966f0fa054ba7993783bf64ca2be218c
\ No newline at end of file
diff --git a/.idea/sonarlint/securityhotspotstore/0/0/001fdc7418679b6419e44b1142ab051819764ece b/.idea/sonarlint/securityhotspotstore/0/0/001fdc7418679b6419e44b1142ab051819764ece
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/4/3/43dcb35f966f0fa054ba7993783bf64ca2be218c b/.idea/sonarlint/securityhotspotstore/4/3/43dcb35f966f0fa054ba7993783bf64ca2be218c
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/6/0/6037d4b4b463114752d4470f297faf20f6eb091f b/.idea/sonarlint/securityhotspotstore/6/0/6037d4b4b463114752d4470f297faf20f6eb091f
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/6/7/672311d2a7e203158feec05c65a1596673272747 b/.idea/sonarlint/securityhotspotstore/6/7/672311d2a7e203158feec05c65a1596673272747
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/6/e/6e70b6a94de880e98216f758f5f903c70ccf92d9 b/.idea/sonarlint/securityhotspotstore/6/e/6e70b6a94de880e98216f758f5f903c70ccf92d9
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/8/7/87042d1f46b57381244d70e7a42feeb7710727dc b/.idea/sonarlint/securityhotspotstore/8/7/87042d1f46b57381244d70e7a42feeb7710727dc
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302 b/.idea/sonarlint/securityhotspotstore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/b/a/baef02989dedf0ec859f7bce087a69f29bef2b72 b/.idea/sonarlint/securityhotspotstore/b/a/baef02989dedf0ec859f7bce087a69f29bef2b72
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/c/5/c5d6e48c28c17a397cf53caa8389f831b393980f b/.idea/sonarlint/securityhotspotstore/c/5/c5d6e48c28c17a397cf53caa8389f831b393980f
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/d/3/d355caa07ac4b7aa5002c909a2c1d4a6319cf7e9 b/.idea/sonarlint/securityhotspotstore/d/3/d355caa07ac4b7aa5002c909a2c1d4a6319cf7e9
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/f/d/fdb03812440437b51cbe4b19e899bfc5f72972fc b/.idea/sonarlint/securityhotspotstore/f/d/fdb03812440437b51cbe4b19e899bfc5f72972fc
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/sonarlint/securityhotspotstore/index.pb b/.idea/sonarlint/securityhotspotstore/index.pb
index dae00e9..ab15ef3 100644
--- a/.idea/sonarlint/securityhotspotstore/index.pb
+++ b/.idea/sonarlint/securityhotspotstore/index.pb
@@ -10,4 +10,6 @@ C
 E
 assets/styles/app.css,5\8\58d82e459ad700473925afc6a4d3ceb1cbdfdf19
 E
-public/files/text.txt,9\9\994b95f5d0e2f9641bf4e2c30422e6a0a6a105b5
\ No newline at end of file
+public/files/text.txt,9\9\994b95f5d0e2f9641bf4e2c30422e6a0a6a105b5
+H
+src/Action/Functions.php,4\3\43dcb35f966f0fa054ba7993783bf64ca2be218c
\ No newline at end of file
diff --git a/src/Action/Functions.php b/src/Action/Functions.php
new file mode 100644
index 0000000..8e9fadc
--- /dev/null
+++ b/src/Action/Functions.php
@@ -0,0 +1,239 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Action;
+
+use DateTime;
+use DateTimeImmutable;
+use DateInterval;
+use Exception;
+use DatePeriod;
+
+class Functions
+{
+    /**
+     * Выполняет сортировку массива по убыванию цены
+     * @param array $array
+     * @return array
+     */
+
+    public function sortPrice(array $array): array
+    {
+        $prices = array_column($array, 'price');
+        $counts = array_column($array, 'count');
+        array_multisort(
+            $prices,
+            SORT_DESC,
+            $counts,
+            SORT_ASC, $array
+        );
+        return $array;
+    }
+
+    /**
+     * На выход должна вернуть отсортированный массив по ключу *price* DESC
+     * и во вторую очередь по *count* ASC:
+     * [['price'=>12, 'count'=>4],  ['price'=>10, 'count'=>2],  ['price'=>8, 'count'=>4],
+     * ['price'=>8, 'count'=>5],  ['price'=>5, 'count'=>5],]
+     */
+
+    /**
+     * Найдет элемент с указаным id
+     * @param array $array - массив, содержащий элементы со структурой
+     * [
+     *  'id' => 30,
+     *  'name' => 'Jhon',
+     *  'age' => 23,
+     * ]
+     * @param $id - ид искомого элемента
+     * @return ?array - найденный элемент
+     */
+
+    public function search(array $array, int $id): ?array
+    {
+        $rowId = array_search($id, array_column($array, 'id'), true);
+        if ($rowId) {
+            return $array[$rowId];
+        }
+        return null;
+    }
+
+    /**
+     * Удалить дубликаты, оставив только уникальные значения
+     * @param array $array
+     * @return array
+     */
+
+    public function uniqElements(array $array): array
+    {
+        return array_unique($array, SORT_REGULAR);
+    }
+
+    /**
+     * Выходной массив:
+     * Array (
+     *   [0] => Array([0] => laravel, [1] => php)
+     *   [1] => Array([0] => codeigniter, [1] => php)
+     *   [3] => Array([0] => c++, [1] => java))
+     * )
+     */
+
+    /**
+     * Сгруппировать подразедлы в верхние разделы меню
+     * Дочерние элементы поместить в массив родителя с ключом submenu
+     * Значение под ключом depth определяет уровень раздела
+     * Массив $aMenu всегда начинается с элемента depth = 0,
+     * все последующие элементы с depth = 1 являются его дочерними
+     * элементами
+     * @param array $aMenu
+     * @return array
+     */
+
+    public function prepareMenu(array $aMenu): array
+    {
+        $result = [];
+        foreach ($aMenu as $arr) {
+            if ($arr['depth'] === 0) {
+                $result[] = array(
+                    'name' => $arr['name'],
+                    'depth' => $arr['depth'],
+                    'submenu' => []
+                );
+                continue;
+            }
+            $result[array_key_last($result)]['submenu'][] = array(
+                'name' => $arr['name'],
+                'depth' => $arr['depth'],
+            );
+        }
+        return $result;
+    }
+
+    /**
+     * Выходные данные:
+     * $aMenu = [
+     * [
+     *  'name' => 'Смартфоны и гаджеты',
+     *  'depth' => 0,
+     *  'submenu' => [
+     *      ['name' => 'Смартфоны, мобильные телефоны','depth' => 1,],
+     *      ['name' => 'Планшеты','depth' => 1,],
+     *      ['name' => 'Наушники и гарнитуры','depth' => 1,],],
+     * ],
+     * [
+     *  'name' => 'Компьютеры и ноутбуки',
+     *  'depth' => 0,
+     *  'submenu' => [
+     *      ['name' => 'Ноутбуки и аксессуары','depth' => 1,],
+     *      ['name' => 'Компьютеры и мониторы','depth' => 1,],
+     *      ['name' => 'Компьютерные комплектующие','depth' => 1,],]],
+     * [
+     *  'name' => 'Техника для дома',
+     *  'depth' => 0,
+     *  'submenu' => [
+     *      ['name' => 'Техника для уборки','depth' => 1,],
+     *      ['name' => 'Товары для ухода за одеждой','depth' => 1,],
+     *      ['name' => 'Аксессуары для техники','depth' => 1,],]
+     * ],
+     * [
+     *  'name' => 'Товары для дома и кухни',
+     *  'depth' => 0,
+     *  'submenu' => [
+     *      ['name' => 'Посуда','depth' => 1,],]],
+     * ];
+     */
+
+    /**
+     * Функция рассчитывает кол-во дней до нового года
+     * @param DateTimeImmutable $date дата от которой, необходимо рассчитать кол-во дней
+     * @return int
+     * @throws Exception
+     */
+
+    public function howDaysToNy(DateTimeImmutable $date): int
+    {
+        $endYear = date("Y-12-31", date_timestamp_get($date));
+        $dateInterval = date_diff(new DateTimeImmutable($endYear), $date);
+        return (int)$dateInterval->format("%a") + 1;
+    }
+
+    /**
+     * Вернет все пятницы 13 в году
+     * @param int $year год, в котором необходимо произвести расчет
+     * @return DateTimeImmutable[]
+     * @throws Exception
+     */
+
+    public function countFriday13(int $year): iterable
+    {
+        $startDate = new DateTime("$year-01-01 Friday");
+        ++$year;
+        $endDate = new DateTime("$year-01-01");
+        $interval = new DateInterval('P7D');
+        foreach (new DatePeriod($startDate, $interval, $endDate) as $day) {
+            yield new DateTimeImmutable($day->format("Y-m-d"));
+        }
+    }
+
+    /**
+     * Вернет кол-во дней между датами
+     * @param DateTimeImmutable $dateStart дата начала
+     * @param DateTimeImmutable $dateEnd дата окончания
+     * @return int
+     */
+    public function diffDays(DateTimeImmutable $dateStart, DateTimeImmutable $dateEnd): int
+    {
+        $dateInterval = date_diff($dateStart, $dateEnd);
+        return (int)$dateInterval->format("%a") ;
+    }
+
+    /**
+     * Напиши функцию, которая принимает путь до файла,
+     * проверяет, что файл существует и выводит пользователю весь контент файла
+     * (файл можешь создать любой)
+     * @param string $filePath путь до файла
+     * @return void
+     * @throws Exception
+     */
+
+    public function readLogFile(string $filePath): void
+    {
+        if (file_exists($filePath)) {
+            $text = "";
+            $file = fopen($filePath, 'rb');
+            while(!feof($file)) {
+                $line = fgets($file);
+                $text .= $line;
+            }
+            fclose($file);
+            print $text;
+        }
+        else {
+            throw new RuntimeException("File not found: $filePath");
+        }
+    }
+
+    /**
+     * Переделай своё решение 8 задачи:
+     * замени вывод всего текста из файла разом на
+     * построчный вывод используя yield
+     * @param string $filePath путь до файла
+     * @return iterable
+     */
+
+    public function readFileLineByLine(string $filePath): iterable
+    {
+        if (file_exists($filePath)) {
+            $file = fopen($filePath, 'rb');
+            while(!feof($file)) {
+                yield fgets($file);
+            }
+            fclose($file);
+        }
+        else {
+            throw new RuntimeException("File not found: $filePath");
+        }
+    }
+}
+
diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php
index 168fb51..94b37f6 100644
--- a/src/Controller/HomeController.php
+++ b/src/Controller/HomeController.php
@@ -2,36 +2,31 @@
 
 namespace App\Controller;
 
-use DateInterval;
-use DatePeriod;
-use DateTime;
-use DateTimeImmutable;
+use App\Action\Functions;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Attribute\Route;
 
 class HomeController extends AbstractController
 {
-    private function readFileLineByLine(string $fileName): iterable  {
-        $filePath = $this->getParameter('kernel.project_dir') . "/public/files/" . $fileName;
-        if (file_exists($filePath)) {
-            $file = fopen($filePath, "r");
-            while(!feof($file)) {
-                yield fgets($file);
-            }
-            fclose($file);
-        }
-        else yield "Такого файла не существует.";
-    }
+    private Functions $functions;
 
+    public function __construct(Functions $functions)
+    {
+        $this->functions = $functions;
+    }
 
     #[Route('/{fileName}', name: 'home')]
     public function home(string $fileName): Response // text.txt
     {
+        $filePath = $this->getParameter('kernel.project_dir') . "/public/files/" . $fileName;
         $text = "";
-        foreach($this->readFileLineByLine($fileName) as $line) {
+        foreach ($this->functions->readFileLineByLine($filePath) as $line) {
             $text .= $line;
         }
-        return $this->render('home.html.twig', ['text' => $text]);
+        $response = new JsonResponse($text);
+        $response->setEncodingOptions(JSON_UNESCAPED_UNICODE);
+        return $response;
     }
 }
-- 
GitLab