класс Foto

Baranov_Dron

Новичок
класс Foto

Пример приведённый тут слегка упрощён, от требуемой задачи, для наглядности.
Использую symfony + phpDoctrinePlugin.

Есть форма добавления статьи, в ней можно вписывать теги данной статьи, название, текст, дату и выбрать изображения для заливки.
Потом скрипт добавляет изображения в папку uploads, и записывает в БД 1 запись в таблицу articles и несколько записей в таблицу foto.
Ну при отображение есть статья и внизу блок с превью картинок. По нажатию будет полное изображение в новом окне, всё понятно...

Идём дальше, есть класс
abstract class BaseArticles extends sfDoctrineRecord
{}
в котором указываются свойства таблицы, и от него наследуется класс
class Articles extends BaseArticles
{}
Ну и тоже самое с классом foto.
Дальше в контролере мы создаём запись типа
PHP:
$art = new Articles;
$art->title = $request->getParameter('title');
$art->text = $request->getParameter('text') ;
     $this->foto[]->name = 'test';
     $this->foto[]->name = 'test';
$art->save();
Ну теперь самое интересное и сложное для меня, кто должен отвечать за заливку фото, а также добавление его в БД?
Я решил проблему следующим образом,
перегрузил метод save()
PHP:
class Foto extends BaseFoto
{
    public $file_object;

    public function setFileObject($file)
    {
        $this->file_object = $file;
    }

     public function save(Doctrine_Connection $conn = null)
    {
        $file = $this->file_object;

        $svimage = getimagesize($file->getTempName());

        $this->extension = $file->getExtension($file->getOriginalExtension());
		$this->filesize = $file->getSize();
		$this->height = $svimage[1];
		$this->width = $svimage[0];
		$this->date = date('Y-m-d H:i:s');

        parent::save($conn);

	    $file->save(sfConfig::get('sf_upload_dir').'/board/'.$this->id.$this->extension);
    }

    public function getRealName()
    {
        return $this->id.$this->extension;
    }
}

Теперь вызов выглядит наподобие
PHP:
$art = new Articles;
$art->title = $request->getParameter('title');
$art->text = $request->getParameter('text') ;
     $this->foto[]->name = 'test';
     $this->foto[]->setFileObject($this->getValue('foto1'));
     $this->foto[]->name = 'test';
     $this->foto[]->setFileObject($this->getValue('foto2'));
$art->save();

Тоесть перетаскиванием изображения с временного хранилища в нужную папку занимается класс Foto, но у меня есть большие сомнения в правильности решения, например в таблице фото имеется столбец булевого типа preview, тоесть есть ли превью, и если нету, чтоб дать демону, запускаемому кроном понять, что для этого изображения сделать preview и значение столбика из false сделать в TRUE.
Но тогда класс Foto отвечает:
1) за создание preview
2) за заливку изображений
3) за добавление информации о изображение в БД
4) за удаление(строки в таблице + самих файлов рисунков)
5) и т.д.

Но по сути правильно ли, что класс foto занимается такими задачами?!
Я вообще думал, что этот класс должен только работать с БД.
И вопрос к пользователям доктрины! Ничего страшного не случится при перегрузки метода save и delete, вроде не должно, но всё же?
 
ты верно сделал, только добавь ещё обработчик на удаление записи.
Я вообще думал, что этот класс должен только работать с БД.
в принципе, так оно и получается. если бы приходило вместо файла его содержимое, тебя же не мучала бы сомнения

-~{}~ 16.09.08 02:11:

вот только перегружать метод save не следует, тебе нужны
preInsert, postInsert для вставки
postDelete для удаления
preUpdate, postUpdate при апдейте
 
AmdY cпасибо за ответ.
Остаётся только два вопроса
1) Передача объекта с фотографией в класс Foto, правильно ли так передавать?
PHP:
class Foto extends BaseFoto 
{
    public $file_object;

    public function setFileObject($file)
    {
        $this->file_object = $file;
    } 
............................
}
2) кто должен делать preview?
Тоесть у меня preview делается cron`ом. Будет ли правильно если в кроне будет что-то наподобие
PHP:
<?php
$foto = new Foto;
for ($i =1; $i <= 10; $i++)
{
    if (!$foto->makeOnePreview())
        break;
}
?>
А метод makeOnePreview() класса Foto будет уже искать одну строчку в таблице foto и делать для одного фото preview, и если всё сделал, то возращает TRUE, а если нету строк для работы, то возратит FALSE...
Правильно ли будет сделать так?
 
это неверный подход, ведь не нужно забывать, что Foto extends BaseFoto в свою очередь унаследовано от Doctrine_Record, что подразумневает работу непосредственно с записью, а не всей таблицей.
$collection = Doctrine::getTable('Foto')->findByMake_preview(1);
foreach($collection AS $item) {
$item->makePreview();
}
 
время...
просто на генерацию превью уходит около 3-4 секунд(для пяти фото), что я считаю неприемлемым.
я тему создавал о этом
http://phpclub.ru/talk/showthread.php?s=&threadid=106551
 
Ну теперь самое интересное и сложное для меня, кто должен отвечать за заливку фото, а также добавление его в БД?
я так сделал:

в контроллере:

PHP:
    // проверка изображений на валидность
    private function checkImage()
    {
        global $_CONFIG;
        
        $this->uploads = array();
        
        if (isset($_FILES['article_image']))
        {
            foreach ($_FILES['article_image']['name'] as $id => $__)
            {
                // параметры изображения из FILES
                $fromFiles = array
                (
                    'name'     => &$_FILES['article_image']['name'][$id],
                    'type'     => &$_FILES['article_image']['type'][$id],
                    'tmp_name' => &$_FILES['article_image']['tmp_name'][$id],
                    'error'    => &$_FILES['article_image']['error'][$id],
                    'size'     => &$_FILES['article_image']['size'][$id],
                    'current'  => &$_POST['current'][$id]
                );
                
                // создаем новый объект изображения
                $img = new newArticleImage($fromFiles);
                $img->setTempDirectory($_CONFIG['dir']['temp']);
                $img->setImageName(translit::UrlTranslit($_POST['article_image_name'][$id]));
                $img->setUploadDir($_CONFIG['dir']['images']['articles']['normal']);
                $img->checkFile();
                
                // сохраняем объект в массиве uploads
                $this->uploads[$id] = $img;
            }
        }
    }
}

далее, в контроллере, методе сохранения статьи:

PHP:
// если есть инициализированные объекты изображений
if ($this->uploads)
{
    foreach ($this->uploads as $img)
    {
        // картинко сохранили 
        if ($img->saveFile($this->id_article))
        {
            // ресайзим 
            $img->setFileSize($_CONFIG['params']['normal_configs']);
            
            // записываем инфо в БД о картинко 
            $this->article->setImageInfo($img);
            
            // делаем 3 превью  картико (3 - потому, что так дизайнер сказало)
            foreach ($_CONFIG['dir']['images']['articles']['preview'] as $id => $dir)
            {
                $img->makePreview($dir, $_CONFIG['params']['preview_configs'][$id]);
            }
        }
    }
}
 
Сверху