「RSSデータの取得とデータの蓄積サンプル」をcakePHPで実運用したサンプル

[前回](http://qiita.com/keitone/items/d34995bab739d8f49b5c)作ったのをベースとして、cakePHPで管理画面を作って実運用したものです。
#実装に必要なもの
・cakePHP1.3
apacheとかは割愛。

#基本的な作り方
[前回](http://qiita.com/keitone/items/d34995bab739d8f49b5c)作成したテーブルを元にしてbakeすればいいはずなんだけど少し改造したのでソースを載せます。cakePHPのバージョンは古いけどそんな凝ったことをしてるわけじゃないので2系以降でも動くと思います。動くんじゃないかな。きっと動くよ。そうに違いない。

#コントローラー
・*app/Controller/PagesController.php*
bakeすれば自動生成されるらしい。そうだっけ？忘れた。<pre>
<?php
/**
 * Static content controller.
 *
 * This file will render views from views/pages/
 *
 * PHP 5
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Controller
 * @since         CakePHP(tm) v 0.2.9
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 */
App::uses('AppController', 'Controller');

/**
 * Static content controller
 *
 * Override this controller by placing a copy in controllers directory of an application
 *
 * @package       app.Controller
 * @link http://book.cakephp.org/2.0/en/controllers/pages-controller.html
 */
class PagesController extends AppController {

/**
 * Controller name
 *
 * @var string
 */
	public $name = 'Pages';

/**
 * This controller does not use a model
 *
 * @var array
 */
	public $uses = array();

/**
 * Displays a view
 *
 * @param mixed What page to display
 * @return void
 */
	public function display() {
		$path = func_get_args();

		$count = count($path);
		if (!$count) {
			return $this->redirect('/');
		}
		$page = $subpage = $title_for_layout = null;

		if (!empty($path[0])) {
			$page = $path[0];
		}
		if (!empty($path[1])) {
			$subpage = $path[1];
		}
		if (!empty($path[$count - 1])) {
			$title_for_layout = Inflector::humanize($path[$count - 1]);
		}
		$this->set(compact('page', 'subpage', 'title_for_layout'));
		$this->render(implode('/', $path));
	}
}

</pre>

・*app/Controller/RssmastersController.php*
ひょっとしたらbakeしてどこもいじってないかもしれない。忘れた。<pre>
<?php
App::uses('AppController', 'Controller');
/**
 * Rssmasters Controller
 *
 * @property Rssmaster $Rssmaster
 * @property PaginatorComponent $Paginator
 */
class RssmastersController extends AppController {

/**
 * Components
 *
 * @var array
 */
	public $components = array('Paginator');

/**
 * index method
 *
 * @return void
 */
	public function index() {
		$this->Rssmaster->recursive = 0;

		// pageLimit 
		$options = $this->paginate;
		$options['limit'] = 50;
		$this->paginate = $options;

		$this->set('rssmasters', $this->Paginator->paginate());
	}

/**
 * view method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function view($id = null) {
		if (!$this->Rssmaster->exists($id)) {
			throw new NotFoundException(__('Invalid rssmaster'));
		}
		$options = array('conditions' => array('Rssmaster.' . $this->Rssmaster->primaryKey => $id));
		$this->set('rssmaster', $this->Rssmaster->find('first', $options));
	}

/**
 * add method
 *
 * @return void
 */
	public function add() {
		if ($this->request->is('post')) {
			$this->Rssmaster->create();
			if ($this->Rssmaster->save($this->request->data)) {
				$this->Session->setFlash(__('The rssmaster has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The rssmaster could not be saved. Please, try again.'));
			}
		}
	}

/**
 * edit method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function edit($id = null) {
		if (!$this->Rssmaster->exists($id)) {
			throw new NotFoundException(__('Invalid rssmaster'));
		}
		if ($this->request->is('post') || $this->request->is('put')) {
			if ($this->Rssmaster->save($this->request->data)) {
				$this->Session->setFlash(__('The rssmaster has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The rssmaster could not be saved. Please, try again.'));
			}
		} else {
			$options = array('conditions' => array('Rssmaster.' . $this->Rssmaster->primaryKey => $id));
			$this->request->data = $this->Rssmaster->find('first', $options);
		}
	}

/**
 * delete method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function delete($id = null) {
		$this->Rssmaster->id = $id;
		if (!$this->Rssmaster->exists()) {
			throw new NotFoundException(__('Invalid rssmaster'));
		}
		$this->request->onlyAllow('post', 'delete');
		if ($this->Rssmaster->delete()) {
			$this->Session->setFlash(__('The rssmaster has been deleted.'));
		} else {
			$this->Session->setFlash(__('The rssmaster could not be deleted. Please, try again.'));
		}
		return $this->redirect(array('action' => 'index'));
	}
}
</pre>


・*app/Controller/RssdataController.php*
やっぱりいじってなかったかな？忘れた。<pre>
<?php
App::uses('AppController', 'Controller');
/**
 * Rssdata Controller
 *
 * @property Rssdatum $Rssdatum
 * @property PaginatorComponent $Paginator
 */
class RssdataController extends AppController {

/**
 * Components
 *
 * @var array
 */
	public $components = array('Paginator', 'Search.Prg');
	public $presetVars = true;

/**
 * index method
 *
 * @return void
 */
	public function index() {
		$this->Rssdatum->recursive = 0;

		$this->Prg->commonProcess();
		$this->paginate = array(
            'conditions' => $this->Rssdatum->parseCriteria($this->passedArgs),
        );

		// pageLimit 
		$options = $this->paginate;
		$options['limit'] = 50;
		//$options['order'] = array('id'=>'asc','status'=>'desc','updated'=>'desc');
		//$options['sort'] = 'id';
		$this->paginate = $options;

		//$this->set('rssdata', $this->Paginator->paginate());
		$this->set('rssdata', $this->paginate());
	}

/**
 * view method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function view($id = null) {
		if (!$this->Rssdatum->exists($id)) {
			throw new NotFoundException(__('Invalid rssdatum'));
		}
		$options = array('conditions' => array('Rssdatum.' . $this->Rssdatum->primaryKey => $id));
		$this->set('rssdatum', $this->Rssdatum->find('first', $options));
	}

/**
 * add method
 *
 * @return void
 */
	public function add() {
		if ($this->request->is('post')) {
			$this->Rssdatum->create();
			if ($this->Rssdatum->save($this->request->data)) {
				$this->Session->setFlash(__('The rssdatum has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The rssdatum could not be saved. Please, try again.'));
			}
		}
	}

/**
 * edit method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function edit($id = null) {
		if (!$this->Rssdatum->exists($id)) {
			throw new NotFoundException(__('Invalid rssdatum'));
		}
		if ($this->request->is('post') || $this->request->is('put')) {
			if ($this->Rssdatum->save($this->request->data)) {
				$this->Session->setFlash(__('The rssdatum has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The rssdatum could not be saved. Please, try again.'));
			}
		} else {
			$options = array('conditions' => array('Rssdatum.' . $this->Rssdatum->primaryKey => $id));
			$this->request->data = $this->Rssdatum->find('first', $options);
		}
	}

/**
 * delete method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function delete($id = null) {
		$this->Rssdatum->id = $id;
		if (!$this->Rssdatum->exists()) {
			throw new NotFoundException(__('Invalid rssdatum'));
		}
		$this->request->onlyAllow('post', 'delete');
		if ($this->Rssdatum->delete()) {
			$this->Session->setFlash(__('The rssdatum has been deleted.'));
		} else {
			$this->Session->setFlash(__('The rssdatum could not be deleted. Please, try again.'));
		}
		return $this->redirect(array('action' => 'index'));
	}}
</pre>

#モデル
・*app/Model/Rssmaster.php*
ほぼいじってない。<pre>
<?php
App::uses('AppModel', 'Model');
/**
 * Rssmaster Model
 *
 */
class Rssmaster extends AppModel {

/**
 * Use table
 *
 * @var mixed False or table name
 */
	public $useTable = 'rssmaster';

/**
 * Display field
 *
 * @var string
 */
	public $displayField = 'name';

}
</pre>

・*app/Model/Rssdatum.php*
ちょっといじってた。<pre>
<?php
App::uses('AppModel', 'Model');
/**
 * Rssdatum Model
 *
 * @property Rssmaster $Rssmaster
 */
class Rssdatum extends AppModel {

	public $primaryKey = 'itemkey';
    public $actsAs = array('Search.Searchable');

	public $filterArgs = array(
		'id' => array('type' => 'value'),
		'itemtitle' => array('type' => 'like'),
	);

	//The Associations below have been created with all possible keys, those that are not needed can be removed

/**
 * belongsTo associations
 *
 * @var array
 */

/*
	public $belongsTo = array(
		'Rssmaster' => array(
			'className' => 'Rssmaster',
			'foreignKey' => 'id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		)
	);
*/



	function beforeFind($queryData)
	{
		if (empty($queryData['order'][0]))
		{
			$queryData['order'] = array(
				array('Rssdatum.id'=>'asc'),
				array('Rssdatum.status'=>'desc'),
				array('Rssdatum.created'=>'desc')
			);
		}
		else
		{
			list($key,$value) = each($queryData['order'][0]);
			if ($key === 'Rssdatum.id')
			{
				$queryData['order'] = array(
					array($key=>$value),
				);
			}
			else
			{
				$queryData['order'] = array(
					array($key=>$value),
					array('Rssdatum.id'=>'asc'),
				);
			}
		}
		return $queryData;
	}

	function index()
	{
		$rssdata = $this->MovieCollection->find('all',
			array('conditions'=>	
				array('NOT' =>
					array('status'=>'-1')
				)
			)
		);
		$this->set('rssdata',$rssdata);
	}

}
</pre>

#ビュー
##Rssmasters
・*app/View/Rssmasters/add.ctp*<pre>
<div class="rssmasters form">
<?php echo $this->Form->create('Rssmaster'); ?>
	<fieldset>
		<legend><?php echo __('Add Rssmaster'); ?></legend>
	<?php
        echo "name<br />";
        echo $this->Form->text('name');
        echo "<br /><br />";

        echo "url<br />";
        echo $this->Form->text('url');
        echo "<br /><br />";

        echo "dispname<br />";
        echo $this->Form->text('dispname');
        echo "<br /><br />";

        echo "rdf<br />";
        echo $this->Form->text('rdf');
        echo "<br /><br />";

        echo "status<br />";
        echo $this->Form->text('status');
        echo "<br /><br />";

        echo "version<br />";
        echo $this->Form->text('version');
        echo "<br /><br />";

        echo "itemlimit<br />";
        echo $this->Form->text('itemlimit');
        echo "<br /><br />";

	?>
	</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
<div class="actions">
	<h3><?php echo __('Actions'); ?></h3>
	<ul>

		<li><?php echo $this->Html->link(__('List Rssmasters'), array('action' => 'index')); ?></li>
	</ul>
</div>
</pre>

・*app/View/Rssmasters/edit.ctp*<pre>
<div class="rssmasters form">
<?php echo $this->Form->create('Rssmaster'); ?>
	<fieldset>
		<legend><?php echo __('Edit Rssmaster'); ?></legend>
	<?php
		echo $this->Form->hidden('id');

		echo "name<br />";
		echo $this->Form->text('name');
		echo "<br /><br />";

		echo "url<br />";	
		echo $this->Form->text('url');
		echo "<br /><br />";

		echo "dispname<br />";
		echo $this->Form->text('dispname');
		echo "<br /><br />";

		echo "rdf<br />";
		echo $this->Form->text('rdf');
		echo "<br /><br />";

		echo "status<br />";
		echo $this->Form->text('status');
		echo "<br /><br />";

		echo "version<br />";
		echo $this->Form->text('version');
		echo "<br /><br />";

		echo "itemlimit<br />";
		echo $this->Form->text('itemlimit');
		echo "<br /><br />";
	?>
	</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
<div class="actions">
	<h3><?php echo __('Actions'); ?></h3>
	<ul>

		<li><?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $this->Form->value('Rssmaster.id')), null, __('Are you sure you want to delete # %s?', $this->Form->value('Rssmaster.id'))); ?></li>
		<li><?php echo $this->Html->link(__('List Rssmasters'), array('action' => 'index')); ?></li>
	</ul>
</div>
</pre>

・*app/View/Rssmasters/index.ctp*<pre>
<div class="rssmasters index">
	<h2><a href="/cake/Rssmasters/"><?php echo __('Rssmasters'); ?></a></h2>
	<p>
	<div class="actions">
		<ul>
			<li><?php echo $this->Html->link(__('New Rssmaster'), array('action' => 'add')); ?></li>
		</ul>
	</div><br /><br />
	<div class="paging">
	<?php
		echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
		echo $this->Paginator->numbers(array('separator' => ''));
		echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
	?>
	</div>
	<table cellpadding="0" cellspacing="0">
	<tr>
			<th><?php echo $this->Paginator->sort('id'); ?></th>
			<th><?php echo $this->Paginator->sort('name'); ?></th>
			<th><?php echo $this->Paginator->sort('url'); ?></th>
			<th><?php echo $this->Paginator->sort('dispname'); ?></th>
			<th><?php echo $this->Paginator->sort('rdf'); ?></th>
			<th><?php echo $this->Paginator->sort('status'); ?></th>
			<th><?php echo $this->Paginator->sort('version'); ?></th>
			<th><?php echo $this->Paginator->sort('itemlimit'); ?></th>
			<th class="actions"><?php echo __('Actions'); ?></th>
	</tr>
	<?php foreach ($rssmasters as $rssmaster): ?>
	<tr>
		<td><?php echo h($rssmaster['Rssmaster']['id']); ?>&nbsp;</td>
		<td><?php echo h($rssmaster['Rssmaster']['name']); ?>&nbsp;</td>
		<td><a href="<?php echo h($rssmaster['Rssmaster']['url']); ?>" target="_blank">url</a>&nbsp;</td>
		<td><?php echo h($rssmaster['Rssmaster']['dispname']); ?>&nbsp;</td>
		<td><a href="<?php echo h($rssmaster['Rssmaster']['rdf']); ?>" target="_blank">rss</a>&nbsp;</td>
		<td><?php echo h($rssmaster['Rssmaster']['status']); ?>&nbsp;</td>
		<td><?php echo h($rssmaster['Rssmaster']['version']); ?>&nbsp;</td>
		<td><?php echo h($rssmaster['Rssmaster']['itemlimit']); ?>&nbsp;</td>
		<td class="actions">
			<?php echo $this->Html->link(__('View'), array('action' => 'view', $rssmaster['Rssmaster']['id'])); ?>
			<?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $rssmaster['Rssmaster']['id'])); ?>
			<?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $rssmaster['Rssmaster']['id']), null, __('Are you sure you want to delete # %s?', $rssmaster['Rssmaster']['id'])); ?>
		</td>
	</tr>
<?php endforeach; ?>
	</table>
	<p>
	<?php
	echo $this->Paginator->counter(array(
	'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
	));
	?>	</p>
	<div class="paging">
	<?php
		echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
		echo $this->Paginator->numbers(array('separator' => ''));
		echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
	?>
	</div>
</div>
</pre>

・*app/View/Rssmasters/view.ctp<pre>
<div class="rssmasters view">
<h2><?php echo __('Rssmaster'); ?></h2>
	<dl>
		<dt><?php echo __('Id'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['id']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Name'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['name']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Url'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['url']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Dispname'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['dispname']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Rdf'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['rdf']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Status'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['status']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Version'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['version']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Itemlimit'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['itemlimit']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Created'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['created']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Updated'); ?></dt>
		<dd>
			<?php echo h($rssmaster['Rssmaster']['updated']); ?>
			&nbsp;
		</dd>
	</dl>
</div>
<div class="actions">
	<h3><?php echo __('Actions'); ?></h3>
	<ul>
		<li><?php echo $this->Html->link(__('Edit Rssmaster'), array('action' => 'edit', $rssmaster['Rssmaster']['id'])); ?> </li>
		<li><?php echo $this->Form->postLink(__('Delete Rssmaster'), array('action' => 'delete', $rssmaster['Rssmaster']['id']), null, __('Are you sure you want to delete # %s?', $rssmaster['Rssmaster']['id'])); ?> </li>
		<li><?php echo $this->Html->link(__('List Rssmasters'), array('action' => 'index')); ?> </li>
		<li><?php echo $this->Html->link(__('New Rssmaster'), array('action' => 'add')); ?> </li>
	</ul>
</div>
</pre>

##Rssdata
・*app/View/Rssdata/add.ctp*<pre>
<div class="rssdata form">
<?php echo $this->Form->create('Rssdatum'); ?>
	<fieldset>
		<legend><?php echo __('Add Rssdatum'); ?></legend>
	<?php
		echo $this->Form->input('id');
		echo $this->Form->input('sitetitle');
		echo $this->Form->input('sitedescription');
		echo $this->Form->input('sitelink');
		echo $this->Form->input('itemtitle');
		echo $this->Form->input('itemdescription_body');
		echo $this->Form->input('itemdescription_plane');
		echo $this->Form->input('itemdescription_image');
		echo $this->Form->input('itemdescription_comment');
		echo $this->Form->input('to');
		echo $this->Form->input('itemlink');
		echo $this->Form->input('status');
		echo $this->Form->input('version');
	?>
	</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
<div class="actions">
	<h3><?php echo __('Actions'); ?></h3>
	<ul>

		<li><?php echo $this->Html->link(__('List Rssdata'), array('action' => 'index')); ?></li>
	</ul>
</div>
</pre>

・*app/View/Rssdata/edit.ctp*<pre>
<div class="rssdata form">
<?php echo $this->Form->create('Rssdatum'); ?>
    <fieldset>
        <legend><?php echo __('Edit Rssdatum'); ?></legend>
    <?php
		echo $this->Form->hidden('itemkey');

		echo "sitetitle<br />";
        echo $this->Form->text('sitetitle', array("disabled"=>"disabled"));
		echo "<br /><br />";

		echo "itemtitle<br />";
        echo $this->Form->text('itemtitle', array("disabled"=>"disabled"));
		echo "<br /><br />";

		echo "itemdescription_plane<br />";
        echo $this->Form->textarea('itemdescription_plane',array("rows"=>"3","disabled"=>"disabled"));
		echo "<br /><br />";

		echo "itemdescription_title<br />";
        echo $this->Form->text('itemdescription_title'); 
		echo "<br /><br />";

		echo "itemdescription_comment<br />";
        echo $this->Form->textarea('itemdescription_comment',array("rows"=>"10")); 
		echo "<br /><br />";


        echo $this->Form->input('to',array(
            'type' => 'select',
            'options' => array(
                'b-d84a3e1719ea-1093091@blogcms.jp'=>'RSSニュース',
                'b-d84a3e1719ea-1100917@blogcms.jp'=>'SS',
                'b-d84a3e1719ea-1100943@blogcms.jp'=>'改変系',
				'b-d84a3e1719ea-1109159@blogcms.jp'=>'画像系',
                'b-d84a3e1719ea-1100926@blogcms.jp'=>'替え歌',
                'b-d84a3e1719ea-1100920@blogcms.jp'=>'一発モノ',
                'b-d84a3e1719ea-1100927@blogcms.jp'=>'箇条書き',
                'b-d84a3e1719ea-1100914@blogcms.jp'=>'ニセwiki',
				'b-d84a3e1719ea-1108806@blogcms.jp'=>'記事まとめ系',
                'b-d84a3e1719ea-1100911@blogcms.jp'=>'ニュースコメント',
            ),'selected'=> $this->Form->value('Rssdata.to')));

        echo $this->Form->input('status', array(
            'type' => 'select',
            'options' => array(
                '1'=>'1:送信予約',
                '0'=>'0:登録のみ'),
            'selected'=>$this->Form->value('Rssdata.status')));

        //echo $this->Form->input('version');
        echo $this->Form->hidden('modified', array('value'=>date('Y-m-d H:i:s')));
    ?>
	<?php echo $this->Form->end(__('Submit')); ?>
    </fieldset>
</div>
</pre>

・*app/View/Rssdata/index.ctp*<pre>
<div class="rssdata index">
	<h2><a href="/cake/Rssdata/"><?php echo __('Rssdata'); ?></a></h2>
	<p>
	<div class="actions">
		<ul>
			<li><?php echo $this->Html->link(__('New Rssdatum'), array('action' => 'add')); ?> </li>
		</ul>
	</div><br /><br />
	<div class="well" style="margin-top:20px;">
	<?php 
		echo $this->Form->create('Rssdatum', array('action'=>'index')); 
		//echo $this->Form->input('itemtitle', array('label' => 'itemtitle検索', 'placeholder' => 'itemtitleを対象に検索')); 
		echo $this->Form->text('itemtitle', array('label' => 'itemtitle検索', 'placeholder' => 'itemtitleを対象に検索','style'=>'width:600px;height:10px')); 
		echo $this->Form->end('検索'); 
	?>
	</div>

	<div class="paging">
	<?php
		echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
		echo $this->Paginator->numbers(array('separator' => ''));
		echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
	?>
	</div>
	<table cellpadding="0" cellspacing="0">
	<tr>
			<th><?php echo $this->Paginator->sort('id'); ?></th>
			<th><?php echo $this->Paginator->sort('sitetitle'); ?></th>
			<th><?php echo $this->Paginator->sort('itemtitle'); ?></th>
			<th><?php echo $this->Paginator->sort('created'); ?></th>
			<th><?php echo $this->Paginator->sort('modified'); ?></th>
			<th>new</th>
			<th><?php echo $this->Paginator->sort('status'); ?></th>
			<th class="actions"><?php echo __('Actions'); ?></th>
	</tr>
	<?php foreach ($rssdata as $rssdatum): ?>
	<tr>
		<td><?php echo h($rssdatum['Rssdatum']['id']); ?>&nbsp;</td>
		<td><?php echo h($rssdatum['Rssdatum']['sitetitle']); ?>&nbsp;</td>
		<td>
			<a href="<?php echo h($rssdatum['Rssdatum']['itemlink']); ?>" target="_blank">
				<b><?php echo h($rssdatum['Rssdatum']['itemtitle']); ?></b></a><br/>
			<?php echo $rssdatum['Rssdatum']['itemdescription_body'] ?>&nbsp;&nbsp;</td>
		<td nowrap><?php echo h($rssdatum['Rssdatum']['created']); ?>&nbsp;</td>
		<td nowrap><?php echo h($rssdatum['Rssdatum']['modified']); ?>&nbsp;</td>
		<td>
		<?php

			// 現在より12時間以内に作成されたNEWSにはnewをつける
			echo (((int)strtotime('now') - (int)strtotime($rssdatum['Rssdatum']['created'])) < 43200) ? "<font color=\"red\">New</font>" : "";
		?>
		</td>
		<td nowrap>
		<?php //echo h($rssdatum['Rssdatum']['status']); 
			if ($rssdatum['Rssdatum']['status'] == 1)
			{
				echo "1:送信予約";
			}elseif ( $rssdatum['Rssdatum']['status'] == 0){
				echo "0:登録のみ";
			}	
		?>&nbsp;</td>
		<td class="actions">
			<?php echo $this->Html->link(__('View'), array('action' => 'view', $rssdatum['Rssdatum']['itemkey']),array('target'=>'_blank')); ?>
			<?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $rssdatum['Rssdatum']['itemkey']),array('target'=>'_blank')); ?>
			<?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $rssdatum['Rssdatum']['itemkey']), null, __('Are you sure you want to delete # %s?', $rssdatum['Rssdatum']['itemkey'])); ?>
		</td>
	</tr>
<?php endforeach; ?>
	</table>
	<p>
	<?php
	echo $this->Paginator->counter(array(
	'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
	));
	?>	</p>
	<div class="paging">
	<?php
		echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
		echo $this->Paginator->numbers(array('separator' => ''));
		echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
	?>
	</div>
</div>

</pre>

・*app/View/Rssdata/view.ctp*<pre>
<div class="rssdata view">
<h2><?php echo __('Rssdatum'); ?></h2>
	<dl>
		<dt><?php echo __('Id'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['id']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Sitetitle'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['sitetitle']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Sitedescription'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['sitedescription']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Sitelink'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['sitelink']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Itemkey'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['itemkey']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Itemtitle'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['itemtitle']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Itemdescription Body'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['itemdescription_body']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Itemdescription Plane'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['itemdescription_plane']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Itemdescription Image'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['itemdescription_image']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Itemdescription Comment'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['itemdescription_comment']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('To'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['to']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Itemlink'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['itemlink']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Status'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['status']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Version'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['version']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Created'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['created']); ?>
			&nbsp;
		</dd>
		<dt><?php echo __('Updated'); ?></dt>
		<dd>
			<?php echo h($rssdatum['Rssdatum']['modified']); ?>
			&nbsp;
		</dd>
	</dl>
</div>
<div class="actions">
	<h3><?php echo __('Actions'); ?></h3>
	<ul>
		<li><?php echo $this->Html->link(__('Edit Rssdatum'), array('action' => 'edit', $rssdatum['Rssdatum']['itemkey'])); ?> </li>
		<li><?php echo $this->Form->postLink(__('Delete Rssdatum'), array('action' => 'delete', $rssdatum['Rssdatum']['itemkey']), null, __('Are you sure you want to delete # %s?', $rssdatum['Rssdatum']['itemkey'])); ?> </li>
		<li><?php echo $this->Html->link(__('List Rssdata'), array('action' => 'index')); ?> </li>
		<li><?php echo $this->Html->link(__('New Rssdatum'), array('action' => 'add')); ?> </li>
	</ul>
</div>
</pre>

#コンソール
[前回](http://qiita.com/keitone/items/d34995bab739d8f49b5c)作ったparserdf.phpをcakePHPのコンソール機能用に書きなおしたもの。
・*app/Console/Command/ParseRdfShell.php*<pre>
<?php

Class ParseRdfShell extends AppShell
{
	public $uses = array('Rssmaster','Rssdatum');
	
	public function index()
	{
		$this->delete();
		$this->getlist();
	}

	public function getlist()
	{
		$options = array(
			'conditions' => array(
				'status' => 1
			),
			'order' => array(
				'id asc'
			),
		);

		foreach($this->Rssmaster->find('all',$options) as $rssmaster)
		{
			$this->parserdf($rssmaster);
		}
	}

	private function delete()
	{
		$sql = "DELETE FROM rssdata WHERE ( status = 0 AND ( itemdescription_comment IS NULL OR itemdescription_comment = '' )) ";
		$sql.= "OR modified < date_add(current_timestamp, interval -3 day) ";
		$this->Rssdatum->query($sql);
		//var_dump($this->Rssdatum->deleteAll(array('itemdescription_plane'=> '' )));
		//debug($this->Rssdatum->getDataSource()->getLog());
	}

	private function parserdf($rssmaster = null)
	{
		$rssdata=array();
		$rssdata['id'] = $rssmaster['Rssmaster']['id'];
		$rssdata['version'] = $rssmaster['Rssmaster']['version'];
		$newslimit = $rssmaster['Rssmaster']['itemlimit'];
		$rdf = $rssmaster['Rssmaster']['rdf'];

		if ($fileContents = file_get_contents($rdf))
		{
			$result = new SimpleXMLElement($fileContents);
	
			// sitetitle
			if (array_key_exists('title', $result->channel))
			{
				$rssdata['sitetitle'] = (string)$result->channel->title;
			}
			else
			{
				$rssdata['sitetitle'] = $rssmaster['Rssmaster']['dispname'];
			}

			// sitedescription
			if (array_key_exists('description', $result->channel) && is_string($result->channel->description))
			{
				$rssdata['sitedescription'] = (string)$result->channel->description;
			}
			else
			{
				$rssdata['sitedescription'] = $rssmaster['Rssmaster']['name'];
			}

			// sitelink
			if (array_key_exists('link', $result->channel))
			{
				$rssdata['sitelink'] = $this->urlcheck((string)$result->channel->link, $rssmaster['Rssmaster']['url']);
			}
			else
			{
				$rssdata['sitelink'] = $rssmaster['Rssmaster']['url'];
			}

			$isitems=false;
			$items=array();

			// RSS Version1.0
			if ($rssdata['version'] === '1.0')
			{
				if (array_key_exists('item', $result))
				{
					$isitems=true;
					$items=$result->item;
				}
			}
			// RSS Version2.0
			elseif($rssdata['version'] === '2.0')
			{
				if (array_key_exists('item', $result->channel))
				{
					$isitems=true;
					$items=$result->channel->item;
				}
			}

			if ($isitems)
			{
				$newscount = 0;
				foreach($items as $row)
				{
					if ($newslimit != 0)
					{
						if ($newscount >= $newslimit) break;
						$newscount++;
					}
					$rssdata['itemtitle'] = (string)$row->title;
					if (substr($rssdata['itemtitle'],0,2) === 'PR' || substr($rssdata['itemtitle'],0,2) == 'AD' || substr($rssdata['itemtitle'],1,2) == 'PR')
					{
						continue;
					}	
					$rssdata['itemlink'] = (string)$row->link;
					$rssdata['itemkey'] = (string)md5($rssdata['itemlink']);
					$rssdata['itemdescription_source'] = (string)$row->description;
					if (is_string($rssdata['itemdescription_source']))
					{
						$rssdata['itemdescription_image'] = $this->getimage($rssdata['itemdescription_source']);
						$rssdata['itemdescription_plane'] = strip_tags($rssdata['itemdescription_source']);
						$rssdata['itemdescription_plane'] = str_replace(array("\r\n","\r","\n"), '', $rssdata['itemdescription_plane']);
						$rssdata['itemdescription_body'] = str_replace("'","\"",$rssdata['itemdescription_source']);
						$rssdata['itemdescription_body'] = str_replace("<p>", "", $rssdata['itemdescription_body']);
						$rssdata['itemdescription_body'] = str_replace("</p>", "", $rssdata['itemdescription_body']);
						$rssdata['itemdescription_body'] = str_replace(array("\r\n","\r","\n"), '', $rssdata['itemdescription_body']);
					}
					if ($rssdata['version'] === '1.0')
					{
						$dc = $row->children('http://purl.org/dc/elements/1.1/');
						//$rssdata['date'] = date('Y.m.d H:i:s', strtotime($dc->date));
						$rssdata['date'] = date('Y-m-d H:i:s', strtotime($dc->date));
					}
					elseif($rssdata['version'] === '2.0')
					{
						//$rssdata['date'] = date('Y.m.d H:i:s',strtotime($row->pubDate));
						$rssdata['date'] = date('Y-m-d H:i:s',strtotime($row->pubDate));
					}

					// 起動時間より48時間より前のニュースは捨てる
					if (((int)strtotime('now') - (int)strtotime($rssdata['date'])) > 172800)
					{
						continue;
					}
					if ($this->recordcount($rssdata['itemkey']) == 0)
					{
						$this->add($rssdata);
					}
				}
			}
		}
	}

	private function recordcount($itemkey = null)
	{
		$options = array(
			'conditions' => array(
				'itemkey' => $itemkey
			),
		);
		return $this->Rssdatum->find('count', $options);
	}

	private function add($rssdata = null)
	{
		$this->Rssdatum->create();
		$this->Rssdatum->save(
			array(
				'id'					=>	$rssdata['id'],
				'sitetitle'				=>	$rssdata['sitetitle'],
				'sitedescription'		=>	$rssdata['sitedescription'],
				'sitelink'				=>	$rssdata['sitelink'],
				'itemkey'				=>	$rssdata['itemkey'],
				'itemtitle'				=>	$rssdata['itemtitle'],
				'itemdescription_body'	=>	$rssdata['itemdescription_body'],
				'itemdescription_plane'	=>	$rssdata['itemdescription_plane'],
				'itemdescription_image'	=>	$rssdata['itemdescription_image'],
				'itemlink'				=>	$rssdata['itemlink'],
				'status'				=>	0,
				'version'				=>	$rssdata['version'],
				'created'				=>	$rssdata['date']
			)
		);
	}

	// url1の形式チェック・存在チェックをする。両方trueならurl1を、falseがあればurl2を返す
	private function urlcheck($url1,$url2)
	{
		$returl = $url1;

		// url形式チェック
		if (preg_match('/^(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$/', $url1))
		{
			// URL存在チェック
			if($fp = @fopen($url1, 'r'))
			{
				fclose($fp);
			}
			else
			{
				$returl = $url2;
			}
		}
		else
		{
			$returl = $url2;
		}
		return $returl;
	}

	// imgタグ抜き出し
	private function getimage($str)
	{
		if (!is_string($str)) return;
		if (preg_match('/(\<img).*(gif|jpg|jpeg|png)(.*?>)/', $str, $match))
		{
			return str_replace("'","\"",$match[0]);
		}
		else
		{
			return "";
		}
	}

	private function logging($array)
	{
		$log = NULL;
		$log.= date("Y/m/d H:i:s")." : ";
		$Ymd = date("Ymd");
		foreach($array as $key => $value)
		{
			if (is_numeric($key))
			{
					continue;
			}
			$log.= "$key=$value,";
		}
		$log = substr($log,0,-1);
		$log.= "\n";
		$logfile = str_replace("php","log",$_SERVER['PHP_SELF']) ;
		error_log($log,3,'/var/log/'.$logfile);
	}

}
</pre>
・実行方法（/var/www/htmlをDocumentRootにしてあります）<pre>
/usr/bin/php /var/www/html/cake/app/Console/cake.php -app /var/www/html/cake/app parse_rdf index > /dev/null
</pre>

#ついでに
[前回](http://qiita.com/keitone/items/d34995bab739d8f49b5c)も書いた通り、もともとブログのためのシステムなのでブログ更新用のスクリプトも書きました。
以下はlivedoorのメールによるブログ投稿システムに一斉投稿するためのスクリプトです。
・*contrib_livedoor.php*<pre>
<?php
mb_language("Japanese");
mb_internal_encoding("UTF-8");

$from="From: root@localhost";		// 投稿用メールアカウント

mb_internal_encoding("utf-8");  // 内部エンコード指定@文字化け対策
$dbHost="127.0.0.1";
$dbUser="root";
$dbPass="password";
$db_select = mysql_connect($dbHost, $dbUser, $dbPass);
mysql_set_charset("utf8",$db_select);   // DBエンコード指定@文字化け対策
$db_selected = mysql_select_db('rssbbs', $db_select);

$sql_count = "SELECT count(*) FROM rssdata WHERE status = 1";
$ret_count = mysql_query($sql_count);
$last_count_array = mysql_fetch_array($ret_count);
$last_count = $last_count_array[0];
//print "$last_count\n";

$sql = "SELECT * FROM rssdata WHERE status = 1 ORDER BY LENGTH(itemdescription_comment) , rssdata.to ";
$ret = mysql_query($sql);
while ($array = mysql_fetch_array($ret))
{
	$id = $array['id'];
	$itemkey = $array['itemkey'];
	$to = $array['to'];

	$blogtitle = ($array['itemdescription_title'] !== '') ? $array['itemdescription_title'] : $array['itemtitle'];
	$blogbody=createbody($array);
	
	if (mb_send_mail($to,$blogtitle,$blogbody,$from))
	{
		echo "メールが送信されました。\n";
	}
	else
	{
		echo "メールの送信に失敗しました。\n";
	}

	$update_sql = "UPDATE rssdata SET status = 0, modified = CURRENT_TIMESTAMP WHERE id = $id AND itemkey = '$itemkey'";
	mysql_query($update_sql);
	logging($array);
	if ($last_count > 1)	
	{
		sleep(63);	// 1分まちなので余裕をもって
	}
	$last_count--;
}
mysql_close($db_select);

//通知
//mb_send_mail("self@localhost",$_SERVER['PHP_SELF']."更新処理終了","更新が終わりました。",$from);

// ---------------------------------------------------------------
//  functions
// ---------------------------------------------------------------
function createbody($array)
{
	$body = NULL;
	$body.= "<i>";
	$body.= "<b>".$array['itemtitle']."</b>";
	$body.= "<br />";
	if ($array['itemdescription_body'] !== '')
	{
		$body.= $array['itemdescription_body'];
		$body.= "<br />";
	}
	$body.= "元記事:".createlink($array['itemlink'],$array['itemlink']);
	$body.= "<br />";
	$body.= "引用元:".createlink($array['sitelink'],$array['sitetitle']);
	$body.= "<br />";
	$body.= "</i>\n";
	$body.= replacehttp($array['itemdescription_comment']);
	return $body;
}

function replacehttp($str)
{
	$href_pattern = '/(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/i';
	$href_replacement = '<a href="${1}${2}" target="_blank">${1}${2}</a>';
	$img_pattern = '/(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)(gif|jpg|jpeg|png)/i';
	$img_replacement = '<img src="${1}${2}${3}" />';

	if (preg_match_all($href_pattern,$str,$match))
	{
		$unique = array_unique($match[0]);
		foreach($unique as $url)
		{
			if (preg_match($img_pattern,$url))
			{
				$str = str_replace($url,"<img src=\"". $url ."\" />", $str);
			}
			else if (preg_match($href_pattern, $url))
			{
				$str = str_replace($url,createlink($url,$url),$str);
			}
		}
	}
	return $str;
}

function createlink($link,$comment)
{
	return "<a href=\"".$link."\" target=\"_blank\">".$comment."</a>";
}

function logging($array)
{
    $log = NULL;
    $log.= date("Y/m/d H:i:s")." : ";
    $Ymd = date("Ymd");
    foreach($array as $key => $value)
    {
        if (is_numeric($key))
        {
            continue;
        }
        $log.= "$key=$value,";
    }
    $log = substr($log,0,-1);
    $log.= "\n";
    $logfile = str_replace("php","log",$_SERVER['PHP_SELF']) ;
    error_log($log,3,'/var/log/'.$logfile);
}
?>
</pre>

運用方法としては
・ParseRdfShell.phpを起動して新しいニュースを取ってくる。
　↓
・cakePHPの管理画面でニュースからブログを記述（ブログは一度に複数記事書いていた）。
　↓
contrib_livedoor.phpを実行して一斉送信。


* * *
こんなに頑張ったのに諸事情によりもうやってないんだなこれが。