<?php
trait app_object_images
{
/**
* Содержит изобржения для объекта
* @var app_images_image[]
*/
protected $_images;
/**
* Метод возвращает директорию, куда необходимо сохранить файлы
* @return string
*/
public function getImagesUploadDirectory()
{
if (!$this->getId())
{
throw new app_exception("Вызов getImagesUploadDirectory() для не сохраненного объекта", 503);
}
$directory = "upload/" . get_class( $this ) . "/" . (($this->getId() % 255 + 1))."/";
if (file_exists($directory) && !is_dir($directory))
{
throw new app_exception("{$directory} не является директорией", 503);
}
if (!file_exists($directory) && !app_fs_mkdir::recursive($directory))
{
throw new app_exception("Не могу создать директорию {$directory} не является директорией", 503);
}
return $directory;
}
/**
* Ratio
* @return string
*/
public function getImagesRatio()
{
return "200:200";
}
/**
* Установка всех изображений
* @param array $images
* @return app_object_images
*/
public function setImages(array $images)
{
$this->_images = $images;
return $this;
}
/**
* Получаем изображения из базы данных
* @return app_images_images|multitype:app_images_array
*/
public function getImages()
{
if (isset($this->_images)) {
return new app_images_array($this->_images);
}
if (!$this->getId()) {
return new app_images_array(array());
}
$this->_images = array();
$db = (new app_db())->query("SELECT * FROM `app_images_image` WHERE `class` = '".get_class($this)."' && `object_id` = '".$this->getId()."' ORDER by `position`");
while ($row = $db->fetch()) {
$this->_images[] = (new app_images_image())->setAttributes($row);
}
return new app_images_array($this->_images);
}
/**
* Универсальный метод, который необходимо вызывать при загрузки изображений на сервер с выбором area по x1,y1 и x2,y2.
* @param unknown $_images
* @return app_object_images
*/
public function userInputImages($_images)
{
$this->getImages(); // Загрузим изображения из БД
if (is_array($_images) && isset($_images['id'])) {
$increment = 0;
foreach (array_keys($_images['id']) as $_key) {
if (!isset($_images['id'][$_key]) || !isset($_images['name'][$_key]) || !isset($_images['filename'][$_key]) || !isset($_images['primary'][$_key]) || !isset($_images['title'][$_key]) || !isset($_images['width']) || !isset($_images['height']) || !isset($_images['x1'][$_key]) || !isset($_images['y1'][$_key]) || !isset($_images['x2'][$_key]) || !isset($_images['y2'][$_key]) || !isset($_images['xThumb'][$_key]) || !$_images['name'][$_key]) {
continue;
}
if (!$_images['id'][$_key]) {
/*
* Загрузка нового изображения
*/
if (!file_exists($_images['filename'][$_key]) || !is_readable($_images['filename'][$_key])) {
// Проверка изображения. Возможно, оно могло исчезнуть при чистке по крону
$this->addError("Файл {$_images['filename'][$_key]} не существует или не доступен для чтения");
continue;
}
/*
* Повторная проверка на попытку загрузить нетипичное изображение. В нормальных условиях
* никогда не должна сработать, поскольку первоначальный ресайз выполняется контроллером загрузки изобращений,
* и проверка качества изображения выполняется там
*/
$image_info = getimagesize($_images['filename'][$_key]);
if (!$image_info || !$image_info[0] || !$image_info[1]) {
$this->addError("Изображение не допустимого формата (#1)");
continue;
}
$this->_images[] = (new app_images_image())
->setClass(get_class($this))
->setObjectId($this->getId())
->setName($_images['name'][$_key])
->setFilename($_images['filename'][$_key])
->setWidth($image_info[0])
->setHeight($image_info[1])
->setRatio( $this->getImagesRatio() )
->setPrimary($_images['primary'][$_key])
->setTitle($_images['title'][$_key])
->setX1($_images['x1'][$_key])
->setY1($_images['y1'][$_key])
->setX2($_images['x2'][$_key])
->setY2($_images['y2'][$_key])
->setXThumb($_images['xThumb'][$_key])
->setPosition($increment++)
;
} else {
/** Обновление данных существующего изображения*/
foreach ($this->getImages() as $image) {
if ($image->getId() && $image->getId() == $_images['id'][$_key]) {
$image
->setTitle($_images['title'][$_key])
->setPrimary($_images['primary'][$_key])
->setX1($_images['x1'][$_key])
->setY1($_images['y1'][$_key])
->setX2($_images['x2'][$_key])
->setY2($_images['y2'][$_key])
->setPosition($increment++)
;
}
}
}
}
}
return $this;
}
/**
* Метод сохранения изображений. Основное назначение, обработать массив изображений,
* и перенести загруженные изображения из временных директорий в стационарные
* @throws app_exception
* @return app_object_images
*/
public function storeAndSaveImages()
{
if (!isset($this->_images) || !is_array($this->_images)) {
return $this;
}
if (!$this->getImagesUploadDirectory()) {
throw app_exception("Метод сохранения изображений не может получить директорию для записи", 503);
}
foreach ($this->_images as $image) {
if (!$image->getId()) {
if (!$this->getId()) {
throw new app_exception("Ой.. Не смог скопировать изображения. Не определен id объекта", 503);
}
if (!$image->getFilename()) {
throw new app_exception("Ой.. Не смог скопировать изображения. Не определен getTempFailename()", 503);
}
$src = $image->getFilename();
$dst = $this->getImagesUploadDirectory().(substr($this->getImagesUploadDirectory(), -1, 1) != DIRECTORY_SEPARATOR ? "/" : null) . basename($image->getFilename());
if (!file_exists($src) || !is_file($src) || !is_readable($src)) {
throw new app_exception("Ой.. Файл {$src} не существует или не доступн для чтения", 503);
}
if (!file_exists(dirname($dst)) || !is_dir(dirname($dst)) || !is_writable(dirname($dst))) {
throw new app_exception("Ой.. Директория ".dirname($dst)." не существует или не доступна для записи", 503);
}
if (!copy($src, $dst)) {
throw new app_exception("Ой.. Не смог скопировать {$src} в {$dst} не существует или не доступна для записи", 503);
}
$image
->setObjectId( $this->getId() )
->setFilename( basename( $dst ))
->setDirectory( dirname($dst) )
->save()
;
} else {
$image->save();
}
}
}
}