Здесь показаны различия между двумя версиями данной страницы.
Both sides previous revision Предыдущая версия Следущая версия | Предыдущая версия | ||
eaze:samples:добавление_фотогалереи_в_vt_к_объекту [2011/09/21 09:49] sergeyfast |
eaze:samples:добавление_фотогалереи_в_vt_к_объекту [2011/09/21 11:30] (текущий) sergeyfast |
||
---|---|---|---|
Строка 266: | Строка 266: | ||
===== SaveEntityAction.php ===== | ===== SaveEntityAction.php ===== | ||
Прежде всего мы должны помнить о том, что albums у объекта Entity - лист. ''EntityFactory::GetById( $id, array( BaseFactory::WithLists => true ) )'' выберет только альбомы, без фотографий. Фотографии будем выбрать вручную. | Прежде всего мы должны помнить о том, что albums у объекта Entity - лист. ''EntityFactory::GetById( $id, array( BaseFactory::WithLists => true ) )'' выберет только альбомы, без фотографий. Фотографии будем выбрать вручную. | ||
- | Создадим метод ''refillAlbumPhotos()'', который добавляет к альбомам фотографии | + | Создадим метод ''refillAlbumPhotos()'', который добавляет к альбомам фотографии. |
<code php> | <code php> | ||
protected function refillAlbumPhotos( $object ) { | protected function refillAlbumPhotos( $object ) { | ||
Строка 280: | Строка 280: | ||
} | } | ||
} | } | ||
+ | </code> | ||
+ | * дополнительно в EntityPhotoFactory мы добавили поиск по entityId. | ||
+ | |||
+ | Далее сделаем так, чтобы фотографии грузились только тогда, когда мы открыли объект для редактирования. | ||
+ | <code php> | ||
+ | /** | ||
+ | * Set Json Albums Data to Template | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function beforeSave() { | ||
+ | if ( $this->action != self::UpdateAction && !empty( $this->currentObject->entityId ) ) { | ||
+ | $this->refillAlbumPhotos( $this->currentObject ); | ||
+ | } | ||
+ | |||
+ | Response::setParameter( 'data', EntityAlbumUtility::PrepareAlbumsData( $this->currentObject ) ); | ||
+ | } | ||
+ | </code> | ||
+ | * EntityAlbumUtility::PrepareAlbumsData() - метод, который подготавливает переменную ''data'' для шаблона photos.tmpl.php. | ||
+ | |||
+ | Теперь, если у объекта есть альбомы и фотографии, то мы уже увидим их в шаблоне :). | ||
+ | |||
+ | Добавим валидацию альбомов и фотографий. | ||
+ | <code php> | ||
+ | protected function validate( $object ) { | ||
+ | $errors = parent::$factory->Validate( $object ); | ||
+ | |||
+ | $albumErrors = EntityAlbumUtility::ValidateAlbums( $object->albums ); | ||
+ | if ( !empty( $albumErrors ) ) { | ||
+ | $errors['fields']['photos']['format'] = 'format'; | ||
+ | Response::setParameter( 'albumErrors', $albumErrors ); | ||
+ | } | ||
+ | |||
+ | return $errors; | ||
+ | } | ||
+ | </code> | ||
+ | * fields => photos поможет нам подсветить таб "Фотографии", если на нем были ошибки (''<div data-row="**photos**"...'' в photos.tmpl.php) и не дать сохранить ошибочный объект в базу. | ||
+ | |||
+ | Теперь можно перейти к сохранению. Для этого сначала нужно заполнить $originalObject фотографиями (в оригинальном объекте они нужны для того, чтобы удалить те фотографии, которые мы удалили с формы). | ||
+ | <code php> | ||
+ | protected function beforeAction() { | ||
+ | if ( !empty( $this->originalObject ) ) { | ||
+ | $this->refillAlbumPhotos( $this->originalObject ); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | add() и update() будут обернуты в транзакцию. | ||
+ | <code php> | ||
+ | /** | ||
+ | * Add Object | ||
+ | * | ||
+ | * @param Entity $object | ||
+ | * @return bool | ||
+ | */ | ||
+ | protected function add( $object ) { | ||
+ | ConnectionFactory::BeginTransaction(); | ||
+ | |||
+ | $result = parent::$factory->Add( $object, array( BaseFactory::WithReturningKeys => true ) ); | ||
+ | $result = $result && EntityAlbumUtility::SaveAlbums( $object, $this->originalObject ); | ||
+ | |||
+ | ConnectionFactory::CommitTransaction( $result ); | ||
+ | |||
+ | return $result; | ||
+ | } | ||
+ | |||
+ | |||
+ | /** | ||
+ | * Update Object | ||
+ | * | ||
+ | * @param Entity $object | ||
+ | * @return bool | ||
+ | */ | ||
+ | protected function update( $object ) { | ||
+ | ConnectionFactory::BeginTransaction(); | ||
+ | |||
+ | $result = parent::$factory->Update( $object ); | ||
+ | $result = $result && EntityAlbumUtility::SaveAlbums( $object, $this->originalObject ); | ||
+ | |||
+ | ConnectionFactory::CommitTransaction( $result ); | ||
+ | | ||
+ | return $result; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Последний штрих. При сохранении фоток мы не получаем их идентификаторы, из-за этого неправильно работает кнопка "Применить" в режиме редактирование. Исправляется это путем переполучения фотографий только при успешном сохранении. | ||
+ | <code php> | ||
+ | protected function afterAction( $success ) { | ||
+ | if ( $this->redirect == 'view' && $success ) { | ||
+ | $this->refillAlbumPhotos( $this->currentObject ); | ||
+ | Response::setParameter( 'data', EntityAlbumUtility::PrepareAlbumsData( $this->currentObject ) ); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Не забудьте посмотреть код [[eaze:samples:добавление_фотогалереи_в_vt_к_объекту_EntityAlbumUtility.php|EntityAlbumUtility.php]]. | ||
+ | |||
+ | |||
+ | ====== Итог ====== | ||
+ | Поставленной цели мы добились. Можно было бы конечно сделать массовый загрузчик на flash и потом и мышкой раскидать фотографии по альбомам, но для этого нужно написать ещё больше javascript'а. | ||
+ | |||
+ | Осталось рассмотреть плюсы и минусы подхода. | ||
+ | |||
+ | ===== Плюсы ===== | ||
+ | * Не нужно дополнительно обрабатывать получение связанных объектов из формы на PHP (albums, photos). | ||
+ | * Не нужно дублировать шаблон отображения album и photo сначала в PHP, потом на JS. Всего используется один шаблон. | ||
+ | * Минимальное количество кода в SaveEntityAction (в основном - только получение листов второго и последующих уровней). | ||
+ | |||
+ | ===== Минусы ===== | ||
+ | * GetFromRequest на втором уровне получает каждый объект через GetById (соответственно сколько файлов - столько запросов при сохранении). //можно исправить, но сложновато// | ||
+ | * Если сохранить страницу при выключенном JS - то все фотографии удалятся (потому что не пришли с формы). //можно исправить через дополнительную переменную, которая выставляется через JS// | ||
+ | * При сохранении страницы для не измененных данных каждый раз выполняется UPDATE. //можно исправить путем добавления проверки на эквивалентность объектов// | ||
+ | |||
+ | //Ещё раз повторюсь, что данный пример не претендует на идеальность и универсальность. Он пытается рассказать, как работать в VT со сложными объектами. Пожелания и дополнения приветствуются. ;)// | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ |