CakePHP URLから画像をダウンロードして特定のディレクトリに保存する

notoです。 画像をURLから特定のディレクトリに保存したい時はありませんか。さらにバリデーションなんてかけたい時はありませんか。ありますよね。あるはずです。

検証環境

  • CakePHP1.3.x
  • PHP5.3.8

URLから画像データを取得する

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private function fetchFromUrl($url) {

    $data['name'] = end(explode('/', $url));
    $data['tmp_name'] = tempnam(sys_get_temp_dir(), $data['name']) . '.' . end(explode('.', $url));

    App::import('Core', 'HttpSocket');
    $httpSocket = new HttpSocket();

    $raw = $httpSocket->get($url);
    $response = $httpSocket->response;

    $data['size'] = strlen($raw);
    $data['type'] = reset(explode(';', $response['header']['Content-Type']));

    file_put_contents($data['tmp_name'], $raw);
    return $data;
}

解説

やっていることは単純でフォームから画像をアップロードした際、controllerが受け取るデータの形は

1
2
3
4
5
6
7
array(
    'name' => '',
    'tmp_name' => '',
    'size' => '',
    'type' => ''
    -- 中略 --
)

こんな感じになっています。そのデータの形を作り上げているわけです。

URLから取得した画像データのバリデーションを行う

app/model/hoge.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public $validate = array(
    //バリデーションルール
);

public function beforeValidate() {
    $this->data[$this->alias][field_name] = $this->fetchFromUrl($this->data[$this->alias][field_name])
}

private function fetchFromUrl($url) {

    $data['name'] = end(explode('/', $url));
    $data['tmp_name'] = tempnam(sys_get_temp_dir(), $data['name']) . '.' . end(explode('.', $url));

    App::import('Core', 'HttpSocket');
    $httpSocket = new HttpSocket();

    $raw = $httpSocket->get($url);
    $response = $httpSocket->response;

    $data['size'] = strlen($raw);
    $data['type'] = reset(explode(';', $response['header']['Content-Type']));

    file_put_contents($data['tmp_name'], $raw);
    return $data;
}

解説

バリデーションをかけたい場合はどうするかというと、beforeValidateを利用します。

beforeValidateは、名前の通りvalidatesを行う前の処理を定義します。 beforeValidate内で、fetchFromUrlメソッドを呼び出すことでバリデーションの前準備をしてあげることになります。

あとはbeforeSaveでよしなにしてもらって、afterSaveでさらによしなにしてもらえればいけますよ!! 投げっぱなしはあれなので、この辺りの処理を行なってくれるプラグインを紹介したいと思います。

UploadPackプラグイン

uploadpack

ここに記載したコードもuploadpackをパク参考にしたものです。 uploadpackプラグインでは、beforeSaveや、afterSaveの処理も投げっぱなしにしてません。ちゃんと書いてあります。

しかし、masterをみると CakePHP2.x系に対応させているようなのでCakePHP1.x系を利用される方は注意してください。

Comments