Доработка office

Здравствуйте.
Допиливаю office под свои нужды. В частности в контроллере profile сделал загрузку фото с компьютера пользователя, а не с gravatar-а, т.е. добавил инпут типа «file» и подредактировал метод Update контроллера.
При этом, картинка обновляется только после перезагрузки странички профиля. Вопрос: как бы заставить картинку обновляться (т.е., видимо, как сделать, чтобы страничка профиля обновлялась) после щелчка по кнопке «Сохранить»?
Олег Трубин
02 сентября 2013, 07:50
modx.pro
2
1 467
0

Комментарии: 12

Василий Наумкин
02 сентября 2013, 11:54
0
А картинка нормально загружается через ajax?

Если не путаю, то Office возвращает все отправленные поля в ответе, массиве data. Если картинка нормально грузится и сохраняется, то там должно быть поле photo с url загруженного.

Надо его словить и подставить в src изображения на странице.

P.S. Контроллер было не обязательно менять. Лучше использовать плагин на событие OnBeforeUserFormSave, чтобы получить картинку, проверить и добавить в сохраняемый массив.
    Олег Трубин
    02 сентября 2013, 13:36
    0
    Картинка, нормально загружается, проверяю — лежит в нужной папке.
    В поле «photo» таблицы user_attributes — пишется правильный адрес этой картинки.
    В чанке в src подставлен плейсхолдер [[+photo]], но картинка обновляется только после перезагрузки страницы. Как бы сделать чтобы она обновлялась сразу?
      Василий Наумкин
      02 сентября 2013, 13:40
      0
      Ты с ajax запросами вообще не знаком?

      У любого запроса есть ответ, В случае с Office, в ответе массив с ключами
      * success — статус ответа
      * message — сообщение об ошибке или успехе
      * data — массив с полями профиля юзера

      Вот data тебе и надо проверить, если там есть photo, то нужно его взять и подставить на страницу. Не знаю, как еще понятнее объяснить.

        Олег Трубин
        02 сентября 2013, 15:50
        0
        В ajax, да и js мои познания оч. слабые, но «допилил» заработало.
        Спасибо, за ответы.
    Олег Трубин
    08 сентября 2013, 18:31
    0
    P.S. Контроллер было не обязательно менять. Лучше использовать плагин на событие OnBeforeUserFormSave, чтобы получить картинку, проверить и добавить в сохраняемый массив.
    Пытаюсь сделать, так, как ты сказал — через плагин на OnBeforeUserFormSave.
    Это событие вызывается когда у тебя в функции Update запускается соответствующий процессор:
    "$response = $this->office->runProcessor('profile/update', $fields);"
    Я не могу понять, как мне в плагине получить массив $fields и добавить туда нужное мне поле.
    Конечно в плагине доступен объект user, и я могу адрес картинки записать через него, но как тогда добиться чтобы этот адрес картинки попал в ответ ajax запроса?
      Василий Наумкин
      08 сентября 2013, 19:03
      1
      0
      Как будет время — постараюсь добавить это в дефолтный функционал.

      А пока держи готовое решение плагином:
      switch ($modx->event->name) {
      
      case 'OnBeforeUserFormSave':
      if ($mode != 'upd') {return;}
      $profile = $user->getOne('Profile');
      
      if (!empty($_FILES['newphoto']) && preg_match('/image/', $_FILES['newphoto']['type']) && $_FILES['newphoto']['error'] == 0) {
      	$path = 'images/users/';
      	$file = $path . md5($modx->user->id . time()).'.jpg';
      	$url = MODX_ASSETS_URL . $file;
      	$dst = MODX_ASSETS_PATH . $file;
      	
      	$tmp = explode('/', $profile->get('photo'));
      	$cur = MODX_ASSETS_PATH . $path . end($tmp);
      	$params = array(
      		'w' => 200		// Ширина
      		,'h' => 200		// Высота
      		,'bg' => 'ffffff'	// Фон
      		,'q' => 95		// Качество в %
      		,'zc' => 0		// Обрезка, TL - это Top Left, есть еще C - center, BR - Bootom Right  и т.д.
      		,'f' => 'jpg'		// Формат изображения
      	);
      	
      	if (empty($_FILES['newphoto']['tmp_name'])) {return;}
      	elseif ($profile->get('photo') && empty($_REQUEST['photo'])) {
      		if (file_exists($cur)) {unlink($cur);}
      		$profile->set('photo', '');
      		return;
      	}
      	else {
      		move_uploaded_file($_FILES['newphoto']['tmp_name'], $dst);
      		$phpThumb = $modx->getService('modphpthumb','modPhpThumb', MODX_CORE_PATH . 'model/phpthumb/', array());
      		$phpThumb->setSourceFilename($dst);
      		foreach ($params as $k => $v) {
      			$phpThumb->setParameter($k, $v);
      		}
      		if ($phpThumb->GenerateThumbnail()) {
      			if (!$phpThumb->renderToFile($dst)) {
      				$modx->log(modX::LOG_LEVEL_ERROR, 'Could not save rendered image to'.$dst);
      			}
      			if (file_exists($cur)) {unlink($cur);}
      			$profile->set('photo', $url);
      		}
      		else {$modx->log(modX::LOG_LEVEL_ERROR, print_r($phpThumb->debugmessages, 1));}
      	}
      }
      break;
        Олег Трубин
        08 сентября 2013, 22:39
        0
        Василий, за код спасибо, но он не решает главной проблемы — в ajax ответе нет картинки, и соответственно на страничке профиля она появляется только после обновления странички.
          Василий Наумкин
          09 сентября 2013, 06:54
          0
          Все просто — в ajax возвращаются все отправленные поля.

          Поэтому, надо в форме сделать так:
          <input type="hidden" name="photo" value="" />
          <input type="file" name="newphoto" />
          В поле newfile отправится загружаемый файл — именно его мы ловим в плагине.
          А скрытое поле photo нужно только для того, чтобы в ajax ответе появилось значение.
            Олег Трубин
            09 сентября 2013, 12:06
            0
            Вот про ход конём в виде скрытого инпута, я как-то не допёр. Очередное спасибо!
              Олег Трубин
              09 сентября 2013, 12:14
              0
              Возможно, кто-то будет читать нашу переписку, поэтому добавлю, что скрытое поле должно быть таким:
              <input type="hidden" name="photo" value="[[+photo]]" />
              Иначе, при изменении других полей, картинка из профиля будет будет удаляться.
                Василий Наумкин
                09 сентября 2013, 12:36
                0
                Да, верно. Куда то потерялся у меня плейсхолдер =)

                В любом случае, я очень надеюсь добавить это в родной функционал, и читать не придётся.
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      12