2017年3月27日月曜日

cakephp2 Call to undefined functionエラー

コントローラーに定義したfunctionを呼び出す際、表記エラーになった。
function定義
function isAuthorizedUserProj($proj_id) {
              ......
        }

ほかのfunctionから呼ぶ出す
        if (isAuthorizedUserProj($id)) {
              ......
        }

調べたところ、
In general you need to use $this-> when accessing class methods and variables.
ということで、if ($this->isAuthorizedUserProj($id))に変更すればOK

cakephp2のページ遷移

基本的に、actionごとにviewが用意されている。
場合によって、ほかのページに遷移する必要がある。そのとき、下記のように、「redirect」を使う。

$this->redirect(
array('controller' => 'Users', 'action' => 'login')
);

htmlのimg tag内base64画像をサーバーに送信(cakephpの場合)

<img src="data:image/jpeg;base64,/9j.....=">

このsrcの画像をサーバーに送りたい。

JS側は以下のような感じ
function asyncSend() {
      // Generate the image data
      var base64image  = $("#createdPic").attr('src');
      // Sending the image data to Server
      $.ajax({
          method: "POST",
          url: '/Projects/ajaxCall',
          data: { "base64image" : base64image },
          success: function (msg) {
              console.log("OK");
          },
          error: function (response, desc, exception) {
              console.log("NG");
          }
      });
    }

サーバー側はcakephpを使用
public function ajaxCall() {
$this->autoRender = FALSE; //Viewある場合不要
    if($this->request->is('ajax')) {
            $img = $this->request->data['base64image'];
            $img = str_replace('data:image/jpeg;base64,', '', $img);
    $img = str_replace(' ', '+', $img);
    $data = base64_decode($img); //base64_decode() でバイナリに戻す
    $file = 'image.jpeg';
    $success = file_put_contents($file, $data);
        }
}

参考:http://stackoverflow.com/questions/1532993/i-have-a-base64-encoded-png-how-do-i-write-the-image-to-a-file-in-php

Chrome キャッシュ無効化

2回ほど、ブラウザのキャッシュデータにやられて、無駄な時間を使ってしまった。
Chrome キャッシュ無効化の方法をネットで見つかった。
検証→Settingのところで、「Disable cache (while DevTools is open)」のチェックを入れること。

参考:http://qiita.com/cubdesign/items/dca4d933539235bb5f11

2017年3月24日金曜日

cakephp2におけるユーザー認証(Auth)

usersテーブルが作成され、bakeしたことを前提とする。

1)usersテーブルに下記2つ項目を定義する必要がある。
「username」と「password」

2)UsersControllerに認証権限を設定
   public function beforeFilter() {
        parent::beforeFilter();
        $this->Auth->allow('add');
    }

3)app/Controller/AppController.phpに「Auth」を追加(これらをUsersControllerに追加しても大丈夫)
class AppController extends Controller {
    //...

    public $components = array(
        'Flash',
        'Auth' => array(
            'loginRedirect' => array(
                'controller' => 'posts',
                'action' => 'index'
            ),
            'logoutRedirect' => array(
                'controller' => 'pages',
                'action' => 'display',
                'home'
            ),
            'authenticate' => array(
                'Form' => array(
                    'passwordHasher' => 'Blowfish'
                )
            )
        )
    );

    public function beforeFilter() {
        $this->Auth->allow('index', 'view');
    }
    //...
}

4)UsersControllerにlogin/logoutを定義
public function login() {
    if ($this->request->is('post')) {
        if ($this->Auth->login()) {
            return $this->redirect($this->Auth->redirectUrl());
        }
        $this->Flash->error(__('Invalid username or password, try again'));
    }
}

public function logout() {
    return $this->redirect($this->Auth->logout());
}

5)User Modelでpasswordをhashする
App::uses('AppModel', 'Model');
App::uses('BlowfishPasswordHasher', 'Controller/Component/Auth');

class User extends AppModel {

// ...

public function beforeSave($options = array()) {
    if (isset($this->data[$this->alias]['password'])) {
        $passwordHasher = new BlowfishPasswordHasher();
        $this->data[$this->alias]['password'] = $passwordHasher->hash(
            $this->data[$this->alias]['password']
        );
    }
    return true;
}

6)login functionのviewを追加
<div class="users form">
<?php echo $this->Flash->render('auth'); ?>
<?php echo $this->Form->create('User'); ?>
    <fieldset>
        <legend>
            <?php echo __('Please enter your username and password'); ?>
        </legend>
        <?php echo $this->Form->input('username');
        echo $this->Form->input('password');
    ?>
    </fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>


Authでログインしたユーザーのアクセスは以下2つ
// どこからでも利用できます。
AuthComponent::user('id')

// Controllerの中でのみ利用できます。
$this->Auth->user('id');

コントローラーで取得条件を指定することによって、ユーザーがどこまで権限があるか制御する

2017年3月23日木曜日

dpiに関して

canvasで出力された画像のdpiは96に固定されている。印刷するには、最低150dpiのものが必要とされている。どうすれば良いかいろいろ検討してみたが、結論として、パソコン画像に対して、dpiは意味を持っていない、ピクセルのみ意味がある。150dpi印刷するには、画像のdpiを上げることではなく、ピクセル数(サイズ)を上げれば良い。

以下のリンク、とても参考になった。
http://www.dpiphoto.eu/dpi.htm

2017年3月17日金曜日

jQuery オブジェクトをDOM エレメントに変換

jQuery オブジェクトの[0]はDOMです。

var dom_element = jq_obj[0];

canvas drawImage() 画像が表示されない

以下のように画面に画像を表示させたいが、うまく行かなかった。

drawFrame();
   
    function drawFrame() {
      var img = new Image();
      img.src = "./frame.jpg";
      ctx.drawImage(img, 0, 0);
    }

原因は、画像をload完了しないまま、drawImageが実行してしまった。
onloadを追加してあげると、解決できた。

  img.onload = function() {
        ctx.drawImage(img, 0, 0);
      }

2017年3月15日水曜日

jsで二次配列を使うには

var orgSize = [];
orgSize[j]['width'] = img.width;

というふうにorgSizeを二次配列として使おうが、エラーになった。

orgSize[j] = new Array();
のように、さらに配列宣言をしないといけない。

2017年3月10日金曜日

JQuery id セレクタに変数と配列を使う場合

document.getElementById( "caseFrame" ).innerHTML += '<div class = "drag" style="display:inline-block"><img id="upload-pic[' + memory_file_counter + ']" src="' + dataUri + '"></div>' ;

ここで[0]みたいようなidを指定する必要があります。
var resizeId = '#upload-pic\\[' + memory_file_counter + '\\]';
$(resizeId).resizable();

\\で[や]など特殊文字を変換、+で変数を入れる。

2017年3月6日月曜日

jquery attr error

下記のコマンドを実行したら、エラーになった。

upload_pic = $('[name^=upload-pic]');
var attr_style = upload_pic[0].attr('style');
console.log(attr_style);

Uncaught TypeError: upload_pic[0].attr is not a function

調べてみたら、upload_pic[0]はplain DOM elementsのため、.attrを使うには、 jQuery objectに変換する必要があります。
var attr_style = $(upload_pic[0]).attr('style');

2017年3月3日金曜日

PHPで複数のfileをupload

HTML側
<form method="POST" enctype="multipart/form-data" action="merge.php">
<input type="file" name="upload_file[]" multiple id="file">
<input type="submit" name="submit" value="upload" />

PHP側
<?php
if(count($_FILES['upload_file'])) {
    foreach($_FILES['upload_file'] as $file) {
        print_r($file);
    }
}

参考:https://davidwalsh.name/multiple-file-upload

2017年3月2日木曜日

HTML5 File API

<input type="file" multiple id="file">  //multipleあれば、複数ファイルを選択できる

document.getElementById( "file" ).addEventListener( "change", function() {
 var fileList = this.files ;  //this.filesはFileListオブジェクト
 for( var i=0,l=fileList.length; l>i; i++ ) {
  var fileReader = new FileReader() ; //インスタンスを作成
  fileReader.readAsDataURL( fileList[i] ) ;  // ファイルをデータURIとして読み込む

//読み込みが成功して完了した場合、HTMLを書き出す
  fileReader.onload = function() {
   var dataUri = this.result ;
   document.getElementById( "output" ).innerHTML += '<img src="' + dataUri + '">' ;
  } 
 }
} ) ;
参考:
https://syncer.jp/javascript-reverse-reference/output-local-image
https://app.codegrid.net/entry/file-api-filereader-api

複数のfileをuploadするには

<input type="file" multiple id="file">