|
@@ -48,22 +48,26 @@ class Commands {
|
|
|
|
|
|
// В тему разрешается добавлять и другие ключи, как, например в теме оценок
|
|
// В тему разрешается добавлять и другие ключи, как, например в теме оценок
|
|
|
|
|
|
- private array $theme_schedule =
|
|
|
|
|
|
+ private static array $theme_schedule =
|
|
[
|
|
[
|
|
"line_spacing"=> 5,
|
|
"line_spacing"=> 5,
|
|
"padding"=> 10,
|
|
"padding"=> 10,
|
|
"colors"=> [
|
|
"colors"=> [
|
|
"background"=> [220,220,220],
|
|
"background"=> [220,220,220],
|
|
"title_color"=> [30, 30, 30],
|
|
"title_color"=> [30, 30, 30],
|
|
- "body_bg_even"=> [180, 180, 170],
|
|
|
|
- "body_bg_odd" => [210, 210, 200],
|
|
|
|
|
|
+ "body_bg_even"=> [0, 255, 0],
|
|
|
|
+ "body_bg_odd" => [0, 255, 255],
|
|
|
|
+ //~ "body_bg_even"=> [180, 180, 170],
|
|
|
|
+ //~ "body_bg_odd" => [210, 210, 200],
|
|
"body_fg" => [40, 40, 40]
|
|
"body_fg" => [40, 40, 40]
|
|
],
|
|
],
|
|
"title_font_size"=> 30,
|
|
"title_font_size"=> 30,
|
|
"body_font_size"=> 20,
|
|
"body_font_size"=> 20,
|
|
"body_line_constraints" => [0, 40, 25],
|
|
"body_line_constraints" => [0, 40, 25],
|
|
"title_line_constraints" => 35,
|
|
"title_line_constraints" => 35,
|
|
- "font" => rootdir.'resources/Lato-Regular.ttf'
|
|
|
|
|
|
+ "font" => rootdir.'/resources/Lato-Regular.ttf',
|
|
|
|
+ "body_line_height" => 25,
|
|
|
|
+ "title_line_height" => 35
|
|
];
|
|
];
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
@@ -175,33 +179,54 @@ class Commands {
|
|
// 2. Попросить подождать
|
|
// 2. Попросить подождать
|
|
self::askWait($driver, $u);
|
|
self::askWait($driver, $u);
|
|
|
|
|
|
- // 3. Составить расписание
|
|
|
|
- $data = $em->getRepository(Entities\Pair::class)
|
|
|
|
- ->getPairsOfScheduleForGroup($schedule);
|
|
|
|
-
|
|
|
|
- $text = "";
|
|
|
|
- foreach ($data as $row) {
|
|
|
|
- $time = $row->getTime();
|
|
|
|
- $name = $row->getPairName()->getName();
|
|
|
|
- $details = $row->getConductionDetails();
|
|
|
|
-
|
|
|
|
- // Составление текста о преподавателе и месте проведения
|
|
|
|
- $details_texts = [];
|
|
|
|
- foreach ($details as $detail) {
|
|
|
|
- $initials = $detail->getEmployee()->getNameWithInitials();
|
|
|
|
- $place = $detail->getPlace()->getName();
|
|
|
|
-
|
|
|
|
- $details_text[] = $initials.' '.$place;
|
|
|
|
- }
|
|
|
|
- $details_text = implode(' / ', $details_text);
|
|
|
|
-
|
|
|
|
- $text .= $time->format('H:i');
|
|
|
|
- $text .= $name;
|
|
|
|
- $text .= ":".$details_text;
|
|
|
|
- $text .= "\n";
|
|
|
|
- }
|
|
|
|
|
|
+ //~ // 3. Составить расписание
|
|
|
|
+ //~ $data = $em->getRepository(Entities\Pair::class)
|
|
|
|
+ //~ ->getPairsOfScheduleForGroup($schedule);
|
|
|
|
+
|
|
|
|
+ //~ $text = "";
|
|
|
|
+ //~ foreach ($data as $row) {
|
|
|
|
+ //~ $time = $row->getTime();
|
|
|
|
+ //~ $name = $row->getPairName()->getName();
|
|
|
|
+ //~ $details = $row->getConductionDetails();
|
|
|
|
+
|
|
|
|
+ //~ // Составление текста о преподавателе и месте проведения
|
|
|
|
+ //~ $details_texts = [];
|
|
|
|
+ //~ foreach ($details as $detail) {
|
|
|
|
+ //~ $initials = $detail->getEmployee()->getNameWithInitials();
|
|
|
|
+ //~ $place = $detail->getPlace()->getName();
|
|
|
|
+
|
|
|
|
+ //~ $details_text[] = $initials.' '.$place;
|
|
|
|
+ //~ }
|
|
|
|
+ //~ $details_text = implode(' / ', $details_text);
|
|
|
|
+
|
|
|
|
+ //~ $text .= $time->format('H:i');
|
|
|
|
+ //~ $text .= $name;
|
|
|
|
+ //~ $text .= ":".$details_text;
|
|
|
|
+ //~ $text .= "\n";
|
|
|
|
+ //~ }
|
|
|
|
+
|
|
|
|
+ //$driver->sendMessage($u, Message::create($text));
|
|
|
|
+
|
|
|
|
+ $data =
|
|
|
|
+ [
|
|
|
|
+ ["Время проведения", "Дисциплина", "Кто проводит"],
|
|
|
|
+ ["12:28", "Матеша", "лол хз"],
|
|
|
|
+ ["Виталий", "балбесина", "ахахах"],
|
|
|
|
+ ["шучу", "шучу", "шучу"],
|
|
|
|
+ ["12:28", "не матеша", "аааааааааааааааааааааааааааааааа я шучу жеееееееееееееееее"],
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ $img = self::generateTable(
|
|
|
|
+ $data,
|
|
|
|
+ "Расписание на сегодня",
|
|
|
|
+ self::$theme_schedule,
|
|
|
|
+ [__CLASS__, "bodyLineDefault"]
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ $success = self::saveImage($img, "schedule");
|
|
|
|
+ $driver->varDump('success', $success);
|
|
|
|
|
|
- $driver->sendMessage($u, Message::create($text));
|
|
|
|
|
|
+ //~ $driver->sendMessage($u, Message::create("gpicview ".$filename));
|
|
|
|
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
@@ -492,7 +517,7 @@ class Commands {
|
|
|
|
|
|
// Разбивает длинную строку на линии, перенося слова
|
|
// Разбивает длинную строку на линии, перенося слова
|
|
// (слова - это участки текста, разделённые пробелами)
|
|
// (слова - это участки текста, разделённые пробелами)
|
|
- private function splitLongString($text, $line_size) : array {
|
|
|
|
|
|
+ private static function splitLongString($text, $line_size) : array {
|
|
|
|
|
|
// Не разделять слова
|
|
// Не разделять слова
|
|
if ($line_size == 0) {
|
|
if ($line_size == 0) {
|
|
@@ -546,12 +571,12 @@ class Commands {
|
|
// $title - название
|
|
// $title - название
|
|
// $theme - настройки рисования
|
|
// $theme - настройки рисования
|
|
// $draw_body_line - функция отрисовки заднего фона таблицы
|
|
// $draw_body_line - функция отрисовки заднего фона таблицы
|
|
- private function generateTable(
|
|
|
|
|
|
+ private static function generateTable(
|
|
array $data,
|
|
array $data,
|
|
string $title,
|
|
string $title,
|
|
array $theme,
|
|
array $theme,
|
|
- callable $draw_body_line) {
|
|
|
|
-
|
|
|
|
|
|
+ callable $draw_body_line)
|
|
|
|
+ {
|
|
$width = count($data[0]);
|
|
$width = count($data[0]);
|
|
$height = count($data);
|
|
$height = count($data);
|
|
|
|
|
|
@@ -588,6 +613,7 @@ class Commands {
|
|
// 2. Вычисление и сохранение размеров текста в яйчейке
|
|
// 2. Вычисление и сохранение размеров текста в яйчейке
|
|
list($cell_width, $cell_height) = self::getTextSize(
|
|
list($cell_width, $cell_height) = self::getTextSize(
|
|
$cell_lines,
|
|
$cell_lines,
|
|
|
|
+ $theme['body_line_height'],
|
|
$theme['line_spacing'],
|
|
$theme['line_spacing'],
|
|
$theme['font'],
|
|
$theme['font'],
|
|
$theme['body_font_size']
|
|
$theme['body_font_size']
|
|
@@ -598,26 +624,25 @@ class Commands {
|
|
|
|
|
|
// 3. Определение макс. размера ширины колонки и высоты текущей
|
|
// 3. Определение макс. размера ширины колонки и высоты текущей
|
|
// строки
|
|
// строки
|
|
- $col_sizes[$x] = max($cols_sizes[$x], $cell_width);
|
|
|
|
|
|
+ $col_sizes[$x] = max($col_sizes[$x], $cell_width);
|
|
$row_height = max($row_height, $cell_height);
|
|
$row_height = max($row_height, $cell_height);
|
|
}
|
|
}
|
|
|
|
|
|
$row_sizes[] = $row_height;
|
|
$row_sizes[] = $row_height;
|
|
$cells[] = $row_lines;
|
|
$cells[] = $row_lines;
|
|
}
|
|
}
|
|
- $body_width = array_sum($col_sizes) + $theme['padding'] * 2;
|
|
|
|
- $body_height = array_sum($row_sizes) + $theme['padding'] * 2;
|
|
|
|
|
|
+ $body_width = array_sum($col_sizes);
|
|
|
|
+ $body_height = array_sum($row_sizes);
|
|
|
|
|
|
// Обработка названия таблицы
|
|
// Обработка названия таблицы
|
|
$title_lines = self::splitLongString($title, $theme['title_line_constraints']);
|
|
$title_lines = self::splitLongString($title, $theme['title_line_constraints']);
|
|
list($title_width, $title_height) = self::getTextSize(
|
|
list($title_width, $title_height) = self::getTextSize(
|
|
$title_lines,
|
|
$title_lines,
|
|
|
|
+ $theme['title_line_height'],
|
|
$theme['line_spacing'],
|
|
$theme['line_spacing'],
|
|
$theme['font'],
|
|
$theme['font'],
|
|
$theme['title_font_size']
|
|
$theme['title_font_size']
|
|
);
|
|
);
|
|
- $title_width += $theme['padding'] * 2;
|
|
|
|
- $title_height += $theme['padding'] * 2;
|
|
|
|
|
|
|
|
// Вычисление размеров таблицы. Пытаемся сделать квадрат
|
|
// Вычисление размеров таблицы. Пытаемся сделать квадрат
|
|
$table_width = max($body_width, $title_width);
|
|
$table_width = max($body_width, $title_width);
|
|
@@ -632,7 +657,9 @@ class Commands {
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
#region Отрисовка
|
|
#region Отрисовка
|
|
- $im = imagecreatetruecolor($table_width, $table_height);
|
|
|
|
|
|
+ $im = imagecreatetruecolor(
|
|
|
|
+ $table_width + $theme['padding'] * 2,
|
|
|
|
+ $table_height + $theme['padding'] * 2);
|
|
|
|
|
|
$gdcolors = [];
|
|
$gdcolors = [];
|
|
foreach ($theme['colors'] as $color_name => $color) {
|
|
foreach ($theme['colors'] as $color_name => $color) {
|
|
@@ -644,24 +671,44 @@ class Commands {
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // DEBUG START
|
|
|
|
+ $gdcolors['dbg_red'] = imagecolorallocate($im, 255, 0, 0);
|
|
|
|
+ // DEBUG END
|
|
|
|
+
|
|
// Заполнение заднего фона
|
|
// Заполнение заднего фона
|
|
imagefilledrectangle(
|
|
imagefilledrectangle(
|
|
$im,
|
|
$im,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
- $table_width - 1,
|
|
|
|
- $table_height - 1,
|
|
|
|
|
|
+ $table_width + $theme['padding'] * 2 - 1,
|
|
|
|
+ $table_height + $theme['padding'] * 2 - 1,
|
|
$gdcolors['background']
|
|
$gdcolors['background']
|
|
);
|
|
);
|
|
|
|
|
|
- // Дальше мы всё рисуем снизу вверх, потому что зачем то разработчики
|
|
|
|
- // GD решили в отрисовку текста передавать как Y координату
|
|
|
|
- // нижний край, а не верхний
|
|
|
|
-
|
|
|
|
// Отрисовка названия
|
|
// Отрисовка названия
|
|
- $line_y = $title_height - $theme['padding'];
|
|
|
|
- foreach (array_reverse($title_lines) as $line) {
|
|
|
|
- $area = imagettftext(
|
|
|
|
|
|
+ // Пробел + высота одной строки
|
|
|
|
+ $line_y = $theme['padding'] + $theme['title_line_height'];
|
|
|
|
+ foreach ($title_lines as $line) {
|
|
|
|
+
|
|
|
|
+ // DEBUG START
|
|
|
|
+ $dbgarea = imagettfbbox(
|
|
|
|
+ $theme['title_font_size'],
|
|
|
|
+ 0,
|
|
|
|
+ $theme['font'],
|
|
|
|
+ $line);
|
|
|
|
+ imagefilledrectangle(
|
|
|
|
+ $im,
|
|
|
|
+
|
|
|
|
+ $theme['padding'],
|
|
|
|
+ $line_y,
|
|
|
|
+
|
|
|
|
+ $theme['padding'] + abs($dbgarea[2] - $dbgarea[0]),
|
|
|
|
+ $line_y - $theme['title_line_height'],
|
|
|
|
+
|
|
|
|
+ $gdcolors['dbg_red']);
|
|
|
|
+ // DEBUG END
|
|
|
|
+
|
|
|
|
+ imagettftext(
|
|
$im,
|
|
$im,
|
|
$theme['title_font_size'],
|
|
$theme['title_font_size'],
|
|
0,
|
|
0,
|
|
@@ -671,12 +718,19 @@ class Commands {
|
|
$theme['font'],
|
|
$theme['font'],
|
|
$line
|
|
$line
|
|
);
|
|
);
|
|
- $line_y -= abs($area[1] - $area[5]) + $theme['line_spacing'];
|
|
|
|
|
|
+ // Добавление ещё строки
|
|
|
|
+ $line_y += $theme['title_line_height'] + $theme['line_spacing'];
|
|
}
|
|
}
|
|
|
|
|
|
// Отрисовка тела таблицы
|
|
// Отрисовка тела таблицы
|
|
- $line_y = $body_height + $title_height;//+$theme['padding']-$theme['padding'];
|
|
|
|
- for ($y = $height - 1; $y > -1; $y--) {
|
|
|
|
|
|
+ $body_y =
|
|
|
|
+ $theme['padding'] +
|
|
|
|
+ $theme['title_line_height'] +
|
|
|
|
+ $theme['padding'];
|
|
|
|
+
|
|
|
|
+ $line_y = $body_y;
|
|
|
|
+ for ($y = 0; $y < $height; $y++) {
|
|
|
|
+ // Задний фон строки таблицы
|
|
call_user_func(
|
|
call_user_func(
|
|
$draw_body_line,
|
|
$draw_body_line,
|
|
$im,
|
|
$im,
|
|
@@ -687,10 +741,48 @@ class Commands {
|
|
$theme['padding'], // x1
|
|
$theme['padding'], // x1
|
|
$line_y, // y1
|
|
$line_y, // y1
|
|
|
|
|
|
- $body_width - $theme['padding'], // x2
|
|
|
|
- $line_y - $row_sizes[$y] // y2
|
|
|
|
|
|
+ $theme['padding'] + $body_width, // x2
|
|
|
|
+ $line_y + $row_sizes[$y] // y2
|
|
);
|
|
);
|
|
|
|
+
|
|
|
|
+ // Содержимое яйчеек
|
|
|
|
+ $celltext_x = $theme['padding'] * 2;
|
|
|
|
+ for ($x = 0; $x < $width; $x++) {
|
|
|
|
+ $celltext_y = $line_y + $theme['padding'];
|
|
|
|
+
|
|
|
|
+ foreach ($cells[$y][$x] as $cell_line) {
|
|
|
|
+ imagettftext(
|
|
|
|
+ $im,
|
|
|
|
+ $theme['body_font_size'],
|
|
|
|
+ 0,
|
|
|
|
+ $celltext_x,
|
|
|
|
+ $celltext_y + $theme['body_line_height'],
|
|
|
|
+ $gdcolors['body_fg'],
|
|
|
|
+ $theme['font'],
|
|
|
|
+ $cell_line
|
|
|
|
+ );
|
|
|
|
+ $celltext_y +=
|
|
|
|
+ $theme['body_line_height'] +
|
|
|
|
+ $theme['line_spacing'];
|
|
|
|
+ }
|
|
|
|
+ $celltext_x += $col_sizes[$x];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $line_y += $row_sizes[$y];
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // Рамка таблицы
|
|
|
|
+ imagerectangle(
|
|
|
|
+ $im,
|
|
|
|
+
|
|
|
|
+ $theme['padding'],
|
|
|
|
+ $body_y,
|
|
|
|
+
|
|
|
|
+ $theme['padding'] + $body_width,
|
|
|
|
+ $body_y + $body_height,
|
|
|
|
+
|
|
|
|
+ $gdcolors['dbg_red']
|
|
|
|
+ );
|
|
|
|
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
@@ -698,14 +790,21 @@ class Commands {
|
|
}
|
|
}
|
|
|
|
|
|
// Вычисляет высоту и ширину текста без padding в пикселях
|
|
// Вычисляет высоту и ширину текста без padding в пикселях
|
|
- private function getTextSize($lines, $line_spacing, $font, $font_size) {
|
|
|
|
|
|
+ private static function getTextSize(
|
|
|
|
+ $lines,
|
|
|
|
+ $line_height,
|
|
|
|
+ $line_spacing,
|
|
|
|
+ $font,
|
|
|
|
+ $font_size
|
|
|
|
+ )
|
|
|
|
+ {
|
|
$width = 0;
|
|
$width = 0;
|
|
$height = 0;
|
|
$height = 0;
|
|
|
|
|
|
foreach ($lines as $line) {
|
|
foreach ($lines as $line) {
|
|
$box = imagettfbbox($font_size, 0, $font, $line);
|
|
$box = imagettfbbox($font_size, 0, $font, $line);
|
|
$width = max($width, abs($box[2] - $box[0]));
|
|
$width = max($width, abs($box[2] - $box[0]));
|
|
- $height += abs($box[1] - $box[5]) + $line_spacing;
|
|
|
|
|
|
+ $height += $line_height + $line_spacing;
|
|
}
|
|
}
|
|
|
|
|
|
// В последней строке не нужно добавлять расстояния между строками
|
|
// В последней строке не нужно добавлять расстояния между строками
|
|
@@ -715,7 +814,7 @@ class Commands {
|
|
}
|
|
}
|
|
|
|
|
|
// Отрисовывает обычный задний фон строки таблицы
|
|
// Отрисовывает обычный задний фон строки таблицы
|
|
- private function bodyLineDefault(
|
|
|
|
|
|
+ private static function bodyLineDefault(
|
|
$im,
|
|
$im,
|
|
$colors,
|
|
$colors,
|
|
$data,
|
|
$data,
|
|
@@ -732,5 +831,12 @@ class Commands {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Сохраняет изображение в директорию /tmp
|
|
|
|
+ private static function saveImage($image, $filename_base) : string {
|
|
|
|
+ $filename = "/home/vad/".$filename_base.rand(1111,9999).".png";
|
|
|
|
+ return imagepng($image, $filename);
|
|
|
|
+ return $filename;
|
|
|
|
+ }
|
|
|
|
+
|
|
#endregion
|
|
#endregion
|
|
}
|
|
}
|