CakePHP2.x 画像アップロードフォームの実装まとめ

CakePHP2.x 画像アップロードフォームの実装まとめ

CakePHP2.x 画像アップロードフォームを実装したのでまとめておきます。

ユーザマイページにユーザアイコンを登録する良くある箇所の例です。

環境 PHP7.0 CakePHP2.10.2

コントローラー UsersController.php

  /**
   * マイページ・ユーザアイコンの保存
   *
   * @param
   * @return
   */
  public function index() {
    // ユーザアイコンの初期表示
    $user = $this->Auth->user();
    $usersIcon = $this->UsersIcon->findByUserId($user['id']);
    $this->set('hasUsersIcon', isset($usersIcon['UsersIcon']['user_icon']) ? true : false);

    if (!$this->request->is('post')) {
      return;
    }

    // ユーザアイコンの入力チェック
    if (empty($this->request->data['UsersIcon']['user_icon']['tmp_name'])) {
      $this->Flash->error('画像が選択されていません。', array('clear' => true));
       return $this->redirect($this->referer());
    }
    if (!is_uploaded_file($this->request->data['UsersIcon']['user_icon']['tmp_name'])) {
      $this->Flash->error('アップロードされた画像ではありません。', array('clear' => true));
       return $this->redirect($this->referer());
    }
    $iconSizeLimit = 1024 * 1024;
    if ($this->request->data['UsersIcon']['user_icon']['size'] > $iconSizeLimit) {
      $this->Flash->error('画像サイズが大きすぎます。1MB以内の画像が登録可能です。', array('clear' => true));
       return $this->redirect($this->referer());
    }

    // ユーザアイコンの保存
    $saveData = array();
    if ($usersIcon) {
      $saveData['id'] = $usersIcon['UsersIcon']['id'];
    }
    $saveData['user_id'] = $user['id'];
    $saveData['user_icon'] = file_get_contents($this->request->data['UsersIcon']['user_icon']['tmp_name']);
    $this->UsersIcon->save($saveData);

    $this->Flash->success('ユーザアイコンを保存しました。', array('clear' => true));

    // アイコン表示の為リダイレクト
    return $this->redirect($this->referer());
  }
  /**
   * ユーザアイコンの表示
   *
   * @param int $userId
   * @return
   */
  public function showUsersIcon($userId) {
    $this->layout = false;
    $usersIcon = $this->UsersIcon->findByUserId($userId);
    if (empty($usersIcon)) {
      // ユーザアイコンを保有しないユーザのデフォルトアイコン
      if ($this->User->exists($userId)) {
        header('Content-type: image/jpeg');
        readfile('img/user_default_icon.png');
        exit;
      }
      throw new NotFoundException(Configure::read('404_message'));
    }
    header('Content-type: image/jpeg');
    echo $usersIcon['UsersIcon']['user_icon'];
  }

  /**
   * ユーザアイコンの削除
   *
   * @param int $userId
   * @return
   */
  public function deleteUsersIcon() {
    if (!$this->request->is('post')) {
      return $this->redirect(array('controller' => 'users', 'action' => 'index'));
    }
    $user = $this->Auth->user();
    $conditions = array(
      'user_id' => $user['id'],
    );

    $this->UsersIcon->deleteAll($conditions);

    $this->Flash->success('ユーザアイコンを削除しました。', array('clear' => true));

    // アイコン非表示の為リダイレクト
    return $this->redirect(array('controller' => 'users', 'action' => 'index'));
  }

コメント以外でちょっと補足です。

DBはusersテーブルとusers_iconsテーブルがあります。

画像はカラム `user_icon` MEDIUMBLOB, に保存しました。

上記のマイページはログイン状態でないと入れません。

ispostチェックのところまでが初期表示用で、以降が画像保存ボタンを押した時の処理です。

ビュー index.ctp

          echo $this->Form->create('UsersIcon', array('type' => 'file'));
          echo $this->Form->input('user_icon', array('type' => 'file', 'label' => 'ファイルを選択', 'style' => 'display:none;'));
          echo $this->Form->button('保存する');
          echo $this->Form->end();
          if ($hasUsersIcon) {
            echo $this->Html->image('/users/showUsersIcon/' . $user['id'], array('class' => 'user_icon'));

            echo $this->Form->create('User', array('url' => array('controller' => 'users', 'action' => 'deleteUsersIcon')));
            echo $this->Form->button('削除する');
            echo $this->Form->end();
          }

補足です。

  • ファイルを選択ボタン
  • 保存するボタン
  • 削除するボタン

のボタンがあります。

ファイルを選択ボタンをdisplay:none;にしてある理由はデフォルトボタンだと、ブラウザ依存で勝手に「ファイルを選択していません」とかの文字が入って枠外に飛び出てしまいました。

しかもブラウザによって文言が違うのでこれを非表示にしたかったのです。そしてラベルだけでボタンの装飾を実装しました。

CSS ボタン装飾

/* ユーザアイコン登録フォームボタン */
.user_icon_form label, .user_icon_form button {
  height: 24px;
  margin: 0;
  padding: 0 16px;
  margin: 5px;
  display: inline-block;
  font-size: 14px;
  line-height: 24px;
  vertical-align: middle;
  min-width: 64px;
  color: #555;
  background-color: #eee;
  border: solid 1px #bbb;
  border-radius: 2px;
  box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
}
.user_icon_form label:hover, .user_icon_form button:hover {
  cursor: pointer;
}

補足です。

ビュー側の補足に書いたようにラベルをボタン風にする必要がありました。

あとは普通の「保存」「削除」ボタンの装飾です。

ユーザデフォルトアイコンについて

こっちに書きました。

https://normalblog.net/system/cakephp2-x-user-icon/

ファイル保存・DB保存について

https://normalblog.net/system/file_uploads/

Comments

No comments yet. Why don’t you start the discussion?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です