Controllerで全国の都市のテーブルを引っ張る

NationwidesController.phpを作ります。

<?php

namespace App\Controller;

use Cake\ORM\TableRegistry;  

class NationwidesController extends AppController
{	
	public function initialize()
    {
         parent::initialize();
         $this->Sapporos = TableRegistry::get('sapporos');
         $this->Kushiros = TableRegistry::get('kushiros');
         $this->Sendais = TableRegistry::get('sendais');
         $this->Niigatas = TableRegistry::get('niigatas');
         $this->Kanazawas = TableRegistry::get('kanazawas');
         $this->Yokohamas = TableRegistry::get('Yokohamas');
         $this->Marunouchis = TableRegistry::get('Marunouchis');
         $this->Nagoyas = TableRegistry::get('nagoyas');
         $this->Osakas = TableRegistry::get('osakas');
         $this->Hiroshimas = TableRegistry::get('hiroshimas');
         $this->Kochis = TableRegistry::get('kochis');
         $this->Fukuokas = TableRegistry::get('fukuokas');
         $this->Kagoshimas = TableRegistry::get('kagoshimas');
         $this->Nahas = TableRegistry::get('nahas');
    }

	public function index()
	{
		$this->viewBuilder()->layout('my_layout');
		$now = date("Y-m-d H:i:s");
		$params = array(
		    'conditions' => array(
		        'forecast >' => $now, 
		    ),
		);
		$sapporos = $this->Sapporos->find('all', $params)->limit(8);
		$kushiros = $this->Kushiros->find('all', $params)->limit(8);
		$sendais = $this->Sendais->find('all', $params)->limit(8);
		$niigatas = $this->Niigatas->find('all', $params)->limit(8);
		$kanazawas = $this->Kanazawas->find('all', $params)->limit(8);
		$marunouchis = $this->Marunouchis->find('all', $params)->limit(8);
		$yokohamas = $this->Yokohamas->find('all', $params)->limit(8);
		$nagoyas = $this->Nagoyas->find('all', $params)->limit(8);
		$osakas = $this->Osakas->find('all', $params)->limit(8);
		$hiroshimas = $this->Hiroshimas->find('all', $params)->limit(8);
		$kochis = $this->Kochis->find('all', $params)->limit(8);
		$fukuokas = $this->Fukuokas->find('all', $params)->limit(8);
		$kagoshimas = $this->Kagoshimas->find('all', $params)->limit(8);
		$nahas = $this->Nahas->find('all', $params)->limit(8);
		$this->set(compact('sapporos'));
		$this->set(compact('kushiros'));
		$this->set(compact('sendais'));
		$this->set(compact('niigatas'));
		$this->set(compact('kanazawas'));	
		$this->set(compact('marunouchis'));
		$this->set(compact('yokohamas'));
		$this->set(compact('nagoyas'));
		$this->set(compact('osakas'));
		$this->set(compact('hiroshimas'));
		$this->set(compact('kochis'));
		$this->set(compact('fukuokas'));
		$this->set(compact('kagoshimas'));
		$this->set(compact('nahas'));
	}
}
?>

viewにちゃんとデータが入っているようです。
釧路-7.5°C って本当でしょうか? ん?

全国の都市のテーブルをつくる

city.list.jsonから、都市名を抽出します。
Sapporo-shi, Kushiro, Sendai-shi, Niigata-shi,Kanazawa-shi
Nagoya-shi, Osaka-shi, Hiroshima-shi, Kochi-shi, Fukuoka-shi
Kagoshima-shi, Naha-shi

それぞれ、cake用に、sをつけてテーブルをつくります。

create table weather.nahas(
	id int unsigned auto_increment primary key,
	forecast datetime,
	main varchar(255),
	description varchar(255),
	temp float,
	humidity int,
	cloud int,
	speed float,
	created datetime default null
);

sapporos, kushiros, sendais, niigatas, kanazawas, nagoyas,
osakas, hiroshimas, kochis, fukuokas, kagoshimas, nahas

kushiroは二つあるので注意が必要ですね。longitudeが144の方が北海度の釧路です。

{
    "id": 2129376,
    "name": "Kushiro",
    "country": "JP",
    "coord": {
      "lon": 144.374725,
      "lat": 42.974998
    }

{
    "id": 1858025,
    "name": "Kushiro",
    "country": "JP",
    "coord": {
      "lon": 135.416672,
      "lat": 34.799999
    }

テーブルが出来たので、データをDBに入れていきます。
まず、sapporoから。

問題なく入ってますね。

問題なさそうなので、一気に入れます。と思ったら、早速レコードに重複が出たのでやり直しのようです。(涙)
forecast datetime unique 修正にして、改めて一気にいれます。

<?php
require "sapporos.php";
require "kushiros.php";
require "sendais.php";
require "niigatas.php";
require "kanazawas.php";
require "marunouchis.php";
require "yokohamas.php";
require "nagoyas.php";
require "osakas.php";
require "hiroshimas.php";
require "kochis.php";
require "fukuokas.php";
require "kagoshimas.php";
require "nahas.php";
?>

面倒そうでしたが、やってみると案外サクサクいきましたね。

javascriptで配列に追加

配列に追加はpushを使います。

var icon = [];
var list = JSON.parse('');
for (var i = 0; i < list.length; i++){
	if(list[i] =='Clear'){
	 icon.push('/img/icon05.png');
	}else if(list[i] =='Clouds'){
	 icon.push('/img/icon06.png');
	} else{
	 icon.push('/img/icon07.png');
	}
}

下記のような書き方だと、配列iconの値は1つだけになります。

var icon = [];
var list = JSON.parse('');
for (var i = 0; i < list.length; i++){
	if(list[i] =='Clear'){
	 icon = '/img/icon05.png';
	}else if(list[i] =='Clouds'){
	 icon = '/img/icon06.png';
	} else{
	 icon = '/img/icon07.png';
	}
}

嵌ってしまった。。。

controllerのlimitの使い方

findの後に->limit(n)で繋げます。

public function index()
	{
		$this->viewBuilder()->layout('my_layout');
		$now = date("Y-m-d H:i:s");
		$params = array(
		    'conditions' => array(
		        'forecast >' => $now, 
		    ),
		);
		$marunouchis = $this->Marunouchis->find('all', $params)->limit(3);
		$yokohamas = $this->Yokohamas->find('all', $params);	
		$this->set(compact('marunouchis'));
		$this->set(compact('yokohamas'));
	}
}

$paramのconditionsに追記するとエラーになりますね。

weather mapの情報を元に、google mapのアイコンを変える

埼玉のテーブルはまだ作っていませんが、暫定として、

<style>
#map {
		height: 250px;
		width: 100%;
        font-size:small;
        margin-bottom:10px;
	}
</style>

<?php
	$this->assign('title', '首都圏の天気予報');
?>
<?= $this->element('module'); ?>

<h1>首都圏の今日明日の天気予報</h1>
<div id="map"></div>
<b><a href="marunouchis">東京</a></b>
<table class="table1">
	<tr>
	<?php 
	$i = 1;
	foreach ($marunouchis as $marunouchi){
	if($i < 9){
	echo "<td width=\"150px\">";
	echo h($marunouchi->forecast)."<br>";
	$date = h($marunouchi->forecast);
	$result = substr($date, -8);
	if($result == ' 9:00 PM' or $result == '12:00 AM' or $result == ' 3:00 AM'){
	echo convert3(($marunouchi->main))."<br>";
	} else {
	echo convert(($marunouchi->main))."<br>";
	}
	echo convert2(($marunouchi->description))."<br>";
	echo "気温".h($marunouchi->temp)."°C<br>";
	echo "湿度". h($marunouchi->humidity)."%<br>";
	echo "雲の量".h($marunouchi->cloud)."<br>";
	echo "風速".h($marunouchi->speed)."m<br>";
	echo "<td>";
	if($result == '12:00 PM'){
		$mmain = json_encode(h($marunouchi->main));
	}
	}
	$i++;
	}
	?>
	</tr>
</table>

<b><a href="yokohamas">横浜</a></b>
<table class="table1">
	<tr>
	<?php 
	$i = 1;
	foreach ($yokohamas as $yokohama){
	if($i < 9){
		echo "<td width=\"150px\">";
		echo h($yokohama->forecast)."<br>";
		$date = h($yokohama->forecast);
		$result = substr($date, -8);
		if($result == ' 9:00 PM' or $result == '12:00 AM' or $result == ' 3:00 AM'){
		$value = convert3(($yokohama->main))."<br>";
		} else {
		$value = convert(($yokohama->main))."<br>";
		}
		echo $value;
		echo convert2(($yokohama->description))."<br>";
		echo "気温".h($yokohama->temp)."°C<br>";
		echo "湿度". h($yokohama->humidity)."%<br>";
		echo "雲の量".h($yokohama->cloud)."<br>";
		echo "風速".h($yokohama->speed)."m<br>";
		echo "<td>";
		if($result == '12:00 PM'){
		$ymain = json_encode(h($yokohama->main));
		}
	  }
	$i++;
	}
	?>
	</tr>
</table>

<script>
var mmain = JSON.parse('<?php echo $mmain; ?>');
if(mmain =='Clear'){
 var micon = '/img/icon05.png'
}else if(ymain =='Clouds'){
 var micon = '/img/icon06.png'
} else{
 var micon = '/img/icon07.png'
}
var ymain = JSON.parse('<?php echo $ymain; ?>');
if(ymain =='Clear'){
 var yicon = '/img/icon05.png'
}else if(ymain =='Clouds'){
 var yicon = '/img/icon06.png'
} else{
 var yicon = '/img/icon07.png'
}

var map;
var marker = [];
var infoWindow = [];
var markerData = [ 
  {
       name: '東京',
       lat: 35.681167,
        lng: 139.767052,
        icon: micon
 }, {
        name: '横浜',
     	lat: 35.469716,
        lng: 139.629184,
        icon: yicon
 }, {
        name: '埼玉',
     lat: 35.861729,
      lng: 139.645482,
      icon: '/img/icon06.png'
 }
];
 
function initMap() {
    var mapLatLng = new google.maps.LatLng({lat: 35.681167, lng: 139.767052}); 
   map = new google.maps.Map(document.getElementById('map'), { 
     center: mapLatLng, 
      zoom: 9
   });
 
 // マーカー毎の処理
 for (var i = 0; i < markerData.length; i++) {
        markerLatLng = new google.maps.LatLng({lat: markerData&#91;i&#93;&#91;'lat'&#93;, lng: markerData&#91;i&#93;&#91;'lng'&#93;});
        marker&#91;i&#93; = new google.maps.Marker({ 
         position: markerLatLng, 
            map: map
       });
 
     infoWindow&#91;i&#93; = new google.maps.InfoWindow({ 
         content: '<div class="map">' + markerData[i]['name'] + '</div>' 
       });
 
     markerEvent(i);
 }
   for (var i = 0; i < markerData.length; i++) {
   marker&#91;i&#93;.setOptions({
        icon: {
         url: markerData&#91;i&#93;&#91;'icon'&#93;
       }
   });
   }
}
 
function markerEvent(i) {
    marker&#91;i&#93;.addListener('click', function() {
      infoWindow&#91;i&#93;.open(map, marker&#91;i&#93;);
  });
}
</script>
<script async defer
src = "https:maps.googleapis.com/maps/api/js?key=not watch&callback=initMap">
</script>

大分できてきました。

あとは全国の天気ですね。

cakeのviewでjavascript

scriptタグで書けば、普通に表示されます。

<script>
var map;
    function initMap(){
        map = new google.maps.Map(document.getElementById('map'),{
            center:{lat: 35.681167, lng: 139.767052},
            zoom: 8
        });
    }
</script>
<script async defer
src = "https:maps.googleapis.com/maps/api/js?key=&callback=initMap">
</script>

天気のラベルを渡したいですね。

cakeで複数のテーブルを参照するページをつくる

例えば、丸の内と横浜のデータを引っ張て来て、首都圏の天気として表示させてたいとする。
その場合は、controllerで “use Cake\ORM\TableRegistry;” を使って、テーブルを定義する。

<?php

namespace App\Controller;

use Cake\ORM\TableRegistry;  

class TestsController extends AppController
{	
	public function initialize()
    {
         parent::initialize();
         $this->Yokohamas = TableRegistry::get('Yokohamas');
         $this->Marunouchis = TableRegistry::get('Marunouchis');
    }

	public function index()
	{
		$this->viewBuilder()->layout('my_layout');
		$now = date("Y-m-d H:i:s");
		$params = array(
		    'conditions' => array(
		        'id' => '1', 
		    ),
		);
		$marunouchis = $this->Marunouchis->find('all', $params);
		$yokohamas = $this->Yokohamas->find('all', $params);	
		$this->set(compact('marunouchis'));
		$this->set(compact('yokohamas'));
	}
}
?>

viewでは、marunouchisとyokohamasを呼び出せる。

cakeでデータベースを参照しないページをつくる

src/Templateに対象フォルダとindex.ctpをつくります。

controllerをつくります。

<?php
namespace App\Controller;
class TestsController extends AppController
{	
	var $name = 'Tests';
	var $useTable = false;
	public function index()
	{
		$this->viewBuilder()->layout('my_layout');		
	}
}
?>

表示されました。modelはつくらなくても、エラーは表示されません。