Как работает загрузка картинок?

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
Доброго времени суток. Подскажите пожалуйста, какая логика загрузки картинки на сервер, когда она загружается и меняется ссылка на нее. На сайте очень большое количество треков, альбомов и исполнителей сохранных в базе но с картинкой от звука, как их загрузить на сервер?
 

MSE-Script

Developer
Команда форума
Сообщения
867
Реакции
309
@ushkom, Доброе утро. Изображение загружается в момент сохранения трека из источника и при нажатии соответствующей кнопки в окне редактирования трека. Для массовой загрузки потребуется программное вмешательство: выгрузить из БД все ресурсы и для каждого "дернуть" метод загрузки изображения.
 

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
У треков картинки почти все загружены, а у сохраненных альбомов и исполнителей в основном все картинки из источника, хотя в настройках включено сохранение. По какой причине они не загружены на сервер?

Или картинки загружаются только для треков, а для исполнителей и альбомов нет?
 
Последнее редактирование:

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
Добавил в app/Controllers/Album.php
Код:
         # Сохранение постеров на сервер
            $this->album['poster'] = $this->saveImage($this->album['poster']);
И в app/Controllers/Artist.php
Код:
         # Сохранение постеров на сервер
            $this->artist['poster'] = $this->saveImage($this->artist['poster']);
Стало сохранять, а как сохранить изображение старых артистов и альбомов не подскажите?
 

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
А в реализации не сможете помочь? Не совсем понимаю как реализовать.
 

MSE-Script

Developer
Команда форума
Сообщения
867
Реакции
309
Записать в какой-то modules/poster_update.php:

PHP:
<?php

// Подключение автозагрузчика
require_once('../../vendor/autoload.php');

$model = new \App\Model\ArtistModel();
$controller = new \App\Controllers\Controller();

$artists = $model->getAll();

foreach ($artists as $artist) {
   $new_poster = $controller->saveImage($artist['poster']);
   $result = $model->update(['poster' => $new_poster, 'id' => $artist['id']]);
   if ($result !== -1)
      print('Ресурс обновлен');
   else
      print('Ошибка обновления ресурса');
}
Код не проверялся, могут быть ошибки. Перед выполнением обязательно сделать бэкап.
 

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
Большое спасибо, буду разбираться. Ругается на эту строчку:

Код:
$new_poster = $controller->saveImage($artist['poster']);

mod_fcgid: stderr: PHP Fatal error:  Uncaught Error: Call to protected method App\\Controllers\\Controller::saveImage() from context '' in /home/admin/web/musicat.net/public_html/modules/poster_artist_update.php:13
Можно еще вопрос. Пытаюсь добавить сохранение картинок в ZvookUtils.php
Добавляю перед
Код:
$this->saveTrack($result);
Это
Код:
$this->track['poster'] = $this->saveImage($this->track['poster']);
После
Код:
$insert_id = $this->track_controller->saveTrack();
Это
Код:
$image = $this->track_controller->saveImage();
И сам запрос меняю на это
Код:
$stmt = $this->db->prepare("UPDATE `tracks` SET `url` = '{$new_url}' `poster` = '{$image}' WHERE `id` = {$insert_id}");
Но к сожалению не получается, если не сложно подправьте пожалуйста. Спасибо за помощь
 
Последнее редактирование:

MSE-Script

Developer
Команда форума
Сообщения
867
Реакции
309
Ругается на эту строчку
Файл Controller.php, protected изменить на public, после окончания процедуры обновления вернуть обратно.


Пытаюсь добавить сохранение картинок в ZvookUtils.php
В этом модуле нет $this->track. Там нужно что-то вроде:

PHP:
$track['poster'] = $this->track_controller->saveImage($track['poster']);
и добавить это перед:
PHP:
$this->track_controller->saveTrack();
 

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
$track['poster'] = $this->track_controller->saveImage($track['poster']);
Спасибо большое за помощь. Подправил по Вашим рекомендациям, но к сожалению не хочет работать. Код получился таким:
Код:
   protected function saveTrack (array $result)
   {
      // Подготовка
      $track = $this->track_controller->createNewTrack($result);
      $url = preg_replace(["#{artist}#", "#{name}#"], [$track['artist']['name'], $track['name']], $this->MSE->config['track_url']);
      $track['url'] = Utils::prepareUrl($url);
      $this->track_controller->track = $track;
      $track['poster'] = ($this->track_controller->saveImage($track['poster']));
      $image = '`poster` = `' . $track['poster'] . '`';      
      $insert_id = $this->track_controller->saveTrack();
      print(" | Результат вставки: {$insert_id} <br />\n");

      // Добавить ID трека в начало URL
      if ($this->config['add_id']) {
         $new_url = $insert_id . '-' . $track['url'];
         $stmt = $this->db->prepare("UPDATE `tracks` SET `url` = '{$new_url}' {$image} WHERE `id` = {$insert_id}");
         $stmt->execute();
      }

      if ($insert_id)
         $this->added_counter++;

      return $insert_id;
   }
Где я допустил ошибку?
 
Последнее редактирование:

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
Файл Controller.php, protected изменить на public, после окончания процедуры обновления вернуть обратно.
Выдает в логах ошибку
Код:
mod_fcgid: stderr: PHP Warning:  exif_imagetype(https:/uploads/images/c2/c2f6ea9584149a796cb33a5ed7ef5dbd.jpg): failed to open stream: No such file or directory in /home/admin/web/musicat.net/public_html/app/Controllers/Controller1.php on line 169
Ругается на эту строчку
Код:
$mime = image_type_to_mime_type(exif_imagetype($url));
Что теперь скрипту не нравится?

Я создал Controller1.php поэтому путь в логах на него

Полный Controller1.php
Код:
<?php

namespace App\Controllers;

use \App\Model\MenuModel;
use \App\Mse;

class Controller1
{
   public static $instance;
   public $menu;
   public $seoTags = [];
   public $breadcrumbs = [];
   public $error;
   public $results;
   public $MSE;

   public function __construct ()
   {
      $this->MSE = Mse::getInstance();
      $this->loadMenu();
   }

   # Загрузка шаблона для текущего контроллера и отрисовка страницы
   public function loadViews ($data = NULL, $template_name = NULL)
   {
      $data['menu']           = $this->menu;
      $data['breadcrumbs']    = $this->getBreadcrumbs();
      $data['seo']            = $this->seoTags;

      $this->MSE->loadTemplate($this->MSE->smarty, mb_strtolower($template_name ?? $this->MSE->controller), $data);
   }

   /**
    * Получение списка хлебных крошек для вывода на страницу
    *
    * @return array
    */
   public function getBreadcrumbs ()
   {
      $main_crumb[] = [
         'link'   => '/',
         'title'  => 'Главная'
      ];

      return count($this->breadcrumbs) ? array_merge($main_crumb, $this->breadcrumbs) : false;
   }

   /**
    * Добавление элемента хлебных крошек
    *
    * @param array $crumb - Массив с данными о элементе
    */
   public function addBreadcrumbs (array $crumb)
   {
      $this->breadcrumbs[] = $crumb;
   }

   public function addSeoTags ($name, $value)
   {
      $this->seoTags[$name] = $value;
   }

   # Генерация ошибки
   # Ввод: Идентификатор ошибки из конфига config_errors.php
   # Вывод: Ошибка и остановка скрипта
   # -----------------------------
   public function createError($errorName)
   {
      $this->error = $this->MSE->setError($errorName);

      # Кастомный header для текущей ошибки
      if (isset($this->error['header']))
         header($this->error['header']);

      $data['ERROR'] = $this->error;
      $this->addSeoTags('title',          $this->error['title']);
      $this->addSeoTags('description',    $this->error['title']);
      $this->addSeoTags('heading',        $this->error['title']);
      $this->loadViews($data, 'error');
      exit;
   }

   # Генерация списка ключевых слов из результата парсинга
   # Ввод: Результат парсинга
   # Вывод: Список ключей, отсортированых по релевантности
   # -----------------------------
   public function getRandKeys ($data)
   {
      if (isset($data['tracks']) && is_array($data['tracks'])) {

         # Наполнить массив $trackKeyArray исполнителями и названиями треков
         $trackKeyArray = array();
         foreach ($data['tracks'] as $trackItem) {

            # Исполнитель и трек не должны быть больше 70 символов
            if (strlen($trackItem['artist']['name'] . $trackItem['name']) < 70) {
              $trackKeyArray[] = $trackItem['artist']['name'];
              $trackKeyArray[] = $trackItem['name'];
            }
         }

         return $this->createKeyWords($trackKeyArray);
       }
   }

   # Генерация ключей для meta-keywords
   # Из страницы выбираются все ключевые слова, очищаются, сортируются по вхождению на странице
   #--------------------------------------
   public function createKeyWords ($trackKeyArray)
   {
      $wordArray = array();

      if (!$trackKeyArray)
         return null;

      # Делим ключи на отдельные слова
      foreach ($trackKeyArray as $trackKey) {
          $keyWords[] = explode(' ', $trackKey);
      }

      # Перебираем полученные ключи, очищаем от мусора
      for ($i=0; $i < count($keyWords); $i++) {
          foreach ($keyWords[$i] as $keyWord) {
              if (strlen($keyWord) > 4) {
                  $keyWord = trim(htmlspecialchars($keyWord));
                  $wordArray[] = preg_replace('#\.|,|\(|\)#', '', $keyWord);
              }
          }
      }

      # Сортируем ключи по релевантности
      $randKeyword = '';
      $keyWordsCount = array_count_values($wordArray);
      array_multisort($keyWordsCount, SORT_DESC);
      $keyWords = array_keys($keyWordsCount);
      for ($i = 0; $i < 10; $i++) {
          if (isset($keyWords[$i])) {
              $randKeyword .= $keyWords[$i] . ", ";
          }
          if (isset($keyWords[$i])) {
              $randKeyword .= $keyWords[$i] . ", ";
          }
          return (substr($randKeyword, 0, strrpos($randKeyword, ', ')));
      }
   }

   # Преобразование BB-codes в теги
   # Ввод: Строка, содержащая BB-codes
   # Вывод: Строка, содержащая валидные теги
   public function convertBBcodes ($text)
   {
      return preg_replace($this->MSE->config_bbcodes['search'], $this->MSE->config_bbcodes['replace'], $text);
   }

   public function saveImage ($url)
   {
      # Проверка URL на корретность протокола
      if (!preg_match('#(http|https)#', $url)) {
         $url = "https:{$url}";
      }

      # Определение каталога и путей для будушего файла
      $newName = md5($url);
      $relativeDir = '/uploads/images/' . substr($newName, 0, 2);
      $absoluteDir = dirname(__DIR__, 2) .$relativeDir;

      # Определение mime-типа файла
      $mime = image_type_to_mime_type(exif_imagetype($url));
      if ($mime === 'image/jpeg') {

         $absolutePatch = $absoluteDir . '/' . $newName . '.jpg';
         $relativePatch = $relativeDir. '/' . $newName . '.jpg';

         # Проверка на дубликат файла
         if (file_exists($absolutePatch)) {
            return $relativePatch;
         }

         # Проверка прав на запись и создание каталога для файла
         if (!is_dir($absoluteDir))
         {
            mkdir($absoluteDir, 0777, true);
         }

         # Сжатие и сохранение изображения на сервер
         $image = imagecreatefromjpeg($url);
         imagejpeg($image, $absolutePatch, $this->MSE->config_system['poster_quality']);
         imagedestroy($image);
         return $relativePatch;

      } else {
         return $url;
      }

   }

   public function loadMenu ()
   {
      $model = new MenuModel();
      $this->menu = $model->getAll();
   }
}

Полный poster_artist_update.php
Код:
<?php

// Подключение автозагрузчика
ini_set('max_execution_time', 0);
require_once(dirname(__FILE__) . '/../vendor/autoload.php');

$model = new \App\Model\ArtistModel();
$controller = new \App\Controllers\Controller1();

$artists = $model->getAll();

foreach ($artists as $artist) {
   $new_poster = $controller->saveImage($artist['poster']);
   $result = $model->update(['poster' => $new_poster, 'id' => $artist['id']]);
   if ($result !== -1)
      print('Ресурс обновлен<br />');
   else
      print('Ошибка обновления ресурса<br />');
}
 
Последнее редактирование:

MSE-Script

Developer
Команда форума
Сообщения
867
Реакции
309
Что теперь скрипту не нравится?
Попытка загрузить уже загруженный ранее файл. Перед загрузкой нужно добавить проверку, что-то вроде:
PHP:
if (preg_match('#zvooq\.com#ui'), $track['poster'])
    print('В URI обнаружен признак источника');
else
    print('Ссылка является локальным путем');
 

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
Не совсем понял, где проверка должна быть?

Таким образом?
Код:
<?php

// Подключение автозагрузчика
ini_set('max_execution_time', 0);
require_once(dirname(__FILE__) . '/../vendor/autoload.php');

$model = new \App\Model\ArtistModel();
$controller = new \App\Controllers\Controller1();

$artists = $model->getAll();

foreach ($artists as $artist) {
      if (preg_match(('#zvooq\.com#ui'), $track['poster']))
      {
       $new_poster = $controller->saveImage($artist['poster']);
       $result = $model->update(['poster' => $new_poster, 'id' => $artist['id']]);
       $insert_id = $artist['id'];
      }else{
      print('Ссылка является локальным путем');
      }
   if ($result !== -1)
      print(" | Ресурс {$insert_id} обновлен<br />");
   else
      print(" | Ошибка обновления ресурса {$insert_id}<br />");
}
 
Последнее редактирование:

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
Частично убрал ошибки в логах. В Controller1.php изменил это:
Код:
      # Проверка URL на корретность протокола
      if (!preg_match('#(http|https)#', $url)) {
         $url = "https:{$url}";
      }
На это:
Код:
      # Проверка URL на корретность протокола
      if (!preg_match('#(http|https)#', $url)) {
         $url = dirname(__DIR__, 2) .$url;
      }
Теперь нет ошибки с путем к изображением
Код:
mod_fcgid: stderr: PHP Warning:  exif_imagetype(https:/uploads/images/c2/c2f6ea9584149a796cb33a5ed7ef5dbd.jpg): failed to open stream: No such file or directory in /home/admin/web/musicat.net/public_html/app/Controllers/Controller1.php on line 169
Но осталась ошибка:
Код:
[Fri Sep 25 23:30:48.818185 2020] [fcgid:warn] [pid 13150] [client 109.162.124.206:54132] mod_fcgid: stderr: PHP Warning:  exif_imagetype(https://cdn52.zvooq.com/pic?type=artist&amp;id=76001761&amp;size=600x600&amp;ext=jpg): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
[Fri Sep 25 23:30:48.818189 2020] [fcgid:warn] [pid 13150] [client 109.162.124.206:54132] mod_fcgid: stderr:  in /home/admin/web/musicat.net/public_html/app/Controllers/Controller1.php on line 170
Нашел похожее по этой ссылке, но разобраться не получается, знаний маловато.

Получается exif_imagetype() не может обработать такого рода ссылки. Проверял здесь, тоже ошибка
 
Последнее редактирование:

ushkom

Ветеран
Клиент
Сообщения
122
Реакции
10
Добрый день. Если не сложно, помогите с модулями. Буду признателен.
 
Сверху